summaryrefslogtreecommitdiffstats
path: root/net/ipv6/route.c
diff options
context:
space:
mode:
authorHannes Frederic Sowa <hannes@stressinduktion.org>2013-09-21 10:55:59 -0400
committerDavid S. Miller <davem@davemloft.net>2013-09-27 17:32:16 -0400
commit8d2ca1d7b5c3e63b3a8a81ae99015b615c5f2bf7 (patch)
tree37202066f7715ffc4858c4dd9b5c66c1c8c5cd76 /net/ipv6/route.c
parent6229ed1f22592d5ee8360a638cb965fef88b080f (diff)
ipv6: avoid high order memory allocations for /proc/net/ipv6_route
Dumping routes on a system with lots rt6_infos in the fibs causes up to 11-order allocations in seq_file (which fail). While we could switch there to vmalloc we could just implement the streaming interface for /proc/net/ipv6_route. This patch switches /proc/net/ipv6_route from single_open_net to seq_open_net. loff_t *pos tracks dst entries. Also kill never used struct rt6_proc_arg and now unused function fib6_clean_all_ro. Cc: Ben Greear <greearb@candelatech.com> Cc: Patrick McHardy <kaber@trash.net> Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r--net/ipv6/route.c46
1 files changed, 1 insertions, 45 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index c979dd96d82a..aa901bb60cf2 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2800,56 +2800,12 @@ static int ip6_route_dev_notify(struct notifier_block *this,
2800 2800
2801#ifdef CONFIG_PROC_FS 2801#ifdef CONFIG_PROC_FS
2802 2802
2803struct rt6_proc_arg
2804{
2805 char *buffer;
2806 int offset;
2807 int length;
2808 int skip;
2809 int len;
2810};
2811
2812static int rt6_info_route(struct rt6_info *rt, void *p_arg)
2813{
2814 struct seq_file *m = p_arg;
2815
2816 seq_printf(m, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen);
2817
2818#ifdef CONFIG_IPV6_SUBTREES
2819 seq_printf(m, "%pi6 %02x ", &rt->rt6i_src.addr, rt->rt6i_src.plen);
2820#else
2821 seq_puts(m, "00000000000000000000000000000000 00 ");
2822#endif
2823 if (rt->rt6i_flags & RTF_GATEWAY) {
2824 seq_printf(m, "%pi6", &rt->rt6i_gateway);
2825 } else {
2826 seq_puts(m, "00000000000000000000000000000000");
2827 }
2828 seq_printf(m, " %08x %08x %08x %08x %8s\n",
2829 rt->rt6i_metric, atomic_read(&rt->dst.__refcnt),
2830 rt->dst.__use, rt->rt6i_flags,
2831 rt->dst.dev ? rt->dst.dev->name : "");
2832 return 0;
2833}
2834
2835static int ipv6_route_show(struct seq_file *m, void *v)
2836{
2837 struct net *net = (struct net *)m->private;
2838 fib6_clean_all_ro(net, rt6_info_route, 0, m);
2839 return 0;
2840}
2841
2842static int ipv6_route_open(struct inode *inode, struct file *file)
2843{
2844 return single_open_net(inode, file, ipv6_route_show);
2845}
2846
2847static const struct file_operations ipv6_route_proc_fops = { 2803static const struct file_operations ipv6_route_proc_fops = {
2848 .owner = THIS_MODULE, 2804 .owner = THIS_MODULE,
2849 .open = ipv6_route_open, 2805 .open = ipv6_route_open,
2850 .read = seq_read, 2806 .read = seq_read,
2851 .llseek = seq_lseek, 2807 .llseek = seq_lseek,
2852 .release = single_release_net, 2808 .release = seq_release_net,
2853}; 2809};
2854 2810
2855static int rt6_stats_seq_show(struct seq_file *seq, void *v) 2811static int rt6_stats_seq_show(struct seq_file *seq, void *v)