Latest Cisco, PMP, AWS, CompTIA, Microsoft Materials on SALE Get Now Get Now

Cisco VLAN Technologies: Access Ports, Trunks, and Why the Native VLAN Decides Your Security Posture

VLAN configuration looks like the easiest thing on a Catalyst switch and generates a disproportionate share of production incidents. The commands are three words long, the concepts fit on a whiteboard, and yet native VLAN mismatches bridge two broadcast domains together, an switchport trunk allowed vlan typed without add silently removes forty VLANs from a live uplink, and a switch left in the default DTP mode will happily form a trunk with anything that asks. None of these are exotic failures. They are what happens when a configuration that reads correctly does something different from what the operator intended.

The mental model that prevents most of it is simple: an access port belongs to exactly one VLAN and sends every frame untagged; a trunk port carries many VLANs and tags all of them except one — the native VLAN — which it sends untagged. The 802.1Q tag is four bytes inserted after the source MAC address, containing a 16-bit TPID of 0x8100 and a 16-bit control field whose lower twelve bits are the VLAN ID. Everything else in VLAN configuration is a consequence of those two facts: the native VLAN exists because 802.1Q needed backward compatibility with untagged devices, the allowed-VLAN list exists to limit which tags a trunk will carry, and DTP exists to negotiate which of the two roles a port takes — a negotiation you should almost always disable.

This article is a configuration guide with the reasoning attached. Section one covers what you need to know before typing anything: VLAN number ranges and where they are stored, the tag format, and the reference topology. Section two builds access ports properly, including voice VLANs and the protection features that belong on every edge port. Section three covers trunks — encapsulation, allowed-VLAN lists, DTP modes, and the native VLAN decision. Section four is verification: which command answers which question and what healthy output looks like. Section five is the failure catalogue, including the two VLAN hopping attacks and the exact configuration that stops each of them.

Blog ClaimAlmost every VLAN outage traces to one of two commands behaving as specified rather than as expected — switchport trunk allowed vlan replacing instead of appending, and switchport mode dynamic auto forming a trunk you never asked for.
 
The 802.1Q tag layout, and the three port behaviours you actually configure: access (all untagged), trunk (tagged except native), and voice (untagged data plus one tagged VLAN).

What Do You Need to Know Before Configuring a Single VLAN?

What are the VLAN ranges and where are VLANs stored?

VLAN IDs 1 through 1005 are the normal range and are stored in a separate file, vlan.dat in flash, not in the running configuration. VLANs 1002 through 1005 are reserved for legacy FDDI and Token Ring and cannot be reused. VLANs 1006 through 4094 are the extended range; on VTP version 1 and 2 the switch must be in VTP transparent mode to create them, while VTP version 3 supports the extended range in server mode. VLAN 1 always exists and cannot be deleted. Because normal-range VLANs live in vlan.dat, copying a configuration to a new switch does not carry the VLAN database with it — a fact that produces a switch full of correct port assignments to VLANs that do not exist.

A Deeper Dive into Ranges, Storage, and the Tag

The vlan.dat problem

Two operations expose this. Restoring a configuration onto a replacement switch brings the interface commands but not the VLAN database, so every access port lands in an inactive VLAN and the ports go down. And write erase alone does not reset a switch to factory state, because vlan.dat survives it — a lab switch that "still has the old VLANs" after an erase is the normal, documented behaviour.

! Full reset - erasing the config alone leaves the VLAN database
SW1# write erase
SW1# delete flash:vlan.dat
Delete filename [vlan.dat]?
Delete flash:/vlan.dat? [confirm]
SW1# reload
!
! Confirm which VLANs actually exist before assigning ports
SW1# show vlan brief

Creating VLANs, and the shortcut that hides mistakes

Assigning a port to a VLAN that does not exist causes IOS to create it automatically on most platforms — helpful in a lab, dangerous in production, because a typo in the VLAN number creates a new VLAN rather than producing an error. Create VLANs explicitly with names, then assign ports, and any typo becomes an inactive-VLAN symptom you can see rather than a silent new broadcast domain.

! Explicit VLAN creation with names - do this before assigning ports
vlan 10
 name USERS
vlan 20
 name SERVERS
vlan 100
 name DATA
vlan 200
 name VOICE
! A dedicated, unused VLAN reserved for the trunk native - no ports, no SVI
vlan 999
 name NATIVE-UNUSED
! Extended range on VTP v1/v2 requires transparent mode
vtp mode transparent
vlan 1500
 name EXTENDED-EXAMPLE
