I have spent way too much time to configure VLAN ID X on underlying ethernet device Y with systemd-networkd. The documentation appears to be lacking a full example, so I decided to write a blog post after I finally succeeded.
To me the systemd-networkd-way seems a bit complex with quite some redundancy. 😕 The benefit for using it, however, is the declarative form and many features it offers which would take quite some scripting effort with plain 'ifupdown'. Those features are out of scope for this post, though.
The first step is to just register the VLAN ID – yes, just its number – as network device (netdev).
Despite it being named a 'dev' configured in a
NetDev section in a
.netdev file, it does not actually add a
(virtual) device yet. 🙄
Example (in e.g.
[NetDev] Name=myvlan Kind=vlan [VLAN] Id=123
Repeat this for as many VLANs that you need, each in a separate file. I did this for VLAN IDs 1234 and 1337 too.
The name of the file does not really matter; the files in
/etc/systemd/network/ are being processed in lexicographical
order and the VLANs are matched by the name in the NetDev.Name setting.
The second step is making the underlying ethernet device a member of VLAN(s) in a 'network' file. This will create virtual interfaces for each VLAN on all matched devices.
By example (in e.g.
[Match] Name=eth1 Type=ether [Network] Description=The unconfigured physical ethernet device # Make eth1 member of these three VLANs and create virtual # interfaces on it: VLAN=myvlan VLAN=othervlan VLAN=yetanother # In case of 'tagged only' setups, you probably don't need any IP # configuration on the link without VLAN (or: default VLAN). # For that just omit an [Address] section and disable all the # autoconfiguration magic like this: LinkLocalAddressing=no LLDP=no EmitLLDP=no IPv6AcceptRA=no IPv6SendRA=no
I expected this to happen in a link-configuration file at first.
Final configuration step three is the configuration of the (virtual) interface for the VLAN in another 'network' file matching the VLAN.
By example (in e.g.
[Match] Name=myvlan Type=vlan [Network] Description=The interface for myvlan # Very simple static IPv4-only address configuration. # Well, an IPv6-link-local address as well, by default. [Address] Address=10.1.2.3/24
Now that the configuration is done, restart the 'systemd-networkd' service to apply it and inspect the result.
systemctl restart systemd-networkd
root@myhost:~# networkctl list IDX LINK TYPE OPERATIONAL SETUP 1 lo loopback routable configured 2 eth1 ether carrier configured 3 wlp2s0 wlan off unmanaged 4 myvlan vlan routable configured 5 othervlan vlan routable configured 6 yetanother vlan routable configured
root@myhost:~# cat /proc/net/vlan/config VLAN Dev name | VLAN ID Name-Type: VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD myvlan | 123 | eth1 othervlan | 1234 | eth1 yetanother | 1337 | eth1
root@myhost:~# ip addr show dev eth1 2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether [...] root@myhost:~# ip addr show dev myvlan 4: myvlan@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether [...] inet 10.1.2.3/24 brd 10.1.2.255 scope global myvlan valid_lft forever preferred_lft forever inet6 fe80::fd5b:7cd4:d4c6:f123/64 scope link valid_lft forever preferred_lft forever
.123 to the interface name would already configure VLAN 123 on the interface before, e.g.
Alternatively, a name with
vlan123 would configure it using
/etc/network/interfaces like this:
# myvlan auto vlan123 iface vlan123 inet static vlan-raw-device eth1 address 10.1.2.3/24
Very short compared to systemd-networkd 😬, but also quite implicit.