Home / Alt manpages / arpd(8)

  • arpd(8)
  • Admin command
  • linux

Run arpd Safely as a Userspace ARP Cache Helper

When the kernel's own ARP resolution is not enough, arpd is the userspace daemon that learns and can drive neighbour resolution instead. This walks through letting it collect gratuitous ARP information, reading the database it builds, and deciding whether kernel-helper mode is worth the risk. The examples target iproute2 6.1.0-1ubuntu6.4. Allow about 20 minutes for a read-only trial, longer if you intend to change live neighbour resolution.

arpd is a userspace daemon, not a general ARP troubleshooting command. It stores what it learns on disk and can feed it to a kernel built with CONFIG_ARPD. Plain collection mode never takes over kernel resolution, but -a and -k do affect network behaviour, so treat those as a maintenance-window change.

1. Check the installed command

Start with checks that need no elevated privileges, unless your executable or package database is locked down further than usual:

$ command -v arpd
/usr/sbin/arpd
$ dpkg-query -W -f='${Package} ${Version}\n' iproute2
iproute2 6.1.0-1ubuntu6.4
$ arpd -h
Usage: arpd [ -lkh? ] [ -a N ] [ -b dbase ] [ -B number ] [ -f file ] [ -n time ] [-p interval ] [ -R rate ] [ interfaces ]

The help output confirms the option spelling on this host. The installed manual describes the same interface and gives a default database path of /var/lib/arpd/arpd.db. Use an explicit path during a trial so you know exactly which file you are changing.

Checkpoint

Confirm command -v arpd resolves to the binary you intend to run, and record the package version in your change notes.

2. Choose an isolated database

This changes local filesystem state, so run it as the account that will own and run the daemon, in a location reserved for your test. Never point the first trial at a shared or production database:

$ install -d -m 0750 "$HOME/arpd-test"
$ DB="$HOME/arpd-test/arpd.db"
$ rm -f -- "$DB"
$ printf 'database: %s\n' "$DB"
database: /home/you/arpd-test/arpd.db

Swap in your own shell output for the home directory shown. That rm is deliberately scoped to the new test file; do not adapt it to /var/lib/arpd/arpd.db without first checking whether that database holds useful operational data.

3. Collect passively first

Run arpd with only -b. With no interfaces named it watches everything, but the manual says it will not adjust sysctl values in that case, and it only collects gratuitous ARP information without sending active queries:

$ arpd -b "$DB"

This stays in the foreground. Let it run long enough to see normal local ARP traffic, then stop it with an ordinary interrupt:

^C

SIGINT or SIGTERM makes arpd sync its database and exit cleanly. Warning: the manual warns that other signals, including kill -9, may corrupt the database and leave adjusted sysctl parameters unpredictable. If a service manager started the process, stop it through that manager instead.

Checkpoint

The daemon should have exited after the interrupt, and the database should now exist:

$ test -f "$DB" && echo "database exists"
database exists
$ ls -l -- "$DB"
-rw------- 1 you you ... /home/you/arpd-test/arpd.db

Exact permissions, owner and size depend on the local build and filesystem. What matters is that the file exists at the path you intended.

4. Dump the database without starting the daemon

Use -l with the same database path to see what got collected:

$ arpd -l -b "$DB"
2 192.0.2.10 02:00:00:00:00:10
2 192.0.2.11 FAILED:1712345678

Each normal row is an interface index, an IP address and a MAC address. A negative entry uses FAILED followed by the last time the host was proven dead. An empty dump just means your host saw no suitable gratuitous ARP packets, not that ARP itself is broken, and your interface index and addresses will be host-specific.

A FAILED timestamp is data from the database, not a promise the host is offline right now. Reach for ip neigh and a real connectivity check when you need current reachability.

5. Load a text database only when you mean to replace data

-f reads a text database shaped like -l output and exits after loading it; a filename of - means standard input. Loading changes the selected database, so back it up first:

$ cp --preserve=all "$DB" "$DB.before-load"
$ arpd -f /path/to/arpd-dump.txt -b "$DB"
$ arpd -l -b "$DB"

Recovery

If the load was a mistake, stop using the database and restore the backup after double-checking the paths:

$ cp --preserve=all "$DB.before-load" "$DB"

Never feed untrusted text straight into an operational database. The dump format is simple, but correctness still depends on interface indexes and addresses matching the host it will run on.

6. Understand active query mode before switching it on

-a NUMBER makes arpd send broadcast queries as well as listen passively, with the number controlling how many queries happen before it considers a destination dead. This is a network-affecting example, not a harmless diagnostic:

$ sudo arpd -b /var/lib/arpd/arpd.db -a 1 eth0 eth1

Use your real interface names, checked first with ip link. Elevated privileges are normally required for daemon and network access, but sudo does not make a bad configuration safe. Start with one known interface and an actual maintenance window.

-k suppresses broadcast queries from the kernel and only makes sense alongside -a. The manual's documented normal mode, giving arpd full authority over broadcast resolution, looks like this:

$ sudo arpd -b /var/lib/arpd/arpd.db -a 3 -k eth0 eth1

Warning

This can change how hosts get resolved and magnifies the impact of a bad database or wrong interface list. It is the manual's normal intended mode, but it is not the default precisely to stop you enabling it by accident. Record the previous command or service configuration first, and after stopping a foreground instance with SIGTERM or SIGINT, verify the original setup is genuinely back before calling the change undone.

7. Check kernel prerequisites and tuning limits

For arpd to act as a kernel ARP resolver, the kernel needs CONFIG_ARPD. Supply interface names and the daemon can adjust neighbour sysctl parameters; omit them and it assumes you manage those settings yourself. Check the values before changing anything:

$ for iface in eth0 eth1; do
>   printf '%s app_solicit: ' "$iface"
>   cat "/proc/sys/net/ipv4/neigh/$iface/app_solicit"
> done

Swap in interface names that exist on your machine, and do not write to these files as part of a first trial. If the kernel lacks the support, arpd can still collect gratuitous ARP information; it just cannot act as a kernel helper.

The remaining timing flags are easy to mix up. -p sets the kernel ARP table poll interval, thirty seconds by default. -R caps the steady broadcast rate at one packet a second by default. -B controls the initial back-to-back burst, defaulting to three. -n sets the negative-cache timeout, sixty seconds by default, meant to pair with -k. Leave the defaults alone until you can name the actual problem that needs a change.

Done means

  • You recorded the installed iproute2 version and confirmed the local arpd syntax.
  • Your first run used an explicit, isolated database and passive collection.
  • You stopped the daemon with SIGINT or SIGTERM and verified the database.
  • You can read normal and FAILED rows from an -l dump.
  • You understand that -a sends broadcasts and that -k changes kernel resolution.
  • Any active-mode change has a recorded rollback path and a maintenance window.