! On VTP v3 the extended range works in server mode:
!   vtp version 3
Range VLAN IDs Stored in VTP constraint Notes
Reserved 0, 4095 Not usable; VID 0 means "priority tagged, no VLAN"
Default 1 vlan.dat None Cannot be deleted; carries CDP, VTP, DTP, PAgP regardless of pruning
Normal 2–1001 vlan.dat Propagated by VTP in server/client mode The everyday range
Legacy reserved 1002–1005 vlan.dat FDDI and Token Ring; cannot be reused or deleted
Extended 1006–4094 Running config (VTPv1/v2 transparent) or vlan.dat (VTPv3) Transparent mode required on VTPv1/v2 Needed for large multi-tenant designs

The tag, and why frames grow by four bytes

An 802.1Q tag adds four bytes: a 16-bit TPID of 0x8100 that identifies the frame as tagged, followed by three bits of Priority Code Point (the Layer 2 CoS value), one Drop Eligible Indicator bit, and twelve bits of VLAN ID. A standard 1518-byte Ethernet frame therefore becomes 1522 bytes on a trunk. Switches handle these "baby giants" natively, but an intermediate device with a strict 1518-byte limit — an old media converter, a misconfigured provider circuit — will drop them, producing a link where small frames pass and large ones do not.

ISL is gone, and what that means for your commands

Cisco's proprietary ISL encapsulated the entire original frame inside a 26-byte header and a 4-byte trailer. It is not supported on Catalyst 9000 or any current platform, which is why switchport trunk encapsulation dot1q is rejected as an unknown command on a Catalyst 9300 — there is nothing to select between. Older platforms that support both require the encapsulation to be set before the mode, because a port cannot become a trunk while encapsulation is negotiate and the mode is trunk.

Platform-dependent command availabilityOn a Catalyst 2960/3560/3750 you will need switchport trunk encapsulation dot1q before switchport mode trunk. On a Catalyst 9200/9300/9500 the command does not exist. Configuration templates that target both generations need conditional handling, and a template that unconditionally includes the encapsulation line will fail silently or noisily depending on your deployment tooling.
Build order that avoids self-inflicted outagesCreate VLANs, then configure trunks with an explicit allowed list, then assign access ports. Doing it in reverse means access ports come up in VLANs that the uplink trunk does not yet carry, and you spend the first ten minutes troubleshooting a problem your own sequencing created.
Sub claimThe VLAN database lives outside the running configuration, which means a config restore is not a switch restore — and that single fact accounts for most "the replacement switch came up wrong" incidents.

How Do I Configure Access Ports Correctly?

What does a complete access port configuration look like?

Five lines, not one. Set the mode statically with switchport mode access so DTP cannot negotiate the port into a trunk. Assign the VLAN with switchport access vlan. Disable negotiation explicitly with switchport nonegotiate. Enable spanning-tree portfast edge so the port forwards immediately and does not generate topology-change notifications. Add spanning-tree bpduguard enable so that a switch plugged into that port error-disables it rather than joining your topology. Omitting any of the last three turns an access port into an attack surface or a convergence event.

A Deeper Dive into Access Port Configuration

The baseline data access port

! ===== Standard user access port =====
interface range GigabitEthernet1/0/1 - 40
 description ---- user access ----
 switchport mode access
 switchport access vlan 100
 ! Refuse DTP outright - this port will never become a trunk
 switchport nonegotiate
 ! Immediate forwarding, no TCN generated on link transitions
 spanning-tree portfast edge
 ! A switch plugged in here err-disables the port instead of joining STP
 spanning-tree bpduguard enable
 no shutdown

Why switchport mode access alone is not enough

Setting the mode to access does prevent the port from becoming a trunk, and on modern IOS-XE it also stops DTP frames from being sent. But switchport nonegotiate is still worth configuring explicitly for two reasons: it makes the intent visible to the next engineer reading the configuration, and on some older platforms and code versions the behaviour of an access-mode port with respect to DTP frames has varied. Configuring it costs nothing and removes the ambiguity.

Voice VLAN: an access port that carries a tagged VLAN

A port with switchport voice vlan is not a trunk, despite carrying two VLANs. The data VLAN remains untagged and the voice VLAN is tagged, and the phone learns the voice VLAN ID through CDP or LLDP-MED. DTP does not apply. This distinction matters when you audit trunk ports: show interfaces trunk will not list voice ports, which is correct and occasionally confusing.

