OPNsenseXIV · VLANs and SegmentationVLAN foundations
VLAN creation and parent interfaces — building the trunk in OPNsense
What you'll learn
- Create a VLAN in the OPNsense GUI on top of a parent interface
- Assign the VLAN to a logical interface with a description
- Verify the VLAN at the FreeBSD kernel level with ifconfig
- Identify the configuration traps that prevent a VLAN from coming up
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
A VLAN in OPNsense is a three-step artefact: a tag defined on a parent interface, the tag assigned to a logical interface, and the logical interface configured with addressing and rules. Skipping any one of the three steps leaves the VLAN either non-existent at the kernel level or unconfigured at the firewall level. This lesson covers the creation path, the parent-interface decision, and the verification at the kernel and PF level.
The previous lesson covered the wire-level view of 802.1Q. This lesson covers what the operator does in the GUI and what the FreeBSD kernel exposes after the operator has done it.
The three artefacts
A working VLAN in OPNsense has three artefacts:
- VLAN definition. A record under
Interfaces → Assignments → VLANsthat binds a VLAN ID to a parent interface. - Interface assignment. The VLAN is assigned to a logical interface (e.g.
OPT1) underInterfaces → Assignments. The logical interface is what PF sees; the VLAN definition is what tells the kernel which tag to strip. - Interface configuration. The logical interface has an IPv4 (and optionally IPv6) address, a description, and rules under
Firewall → Rules.
A common confusion: the operator creates a VLAN definition but does not assign it to a logical interface. The VLAN exists in the OPNsense configuration but has no IP, no rules, and no presence in PF. The kernel may or may not have a vlan\<N\> pseudo-interface depending on how OPNsense handles unassigned VLANs.
Parent interface selection
The parent interface is the NIC or vNIC that carries the trunk. For most OPNsense deployments:
- LAN-side trunk: The NIC connected to the internal switch that carries VLANs for users, servers, management, etc.
- WAN-side: The WAN is typically on a separate, untagged NIC. ISPs that deliver services on VLAN tags (some IPTV, some business circuits) are the exception.
- DMZ-side trunk: A NIC connected to a DMZ switch, carrying one or more DMZ VLANs. Part XV covers this in detail.
$ ifconfig -ligb0 igb1 igb2 loIllustrative output
For a small deployment, the parent is typically igb1 (the LAN-side NIC). For a virtualised deployment, the parent is a vNIC (e.g. vtnet1) connected to a VLAN-aware bridge.
Creating the VLAN definition
In the OPNsense GUI:
- Navigate to
Interfaces → Assignments → VLANs. - Click Add to create a new VLAN.
- Fill in:
- Parent interface: the NIC or vNIC carrying the trunk (e.g.
igb1). - VLAN tag: the 802.1Q VLAN ID (1–4094). Pick an ID that matches the switch configuration exactly.
- Description: a human-readable name (e.g.
Servers,Guest,Management). The description appears in the GUI and in the generated configuration. - VLAN priority: the PCP bits in the 802.1Q tag (0–7). Leave at 0 unless QoS is in use.
- Parent interface: the NIC or vNIC carrying the trunk (e.g.
- Click Save, then Apply to push the change to the running configuration.
After the apply, the kernel creates a vlan\<N\> pseudo-interface. The name in the GUI is the logical interface name (e.g. OPT1); the underlying kernel name is something like igb1_vlan10 for a VLAN ID 10 on parent igb1.
Assigning the VLAN to a logical interface
A VLAN definition alone does not give the VLAN a presence in PF. The VLAN must be assigned to a logical interface:
- Navigate to
Interfaces → Assignments. - The newly-created VLAN appears in the “Available network ports” dropdown with the form
<parent>.<vlan_tag>(e.g.igb1.10). - Select it and click Add. The VLAN moves to the “Assigned interfaces” list with a default name like
OPT1. - Optionally rename the interface to something descriptive by clicking it and editing the name.
The logical interface now exists. It can be configured with an IPv4 address (Interfaces → OPT1 → Static IPv4 address) and rules (Firewall → Rules → OPT1).
$ ifconfig igb1_vlan10igb1_vlan10: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=4600703<RXCSUM,TXCSUM,TSO4,TSO6,LRO,VLAN_HWTAGGING,VLAN_HWCSUM,POLLING,VLAN_HWFILTER>
ether 00:1b:21:xx:xx:xx
inet 192.0.2.1 netmask 0xffffff00 broadcast 192.0.2.255
inet6 fe80::21b:21ff:fexx:xxxx%igb1_vlan10 prefixlen 64 scopeid 0x6
vlan: 10 parent interface: igb1
groups: vlan
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
nd6 options=23<PERFORMNUD,ACCEPT_RTADV,IFDISABLED,AUTO_LINKLOCAL>Illustrative output
The two diagnostic lines to look for are vlan: 10 (the tag is bound) and parent interface: igb1 (the parent is correct). If either is wrong, the VLAN is bound to the wrong parent or the wrong tag.
Verifying the VLAN is in PF
A VLAN that exists in the kernel but is not assigned to a logical interface does not appear in PF. The operator who cannot reach the GUI on the VLAN’s IP and has confirmed the kernel sees the VLAN should check the assignment.
The verification commands:
ifconfig igb1_vlan10— confirms the kernel sees the sub-interface with the correct tag, parent, and IP.pfctl -s rules | grep igb1_vlan10— confirms PF has rules on the sub-interface. If the grep returns nothing, the sub-interface is not in the ruleset.pfctl -s state | grep igb1_vlan10— confirms state can be created on the sub-interface.
If pfctl -s rules returns nothing for the sub-interface, the most likely cause is that the VLAN was created but never assigned to a logical interface, or that the rules were not added on the logical interface after the assignment.
Common configuration traps
Three traps recur.
Trap 1: VLAN created but not assigned
The operator creates the VLAN definition and clicks Apply, then never assigns the VLAN to a logical interface. The VLAN exists at the kernel level but has no IP, no rules, and no presence in PF. The switch sees tagged frames on the trunk; the firewall kernel strips the tag; the inner frame has nowhere to go because no sub-interface has an IP or rules.
The diagnostic: ifconfig shows the sub-interface, but pfctl -s rules | grep returns nothing. The fix: assign the VLAN to a logical interface in Interfaces → Assignments.
Trap 2: Logical interface created but no IP
The VLAN is assigned, but the logical interface has no IPv4 address. The sub-interface is up at the kernel level (it can send and receive frames) but has no Layer 3 presence. Hosts on the VLAN cannot ARP the firewall; the firewall cannot route.
The diagnostic: ifconfig \<sub\> shows the interface is up but has no inet line. The fix: configure a static IPv4 address on the logical interface.
Trap 3: VLAN ID mismatch with the switch
The firewall has VLAN 10; the switch has VLAN 20. The two ends of the trunk do not agree. The diagnostic is asymmetric: the firewall’s tcpdump on the parent interface shows tagged frames, but the switch’s view of the trunk shows that the firewall’s frames are for a VLAN ID the switch is not allowing on the port.
The fix: align the VLAN ID on both ends. The operator’s network documentation should be the source of truth; if the documentation says VLAN 10 but the switch is configured for VLAN 20, the switch is wrong.
A worked example
The smallest production example:
| Step | Action | Where |
|---|---|---|
| 1 | Identify the parent: igb1 (the LAN-side NIC) | Hardware |
| 2 | Create VLAN 10 with description “Servers” on parent igb1 | Interfaces → Assignments → VLANs |
| 3 | Assign the VLAN to OPT1 | Interfaces → Assignments |
| 4 | Configure OPT1 with IPv4 192.0.2.1/24 | Interfaces → OPT1 |
| 5 | Add rules to OPT1 (initially a default-deny, then permit as needed) | Firewall → Rules → OPT1 |
| 6 | Verify at the kernel: ifconfig igb1_vlan10 shows vlan: 10 and inet 192.0.2.1 | Console / SSH |
| 7 | Verify in PF: pfctl -s rules | grep igb1_vlan10 shows the rules | Console / SSH |
| 8 | Verify on the switch: the trunk port allows VLAN 10 | Switch CLI / GUI |
| 9 | Verify on the wire: tcpdump -nei igb1 vlan 10 shows the expected traffic | Console |
If all nine checks pass, the VLAN is working end to end. If any one fails, the operator knows which step is wrong.
Summary
- A VLAN in OPNsense has three artefacts: the VLAN definition, the assignment to a logical interface, and the interface configuration (IP, rules).
- The parent interface is the NIC or vNIC that carries the trunk. Most deployments use the LAN-side NIC.
- The VLAN ID on the firewall must match the VLAN ID on the switch exactly. Asymmetric configuration is the most common production bug.
- Verification at the kernel level:
ifconfig \<parent\>_vlan\<N\>shows the tag, parent, and IP. Verification at the PF level:pfctl -s rules | grep \<sub\>shows the rules.
Knowledge check · 4 questions
Q1. You create a VLAN definition in the OPNsense GUI on parent igb1 with tag 10 and click Apply. You do not see the VLAN in the list of assignable interfaces. What is the most likely cause?
Q2. A VLAN definition in OPNsense (without an assignment to a logical interface) is enough for PF to apply rules to traffic on that VLAN.
Q3. Which of the following are valid ways to verify that a VLAN is working end to end in OPNsense? Select all that apply.
Q4. You create a VLAN 10 on parent igb1, assign it to OPT1, configure 192.0.2.1/24, and add a default-deny rule. Hosts on VLAN 10 cannot reach the firewall IP. ifconfig igb1_vlan10 shows status: no carrier. What is the most likely cause?
Passing score: 75%. Answers are checked in this browser.