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 <a...@freebsd.org> 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

Reply via email to