! ===== Access port with an attached IP phone =====
interface range GigabitEthernet1/0/1 - 40
 description ---- phone + PC ----
 switchport mode access
 switchport access vlan 100
 switchport voice vlan 200
 switchport nonegotiate
 spanning-tree portfast edge
 spanning-tree bpduguard enable
 ! The phone learns VLAN 200 via CDP or LLDP-MED; both must be enabled
 cdp enable
 lldp transmit
 lldp receive
! Variants for phones that cannot tag, or that need only CoS
interface GigabitEthernet1/0/5
 ! Phone sends voice traffic untagged on the access VLAN
 switchport voice vlan untagged
!
interface GigabitEthernet1/0/6
 ! Phone tags with VLAN 0 - priority only, no separate VLAN
 switchport voice vlan dot1p

Port security on an access port

Port security caps how many MAC addresses a port will learn and what happens when the cap is exceeded. On a phone-plus-PC port the count must be at least two, and in practice three, because the phone presents a MAC on both the voice and data VLANs during some boot sequences. Sticky learning writes learned addresses into the running configuration, which persists them only if you save.

! ===== Port security sized for a phone + PC =====
interface range GigabitEthernet1/0/1 - 40
 switchport port-security
 switchport port-security maximum 3
 ! Per-VLAN cap: 1 MAC on voice, 2 on data
 switchport port-security maximum 1 vlan voice
 switchport port-security maximum 2 vlan access
 ! restrict = drop + log + counter; shutdown = err-disable the port
 switchport port-security violation restrict
 switchport port-security aging time 5
 switchport port-security aging type inactivity
Violation mode Traffic from offending MAC Port state Syslog / SNMP trap Violation counter
protect Dropped Stays up No Not incremented
restrict Dropped Stays up Yes Incremented
shutdown (default) Dropped Err-disabled Yes Incremented

Moving a port between VLANs safely

Changing switchport access vlan on a live port is instant and does not bounce the link, which means the attached host keeps its old IP address and ARP cache while sitting in a new subnet. On a user port that is briefly annoying; on a server port it is an outage. Bounce the port after the change, or schedule it.

Pitfall: assigning a port to a VLAN that does not exist Symptom: the port shows as connected in show interfaces status but the host has no connectivity, and show vlan brief does not list the VLAN. Cause: depending on platform and code, IOS either auto-creates the VLAN or leaves the port in an inactive state. In the auto-create case a typo silently produces a new isolated broadcast domain. Confirm: show interfaces GigabitEthernet1/0/7 switchport and read the Access Mode VLAN line — it will show (Inactive) if the VLAN does not exist. Fix: create the VLAN explicitly, or correct the port assignment. Always pre-create VLANs rather than relying on auto-creation.
Sub claimAn access port configuration is five commands, not one — and the four that are not switchport access vlan are the ones that determine whether the port is safe to hand to a user.

How Do I Configure Trunks, and What Should the Native VLAN Be?

What is the correct trunk configuration?

Set the mode statically to trunk, disable DTP with switchport nonegotiate, set the native VLAN to a dedicated unused VLAN rather than leaving it at VLAN 1, and prune the allowed list to exactly the VLANs the link must carry. On platforms that still support ISL, set switchport trunk encapsulation dot1q first. Never leave a trunk at the default allowed list of 1–4094 on an interswitch link you care about, because every VLAN you later create is automatically carried everywhere, including through spanning-tree instances you did not intend to extend.

A Deeper Dive into Trunk Configuration, DTP, and the Native VLAN

The complete trunk configuration

! ===== Interswitch trunk, IOS-XE Catalyst 9000 =====
interface TenGigabitEthernet1/1/1
 description ---- uplink to DIST-1 Te1/0/5 ----
 switchport mode trunk
 ! Refuse DTP - the mode is decided here, not negotiated
 switchport nonegotiate
 ! Dedicated unused native VLAN, identical on both ends
 switchport trunk native vlan 999
 ! Explicit allowed list - only what this link must carry
 switchport trunk allowed vlan 10,20,100,200
 spanning-tree link-type point-to-point
 spanning-tree guard loop
 udld port aggressive
! ===== Same trunk on a platform that still supports ISL =====
interface GigabitEthernet0/1
 ! Encapsulation MUST be set before the mode on these platforms
 switchport trunk encapsulation dot1q
 switchport mode trunk
 switchport nonegotiate
 switchport trunk native vlan 999
 switchport trunk allowed vlan 10,20,100,200

DTP modes and what each combination produces

