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>
This commit is contained in:

committed by
David S. Miller

parent
6229ed1f22
commit
8d2ca1d7b5
@@ -2800,56 +2800,12 @@ static int ip6_route_dev_notify(struct notifier_block *this,
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
||||
struct rt6_proc_arg
|
||||
{
|
||||
char *buffer;
|
||||
int offset;
|
||||
int length;
|
||||
int skip;
|
||||
int len;
|
||||
};
|
||||
|
||||
static int rt6_info_route(struct rt6_info *rt, void *p_arg)
|
||||
{
|
||||
struct seq_file *m = p_arg;
|
||||
|
||||
seq_printf(m, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen);
|
||||
|
||||
#ifdef CONFIG_IPV6_SUBTREES
|
||||
seq_printf(m, "%pi6 %02x ", &rt->rt6i_src.addr, rt->rt6i_src.plen);
|
||||
#else
|
||||
seq_puts(m, "00000000000000000000000000000000 00 ");
|
||||
#endif
|
||||
if (rt->rt6i_flags & RTF_GATEWAY) {
|
||||
seq_printf(m, "%pi6", &rt->rt6i_gateway);
|
||||
} else {
|
||||
seq_puts(m, "00000000000000000000000000000000");
|
||||
}
|
||||
seq_printf(m, " %08x %08x %08x %08x %8s\n",
|
||||
rt->rt6i_metric, atomic_read(&rt->dst.__refcnt),
|
||||
rt->dst.__use, rt->rt6i_flags,
|
||||
rt->dst.dev ? rt->dst.dev->name : "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ipv6_route_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct net *net = (struct net *)m->private;
|
||||
fib6_clean_all_ro(net, rt6_info_route, 0, m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ipv6_route_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open_net(inode, file, ipv6_route_show);
|
||||
}
|
||||
|
||||
static const struct file_operations ipv6_route_proc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = ipv6_route_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release_net,
|
||||
.release = seq_release_net,
|
||||
};
|
||||
|
||||
static int rt6_stats_seq_show(struct seq_file *seq, void *v)
|
||||
|
Reference in New Issue
Block a user