I have this configuration to put my LAN and WAN (not AP) network interfaces on the same bridge but I'm wondering if there is a better way to do it? Has anyone done this in a better way? Thanks.
I've only tested it on Ubuntu 22.10 with Network Manager
disabled and systemd-networkd
enabled. I did that part like this:
sudo systemctl disable --now NetworkManager-dispatcher.service NetworkManager-wait-online.service NetworkManager.service
sudo systemctl enable --now systemd-networkd.service
Install some packages, you definitely need iw
while bridge-utils
and ebtables
are optional but good to have for troubleshooting, etc.
sudo apt install bridge-utils ebtables iw
In the netplan yaml file below:
- Replace eth0 with the name of your LAN network interface.
- Replace wlan0 with the name of your LAN network interface.
For network interface names, see the output of running these commands:
ip a
and ip l
Create: /etc/netplan/02-bridge.yaml
Contents:
network:
version: 2
renderer: networkd
ethernets:
eth0:
dhcp4: no
wifis:
wlan0:
dhcp4: no
access-points:
"<your SSID>":
password: "<your password>"
bridges:
br0:
dhcp4: yes
interfaces:
- eth0
- wlan0
Copy the systemd-networkd.service unit file to the directory where administrators can override unit files. It is not safe to edit a unit file under /lib/systemd/system because a package update can overwrite your modifications. This is by design.
sudo cp /lib/systemd/system/systemd-networkd.service /etc/systemd/system/systemd-networkd.service
Then edit /etc/systemd/system/systemd-networkd.service
, adding an ExecStartPre
above the existing ExecStart
.
$ diff -u /lib/systemd/system/systemd-networkd.service /etc/systemd/system/systemd-networkd.service
--- /lib/systemd/system/systemd-networkd.service 2022-09-20 11:19:06.000000000 -0400
+++ /etc/systemd/system/systemd-networkd.service 2022-10-09 20:48:35.657885031 -0400
@@ -23,6 +23,7 @@
BusName=org.freedesktop.network1
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW
DeviceAllow=char-* rw
+ExecStartPre=-/sbin/iw dev wlan0 set 4addr on
ExecStart=!!/lib/systemd/systemd-networkd
ExecReload=networkctl reload
LockPersonality=yes
I do that because the iw ... 4addr
, which turns on WDS mode has to happen before the wlan0 interfaces is added to the br0 bridge or you get:
Oct 09 14:14:34 wookums systemd-networkd[2006]: wlan0: Failed to set master interface: Device does not allow enslaving to a bridge. Operation not supported
Once WDS ("4addr") mode is enabled that error no longer happens.
I tried to use networkd-dispatcher
to set WDS ("4addr") mode but it is started after systemd-networkd
attempts to put wlan0 into the br0 bridge and fails because WDS has not yet been enabled.
It seems really gross to have to cram something into systemd-networkd.service
just to have one line of code be run before something goes wrong because it wasn't run in time.
Aside from the obvious improvement of using a systemd unit file drop-in instead of copying all of systemd-networkd.service into /etc/systemd/system, is there any way to this better?
UPDATE:
- wpa_supplicant connects to the AP using DHCP; the AP is a DHCP server and the wlan0 is a client. However, the IP address of wlan0 (acquired via DHCP) does not appear to be visible because bridge slaves do not have IP addresses assigned, only the bridge itself has one. The br0 and wlan0 interfaces will not have the same IP address; the wlan0 interface will not be usable even though
brctl show
and ip a
, etc. will look OK.
Thanks
KES