netifd icon indicating copy to clipboard operation
netifd copied to clipboard

interface-ip: install routes after IPv6 prefix address setup

Open kempniu opened this issue 6 months ago • 3 comments

In interface_ip_set_enabled(), routes are currently installed after IP addresses are set up, but before IPv6 prefix addresses are set up. This prevents configured static IPv6 routes that have next hops set to addresses belonging to those prefixes from being installed during interface setup as the relevant netlink requests return -EHOSTUNREACH (No route to host). Fix by deferring route installation until after IPv6 prefix addresses are configured.


This PR should help with openwrt/openwrt#5089, but it does not solve the problem completely for all types of IPv6 routes defined via config route6 in /etc/config/network. It boils down to when the IPv6 prefix of the route's next hop gets configured.

Let's assume we want to route an arbitrary IPv6 subnet via an IPv6 next hop located on the LAN side. Now:

  1. With the code currently present in netifd's master branch, AFAICT, virtually no static IPv6 routes configured via /etc/config/network will be installed properly.

  2. With the change proposed in this PR applied, static IPv6 routes whose next hops are in (statically defined) ULA prefixes should be installed correctly; that's because netifd will be able to configure the ULA-sourced IPv6 address on a given interface before attempting to install any IPv6 routes, preventing "No route to host" errors.

  3. With the change proposed in this PR applied, static IPv6 routes whose next hops are in prefixes that are assigned dynamically (e.g. when prefix setup is only triggered after wan6 goes up) will still not be installed properly.

The problem with this last scenario is that when the LAN interface goes up and netifd attempts to install the static IPv6 route, it still doesn't know what IPv6 prefix to assign addresses from on the LAN side (because the WAN side may not yet be up). I currently have to work around this by dropping a hotplug script into /etc/hotplug.d/iface/, e.g.:

[ "${ACTION}" = "ifup" ] && [ "${INTERFACE}" = "wan6" ] && {
	ip -6 route add <prefix> via <next-hop>
}

I guess the core issue here is that this route should be installed "for the LAN interface" after another interface gets its IPv6 addressing set up. Sadly, I don't know enough about the inner workings of netifd to propose a proper solution for that scenario.

kempniu avatar Jun 12 '25 12:06 kempniu

I don't think netifd is handling dynamic prefix allocation by itself but delegate this to odhcp6c. A way to do that would be to use odhcp6c event scripts (/etc/odhcp6c.user or any files under /etc/odhcp6c.user.d/) and react to updated or updated-ra events by reparsing the config route6 entries and set them up via ip-6 route again? Or propose a new feature for odhcp6c to handle that internally?

nvandamme avatar Oct 13 '25 12:10 nvandamme

Right, I guess netifd might not handle prefix allocation, but apparently it does handle address setup for prefixes that were already allocated and that's what the commit message for this PR discusses. Otherwise, I don't know what these lines do:

https://github.com/openwrt/netifd/blob/88a965fba399c2012eac77e5c3c4f28c9113c5ca/interface-ip.c#L1743-L1748

nor why moving the interface_ip_set_route_enabled() calls below the above lines fixes at least some of the use cases.

Furthermore, I'm not using DHCPv6 for prefix allocation in my setup; the IPv6 prefix in question is defined statically in /etc/config/network (via list ip6prefix), but it is not set up until the interface it is configured for goes up (it's a 6in4 tunnel). Therefore, I'm not sure odhcp6c even kicks in anywhere here...

kempniu avatar Oct 21 '25 12:10 kempniu

Make sense, i was focused on the dynamic part only.

nvandamme avatar Oct 22 '25 06:10 nvandamme