diff options
author | Eric Dumazet <edumazet@google.com> | 2015-07-27 05:33:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-07-29 02:41:24 -0400 |
commit | 11c91ef98f37cd743098de26160fffd7f9bd40e1 (patch) | |
tree | fbac25bfba3cd3487b659d37cf31d5d9d5c7070a /net | |
parent | 865b804244f228e80fb62abe464296399253cce8 (diff) |
arp: filter NOARP neighbours for SIOCGARP
When arp is off on a device, and ioctl(SIOCGARP) is queried,
a buggy answer is given with MAC address of the device, instead
of the mac address of the destination/gateway.
We filter out NUD_NOARP neighbours for /proc/net/arp,
we must do the same for SIOCGARP ioctl.
Tested:
lpaa23:~# ./arp 10.246.7.190
MAC=00:01:e8:22:cb:1d // correct answer
lpaa23:~# ip link set dev eth0 arp off
lpaa23:~# cat /proc/net/arp # check arp table is now 'empty'
IP address HW type Flags HW address Mask Device
lpaa23:~# ./arp 10.246.7.190
MAC=00:1a:11:c3:0d:7f // buggy answer before patch (this is eth0 mac)
After patch :
lpaa23:~# ip link set dev eth0 arp off
lpaa23:~# ./arp 10.246.7.190
ioctl(SIOCGARP) failed: No such device or address
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Vytautas Valancius <valas@google.com>
Cc: Willem de Bruijn <willemb@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/arp.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 933a92820d26..6c8b1fbafce8 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -1017,14 +1017,16 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev) | |||
1017 | 1017 | ||
1018 | neigh = neigh_lookup(&arp_tbl, &ip, dev); | 1018 | neigh = neigh_lookup(&arp_tbl, &ip, dev); |
1019 | if (neigh) { | 1019 | if (neigh) { |
1020 | read_lock_bh(&neigh->lock); | 1020 | if (!(neigh->nud_state & NUD_NOARP)) { |
1021 | memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len); | 1021 | read_lock_bh(&neigh->lock); |
1022 | r->arp_flags = arp_state_to_flags(neigh); | 1022 | memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len); |
1023 | read_unlock_bh(&neigh->lock); | 1023 | r->arp_flags = arp_state_to_flags(neigh); |
1024 | r->arp_ha.sa_family = dev->type; | 1024 | read_unlock_bh(&neigh->lock); |
1025 | strlcpy(r->arp_dev, dev->name, sizeof(r->arp_dev)); | 1025 | r->arp_ha.sa_family = dev->type; |
1026 | strlcpy(r->arp_dev, dev->name, sizeof(r->arp_dev)); | ||
1027 | err = 0; | ||
1028 | } | ||
1026 | neigh_release(neigh); | 1029 | neigh_release(neigh); |
1027 | err = 0; | ||
1028 | } | 1030 | } |
1029 | return err; | 1031 | return err; |
1030 | } | 1032 | } |