Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 11c91ef9 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

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: default avatarEric Dumazet <edumazet@google.com>
Reported-by: default avatarVytautas Valancius <valas@google.com>
Cc: Willem de Bruijn <willemb@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 865b8042
Loading
Loading
Loading
Loading
+9 −7
Original line number Original line Diff line number Diff line
@@ -1017,15 +1017,17 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)


	neigh = neigh_lookup(&arp_tbl, &ip, dev);
	neigh = neigh_lookup(&arp_tbl, &ip, dev);
	if (neigh) {
	if (neigh) {
		if (!(neigh->nud_state & NUD_NOARP)) {
			read_lock_bh(&neigh->lock);
			read_lock_bh(&neigh->lock);
			memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len);
			memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len);
			r->arp_flags = arp_state_to_flags(neigh);
			r->arp_flags = arp_state_to_flags(neigh);
			read_unlock_bh(&neigh->lock);
			read_unlock_bh(&neigh->lock);
			r->arp_ha.sa_family = dev->type;
			r->arp_ha.sa_family = dev->type;
			strlcpy(r->arp_dev, dev->name, sizeof(r->arp_dev));
			strlcpy(r->arp_dev, dev->name, sizeof(r->arp_dev));
		neigh_release(neigh);
			err = 0;
			err = 0;
		}
		}
		neigh_release(neigh);
	}
	return err;
	return err;
}
}