VLANs the systemd-networkd-way
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.
Register the VLAN IDs as a 'netdev'
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. /etc/systemd/network/00-myvlan.netdev
)
[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.
Tip
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.
Assign it to an underlying ethernet device
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. /etc/systemd/network/10-myethernet.network
):
[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.
Configure the VLAN interface with another network file
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. /etc/systemd/network/20-myvlan.network
):
[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
Apply the configuration and inspect
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
VLANs the old-school way
Adding a .123
to the interface name would already configure VLAN 123 on the interface before, e.g. eth1.123
.
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.