Dynamic Trunking Protocol negotiates whether a link becomes a trunk. There are five settings, and the default on most Catalyst platforms is dynamic auto — a port that will not initiate trunking but will accept it if the far end asks. That default is why an attacker who can send a DTP frame from a laptop can turn an access port into a trunk and reach every VLAN on the switch.

Local mode Remote: access Remote: dynamic auto Remote: dynamic desirable Remote: trunk
access Access Access Access Mismatch — limited connectivity
dynamic auto Access Access — neither side initiates Trunk Trunk
dynamic desirable Access Trunk Trunk Trunk
trunk Mismatch Trunk Trunk Trunk
trunk + nonegotiate Mismatch Local trunk, remote access Same — remote never learns Trunk

The bottom row is the one worth internalising. With nonegotiate, no DTP frames are sent, so a remote port in dynamic auto or dynamic desirable never learns it should trunk and stays in access mode. That produces a one-sided trunk — the classic outcome of configuring nonegotiate on one end of a link and leaving the other end at default. Configure both ends statically or neither.

Pitfall: switchport nonegotiate on one end only Symptom: only the native VLAN passes across a link between two switches; tagged VLANs are dropped. show interfaces trunk lists the port on one switch and shows nothing on the other. Cause: one end is a static trunk with DTP suppressed, the other is in dynamic auto and never received a DTP frame telling it to trunk. Confirm: show interfaces <intf> switchport on both ends and compare Operational Mode — one will read trunk and the other static access. Fix: configure switchport mode trunk and switchport nonegotiate on both ends. Never rely on one side to negotiate the other into place.

The allowed VLAN list, and the keyword everyone forgets

The default trunk allowed list is 1–4094. Once you set an explicit list, the plain form of the command replaces the entire list rather than adding to it. Typing switchport trunk allowed vlan 30 on a trunk that was carrying 10, 20, 100 and 200 removes all four and leaves only VLAN 30. On a production uplink this is an immediate multi-VLAN outage, and it is one of the most common self-inflicted incidents in switching.

! DANGEROUS on a live trunk - this REPLACES the entire list
switchport trunk allowed vlan 30
!
! SAFE - append VLAN 30 to whatever is already permitted
switchport trunk allowed vlan add 30
! Remove a single VLAN
switchport trunk allowed vlan remove 20
! Everything except a few
switchport trunk allowed vlan except 300-400
! Nothing at all - useful for staging, catastrophic if forgotten
switchport trunk allowed vlan none
Muscle memory worth buildingType add or remove every single time, even when you believe the list is empty. The cost of an unnecessary add is zero. The cost of a forgotten one is a multi-VLAN outage on a distribution uplink at the moment you were making an unrelated change.

Choosing the native VLAN

The native VLAN is the one VLAN sent untagged on an 802.1Q trunk. It defaults to VLAN 1, and leaving it there is a design weakness for two reasons. First, VLAN 1 carries control-plane traffic — CDP, VTP, DTP, PAgP — and mixing user data with it is unnecessary. Second, the 802.1Q double-tagging attack requires the attacker to be in the native VLAN of a trunk; if the native VLAN is a dedicated VLAN with no access ports in it, no attacker can be in it.

The correct pattern is a VLAN created for this purpose only: no access ports assigned, no SVI, and excluded from the trunk allowed list so no traffic is carried in it at all. On modern platforms you can go further and tag everything, eliminating the untagged case entirely.

! ===== Hardened native VLAN configuration =====
vlan 999
 name NATIVE-UNUSED
!
interface TenGigabitEthernet1/1/1
 switchport mode trunk
 switchport nonegotiate
 switchport trunk native vlan 999
 ! 999 is deliberately NOT in the allowed list - nothing rides untagged
 switchport trunk allowed vlan 10,20,100,200
!
! Strongest form: tag the native VLAN too, so nothing is ever untagged
vlan dot1q tag native
! ^ Global. Both ends must have it, or the trunk breaks entirely.
Pitfall: native VLAN mismatch across a trunk Symptom: CDP logs %CDP-4-NATIVE_VLAN_MISMATCH: Native VLAN mismatch discovered on GigabitEthernet1/0/1 (999), with SW2 GigabitEthernet0/1 (1). Hosts in two different VLANs can reach each other. Under PVST+, spanning tree may block the port with a PVID inconsistency. Cause: the two ends disagree on which VLAN is untagged, so frames leaving untagged in VLAN 999 arrive and are placed in VLAN 1 — the two broadcast domains are now bridged. Confirm: show interfaces trunk on both ends and compare the Native vlan column; show spanning-tree inconsistentports for the PVID case. Fix: set the same native VLAN on both ends. Treat this as a security incident as well as a configuration error — two VLANs were merged.

