Watch Linux Network Changes with ip monitor
Something changed the routing table and nobody knows what: ip monitor catches it happening next time instead of guessing after the fact. It watches live netlink events, and you can narrow the stream to a device, an object type, or record it for later.
The route
Jump straight to the step you need, or tick off Done means at the end.
- 1. Confirm the installed command
- 2. Watch only the events you need
- 3. Add timestamps and labels before investigating
- 4. Produce a harmless event and verify the stream
- 5. Record binary netlink history with rtmon
- 6. Include network namespaces when the host uses them
- 7. Keep captures readable and safe
- Common traps
The examples use iproute2 6.1.0, part of the iproute2 package on this machine. Allow about 15 minutes for a first investigation. You need a shell and a network change to observe; recording events may need elevated privileges on your host.
1. Confirm the installed command
Check which binary you are using and what syntax it advertises, an ordinary read-only step:
$ command -v ip
/usr/sbin/ip
$ ip -V
ip utility, iproute2-6.1.0, libbpf 1.3.0
$ ip monitor help
Usage: ip monitor [ all | OBJECTS ] [ FILE ] [ label ] [ all-nsid ]
[ dev DEVICE ]
OBJECTS := address | link | mroute | neigh | netconf |
nexthop | nsid | prefix | route | rule | stats
FILE := file FILENAME
The version matters when comparing output against another host. One thing that trips people up: ip monitor does not take an initial snapshot. It waits for netlink messages, so a blank terminal usually means a running monitor, not a failed command.
Checkpoint
Keep this terminal free for the monitor. Run whatever produces the change in a second terminal.
2. Watch only the events you need
Choose an object type after monitor. For a broad view of interface changes, as an ordinary user:
$ ip monitor link
It stays attached until Ctrl-C. To avoid waiting indefinitely while checking syntax, add a timeout:
$ timeout 10s ip monitor link
linkfor interfaces,addressfor addresses,routefor routes.neighfor neighbour state,rulefor policy rules,netconffor network configuration.- The manual also lists multicast routes, prefixes, statistics, namespace identifiers and nexthops.
allgets you every supported object type, but on a busy host that stream gets hard to read fast.
Limit a live stream to one device with dev:
$ ip monitor address route dev eth0
Swap in the real interface name. This command changes nothing on the interface itself; if you are unsure of the name, check it separately with ip link show.
3. Add timestamps and labels before investigating
Timing usually matters more than the event text. The long options are -timestamp and -tshort, short forms -t and -ts. The short form stays compact on the event line:
$ timeout 10s ip -ts monitor address route dev eth0
Output starts with something like [2026-09-24T14:45:12.345], exact events and times depend on the host. The longer form puts a human-readable timestamp on its own line:
$ timeout 10s ip -t monitor link
Use label when several object families share one stream, it prefixes each message with something like [LINK] or [NEIGH]:
$ ip -ts monitor all label
Tip
Option placement is easy to get backwards. Timestamp switches belong to ip, before monitor; object filters and monitor options follow it. Keep this shape when adapting the command:
$ ip -ts monitor OBJECTS label dev DEVICE
4. Produce a harmless event and verify the stream
A monitor is easiest to validate when you already know what event should appear. Toggling an interface administratively changes live state, and it can interrupt traffic, so never do that on a production, remote or shared interface. On a test machine with console access and a safely interruptible interface, this needs elevated privileges:
# ip link set dev TEST_DEVICE down
# ip link set dev TEST_DEVICE up
Warning
If the interface carries the route your current shell depends on, do not run this remotely. Swap in a deliberately chosen test interface; the monitor should show link messages, though exact flags depend on the driver. Restore it with the second command if that was your only change.
A safer first check is to just watch a change your normal network manager is already making: start the monitor, reconnect a test network, or wait for a DHCP renewal if that is part of your setup. Do not manufacture a route or address purely for output, those changes can affect connectivity and policy.
Checkpoint
Stop the monitor with Ctrl-C once you have the lines you need. A non-zero status from timeout hitting its limit is expected, and it does not describe the network event itself.
5. Record binary netlink history with rtmon
Live monitoring only sees messages after the listener starts. The companion rtmon command records RTNETLINK messages to a binary file that ip monitor can replay later, start it before a maintenance action when you need the full sequence:
# rtmon file /var/log/rtmon.log
This stays attached until Ctrl-C. Pick a path the process can actually write to, writing under /var/log normally needs root, and the recorded file can reveal interface, address and routing details, so protect its permissions. A safer non-persistent test path:
$ rtmon file /tmp/rtmon-test.log
On a system that denies netlink monitoring to ordinary users, expect something like Cannot bind netlink socket: Operation not permitted. That is a permission boundary, not a reason to loosen network security policy: run the recorder with minimum privilege, in a controlled maintenance window.
Stop the recorder, then replay it:
$ ip monitor file /tmp/rtmon-test.log
In file mode ip reads the supplied file instead of opening RTNETLINK. The file has to contain binary RTNETLINK messages, not a text capture made by redirecting a live monitor's output, and there is no need to pass all when replaying.
6. Include network namespaces when the host uses them
all-nsid asks the monitor to listen for namespaces with an assigned namespace identifier, in the namespace where the monitor runs:
$ ip -ts monitor all-nsid label
Events get prefixed with the originating namespace, for example [nsid 0]. An empty or incomplete view can be entirely correct if a namespace has no assigned identifier: this option does not discover every namespace on its own, and does not move the monitor into another namespace. Check namespace setup separately before blaming a routing failure.
7. Keep captures readable and safe
Redirect text output only when you want a human-readable transcript:
$ timeout 60s ip -ts monitor address route label > /tmp/ip-monitor.txt
$ less /tmp/ip-monitor.txt
The shell creates or truncates that file before ip even starts, so use a new filename when an old capture matters. Do not confuse this text file with an rtmon binary log. For sensitive investigations, set a restrictive umask before creating the capture, and remove it through your normal retention process afterwards.
Common traps
- No output at all. Check the object filter, device name, namespace, permissions, and whether a real event actually happened after the monitor started.
- Too much output. Drop
all, pick one object family, and adddev DEVICE. - Replay fails. Confirm the file actually came from
rtmonand was not replaced by a text redirect.
Done means
- Version and syntax confirmed: installed iproute2 version and monitor syntax checked.
- Stream scoped correctly: you can watch a chosen object type and restrict it to one device.
- Timestamps and labels added where they help identify events.
- No false snapshot assumed: live mode waits for future changes, it gives you no initial state.
- Binary versus text understood: an
rtmoncapture is not the same as a text transcript. - Production left alone: no disruption caused, and any capture with network details is protected.