Skip to main content
RunBook Academy

LinuxXXI · Advanced Linux NetworkingVLAN

VLANs and 802.1Q - segmenting a network with tags

Intermediate⏱ ~12 minipnetplansystemd-networkd

What you'll learn

  • Explain what a VLAN is and why production networks use them
  • Configure a VLAN subinterface with ip link
  • Configure a VLAN with Netplan and systemd-networkd, including the parent link stanza
  • Recognise when a switch trunk is the right configuration

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-11

Not yet marked complete on this device.

A VLAN (Virtual LAN) is a layer-2 broadcast domain. VLANs let one physical switch act as many independent switches. Hosts in different VLANs cannot communicate at layer 2 even though they share the same physical network. Inter-VLAN routing requires a router or layer-3 switch.

The 802.1Q tag

A VLAN is identified by a 12-bit tag (1-4094). When a frame goes on a “trunk” link (one that carries multiple VLANs), an extra 4-byte tag is inserted between the source MAC and the EtherType:

+--------+------+------+--------+------+--------+
|Preamble| Dest | Src  | 0x8100 | Tag  | EtherType | Payload | FCS |
|        | MAC  | MAC  | (TPID) |(TCI) |          |         |     |
+--------+------+------+--------+------+--------+

The TCI contains:

  • Priority Code Point (PCP): 3 bits, used for QoS.
  • Drop Eligible Indicator (DEI): 1 bit.
  • VLAN ID: 12 bits (1-4094; 0 and 4095 are reserved).

Most switches call the trunk port “tagged” and the per-VLAN endpoint port “untagged” or “access”.

Linux VLAN subinterface

Linux creates a VLAN subinterface named <parent>.<vlanid>. The vlanid is the VLAN tag number.

ip link add link eth0 name eth0.100 type vlan id 100
ip link set eth0.100 up
ip addr add 10.100.0.10/24 dev eth0.100
ip route add default via 10.100.0.1 dev eth0.100

The parent interface (eth0) carries the 802.1Q tag. The subinterface (eth0.100) is the untagged interface Linux presents to the rest of the stack.

Inspect

ip -d link show eth0.100

The output includes vlan id 100 and the protocol. The vlan protocol field is 802.1Q by default; some networks use Q-in-Q (0x88a8).

Configure with Netplan

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: no
  vlans:
    eth0.100:
      id: 100
      link: eth0
      addresses:
        - 10.100.0.10/24
      routes:
        - to: default
          via: 10.100.0.1

The vlans: key is at the same level as ethernets:. The link: key points to the parent interface.

Configure with systemd-networkd

A .netdev file creates the VLAN device:

# /etc/systemd/network/10-eth0.100.netdev
[NetDev]
Name=eth0.100
Kind=vlan

[VLAN]
Id=100

The parent link’s own .network file is what attaches it:

# /etc/systemd/network/10-eth0.network
[Match]
Name=eth0

[Network]
VLAN=eth0.100

A third file configures the VLAN device’s address:

# /etc/systemd/network/11-eth0.100.network
[Match]
Name=eth0.100

[Network]
Address=10.100.0.10/24
Gateway=10.100.0.1

Reload:

sudo networkctl reload
networkctl status eth0
networkctl status eth0.100

Three files, not two. The .netdev creates the device and the .network addresses it, but neither of them says which link the VLAN sits on. Only VLAN=eth0.100 in the parent’s [Network] section does that. It is the same pattern the bonding and bridge lessons use, where the port-side .network carries Bond= or Bridge=.

Configure with NetworkManager

sudo nmcli connection add \
  type vlan \
  con-name eth0.100 \
  ifname eth0.100 \
  dev eth0 \
  id 100 \
  ipv4.method manual \
  ipv4.addresses 10.100.0.10/24 \
  ipv4.gateway 10.100.0.1

sudo nmcli connection up eth0.100

Switch port configuration

The Linux side is only half of a VLAN. The switch port the host plugs into must be configured:

  • Access port: untagged on a single VLAN. The host sends untagged frames; the switch adds the tag internally.
  • Trunk port: tagged on multiple VLANs. The host must tag its own frames (this is what Linux does with a VLAN subinterface).

If the switch port is an access port and the host sends tagged frames, the switch drops them. If the switch port is a trunk but the host sends untagged frames, the switch treats them as the “native” VLAN - which may not be what you want.

VLAN 1 and the native VLAN

VLAN 1 is the default on most switches. It is also the default “native VLAN” - untagged frames received on a trunk port are assumed to belong to the native VLAN. Many organisations disable VLAN 1 entirely for security; do not use it for production traffic.

Knowledge check

Knowledge check · 5 questions

  1. Q1. What command creates a VLAN subinterface eth0.100 with VLAN ID 100?

  2. Q2. A switch access port and a host sending tagged frames will silently drop each other traffic.

  3. Q3. Which of the following can configure VLANs on Linux? Select all that apply.

  4. Q4. How many systemd-networkd files does a VLAN on eth0 need, and what does each one do?

  5. Q5. After a migration to systemd-networkd, eth0.100 is UP with the right address, ip link and networkctl status eth0.100 look healthy, and no traffic passes. What is the first thing to check?

Passing score: 75%. Answers are checked in this browser.