Build and Inspect Linux Nexthop Groups with ip nexthop
You will finish with a small set of reusable kernel nexthop objects: two gateways, a weighted multipath group, and commands for inspecting or removing them. The examples use iproute2 6.1.0-1ubuntu6.4, with ip reporting iproute2-6.1.0. Allow about fifteen minutes. You need a shell, the iproute2 package, and root privileges for changes to the kernel nexthop table.
The route
Jump straight to the step you need, or tick off Done means at the end.
A nexthop is not a route. It describes how traffic can leave, while a route can refer to that description by ID. This separation lets several routes share the same gateway or group. The IDs below are examples: check that they are unused before applying a change.
1. Check the installed command and current table
Start with read-only commands. They need no elevated privilege on this machine:
$ ip -Version
ip utility, iproute2-6.1.0, libbpf 1.3.0
$ ip nexthop show
$ printf 'status: %s\n' "$?"
status: 0
An empty ip nexthop show result is valid. If your output contains entries, choose IDs that do not appear there. ip nexthop list is accepted by the installed command as an alternative spelling for show.
Checkpoint
Record the IDs you intend to use, and confirm that the interface names and gateway addresses are real on this host. A wrong interface or gateway can make later routing tests fail even when the nexthop object itself is syntactically valid.
2. Add two ordinary nexthops
The following commands create objects 4241 and 4242. Replace the example addresses and interface before running them. These are state-changing commands and normally require sudo:
$ sudo ip nexthop add id 4241 via 192.0.2.1 dev eth0
$ sudo ip nexthop add id 4242 via 198.51.100.1 dev eth0
via names the next router and dev selects the output device. The address family of via must match the nexthop instance. The documentation also supports IPv6 addresses, but do not mix families in one design without checking the surrounding routes.
Verify each object:
$ ip nexthop get id 4241
id 4241 via 192.0.2.1 dev eth0
$ ip nexthop get id 4242
id 4242 via 198.51.100.1 dev eth0
The exact formatting can vary with the installed iproute2 build, so check the ID, gateway and device rather than copying whitespace. If an ID already exists, add fails instead of silently replacing it. To abandon this example, remove the objects with the commands in step 5.
3. Create a weighted multipath group
Object 4243 can refer to both nexthops:
$ sudo ip nexthop add id 4243 group 4241,5/4242,11
The slash separates group members. Each member has the form id,weight; omitting the weight gives the default equal weighting. Here, the group expresses a relative weight of 5 for ID 4241 and 11 for ID 4242. The default group type is mpath, backed by the hash-threshold algorithm.
Inspect only groups:
$ ip nexthop show groups
id 4243 group 4241,5/4242,11 type mpath
A nexthop group does not automatically install a route to a destination. A route must be configured separately to use the group ID, and that route is outside this guide. Treat the object and the route as separate changes when planning rollback.
4. Choose a resilient group when membership changes
A resilient group is designed to keep bucket assignments steadier when nexthops are added or removed. This can matter for long-lived flows. Create one with an explicit bucket count:
$ sudo ip nexthop add id 4244 group 4241/4242 type resilient buckets 32
buckets cannot be changed for an existing group. The idle timer defaults to 120 seconds. The unbalanced timer defaults to 0, which disables automatic rebalancing. If you set a non-zero unbalanced timer, the kernel may rebalance an unbalanced group and some flows may reset. That is a service-impacting choice, so set it only when you understand the traffic behaviour:
$ sudo ip nexthop replace id 4244 group 4241/4242 type resilient buckets 32 idle_timer 120 unbalanced_timer 60
Do not use replace as a harmless preview. It changes an existing object or adds it when absent. Verify the result with ip nexthop get id 4244 and stop if the displayed group differs from the intended one.
5. Inspect buckets and recover from a mistake
Bucket commands are useful for resilient groups. List the buckets belonging to group 4244:
$ ip nexthop bucket list id 4244
To inspect one bucket, use its index from that listing:
$ ip nexthop bucket get id 4244 index 0
You can also select buckets by the nexthop ID they hold:
$ ip nexthop bucket list nhid 4241
These commands read the kernel table. They do not change bucket assignments.
Recovery warning: deleting an object can break routes that refer to it, and flushing can remove many objects at once. Prefer explicit deletion:
$ sudo ip nexthop del id 4244
$ sudo ip nexthop del id 4243
$ sudo ip nexthop del id 4242
$ sudo ip nexthop del id 4241
Delete groups before their member nexthops. If a deletion fails because another object or route still refers to the ID, inspect those dependencies first. Never use ip nexthop flush on a production host until its selector is fully understood; its criteria are the same selectors used by show, including dev, vrf, master, groups and fdb.
6. Confirm the final state
After creating or removing objects, make the check narrow and repeatable:
$ ip nexthop show id 4241
$ ip nexthop show id 4242
$ ip nexthop show id 4243
$ ip nexthop show id 4244
After the recovery commands, each query should produce no output and return status 0 on this system. Before a real deployment, also test the route that consumes the nexthop group and monitor the affected flows. ip nexthop verifies the object table; it does not prove that a destination route, policy rule or application path is correct.
Done means
- The installed iproute2 version and free IDs were checked.
- Each ordinary nexthop shows the intended gateway and device.
- The group type, members, weights and resilient bucket settings were verified.
- Any route using the objects was considered separately from object rollback.
- Unused test objects were deleted explicitly, or their IDs were recorded for later cleanup.