Chas, It's been a while since I've looked at that call path in detail, but if memory serves, when the interface is going down, the thread that is doing the "down" acquires a reference to the in_dev, so nothing in the chain should actually have the last reference-- the in_dev is freed when the last reference is removed in the thread that caused all of it. But there is a bug in starting the timer from igmp_group_dropped() after the ifc timer has been deleted-- I now see your point there. ip_mc_down() clears the list of deleted records that would be reported, but the timer would be started, anyway. Below is a patch that I think might do the trick, for your case, but I need to check on possible races with group drops while doing a down-- if so, it'll need some reworking to handle those. I'm concerned about checking IFF_UP in the same place as it does the all hosts group because a) I'm not sure the flag is cleared at that point and b) I'm not sure in the v2 case if it currently sends (immediately) leave messages that with the check might not be sent. A little investigation would turn up the answers to those, but a patch that doesn't affect existing v2 behaviour (unless it's incorrect :-)) would be better. Meantime, if you get a chance to try this patch, please let me know if it doesn't work. I'll do some testing on my own, but haven't done any yet. +-DLS (in-line for viewing, attached for applying, since my mailer messes with whitespace) *** linux-2.5.73F4/net/ipv4/igmp.c 2003-06-23 13:26:02.000000000 -0700 --- linux-2.5.73F5/net/ipv4/igmp.c 2003-07-07 12:54:57.000000000 -0700 *************** *** 1196,1202 **** --- 1196,1206 ---- ASSERT_RTNL(); + for (i=in_dev->mc_list; i; i=i->next) + igmp_group_dropped(i); + #ifdef CONFIG_IP_MULTICAST + igmpv3_clear_delrec(in_dev); in_dev->mr_ifc_count = 0; if (del_timer(&in_dev->mr_ifc_timer)) __in_dev_put(in_dev); *************** *** 1205,1217 **** __in_dev_put(in_dev); #endif - for (i=in_dev->mc_list; i; i=i->next) - igmp_group_dropped(i); - - #ifdef CONFIG_IP_MULTICAST - igmpv3_clear_delrec(in_dev); - #endif - ip_mc_dec_group(in_dev, IGMP_ALL_HOSTS); } --- 1209,1214 ---- (See attached file: igmp.patch)
Attachment:
igmp.patch
Description: Binary data