Skip to main content
RunBook Academy

← All runbooks in VyOS

medium riskservice affecting~35 min

Runbook: Add a VLAN

1 · Prerequisites

Confirm every item is in place before any state change.

2 · Pre-checks

Read-only diagnostic commands. If any of these don't match expected output, stop and investigate further.

  • · The parent interface is already in service and reads u/u in show interfaces — a VLAN cannot be added to a link that is not up
  • · Tagged frames for the VID are already arriving on the parent: monitor traffic interface eth1 filter 'vlan 10' returns traffic before any configuration change
  • · The switch owner has confirmed in writing that the VID is allowed on this trunk port, and that the port is a trunk rather than an access port
  • · Baseline captured: show interfaces, show ip route, show configuration commands filtered on the parent interface
  • · The address this router will hold on the VLAN is confirmed free, and it is not the address another router already holds as the segment gateway
  • · show ip route checked for the VLAN's subnet — the new connected route installs at administrative distance 0 and displaces every other source for that prefix
  • · The firewall ruleset that will apply to this VLAN is named and owned. A new sub-interface arrives with no rules of its own.
  • · Out-of-band console open, peer reviewer named for the compare diff, change window end time agreed

3 · Procedure

Execute each step in order. Verify the expected output of a step before moving to the next.

  1. 1Confirm the frames exist before you configure anything: monitor traffic interface eth1 filter 'vlan 10'. If nothing arrives, this is a switch change and not a router change — stop here.
  2. 2Capture the baseline from the out-of-band console: show interfaces, show ip route, show configuration commands filtered on the parent.
  3. 3Commit 1, the sub-interface without an address: configure, set interfaces ethernet eth1 vif 10 description 'CR-1204 VLAN 10 DATA', compare, commit. No address yet — this cannot draw traffic.
  4. 4Confirm the kernel created the device and is demultiplexing the tag into it: ip link show eth1.10 shows eth1.10@eth1 up, and tcpdump -i eth1.10 -n -c 10 shows untagged traffic because the kernel has already stripped the tag.
  5. 5Commit 2, the address: set interfaces ethernet eth1 vif 10 address '192.0.2.1/24', then compare. Read the diff for anything touching the PARENT node — a parent-level change affects every VLAN on the trunk, not just this one.
  6. 6Have the named reviewer read the diff, then apply with commit-confirm 10 if you reach this router over the network, or commit from the console.
  7. 7Verify the address in both views: show interfaces ethernet eth1 vif 10 and ip addr show eth1.10 must agree.
  8. 8Verify the route: show ip route shows the new connected route on eth1.10, and the rest of the table matches the baseline.
  9. 9Verify reachability on the VLAN itself: a host on the VLAN must reach the router's address, and the router must reach that host.
  10. 10Verify what the VLAN is actually for: if this router routes between VLANs, test a path from this VLAN to another one. Reaching the router proves the address; it proves nothing about routing.
  11. 11Apply and verify the firewall ruleset for the new VLAN before it carries production traffic.
  12. 12Confirm inside the timer with confirm, then save, then close the ticket with the post-change show interfaces, show ip route, and the approved diff.

4 · Verification

Confirm the procedure actually fixed the problem.

  • ip link show eth1.10 shows the device as eth1.10@eth1 and up — the @eth1 names the parent and proves the tag binding
  • show interfaces ethernet eth1 vif 10 and ip addr show eth1.10 both show the configured address
  • tcpdump -i eth1.10 -n shows traffic, and it is untagged: the kernel strips the 802.1Q tag on the way into the sub-interface
  • show ip route contains the connected route for the VLAN subnet on eth1.10, and differs from the baseline by that route alone
  • A host on the VLAN reaches the router address, and the router reaches that host
  • An inter-VLAN path through this router is tested end to end, if inter-VLAN routing is what the VLAN is for
  • The intended firewall ruleset is applied to this sub-interface and its effect confirmed, not assumed
  • save has run, so the sub-interface survives a reboot

5 · Rollback

