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>
This commit is contained in:
parent
865b804244
commit
11c91ef98f
|
@ -1017,14 +1017,16 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
|
|||
|
||||
neigh = neigh_lookup(&arp_tbl, &ip, dev);
|
||||
if (neigh) {
|
||||
read_lock_bh(&neigh->lock);
|
||||
memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len);
|
||||
r->arp_flags = arp_state_to_flags(neigh);
|
||||
read_unlock_bh(&neigh->lock);
|
||||
r->arp_ha.sa_family = dev->type;
|
||||
strlcpy(r->arp_dev, dev->name, sizeof(r->arp_dev));
|
||||
if (!(neigh->nud_state & NUD_NOARP)) {
|
||||
read_lock_bh(&neigh->lock);
|
||||
memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len);
|
||||
r->arp_flags = arp_state_to_flags(neigh);
|
||||
read_unlock_bh(&neigh->lock);
|
||||
r->arp_ha.sa_family = dev->type;
|
||||
strlcpy(r->arp_dev, dev->name, sizeof(r->arp_dev));
|
||||
err = 0;
|
||||
}
|
||||
neigh_release(neigh);
|
||||
err = 0;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue