Inspect Linux Network Devices Safely with devlink
Someone tells you to "check devlink" on a box with a fancy NIC or switch chip, and you would rather look than touch. Here is how to use devlink to list devices and ports and capture JSON without changing hardware state. Allow about 15 minutes; every example is read-only unless marked as disruptive.
The route
Jump straight to the step you need, or tick off Done means at the end.
- Tool version: the installed
iproute2package is 6.1.0-1ubuntu6.4. - Driver-dependent: the available objects and commands vary with the driver.
- Empty is normal: a system can have perfectly working network interfaces and expose nothing through devlink.
1. Confirm the installed tool
Start as your ordinary user. The version option is -V, with a capital letter. The long spelling --version is not accepted by this installed command.
$ command -v devlink
/usr/sbin/devlink
$ devlink -V
devlink utility, iproute2-6.1.0
The version line identifies the iproute2 utility, not the firmware or driver managing a device. Keep those versions separate when reporting a problem.
Tip
If command -v finds nothing, install the distribution's iproute2 package through your normal package process. Do not copy a different binary into place while diagnosing a driver issue.
2. List devlink devices
The main inventory command is devlink dev show. With no device argument it asks the kernel for every registered devlink device.
$ devlink dev show
No output and exit status 0 means the query found no device to print. That is not a failure. On this machine, the equivalent JSON query returns an empty object:
$ devlink -j dev show
{"dev":{}}
On a host with a supported device, expect an identifier such as pci/0000:03:00.0. Do not invent one. Copy the exact value from your own output before using it in a later command.
When a script needs to tell an empty result from an error, check the status directly:
$ devlink dev show
$ printf 'devlink exit status: %s\n' "$?"
devlink exit status: 0
3. Inspect the device and its ports
Ask the installed command what the device object supports before trying anything specialised:
$ devlink dev help
Usage: devlink dev show [ DEV ]
devlink dev eswitch set DEV [ mode { legacy | switchdev } ]
devlink dev param set DEV name PARAMETER value VALUE cmode { permanent | driverinit | runtime }
devlink dev reload DEV [ netns { PID | NAME | ID } ]
devlink dev info [ DEV ]
devlink dev flash DEV file PATH [ component NAME ]
devlink dev selftests run DEV [id TESTNAME ]
The full help text is longer than this. Even this excerpt shows the boundary: show and info inspect state, while reload, flash, parameter changes and some self-tests can affect a device.
If step 2 gave you a device identifier, substitute it literally:
$ DEV='pci/0000:03:00.0'
$ devlink dev info "$DEV"
$ devlink port show "$DEV"
- Do not guess the placeholder. Replace it only with an identifier printed by your host.
- Port output can include a devlink port identifier and a related netdevice name.
- Friendly names are shown by default. Use
-nto turn off these nice names and see the devlink identification instead. - Ports are not interfaces. Linux documentation describes a devlink port as a logical ingress or egress point, not necessarily a one-to-one copy of what
ip linkshows. Layout is device and driver specific.
4. Save JSON for repeatable inspection
Use -j for JSON output. Add -p when a human needs formatted JSON. Put options before the object name:
$ devlink -p -j dev show
{
"dev": {}
}
$ devlink -j port show
{"port":{}}
JSON saves you parsing aligned columns. It does not make missing data appear: an empty result still means the kernel exposed no objects for that query.
- Hex values: add
-x. - IEC units for human-readable rates: add
-i.
For a one-off record, write to a new file rather than overwriting an existing capture:
$ devlink -j dev show > devlink-devices.json.new
$ test -s devlink-devices.json.new
$ mv devlink-devices.json.new devlink-devices.json
The final move replaces the old capture only after the command has produced non-empty output. If the command fails, check the .new file, remove it, and keep the previous record. The command itself does not alter the device.
5. Watch netlink events when investigating a change
devlink monitor watches for devlink netlink messages. Start broad, in a terminal used only for observation:
$ devlink monitor all
Leave it running while an already-approved maintenance action happens in another terminal. Stop it with Ctrl-C; that ends the monitor and does not undo the event it observed. Narrow the stream when the output is noisy:
$ devlink monitor dev port health trap
The syntax accepts all or an object list. It reports messages and has no rollback. Record the original device and port inventory before a maintenance window so you have something concrete to compare afterwards.
6. Keep state-changing commands out of an inspection
Several commands in devlink dev help are operational controls, not harmless discovery.
- Reload can interrupt a device.
- Flash can replace firmware.
- Eswitch mode, port split, port function and persistent parameter changes can disrupt networking.
Warning
Do not paste any of these into a production shell merely because they appeared in help. For the same reason, do not use devlink port set, devlink port split, devlink port unsplit, devlink port add or devlink port del during an inventory exercise.
If a later change is required, first record the current output, confirm the exact driver documentation, arrange console or out-of-band recovery, and schedule a maintenance window. There is no universal undo command: recovery depends on the driver, device and change.
Most read-only queries work without elevated privileges. If one fails with a permissions error, retrying with sudo may be appropriate on a machine you administer, but it will not create a missing devlink device or add unsupported commands. Treat firmware paths, device identifiers and batch files as sensitive operational inputs.
7. Use batch mode only for reviewed read-only commands
The -b option reads commands from a file or standard input and stops at the first failure. -force continues after errors but returns a non-zero status if any command failed. That suits a reviewed inventory, and is risky if the file contains a reload, flash or set operation.
$ devlink -b /path/to/reviewed-devlink-inventory.txt
$ printf 'batch exit status: %s\n' "$?"
- Review the file first.
- One read-only command per line, with explicit device identifiers copied from discovery.
- No secrets in comments or shell-expanded paths.
Warning
A batch run is not transactional. If a later command fails, earlier commands have not been rolled back.
Done means
- Version known:
devlink -Videntified the installed iproute2 utility. - Inventory recorded: you ran
devlink dev showand noted whether the result was empty or held real device identifiers. - Inspection separated from control: you used
devlink dev helpand the relevantporthelp. - Identifiers are real: any device or port identifier in a command came from your host's output.
- Captures are comparable: JSON and monitor output can be compared without changing device state.
- Recovery path ready: you have one before considering reload, firmware, port or parameter changes.