* unregister_netdevice: waiting for tun6to4 to become free. @ 2004-09-20 21:24 Pekka Pietikainen 2004-09-21 0:59 ` Jeff Garzik 0 siblings, 1 reply; 13+ messages in thread From: Pekka Pietikainen @ 2004-09-20 21:24 UTC (permalink / raw) To: netdev Hiya When trying to do /etc/init.d/network stop (or reboot) my fc3test-all-updated-so-kernel-is-2.6.9-rc2-bk5ish, the thing hangs with a "unregister_netdevice: waiting for tun6to4 to become free. Usage count = 1". The 6to4 tunnel is over the kernel PPPoE tunnel in case that makes a difference What it's trying to do is /sbin/ip tunnel del tun6to4, which works just fine when run by itself, when looking at /proc/net/dev the device is no longer there at that point. I think the situation where it breaks if the ppp device it's running on top of goes down just before. Just a guess tho :-) Any obvious explanations or should I poke further? ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: unregister_netdevice: waiting for tun6to4 to become free. 2004-09-20 21:24 unregister_netdevice: waiting for tun6to4 to become free Pekka Pietikainen @ 2004-09-21 0:59 ` Jeff Garzik 2004-09-21 6:24 ` Andre Tomt 0 siblings, 1 reply; 13+ messages in thread From: Jeff Garzik @ 2004-09-21 0:59 UTC (permalink / raw) To: Pekka Pietikainen; +Cc: netdev Pekka Pietikainen wrote: > Hiya > > When trying to do /etc/init.d/network stop (or reboot) my > fc3test-all-updated-so-kernel-is-2.6.9-rc2-bk5ish, the thing hangs with a > "unregister_netdevice: waiting for tun6to4 to become free. Usage count = 1". > The 6to4 tunnel is over the kernel PPPoE tunnel in case that makes a > difference I hit this _once_ on my gateway (NAT'ing firewall IPv4, now also IPv6 router). No idea why it went away, I just assumed a more recent kernel fixed something. Jeff ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: unregister_netdevice: waiting for tun6to4 to become free. 2004-09-21 0:59 ` Jeff Garzik @ 2004-09-21 6:24 ` Andre Tomt 2004-09-22 12:08 ` David Woodhouse [not found] ` <20040921121332.GR31616@rei.reeler.org> 0 siblings, 2 replies; 13+ messages in thread From: Andre Tomt @ 2004-09-21 6:24 UTC (permalink / raw) To: Jeff Garzik; +Cc: Pekka Pietikainen, netdev Jeff Garzik wrote: > I hit this _once_ on my gateway (NAT'ing firewall IPv4, now also IPv6 > router). > > No idea why it went away, I just assumed a more recent kernel fixed > something. We've been seeing this all the time on 2.6.8.1 + "critical fixes". Pretty much anytime a router with tunneling interfaces is taken down for shutdown or reboot, it hangs spinning waiting for the tunnel devices to get freed, as ifdown gets run. It also happens when ifdown'ing them by themselfes. It's rather annoying, as doing a sysrq-boot is pretty much the only way out. Not good at all on a router :-) I'm having some problems getting this reproduced in the lab setup, but I did get a sysrq-t out of one of the affected production routers: | Sep 18 00:53:36 ed-gw1 kernel: ip S C0350720 0 1725 1723 (NOTLB) | Sep 18 00:53:36 ed-gw1: dd02ceb4 00000082 dd678190 c0350720 0000007c dec44400 dd02c000 e00fddae | Sep 18 00:53:36 ed-gw1 kernel: e25ac5eb 0000007c c14b36f0 00000199 0f055c16 0000007d dd678338 000351bf | Sep 18 00:53:36 ed-gw1 kernel: dd02cec8 dec44400 dd02c000 c026cb73 dd02cec8 000351bf e0038d9c c0356380 | Sep 18 00:53:36 ed-gw1 kernel: Call Trace: | Sep 18 00:53:36 ed-gw1 kernel: [pg0+534273454/1070096384] addrconf_ifdown+0x3e/0x250 [ipv6] | Sep 18 00:53:36 ed-gw1 kernel: [schedule_timeout+99/192] schedule_timeout+0x63/0xc0 | Sep 18 00:53:36 ed-gw1 kernel: [process_timeout+0/16] process_timeout+0x0/0x10 | Sep 18 00:53:36 ed-gw1 kernel: [netdev_wait_allrefs+85/288] netdev_wait_allrefs+0x55/0x120 | Sep 18 00:53:36 ed-gw1 kernel: [netdev_run_todo+237/512] netdev_run_todo+0xed/0x200 | Sep 18 00:53:36 ed-gw1 kernel: [dev_ioctl+438/752] dev_ioctl+0x1b6/0x2f0 | Sep 18 00:53:36 ed-gw1 kernel: [sock_ioctl+544/560] sock_ioctl+0x220/0x230 | Sep 18 00:53:36 ed-gw1 kernel: [sys_ioctl+201/576] sys_ioctl+0xc9/0x240 | Sep 18 00:53:36 ed-gw1 kernel: [sysenter_past_esp+82/113] sysenter_past_esp+0x52/0x71 The tunnel is defined like this in /etc/network/interfaces (Debian Sarge) | auto vid | iface vid inet6 v4tunnel | address 2001:730:f:ffff::11 | netmask 126 | endpoint <remote ip> | local <local ip> | up /sbin/ip -6 route add 2001:730:f:12::/64 dev vid metric 1 | up /sbin/ip -6 tunnel change vid ttl 255 Next time I'm doing anything I'll be sure I run ifdown in verbose mode, but my best guess is it failing at "ip tunnel del %iface%" The kernel does not have NAT and/or connection tracking loaded on this router. Connection tracking is available as modules, but not loaded. NAT is not enabled at all. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: unregister_netdevice: waiting for tun6to4 to become free. 2004-09-21 6:24 ` Andre Tomt @ 2004-09-22 12:08 ` David Woodhouse 2004-09-22 18:15 ` David S. Miller [not found] ` <20040921121332.GR31616@rei.reeler.org> 1 sibling, 1 reply; 13+ messages in thread From: David Woodhouse @ 2004-09-22 12:08 UTC (permalink / raw) To: Andre Tomt; +Cc: Jeff Garzik, Pekka Pietikainen, netdev On Tue, 2004-09-21 at 08:24 +0200, Andre Tomt wrote: > Jeff Garzik wrote: > > I hit this _once_ on my gateway (NAT'ing firewall IPv4, now also IPv6 > > router). > > > > No idea why it went away, I just assumed a more recent kernel fixed > > something. > > We've been seeing this all the time on 2.6.8.1 + "critical fixes". > Pretty much anytime a router with tunneling interfaces is taken down for > shutdown or reboot, it hangs spinning waiting for the tunnel devices to > get freed, as ifdown gets run. It's not just tunnel interfaces. It seems to be related to hot-unplug of interfaces with live IPv6 addresses. I've seen it on my prism54 card too on many recent kernels. All I have to do is insert it and remove it a few times. -- dwmw2 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: unregister_netdevice: waiting for tun6to4 to become free. 2004-09-22 12:08 ` David Woodhouse @ 2004-09-22 18:15 ` David S. Miller 2004-09-23 6:18 ` YOSHIFUJI Hideaki / 吉藤英明 0 siblings, 1 reply; 13+ messages in thread From: David S. Miller @ 2004-09-22 18:15 UTC (permalink / raw) To: David Woodhouse; +Cc: andre, jgarzik, pp, netdev On Wed, 22 Sep 2004 13:08:52 +0100 David Woodhouse <dwmw2@infradead.org> wrote: > On Tue, 2004-09-21 at 08:24 +0200, Andre Tomt wrote: > > Jeff Garzik wrote: > > > I hit this _once_ on my gateway (NAT'ing firewall IPv4, now also IPv6 > > > router). > > > > > > No idea why it went away, I just assumed a more recent kernel fixed > > > something. > > > > We've been seeing this all the time on 2.6.8.1 + "critical fixes". > > Pretty much anytime a router with tunneling interfaces is taken down for > > shutdown or reboot, it hangs spinning waiting for the tunnel devices to > > get freed, as ifdown gets run. > > It's not just tunnel interfaces. It seems to be related to hot-unplug of > interfaces with live IPv6 addresses. I've seen it on my prism54 card too > on many recent kernels. All I have to do is insert it and remove it a > few times. There is code in ipv6 which takes route references to devices and moves that reference over to loopback. There might be bugs in that area, and I would suggest debugging in that area. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: unregister_netdevice: waiting for tun6to4 to become free. 2004-09-22 18:15 ` David S. Miller @ 2004-09-23 6:18 ` YOSHIFUJI Hideaki / 吉藤英明 0 siblings, 0 replies; 13+ messages in thread From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-09-23 6:18 UTC (permalink / raw) To: davem; +Cc: dwmw2, andre, jgarzik, pp, netdev, yoshfuji In article <20040922111544.469dc4c2.davem@davemloft.net> (at Wed, 22 Sep 2004 11:15:44 -0700), "David S. Miller" <davem@davemloft.net> says: > > It's not just tunnel interfaces. It seems to be related to hot-unplug of > > interfaces with live IPv6 addresses. I've seen it on my prism54 card too > > on many recent kernels. All I have to do is insert it and remove it a > > few times. > > There is code in ipv6 which takes route references to devices and moves > that reference over to loopback. There might be bugs in that area, and > I would suggest debugging in that area. Okay, I'll look into it again... --yoshfuji ^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <20040921121332.GR31616@rei.reeler.org>]
[parent not found: <4151E680.80203@tomt.net>]
[parent not found: <20040922211942.GA1674@postel.suug.ch>]
[parent not found: <41523670.1090603@tomt.net>]
[parent not found: <41523EC5.20805@tomt.net>]
* Re: unregister_netdevice: waiting for tun6to4 to become free. [not found] ` <41523EC5.20805@tomt.net> @ 2004-09-23 7:13 ` Andre Tomt 2004-09-23 8:07 ` Andre Tomt 0 siblings, 1 reply; 13+ messages in thread From: Andre Tomt @ 2004-09-23 7:13 UTC (permalink / raw) To: Thomas Graf; +Cc: netdev (CC'ed to netdev) <snip> I can taste the bug now :-) Me and Thomas Graf have been discussing this a bit off-list; so for those on netdev, this is my current setup: server A sets up a sit tunnel to server B. server B has a sit tunnel to Provider. All communication between A, B and Provider is going over ethernet on the physical layer. server B is the one getting stuck in "waiting for <device> to become free.." when ifdown'ing (ip tunnel del) the interface to Provider. If I boot with net.ipv6.conf.default.forward = 1 in sysctl.conf - but then after the boot do echo 1 > /proc/sys/net/ipv6/conf/all/forward (to actually get it running) we'll crash and burn when taking down the interface. Only setting /proc/sys/net/ipv6/conf/all/forward = 1, but never touch default, it goes down cleanly. I have the ipv6/conf/default/forwarding set in sysctl.conf on all the routers, and it seems zebra sets the ipv6/conf/all/forwarding later on. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: unregister_netdevice: waiting for tun6to4 to become free. 2004-09-23 7:13 ` Andre Tomt @ 2004-09-23 8:07 ` Andre Tomt 2004-09-23 8:22 ` YOSHIFUJI Hideaki / 吉藤英明 0 siblings, 1 reply; 13+ messages in thread From: Andre Tomt @ 2004-09-23 8:07 UTC (permalink / raw) To: Thomas Graf; +Cc: netdev Andre Tomt wrote: > (CC'ed to netdev) > > <snip> > > I can taste the bug now :-) > > Me and Thomas Graf have been discussing this a bit off-list; so for > those on netdev, this is my current setup: > > server A sets up a sit tunnel to server B. server B has a sit tunnel to > Provider. All communication between A, B and Provider is going over > ethernet on the physical layer. > > server B is the one getting stuck in "waiting for <device> to become > free.." when ifdown'ing (ip tunnel del) the interface to Provider. > > > If I boot with net.ipv6.conf.default.forward = 1 in sysctl.conf - but > then after the boot do echo 1 > /proc/sys/net/ipv6/conf/all/forward (to > actually get it running) > > we'll crash and burn when taking down the interface. > > Only setting /proc/sys/net/ipv6/conf/all/forward = 1, but never touch > default, it goes down cleanly. > > I have the ipv6/conf/default/forwarding set in sysctl.conf on all the > routers, and it seems zebra sets the ipv6/conf/all/forwarding later on. > Possibly important note: if I set up both conf.all and conf.default (order does not matter) before the tunnel devices are created, everything works as expected. eg. in sysctl.conf: net.ipv6.conf.default.forwarding=1 net.ipv6.conf.all.forwarding=1 if default is set first, then tunnels created, followed by setting "all"; everything breaks down on ifdown. pretty neat :) ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: unregister_netdevice: waiting for tun6to4 to become free. 2004-09-23 8:07 ` Andre Tomt @ 2004-09-23 8:22 ` YOSHIFUJI Hideaki / 吉藤英明 2004-09-24 19:05 ` [PATCH/RFC] PATCH: IPV6: Fix multiple leakages (is Re: unregister_netdevice: waiting for tun6to4 to become free.) YOSHIFUJI Hideaki / 吉藤英明 2004-12-16 0:32 ` unregister_netdevice: waiting for tun6to4 to become free Pekka Pietikainen 0 siblings, 2 replies; 13+ messages in thread From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-09-23 8:22 UTC (permalink / raw) To: andre, tgraf, pp, jgarzik, dwmw2; +Cc: netdev, yoshfuji, davem In article <4152843D.6010204@tomt.net> (at Thu, 23 Sep 2004 10:07:25 +0200), Andre Tomt <andre@tomt.net> says: > > If I boot with net.ipv6.conf.default.forward = 1 in sysctl.conf - but > > then after the boot do echo 1 > /proc/sys/net/ipv6/conf/all/forward (to > > actually get it running) > > > > we'll crash and burn when taking down the interface. > > > > Only setting /proc/sys/net/ipv6/conf/all/forward = 1, but never touch > > default, it goes down cleanly. > > > > I have the ipv6/conf/default/forwarding set in sysctl.conf on all the > > routers, and it seems zebra sets the ipv6/conf/all/forwarding later on. > > > > Possibly important note: > > if I set up both conf.all and conf.default (order does not matter) > before the tunnel devices are created, everything works as expected. > > eg. in sysctl.conf: > net.ipv6.conf.default.forwarding=1 > net.ipv6.conf.all.forwarding=1 > > if default is set first, then tunnels created, followed by setting > "all"; everything breaks down on ifdown. > > pretty neat :) Thank you everyone for tracking down this bug. I will fix this bug and come up with patch tomorrow (or so). Thanks again. -- Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org> GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH/RFC] PATCH: IPV6: Fix multiple leakages (is Re: unregister_netdevice: waiting for tun6to4 to become free.) 2004-09-23 8:22 ` YOSHIFUJI Hideaki / 吉藤英明 @ 2004-09-24 19:05 ` YOSHIFUJI Hideaki / 吉藤英明 2004-09-24 20:51 ` Andre Tomt 2004-09-27 19:23 ` David S. Miller 2004-12-16 0:32 ` unregister_netdevice: waiting for tun6to4 to become free Pekka Pietikainen 1 sibling, 2 replies; 13+ messages in thread From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-09-24 19:05 UTC (permalink / raw) To: davem; +Cc: andre, tgraf, pp, jgarzik, dwmw2, netdev, yoshfuji Hello. In article <20040923.172253.125681726.yoshfuji@linux-ipv6.org> (at Thu, 23 Sep 2004 17:22:53 +0900 (JST)), YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org> says: > Thank you everyone for tracking down this bug. > I will fix this bug and come up with patch tomorrow (or so). Well, I've created changesets which should fix multiple leakages. Here's the snapshot. Please review. Also available at: <bk://bk.skbuff.net:20609/linux-2.6-refcnt/>. Thanks. HEADLINES --------- ChangeSet@1.2005, 2004-09-24 15:54:32+09:00, yoshfuji@linux-ipv6.org [IPV6] Fix device multicast list leakage when forwarding is on. ChangeSet@1.2006, 2004-09-24 16:29:02+09:00, yoshfuji@linux-ipv6.org [IPV6] Don't multiply join multicast/anycast addresses. ChangeSet@1.2007, 2004-09-24 17:19:13+09:00, yoshfuji@linux-ipv6.org [IPV6] Save number of arguments for __ipv6_dev_mc_dev(). ChangeSet@1.2008, 2004-09-24 17:30:22+09:00, yoshfuji@linux-ipv6.org [IPV6] use __ipv6_dev_mc_dec() where appropriate. ChangeSet@1.2009, 2004-09-24 20:39:28+09:00, yoshfuji@linux-ipv6.org [IPV6] leave solicited-node multicast address during device deletion. ChangeSet@1.2010, 2004-09-24 20:49:10+09:00, yoshfuji@linux-ipv6.org [IPV6] leave subnet-routers anycast address during device deletion. ChangeSet@1.2011, 2004-09-24 20:56:13+09:00, yoshfuji@linux-ipv6.org [IPV6] Clean up anycast membership management. CHANGESETS ---------- ChangeSet@1.2005, 2004-09-24 15:54:32+09:00, yoshfuji@linux-ipv6.org [IPV6] Fix device multicast list leakage when forwarding is on. We failed to leave all-routers multicast address. Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> diff -Nru a/net/ipv6/mcast.c b/net/ipv6/mcast.c --- a/net/ipv6/mcast.c 2004-09-24 20:57:13 +09:00 +++ b/net/ipv6/mcast.c 2004-09-24 20:57:13 +09:00 @@ -2110,6 +2110,11 @@ */ __ipv6_dev_mc_dec(idev->dev, idev, &maddr); + if (idev->cnf.forwarding) { + ipv6_addr_all_routers(&maddr); + __ipv6_dev_mc_dec(idev->dev, idev, &maddr); + } + write_lock_bh(&idev->lock); while ((i = idev->mc_list) != NULL) { idev->mc_list = i->next; ChangeSet@1.2006, 2004-09-24 16:29:02+09:00, yoshfuji@linux-ipv6.org [IPV6] Don't multiply join multicast/anycast addresses. Case 1: if net.ipv6.conf.IFACE.forwarding has been set to 1, we multiply join routers' multicast/anycast addresses by setting net.ipv6.conf.all.forwarding to 1. Noticed by Andre Tomt <andre@tomt.net>. Case 2: if we change net.ipv6.conf.FOO.forwarding from 1 to 2, we multiply join routers' multicast/anycast addresses. Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> diff -Nru a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c --- a/net/ipv6/addrconf.c 2004-09-24 20:57:16 +09:00 +++ b/net/ipv6/addrconf.c 2004-09-24 20:57:16 +09:00 @@ -430,22 +430,20 @@ } -static void addrconf_forward_change(struct inet6_dev *idev) +static void addrconf_forward_change(void) { struct net_device *dev; - - if (idev) { - dev_forward_change(idev); - return; - } + struct inet6_dev *idev; read_lock(&dev_base_lock); for (dev=dev_base; dev; dev=dev->next) { read_lock(&addrconf_lock); idev = __in6_dev_get(dev); if (idev) { + int changed = (!idev->cnf.forwarding) ^ (!ipv6_devconf.forwarding); idev->cnf.forwarding = ipv6_devconf.forwarding; - dev_forward_change(idev); + if (changed) + dev_forward_change(idev); } read_unlock(&addrconf_lock); } @@ -3025,18 +3023,18 @@ ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); - if (write && *valp != val && valp != &ipv6_devconf_dflt.forwarding) { - struct inet6_dev *idev = NULL; - + if (write && valp != &ipv6_devconf_dflt.forwarding) { if (valp != &ipv6_devconf.forwarding) { - idev = (struct inet6_dev *)ctl->extra1; - if (idev == NULL) - return ret; - } else + if ((!*valp) ^ (!val)) { + struct inet6_dev *idev = (struct inet6_dev *)ctl->extra1; + if (idev == NULL) + return ret; + dev_forward_change(idev); + } + } else { ipv6_devconf_dflt.forwarding = ipv6_devconf.forwarding; - - addrconf_forward_change(idev); - + addrconf_forward_change(); + } if (*valp) rt6_purge_dflt_routers(0); } @@ -3077,15 +3075,19 @@ } if (valp != &ipv6_devconf_dflt.forwarding) { - struct inet6_dev *idev; if (valp != &ipv6_devconf.forwarding) { - idev = (struct inet6_dev *)table->extra1; + struct inet6_dev *idev = (struct inet6_dev *)table->extra1; + int changed; if (unlikely(idev == NULL)) return -ENODEV; - } else - idev = NULL; - *valp = new; - addrconf_forward_change(idev); + changed = (!*valp) ^ (!new); + *valp = new; + if (changed) + dev_forward_change(idev); + } else { + *valp = new; + addrconf_forward_change(); + } if (*valp) rt6_purge_dflt_routers(0); ChangeSet@1.2007, 2004-09-24 17:19:13+09:00, yoshfuji@linux-ipv6.org [IPV6] Save number of arguments for __ipv6_dev_mc_dev(). dev is unused in the function. Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> diff -Nru a/net/ipv6/mcast.c b/net/ipv6/mcast.c --- a/net/ipv6/mcast.c 2004-09-24 20:57:19 +09:00 +++ b/net/ipv6/mcast.c 2004-09-24 20:57:19 +09:00 @@ -870,7 +870,7 @@ /* * device multicast group del */ -static int __ipv6_dev_mc_dec(struct net_device *dev, struct inet6_dev *idev, struct in6_addr *addr) +static int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr) { struct ifmcaddr6 *ma, **map; @@ -903,7 +903,7 @@ if (!idev) return -ENODEV; - err = __ipv6_dev_mc_dec(dev, idev, addr); + err = __ipv6_dev_mc_dec(idev, addr); in6_dev_put(idev); @@ -2108,11 +2108,11 @@ * addrconf.c has NULL'd out dev->ip6_ptr so in6_dev_get() will * fail. */ - __ipv6_dev_mc_dec(idev->dev, idev, &maddr); + __ipv6_dev_mc_dec(idev, &maddr); if (idev->cnf.forwarding) { ipv6_addr_all_routers(&maddr); - __ipv6_dev_mc_dec(idev->dev, idev, &maddr); + __ipv6_dev_mc_dec(idev, &maddr); } write_lock_bh(&idev->lock); ChangeSet@1.2008, 2004-09-24 17:30:22+09:00, yoshfuji@linux-ipv6.org [IPV6] use __ipv6_dev_mc_dec() where appropriate. Use __ipv6_dev_mc_dec() instead where the caller knows idev. Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> diff -Nru a/net/ipv6/mcast.c b/net/ipv6/mcast.c --- a/net/ipv6/mcast.c 2004-09-24 20:57:22 +09:00 +++ b/net/ipv6/mcast.c 2004-09-24 20:57:22 +09:00 @@ -128,6 +128,8 @@ static struct socket *igmp6_socket; +static int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr); + static void igmp6_join_group(struct ifmcaddr6 *ma); static void igmp6_leave_group(struct ifmcaddr6 *ma); static void igmp6_timer_handler(unsigned long data); @@ -256,9 +258,9 @@ if (idev) { (void) ip6_mc_leave_src(sk,mc_lst,idev); + __ipv6_dev_mc_dec(idev, &mc_lst->addr); in6_dev_put(idev); } - ipv6_dev_mc_dec(dev, &mc_lst->addr); dev_put(dev); } sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); @@ -322,9 +324,9 @@ if (idev) { (void) ip6_mc_leave_src(sk, mc_lst, idev); + __ipv6_dev_mc_dec(idev, &mc_lst->addr); in6_dev_put(idev); } - ipv6_dev_mc_dec(dev, &mc_lst->addr); dev_put(dev); } ChangeSet@1.2009, 2004-09-24 20:39:28+09:00, yoshfuji@linux-ipv6.org [IPV6] leave solicited-node multicast address during device deletion. Because in6_dev_get() fails during device deletion, we failed to leave solicited-node multicast address. Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> diff -Nru a/include/net/addrconf.h b/include/net/addrconf.h --- a/include/net/addrconf.h 2004-09-24 20:57:26 +09:00 +++ b/include/net/addrconf.h 2004-09-24 20:57:26 +09:00 @@ -74,7 +74,7 @@ const struct sock *sk2); extern void addrconf_join_solict(struct net_device *dev, struct in6_addr *addr); -extern void addrconf_leave_solict(struct net_device *dev, +extern void addrconf_leave_solict(struct inet6_dev *idev, struct in6_addr *addr); /* @@ -89,6 +89,7 @@ struct in6_addr *src_addr); extern int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr); +extern int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr); extern int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr); extern void ipv6_mc_up(struct inet6_dev *idev); extern void ipv6_mc_down(struct inet6_dev *idev); diff -Nru a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c --- a/net/ipv6/addrconf.c 2004-09-24 20:57:26 +09:00 +++ b/net/ipv6/addrconf.c 2004-09-24 20:57:26 +09:00 @@ -1060,15 +1060,15 @@ ipv6_dev_mc_inc(dev, &maddr); } -void addrconf_leave_solict(struct net_device *dev, struct in6_addr *addr) +void addrconf_leave_solict(struct inet6_dev *idev, struct in6_addr *addr) { struct in6_addr maddr; - if (dev->flags&(IFF_LOOPBACK|IFF_NOARP)) + if (idev->dev->flags&(IFF_LOOPBACK|IFF_NOARP)) return; addrconf_addr_solict_mult(addr, &maddr); - ipv6_dev_mc_dec(dev, &maddr); + __ipv6_dev_mc_dec(idev, &maddr); } @@ -2994,7 +2994,7 @@ dst_release(&ifp->rt->u.dst); break; case RTM_DELADDR: - addrconf_leave_solict(ifp->idev->dev, &ifp->addr); + addrconf_leave_solict(ifp->idev, &ifp->addr); if (ifp->idev->cnf.forwarding) { struct in6_addr addr; diff -Nru a/net/ipv6/anycast.c b/net/ipv6/anycast.c --- a/net/ipv6/anycast.c 2004-09-24 20:57:26 +09:00 +++ b/net/ipv6/anycast.c 2004-09-24 20:57:26 +09:00 @@ -408,7 +408,7 @@ else idev->ac_list = aca->aca_next; write_unlock_bh(&idev->lock); - addrconf_leave_solict(dev, &aca->aca_addr); + addrconf_leave_solict(idev, &aca->aca_addr); dst_hold(&aca->aca_rt->u.dst); if (ip6_del_rt(aca->aca_rt, NULL, NULL)) diff -Nru a/net/ipv6/mcast.c b/net/ipv6/mcast.c --- a/net/ipv6/mcast.c 2004-09-24 20:57:26 +09:00 +++ b/net/ipv6/mcast.c 2004-09-24 20:57:26 +09:00 @@ -128,7 +128,7 @@ static struct socket *igmp6_socket; -static int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr); +int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr); static void igmp6_join_group(struct ifmcaddr6 *ma); static void igmp6_leave_group(struct ifmcaddr6 *ma); @@ -872,7 +872,7 @@ /* * device multicast group del */ -static int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr) +int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr) { struct ifmcaddr6 *ma, **map; ChangeSet@1.2010, 2004-09-24 20:49:10+09:00, yoshfuji@linux-ipv6.org [IPV6] leave subnet-routers anycast address during device deletion. Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> diff -Nru a/include/net/addrconf.h b/include/net/addrconf.h --- a/include/net/addrconf.h 2004-09-24 20:57:29 +09:00 +++ b/include/net/addrconf.h 2004-09-24 20:57:29 +09:00 @@ -112,6 +112,7 @@ extern int inet6_ac_check(struct sock *sk, struct in6_addr *addr, int ifindex); extern int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr); +extern int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr); extern int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr); extern int ipv6_chk_acast_addr(struct net_device *dev, struct in6_addr *addr); diff -Nru a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c --- a/net/ipv6/addrconf.c 2004-09-24 20:57:29 +09:00 +++ b/net/ipv6/addrconf.c 2004-09-24 20:57:29 +09:00 @@ -3000,7 +3000,7 @@ ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); if (!ipv6_addr_any(&addr)) - ipv6_dev_ac_dec(ifp->idev->dev, &addr); + __ipv6_dev_ac_dec(ifp->idev, &addr); } dst_hold(&ifp->rt->u.dst); if (ip6_del_rt(ifp->rt, NULL, NULL)) diff -Nru a/net/ipv6/anycast.c b/net/ipv6/anycast.c --- a/net/ipv6/anycast.c 2004-09-24 20:57:29 +09:00 +++ b/net/ipv6/anycast.c 2004-09-24 20:57:29 +09:00 @@ -377,15 +377,10 @@ /* * device anycast group decrement */ -int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr) +int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr) { - struct inet6_dev *idev; struct ifacaddr6 *aca, *prev_aca; - idev = in6_dev_get(dev); - if (idev == NULL) - return -ENODEV; - write_lock_bh(&idev->lock); prev_aca = NULL; for (aca = idev->ac_list; aca; aca = aca->aca_next) { @@ -395,12 +390,10 @@ } if (!aca) { write_unlock_bh(&idev->lock); - in6_dev_put(idev); return -ENOENT; } if (--aca->aca_users > 0) { write_unlock_bh(&idev->lock); - in6_dev_put(idev); return 0; } if (prev_aca) @@ -417,10 +410,20 @@ dst_release(&aca->aca_rt->u.dst); aca_put(aca); - in6_dev_put(idev); return 0; } +int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr) +{ + int ret; + struct inet6_dev *idev = in6_dev_get(dev); + if (idev == NULL) + return -ENODEV; + ret = __ipv6_dev_ac_dec(idev, addr); + in6_dev_put(idev); + return ret; +} + /* * check if the interface has this anycast address */ ChangeSet@1.2011, 2004-09-24 20:56:13+09:00, yoshfuji@linux-ipv6.org [IPV6] Clean up anycast membership management. Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> diff -Nru a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c --- a/net/ipv6/addrconf.c 2004-09-24 20:57:32 +09:00 +++ b/net/ipv6/addrconf.c 2004-09-24 20:57:32 +09:00 @@ -128,6 +128,9 @@ TIMER_INITIALIZER(addrconf_verify, 0, 0); static spinlock_t addrconf_verify_lock = SPIN_LOCK_UNLOCKED; +static void addrconf_join_anycast(struct inet6_ifaddr *ifp); +static void addrconf_leave_anycast(struct inet6_ifaddr *ifp); + static int addrconf_ifdown(struct net_device *dev, int how); static void addrconf_dad_start(struct inet6_ifaddr *ifp, int flags); @@ -419,13 +422,10 @@ ipv6_dev_mc_dec(dev, &addr); } for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) { - ipv6_addr_prefix(&addr, &ifa->addr, ifa->prefix_len); - if (ipv6_addr_any(&addr)) - continue; if (idev->cnf.forwarding) - ipv6_dev_ac_inc(idev->dev, &addr); + addrconf_join_anycast(ifa); else - ipv6_dev_ac_dec(idev->dev, &addr); + addrconf_leave_anycast(ifa); } } @@ -1071,6 +1071,23 @@ __ipv6_dev_mc_dec(idev, &maddr); } +void addrconf_join_anycast(struct inet6_ifaddr *ifp) +{ + struct in6_addr addr; + ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); + if (ipv6_addr_any(&addr)) + return; + ipv6_dev_ac_inc(ifp->idev->dev, &addr); +} + +void addrconf_leave_anycast(struct inet6_ifaddr *ifp) +{ + struct in6_addr addr; + ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); + if (ipv6_addr_any(&addr)) + return; + __ipv6_dev_ac_dec(ifp->idev, &addr); +} static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) { @@ -2223,14 +2240,6 @@ addrconf_mod_timer(ifp, AC_RS, ifp->idev->cnf.rtr_solicit_interval); spin_unlock_bh(&ifp->lock); } - - if (ifp->idev->cnf.forwarding) { - struct in6_addr addr; - - ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); - if (!ipv6_addr_any(&addr)) - ipv6_dev_ac_inc(ifp->idev->dev, &addr); - } } #ifdef CONFIG_PROC_FS @@ -2992,16 +3001,13 @@ dst_hold(&ifp->rt->u.dst); if (ip6_ins_rt(ifp->rt, NULL, NULL)) dst_release(&ifp->rt->u.dst); + if (ifp->idev->cnf.forwarding) + addrconf_join_anycast(ifp); break; case RTM_DELADDR: + if (ifp->idev->cnf.forwarding) + addrconf_leave_anycast(ifp); addrconf_leave_solict(ifp->idev, &ifp->addr); - if (ifp->idev->cnf.forwarding) { - struct in6_addr addr; - - ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); - if (!ipv6_addr_any(&addr)) - __ipv6_dev_ac_dec(ifp->idev, &addr); - } dst_hold(&ifp->rt->u.dst); if (ip6_del_rt(ifp->rt, NULL, NULL)) dst_free(&ifp->rt->u.dst); -- Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org> GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH/RFC] PATCH: IPV6: Fix multiple leakages (is Re: unregister_netdevice: waiting for tun6to4 to become free.) 2004-09-24 19:05 ` [PATCH/RFC] PATCH: IPV6: Fix multiple leakages (is Re: unregister_netdevice: waiting for tun6to4 to become free.) YOSHIFUJI Hideaki / 吉藤英明 @ 2004-09-24 20:51 ` Andre Tomt 2004-09-27 19:23 ` David S. Miller 1 sibling, 0 replies; 13+ messages in thread From: Andre Tomt @ 2004-09-24 20:51 UTC (permalink / raw) To: YOSHIFUJI Hideaki / 吉藤英明 Cc: davem, tgraf, pp, jgarzik, dwmw2, netdev YOSHIFUJI Hideaki / 吉藤英明 wrote: >>Thank you everyone for tracking down this bug. >>I will fix this bug and come up with patch tomorrow (or so). > > Well, I've created changesets which should fix multiple leakages. > Here's the snapshot. Please review. I applied the following set to my internal 2.6.8.1 tree; > ChangeSet@1.2006, 2004-09-24 16:29:02+09:00, yoshfuji@linux-ipv6.org > [IPV6] Don't multiply join multicast/anycast addresses. It fixed my problem, thanks :-) Unless someone convinces me it has ill-effects with whats in the 2.6.8.1 ipv6 stack, it will probably go out in a router upgrade push some late night this weekend. -- André Tomt ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH/RFC] PATCH: IPV6: Fix multiple leakages (is Re: unregister_netdevice: waiting for tun6to4 to become free.) 2004-09-24 19:05 ` [PATCH/RFC] PATCH: IPV6: Fix multiple leakages (is Re: unregister_netdevice: waiting for tun6to4 to become free.) YOSHIFUJI Hideaki / 吉藤英明 2004-09-24 20:51 ` Andre Tomt @ 2004-09-27 19:23 ` David S. Miller 1 sibling, 0 replies; 13+ messages in thread From: David S. Miller @ 2004-09-27 19:23 UTC (permalink / raw) To: yoshfuji; +Cc: andre, tgraf, pp, jgarzik, dwmw2, netdev, yoshfuji On Sat, 25 Sep 2004 04:05:06 +0900 (JST) YOSHIFUJI Hideaki / ^[$B5HF#1QL@^[(B <yoshfuji@linux-ipv6.org> wrote: > bk://bk.skbuff.net:20609/linux-2.6-refcnt/ These changes look fine. Pulled, thank you Yoshifuji. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: unregister_netdevice: waiting for tun6to4 to become free. 2004-09-23 8:22 ` YOSHIFUJI Hideaki / 吉藤英明 2004-09-24 19:05 ` [PATCH/RFC] PATCH: IPV6: Fix multiple leakages (is Re: unregister_netdevice: waiting for tun6to4 to become free.) YOSHIFUJI Hideaki / 吉藤英明 @ 2004-12-16 0:32 ` Pekka Pietikainen 1 sibling, 0 replies; 13+ messages in thread From: Pekka Pietikainen @ 2004-12-16 0:32 UTC (permalink / raw) To: YOSHIFUJI Hideaki / ?$B5HF#1QL@; +Cc: netdev On Thu, Sep 23, 2004 at 05:22:53PM +0900, YOSHIFUJI Hideaki / ?$B5HF#1QL@ wrote: > > > If I boot with net.ipv6.conf.default.forward = 1 in sysctl.conf - but > > > then after the boot do echo 1 > /proc/sys/net/ipv6/conf/all/forward (to > > > actually get it running) > > > I have the ipv6/conf/default/forwarding set in sysctl.conf on all the > > > routers, and it seems zebra sets the ipv6/conf/all/forwarding later on. > > if default is set first, then tunnels created, followed by setting > > "all"; everything breaks down on ifdown. > > > > pretty neat :) > > Thank you everyone for tracking down this bug. > I will fix this bug and come up with patch tomorrow (or so). > Thanks again. Hiya There seems to be a regression, I've recently bumped into this bug again. (2.6.9-fc3-latest-thing, I didn't see anything relevant in latest Linus bk). It did work for some time ago, since them my ipv6 configuration has changed and I've updated the kernel quite a bit. if [ "$device" != "sit0" ]; then if ipv6_exec_ip tunnel show $device 2>/dev/null | LC_ALL=C grep -q -w "ipv6/ip"; then ipv6_exec_ip tunnel del $device is what triggers it, tunnel del gets stuck with a refcnt of 1, device is no longer in /proc/net/dev. Tunnel is run on top of PPPoE and it's a dynamic sixxs.net aiccu thing. IPv6 forwarding is on. http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=282023 seems to be related too. ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2004-12-16 0:32 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-09-20 21:24 unregister_netdevice: waiting for tun6to4 to become free Pekka Pietikainen
2004-09-21 0:59 ` Jeff Garzik
2004-09-21 6:24 ` Andre Tomt
2004-09-22 12:08 ` David Woodhouse
2004-09-22 18:15 ` David S. Miller
2004-09-23 6:18 ` YOSHIFUJI Hideaki / 吉藤英明
[not found] ` <20040921121332.GR31616@rei.reeler.org>
[not found] ` <4151E680.80203@tomt.net>
[not found] ` <20040922211942.GA1674@postel.suug.ch>
[not found] ` <41523670.1090603@tomt.net>
[not found] ` <41523EC5.20805@tomt.net>
2004-09-23 7:13 ` Andre Tomt
2004-09-23 8:07 ` Andre Tomt
2004-09-23 8:22 ` YOSHIFUJI Hideaki / 吉藤英明
2004-09-24 19:05 ` [PATCH/RFC] PATCH: IPV6: Fix multiple leakages (is Re: unregister_netdevice: waiting for tun6to4 to become free.) YOSHIFUJI Hideaki / 吉藤英明
2004-09-24 20:51 ` Andre Tomt
2004-09-27 19:23 ` David S. Miller
2004-12-16 0:32 ` unregister_netdevice: waiting for tun6to4 to become free Pekka Pietikainen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).