Pruning: manual versus VTP

Limiting which VLANs traverse a trunk reduces broadcast propagation and shrinks the spanning-tree topology. Manual pruning via the allowed list is explicit and auditable. VTP pruning is dynamic — a switch tells its neighbour it has no active ports in a VLAN, and the neighbour stops forwarding that VLAN's flooded traffic. VTP pruning never prunes VLAN 1. Manual pruning is generally preferred in designs where predictability matters more than administrative convenience.

! VTP pruning - dynamic, requires VTP server/client mode
vtp pruning
! Control which VLANs are eligible for dynamic pruning
interface TenGigabitEthernet1/1/1
 switchport trunk pruning vlan 10,20,100,200
! Manual pruning - explicit, works regardless of VTP mode
 switchport trunk allowed vlan 10,20,100,200
Sub claimA trunk has four settings that must match end to end — mode, encapsulation, native VLAN, and allowed list — and three of the four fail silently when they do not, which is why trunk verification is a two-sided exercise.

How Do I Verify a VLAN and Trunk Configuration?

Which command answers which question?

show vlan brief tells you which VLANs exist and which ports are assigned to each — note that it lists only access ports, never trunks. show interfaces trunk is the single most useful trunk command: it shows mode, encapsulation, native VLAN, the configured allowed list, and — critically — the list of VLANs actually forwarding after spanning tree and pruning are applied. show interfaces <intf> switchport gives you the administrative versus operational mode for one port, which is how you diagnose a DTP mismatch. show interfaces status gives a fast per-port summary including the VLAN column.

A Deeper Dive into Verification Output

The four sections of show interfaces trunk

ACC-1# show interfaces trunk

Port        Mode         Encapsulation  Status        Native vlan
Te1/1/1     on           802.1q         trunking      999
Te1/1/2     on           802.1q         trunking      999

Port        Vlans allowed on trunk
Te1/1/1     10,20,100,200
Te1/1/2     10,20,100,200

Port        Vlans allowed and active in management domain
Te1/1/1     10,20,100,200
Te1/1/2     10,20,100,200

Port        Vlans in spanning tree forwarding state and not pruned
Te1/1/1     10,100,200
Te1/1/2     20
! ^ THIS is the section that matters. VLAN 20 is blocked on Te1/1/1
!   and forwarding on Te1/1/2 - that is MST/PVST load balancing at work.

Reading these four sections in order answers four different questions. Section one: is the port trunking at all, and what is the native VLAN? Section two: what did I configure? Section three: which of those VLANs actually exist on this switch? Section four: which are actually forwarding right now? A VLAN present in section two but absent from section three does not exist in the VLAN database. A VLAN present in section three but absent from section four is blocked by spanning tree or pruned.

Diagnosing a mode mismatch

ACC-1# show interfaces GigabitEthernet1/0/47 switchport
Name: Gi1/0/47
Switchport: Enabled
Administrative Mode: trunk
Operational Mode: static access
Administrative Trunking Encapsulation: dot1q
Negotiation of Trunking: Off
Access Mode VLAN: 1 (default)
Trunking Native Mode VLAN: 999 (NATIVE-UNUSED)
Administrative Native VLAN tagging: enabled
Voice VLAN: none
Trunking VLANs Enabled: 10,20,100,200
Pruning VLANs Enabled: 2-1001
! ^ Administrative says trunk, Operational says access. The far end
!   is refusing, or the local encapsulation was never resolved.

Checking VLAN existence and port membership

ACC-1# show vlan brief

VLAN Name                    Status    Ports
---- ----------------------- --------- -------------------------------
1    default                 active    Gi1/0/45, Gi1/0/46
10   USERS                   active    Gi1/0/1, Gi1/0/2, Gi1/0/3
20   SERVERS                 active
100  DATA                    active    Gi1/0/10, Gi1/0/11
200  VOICE                   active    Gi1/0/10, Gi1/0/11
999  NATIVE-UNUSED           active
! Trunk ports NEVER appear in this output. VLAN 20 having no ports
! listed does not mean it is unused - it may exist only on trunks.
!
ACC-1# show vlan id 100
VLAN Name         Status    Ports
---- ------------ --------- -----------------------------------------
100  DATA         active    Gi1/0/10, Gi1/0/11

Fast per-port triage

