Skip to main content
RunBook Academy

OPNsenseXIV · VLANs and SegmentationVLAN foundations

802.1Q and VLAN trunking — what tagged frames actually are

Intermediate⏱ ~14 mintcpdumpifconfigvlan

What you'll learn

  • Describe the 802.1Q tag and where it sits in an Ethernet frame
  • Explain trunk ports, access ports and the native VLAN
  • Identify the wire-level difference between tagged and untagged traffic
  • Recognise the production failure modes of misconfigured trunk ports

Prerequisites

Verified against OPNsense 25.x · FreeBSD 14.x · PF (FreeBSD packet filter) FreeBSD 14.x · Unbound 1.20+ · Kea DHCP OPNsense 25.x plugin · WireGuard in-kernel + OPNsense plugin · strongSwan (IPsec plugin) OPNsense 25.x plugin · OpenVPN 2.6.x · Suricata 7.x · 2026-08-14

Not yet marked complete on this device.

The firewall operator who has never read a tagged frame at the bit level is working at one remove from the production system. 802.1Q is not an opaque feature of the switch; it is a 4-byte field inserted into a real Ethernet frame, and tcpdump shows it. This lesson covers what is on the wire, what trunk and access ports actually do, what the native VLAN is, and the production failure modes that come from getting any of those wrong.

The OPNsense firewall terminates VLANs because the firewall itself is the boundary between VLANs. To terminate a VLAN, the firewall must understand the tag, must know what to do with a frame that carries the tag, and must be able to forward the inner payload to the right sub-interface. Every one of those steps is observable on the wire with a packet capture.

The 802.1Q frame

A normal Ethernet II frame looks like this:

+---------+---------+-----------+---------+-----------+
| Dst MAC | Src MAC | Ethertype | Payload |   FCS     |
+---------+---------+-----------+---------+-----------+
   6 B       6 B       2 B       46-1500    4 B

An 802.1Q-tagged frame inserts a 4-byte tag between the source MAC and the ethertype:

+---------+---------+--------+--------+-----------+---------+-----------+
| Dst MAC | Src MAC |  TPID  |   TCI  | Ethertype | Payload |   FCS     |
+---------+---------+--------+--------+-----------+---------+-----------+
   6 B       6 B     2 B      2 B       2 B       46-1500    4 B
              |        |        |
              |        |        +--- 3 bits PCP (priority) + 1 bit DEI + 12 bits VLAN ID
              |        +------------ 0x8100 (tag protocol identifier)
              +------------------- 4 bytes total inserted between Src MAC and Ethertype

The TPID is the constant 0x8100. When a NIC sees that value after the source MAC, it knows the frame is tagged. The TCI holds a 3-bit Priority Code Point (PCP, for QoS), a 1-bit Drop Eligible Indicator (DEI), and the 12-bit VLAN ID. VLAN IDs run from 0 to 4095, with 0 and 4095 reserved; usable IDs are 1–4094.

The ethertype that follows the tag is the inner ethertype — typically 0x0800 for IPv4 or 0x86DD for IPv6. The outer ethertype (the one right after the source MAC) is always 0x8100 for a tagged frame. This is how the receiver knows the frame is 802.1Q.

Trunk and access ports

A switch port operates in one of two modes:

  • Access port. Carries traffic for a single VLAN. The switch strips the 802.1Q tag on egress (frames leave the port untagged) and inserts the tag on ingress (frames arrive at the switch untagged). Hosts connected to access ports do not see 802.1Q tags; they see ordinary Ethernet.
  • Trunk port. Carries traffic for multiple VLANs. The switch does not strip the tag on egress; frames leave tagged. A trunk port is identified to a switch by the list of VLAN IDs it is allowed to carry, and the operator configures that list explicitly.

The firewall’s NIC is usually connected to a trunk port. The firewall is responsible for stripping the tag (because the kernel exposes each VLAN ID as a separate sub-interface) and forwarding the untagged inner frame to the sub-interface.

Read-only / Safetcpdump vlan+arp
$ tcpdump -nei igb0 -e 'vlan 10 or arp'
12:34:56.789012 aa:bb:cc:11:22:33 > ff:ff:ff:ff:ff:ff, ARP, Request who-has 192.0.2.1 tell 192.0.2.50, length 28
12:34:56.789345 aa:bb:cc:11:22:33 > 66:77:88:99:aa:bb, ethertype 802.1Q (0x8100), length 46: vlan 10, p 0, ethertype ARP, Reply 192.0.2.1 is-at 66:77:88:99:aa:bb, length 28

Illustrative output

The first frame in the capture is untagged (no vlan field). The second is explicitly tagged with vlan 10, p 0 — the priority code point is 0 (best effort), the VLAN ID is 10. The same ARP exchange, two views.

