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.)
 
A small observation since it's relevant and this post came up in my research. I'm working through some OpenVPN patches for Haiku, and noticed that metric exists on the interface level under BSD, while Linux implements metric on the individual routes.

The Linux design allows for a "individual route cost", meaning the network stack tries lower cost routes before higher cost routes that have the same functional destination networks.

Haiku duplicated the interface level metric design FreeBSD has, and I think implementing it on the interface level leaves a lot of gaps around route prioritization. I'm trying to decide which design is better currently 😆
 
In my humble opinion, keeping per-interface metric as is and leaving per-route metric for routing protocol used would be make things simpler.

Because per-route metrics can quite easily changes with reasons the local admin (i.e., you) can not at all manage on Internet (especially outside the AS you're belong to).

Trying to set per-root metrics would need knowledges and authorities of
  • local statically-routed networks
  • simple routed based networks
  • BGP used for edge routers between ISPs (having their own AS) and routing informations propageted between them
all in realtime. Maybe more to know for effectively managing route-based metrics.

Of course, there are actually required if you really want fastest and most robust connections all the time.

And also does not apply if, for example, you have 1 interface in your computer, and via 1 or more hubs, 2 connections (ONU/Modem) to different upstream that one is FTTH and another is GSM/PDC cellular phone network. Clearly different in physical connection speeds.
In this example, only route-based metric would work automatically. But as I don't know about your network infrastructure, needed to consider a bit too paranoid cases that I myself cannot manage.
 
In my humble opinion, keeping per-interface metric as is and leaving per-route metric for routing protocol used would be make things simpler.
THIS.

Usually those basic priorities (metrics) are logically bound to the interface - i.e. ultimately its bandwidth, which is the main factor for the "route cost" in most scenarios anyways. But they are identical for all routes over a distinct interface and hence they simply inherit the priorities of the interface - that's clean, intuitive and what most people need if they handle multiple interfaces and static/default routes.
E.g. a fiber uplink and copper or mobile backup - the fiber gets the lowest metric, the backup a much higher. The default routes are then simply chosen by the lower metric. Intuitive, simple and what 99% of people will need. Nobody wants to fiddle with dhcp-hooks or scripts for a routing daemon to attach the correct priorities to default routes - that's just tedious and unnecessary. Always follow the KISS principle!

Managing more complex routing priorities is the job of distinct routing protocols as they usually are dynamic and can/need to change on more than one system - and also on systems outside of your network, because the return path also needs to be adjusted. If you are managing such routes manually with route priorities you are doing something horribly wrong...
 
Back
Top