$linuxjunkies
>

VLANs on Linux

Configure 802.1Q VLAN sub-interfaces on Linux using ip link and NetworkManager, covering switch trunk port setup, persistence, and firewall integration.

IntermediateUbuntuDebianFedoraArch9 min readUpdated June 7, 2026

Before you start

  • A physical or virtual NIC whose switch port is or can be configured as a trunk/tagged port
  • Root or sudo access on the Linux host
  • iproute2 installed (present by default on all major distros)
  • NetworkManager installed if using the nmcli method

VLANs (Virtual Local Area Networks) let you segment a single physical network into multiple isolated broadcast domains without buying extra hardware. On Linux, the kernel's 802.1Q driver handles VLAN tagging in software, and you configure it either with ip link directly or through NetworkManager. This guide covers both paths, touches on what your switch needs to do, and shows you how to verify everything is working.

How 802.1Q Tagging Works

When a frame leaves a VLAN-aware interface, the kernel inserts a 4-byte 802.1Q tag into the Ethernet header. That tag carries a 12-bit VLAN ID (1–4094). The switch reads the tag, forwards the frame on the correct VLAN, and either strips the tag (access port) or leaves it intact (trunk port) depending on port configuration.

On the Linux side, you create a VLAN sub-interface (e.g., eth0.10) on top of a physical or bond interface. The parent carries all tagged traffic; each sub-interface sees only frames for its VLAN ID.

Switch-Side Prerequisites

Before touching Linux, make sure the switch port connected to your Linux machine is configured as a trunk port (Cisco terminology) or tagged port (HP/Aruba/OpenWrt terminology). It must allow every VLAN ID you plan to use. A common setup:

  • Native/untagged VLAN: your management network (e.g., VLAN 1)
  • Tagged VLANs: everything else (e.g., VLAN 10, VLAN 20, VLAN 30)

If the switch port is an access port, VLAN sub-interfaces will not pass traffic — Linux will tag frames that the switch will simply drop.

This method works on any distro and survives without NetworkManager. Changes made here are not persistent across reboots unless you write a systemd-networkd unit or distro network config. Use it for testing or in conjunction with systemd-networkd.

Load the 8021q Kernel Module

Most kernels ship it as a module. Load it if it is not already present:

sudo modprobe 8021q

To load it automatically at boot, add it to modules-load:

echo '8021q' | sudo tee /etc/modules-load.d/8021q.conf

Create a VLAN Sub-Interface

Replace eth0 with your physical interface name and 10 with your VLAN ID:

sudo ip link add link eth0 name eth0.10 type vlan id 10

Bring it up and assign an address:

sudo ip link set eth0.10 up
sudo ip addr add 192.168.10.5/24 dev eth0.10

Add a default route via this VLAN if needed:

sudo ip route add default via 192.168.10.1 dev eth0.10

Inspect the VLAN Interface

ip -d link show eth0.10

Look for vlan protocol 802.1Q id 10 in the output. That confirms the tag is set correctly.

Persistent Configuration with systemd-networkd

Create two unit files — one for the VLAN definition, one for the address:

sudo tee /etc/systemd/network/10-eth0.network <<'EOF'
[Match]
Name=eth0

[Network]
VLAN=eth0.10
EOF
sudo tee /etc/systemd/network/20-eth0.10.netdev <<'EOF'
[NetDev]
Name=eth0.10
Kind=vlan

[VLAN]
Id=10
EOF
sudo tee /etc/systemd/network/20-eth0.10.network <<'EOF'
[Match]
Name=eth0.10

[Network]
Address=192.168.10.5/24
Gateway=192.168.10.1
EOF
sudo systemctl enable --now systemd-networkd

Method 2: NetworkManager

NetworkManager is the default on Fedora, RHEL, Rocky, Ubuntu Desktop, and most modern distros. It handles VLAN configuration cleanly through nmcli or the TUI nmtui.

Create a VLAN Connection via nmcli

sudo nmcli connection add \
  type vlan \
  con-name "vlan10" \
  ifname eth0.10 \
  vlan.parent eth0 \
  vlan.id 10 \
  ipv4.method manual \
  ipv4.addresses "192.168.10.5/24" \
  ipv4.gateway "192.168.10.1" \
  ipv4.dns "1.1.1.1" \
  connection.autoconnect yes

Activate the connection immediately:

sudo nmcli connection up vlan10

NetworkManager writes the connection profile to /etc/NetworkManager/system-connections/vlan10.nmconnection and brings it up at every boot automatically.

Using nmtui (TUI Method)

If you prefer a text interface, run sudo nmtui, choose Edit a connection, then Add, select VLAN, and fill in the device, VLAN ID, and IP settings. This is convenient on servers without a GUI.

