kernel: backport out-of-memory fix for non-Ethernet devices
[openwrt/openwrt.git] / target / linux / generic / backport-5.4 / 600-ipv6-addrconf-call-ipv6_mc_up-for-non-Ethernet-inter.patch
1 From 82afdcd4ec3c8ca6551cbf7c43c09e2fd240487a Mon Sep 17 00:00:00 2001
2 From: Hangbin Liu <liuhangbin@gmail.com>
3 Date: Tue, 10 Mar 2020 15:27:37 +0800
4 Subject: [PATCH] ipv6/addrconf: call ipv6_mc_up() for non-Ethernet interface
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Rafał found an issue that for non-Ethernet interface, if we down and up
10 frequently, the memory will be consumed slowly.
11
12 The reason is we add allnodes/allrouters addressed in multicast list in
13 ipv6_add_dev(). When link down, we call ipv6_mc_down(), store all multicast
14 addresses via mld_add_delrec(). But when link up, we don't call ipv6_mc_up()
15 for non-Ethernet interface to remove the addresses. This makes idev->mc_tomb
16 getting bigger and bigger. The call stack looks like:
17
18 addrconf_notify(NETDEV_REGISTER)
19 ipv6_add_dev
20 ipv6_dev_mc_inc(ff01::1)
21 ipv6_dev_mc_inc(ff02::1)
22 ipv6_dev_mc_inc(ff02::2)
23
24 addrconf_notify(NETDEV_UP)
25 addrconf_dev_config
26 /* Alas, we support only Ethernet autoconfiguration. */
27 return;
28
29 addrconf_notify(NETDEV_DOWN)
30 addrconf_ifdown
31 ipv6_mc_down
32 igmp6_group_dropped(ff02::2)
33 mld_add_delrec(ff02::2)
34 igmp6_group_dropped(ff02::1)
35 igmp6_group_dropped(ff01::1)
36
37 After investigating, I can't found a rule to disable multicast on
38 non-Ethernet interface. In RFC2460, the link could be Ethernet, PPP, ATM,
39 tunnels, etc. In IPv4, it doesn't check the dev type when calls ip_mc_up()
40 in inetdev_event(). Even for IPv6, we don't check the dev type and call
41 ipv6_add_dev(), ipv6_dev_mc_inc() after register device.
42
43 So I think it's OK to fix this memory consumer by calling ipv6_mc_up() for
44 non-Ethernet interface.
45
46 v2: Also check IFF_MULTICAST flag to make sure the interface supports
47 multicast
48
49 Reported-by: Rafał Miłecki <zajec5@gmail.com>
50 Tested-by: Rafał Miłecki <zajec5@gmail.com>
51 Fixes: 74235a25c673 ("[IPV6] addrconf: Fix IPv6 on tuntap tunnels")
52 Fixes: 1666d49e1d41 ("mld: do not remove mld souce list info when set link down")
53 Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
54 Signed-off-by: David S. Miller <davem@davemloft.net>
55 ---
56 net/ipv6/addrconf.c | 4 ++++
57 1 file changed, 4 insertions(+)
58
59 --- a/net/ipv6/addrconf.c
60 +++ b/net/ipv6/addrconf.c
61 @@ -3345,6 +3345,10 @@ static void addrconf_dev_config(struct n
62 (dev->type != ARPHRD_NONE) &&
63 (dev->type != ARPHRD_RAWIP)) {
64 /* Alas, we support only Ethernet autoconfiguration. */
65 + idev = __in6_dev_get(dev);
66 + if (!IS_ERR_OR_NULL(idev) && dev->flags & IFF_UP &&
67 + dev->flags & IFF_MULTICAST)
68 + ipv6_mc_up(idev);
69 return;
70 }
71