ACC-1# show interfaces status

Port      Name               Status       Vlan       Duplex  Speed Type
Gi1/0/1   user access        connected    100        a-full  a-1000 10/100/1000
Gi1/0/7   user access        connected    1          a-full  a-1000 10/100/1000
Gi1/0/8   user access        err-disabled 100          auto    auto 10/100/1000
Te1/1/1   uplink DIST-1      connected    trunk      full    10G   10Gbase-SR
! Gi1/0/7 fell back to VLAN 1 - the access vlan command is missing
! or the VLAN was deleted. Gi1/0/8 needs 'show interfaces status err-disabled'.
!
ACC-1# show interfaces status err-disabled
Port      Name               Status       Reason               Err-disabled Vlans
Gi1/0/8   user access        err-disabled bpduguard
Question Command What to look at Failure indicator
Does this VLAN exist? show vlan brief Status column VLAN absent, or status act/unsup
Is this port trunking? show interfaces trunk Section 1, Status column Port not listed at all
Do both ends agree on native? show interfaces trunk on both Native vlan column Different values; CDP mismatch log
Which VLANs actually forward? show interfaces trunk Section 4 VLAN missing from section 4 but present in section 3
Why is this port in access mode? show interfaces X switchport Administrative vs Operational Mode The two disagree
Why is the port down? show interfaces status err-disabled Reason column bpduguard, psecure-violation, udld
SVI state depends on more than the VLAN existingA interface Vlan10 comes up only when VLAN 10 exists in the database, is not shut down, and at least one port in VLAN 10 is in spanning-tree forwarding state — including a trunk that carries it. This is autostate. A distribution switch whose only VLAN 10 presence is a trunk to a switch that has just rebooted will show the SVI down, which looks like a routing problem and is not. switchport autostate exclude on a specific port removes it from that calculation.
Sub claimSection four of show interfaces trunk — VLANs in forwarding state and not pruned — is the only output that reflects reality; the three sections above it describe intent, existence, and configuration, none of which guarantee a frame will pass.

Which VLAN Misconfigurations Cause Outages or Security Exposure?

What are the highest-impact VLAN mistakes?

Six. The allowed vlan command typed without add removes every other VLAN from a live trunk. A native VLAN mismatch bridges two broadcast domains and can trigger a spanning-tree PVID inconsistency. DTP left at the default lets an attacker negotiate a trunk from an access port — switch spoofing. An attacker sitting in the native VLAN can double-tag frames into another VLAN. A restored configuration without vlan.dat leaves every access port in an inactive VLAN. And an SVI that will not come up because no port in its VLAN is forwarding looks like a routing failure while being a Layer 2 one.

A Deeper Dive into the Failure and Attack Catalogue

Switch spoofing: the attack DTP enables

An attacker connects to an access port left in dynamic auto or dynamic desirable and sends a DTP frame requesting trunk mode. The switch obliges. The attacker's port is now a trunk carrying every VLAN in the allowed list — by default, all of them. From there, tagging a frame with any VLAN ID reaches that VLAN directly, bypassing every inter-VLAN access control you configured on the router.

The fix costs two commands per port and there is no operational reason to omit them. Static mode plus nonegotiate removes the negotiation entirely.

! ===== The two commands that eliminate switch spoofing =====
interface range GigabitEthernet1/0/1 - 40
 switchport mode access
 switchport nonegotiate
!
! Audit: find every port still capable of negotiating a trunk
SW1# show interfaces switchport | include Name|Negotiation
! Any port showing 'Negotiation of Trunking: On' is exposed.

Double tagging: the attack the native VLAN enables

The attacker sends a frame with two 802.1Q tags: an outer tag matching the trunk's native VLAN and an inner tag naming the target VLAN. The first switch strips the outer tag — because that VLAN is native and therefore untagged on egress — and forwards the frame across the trunk still carrying the inner tag. The second switch reads the inner tag and delivers the frame into the target VLAN. The attack is one-way, since no return path exists, but one-way is sufficient for many purposes.

It requires the attacker to be in the native VLAN. Three configurations independently break it: use a dedicated native VLAN with no access ports, exclude that VLAN from the trunk allowed list, or tag the native VLAN globally so nothing ever travels untagged.

