linux-stable/net/ipv6
Hangbin Liu 4dcb3398fb ipv6/addrconf: call ipv6_mc_up() for non-Ethernet interface
[ Upstream commit 60380488e4 ]

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 <zajec5@gmail.com>
Tested-by: Rafał Miłecki <zajec5@gmail.com>
Fixes: 74235a25c6 ("[IPV6] addrconf: Fix IPv6 on tuntap tunnels")
Fixes: 1666d49e1d ("mld: do not remove mld souce list info when set link down")
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-03-20 10:54:07 +01:00
..
ila License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
netfilter netfilter: masquerade: don't flush all conntracks if only one address deleted on device 2019-11-20 18:00:52 +01:00
addrconf.c ipv6/addrconf: call ipv6_mc_up() for non-Ethernet interface 2020-03-20 10:54:07 +01:00
addrconf_core.c
addrlabel.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
af_inet6.c ipv6: Consider sk_bound_dev_if when binding a socket to an address 2019-02-06 17:31:31 +01:00
ah6.c
anycast.c
calipso.c ipv6: make ipv6_renew_options() interrupt/kernel safe 2018-08-24 13:09:13 +02:00
datagram.c ip: on queued skb use skb_header_pointer instead of pskb_may_pull 2019-01-23 08:09:47 +01:00
esp6.c esp: Skip TX bytes accounting when sending from a request socket 2019-03-23 14:35:14 +01:00
esp6_offload.c esp: Fix GRO when the headers not fully in the linear part of the skb. 2018-02-25 11:07:46 +01:00
exthdrs.c ipv6: make ipv6_renew_options() interrupt/kernel safe 2018-08-24 13:09:13 +02:00
exthdrs_core.c
exthdrs_offload.c
fib6_notifier.c net: Add module reference to FIB notifiers 2017-09-01 20:33:42 -07:00
fib6_rules.c
fou6.c
icmp.c net/ipv6: Fix linklocal to global address with VRF 2018-07-28 07:55:42 +02:00
inet6_connection_sock.c net: add bool confirm_neigh parameter for dst_ops.update_pmtu 2020-01-04 14:00:14 +01:00
inet6_hashtables.c tcp/dccp: fix possible race __inet_lookup_established() 2020-01-04 14:00:19 +01:00
ip6_checksum.c net: udp: fix handling of CHECKSUM_COMPLETE packets 2018-11-04 14:52:49 +01:00
ip6_fib.c ipv6: Fix route replacement with dev-only route 2020-03-11 18:02:47 +01:00
ip6_flowlabel.c ipv6: flowlabel: fl6_sock_lookup() must use atomic_inc_not_zero 2019-06-22 08:16:14 +02:00
ip6_gre.c ip6_gre: do not confirm neighbor when do pmtu update 2020-01-04 14:00:15 +01:00
ip6_icmp.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ip6_input.c ipv6: drop incoming packets having a v4mapped source address 2019-10-07 18:55:16 +02:00
ip6_offload.c gso_segment: Reset skb->mac_len after modifying network header 2018-09-29 03:06:00 -07:00
ip6_offload.h
ip6_output.c ipv6: Fix dangling pointer when ipv6 fragment 2019-04-17 08:37:45 +02:00
ip6_tunnel.c net, ip6_tunnel: fix namespaces move 2020-01-29 15:02:35 +01:00
ip6_udp_tunnel.c ipv6: explicitly initialize udp6_addr in udp_sock_create6() 2019-01-09 17:14:43 +01:00
ip6_vti.c vti[6]: fix packet tx through bpf_redirect() 2020-02-05 14:18:23 +00:00
ip6mr.c ip6mr: Do not call __IP6_INC_STATS() from preemptible context 2019-03-13 14:03:07 -07:00
ipcomp6.c
ipv6_sockglue.c ipv6: make ipv6_renew_options() interrupt/kernel safe 2018-08-24 13:09:13 +02:00
Kconfig ipv6: ila: select CONFIG_DST_CACHE 2018-07-25 11:25:09 +02:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
mcast.c mld: fix memory leak in mld_del_delrec() 2019-09-10 10:32:21 +01:00
mcast_snoop.c
mip6.c
ndisc.c ipv6/ndisc: Preserve IPv6 control buffer if protocol error handlers are called 2018-11-04 14:52:48 +01:00
netfilter.c netfilter: ipv6: Don't preserve original oif for loopback address 2019-02-27 10:08:08 +01:00
output_core.c inet: switch IP ID generator to siphash 2019-06-09 09:18:10 +02:00
ping.c ipv6: Fix the link time qualifier of 'ping_v6_proc_exit_net()' 2019-09-19 09:08:00 +02:00
proc.c inet: frags: break the 2GB limit for frags storage 2018-09-19 22:43:46 +02:00
protocol.c
raw.c ipv6: use READ_ONCE() for inet->hdrincl as in ipv4 2019-06-11 12:21:46 +02:00
reassembly.c inet: frags: call inet_frags_fini() after unregister_pernet_subsys() 2020-01-27 14:46:36 +01:00
route.c ipv6: Fix nlmsg_flags when splitting a multipath route 2020-03-11 18:02:47 +01:00
seg6.c ipv6: propagate genlmsg_reply return code 2019-02-27 10:08:06 +01:00
seg6_hmac.c ipv6: sr: fix passing wrong flags to crypto_alloc_shash() 2018-07-22 14:28:43 +02:00
seg6_iptunnel.c ipv6: sr: clear IP6CB(skb) on SRH ip4ip6 encapsulation 2019-02-06 17:31:31 +01:00
seg6_local.c ipv6: sr: remove SKB_GSO_IPXIP6 on End.D* actions 2020-01-29 15:02:35 +01:00
sit.c sit: do not confirm neighbor when do pmtu update 2020-01-04 14:00:17 +01:00
syncookies.c
sysctl_net_ipv6.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
tcp_ipv6.c ipv6: Fix handling of LLA with VRF and sockets bound to VRF 2019-12-01 09:14:14 +01:00
tcpv6_offload.c gso: validate gso_type in GSO handlers 2018-01-31 14:03:47 +01:00
tunnel6.c
udp.c net: annotate accesses to sk->sk_incoming_cpu 2019-11-10 11:25:23 +01:00
udp_impl.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
udp_offload.c gso: validate gso_type in GSO handlers 2018-01-31 14:03:47 +01:00
udplite.c
xfrm6_input.c xfrm: reset transport header back to network header after all input transforms ahave been applied 2018-11-04 14:52:37 +01:00
xfrm6_mode_beet.c
xfrm6_mode_ro.c
xfrm6_mode_transport.c xfrm: reset transport header back to network header after all input transforms ahave been applied 2018-11-04 14:52:37 +01:00
xfrm6_mode_tunnel.c
xfrm6_output.c xfrm6: call kfree_skb when skb is toobig 2018-11-04 14:52:37 +01:00
xfrm6_policy.c net: add bool confirm_neigh parameter for dst_ops.update_pmtu 2020-01-04 14:00:14 +01:00
xfrm6_protocol.c
xfrm6_state.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xfrm6_tunnel.c xfrm6_tunnel: Fix potential panic when unloading xfrm6_tunnel module 2019-05-25 18:25:34 +02:00