Distro-Specific Notes

  • Debian/Ubuntu server: NetworkManager may not be installed by default. Install with sudo apt install network-manager, or use systemd-networkd instead.
  • Fedora/RHEL/Rocky: NetworkManager is the canonical tool. nmcli is fully supported; systemd-networkd is available but not the default.
  • Arch: Both NetworkManager (pacman -S networkmanager) and systemd-networkd are equally supported. Pick one and disable the other to avoid conflicts.

Multiple VLANs

Repeat the sub-interface creation for each VLAN ID. There is no limit imposed by Linux (the 802.1Q spec caps IDs at 4094). Each sub-interface gets its own IP, routing, and firewall rules:

# VLAN 20
sudo nmcli connection add type vlan con-name "vlan20" ifname eth0.20 \
  vlan.parent eth0 vlan.id 20 \
  ipv4.method manual ipv4.addresses "192.168.20.5/24" \
  ipv4.gateway "192.168.20.1" connection.autoconnect yes

# VLAN 30
sudo nmcli connection add type vlan con-name "vlan30" ifname eth0.30 \
  vlan.parent eth0 vlan.id 30 \
  ipv4.method manual ipv4.addresses "192.168.30.5/24" \
  ipv4.gateway "192.168.30.1" connection.autoconnect yes

Firewall Considerations

Each VLAN sub-interface is a separate network interface from the firewall's perspective. With nftables, you match on interface name. With firewalld (Fedora/RHEL), assign each sub-interface to a zone:

sudo firewall-cmd --zone=internal --add-interface=eth0.10 --permanent
sudo firewall-cmd --zone=dmz --add-interface=eth0.20 --permanent
sudo firewall-cmd --reload

On Ubuntu with ufw:

sudo ufw allow in on eth0.10 to any port 22

Verification

Confirm the interface is up and tagged:

ip -d link show eth0.10
ip addr show eth0.10

Send test traffic and capture tags with tcpdump on the parent interface:

sudo tcpdump -i eth0 -e -nn vlan

You should see frames with vlan 10 in the output. If the interface shows no RX traffic when you expect it, the switch port is almost certainly not trunking that VLAN ID.

Check the routing table is populated correctly:

ip route show

Troubleshooting

  • No traffic on the VLAN interface: Verify the switch port is a trunk/tagged port and that the VLAN ID is allowed on it. Use tcpdump -i eth0 -e vlan — if you see no tagged frames arriving, the problem is upstream.
  • Interface created but no IP: Check journalctl -u NetworkManager or journalctl -u systemd-networkd for DHCP or static address errors.
  • 8021q module not found: Your kernel may have it built in (grep 8021q /boot/config-$(uname -r) should show CONFIG_VLAN_8021Q=y). If it shows =m, modprobe should work; if it is absent, you need a custom kernel build.
  • Conflicting network managers: Running both NetworkManager and systemd-networkd managing the same interface causes unpredictable behavior. Check with systemctl status NetworkManager systemd-networkd and disable whichever you are not using.
  • MTU issues: The 802.1Q tag adds 4 bytes. If your network path has MTU set exactly to 1500, consider setting the VLAN interface MTU to 1496 or enabling jumbo frames on the physical interface.
tested on:Ubuntu 24.04Fedora 40Debian 12Arch 2024.05

Frequently asked questions

Can I use VLANs on a Wi-Fi interface?
Technically yes, but most Wi-Fi drivers and access points do not support 802.1Q trunking. It only works reliably if your AP is in bridge mode or supports per-SSID VLAN tagging, and even then driver support is inconsistent. Wired interfaces are strongly preferred.
Does the parent interface need an IP address?
No. The physical parent interface can be left with no IP (just brought up with 'ip link set eth0 up') while all addressing lives on the VLAN sub-interfaces. This is the standard approach when all traffic is VLAN-tagged.
What is the difference between a VLAN sub-interface and a bridge?
A VLAN sub-interface filters frames by 802.1Q tag. A bridge connects multiple interfaces at Layer 2 so they share a broadcast domain. You often use both together — for example, bridging a VLAN sub-interface to a VM's tap interface on a hypervisor.
Will VLAN interfaces appear in 'ip link show' output?
Yes. Every VLAN sub-interface appears as a normal interface in 'ip link show' output, indented under its parent when using 'ip -d link show'. You can also list only VLAN interfaces with 'ip link show type vlan'.
Can I change the VLAN ID of an existing interface without recreating it?
No. The VLAN ID is set at creation time and cannot be changed with ip link set. Bring the interface down, delete it with 'ip link delete eth0.10', then recreate it with the new ID.

Related guides