You are not logged in.

#1 2018-07-29 22:01:33

daniel_20180729
Member
Registered: 2018-07-29
Posts: 2

[SOLVED] Configuring Promiscuous Mode via systemd

Hi,
I am trying to configure a software bridge on Arch Linux (4.17.10-1-ARCH, systemd 239). In the end, the topology should look like this:

              sw0.2
               |
            (VID 2)
               |
<int. switch: sw0 eno1 ... >
                   |
                (VID 2)
                   |
    <ext. switch 0/13>

The physical Ethernet interface eno1 is the link to an external switch, while sw0.2 will connect the host to the network tagged on VLAN ID 2. In the future, other virtual hosts (e.g. containers) will be connected to the bridge as well (potentially on different VLAN IDs). I tired to configure this setup with networkd as follows:

eno1.network:
[Match]
Name=eno1

[Network]
Bridge=sw0

[BridgeVLAN]
VLAN=2
--------

sw0.2.netdev:
[NetDev]
Name=sw0.2
Kind=vlan

[VLAN]
Id=2
--------

sw0.2.network:
[Match]
Name=sw0.2

[Network]
DHCP=no

[Address]
Address=192.168.0.3/24

[Route]
Gateway=192.168.0.1
--------

sw0.netdev:
[NetDev]
Name=sw0
Kind=bridge

[Bridge]
DefaultPVID=none
VLANFiltering=yes
--------

sw0.network:
[Match]
Name=sw0

[Network]
DHCP=no
VLAN=sw0.2

[BridgeVLAN]
VLAN=2
--------

My problem with this setup is that the brige only works after I (manually) enable promiscuous mode on eno1, which seems logical for a bridge but also leads me to my first questions:

QUESTION-1: Is there a reason why promiscuous mode is not automatically enabled on a physical NIC that is a member of a bridge? Maybe there is something wrong with my configuration? Also, if I create the bridge manually and add a physical interface to the bridge, it will not enter promiscuous mode automatically either. So maybe it is a feature?

I tried to work around this issue by using a systemd service to enable promiscuous mode:

promiscuous_mode@.service:
[Unit]
Description=Control promiscuous mode for interface %i
After=network.target

[Service]
Type=oneshot
ExecStartPre=/sbin/ip a s
ExecStart=/sbin/ip link set promisc on dev %i
ExecStop=/sbin/ip link set promisc off dev %i
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

However, this does not work and results in the following error:

Jul 29 14:15:53 nas0 ip[425]: Cannot find device "eno1"

which is why I included the "ExecStartPre=/sbin/ip a s" line to see what is going regarding interface availability and naming.

Indeed, what I am seeing in the `journalctl -xe` output is:

-- Unit promiscuous_mode@eno1.service has begun starting up.
Jul 29 14:15:53 nas0 kernel: 8021q: 802.1Q VLAN Support v1.8
Jul 29 14:15:53 nas0 systemd-udevd[320]: link_config: autonegotiation is unset or enabled, the speed and duplex are not writable.
Jul 29 14:15:53 nas0 systemd-networkd[403]: request_name_destroy_callback n_ref=1
Jul 29 14:15:53 nas0 systemd[1]: Starting Permit User Sessions...
-- Subject: Unit systemd-user-sessions.service has begun start-up
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit systemd-user-sessions.service has begun starting up.
Jul 29 14:15:53 nas0 systemd-networkd[403]: sw0.2: netdev ready
Jul 29 14:15:53 nas0 systemd-networkd[403]: lo: Link is not managed by us
Jul 29 14:15:53 nas0 systemd-networkd[403]: eth0: Link is not managed by us
Jul 29 14:15:53 nas0 kernel: IPv6: ADDRCONF(NETDEV_UP): sw0: link is not ready
Jul 29 14:15:53 nas0 kernel: IPv6: ADDRCONF(NETDEV_UP): sw0.2: link is not ready
Jul 29 14:15:53 nas0 ip[420]: 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
Jul 29 14:15:53 nas0 ip[420]:     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
Jul 29 14:15:53 nas0 ip[420]:     inet 127.0.0.1/8 scope host lo
Jul 29 14:15:53 nas0 ip[420]:        valid_lft forever preferred_lft forever
Jul 29 14:15:53 nas0 ip[420]:     inet6 ::1/128 scope host
Jul 29 14:15:53 nas0 ip[420]:        valid_lft forever preferred_lft forever
Jul 29 14:15:53 nas0 ip[420]: 2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
Jul 29 14:15:53 nas0 ip[420]:     link/ether 68:05:ca:7b:2e:f5 brd ff:ff:ff:ff:ff:ff
Jul 29 14:15:53 nas0 ip[420]: 3: sw0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
Jul 29 14:15:53 nas0 ip[420]:     link/ether 06:21:80:af:f7:47 brd ff:ff:ff:ff:ff:ff
Jul 29 14:15:53 nas0 ip[420]: 4: sw0.2@sw0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
Jul 29 14:15:53 nas0 ip[420]:     link/ether 06:21:80:af:f7:47 brd ff:ff:ff:ff:ff:ff
Jul 29 14:15:53 nas0 kernel: checking generic (dd000000 300000) vs hw (dd000000 1000000)
Jul 29 14:15:53 nas0 kernel: fb: switching to astdrmfb from EFI VGA
Jul 29 14:15:53 nas0 kernel: Console: switching to colour dummy device 80x25
Jul 29 14:15:53 nas0 kernel: fbcon: astdrmfb (fb0) is primary device
Jul 29 14:15:53 nas0 systemd[1]: Started Permit User Sessions.
-- Subject: Unit systemd-user-sessions.service has finished start-up
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit systemd-user-sessions.service has finished starting up.
--
-- The start-up result is RESULT.
Jul 29 14:15:53 nas0 systemd-logind[405]: Watching system buttons on /dev/input/event2 (Power Button)
Jul 29 14:15:53 nas0 systemd-logind[405]: Watching system buttons on /dev/input/event0 (Sleep Button)
Jul 29 14:15:53 nas0 systemd-logind[405]: Watching system buttons on /dev/input/event1 (Power Button)
Jul 29 14:15:53 nas0 sshd[416]: Server listening on 0.0.0.0 port 22.
Jul 29 14:15:53 nas0 sshd[416]: Server listening on :: port 22.
Jul 29 14:15:53 nas0 ip[425]: Cannot find device "eno1"
Jul 29 14:15:53 nas0 kernel: Console: switching to colour frame buffer device 160x64
Jul 29 14:15:53 nas0 kernel: usb 1-14.1: New USB device found, idVendor=0557, idProduct=2419, bcdDevice= 1.00
Jul 29 14:15:53 nas0 kernel: usb 1-14.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
Jul 29 14:15:53 nas0 kernel: ast 0000:09:00.0: fb0: astdrmfb frame buffer device
Jul 29 14:15:53 nas0 systemd[1]: promiscuous_mode@eno1.service: Main process exited, code=exited, status=1/FAILURE
Jul 29 14:15:53 nas0 systemd[1]: promiscuous_mode@eno1.service: Failed with result 'exit-code'.
Jul 29 14:15:53 nas0 systemd[1]: Failed to start Control promiscuous mode for interface eno1.
-- Subject: Unit promiscuous_mode@eno1.service has failed
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit promiscuous_mode@eno1.service has failed.