Pitfall: leaving the native VLAN as VLAN 1 with user ports in it Symptom: a penetration test demonstrates one-way frame injection into a VLAN that has no route from the user segment. Nothing appears wrong in normal operation. Cause: the trunk native VLAN is VLAN 1, user access ports are also in VLAN 1, so an attacker can craft a double-tagged frame whose outer tag is stripped at the first hop. Confirm: show interfaces trunk native VLAN column, cross-referenced with show vlan brief for VLAN 1 port membership. Fix: create a dedicated native VLAN with no ports and no SVI, set it on every trunk, and leave it out of the allowed list. Where all devices support it, add global vlan dot1q tag native.
! ===== Complete anti-VLAN-hopping baseline =====
vlan 999
 name NATIVE-UNUSED
!
! 1. No access ports in VLAN 1 or 999
interface range GigabitEthernet1/0/1 - 40
 switchport mode access
 switchport access vlan 100
 switchport nonegotiate
 spanning-tree bpduguard enable
!
! 2. Trunks use the dedicated native VLAN and an explicit allowed list
interface range TenGigabitEthernet1/1/1 - 2
 switchport mode trunk
 switchport nonegotiate
 switchport trunk native vlan 999
 switchport trunk allowed vlan 10,20,100,200
!
! 3. Shut down every unused port and park it in a black-hole VLAN
vlan 666
 name PARKING
interface range GigabitEthernet1/0/41 - 44
 switchport mode access
 switchport access vlan 666
 switchport nonegotiate
 shutdown

The allowed-list replacement outage

Worth restating on its own because of how often it happens. An engineer adds VLAN 30 to a distribution uplink during business hours, types switchport trunk allowed vlan 30, and instantly removes VLANs 10, 20, 100 and 200 from that trunk. Everything behind the access switch loses connectivity. Recovery is fast once diagnosed, but diagnosis takes longer than it should because the running configuration now reads as though VLAN 30 was always the only allowed VLAN.

! Before the change - capture the current list
SW1# show interfaces TenGigabitEthernet1/1/1 trunk | include Vlans allowed
Te1/1/1     10,20,100,200
!
! The safe change
SW1(config-if)# switchport trunk allowed vlan add 30
!
! Recovery if the unsafe form was already applied
SW1(config-if)# switchport trunk allowed vlan 10,20,30,100,200

The vlan.dat gap during hardware replacement

A switch fails, a spare is racked, the saved configuration is restored, and every access port comes up in an inactive VLAN because the VLAN database was never on the spare. The interface configuration looks perfect. show vlan brief shows only VLAN 1 and the reserved VLANs. The fix is to create the VLANs, which means your change process needs the VLAN list stored somewhere other than the switch it lives on.

! Verify before declaring a replacement switch ready
SW-NEW# show vlan brief | count active
Number of lines which match regexp = 6
! If that count is 5 (VLAN 1 + 1002-1005), no user VLANs exist.
!
SW-NEW# show interfaces status | include inactive
Gi1/0/1  user access  inactive  100  auto auto 10/100/1000

SVI down with everything apparently correct

An SVI requires a forwarding port in its VLAN. If the only member port is a trunk to a switch that is rebooting, or if all access ports in that VLAN are administratively down, the SVI goes down and the routed subnet disappears. This is autostate working correctly, and it is regularly misdiagnosed as an OSPF or HSRP problem because the symptom appears at Layer 3.

! Diagnose an SVI that will not come up
DIST-1# show interfaces Vlan20
Vlan20 is down, line protocol is down (autostate enabled)
!
DIST-1# show vlan id 20
VLAN Name       Status    Ports
---- ---------- --------- --------------------------------------
20   SERVERS    active
! ^ No ports. No trunk carries VLAN 20 in forwarding state either.
!
! Option A (correct): fix the Layer 2 path so a port forwards VLAN 20
! Option B (deliberate): exclude a port from the autostate calculation
DIST-1(config)# interface TenGigabitEthernet1/0/5
DIST-1(config-if)# switchport autostate exclude
Failure First symptom Confirming command Fix Prevention
Allowed list replaced Multiple VLANs lose connectivity instantly show interfaces trunk, section 2 Restore the full list Always type add / remove
Native VLAN mismatch Two VLANs bridged; CDP mismatch log show interfaces trunk native column Match both ends Dedicated native VLAN in the template
DTP left at default Attacker negotiates a trunk from an access port show interfaces switchport Negotiation line switchport nonegotiate Static mode on every port, always
Double tagging possible One-way injection into another VLAN Native VLAN vs VLAN 1 port membership Dedicated unused native VLAN vlan dot1q tag native where supported
Missing vlan.dat Access ports inactive after replacement show vlan brief Create the VLANs Store the VLAN list in config management
SVI down (autostate) Routed subnet disappears; looks like a routing fault show interfaces Vlan<N> Restore a forwarding L2 port, or exclude Understand autostate before blaming the IGP
One-sided trunk Only the native VLAN passes show interfaces X switchport both ends Static trunk both ends Never mix static and dynamic modes
Exam contextVLAN configuration is foundational across the whole Cisco track — CCNA 200-301 examines access ports, trunks, and native VLANs directly; ENCOR 350-401 adds the security dimension; and the CCIE Enterprise Infrastructure lab assumes it as a prerequisite rather than testing it, which means a VLAN mistake early in a lab section costs you the tasks that depend on it. The native VLAN and allowed-list behaviours in particular appear as constraints inside larger tasks.
Sub claimBoth VLAN hopping attacks are eliminated by configuration choices that cost nothing — static access mode with nonegotiate, and a native VLAN that has no members — which makes their continued presence in production networks a template problem rather than a technical one.

