Dynamic Trunking Protocol (DTP) appeared in early Cisco switching to reduce configuration overhead—two switches could negotiate trunk status without manual commands on both ends. Today, most production networks disable DTP entirely due to VLAN hopping vulnerabilities, but understanding how DTP works is essential for diagnosing unexpected trunk formation and securing your switching infrastructure.
What DTP Does
DTP is a Layer 2 protocol that allows switches to negotiate whether a port should operate as a trunk or an access port. Without DTP, you must manually configure both sides of a link as either switchport mode trunk or switchport mode access. With DTP, you can use modes like switchport mode dynamic auto and let the switches discover each other's capabilities.
DTP frames are sent as Cisco proprietary Ethernet frames (EtherType 0x2004) out of every port. Unlike protocols that need explicit enablement, DTP runs by default on Catalyst switches when a port is in Layer 2 mode. This "always on" behavior is the root of DTP security issues.
DTP Modes Explained
Every switch port operates in one of four DTP modes:
Switchport Mode Trunk - Explicitly configures the port as a trunk - Sends DTP frames to tell neighbors "I am a trunk" - Will trunk with another port in trunk mode or desirable mode - Never reverts to access mode based on DTP negotiation
Switchport Mode Dynamic Desirable - Actively requests trunk formation - Sends DTP frames saying "I want to negotiate a trunk" - Will trunk with a port in trunk or desirable mode - Will accept a trunk from auto or desirable neighbors - Defaults to access mode if no trunk partner responds
Switchport Mode Dynamic Auto - Passively waits for a trunk request - Sends DTP frames but signals "I can be a trunk" - Will only form a trunk if the neighbor is in trunk or desirable mode - If no trunk request arrives, remains in access mode - This is the factory default on many Catalyst switches
Switchport Mode Nonegotiate - Disables DTP entirely on that port - No DTP frames sent or received - Port behaves as whatever mode is statically configured - Preferred in production networks
DTP Frame Format
DTP frames carry these key fields in a proprietary TLV (Type-Length-Value) structure:
Destination MAC: 01:00:0c:cc:cc:cc (Cisco reserved multicast)
Source MAC: Switch MAC address
EtherType: 0x2004
Domain TLV: Management domain name
Status TLV: Port trunk status (access, trunk, desirable, auto, nonegotiate)
DTPort TLV: Duplex (half/full)
A switch sends DTP frames every 30 seconds on Layer 2 ports. Frames are sent even before a port becomes active, which is why you see DTP negotiation happen moments after a cable connects.
DTP Negotiation Matrix
This matrix shows which mode combinations result in a trunk forming:
| Trunk | Desirable | Auto | Access | Nonegotiate |
-----------|-------|-----------|------|--------|-------------|
Trunk | Trunk | Trunk | Trunk| Access | Access |
Desirable | Trunk | Trunk | Trunk| Access | Access |
Auto | Trunk | Trunk | Acc | Access | Access |
Access | Acc | Access | Acc | Access | Access |
Noneg | Access| Access | Acc | Access | Access |
Key observations: - auto + auto always results in access (neither actively requests a trunk) - desirable + auto results in trunk (desirable forces it) - trunk + anything except access/nonegotiate results in trunk - nonegotiate never trunks unless statically configured as trunk mode
How DTP Negotiates Trunk Formation
When a cable connects between two switches:
- Port activation: The switch interface comes up. Both sides enable DTP if not disabled.
- DTP frame exchange: Each port sends DTP TLVs advertising its mode every 30 seconds:
- Port in
desirablemode: "I want to trunk" - Port in
automode: "I can trunk if you want" - Port in
accessmode: "I am access" - Port in
nonegotiatemode: "DTP is disabled; use static config" - Mode evaluation: Each switch evaluates the received DTP frame against the local port mode using the negotiation matrix.
- Trunk formation: If the matrix result is "Trunk", both sides:
- Enable trunk mode on that port
- Begin tagging frames with 802.1Q VLAN IDs
- Use the native VLAN (default 1) for untagged frames
- Start forwarding traffic for all allowed VLANs
- Continuous monitoring: DTP frames continue every 30 seconds. If one side switches to
accessmode, the other port (inautomode) reverts to access within 60 seconds.
Why DTP Is a Security Risk: VLAN Hopping
DTP's automatic trunk formation enables a VLAN hopping attack. An attacker can:
- Craft a DTP frame claiming to be a switch in
desirablemode - Send it from an access port to a switch running
dynamic auto(the default) - Trick the switch into forming a trunk on that port via the negotiation matrix
- Access all VLANs that were previously isolated on that trunk
This works because: - DTP frames aren't authenticated - Access ports send DTP frames, allowing an attacker with a device on an access port to send crafted frames - Dynamic auto is still common on older deployments - No warning is logged when a port suddenly becomes a trunk
Example attack scenario: - Switch port Gi1/0/10 is in dynamic auto mode, assigned to VLAN 10 (Users) - An attacker connects to port Gi1/0/10 with a managed switch or NIC spoofing DTP - They configure their device in dynamic desirable mode - Port Gi1/0/10 negotiates a trunk (per the matrix: desirable + auto = trunk) - Attacker can now send/receive traffic on all VLANs
The attacker can then: - Sniff traffic from VLAN 20 (Servers) - Spoof access to protected VLANs - Perform trunk takeover attacks
Disabling DTP in Production
Best practice is to disable DTP on all ports and use explicit static configuration:
Configuration
Access port configuration (user-facing):
DIST-SW1(config)# interface range Gi1/0/23-24
DIST-SW1(config-if-range)# switchport mode access
DIST-SW1(config-if-range)# switchport nonegotiate
DIST-SW1(config-if-range)# switchport access vlan 10
DIST-SW1(config-if-range)# end
Trunk port configuration (switch-to-switch):
CORE-SW1(config)# interface Gi1/0/1
CORE-SW1(config-if)# switchport trunk encapsulation dot1q
CORE-SW1(config-if)# switchport mode trunk
CORE-SW1(config-if)# switchport nonegotiate
CORE-SW1(config-if)# switchport trunk allowed vlan 10,20,30,40,50,99
CORE-SW1(config-if)# switchport trunk native vlan 99
CORE-SW1(config-if)# end
The switchport nonegotiate command: - Disables DTP completely on that port - Prevents the port from sending or receiving DTP frames - Forces the port to use the static mode configuration - Is compatible with all DTP modes (though used here with explicit mode trunk or mode access)
Why Disable DTP on Every Port
Even on trunk ports, disabling DTP provides these benefits:
- Security: No DTP hopping attacks possible on that port
- Predictability: Port mode is always what you configured, never negotiated
- Troubleshooting: When a port isn't a trunk, you immediately know static config is wrong (not a negotiation failure)
- Consistency: All ports follow the same rule: no negotiation
- Performance: Slightly reduces CPU overhead (no DTP frames processed)
Verification with show dtp interface
Check DTP status on a port before disabling it:
CORE-SW1# show dtp interface Gi1/0/1
DTP information for Gi1/0/1:
Switchport: Enabled
Role: Desirable
Status: Trunk
Encapsulation: Dot1q
Negotiation of Trunking: On
Access VLANs: none
Trunking VLANs: All
Pruning VLANs: 2-1001
Capture Mode: Off
Captures Voice VLAN: false
Key fields: - Role: Shows the current DTP mode (desirable, auto, nonegotiate, etc.) - Status: Current actual state (trunk, access, disabled, dot1q-tunnel) - Negotiation of Trunking: "On" means DTP is active, "Off" means nonegotiate is set
After applying switchport nonegotiate:
CORE-SW1# show dtp interface Gi1/0/1
DTP information for Gi1/0/1:
Switchport: Enabled
Role: Nonegotiate
Status: Trunk
Encapsulation: Dot1q
Negotiation of Trunking: Off
Access VLANs: none
Trunking VLANs: All
Pruning VLANs: 2-1001
Capture Mode: Off
Captures Voice VLAN: false
Notice "Role" changed to "Nonegotiate" and "Negotiation of Trunking" is now "Off".
View DTP activity globally:
CORE-SW1# show dtp
Global DTP information:
Sends DTP frames: On
Interface DTP administratively off: 3
CORE-SW1# show dtp interface Gi1/0/2
DTP information for Gi1/0/2:
Switchport: Enabled
Role: Nonegotiate
Status: Access
Encapsulation: Dot1q
Negotiation of Trunking: Off
Complete Lab Topology Configuration
Apply switchport nonegotiate across the lab:
CORE-SW1 (Cat 9300, trunk ports to distribution)
CORE-SW1(config)# interface Gi1/0/1
CORE-SW1(config-if)# switchport trunk encapsulation dot1q
CORE-SW1(config-if)# switchport mode trunk
CORE-SW1(config-if)# switchport nonegotiate
CORE-SW1(config-if)# switchport trunk allowed vlan 10,20,30,40,50,99
CORE-SW1(config-if)# switchport trunk native vlan 99
CORE-SW1(config-if)# channel-group 1 mode active
CORE-SW1(config-if)# exit
CORE-SW1(config)# interface Gi1/0/2
CORE-SW1(config-if)# switchport trunk encapsulation dot1q
CORE-SW1(config-if)# switchport mode trunk
CORE-SW1(config-if)# switchport nonegotiate
CORE-SW1(config-if)# switchport trunk allowed vlan 10,20,30,40,50,99
CORE-SW1(config-if)# switchport trunk native vlan 99
CORE-SW1(config-if)# channel-group 1 mode active
CORE-SW1(config-if)# exit
CORE-SW1(config)# interface Gi1/0/3
CORE-SW1(config-if)# switchport trunk encapsulation dot1q
CORE-SW1(config-if)# switchport mode trunk
CORE-SW1(config-if)# switchport nonegotiate
CORE-SW1(config-if)# switchport trunk allowed vlan 10,20,30,40,50,99
CORE-SW1(config-if)# switchport trunk native vlan 99
CORE-SW1(config-if)# channel-group 2 mode active
CORE-SW1(config-if)# exit
CORE-SW1(config)# interface Gi1/0/4
CORE-SW1(config-if)# switchport trunk encapsulation dot1q
CORE-SW1(config-if)# switchport mode trunk
CORE-SW1(config-if)# switchport nonegotiate
CORE-SW1(config-if)# switchport trunk allowed vlan 10,20,30,40,50,99
CORE-SW1(config-if)# switchport trunk native vlan 99
CORE-SW1(config-if)# channel-group 2 mode active
CORE-SW1(config-if)# end
DIST-SW1 (Cat 9200, access-facing)
DIST-SW1(config)# interface range Gi1/0/23-24
DIST-SW1(config-if-range)# switchport mode access
DIST-SW1(config-if-range)# switchport nonegotiate
DIST-SW1(config-if-range)# switchport access vlan 10
DIST-SW1(config-if-range)# exit
DIST-SW1(config)# interface range Gi1/0/1-4
DIST-SW1(config-if-range)# switchport trunk encapsulation dot1q
DIST-SW1(config-if-range)# switchport mode trunk
DIST-SW1(config-if-range)# switchport nonegotiate
DIST-SW1(config-if-range)# switchport trunk allowed vlan 10,20,30,40,50,99
DIST-SW1(config-if-range)# switchport trunk native vlan 99
DIST-SW1(config-if-range)# end
ACC-SW1 (Cat 9200L, all access ports)
ACC-SW1(config)# interface range Gi1/0/1-22
ACC-SW1(config-if-range)# switchport mode access
ACC-SW1(config-if-range)# switchport nonegotiate
ACC-SW1(config-if-range)# switchport access vlan 10
ACC-SW1(config-if-range)# end
Verification
Verify all ports have DTP disabled:
CORE-SW1# show dtp interface Gi1/0/1 | include "Negotiation"
Negotiation of Trunking: Off
DIST-SW1# show dtp interface Gi1/0/23 | include "Negotiation"
Negotiation of Trunking: Off
Check that trunks are still active (Role is nonegotiate but Status is still trunk):
CORE-SW1# show interfaces Gi1/0/1 switchport | include "Operational"
Operational Mode: trunk
All trunk ports continue to function—DTP is just disabled, not the trunk itself.
Troubleshooting DTP Issues
Symptom 1: Unexpected Trunk Formation
Symptom: A port is suddenly carrying traffic from multiple VLANs when it should only be access.
Cause: The port is in dynamic auto or dynamic desirable mode and DTP negotiation formed an unexpected trunk with a neighbor in compatible mode.
Fix:
interface Gi1/0/10
switchport nonegotiate
switchport mode access
switchport access vlan 10
Verify:
DIST-SW1# show dtp interface Gi1/0/10
DTP information for Gi1/0/10:
Negotiation of Trunking: Off
Status: Access
Symptom 2: Port in Access Mode Doesn't Become Trunk After Cable Change
Symptom: You connect two switches with ports in dynamic auto mode, but they don't form a trunk. Both ports stay in access mode.
Cause: Two auto ports together default to access mode—neither actively requests a trunk. This is per the negotiation matrix: auto + auto = access.
Fix: Change one side to desirable or explicit trunk mode:
CORE-SW1(config)# interface Gi1/0/1
CORE-SW1(config-if)# switchport mode trunk
CORE-SW1(config-if)# switchport nonegotiate
Or re-enable one side's active negotiation (not recommended):
CORE-SW1(config)# interface Gi1/0/1
CORE-SW1(config-if)# switchport mode dynamic desirable
Wait 30 seconds for DTP frames to exchange:
CORE-SW1# show interfaces Gi1/0/1 switchport | include "Operational Mode"
Operational Mode: trunk
Symptom 3: DTP Hopping Attack Detected in Logs
Symptom: You see syslog messages about unexpected trunk formation or a security team reports DTP spoofing on your network.
Cause: An attacker (or misconfigured device) sent a crafted DTP frame to a port in dynamic auto mode.
Fix: Apply switchport nonegotiate to all Layer 2 ports company-wide:
Device(config)# interface range Gi1/0/1-48
Device(config-if-range)# switchport nonegotiate
Device(config-if-range)# end
Verify:
Device# show dtp interface Gi1/0/1 | include "Negotiation"
Negotiation of Trunking: Off
Now even if a DTP frame arrives, it's ignored—the port obeys only static configuration.
Key Takeaways
- DTP is convenient but dangerous: Automatic trunk negotiation opens the door to VLAN hopping attacks via DTP frame spoofing.
- Disable DTP on all ports: Use
switchport nonegotiateon every Layer 2 port (access and trunk) to prevent negotiation-based attacks. - Understand the negotiation matrix:
auto + auto = access(neither side forces trunk), whiledesirable + auto = trunk(desirable wins). - DTP frames are unauthenticated: Any device on an access VLAN can craft and send DTP frames, making DTP spoofing trivial.
- Best practice is static configuration: Manually set
switchport mode trunkorswitchport mode accesson every port and disable DTP. This is the production standard for secure, predictable networks.