A quick note for me on switching between wireless and wired networks on my FreeBSD laptops.
For a long time I've been confused at how to switch from the wireless (iwn0) connection to a wired one (em0). I'm mostly using a ThinkPad X220 (currently on 14.3-RELEASE), which has both a wireless card and (like all good machines should) a network jack. The network is setup as following /etc/rc.conf:
wlans_iwn0="wlan0"
ifconfig_wlan0="WPA DHCP" # remove WPA when using an open networkwith the relevant details for joining the network in /etc/wpa_supplicant.conf, all as described in the FreeBSD Handbook.
I did, for a while, have a LAGG setup which would switch between the two (as per example 3), but that ended up causing confusion when I wanted to try more complicated networking with jails, and 99% of the time I use the wireless, so there wasn't a big advantage.
But when I wanted to switch, I thought all I had to do was (running as root):
# ifconfig wlan0 down
# dhclient em0 # implicitly 'up's the interfaceWhich should turn the wireless off, and get a new IP address and DNS information from the network. Except it didn't work. I could connect to IP in the browser, ping local machines and drill(1) would give me correct DNS resolution - but, I couldn't connect to any websites in the browser. Typing henryleach.com into would result in browsers claiming there was no network connection.
Turns out the problem is that down isn't sufficient to completely kill off the connection somehow. I've not understood the details, but I suspect this is what this line in the ifconfig(8) manual page "..This action does not automatically disable routes using the interface." is alluding to. More digging didn't reveal to me what the actual difference is (if you have a good explanation, please let me know).
To properly kill the connection it's necessary to also 'destroy' the cloned wlan0 interface, so the steps should be:
# ifconfig wlan0 down
# ifconfig wlan0 destroy
# dhclient em0With wlan0 completely gone, I didn't have this strange half state that confused the browsers. Or it's possible just to do:
# service netif stopThat will down and destroy the cloned interface for you. Once finished with the wired connection, you can ifconfig em0 down and start netif again with service netif start.
What's Happening?
After asking on Mastodon I got some hints to what might be happening, and certainly it's possible to see that the default route doesn't seem to update when not using the 'destroy' option, but what is triggering this still isn't clear to me.
When starting the network with wlan0 as per the rc.conf file above, then using netstat(1) we can see the following:
# netstat -4 -r -n | grep -v lo0
Routing tables
Internet:
Destination Gateway Flags Netif Expire
default 10.0.0.1 UGS wlan0
10.0.0.0/16 link#3 U wlan0Here 10.0.0.1 is the router/firewall of my home network. Using route(8) on the 'default' route shows:
# route -4 -d get default
route to: default
destination: default
mask: default
gateway: <10.0.0.1 full domain name>
fib: 0
interface: wlan0
flags: <UP,GATEWAY,DONE,STATIC>
recvpipe sendpipe ssthresh rtt,msec mtu weight expire
0 0 0 0 1500 1 0The running the commands that end up leaving the machine in a confused state:
# ifconfig wlan0 down
# dhclient em0Results in netstat still showing wlan0 for the Net(work)i(nter)f(ace) on the default route:
# netstat -4 -r -n | grep -v lo0
Routing tables
Internet:
Destination Gateway Flags Netif Expire
default 10.0.0.1 UGS wlan0
10.0.0.0/16 link#1 U em0and route shows:
# route -4 -d get default
route to: default
destination: default
mask: default
gateway: <10.0.0.1 full domain name>
fib: 0
interface: wlan0
flags: <UP,GATEWAY,DONE,STATIC>
recvpipe sendpipe ssthresh rtt,msec mtu weight expire
0 0 0 0 1500 1 0Which seems to prove that the route isn't updated with just the 'down' option. Doing things cleanly with:
# service netif stop
# dhclient em0We can see em0 listed in netstat:
# netstat -4 -r -n | grep -v lo0
Routing tables
Internet:
Destination Gateway Flags Netif Expire
default 10.0.0.1 UGS em0
10.0.0.0/16 link#1 U em0and route:
# route -4 -d get default
route to: default
destination: default
mask: default
gateway: <10.0.0.1 (gateway) full domain name>
fib: 0
interface: em0
flags: <UP,GATEWAY,DONE,STATIC>
recvpipe sendpipe ssthresh rtt,msec mtu weight expire
0 0 0 0 1500 1 0I also did some searching through /etc/rc.d/netif, but wasn't able to see any reference to the difference, but that's probably just my limited ability to understand longer shell scripts (a 'language' I have to admit I find hard to work with for anything but the most basic scripts).
The other thing that currently doesn't work for me, even doing service netif stop and then dhclient em0, is that the route for the loopback/localhost, lo0, interface, which I notice when testing this post using Hugo's built in server. That normally serves a page at http://localhost:1313, but with the above this doesn't work anymore.
After a normal 'netif start', including the local interface I see:
# netstat -4 -r -n
Routing tables
Internet:
Destination Gateway Flags Netif Expire
default 10.0.0.1 UGS wlan0
10.0.0.0/16 link#3 U wlan0
<my IP> link#2 UHS lo0
127.0.0.1 link#2 UH lo0and route shows:
# route -d get 127.0.0.1
route to: localhost
destination: localhost
fib: 0
interface: lo0
flags: <UP,HOST,DONE,PINNED>
recvpipe sendpipe ssthresh rtt,msec mtu weight expire
0 0 0 0 16384 1 0Then after that netstat shows zero routes, and running dhclient em0, doesn't restore this route:
# netstat -4 -r -n
Routing tables
Internet:
Destination Gateway Flags Netif Expire
default 10.0.0.1 UGS em0
10.0.0.0/16 link#1 U em0
<my IP> link#2 UHS lo0Which then implies if you want to make sure all the routes you're normally expecting work, it's best to change the configuration in /etc/rc.conf and then stop and start netif, as it's clearly doing some additional things that right now I can't figure out.
The only other point of interest I could see is that on OpenBSD's ifconfig(8) man page it says next to the 'down' option: "This action automatically disables routes using the interface.". Then I'm assuming that there (I don't currently have an OpenBSD installation up and running) just the 'down' option would work?