diff options
author | Eric Dumazet <edumazet@google.com> | 2015-07-29 12:01:41 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-07-29 23:01:39 -0700 |
commit | c8507fb235bea3314a02a67ddda0d4e6cf01fa78 (patch) | |
tree | 72614a517252c75efc1b8e3b1803cb6cc395c92c /net | |
parent | b2428f94f4f79cc6045e538ed3e8329b16711712 (diff) | |
download | linux-stable-c8507fb235bea3314a02a67ddda0d4e6cf01fa78.tar.gz linux-stable-c8507fb235bea3314a02a67ddda0d4e6cf01fa78.tar.bz2 linux-stable-c8507fb235bea3314a02a67ddda0d4e6cf01fa78.zip |
ipv6: flush nd cache on IFF_NOARP change
This patch is the IPv6 equivalent of commit
6c8b4e3ff81b ("arp: flush arp cache on IFF_NOARP change")
Without it, we keep buggy neighbours in the cache, with destination
MAC address equal to our own MAC address.
Tested:
tcpdump -i eth0 -s 0 ip6 -n -e &
ip link set dev eth0 arp off
ping6 remote // sends buggy frames
ip link set dev eth0 arp on
ping6 remote // should work once kernel is patched
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Mario Fanelli <mariofanelli@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv6/ndisc.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 0a05b35a90fc..c53331cfed95 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1650,6 +1650,7 @@ int ndisc_rcv(struct sk_buff *skb) static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr) { struct net_device *dev = netdev_notifier_info_to_dev(ptr); + struct netdev_notifier_change_info *change_info; struct net *net = dev_net(dev); struct inet6_dev *idev; @@ -1664,6 +1665,11 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, ndisc_send_unsol_na(dev); in6_dev_put(idev); break; + case NETDEV_CHANGE: + change_info = ptr; + if (change_info->flags_changed & IFF_NOARP) + neigh_changeaddr(&nd_tbl, dev); + break; case NETDEV_DOWN: neigh_ifdown(&nd_tbl, dev); fib6_run_gc(0, net, false); |