Linux 802.1Q VLAN Tagging on Physical Interfaces

The Linux operating system manages IEEE 802.1Q Virtual Local Area Network (VLAN) tagging by creating virtual network devices layered directly over physical network interfaces. This mechanism is powered by the Linux kernel's networking subsystem and the dedicated 8021q module, which processes tagged Ethernet frames, manipulates packet headers, and leverages network interface card (NIC) hardware acceleration. The following sections explain the underlying architecture, packet egress and ingress paths, user-space configuration, and hardware offloading capabilities.

The 802.1Q Kernel Architecture

At the core of Linux VLAN handling is the 8021q kernel module. When loaded, it registers the vlan device type with the kernel's network core. Rather than reconfiguring the physical interface itself to handle multi-tenant traffic internally, Linux introduces a parent-child device model:

Egress Processing (Transmitting Frames)

When an application sends data out of a VLAN sub-interface (e.g., eth0.100), the Linux network stack processes the packet through the following sequence:

  1. Routing and Socket Allocation: The routing table directs outbound packets to the virtual device interface (eth0.100).
  2. Socket Buffer (sk_buff) Tagging: The kernel prepares the packet buffer (sk_buff). It populates the 4-byte 802.1Q header fields:
    • Tag Protocol Identifier (TPID): Defaults to 0x8100.
    • Priority Code Point (PCP): 3 bits mapping Quality of Service (QoS) priorities from the socket.
    • Drop Eligible Indicator (DEI): 1 bit indicating frame drop priority during congestion.
    • VLAN Identifier (VID): 12 bits identifying the specific VLAN (ranging from 1 to 4094).
  3. Software vs. Hardware Insertion: If hardware offloading is disabled, the kernel modifies the packet payload directly by inserting the 4-byte tag into the Ethernet header before passing it down. If hardware offloading is enabled, the kernel stores the VLAN metadata inside the sk_buff descriptor rather than altering the frame payload.
  4. Transmission: The packet is handed over to the physical interface's queue discipline (qdisc) and dispatched through the device driver.

Ingress Processing (Receiving Frames)

When the physical network interface receives an 802.1Q tagged Ethernet frame from the wire:

  1. Frame Capture: The physical driver places the received frame into an allocated sk_buff.
  2. VLAN Demultiplexing: In the core reception path (__netif_receive_skb_core), the kernel inspects the frame. If the frame contains an 802.1Q tag, the kernel extracts the VID.
  3. Interface Lookup: The kernel searches an internal hash table for a child VLAN interface associated with both the parent interface and the extracted VID.
  4. Stripping and Repath:
    • If a matching VLAN device is found, the kernel strips the 802.1Q tag from the header (or retrieves it from hardware offload registers), updates the packet's receive device pointer from eth0 to eth0.100, and loops back into the packet processing stack.
    • If no matching interface exists and no bridge or raw packet socket is listening for untracked tags, the packet is discarded.
  5. Upper-Layer Processing: The untagged frame is passed upward to layer 3 (IPv4/IPv6) as if it arrived natively on a standard physical interface.

Hardware Offloading (Acceleration)

Software insertion and removal of the 4-byte 802.1Q header incurs CPU overhead due to memory copies and packet resizing. Modern NICs mitigate this via hardware offloading:

These offload capabilities can be queried and managed using ethtool:

# View offload status
ethtool -k eth0 | grep vlan

# Enable hardware TX/RX VLAN offloading
ethtool -K eth0 tx-vlan-hw-insert on
ethtool -K eth0 rx-vlan-hw-parse on

Configuration via iproute2

Linux manages VLAN interfaces natively via the modern ip utility. To create, activate, and manage an 802.1Q VLAN interface:

# Ensure the 8021q module is loaded
modprobe 8021q

# Create a VLAN sub-interface for VLAN ID 50 on eth0
ip link add link eth0 name eth0.50 type vlan id 50

# Assign an IP address to the VLAN interface
ip addr add 192.168.50.2/24 dev eth0.50

# Bring the physical and VLAN interfaces up
ip link set dev eth0 up
ip link set dev eth0.50 up

Through this abstraction, Linux provides a scalable, standards-compliant way to segment traffic without requiring multiple physical adapters.