Skip to content

Commit 6038048

Browse files
liuhangbindavem330
authored andcommitted
ipv6/addrconf: call ipv6_mc_up() for non-Ethernet interface
Rafał found an issue that for non-Ethernet interface, if we down and up frequently, the memory will be consumed slowly. The reason is we add allnodes/allrouters addressed in multicast list in ipv6_add_dev(). When link down, we call ipv6_mc_down(), store all multicast addresses via mld_add_delrec(). But when link up, we don't call ipv6_mc_up() for non-Ethernet interface to remove the addresses. This makes idev->mc_tomb getting bigger and bigger. The call stack looks like: addrconf_notify(NETDEV_REGISTER) ipv6_add_dev ipv6_dev_mc_inc(ff01::1) ipv6_dev_mc_inc(ff02::1) ipv6_dev_mc_inc(ff02::2) addrconf_notify(NETDEV_UP) addrconf_dev_config /* Alas, we support only Ethernet autoconfiguration. */ return; addrconf_notify(NETDEV_DOWN) addrconf_ifdown ipv6_mc_down igmp6_group_dropped(ff02::2) mld_add_delrec(ff02::2) igmp6_group_dropped(ff02::1) igmp6_group_dropped(ff01::1) After investigating, I can't found a rule to disable multicast on non-Ethernet interface. In RFC2460, the link could be Ethernet, PPP, ATM, tunnels, etc. In IPv4, it doesn't check the dev type when calls ip_mc_up() in inetdev_event(). Even for IPv6, we don't check the dev type and call ipv6_add_dev(), ipv6_dev_mc_inc() after register device. So I think it's OK to fix this memory consumer by calling ipv6_mc_up() for non-Ethernet interface. v2: Also check IFF_MULTICAST flag to make sure the interface supports multicast Reported-by: Rafał Miłecki <[email protected]> Tested-by: Rafał Miłecki <[email protected]> Fixes: 74235a2 ("[IPV6] addrconf: Fix IPv6 on tuntap tunnels") Fixes: 1666d49 ("mld: do not remove mld souce list info when set link down") Signed-off-by: Hangbin Liu <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d752a49 commit 6038048

File tree

1 file changed

+4
-0
lines changed

1 file changed

+4
-0
lines changed

net/ipv6/addrconf.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3347,6 +3347,10 @@ static void addrconf_dev_config(struct net_device *dev)
33473347
(dev->type != ARPHRD_NONE) &&
33483348
(dev->type != ARPHRD_RAWIP)) {
33493349
/* Alas, we support only Ethernet autoconfiguration. */
3350+
idev = __in6_dev_get(dev);
3351+
if (!IS_ERR_OR_NULL(idev) && dev->flags & IFF_UP &&
3352+
dev->flags & IFF_MULTICAST)
3353+
ipv6_mc_up(idev);
33503354
return;
33513355
}
33523356

0 commit comments

Comments
 (0)