diff options
author | Eric Dumazet <edumazet@google.com> | 2015-07-29 06:01:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-07-30 02:01:39 -0400 |
commit | c8507fb235bea3314a02a67ddda0d4e6cf01fa78 (patch) | |
tree | 72614a517252c75efc1b8e3b1803cb6cc395c92c /net/ipv6 | |
parent | b2428f94f4f79cc6045e538ed3e8329b16711712 (diff) |
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/ipv6')
-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) | |||
1650 | static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr) | 1650 | static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr) |
1651 | { | 1651 | { |
1652 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); | 1652 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); |
1653 | struct netdev_notifier_change_info *change_info; | ||
1653 | struct net *net = dev_net(dev); | 1654 | struct net *net = dev_net(dev); |
1654 | struct inet6_dev *idev; | 1655 | struct inet6_dev *idev; |
1655 | 1656 | ||
@@ -1664,6 +1665,11 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, | |||
1664 | ndisc_send_unsol_na(dev); | 1665 | ndisc_send_unsol_na(dev); |
1665 | in6_dev_put(idev); | 1666 | in6_dev_put(idev); |
1666 | break; | 1667 | break; |
1668 | case NETDEV_CHANGE: | ||
1669 | change_info = ptr; | ||
1670 | if (change_info->flags_changed & IFF_NOARP) | ||
1671 | neigh_changeaddr(&nd_tbl, dev); | ||
1672 | break; | ||
1667 | case NETDEV_DOWN: | 1673 | case NETDEV_DOWN: |
1668 | neigh_ifdown(&nd_tbl, dev); | 1674 | neigh_ifdown(&nd_tbl, dev); |
1669 | fib6_run_gc(0, net, false); | 1675 | fib6_run_gc(0, net, false); |