I use /etc/dhclient-enter-hooks and /etc/dhclient-exit hooks to override functions in dhclient-script.
That way I can control which interface updates /etc/resolv.conf and/or default routes even in FIB's that are not associated directly with the interface if I want, or multiple FIB's, etc.. On Fri, Sep 19, 2025 at 12:19 PM Roy Marples <[email protected]> wrote: > You could look into using dhcpcd from ports which solved this multihome > issue years ago. > > Each interface automatically get a metric based on type and index. This is > override able, lowest wins. > For any competing setup, lowest takes precedence and seamlessly changes > when the interface goes down or loses a lease. > > Roy > > > > ---- On Fri, 19 Sep 2025 20:13:45 +0100 *Andriy Gapon <[email protected]>* > wrote ---- > > > > Admittedly not a very common configuration, but still possible and some > people > have it (according to the Internet). I am also trying to set up such a > configuration for "reasons". > > In the simplest form, there are two network interfaces connected to two > different networks. Each network has its own DHCP server, its own router / > gateway to the wider Internet, its own DNS server(s), etc. The networks > are > likely to be completely unaware of each other. > > The host itself may be a router providing internet access to another local > network via another interface (or even multiple networks + interfaces). > But > that's not important. > > Some things provided via DHCP are per interface, but others are per host > ("global"). Each interface can get its own IP address, that's fine. > But, for example, which gateway to select for the default route? > > Dealing with those "global" things is the main issue in such a setup. > > What do we have now? > Specifically, with dhclient that's a part of the base. > > Essentially, it has a winner takes it all approach. > That's implemented in the default dhclient-script and the gist of the > logic is > in is_default_interface() function. Whichever interface is first to get a > lease > with a router wins. dhclient-script would set the default route to the > router > and as long as the default route goes through the interface, the interface > remains the winner (for subsequent updates). > > So, the winner gets to set the default route. > The winner also gets to set the resolver configuration (using > resolvconf(8), by > default). > Losers can only configure their interface, other information is lost. > > If DHCP is simply configured for multiple interfaces via rc.conf, without > any > extra settings, then there is an obvious problem. A winner would depend on > random things like which interface gets link first, which DHCP sever is > more > responsive, etc. And a random winner is not always what is desired. > > As far as I know, there is no way to set any priority or anything like > that. > I found only two solutions used by other people, both not ideal. > > One solution is to start dhclient-s "manually" (i.e., outside of rc.conf > declarative configuration) via something like rc.local. This way we can > control > which interface gets configured first. > > The other approach is to create a dhclient.conf configuration for the > "secondary" interface(s) which would ignore the "global" options (routers, > name > servers, etc). This way the "primary" interface would be the only one that > gets > and sets the global configuration while all interfaces get their > individual IP > configuration. > > The latter approach is "less intrusive" (more declarative), but it has a > flaw > that if the selected primary network is down then there would be no > default > route at all. > > Both solutions still have the issue of discarding the global options from > the > secondary interface (either explicitly in dhclient.conf or by > dhclient-script's > strategy). And those options may come handy if we want to dynamically flip > (and > as seamlessly as possible) between interfaces based on some events / > criteria. > > It's especially interesting that dhclient uses the power of resolvconf(8) > (unless forced to update /etc/resolv.conf directly) but still takes only > the > winner's configuration. > I think that it could just add configurations from all interfaces and let > resolvconf(8) deal with that. And an administrator would have control over > how > multiple configurations are merged via resolvconf.conf. Especially, if a > local > resolver (like unbound, for instance) is used. E.g., it would be possible > to > use different name servers based on domain, etc. > > Regarding routing, these days we can have multiple FIBs, so instead of > discarding "secondary" routing information we could use it to configure a > non-default FIB. > > Initially, I wanted to start working on some changes to dhclient-script to > implement those ideas. But then it occurred to me that it would easier to > get > what I want by changes external to dhclient. > > If there was a way to run a secondary dhclient with a non-default FIB > (e.g., via > setfib) then that alone would achieve the goals: > - the secondary dhclient would be considered a winner because it's the > only one > to set the default route of the FIB; > - so, it would obviously set the default route in the FIB; > - and because the dhclient is considered a winner, it would also call > resolvconf. > > I wonder if it would be a good idea to run dhclient under setfib if an > interface > is configured with DHCP/DHCPSYNC "virtual" option and real ifconfig 'fib' > option. > Or would that clash with some other uses / intentions? > Then maybe we could add another virtual option like FIB<X> or DHCPFIB<X>? > Or, probably even better, some thing like dhclient_fib_IF=X? > Akin to background_dhclient, for example. > > The standard dhclient_fib option is, obviously, of no use because it would > put > all dhclient-s into the same FIB. > > -- > Andriy Gapon > > > > >