So, at the boot stage where my promiscuous_mode@eno1.service is started only one of the 9 NICs in that machine is available and this NIC still goes by its "eth" name. Later in the boot process, the other 8 NICs become available and eventually get renamed to "enX", including eno1, which I want to use for the bridge. Setting `After=systemd-networkd.service` does not help either.

What helps, though, is inserting `ExecStartPre=/sbin/sleep 10` (as the first ExecStartPre command) to promiscuous_mode@.service (I did not attemt to minimize the sleep duration, I just tired 10 and it worked). The the `journalctl -xe` output now lists all 9 NICs. However, I do not consider adding a delay to "solve" this dependency a good idea.

This leads to my following questions:

QUESTION-2: Is there a networkd-way to configure promiscuous mode that I have missed? However, even the Arch Wiki seems to recommend creating a systemd service for that: https://wiki.archlinux.org/index.php/Ne … cuous_mode. Also, neither systemd.netdev(5), systemd.network(5), nor systemd-networkd(8) contain the pattern "promisc".

QUESTION-3: The Ethenet interface names do not seem to be immediately stable after network.target (but seem to take a couple of seconds to settle). Is there a different target to depend on (e.g. via `After=` in the service unit) when one relys on stable/final Ethernet interface names?

QUESTION-4: From the full `journalctl -xe` output it even seems that the remaining 8 NICs are attached after network.target and systemd-networkd.service have finished starting up. Is systemd even the right place to trigger the service that enables promiscuous mode or should the promiscuous mode service be triggered via e.g. udev after the device is attached?

Best regards,
Daniel

Update 2018/07/30: Mark solved.

Last edited by daniel_20180729 (2018-07-30 20:16:28)

Offline

#2 2018-07-30 14:18:50

lo1
Member
Registered: 2017-09-25
Posts: 584

Re: [SOLVED] Configuring Promiscuous Mode via systemd

QUESTION-1: Is there a reason why promiscuous mode is not automatically enabled on a physical NIC that is a member of a bridge? [...]
So maybe it is a feature?

It is indeed a feature, promiscuous mode is useful for debugging and bridging but, because of how it is intended to work, it introduces some security flaw and the user should acknowledge them.

QUESTION-2: Is there a networkd-way to configure promiscuous mode that I have missed?

Not that I know, but probably even this is a feature and not a bug.

QUESTION-3: The Ethenet interface names do not seem to be immediately stable after network.target (but seem to take a couple of seconds to settle). Is there a different target to depend on (e.g. via `After=` in the service unit) when one relys on stable/final Ethernet interface names?

The most elegant solution IMHO is to set static device naming with an ad-hoc udev rule.

QUESTION-4: From the full `journalctl -xe` output it even seems that the remaining 8 NICs are attached after network.target and systemd-networkd.service have finished starting up. Is systemd even the right place to trigger the service that enables promiscuous mode or should the promiscuous mode service be triggered via e.g. udev after the device is attached?

I'm sure this is doable with udev and if the right sysfs attribute is available, but unfortunately this goes beyond my knowledge.

Offline

#3 2018-07-30 20:10:39

daniel_20180729
Member
Registered: 2018-07-29
Posts: 2

Re: [SOLVED] Configuring Promiscuous Mode via systemd

Hi,

thanks for your insights! Your answers to my first two questions seem plausible - it's also more or less what I anticipated.

Regarding QUESTION-3, I, in the meantime, came across https://www.freedesktop.org/wiki/Softwa … orkTarget/, which mentions the "network-online.target" target. network-online.target waits until the network is "up". While the definition of "up" remains vague on the aforementioned website, it seems to do the trick in my case without any additional udev involvement.

So, my promiscuous mode service now looks like this:

promiscuous_mode@.service:
[Unit]
Description=Control promiscuous mode for interface %i
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/sbin/ip link set promisc on dev %i
ExecStop=/sbin/ip link set promisc off dev %i
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Thanks,
Daniel

PS: Also, thanks for the hint on static device names. I might consider this for this particular setup in the future (or switch to a MAC-based name policy (https://www.freedesktop.org/software/sy … .link.html)).

Offline

Board footer

Powered by FluxBB