How to set priority for multiple network interfaces?

cracauer@

Developer
Let's say I have a laptop with wlan and GbE. Both are configured for DHCP in /etc/rc.conf. Both get their IP addresses and netmasks. I consistently get the default route set to the wlan interface, although I want it on the ethernet interface.

Is there a way to achieve that with the existing /etc/rc infrastructure?


And speaking of this, does anybody have a reliable script that would switch from wlan0 to ethernet when either a carrier on a built-in interface comes along, or even when a hot-pluggable ethernet adapter is added?
 
If if_lagg(4) is supported by both your wired and wireless interfaces, it would help you with failover protocol.
My current environment doesn't support (if I recall correctly, iwlwifi(4) not yet supports it and not yet stable enough for my environment), so I cannot at all whether it currently work as before or not.

One thing I could recall is that MAC address of both interfaces must match for configuration you want (means, can override MAC address with whatever you want by ifconfig(8) or anything else).
 
Though I know you want existing rc infrastructure.
rc.conf(5)
Code:
The variable can contain arguments to ifconfig(8),
as well as special case-insensitive keywords described below.
Such keywords are removed before passing the value to
ifconfig(8) while the order of the other arguments is
preserved.
So I guess something like
Code:
ifconfig_wlan0="DHCP metric 100"
may work?

I think I was using bridge in similar setup years ago, bridging wired and wireless interfaces and running DHCP client on that bridge. Bonus - you have same IP address all the time and you don't loose open connections when changing from wifi to wire and back.
 
I don't think interface metric alone will work.

The only default route sits on the wlan interface, the GbE interface doesn't have access to the interwebs.

If I am not mistaken I must manipulate the script running the various dhclients to only access the default route from the interface I prefer.
 
Any chance of using carp for the interfaces? I know it probably isn't what you want, but it would at least take care of the availability locally.
 
The only default route sits on the wlan interface, the GbE interface doesn't have access to the interwebs.
As a data point, if you disable the wlan interface, does the GbE get a default route?
Asking since I had something similar on a Linux system at $WORK, the second interface default route wound up overriding the default route from the wired. Vauge memory it was an option on the WLAN bits to say something like "ignore the default route"

Do the two interfaces wind up on 2 different networks/subnetworks?
 
I still think if_lagg(4) fits this situation if both interfaces support it.
failover Sends traffic only through the active port. If the master
port becomes unavailable, the next active port is used. The
first interface added is the master port; any interfaces
added after that are used as failover devices.

By default, received traffic is only accepted when it is
received through the active port. This constraint can be
relaxed by setting the net.link.lagg.failover_rx_all
sysctl(8) variable to a nonzero value, which is useful for
certain bridged network setups.
The only default route sits on the wlan interface, the GbE interface doesn't have access to the interwebs.
Assuming that GbE interface is connected to completely closed intranet and other computers/controllers are linked each other or any hosts on the intranet (maybe including you are mentioneng), making network segments different with wired and wireless networks could be sufficient (if not yet done). This case, even if_lagg(4) would be unneeded, but in this case, to not confusing the network by name service, wired network could be forced to use /etc/hosts based and stop propagating name server from wired DHCP server. Possibly overlooking something...
 
I will look into if_lagg. Although I would like a solution that works with any NIC driver around. Will keep you updated.
 
... a reliable script that would switch from wlan0 to ethernet when either a carrier on a built-in interface comes along, or even when a hot-pluggable ethernet adapter is added?
Don't know if I understand what you're trying to achieve. A script that constantly looks for link up/down events would likely have to run as a daemon. That's what devd already does and it allows you to run a script in case of a link up or link down. Create a file with suffix .conf in /usr/local/etc/devd and start with this in it:

Code:
notify 100 {
    match "system"      "IFNET";
    action "/usr/bin/logger IFNET 1-$device 2-$class 3-$device-name 4-$bus 5-$notify 6-$parent 7-$mode 8-$notify 9-$cdev a-$type $vendor:$product $*";
};

Then restart devd and plug in a USB-adapter or a cable. See the messages in [/var/log/messages, the vars and values can help to add the match "var" "value" lines needed to filter out the event(s) you need.
Devd knows LINK_UP and LINK_DOWN type events, see devd.conf() under IFNET. Once you filtered out the LINK_UP you need, you replace action with a command or a script name. You can use the variables in that action line, var $subsystem contains the name of the interface and $type will be either LINK_UP or LINK_DOWN.
 
I also had similar cases several times, where I really just wanted two (or more) default routes with different priorities...
You can build fallback routing with multiple FIBs and PF (PF/OPNsense does it this way too), but it always feels like an overcomplicated hack for something that should be much easier...
I think we really need route priorities like OpenBSD has: https://man.openbsd.org/route#priority
 
I don’t have anything automated when I plug in, but when I want to switch service netif stop wlan0 && service netif start em0 does the job.
 
I will look into if_lagg. Although I would like a solution that works with any NIC driver around. Will keep you updated.
I've used lagg(4) for years. There are some differences, such as wpa_supplicant bugs that you won't experience the previous bug using wlan(4) directly. lagg(4) used to switch from my ethernet to wlan(4) and back again. But as of a commit a number of months ago (maybe a year or more) it will switch from the priority 1 NIC to the priority 2 NIC (wlan0) but not back again.

Also, if you use wake on LAN on your ethernet interface, put ifconfig lagg0 down in rc.shutdown or the shutdown code in the driver will never enable WOL on the ethernet NIC because it will never be called by the kernel. lagg(4) doesn't expose underlying wol. The real fix would be to have the kernel shut down lagg(4) -- actually all cloned interfaces -- prior to shutting down interfaces directly associated with hardware. (On my todo list.)
 
Back
Top