The native VLAN

A trunk port has a special VLAN ID called the native VLAN. Frames for the native VLAN are sent untagged across the trunk. Every other VLAN on the trunk is tagged. The native VLAN exists to allow devices that do not understand 802.1Q tagging (older equipment, some management devices) to participate on the trunk by handling one VLAN untagged.

The default native VLAN on most switches is VLAN 1. Cisco switches have historically used VLAN 1 as both the default access VLAN and the default native VLAN on trunks; modern best practice is to use a dedicated, unused VLAN (e.g. VLAN 999 or some other reserved ID) as the native VLAN so that untagged traffic does not collide with anything else.

What the firewall kernel sees

When a tagged frame arrives on a NIC, the FreeBSD kernel performs tag stripping before the packet reaches PF. The kernel maintains a set of vlan\<N\> sub-interfaces (or, in OPNsense’s terminology, VLAN interfaces on top of a parent interface). For each sub-interface, the kernel knows which VLAN ID the sub-interface is bound to. When a tagged frame arrives:

  1. The NIC driver receives the raw frame.
  2. If the NIC supports VLAN hardware offload, the NIC itself strips the tag and delivers the inner frame to the right sub-interface queue. If not, the kernel strips the tag in software.
  3. The inner frame is delivered to the sub-interface as an untagged Ethernet frame.
  4. PF sees the inner frame as if it had arrived on a regular NIC, but the ingress interface is the sub-interface — not the parent.

The operator who captures on the parent interface sees tagged frames; the operator who captures on the sub-interface sees untagged frames.

Reading a tagged frame by hand

The 4-byte 802.1Q tag occupies a specific position in the frame. To read it manually from a hex dump:

Offset (bytes)  Field
0-5             Destination MAC
6-11            Source MAC
12-13           TPID (should be 0x8100 for 802.1Q)
14-15           TCI: PCP (3 bits) | DEI (1 bit) | VLAN ID (12 bits)
16-17           Inner ethertype
18-...          Payload
last 4          FCS (Ethernet CRC)

For example, the bytes 81 00 00 0a at offset 12 mean: TPID 0x8100 (tagged), TCI 0x000a (PCP 0, DEI 0, VLAN ID 10). The operator reading a hex dump can identify the VLAN by these 4 bytes alone.

When tagging breaks

Three production failure modes recur:

  1. Asymmetric trunk configuration. The switch is configured for VLANs 10, 20, 30 on the trunk; the firewall has sub-interfaces for 10, 20, 40. Frames for VLAN 30 from the firewall never reach the switch’s VLAN 30 (because the switch drops unknown VLANs), and frames for VLAN 40 from the switch never reach the firewall (because the firewall drops unknown VLANs). The symptom is intermittent: some VLANs work, others do not, and the failure does not correlate with anything obvious.

  2. Native VLAN mismatch. The switch’s native VLAN on the trunk is VLAN 1; the firewall’s parent interface has no configuration for VLAN 1. Untagged frames (which the switch sends for native VLAN traffic) are dropped by the firewall. The operator who has never configured the native VLAN on the switch often does not realise untagged frames are arriving.

  3. MTU overshoot on tagged frames. A host on VLAN 10 sends a 1500-byte packet. The frame is 1504 bytes on the wire (with the tag). If the switch is configured for an MTU of 1500 (not 1504) and the firewall driver also caps at 1500, the frame is dropped at one of those boundaries. Path MTU discovery can save the day if the firewall sends ICMP type 3 code 4, but many firewalls drop those.

Summary

  • An 802.1Q-tagged frame is a standard Ethernet frame with a 4-byte tag (TPID 0x8100 + TCI) inserted between the source MAC and the ethertype.
  • A trunk port carries tagged frames for multiple VLANs; an access port carries untagged frames for a single VLAN.
  • The native VLAN on a trunk is sent untagged. Misconfiguration of the native VLAN is a real production failure mode.
  • The FreeBSD kernel (and modern NICs) strip the 802.1Q tag before PF sees the frame. The tag is visible to tcpdump only when VLAN hardware offload is disabled.
  • Three production failure modes recur: asymmetric trunk configuration, native VLAN mismatch, and MTU overshoot.

Knowledge check · 4 questions

  1. Q1. An Ethernet frame carries the bytes 81 00 00 32 at offset 12 (between source MAC and ethertype). What VLAN ID is the frame tagged with?

  2. Q2. A trunk port configured with native VLAN 1 sends frames for VLAN 1 across the trunk without an 802.1Q tag.

  3. Q3. Which of the following are valid production failure modes of 802.1Q trunking? Select all that apply.

  4. Q4. You run tcpdump on the parent interface igb0 and see no vlan field on any frame, but hosts on VLAN 10 work normally. What is the most likely explanation?

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