If verification fails, undo the procedure in reverse order.

  • Before the address commit, rollback is invisible to traffic: delete interfaces ethernet eth1 vif 10, commit
  • After the address commit and before confirm, do nothing — the commit-confirm timer restores the previous configuration by itself
  • After confirm: delete interfaces ethernet eth1 vif 10, compare, commit, save. This removes the kernel device, the address and the connected route in one operation.
  • Anything using this router as its gateway on the VLAN loses that gateway the instant the delete is committed — confirm who moved onto it during the window before you revert
  • If you also changed a PARENT-level node in the same window (MTU, native-vlan), a whole-tree rollback 1 reverts those too, and reverting a parent MTU resets the parent and drops every VLAN on the trunk. Read compare before committing any rollback.
  • Verify the reverted state against the baseline captured in step 2, not against memory

6 · Escalation

When the runbook isn't enough, contact:

  • · Escalate to the switch owner when no tagged frames for the VID arrive on the parent, when frames arrive with a different VID, or when every frame is untagged — none of these is fixable on the router
  • · Escalate to the switch owner rather than working around a native-VLAN mismatch: untagged frames landing in different VLANs at each end is a trunk configuration defect, not a router one
  • · Escalate to network engineering before committing the address if show ip route already carries the VLAN subnet from another source
  • · Escalate to network engineering if this router is one of a redundant pair on the VLAN — the virtual address is a separate change with its own failover behaviour and must not be improvised here
  • · Escalate to security if the trunk still carries VLAN 1 as its native VLAN, or if unused VIDs are allowed on the port. Both are the double-tagging attack surface and both are switch-side changes.
  • · Hold rather than force: commit the sub-interface with disable set, hand the blocking item to its owner with an agreed end time, and record the router as unchanged

Adding a VLAN to a VyOS router is half a change. The router half is two set lines and takes a minute. The half that determines whether it works is on a switch, and on most estates that switch belongs to somebody else.

That asymmetry is what this runbook is built around. The commonest outcome of a VLAN addition that “did not work” is a sub-interface that is configured correctly, is up, has the right address, and receives nothing — because the VID was never allowed on the trunk port. Every VyOS diagnostic agrees the router is fine, and the router is fine.

The good news is that the decisive check is free, takes thirty seconds, and can be run before you touch configure. The parent interface sees every frame on the wire, tagged or not, whether or not a sub-interface exists for that VID. If the frames are not there before the change, no configuration you commit will make them appear.

When to use this runbook

  • A new VLAN is being added to a router already trunked to the switch: the router-on-a-stick pattern, one physical link carrying several VLANs with the router providing L3 between them.
  • A router needs an L3 presence on a VLAN that already exists elsewhere in the estate.
  • A VLAN that was pruned from a trunk during an incident is being restored.

When not to use it

  • The physical parent is not in service yet. Bring the interface up first with the Add an Interface runbook; a VLAN on a link that is not up cannot be validated.
  • This router is the access-port end for a single VLAN. Then there is no vif at all: the switch sends untagged frames and the address goes on the parent. That configuration is rare on a production router and is worth confirming rather than assuming.
  • Stacked VLANs (QinQ). The shape is the same but the validation is not, and a service-provider outer tag has different failure modes than a customer inner tag.
  • Changing the native VLAN on an existing trunk. That changes how untagged frames are classified, at both ends, and there is a window in which the two ends disagree. It is its own coordinated change.

Blast radius

The new sub-interface — plus, potentially, every other VLAN on the same physical link.

The sub-interface itself is well contained: creating vif 10 does not disturb vif 20. The risk is in the parent. Any node you change under interfaces ethernet eth1 while you are “in there anyway” — MTU, native-vlan, disable, a description edit that turns into a typo — lands on the trunk as a whole. That is why the procedure asks you to read the compare output specifically for parent-level lines.

The second exposure is the routing table. A VLAN address creates a connected route, and connected routes install at administrative distance 0: ahead of static at 1, eBGP at 20, OSPF at 110, iBGP at 200. If the VLAN’s subnet is already carried by a dynamic protocol, committing the address makes this router stop believing the protocol and start believing the wire.

