Run arpd Safely as a Userspace ARP Cache Helper
You will finish with a controlled way to let arpd collect gratuitous ARP information, inspect the resulting database, and decide whether kernel-helper mode is appropriate. The examples target the installed iproute2 package version 6.1.0-1ubuntu6.4. Allow about 20 minutes for a read-only trial, or longer if you intend to change live neighbour resolution.
The route
Jump straight to the step you need, or tick off Done means at the end.
arpd is a userspace daemon, not a general ARP troubleshooting command. It stores learned information on disk and can feed it to a kernel built with CONFIG_ARPD. The ordinary collection mode does not take over kernel resolution. The -a and -k modes do affect network behaviour, so treat them as a maintenance-window change.
1. Check the installed command
Start with read-only checks. They need no elevated privileges unless your local executable or package database is restricted:
$ 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 database path during a trial so that you know exactly which file is being changed.
Checkpoint
Confirm that command -v arpd resolves to the binary you intend to run and that the package version is recorded in your change notes.
2. Choose an isolated database
Make a directory in a location reserved for your test. This changes local filesystem state, so run it as the account that will own and run the daemon. Do not use a shared or production database for the first trial:
$ 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
Replace the displayed home directory with your own shell output. The rm command is deliberately scoped to the new test file. Do not adapt it to /var/lib/arpd/arpd.db unless you have first checked whether that database contains useful operational data.
3. Collect passively first
Run arpd with only -b. With no interface names, it watches all interfaces, but the manual says it does not adjust sysctl values in that case. This mode collects gratuitous ARP information without enabling active broadcast queries:
$ arpd -b "$DB"
This command stays in the foreground. Leave it running long enough for normal local ARP traffic to arrive, then stop it with an ordinary interrupt:
^C
A SIGINT or SIGTERM makes arpd sync its database and exit gracefully. Do not use an arbitrary signal or kill -9 for normal shutdown: the manual warns that other signals may corrupt the database and leave adjusted sysctl parameters unpredictable. If the process was started by a service manager, stop it through that manager instead.
Checkpoint
The daemon should have exited after the interrupt, and the database should now be present:
$ test -f "$DB" && echo "database exists"
database exists
$ ls -l -- "$DB"
-rw------- 1 you you ... /home/you/arpd-test/arpd.db
The exact permissions, owner and size depend on the local build and filesystem. The useful checks are that the file exists and that you used the intended path.
4. Dump the database without starting the daemon
Use -l with the same database path to inspect what was 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 contains an interface index, an IP address and a MAC address. A negative entry uses FAILED followed by the most recent time when the host was proved dead. Your output may be empty if the host saw no suitable gratuitous ARP packets, and the interface index and addresses will be host-specific. Do not treat an empty dump as proof that ARP is broken.
The timestamp in a failed entry is data from the database, not a promise that the host is currently offline. Use normal network diagnostics, such as ip neigh and a controlled connectivity check, when you need current reachability.
5. Load a text database only when you mean to replace data
-f reads a text database in a format similar to the -l output and exits after loading it. A file argument of - means standard input. Loading data changes the selected database, so make a backup first:
$ cp --preserve=all "$DB" "$DB.before-load"
$ arpd -f /path/to/arpd-dump.txt -b "$DB"
$ arpd -l -b "$DB"
If the load was a mistake, stop using the database and restore the backup after checking the paths:
$ cp --preserve=all "$DB.before-load" "$DB"
Do not feed untrusted text directly into an operational database. The dump format is simple, but correctness still depends on interface indexes, addresses and MAC addresses matching the host where the data will be used.
6. Understand active query mode before enabling it
The -a NUMBER option makes arpd send broadcast queries as well as listen passively. The number controls how many queries are made before a destination is considered dead. The following is therefore 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, and check them first with ip link. Elevated privileges are normally required for daemon operation and network access, but sudo does not make an unsuitable configuration safe. Start with a single known interface and a maintenance window.
-k suppresses broadcast queries by the kernel and only makes sense with -a. The documented mode that gives arpd authority over broadcast resolution is therefore shaped like this:
$ sudo arpd -b /var/lib/arpd/arpd.db -a 3 -k eth0 eth1
This can change how hosts are resolved and can increase the impact of a bad database or wrong interface list. The manual calls it the normal intended mode, but it is not the default specifically to avoid accidentally enabling an aggressive configuration. Record the previous command or service configuration before making this change so that you can restore it. Stop a foreground instance with SIGTERM or SIGINT and verify that the original service configuration is back in place before declaring the change undone.
7. Check kernel prerequisites and tuning limits
For arpd to serve as a kernel ARP resolver, the kernel needs CONFIG_ARPD. When you supply interface names, the daemon can adjust relevant neighbour sysctl parameters. When you omit interface names, it assumes that 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
Replace the interface names with directories that exist on your machine. Do not write to these files as part of a first trial. If the kernel lacks the required support, arpd can still collect gratuitous ARP information, but the kernel-helper purpose will not be available.
The remaining timing options are easy to confuse. -p sets the polling interval for the kernel ARP table and defaults to 30 seconds. -R caps the steady broadcast rate and defaults to one packet per second. -B controls the initial back-to-back burst and defaults to three. -n sets negative-cache timeout, defaulting to 60 seconds, and is intended with -k. Keep the defaults until you can explain which observed problem requires a change.
Done means
- You recorded the installed iproute2 version and confirmed the local
arpdsyntax. - 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
FAILEDrows from an-ldump. - You understand that
-asends broadcasts and that-kchanges kernel resolution. - Any active-mode change has a recorded rollback path and a maintenance window.