Or how I came to love
iwd for all of my networking needs...
I have a weird fascination with running as little software as possible on my machines.
For whatever reason, minimizing RAM usage scratches some weird itch of mine. And no, it's not infected. At least, I hope not...
Anyways, after watching a video on installing Arch Linux for fun (don't judge me), the presenter Ermanno (who's videos I VERY HIGHLY RECOMMEND) covered a change to the install process that Arch Linux made recently.
Or I suppose a more accurate description is a change that Arch Linux made to how to connect to a wireless network when you're installing. Keep in mind that the standard Arch Linux install process doesn't have a GUI or any desktop environment with a graphical installer. There's no comfy icon to click on to configure networking, nothing.
Out of curiousity, I started looking into this new replacement sofware -
Once I started falling down that rabbit hole, I discovered just how unnecessary
NetworkManager is in my setup.
Why this works for me§
Like I said, I run a minimal setup. This means I don't need nor want big fancy GUI's for my tools.
To give an example, I run:
- A tiling window manager (i3, bspwm, sway, river are all on regular rotation...)
- A CLI or ncurses-UI for connecting to wifi (this was
nmtuiwhen I was using
- A CLI VPN with no visual feedback or need to graphically configure said VPN.
- I don't connect to esoteric modems like PPPOE, etc from my laptop or desktop.
With all this in mind, all of the "extra" features (read: bloat) of
NetworkManager mean that I'm paying a pretty steep cost in terms of dependencies and memory usage for things I simply don't need.
Note that there are some GUI tools for
iwdat this point, so check those out on the Arch Wiki if you're really curious.
How to make the change§
If you want to make the change yourself, it's actually pretty easy. I recommend doing things in this order, because if you can't get iwd/dhcpcd to work to your liking, it's trivial to go back to
Install iwd and dhcpcd (and openresolv)§
We need all three applications. In short,
dhcpcd handles the DHCP handshake (and thus giving you an IP address) when a connection is established, like plugging in an ethernet cable or connecting to a wifi network with
iwd. As stated
iwd handles wireless connections, that's it.
resolvconf implementation) handles the DNS configuration (mostly the maintenance of your
dhcpcd works with
openresolv automatically, you can read its documentation for more details.
I did mess around with using systemd-resolvd to have one less dependency, but ran into several issues with DNS configuration reliability. Just use
openresolvand you'll be much happier.
On Arch, I installed all necessary software with pacman like so:
# pacman -S iwd dhcpcd openresolv
Disable NetworkManager and wpa_supplicant§
Now that you've downloaded the necessary software, you've got to shutdown
wpa_supplicant to prevent conflicts between the two sets of software.
# systemctl stop NetworkManager wpa_supplicant
Note: Obviously, you'll lose internet at this point.
Start iwd and dhcpcd§
NetworkManager and its wireless sidekick taken care of, spin up iwd and dhcpcd.
# systemctl start iwd dhcpcd
dhcpcd handles all wired connections automatically, so if you're already connected with an ethernet cable you're done.
But, if you need to connect to a wireless network (as I'd wager 99.99% of people reading this do...), you'll need to configured
iwd to know about your wireless network.
To do so you can use the delightful companion for iwd -
You can run
iwctl directly, type
help, and then follow the corresponding documentation. Alternatively, you can pass all of your commands directly to
iwctl, as I demonstrate at the end of this section.
In my case, I simply needed to type the following:
$ iwctl [iwd]# device list wlan0 ...
I simply wanted to ensure that a wireless device was recognized, and it was. This isn't actually required to connect to an access point.
[iwd]# station wlan0 scan
Wait a few seconds as iwd looks up all the networks in your area...
[iwd]# station wlan0 connect "MyNetworkName"
Enter password when prompted and wait ~10 seconds to ensure you don't get an error back. If you do, you likely mistyped your password or your wifi is on the fritz.
Note that you can press
Tabto autocomplete pretty much all commands, including the wireless name above.
Exit out of the application.
Note that instead of using the
iwctl REPL, you can just feed the associated commands directly to
iwctl, like so:
$ iwctl station wlan0 connect "MyNetworkName"
I do like the REPL, as it holds your hand (if necessary), supports tab completion and just feels polished. Use whatever method you prefer.
Ensure you've got an IP address§
You may need to wait a few seconds as
dhcpcd do their corresonding thaaangs, but you should receive an IP address that looks somewhat familiar. You can check this with the
$ ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 60:e1:86:87:bc:89 brd ff:ff:ff:ff:ff:ff inet 192.168.1.217/24 brd 192.168.1.255 scope global dynamic noprefixroute wlan0 valid_lft 33914sec preferred_lft 28514sec inet6 fd22:f6c3:4e66::a7e/128 scope global dynamic noprefixroute valid_lft 35181sec preferred_lft 35181sec inet6 2600:6c52:7b00:55aa::a7e/128 scope global dynamic noprefixroute valid_lft 35181sec preferred_lft 35181sec inet6 fd22:f6c3:4e66:0:dcb8:7af:18a1:8bd9/64 scope global mngtmpaddr noprefixroute valid_lft forever preferred_lft forever inet6 2600:6c52:7b00:55aa:9af:4ba4:ee9b:d32d/64 scope global dynamic mngtmpaddr noprefixroute valid_lft 573699sec preferred_lft 573699sec inet6 fe80::1f0:1103:da4d:ee9b/64 scope link valid_lft forever preferred_lft forever
While that might seem like a wall of text, the
wlan0 is what I'm looking for and tells me that I'm properly connected to my home network.
You can confirm network + DNS connectivity with a simple:
$ ping austindw.com
Or use google.com, whatever you want...
If everything looks good, you can make the switch permanent:
# systemctl enable dhcpcd iwd # systemctl disable NetworkManager wpa_supplicant
Reboot, and you should come up with a perfectly working internet connection.
How to revert§
If you run into issues and you want to switch back, simply do:
# systemctl disable --now dhcpcd iwd # systemctl enable --now NetworkManager wpa_supplicant
This will immediately stop
iwd, then start
wpa_supplicant. With these commands, you'll even be safe to reboot and still use
"But Austin, I just replaced two networking programs with two more networking programs, how is this an improvement?"
Good question - if you measure the RAM usage before and after the switch, you should notice around a ~20MB reduction with the exact same end result.
Additionally, my wireless connections were much more stable with
iwd than with
NetworkManager. I used to have frequent disconnect/reconnect storms when I placed a decent amount of load on my wifi connection. I never quite tracked down the root cause, but the broader stroke of just replacing
NetworkManager completely has yielded a much improved networking experience.
So I have less resource usage, and an extremely stable wireless network connection.
I'm never going back to
NetworkManager if I can help it.
Hopefully this has helped convert you. Give it a try, and you just might be sold on the
dhcpcd power couple for life.