Inputs

  • The VLAN ID, and the subnet and address this router will hold on it.
  • The parent interface, and confirmation that it is a trunk.
  • The switch owner, and their written confirmation that the VID is allowed on that port.
  • Whether this router is the sole gateway for the VLAN or one of a redundant pair.
  • The firewall ruleset that will apply, and its owner.
  • Change window, reviewer, and a working out-of-band path.

Step 1: Prove the frames are already arriving

Read-only / Safewatch the parent for the VID
monitor traffic interface eth1 filter 'vlan 10'

Or from the underlying shell, which shows the link-layer header and is easier to read when you are not sure what you are looking at:

Read-only / Safetcpdump on the parent
tcpdump -i eth1 -e -n vlan 10 -c 10

Three outcomes, and each one decides the change:

  • Tagged frames with your VID arrive. The switch is trunking the VLAN to this port. Proceed.
  • Nothing arrives. The VID is not allowed on this trunk port, or the port is not a trunk. This is a switch change. Stop, and hand it to the switch owner with the capture attached.
  • Frames arrive with a different VID, or untagged. The two ends disagree about what this link carries. Confirm the VID with the switch owner before configuring anything; picking the VID you can see is how one router quietly ends up on the wrong segment.

Step 2: Baseline, and decide the address

Read-only / Safebaseline capture
show interfaces
show ip route
show configuration commands | match eth1

Two questions the baseline answers. Does anything already carry this subnet — and if so, is displacing it the intent, or an accident you are about to have? And is the address free: a VLAN gateway address already held by another router is the most common duplicate, because the VLAN existed elsewhere before it existed here.

If this router is joining an existing gateway pair, the sub-interface takes its own unique address and the shared virtual address is a separate change with its own failover semantics. Do not improvise it into this one.

Step 3: Commit the sub-interface, not the address

Configuration changecommit 1 — the vif
configure
set interfaces ethernet eth1 vif 10 description 'CR-1204 VLAN 10 DATA'
compare
commit

A sub-interface with no address contributes no connected route and draws no traffic, so this commit cannot change forwarding. What it does give you is a real kernel device to test against.

Under the commit, VyOS creates eth1.10 as a VLAN device bound to eth1 with VID 10. The naming matters operationally: the VyOS configuration tree calls it eth1 vif 10, the kernel calls it eth1.10, and roughly half of the diagnostics you will reach for speak the kernel name.

Step 4: Confirm the kernel is demultiplexing the tag

Read-only / Safethe sub-interface device
vyos@vyos:~$ ip link show eth1.10
5: eth1.10@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
  link/ether 52:54:00:12:34:57 brd ff:ff:ff:ff:ff:ff

Illustrative output

Then capture on the sub-interface rather than the parent:

Read-only / Safetcpdump on the sub-interface
tcpdump -i eth1.10 -n -c 10

The traffic here is untagged, because the kernel has already stripped the 802.1Q header on the way in. That is the point of the check: step 1 proved the switch was sending VLAN 10; this proves the router is receiving VLAN 10 and putting it where you asked. Between those two facts there is nothing left for the address commit to surprise you with.

Step 5: Commit the address

Service impact possiblecommit 2 — the address
configure
set interfaces ethernet eth1 vif 10 address '192.0.2.1/24'
compare
commit-confirm 10
exit

Read the compare output twice: once for the lines you intended, and once for anything under interfaces ethernet eth1 that is not under vif 10. A parent-level line in this diff is the difference between affecting one VLAN and affecting the trunk.

Point of no return. After this commit the router holds an address on the VLAN and advertises reachability for the subnet through its connected route. Hosts can start using it immediately, which is what makes the rollback a coordination problem rather than a command.

Step 6: Verify what the VLAN is for, not just that it is up

Read-only / Safeverify
show interfaces ethernet eth1 vif 10
ip addr show eth1.10
show ip route

