0

I want to put my wifi interface wlp3s0 into 4addr mode before adding it to the bridge br0, so I write following /etc/systemd/system/4addr2.service:

[Unit]
Description=Put interface into 4addr mode
Before=sys-subsystem-net-devices-br0.device
After=sys-subsystem-net-devices-wlp3s0.device

[Service]
Type=oneshot
ExecStart=/sbin/iw dev wlp3s0 set 4addr on
RemainAfterExit=true

[Install]
WantedBy=sys-subsystem-net-devices-br0.device

However I see that this service runs BEFORE sys-subsystem-net-devices-wlp3s0.device unit:

enter image description here

jounalctl also didn't give explanation why 4addr2 started before sys-subsystem-net-devices-wlp3s0.device:

$ sudo journalctl -u 4addr2
-- Logs begin at Thu 2020-09-03 08:44:03 EDT, end at Thu 2020-09-03 08:48:53 EDT. --
Sep 03 08:44:05 router systemd[1]: Starting Put interfaces into 4addr mode...
Sep 03 08:44:05 router iw[393]: command failed: No such device (-19)
Sep 03 08:44:05 router systemd[1]: 4addr2.service: Main process exited, code=exited, status=237/KEYRING
Sep 03 08:44:05 router systemd[1]: 4addr2.service: Failed with result 'exit-code'.
Sep 03 08:44:05 router systemd[1]: Failed to start Put interfaces into 4addr mode.

How can I understand why my service started before interface device initialized?

2

Before= and After= only have an effect when sorting jobs that are already part of the job queue, whereas .device units aren't usually part of it – they're not "started", they just pop up out of nowhere, because they only represent what has happened externally.

So you will additionally need to list the same wlp3s0.device in Requires= or even BindsTo=. That way systemd will try to "start" the .device unit (which is defined as waiting for the device to appear), and this will make After= work.

But for a related reason, it won't help to order a service Before=br0. Doing so will not delay the creation of br0, nor the addition of other interfaces to it, because both of those things happen externally and not via systemd.

If you are currently using systemd-networkd to do this, you might need to remove that and instead use the same custom .service to assign the bridge:

ExecStart=/sbin/iw dev wlp3s0 set 4addr on
ExecStart=/sbin/ip link set wlp3s0 master br0

(There might also be other approaches, such as creating a whole new wireless dev that already has 4addr enabled from the beginning, using iw ... interface add on the same phy.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.