diff options
Diffstat (limited to 'net/ipv6/ip6_fib.c')
| -rw-r--r-- | net/ipv6/ip6_fib.c | 22 | 
1 files changed, 21 insertions, 1 deletions
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index cb4459bd1d29..97b9fa8de377 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -643,7 +643,7 @@ static int fib6_commit_metrics(struct dst_entry *dst,  	if (dst->flags & DST_HOST) {  		mp = dst_metrics_write_ptr(dst);  	} else { -		mp = kzalloc(sizeof(u32) * RTAX_MAX, GFP_KERNEL); +		mp = kzalloc(sizeof(u32) * RTAX_MAX, GFP_ATOMIC);  		if (!mp)  			return -ENOMEM;  		dst_init_metrics(dst, mp, 0); @@ -1605,6 +1605,24 @@ static void fib6_prune_clones(struct net *net, struct fib6_node *fn)  	fib6_clean_tree(net, fn, fib6_prune_clone, 1, NULL);  } +static int fib6_update_sernum(struct rt6_info *rt, void *arg) +{ +	__u32 sernum = *(__u32 *)arg; + +	if (rt->rt6i_node && +	    rt->rt6i_node->fn_sernum != sernum) +		rt->rt6i_node->fn_sernum = sernum; + +	return 0; +} + +static void fib6_flush_trees(struct net *net) +{ +	__u32 new_sernum = fib6_new_sernum(); + +	fib6_clean_all(net, fib6_update_sernum, &new_sernum); +} +  /*   *	Garbage collection   */ @@ -1788,6 +1806,8 @@ int __init fib6_init(void)  			      NULL);  	if (ret)  		goto out_unregister_subsys; + +	__fib6_flush_trees = fib6_flush_trees;  out:  	return ret;  | 
