NetworkConfiguration / dhcpcd

DHCP / IPv4LL / IPv6RA / DHCPv6 client.
https://roy.marples.name/projects/dhcpcd
BSD 2-Clause "Simplified" License
348 stars 112 forks source link

Changing route metrics #98

Open cmcqueen opened 2 years ago

cmcqueen commented 2 years ago

I have a scenario in which I'd like to dynamically change route metrics between two network interfaces (Ethernet and WiFi) depending on tested connectivity through each (tested with the help of some Linux policy based routing rules). I'm seeing a couple of behaviours of dhcpcd which aren't ideal for this scenario:

What would be a good way to use dhcpcd in this scenario, of dynamically changing route metrics, which avoids the two issues described?

rsmarples commented 2 years ago

I would like to understand why you need to change the metrics once dhcpcd is running.

However, dhcpcd should not remove the address on SIGHUP, that sounds like a bug and not one I can reproduce. What dhcpcd version are you running?

cmcqueen commented 2 years ago

I would like to understand why you need to change the metrics once dhcpcd is running.

I have an embedded Linux device with Ethernet WAN and Wi-Fi client both active. Normally, the routing metric is set up so the Ethernet WAN is the preferred route.

But, something may go wrong with the Ethernet WAN route, so packets aren't getting through, even though the interface still appears "up" (eg someone unplugs a cable on an upstream switch/router). I have a monitoring task that, using policy based routing, is able to periodically test connectivity on each of Ethernet WAN and Wi-Fi. If Ethernet WAN is a bad route, then the goal is to dynamically change the route metrics so the Wi-Fi becomes the preferred route. And vice-versa.

However, dhcpcd should not remove the address on SIGHUP, that sounds like a bug and not one I can reproduce.

Looking in the code, I see that SIGHUP results in a call to both reload_config() and reconf_reboot(). Does reconf_reboot() redo all addresses, both IPv6 and IPv4?

What dhcpcd version are you running?

I'm running v8.1.6. Built by Yocto dunfell, for an ARM64 embedded Linux system.

rsmarples commented 2 years ago

Assuming that we only care about router reachability we can automate this in dhcpcd itself.

Linux has unreachability detection here: https://github.com/NetworkConfiguration/dhcpcd/blob/master/src/if-linux.c#L902 IPv6 ND handling code here: https://github.com/NetworkConfiguration/dhcpcd/blob/master/src/ipv6nd.c#L694 So when we make the route for the prefixes we can bump the route metric if it's unreachable here: https://github.com/NetworkConfiguration/dhcpcd/blob/master/src/ipv6.c#L2185

We could then extend this to DHCP as well. This would work fine for Linux and NetBSD as their ARP implementations work in a similar fashion to IPv6 ND - other OS's have crusty ARP implementations where this would not work, but heh ho.

Would this satisfy your use case?