Conclusion

VLANs are the one part of switching where the gap between what a command reads like and what it does is widest. switchport trunk allowed vlan 30 reads like adding VLAN 30 and means "the allowed list is now exactly VLAN 30". switchport mode dynamic auto reads like a sensible default and means "I will become a trunk if anyone asks me to". switchport trunk native vlan 1 reads like nothing at all, because it is the default and never appears in the configuration, and it means user traffic and control traffic share a broadcast domain that is also the prerequisite for a documented attack. None of this is hidden; all of it is documented behaviour. It causes incidents because the configuration reads as intent rather than as effect.

The discipline that closes the gap is small and mechanical. Create VLANs explicitly with names before assigning ports, so a typo becomes an inactive port rather than a new broadcast domain. Configure both port roles statically and add nonegotiate, so no port's role is ever decided by a frame from the other end. Use a dedicated native VLAN with no members and keep it out of the allowed list. Type add or remove every time you touch an allowed list. And verify from section four of show interfaces trunk, because that is the only output describing what is actually forwarding rather than what you asked for.

In production this yields a Layer 2 domain whose behaviour matches its documentation and whose edge ports cannot be talked into becoming trunks. In the lab it means the VLAN groundwork is finished in five minutes and stays correct while you build the routing, spanning tree, and security tasks that depend on it. Build the reference topology, then deliberately reproduce each of the seven failures in the table above and watch what each verification command reports while it is broken — particularly the allowed-list replacement, because recognising that output pattern in three seconds is worth more than any amount of theory about it.

Reference Notes

  1. IEEE Std 802.1Q — VLAN tag structure: 16-bit TPID (0x8100), 3-bit Priority Code Point, 1-bit Drop Eligible Indicator, 12-bit VLAN Identifier.
  2. IEEE Std 802.1Q — reserved VLAN identifiers: VID 0 indicates priority-tagged frames with no VLAN, and VID 4095 is reserved, leaving 1–4094 usable.
  3. IEEE Std 802.1Q — maximum tagged frame size of 1522 bytes on a 1500-byte MTU link.
  4. Cisco Catalyst VLAN Configuration Guide — normal-range VLANs 1–1005 stored in vlan.dat; VLANs 1002–1005 reserved for FDDI and Token Ring; VLAN 1 cannot be deleted.
  5. Cisco Catalyst VLAN Configuration Guide — extended-range VLANs 1006–4094 require VTP transparent mode under VTP versions 1 and 2; VTP version 3 supports the extended range in server mode.
  6. Cisco, "Dynamic Trunking Protocol Technote" — the five DTP settings and the resulting mode for each combination, including the access-plus-trunk mismatch case.
  7. Cisco, "Configuring 802.1Q Trunking Between Catalyst Switches" — the requirement that switchport trunk encapsulation be set before switchport mode trunk on dual-encapsulation platforms.
  8. Cisco Catalyst VLAN Configuration Guide — switchport trunk allowed vlan without add or remove replaces the entire allowed list.
  9. Cisco Catalyst VLAN Configuration Guide — vlan dot1q tag native causes all frames on 802.1Q trunks to be tagged, including the native VLAN.
  10. Cisco, "Understanding VLAN Trunk Protocol (VTP)" — VTP pruning behaviour and the fact that VLAN 1 is never pruned.
  11. Cisco Catalyst Security Configuration Guide — port security violation modes protect, restrict, and shutdown, and their differing logging and counter behaviour.
  12. Cisco Catalyst Interface and Hardware Components Configuration Guide — SVI autostate behaviour and the switchport autostate exclude interface command.