The address must appear in both the VyOS view and the kernel view. An address in one and not the other is a sub-interface that is not forwarding, whatever the configuration says.

Then test the thing the VLAN exists for. A host on VLAN 10 reaching the router’s VLAN 10 address proves only that the address is live on the right segment. If this router is providing inter-VLAN routing, test a path from VLAN 10 to another VLAN and back. That is the function being commissioned, and it is the one that fails when a route or a firewall rule is missing.

Then, and only then:

Configuration changeconfirm and persist
configure
confirm
save
exit

confirm keeps the change in the running configuration. save writes it to disk. A VLAN that was commissioned, verified and confirmed but never saved works perfectly until the next reboot.

A new VLAN arrives unfiltered

A new sub-interface has no filtering of its own. In a router-on-a-stick this matters more than on a single routed interface, because separating traffic into VLANs and then applying one shared ruleset to all of them gives back exactly the separation the VLANs were for: a rule that permits something for one VLAN permits it for all of them. Per-VLAN rulesets are the pattern.

Native VLAN: real, important, and not today’s change

Untagged frames on a trunk belong to the native VLAN, which defaults to VLAN 1. Leaving it there is the surface for the double-tagging attack: a frame carrying an outer tag for the native VLAN and an inner tag for the target, where the switch strips the outer tag and forwards the frame into a VLAN the sender should not reach. The standard mitigation is to move the native VLAN to an unused ID and prune VLAN 1 from the trunk.

All of which is correct, and none of which belongs in a change whose purpose is to add one VLAN. Both ends have to move at the same time, and for as long as they disagree, untagged frames land in different VLANs at each end. Raise it with the switch owner as its own coordinated change, and record it in the ticket so it is not lost.

Rollback

Service impact possibleremove the VLAN
configure
delete interfaces ethernet eth1 vif 10
compare
commit
save

One commit removes the kernel device, the address and the connected route together. Before the address commit that is invisible to traffic. After it, anything that started using this router as its VLAN 10 gateway loses it at the moment of the commit — so the question to answer first is who moved during the window, not which command to type.

The trap is the whole-tree revert. If the window also contained a parent-level change, rollback 1 takes that back too, and reverting a parent MTU resets the trunk and interrupts every VLAN on it. Run compare after rollback and before commit, every time; that step is what turns rollback into a reviewed change rather than a second incident.

Common patterns

SymptomLikely causeNext check
Sub-interface up, capture on it silentSwitch is not trunking the VID to this portCapture on the PARENT with a vlan filter
Parent shows tagged frames for another VIDThe two ends disagree about the VLAN IDConfirm the VID with the switch owner
Parent shows only untagged framesThe port is an access port, not a trunkSwitch owner; do not add a vif to work around it
Hosts reach the router, nothing beyond itMissing route or missing firewall rule for the VLANshow ip route, then the ruleset
Inter-VLAN works one direction onlyAsymmetric path with a stateful device in itTest from both ends, not just from the router
Small packets fine, large transfers hangTag overhead against the path MTUDo-not-fragment ping sized across the VLAN
Whole trunk interrupted at commitA parent-level node changed in the same commitRead compare before committing
VLAN works until the router rebootssave never ranCompare running against the boot configuration

Escalation

Escalate rather than work around when:

  • No frames for the VID arrive, frames arrive with a different VID, or all frames are untagged. Every one of these is a switch change, and configuring the router around it produces a router that is wrong in a way that looks right.
  • The VLAN’s subnet is already carried by another routing source.
  • This router will be one of a redundant pair on the VLAN.
  • The trunk still carries VLAN 1 as its native VLAN, or allows VIDs nobody uses. That is an open attack surface and it belongs to the switch owner.

Holding is a legitimate outcome: commit the sub-interface with disable set, name the owner of the blocking item, agree an end time, and record the router as unchanged.

References

  1. VyOS — VLAN sub-interfaces
  2. VyOS — Ethernet interfaces
  3. VyOS — CLI, commit and rollback
  4. ip-link(8)