Arp table sometimes not updating?

Hi,

I'm using my LEDE router to track presence in Homeassistant. It uses luci-mod-rpc to see if my devices are connected to my wifi by checking the arp table.

This works well for my android devices, but for some reason it doesn't for my iPhone X. If ssh into my router and run arp, I can see that the flag of my android devices change from 0x2 to 0x0 (connected to disconnected I suppose?) when I disconnect from wifi, but the flag of my iPhone X often stays on 0x2, and thus Homeassistant keeps on showing it as home, while it's not connected.

Once it missed my device going offline, it will keep on showing it online (flag is 0x2 in the arp table), until I reconnect and disconnect again (unless it fails again, of course).

I don't really know if this is a bug in LEDE, a wrongly use of the arptable by Homeassistant or something wrong with the iPhone X, but it's very annoying and I would like to find a solution :slight_smile:

Emil

The arp table (cache) is intended to help the performance of the network by not requiring a query out to the network for the Layer 2 address of the target device every time a packet needs to be sent. It is not intended to track reachability in real time. It typically has an aging algorithm that removes entries after some period of time, often moderated by the number of entries in the table.

The same applies to the wireless-association table. There are additional complications there as it takes ~1.5 seconds for a client to re-associate and authenticate, along with power consumed. In contrast, a wired arp typically takes milliseconds.

Like even TCP connections, there only way to guess that a client is absent is to try to connect to it and fail.

1 Like

Hi, thanks for your quick reply!

That's what I kinda figured, but how real time are we talking about?
You're talking about seconds, but I'm talking about hours.

What is the meaning of those flags actually? It seems to correlate with being recently seen.

If the arp table is correct up to several minutes that's more than good enough.

From https://github.com/openwrt/linux/blob/master/include/uapi/linux/if_arp.h#L127

/* ARP Flag values. */
#define ATF_COM		0x02		/* completed entry (ha valid)	*/
#define	ATF_PERM	0x04		/* permanent entry		*/
#define	ATF_PUBL	0x08		/* publish entry		*/
#define	ATF_USETRAILERS	0x10		/* has requested trailers	*/
#define ATF_NETMASK     0x20            /* want to use a netmask (only
					   for proxy entries) */
#define ATF_DONTPUB	0x40		/* don't answer this addresses	*/

You might be able to "help" the table update for your needs by pinging the devices. I'd also look at the wireless-association table as an alternate source to determine if "my iPhone is likely in the house"

@Emilv2 did you ever figure out a solution to this problem? I am also having devices stick in the arp table for hours after they left the network. Like you I am using it for the HA device tracker.

i have seen this where entries sticks for hours/days
To clear the arp table

ip -s -s neigh flush all

I since updated to OpenWrt 18.06 which does not provide this api anymore.

I found a custom component luci_ap which uses the wireless-association table like @jeff suggested.

I only tested if for a short while, but it seems to work better and also doesn't seem to have the problem with Apple devices disappearing for a while when idle.

I am looking for a deterministic way to know if a device is connected or not.
wireless-assoc is not possible when using separate access points.

My question is:
Can we rely on "arping" to know the device is connected to the network?
All devices don't respond to "ping" but I believe they do to "arping".

Sort of, for IPv4 and for Ethernet (or where ARP is being proxied), not for IPv6 (different neighbor-detection protocol). Power-save complicates things as well. Further, ARP is about IPv4 addresses, not devices.

1 Like

Right.. the power-save is a bummer.
But that can be considered as a non-connected state.
Basically I am looking to quantify wifi connection quality of a wifi client.
Ping,jitter,loss data from a periodic "fping" (or even arping) command appear to be a good metric.
However I want to exclude the data when device has gone offline as they pollute the data.
That is, measure only when device is connected.