Message ID | 1492802839-16851-1-git-send-email-xiyou.wangcong@gmail.com |
---|---|
State | Not Applicable, archived |
Delegated to: | David Miller |
Headers | show |
On 21/04/17 22:27, Cong Wang wrote: > If we unregister the pim6reg device via default_device_exit_batch(), > we will receive a notification and ip6mr_device_event() will > unregister it again. This causes a kernel BUG at net/core/dev.c:6813. > > Like commit 7dc00c82cbb0 ("ipv4: Fix ipmr unregister device oops") > we should avoid double-unregister in netdevice notifier. > > Reported-by: Andrey Konovalov <andreyknvl@google.com> > Cc: Linus Torvalds <torvalds@linux-foundation.org> > Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> > --- > net/ipv6/ip6mr.c | 11 ++++++----- > 1 file changed, 6 insertions(+), 5 deletions(-) > Cong, Please read the full thread, I've already provided a fix which is similar. https://patchwork.ozlabs.org/patch/753531/ Thanks, Nik
On Fri, Apr 21, 2017 at 12:34 PM, Nikolay Aleksandrov <nikolay@cumulusnetworks.com> wrote: > On 21/04/17 22:27, Cong Wang wrote: >> If we unregister the pim6reg device via default_device_exit_batch(), >> we will receive a notification and ip6mr_device_event() will >> unregister it again. This causes a kernel BUG at net/core/dev.c:6813. >> >> Like commit 7dc00c82cbb0 ("ipv4: Fix ipmr unregister device oops") >> we should avoid double-unregister in netdevice notifier. >> >> Reported-by: Andrey Konovalov <andreyknvl@google.com> >> Cc: Linus Torvalds <torvalds@linux-foundation.org> >> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> >> --- >> net/ipv6/ip6mr.c | 11 ++++++----- >> 1 file changed, 6 insertions(+), 5 deletions(-) >> > > Cong, > Please read the full thread, I've already provided a fix which is similar. > https://patchwork.ozlabs.org/patch/753531/ You beat me on that. ;) You should leave a reply to Andrey's report otherwise people could miss it.
On 21/04/17 23:20, Cong Wang wrote: > On Fri, Apr 21, 2017 at 12:34 PM, Nikolay Aleksandrov > <nikolay@cumulusnetworks.com> wrote: >> On 21/04/17 22:27, Cong Wang wrote: >>> If we unregister the pim6reg device via default_device_exit_batch(), >>> we will receive a notification and ip6mr_device_event() will >>> unregister it again. This causes a kernel BUG at net/core/dev.c:6813. >>> >>> Like commit 7dc00c82cbb0 ("ipv4: Fix ipmr unregister device oops") >>> we should avoid double-unregister in netdevice notifier. >>> >>> Reported-by: Andrey Konovalov <andreyknvl@google.com> >>> Cc: Linus Torvalds <torvalds@linux-foundation.org> >>> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> >>> --- >>> net/ipv6/ip6mr.c | 11 ++++++----- >>> 1 file changed, 6 insertions(+), 5 deletions(-) >>> >> >> Cong, >> Please read the full thread, I've already provided a fix which is similar. >> https://patchwork.ozlabs.org/patch/753531/ > > You beat me on that. ;) You should leave a reply to Andrey's report > otherwise people could miss it. > The patch was sent as a reply to the original report. :-)
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 6ba6c90..72bee6d 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -774,7 +774,8 @@ static struct net_device *ip6mr_reg_vif(struct net *net, struct mr6_table *mrt) * Delete a VIF entry */ -static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head) +static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head, + bool unreg) { struct mif_device *v; struct net_device *dev; @@ -820,7 +821,7 @@ static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head) dev->ifindex, &in6_dev->cnf); } - if (v->flags & MIFF_REGISTER) + if ((v->flags & MIFF_REGISTER) && unreg) unregister_netdevice_queue(dev, head); dev_put(dev); @@ -1340,7 +1341,7 @@ static int ip6mr_device_event(struct notifier_block *this, v = &mrt->vif6_table[0]; for (ct = 0; ct < mrt->maxvif; ct++, v++) { if (v->dev == dev) - mif6_delete(mrt, ct, &list); + mif6_delete(mrt, ct, &list, false); } } unregister_netdevice_many(&list); @@ -1552,7 +1553,7 @@ static void mroute_clean_tables(struct mr6_table *mrt, bool all) for (i = 0; i < mrt->maxvif; i++) { if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC)) continue; - mif6_delete(mrt, i, &list); + mif6_delete(mrt, i, &list, true); } unregister_netdevice_many(&list); @@ -1707,7 +1708,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns if (copy_from_user(&mifi, optval, sizeof(mifi_t))) return -EFAULT; rtnl_lock(); - ret = mif6_delete(mrt, mifi, NULL); + ret = mif6_delete(mrt, mifi, NULL, true); rtnl_unlock(); return ret;
If we unregister the pim6reg device via default_device_exit_batch(), we will receive a notification and ip6mr_device_event() will unregister it again. This causes a kernel BUG at net/core/dev.c:6813. Like commit 7dc00c82cbb0 ("ipv4: Fix ipmr unregister device oops") we should avoid double-unregister in netdevice notifier. Reported-by: Andrey Konovalov <andreyknvl@google.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> --- net/ipv6/ip6mr.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)