Page MenuHomeVyOS Platform

DHCP client: option 121 routes removed by FRR reload, option 3 default installed despite option 121
Open, NormalPublicBUG

Description

With address dhcp and a lease carrying option 121 and option 3, the option 121 routes never stay installed. Option 121 routes are added outside the FRR render (Debian's rfc3442-classless-routes hook via the VyOS ip() wrapper and vtysh). staticd.frr.j2 renders only the option 3 router, so any frr-reload deletes the 121 routes. 98-vyos-static-routes-dhclient-hook runs systemd-run --no-block vyos-frr-render.py --after-commit on every BOUND; the reload lands right after the rfc3442 hook has added the routes:

17:04:19.240 systemd[1]: Started /usr/libexec/vyos/vyos-frr-render.py --after-commit.
17:04:19.313 dhclient-script-vyos: Command was executed successfully via vtysh: "ip route 198.51.100.0/24 10.33.2.2 eth1 tag 210 210 "
frr-reload 17:04:19.747: 'no ip route 198.51.100.0/24 10.33.2.2 eth1 tag 210 210'

Before T9278 (1.5.1) the hook ran only for dhcp-interface static routes and synchronously, so the 121 routes were installed at lease time and lost only at the next commit that reloaded FRR.

Also: the option 3 default is rendered even when option 121 is present. RFC 3442: "If the DHCP server returns both a Classless Static Routes option and a Router option, the DHCP client MUST ignore the Router option."

Impact: option 121 routes via a gateway other than the option 3 router are silently never installed.

Expected: option 121 routes kept across reloads; no option 3 default when option 121 is present.

Suggested fix: render the 121 routes in staticd.frr.j2 (store new_rfc3442_classless_static_routes in the lease dump, decode it like get_dhcp_router()), skip the option 3 default when 121 is present, and drop the vtysh route handling from the dhclient hooks. Reordering hooks does not help.

Details

Version
1.5.1, 1.5-rolling-20261026
Is it a breaking change?
Unspecified (possibly destroys the router)
Issue type
Bug (incorrect behavior)

Event Timeline

A note on how this overlaps with T9482 / https://github.com/vyos/vyos-1x/pull/5582, in case someone picks this up.

That PR adds a check in protocols_static.py for the implicit default route of an interface with address dhcp. FRR's staticd does not accept a blackhole or reject route next to a next-hop route with the same prefix and distance, and a configuration like that stalls the commit in frr-reload for about 14 seconds before it is rolled back. The check looks at the route that staticd.frr.j2 renders from the option 3 router (0.0.0.0/0 <router> <interface> tag 210, with default-route-distance) and only when get_dhcp_router() returns a gateway.

If the option 121 routes are rendered in staticd.frr.j2 as proposed here, the same rule applies to them: a static blackhole for the same prefix with the same distance next to a 121 route would stall staticd as well. The check would need to see the same set of routes that the template renders, including "no option 3 default when option 121 is present". Otherwise it either reports a conflict with a default route that is no longer rendered, or misses a conflict with a 121 route.

The pull request also changes staticd.frr.j2 (the route_options macro and the whitespace of the route lines) and protocols_static.py, so a change to the same template will conflict textually. Whichever is merged second has to be rebased.

I have not tested the option 121 case itself, this is from reading the template and the PR.