Patch "ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf" has been added to the 3.18-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf
to the 3.18-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
ipv6-reorder-ip6_route_dev_notifier-after-ipv6_dev_notf.patch
and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Thu May 11 12:52:00 CEST 2017
From: WANG Cong <[email protected]>
Date: Mon, 8 May 2017 10:12:13 -0700
Subject: ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf
From: WANG Cong <[email protected]>
[ Upstream commit 242d3a49a2a1a71d8eb9f953db1bcaa9d698ce00 ]
For each netns (except init_net), we initialize its null entry in 3 places:
1) The template itself, as we use kmemdup()
2) Code around dst_init_metrics() in ip6_route_net_init()
3) ip6_route_dev_notify(), which is supposed to initialize it after loopback registers
Unfortunately the last one still happens in a wrong order because we expect to initialize net->ipv6.ip6_null_entry->rt6i_idev to net->loopback_dev's idev, thus we have to do that after we add idev to loopback. However, this notifier has priority == 0 same as ipv6_dev_notf, and ipv6_dev_notf is registered after ip6_route_dev_notifier so it is called actually after ip6_route_dev_notifier. This is similar to commit 2f460933f58e ("ipv6: initialize route null entry in addrconf_init()") which fixes init_net.
Fix it by picking a smaller priority for ip6_route_dev_notifier. Also, we have to release the refcnt accordingly when unregistering loopback_dev because device exit functions are called before subsys exit functions.
--- include/net/addrconf.h | 2 ++ net/ipv6/addrconf.c | 1 + net/ipv6/route.c | 13 +++++++++++-- 3 files changed, 14 insertions(+), 2 deletions(-)
include/net/addrconf.h +2 -0
@@ -19,6 +19,8 @@#define ADDRCONF_TIMER_FUZZ (HZ / 4)#define ADDRCONF_TIMER_FUZZ_MAX (HZ) +#define ADDRCONF_NOTIFY_PRIORITY 0 +#include <linux/in.h> #include <linux/in6.h>
net/ipv6/addrconf.c +1 -0
@@ -2984,6 +2984,7 @@ static int addrconf_notify(struct notifi*/ static struct notifier_block ipv6_dev_notf = { .notifier_call = addrconf_notify, + .priority =ADDRCONF_NOTIFY_PRIORITY , };static void addrconf_type_change (struct net_device *dev,unsigned long event)
net/ipv6/route.c +11 -2
@@ -2815,7 +2815,10 @@ static int ip6_route_dev_notify(struct nstruct net_device *dev =netdev_notifier_info_to_dev (ptr);struct net *net =dev_net (dev); -if (event ==NETDEV_REGISTER && (dev->flags &IFF_LOOPBACK )) { +if (!(dev->flags &IFF_LOOPBACK )) +return NOTIFY_OK ; + +if (event ==NETDEV_REGISTER ) { net->ipv6.ip6_null_entry->dst.dev = dev; net->ipv6.ip6_null_entry->rt6i_idev =in6_dev_get (dev);#ifdef CONFIG_IPV6_MULTIPLE_TABLES
@@ -2824,6 +2827,12 @@ static int ip6_route_dev_notify(struct n net->ipv6.ip6_blk_hole_entry->dst.dev = dev; net->ipv6.ip6_blk_hole_entry->rt6i_idev =in6_dev_get (dev);#endif + }else if (event ==NETDEV_UNREGISTER ) { +in6_dev_put (net->ipv6.ip6_null_entry->rt6i_idev); +#ifdef CONFIG_IPV6_MULTIPLE_TABLES +in6_dev_put (net->ipv6.ip6_prohibit_entry->rt6i_idev); +in6_dev_put (net->ipv6.ip6_blk_hole_entry->rt6i_idev); +#endif }return NOTIFY_OK ;
@@ -3130,7 +3139,7 @@ static struct pernet_operations ip6_routstatic struct notifier_block ip6_route_dev_notifier = { .notifier_call = ip6_route_dev_notify, - .priority =0 , + .priority =ADDRCONF_NOTIFY_PRIORITY -10 , };void __init ip6_route_init_special_entries (void )
Patches currently in stable-queue which might be from [email protected] are
queue-3.18/ipv6-initialize-route-null-entry-in-addrconf_init.patch queue-3.18/9p-fix-a-potential-acl-leak.patch queue-3.18/ipv6-reorder-ip6_route_dev_notifier-after-ipv6_dev_notf.patch