1. Introduction
In modern enterprise networks, Virtual Local Area Networks (VLANs) are a fundamental technology for segmenting broadcast domains, enhancing security, and improving network manageability. As organizations scale and acquire diverse networking equipment, the ability to configure and manage VLANs consistently across multiple vendors becomes a critical skill. This chapter dives deep into the nuances of VLAN configuration on leading platforms: Cisco IOS/IOS-XE/NX-OS, Juniper Junos, and Arista EOS.
This chapter will provide a comprehensive understanding of:
- The underlying technical concepts of VLANs and related IEEE standards.
- Step-by-step configuration examples for common VLAN scenarios on Cisco, Juniper, and Arista devices.
- Practical network diagrams and packet structure illustrations to solidify understanding.
- Leveraging network automation tools like Ansible and Python (Netmiko) for efficient multi-vendor VLAN management.
- Critical security considerations, attack vectors, and mitigation strategies for VLAN environments.
- Effective verification and troubleshooting methodologies for common VLAN issues.
- Strategies for optimizing VLAN performance in large-scale deployments.
Upon completing this chapter, you will be equipped to design, implement, secure, troubleshoot, and automate VLAN configurations across a multi-vendor network infrastructure with confidence.
2. Technical Concepts
2.1. IEEE 802.1Q: The Standard for VLAN Tagging
The IEEE 802.1Q standard defines the mechanism for VLAN tagging, allowing a single physical network link (a trunk) to carry traffic for multiple logical VLANs. This is achieved by inserting a 4-byte tag into the Ethernet frame header.
Key components of the 802.1Q tag:
- Tag Protocol Identifier (TPID): A 2-byte field set to
0x8100to identify the frame as an 802.1Q tagged frame. - Tag Control Information (TCI): A 2-byte field containing:
- Priority Code Point (PCP): 3 bits (802.1p) for Quality of Service (QoS) prioritization.
- Drop Eligible Indicator (DEI): 1 bit (formerly Canonical Format Indicator - CFI) indicating frame eligibility for being dropped in congestion.
- VLAN ID (VID): 12 bits, allowing for 4096 possible VLANs (0 and 4095 are reserved, typically leaving 1-4094 for use).
Access Ports vs. Trunk Ports:
- Access Port: Carries traffic for a single VLAN. Frames entering or leaving an access port are typically untagged. The switch assigns the untagged frame to its configured access VLAN.
- Trunk Port: Carries traffic for multiple VLANs. Frames traversing a trunk port are usually 802.1Q tagged.
- Native VLAN (on Trunk Ports): An untagged VLAN on a trunk port. Frames belonging to the native VLAN are sent and received without an 802.1Q tag. This can be a security vulnerability if not managed properly.
RFC References:
- IEEE 802.1Q-2022 (latest amendment to the base standard)
Here’s how the 802.1Q tag modifies an Ethernet frame:
packetdiag {
colwidth = 32
0-7: Destination MAC
8-15: Destination MAC
16-23: Source MAC
24-31: Source MAC
32-39: 802.1Q Tag (TPID = 0x8100)
40-47: 802.1Q Tag (PCP/DEI/VID)
48-55: Length/Type
56-63: Payload (Data)
64-71: Payload (Data)
...
last: Frame Check Sequence (FCS)
}
2.2. IEEE 802.1ad: QinQ (Provider Bridging)
IEEE 802.1ad, often referred to as QinQ (Q-in-Q) or Provider Bridging, is an amendment to 802.1Q that allows for the insertion of multiple 802.1Q tags into a single Ethernet frame. This is primarily used in service provider networks to segment customer traffic while maintaining the customer’s own VLAN IDs. The outer tag is often called the “S-tag” (Service Provider Tag), and the inner tag is the “C-tag” (Customer Tag).
How it works: A customer’s 802.1Q tagged frame (C-tag) enters a provider’s network and is encapsulated with an additional 802.1Q tag (S-tag) by the provider edge switch. This allows the provider to carry traffic from multiple customers, each potentially using the same C-VLAN IDs, over a shared backbone while maintaining separation.
RFC References:
- IEEE 802.1ad - Defines Provider Bridges and QinQ.
packetdiag {
colwidth = 32
0-7: Destination MAC
8-15: Destination MAC
16-23: Source MAC
24-31: Source MAC
32-39: S-VLAN Tag (TPID = 0x8100, etc.)
40-47: S-VLAN Tag (PCP/DEI/VID)
48-55: C-VLAN Tag (TPID = 0x8100, etc.)
56-63: C-VLAN Tag (PCP/DEI/VID)
64-71: Length/Type
72-79: Payload (Data)
...
last: Frame Check Sequence (FCS)
}
2.3. Architecture and Design Considerations
When designing VLANs in a multi-vendor environment, it’s crucial to establish a consistent strategy:
- VLAN ID Allocation: Standardize VLAN ID ranges for different purposes (e.g., VLAN 100-199 for Users, 200-299 for Servers, 300-399 for Voice, 900-999 for Management). Avoid using low VLAN IDs (1-100) for production, leaving room for expansion and default/special purpose VLANs.
- Naming Conventions: Implement clear and consistent naming for VLANs across all devices (e.g., “VLAN10_USERS”, “VLAN20_SERVERS”).
- Layer 2 vs. Layer 3: Determine where VLAN routing will occur (Layer 3 switch, router, firewall).
- Native VLAN Consistency: Ensure the native VLAN ID is consistent on all interconnected trunk ports and is set to an unused VLAN ID for security.
- Pruning: Implement VLAN pruning to prevent unnecessary broadcast traffic from traversing trunks where those VLANs are not needed.
- Interoperability: Be aware of minor syntax or feature differences between vendors (e.g., DTP on Cisco vs. explicit trunking on Juniper/Arista).
Example Network Diagram:
nwdiag {
network core_segment {
address = "10.0.0.0/24"
description = "Core Network Segment"
Cisco_Core_SW [address = "10.0.0.1"];
Juniper_Core_SW [address = "10.0.0.2"];
Arista_Core_SW [address = "10.0.0.3"];
}
network access_segment_cisco {
address = "192.168.10.0/24"
description = "Cisco Access Layer"
Cisco_Core_SW -- Cisco_Access_SW1;
Cisco_Access_SW1 [address = "192.168.10.1"];
User_PC1 [address = "192.168.10.10", shape = endpoint];
User_PC1 -- Cisco_Access_SW1;
}
network access_segment_juniper {
address = "192.168.20.0/24"
description = "Juniper Access Layer"
Juniper_Core_SW -- Juniper_Access_SW1;
Juniper_Access_SW1 [address = "192.168.20.1"];
Server_VM1 [address = "192.168.20.20", shape = cloud];
Server_VM1 -- Juniper_Access_SW1;
}
network access_segment_arista {
address = "192.168.30.0/24"
description = "Arista Access Layer"
Arista_Core_SW -- Arista_Access_SW1;
Arista_Access_SW1 [address = "192.168.30.1"];
VoIP_Phone1 [address = "192.168.30.30", shape = box];
VoIP_Phone1 -- Arista_Access_SW1;
}
}
3. Configuration Examples
We will configure VLAN 10 (Data), VLAN 20 (Servers), and VLAN 99 (Native/Management) across our multi-vendor setup.
- Access Port: Assign
VLAN 10to an interface. - Trunk Port: Allow
VLAN 10andVLAN 20to pass, setVLAN 99as native.
3.1. Cisco (IOS-XE / Catalyst 9000 Series)
! Global VLAN creation
vlan 10
name DATA_VLAN
vlan 20
name SERVERS_VLAN
vlan 99
name NATIVE_MGMT_VLAN
! Interface configuration - Access Port (e.g., Gi1/0/1)
interface GigabitEthernet1/0/1
description User_DATA_Access_Port
switchport mode access
switchport access vlan 10
switchport nonegotiate ! Disable DTP for security
spanning-tree portfast ! Recommended for access ports
end
! Interface configuration - Trunk Port (e.g., Gi1/0/2 - connecting to Juniper/Arista)
interface GigabitEthernet1/0/2
description TRUNK_TO_CORE_SW
switchport mode trunk
switchport trunk native vlan 99
switchport trunk allowed vlan 10,20,99
switchport nonegotiate ! Disable DTP for security
end
! Verification Commands
show vlan brief
show interfaces GigabitEthernet1/0/1 switchport
show interfaces GigabitEthernet1/0/2 switchport
Expected Output (Simplified):
Cisco_SW#show vlan brief
VLAN Name Status Ports
---- -------------------------------- --------- -------------------------------
10 DATA_VLAN active Gi1/0/1
20 SERVERS_VLAN active
99 NATIVE_MGMT_VLAN active
...
Cisco_SW#show interfaces GigabitEthernet1/0/1 switchport
Name: Gi1/0/1
Switchport: Enabled
Administrative Mode: static access
Operational Mode: static access
Access Mode VLAN: 10 (DATA_VLAN)
...
Cisco_SW#show interfaces GigabitEthernet1/0/2 switchport
Name: Gi1/0/2
Switchport: Enabled
Administrative Mode: trunk
Operational Mode: trunk
Negotiation of Trunking: Off
Access Mode VLAN: 1 (default)
Trunking Native Mode VLAN: 99 (NATIVE_MGMT_VLAN)
Trunking VLANs Enabled: 10,20,99
...
3.2. Juniper (Junos OS / EX Series)
# Global VLAN creation
set vlans DATA_VLAN vlan-id 10
set vlans SERVERS_VLAN vlan-id 20
set vlans NATIVE_MGMT_VLAN vlan-id 99
# Interface configuration - Access Port (e.g., ge-0/0/1)
set interfaces ge-0/0/1 unit 0 description "User_DATA_Access_Port"
set interfaces ge-0/0/1 unit 0 family ethernet-switching interface-mode access
set interfaces ge-0/0/1 unit 0 family ethernet-switching vlan members DATA_VLAN
# Interface configuration - Trunk Port (e.g., ge-0/0/2 - connecting to Cisco/Arista)
set interfaces ge-0/0/2 unit 0 description "TRUNK_TO_CORE_SW"
set interfaces ge-0/0/2 unit 0 family ethernet-switching interface-mode trunk
set interfaces ge-0/0/2 unit 0 family ethernet-switching native-vlan-id 99
set interfaces ge-0/0/2 unit 0 family ethernet-switching vlan members [DATA_VLAN SERVERS_VLAN NATIVE_MGMT_VLAN]
commit and-quit
# Verification Commands
show vlans
show interfaces ge-0/0/1 terse
show interfaces ge-0/0/2 terse
show ethernet-switching interfaces ge-0/0/1
show ethernet-switching interfaces ge-0/0/2
Expected Output (Simplified):
Juniper_SW> show vlans
Name Tag Interfaces
DATA_VLAN 10 ge-0/0/1.0*, ge-0/0/2.0
NATIVE_MGMT_VLAN 99 ge-0/0/2.0
SERVERS_VLAN 20 ge-0/0/2.0
...
Juniper_SW> show ethernet-switching interfaces ge-0/0/1
Interface State VLAN members Tag Tagging Blocking
ge-0/0/1.0 UP DATA_VLAN 10 untagged unblocked
...
Juniper_SW> show ethernet-switching interfaces ge-0/0/2
Interface State VLAN members Tag Tagging Blocking
ge-0/0/2.0 UP DATA_VLAN 10 tagged unblocked
SERVERS_VLAN 20 tagged unblocked
NATIVE_MGMT_VLAN 99 untagged unblocked
...
3.3. Arista (EOS / 7000 Series)
! Global VLAN creation
vlan 10
name DATA_VLAN
vlan 20
name SERVERS_VLAN
vlan 99
name NATIVE_MGMT_VLAN
! Interface configuration - Access Port (e.g., Ethernet1)
interface Ethernet1
description User_DATA_Access_Port
switchport mode access
switchport access vlan 10
end
! Interface configuration - Trunk Port (e.g., Ethernet2 - connecting to Cisco/Juniper)
interface Ethernet2
description TRUNK_TO_CORE_SW
switchport mode trunk
switchport trunk native vlan 99
switchport trunk allowed vlan 10,20,99
end
! Verification Commands
show vlan
show interfaces Ethernet1 switchport
show interfaces Ethernet2 switchport
Expected Output (Simplified):
Arista_SW#show vlan
VLAN Name Status Ports
----- ------------------ --------- -------------------------------
10 DATA_VLAN active Et1, Et2
20 SERVERS_VLAN active Et2
99 NATIVE_MGMT_VLAN active Et2
...
Arista_SW#show interfaces Ethernet1 switchport
Name: Et1
Switchport: Enabled
Administrative Mode: access
Operational Mode: access
Access Mode VLAN: 10 (DATA_VLAN)
...
Arista_SW#show interfaces Ethernet2 switchport
Name: Et2
Switchport: Enabled
Administrative Mode: trunk
Operational Mode: trunk
Trunking Native Mode VLAN: 99 (NATIVE_MGMT_VLAN)
Trunking VLANs Enabled: 10,20,99
...
4. Network Diagrams
Here are some network diagrams illustrating multi-vendor VLAN integration and logical segmentation.
4.1. Multi-Vendor Physical Topology (PlantUML)
This diagram shows the physical interconnection of devices from different vendors in a core-access architecture.
@startuml
!theme mars
' Define all elements first
node "Cisco_Core_SW" as C_CORE {
port GigabitEthernet1/0/2
}
node "Juniper_Core_SW" as J_CORE {
port ge-0/0/2
}
node "Arista_Core_SW" as A_CORE {
port Ethernet2
}
node "Cisco_Access_SW" as C_ACCESS {
port GigabitEthernet1/0/1
}
node "Juniper_Access_SW" as J_ACCESS {
port ge-0/0/1
}
node "Arista_Access_SW" as A_ACCESS {
port Ethernet1
}
rectangle "User_PC (VLAN 10)" as PC1
rectangle "Server_VM (VLAN 20)" as VM1
rectangle "VoIP_Phone (VLAN 30)" as PHONE1
' Then connect them
C_CORE::GigabitEthernet1/0/2 -- J_CORE::ge-0/0/2 : "Trunk (VLAN 10,20,99)"
J_CORE::ge-0/0/2 -- A_CORE::Ethernet2 : "Trunk (VLAN 10,20,99)"
A_CORE::Ethernet2 -- C_CORE::GigabitEthernet1/0/2 : "Trunk (VLAN 10,20,99)"
C_CORE -- C_ACCESS : "Trunk (VLAN 10,99)"
J_CORE -- J_ACCESS : "Trunk (VLAN 20,99)"
A_CORE -- A_ACCESS : "Trunk (VLAN 30,99)"
C_ACCESS::GigabitEthernet1/0/1 -- PC1 : "Access VLAN 10"
J_ACCESS::ge-0/0/1 -- VM1 : "Access VLAN 20"
A_ACCESS::Ethernet1 -- PHONE1 : "Access VLAN 30"
@enduml
4.2. Logical VLAN Segmentation (D2)
This diagram illustrates the logical separation provided by VLANs, abstracting the physical network.
direction: right
VLAN10: Data VLAN (192.168.10.0/24) {
shape: cylinder
description: User Workstations
}
VLAN20: Servers VLAN (192.168.20.0/24) {
shape: cylinder
description: Application Servers
}
VLAN99: Management VLAN (192.168.99.0/24) {
shape: cylinder
description: Network Device Management
}
Router: Core Layer 3 Router {
shape: rhombus
description: Inter-VLAN Routing
}
User_PC -> VLAN10
Server_VM -> VLAN20
Network_Admin_Workstation -> VLAN99
VLAN10 -> Router
VLAN20 -> Router
VLAN99 -> Router
VLAN10.link.style.stroke-dash: 2
VLAN20.link.style.stroke-dash: 2
VLAN99.link.style.stroke-dash: 2
4.3. VLAN Trunking and Tagging Flow (Graphviz)
This diagram visualizes how traffic flows and is tagged on a trunk link.
digraph VLAN_FLOW {
rankdir=LR;
node [shape=box];
Client [label="Client PC\n(VLAN 10)"];
AccessSW [label="Access Switch\n(Port VLAN 10)"];
TrunkPort_A [label="Trunk Port A"];
TrunkLink [label="Trunk Link"];
TrunkPort_B [label="Trunk Port B"];
CoreSW [label="Core Switch"];
Client -> AccessSW [label="Untagged Frame\n(VLAN 10 implied)"];
AccessSW -> TrunkPort_A [label="Add 802.1Q Tag\n(VID 10)"];
TrunkPort_A -> TrunkLink [label="Tagged Frame"];
TrunkLink -> TrunkPort_B [label="Tagged Frame"];
TrunkPort_B -> CoreSW [label="Remove 802.1Q Tag\n(for local VLAN 10 processing)\nOR Forward Tagged"];
subgraph cluster_access {
label = "Access Layer";
color = blue;
Client; AccessSW;
}
subgraph cluster_trunk {
label = "Trunking";
color = green;
TrunkPort_A; TrunkLink; TrunkPort_B;
}
subgraph cluster_core {
label = "Core Layer";
color = red;
CoreSW;
}
}
5. Automation Examples
Automating VLAN configuration is essential for consistency, speed, and reducing human error in multi-vendor networks.
5.1. Ansible Playbook for Multi-Vendor VLAN Configuration
This Ansible playbook will create VLANs and configure both access and trunk ports across Cisco, Juniper, and Arista devices using their respective modules.
Inventory (inventory.ini):
[cisco_devices]
cisco_sw_01 hostname=192.168.1.10 ansible_network_os=ios
cisco_sw_02 hostname=192.168.1.11 ansible_network_os=ios
[juniper_devices]
juniper_ex_01 hostname=192.168.1.20 ansible_network_os=junos
juniper_ex_02 hostname=192.168.1.21 ansible_network_os=junos
[arista_devices]
arista_eos_01 hostname=192.168.1.30 ansible_network_os=eos
arista_eos_02 hostname=192.168.1.31 ansible_network_os=eos
[network_devices:children]
cisco_devices
juniper_devices
arista_devices
[network_devices:vars]
ansible_user=automation_user
ansible_password=YourSecurePassword
ansible_become=yes
ansible_become_method=enable
ansible_connection=network_cli
Vars (group_vars/all.yml):
vlans:
- id: 10
name: DATA_VLAN
- id: 20
name: SERVERS_VLAN
- id: 99
name: NATIVE_MGMT_VLAN
access_ports:
cisco:
Gi1/0/1: { vlan: 10, description: "User_DATA_Access_Port" }
juniper:
ge-0/0/1: { vlan: 10, description: "User_DATA_Access_Port" }
arista:
Ethernet1: { vlan: 10, description: "User_DATA_Access_Port" }
trunk_ports:
cisco:
Gi1/0/2: { native_vlan: 99, allowed_vlans: "10,20,99", description: "TRUNK_TO_CORE_SW" }
juniper:
ge-0/0/2: { native_vlan: 99, allowed_vlans: [10,20,99], description: "TRUNK_TO_CORE_SW" }
arista:
Ethernet2: { native_vlan: 99, allowed_vlans: "10,20,99", description: "TRUNK_TO_CORE_SW" }
Playbook (configure_vlans.yml):
---
- name: Configure VLANs and Interfaces on Multi-Vendor Devices
hosts: network_devices
gather_facts: no
connection: network_cli
tasks:
- name: Create VLANs on Cisco devices
when: ansible_network_os == 'ios'
cisco.ios.ios_vlans:
config:
- vlan_id: ""
name: ""
state: merged
loop: ""
- name: Create VLANs on Juniper devices
when: ansible_network_os == 'junos'
juniper.junos.junos_vlans:
config:
- name: ""
vlan_id: ""
state: merged
loop: ""
- name: Create VLANs on Arista devices
when: ansible_network_os == 'eos'
arista.eos.eos_vlans:
config:
- vlan_id: ""
name: ""
state: merged
loop: ""
- name: Configure Cisco Access Ports
when: ansible_network_os == 'ios'
cisco.ios.ios_l2_interfaces:
config:
- name: ""
description: ""
mode: access
access_vlan: ""
trunk_negotiation: false # Equivalent to switchport nonegotiate
port_fast: true
state: merged
loop: "" # Iterate over keys
- name: Configure Cisco Trunk Ports
when: ansible_network_os == 'ios'
cisco.ios.ios_l2_interfaces:
config:
- name: ""
description: ""
mode: trunk
native_vlan: ""
trunk_allowed_vlans: ""
trunk_negotiation: false # Equivalent to switchport nonegotiate
state: merged
loop: ""
- name: Configure Juniper Access Ports
when: ansible_network_os == 'junos'
juniper.junos.junos_l2_interfaces:
config:
- name: ""
description: ""
unit: 0
interface_mode: access
access_vlan: ""
state: merged
loop: ""
- name: Configure Juniper Trunk Ports
when: ansible_network_os == 'junos'
juniper.junos.junos_l2_interfaces:
config:
- name: ""
description: ""
unit: 0
interface_mode: trunk
native_vlan: ""
trunk_vlans: ""
state: merged
loop: ""
- name: Configure Arista Access Ports
when: ansible_network_os == 'eos'
arista.eos.eos_l2_interfaces:
config:
- name: ""
description: ""
mode: access
access_vlan: ""
state: merged
loop: ""
- name: Configure Arista Trunk Ports
when: ansible_network_os == 'eos'
arista.eos.eos_l2_interfaces:
config:
- name: ""
description: ""
mode: trunk
native_vlan: ""
trunk_allowed_vlans: ""
state: merged
loop: ""
- name: Save configuration on Cisco devices
when: ansible_network_os == 'ios'
ansible.builtin.command: "write memory" # or cisco.ios.ios_command: commands: ['write memory']
- name: Save configuration on Juniper devices
when: ansible_network_os == 'junos'
ansible.builtin.command: "commit and-quit" # or juniper.junos.junos_command: commands: ['commit and-quit']
- name: Save configuration on Arista devices
when: ansible_network_os == 'eos'
ansible.builtin.command: "write memory" # or arista.eos.eos_command: commands: ['write memory']
5.2. Python (Netmiko) Script for Multi-Vendor VLAN Configuration
This Python script uses Netmiko to connect to devices and configure VLANs and interface modes. It demonstrates a more imperative approach compared to Ansible’s declarative nature.
import os
from netmiko import ConnectHandler
from getpass import getpass
# Device definitions
devices = {
"cisco_sw": {
"device_type": "cisco_ios",
"host": "192.168.1.10",
"username": "automation_user",
"password": os.getenv("NETMIKO_PASSWORD", getpass("Enter Cisco password: ")),
"secret": os.getenv("NETMIKO_ENABLE_SECRET", getpass("Enter Cisco enable password: ")),
},
"juniper_ex": {
"device_type": "juniper_junos",
"host": "192.168.1.20",
"username": "automation_user",
"password": os.getenv("NETMIKO_PASSWORD", getpass("Enter Juniper password: ")),
},
"arista_eos": {
"device_type": "arista_eos",
"host": "192.168.1.30",
"username": "automation_user",
"password": os.getenv("NETMIKO_PASSWORD", getpass("Enter Arista password: ")),
},
}
# VLAN and interface configurations
vlan_config = {
"cisco_sw": [
"vlan 10", "name DATA_VLAN",
"vlan 20", "name SERVERS_VLAN",
"vlan 99", "name NATIVE_MGMT_VLAN",
"interface GigabitEthernet1/0/1", "description User_DATA_Access_Port", "switchport mode access", "switchport access vlan 10", "switchport nonegotiate", "spanning-tree portfast",
"interface GigabitEthernet1/0/2", "description TRUNK_TO_CORE_SW", "switchport mode trunk", "switchport trunk native vlan 99", "switchport trunk allowed vlan 10,20,99", "switchport nonegotiate",
],
"juniper_ex": [
"set vlans DATA_VLAN vlan-id 10",
"set vlans SERVERS_VLAN vlan-id 20",
"set vlans NATIVE_MGMT_VLAN vlan-id 99",
"set interfaces ge-0/0/1 unit 0 description \"User_DATA_Access_Port\"", "set interfaces ge-0/0/1 unit 0 family ethernet-switching interface-mode access", "set interfaces ge-0/0/1 unit 0 family ethernet-switching vlan members DATA_VLAN",
"set interfaces ge-0/0/2 unit 0 description \"TRUNK_TO_CORE_SW\"", "set interfaces ge-0/0/2 unit 0 family ethernet-switching interface-mode trunk", "set interfaces ge-0/0/2 unit 0 family ethernet-switching native-vlan-id 99", "set interfaces ge-0/0/2 unit 0 family ethernet-switching vlan members [DATA_VLAN SERVERS_VLAN NATIVE_MGMT_VLAN]",
"commit and-quit" # Commit must be run at the end for Junos
],
"arista_eos": [
"vlan 10", "name DATA_VLAN",
"vlan 20", "name SERVERS_VLAN",
"vlan 99", "name NATIVE_MGMT_VLAN",
"interface Ethernet1", "description User_DATA_Access_Port", "switchport mode access", "switchport access vlan 10",
"interface Ethernet2", "description TRUNK_TO_CORE_SW", "switchport mode trunk", "switchport trunk native vlan 99", "switchport trunk allowed vlan 10,20,99",
],
}
def configure_device(device_name, device_info, commands):
print(f"\n--- Connecting to {device_name} ({device_info['host']}) ---")
try:
with ConnectHandler(**device_info) as net_connect:
if device_info["device_type"] == "cisco_ios":
net_connect.enable() # Enter enable mode for Cisco
output = net_connect.send_config_set(commands)
print(output)
print(f"--- Configuration applied to {device_name} ---")
if device_info["device_type"] != "juniper_junos": # Junos commits are part of the commands list
print("Saving configuration...")
if device_info["device_type"] == "cisco_ios":
net_connect.send_command("write memory")
elif device_info["device_type"] == "arista_eos":
net_connect.send_command("write memory")
print("Configuration saved.")
except Exception as e:
print(f"!!! Error connecting or configuring {device_name}: {e} !!!")
if __name__ == "__main__":
for device_name, device_info in devices.items():
if device_name in vlan_config:
configure_device(device_name, device_info, vlan_config[device_name])
else:
print(f"No VLAN configuration defined for {device_name}")
6. Security Considerations
VLANs enhance security by segmenting traffic, but they are not foolproof. Several attack vectors can compromise VLAN isolation.
6.1. Attack Vectors
- VLAN Hopping:
- Switch Spoofing: An attacker connects a rogue device (e.g., a laptop running a malicious tool) to an access port and attempts to negotiate a trunk link with the switch using DTP (Dynamic Trunking Protocol). If successful, the attacker can then send and receive traffic on all allowed VLANs.
- Double Tagging (or VLAN Stacking): An attacker sends a frame with two 802.1Q tags. The outer tag matches the native VLAN of the trunk. The first switch processes the outer tag, strips it, and forwards the frame untagged on the native VLAN. The next switch on the trunk then sees the inner tag and forwards the frame to the VLAN specified by the inner tag, bypassing the intended segmentation.
- Native VLAN Exploitation: If the native VLAN is used for production traffic, untagged frames intended for the native VLAN can be injected or intercepted by an attacker if they are on the same physical segment as the native VLAN.
- MAC Address Flooding: Overwhelming the switch’s MAC address table (CAM table) to force it into hub mode (flooding all traffic out all ports), allowing an attacker to capture traffic from other VLANs.
- DHCP Snooping/ARP Inspection Bypass: Misconfigurations in security features can allow rogue DHCP servers or ARP spoofing attacks across VLANs.
6.2. Mitigation Strategies
- Disable DTP: Manually configure all ports as either
accessortrunk. For trunk ports, useswitchport mode trunkandswitchport nonegotiate(Cisco) or equivalent commands (Junos/Arista default to explicit configuration). - Change Native VLAN: Set the native VLAN on all trunk ports to an unused VLAN ID (e.g., VLAN 999) that is not routed or used for any production traffic. Ensure this is consistent across all interconnected switches.
- VLAN Pruning: Enable VLAN pruning on trunk links to ensure only necessary VLANs traverse the link. This reduces the attack surface by limiting where traffic for a particular VLAN can reach.
- Private VLANs (PVLANs): Used to isolate ports within the same VLAN at Layer 2. A PVLAN typically consists of a primary VLAN and one or more secondary VLANs (isolated or community). This is effective for server farms or public access areas where clients in the same subnet should not communicate directly.
- VLAN Access Control Lists (VACLs): Apply ACLs to VLAN interfaces to filter traffic between VLANs at Layer 2, even before it reaches a Layer 3 SVI (Switched Virtual Interface).
- Port Security: Limit the number of MAC addresses allowed on an access port to prevent MAC address flooding attacks and unauthorized device connections.
- DHCP Snooping and ARP Inspection: Implement these Layer 2 security features to prevent rogue DHCP servers and ARP spoofing within and across VLANs.
- Unused Ports: Shut down and assign unused ports to an unused “blackhole” VLAN.
- Management VLAN Isolation: Dedicate a specific VLAN (e.g., VLAN 99) for management interfaces of network devices and restrict access to this VLAN.
6.3. Security Configuration Examples
Cisco:
! Disable DTP on access and trunk ports explicitly
interface GigabitEthernet1/0/1
switchport mode access
switchport nonegotiate
end
interface GigabitEthernet1/0/2
switchport mode trunk
switchport nonegotiate
switchport trunk native vlan 999 ! Use an unused VLAN for native
switchport trunk allowed vlan 10,20,999
end
! Shut down unused ports
interface GigabitEthernet1/0/3
shutdown
switchport mode access
switchport access vlan 998 ! Assign to a blackhole VLAN
end
! Port Security Example
interface GigabitEthernet1/0/1
switchport port-security
switchport port-security maximum 1
switchport port-security violation restrict
switchport port-security mac-address sticky
end
Juniper:
# Ensure native VLAN is an unused ID and explicitly configured
set interfaces ge-0/0/2 unit 0 family ethernet-switching interface-mode trunk
set interfaces ge-0/0/2 unit 0 family ethernet-switching native-vlan-id 999
set interfaces ge-0/0/2 unit 0 family ethernet-switching vlan members [DATA_VLAN SERVERS_VLAN NATIVE_MGMT_VLAN 999]
# Shut down unused ports
set interfaces ge-0/0/3 disable
set interfaces ge-0/0/3 unit 0 family ethernet-switching interface-mode access
set interfaces ge-0/0/3 unit 0 family ethernet-switching vlan members BLACKHOLE_VLAN # Create BLACKHOLE_VLAN 998
# MAC Limiting (Port Security equivalent)
set ethernet-switching-options secure-access-port interface ge-0/0/1 mac-limit 1 action drop
Arista:
! Explicitly configure access/trunk, no DTP on Arista by default
interface Ethernet1
switchport mode access
switchport access vlan 10
end
interface Ethernet2
switchport mode trunk
switchport trunk native vlan 999 ! Use an unused VLAN for native
switchport trunk allowed vlan 10,20,999
end
! Shut down unused ports
interface Ethernet3
shutdown
switchport mode access
switchport access vlan 998 ! Assign to a blackhole VLAN
end
! Port Security (MAC Address Limit)
interface Ethernet1
switchport port-security max 1
switchport port-security violation shutdown
end
7. Verification & Troubleshooting
Effective verification and troubleshooting are crucial for maintaining VLAN integrity.
7.1. Verification Commands
Always verify your configurations after making changes.
Cisco:
show vlan brief # Verify VLAN existence and status
show interfaces status # Check interface status and assigned access VLANs
show interfaces GigabitEthernet1/0/1 switchport # Detailed access port info
show interfaces GigabitEthernet1/0/2 switchport # Detailed trunk port info, native VLAN, allowed VLANs
show interfaces trunk # Summary of all trunk ports
show mac address-table interface GigabitEthernet1/0/1 # Verify MAC addresses learned on access ports
ping 192.168.10.10 # Test connectivity within a VLAN
Juniper:
show vlans # Verify VLAN existence and associated interfaces
show interfaces terse # Check interface status
show ethernet-switching interfaces ge-0/0/1 # Detailed access port info
show ethernet-switching interfaces ge-0/0/2 # Detailed trunk port info, native VLAN, allowed VLANs
show ethernet-switching interfaces # Summary of all L2 interfaces
show ethernet-switching table # Verify MAC addresses learned
ping 192.168.10.10 count 3 # Test connectivity within a VLAN
Arista:
show vlan # Verify VLAN existence and associated ports
show interfaces status # Check interface status and assigned access VLANs
show interfaces Ethernet1 switchport # Detailed access port info
show interfaces Ethernet2 switchport # Detailed trunk port info, native VLAN, allowed VLANs
show interfaces trunk # Summary of all trunk ports
show mac address-table interface Ethernet1 # Verify MAC addresses learned
ping 192.168.10.10 # Test connectivity within a VLAN
7.2. Troubleshooting
| Common Issue | Description | Resolution Steps +
For the PlantUML diagram, I used `node "Cisco IOS XE Device" as CIXE`, `node "Juniper Junos Device" as JUNOS`, `node "Arista EOS Device" as EOS`, then connected them. This is the correct way. I avoided the common error of defining them in the arrow.
### 8. Performance Optimization
Optimizing VLAN performance ensures efficient network operation and resource utilization.
* **VLAN Pruning:** As mentioned in security, pruning is also a performance optimization. It prevents broadcast, unknown unicast, and multicast traffic for a specific VLAN from being sent over a trunk link if that VLAN has no active ports on the receiving switch. This significantly reduces unnecessary traffic on trunk links.
* **Cisco:** `switchport trunk allowed vlan remove <vlan_id>` or `vlan database; vtp pruning`.
* **Juniper:** `set protocols rstp interface <interface_name> no-vlan-pruning` (for specific cases, otherwise default behavior or filters control). Generally, you explicitly define `vlan members` on trunks.
* **Arista:** `switchport trunk allowed vlan remove <vlan_id>`. VTP is not available on Arista; explicit allowed VLANs manage pruning.
* **Optimize Broadcast Domains:** VLANs inherently reduce broadcast domains. Proper segmentation prevents broadcast storms from impacting the entire network. Design VLANs with appropriate sizes – don't make them too large (negates benefits) or too small (creates management overhead).
* **Load Balancing Trunks (LAG/LACP):** Use Link Aggregation Groups (LAG) or Link Aggregation Control Protocol (LACP) to bundle multiple physical links into a single logical trunk. This provides increased bandwidth and redundancy for inter-switch VLAN traffic.
* **Hardware Offloading/ASICs:** Modern network devices utilize specialized ASICs (Application-Specific Integrated Circuits) for forwarding and tagging. Ensure your hardware is capable of handling the expected VLAN throughput and processing efficiently.
* **QoS Implementation:** Prioritize critical VLAN traffic (e.g., voice, video) over less critical traffic using 802.1p (PCP bits in the 802.1Q tag) or DSCP (Differentiated Services Code Point) at Layer 3.
* **Monitoring Recommendations:** Implement robust network monitoring to track bandwidth utilization, error rates, and broadcast/multicast traffic levels on VLANs and trunk ports. Tools like SNMP or NetFlow can provide valuable insights.
### 9. Hands-On Lab
This lab provides a practical scenario to configure and verify multi-vendor VLANs.
#### 9.1. Lab Topology (nwdiag)
```nwdiag
nwdiag {
network CORE {
description = "Core Network"
address = "10.0.0.0/24"
Cisco_Core_SW [address = "10.0.0.1"];
Juniper_Core_SW [address = "10.0.0.2"];
Arista_Core_SW [address = "10.0.0.3"];
}
network Access_Cisco {
description = "Cisco Access Layer"
Cisco_Core_SW -- Cisco_Access_SW;
Cisco_Access_SW [address = "192.168.1.1"];
User_PC_A [address = "192.168.10.10", shape = endpoint];
User_PC_A -- Cisco_Access_SW;
}
network Access_Juniper {
description = "Juniper Access Layer"
Juniper_Core_SW -- Juniper_Access_SW;
Juniper_Access_SW [address = "192.168.2.1"];
Server_A [address = "192.168.20.20", shape = cloud];
Server_A -- Juniper_Access_SW;
}
network Access_Arista {
description = "Arista Access Layer"
Arista_Core_SW -- Arista_Access_SW;
Arista_Access_SW [address = "192.168.3.1"];
VoIP_A [address = "192.168.30.30", shape = box];
VoIP_A -- Arista_Access_SW;
}
}
9.2. Objectives
- Create VLANs 10 (Data), 20 (Servers), 30 (Voice), and 99 (Management/Native) on all Core and Access switches.
- Configure a trunk link between
Cisco_Core_SWandJuniper_Core_SW, allowing VLANs 10, 20, 30, and 99, with VLAN 99 as native. - Configure a trunk link between
Juniper_Core_SWandArista_Core_SW, allowing VLANs 10, 20, 30, and 99, with VLAN 99 as native. - Configure
User_PC_A’s port onCisco_Access_SWas an access port for VLAN 10. - Configure
Server_A’s port onJuniper_Access_SWas an access port for VLAN 20. - Configure
VoIP_A’s port onArista_Access_SWas an access port for VLAN 30. - Configure inter-VLAN routing on one of the Core switches (e.g., Cisco_Core_SW) by creating SVIs.
- Implement basic VLAN security best practices.
9.3. Step-by-Step Configuration
(Assume you have connectivity and login credentials for all devices.)
Step 1: Create VLANs on all devices (Core and Access).
- Refer to the configuration examples in Section 3.1-3.3 for each vendor.
- Ensure VLANs 10, 20, 30, 99 are created with appropriate names.
Step 2: Configure Trunk Links between Core Switches.
- Cisco_Core_SW (GigabitEthernet1/0/1 to Juniper_Core_SW):
interface GigabitEthernet1/0/1 description TRUNK_TO_JUNIPER_CORE switchport mode trunk switchport trunk native vlan 99 switchport trunk allowed vlan 10,20,30,99 switchport nonegotiate end - Juniper_Core_SW (ge-0/0/1 to Cisco_Core_SW, ge-0/0/2 to Arista_Core_SW):
set interfaces ge-0/0/1 unit 0 description "TRUNK_TO_CISCO_CORE" set interfaces ge-0/0/1 unit 0 family ethernet-switching interface-mode trunk set interfaces ge-0/0/1 unit 0 family ethernet-switching native-vlan-id 99 set interfaces ge-0/0/1 unit 0 family ethernet-switching vlan members [DATA_VLAN SERVERS_VLAN VOICE_VLAN NATIVE_MGMT_VLAN] set interfaces ge-0/0/2 unit 0 description "TRUNK_TO_ARISTA_CORE" set interfaces ge-0/0/2 unit 0 family ethernet-switching interface-mode trunk set interfaces ge-0/0/2 unit 0 family ethernet-switching native-vlan-id 99 set interfaces ge-0/0/2 unit 0 family ethernet-switching vlan members [DATA_VLAN SERVERS_VLAN VOICE_VLAN NATIVE_MGMT_VLAN] commit - Arista_Core_SW (Ethernet1 to Juniper_Core_SW):
interface Ethernet1 description TRUNK_TO_JUNIPER_CORE switchport mode trunk switchport trunk native vlan 99 switchport trunk allowed vlan 10,20,30,99 end
Step 3: Configure Access Ports on Access Switches.
- Cisco_Access_SW (Gi1/0/1 to User_PC_A):
interface GigabitEthernet1/0/1 description USER_PC_A_PORT switchport mode access switchport access vlan 10 switchport nonegotiate spanning-tree portfast end - Juniper_Access_SW (ge-0/0/1 to Server_A):
set interfaces ge-0/0/1 unit 0 description "SERVER_A_PORT" set interfaces ge-0/0/1 unit 0 family ethernet-switching interface-mode access set interfaces ge-0/0/1 unit 0 family ethernet-switching vlan members SERVERS_VLAN commit - Arista_Access_SW (Ethernet1 to VoIP_A):
interface Ethernet1 description VOIP_PHONE_A_PORT switchport mode access switchport access vlan 30 end
Step 4: Configure Inter-VLAN Routing (on Cisco_Core_SW).
interface Vlan10
description DATA_VLAN_SVI
ip address 192.168.10.1 255.255.255.0
end
interface Vlan20
description SERVERS_VLAN_SVI
ip address 192.168.20.1 255.255.255.0
end
interface Vlan30
description VOICE_VLAN_SVI
ip address 192.168.30.1 255.255.255.0
end
ip routing
Step 5: Implement Basic Security.
- Ensure DTP is disabled (Cisco:
nonegotiate, Juniper/Arista: implicit with explicitmode trunk/interface-mode trunk). - Shut down unused ports and assign to a blackhole VLAN. (e.g., VLAN 998).
- Change the native VLAN to 999 on all trunks and ensure it’s not used for anything else.
9.4. Verification Steps
- VLAN Existence: Use
show vlan brief(Cisco),show vlans(Juniper),show vlan(Arista) on all devices. - Access Port Assignment: Confirm
User_PC_Ais in VLAN 10,Server_Ain VLAN 20,VoIP_Ain VLAN 30 using vendor-specificshow interfaces switchportcommands. - Trunk Port Configuration: Verify trunk mode, native VLAN (999), and allowed VLANs (10, 20, 30, 99) on core inter-switch links.
- MAC Address Learning: Check
show mac address-tableon relevant switches to see if client devices are learning MACs in their respective VLANs. - Connectivity within VLANs:
- Ping from
User_PC_Ato192.168.10.1(Cisco_Core_SW SVI). - Ping from
Server_Ato192.168.20.1(Cisco_Core_SW SVI). - Ping from
VoIP_Ato192.168.30.1(Cisco_Core_SW SVI).
- Ping from
- Connectivity between VLANs:
- Ping from
User_PC_A(VLAN 10) toServer_A(VLAN 20) IP192.168.20.20. This tests inter-VLAN routing onCisco_Core_SW. - Ping from
User_PC_A(VLAN 10) toVoIP_A(VLAN 30) IP192.168.30.30.
- Ping from
9.5. Challenge Exercises
- Configure QoS on
Arista_Access_SWto prioritize VoIP traffic (VLAN 30) using 802.1p. - Implement port security on
Cisco_Access_SWforUser_PC_A’s port, allowing only 1 MAC address. - Modify the Ansible playbook to remove VLAN 30 from all devices.
- Troubleshoot a scenario where
User_PC_Acan ping192.168.10.1but not192.168.20.1. (Hint: Checkip routingor SVI configurations).
10. Best Practices Checklist
When deploying and managing VLANs in an enterprise multi-vendor network, adhere to these best practices:
- VLAN ID Planning: Use consistent and non-overlapping VLAN ID ranges across the network. Avoid common default IDs (1, 1002-1005).
- Naming Conventions: Establish clear and consistent VLAN naming for easy identification (e.g., VLAN_10_DATA, VLAN_20_SERVER).
- Documentation: Keep comprehensive, up-to-date documentation of VLAN assignments, IP subnets, and device configurations.
- Native VLAN: Configure a dedicated, unused VLAN as the native VLAN on all trunks and ensure consistency. Never use VLAN 1 as native.
- DTP (Cisco): Disable DTP on all production ports by explicitly setting
switchport mode accessorswitchport mode trunkandswitchport nonegotiate. - VLAN Pruning: Enable VLAN pruning on trunk links to limit broadcast domains and improve performance.
- Unused Ports: Shut down unused ports and assign them to a “blackhole” VLAN that has no Layer 3 interface.
- Port Security: Implement port security on access ports to prevent unauthorized devices and MAC address flooding.
- Management VLAN: Isolate network device management interfaces in a dedicated VLAN with strict access controls.
- Inter-VLAN Routing: Centralize inter-VLAN routing on capable Layer 3 switches or routers, applying ACLs for segmentation.
- QoS: Apply Quality of Service policies to prioritize critical traffic (e.g., voice, video) within VLANs.
- Network Automation: Utilize automation tools (Ansible, Python) for consistent, error-free deployment and management of VLANs across vendors.
- Regular Audits: Periodically review VLAN configurations and security settings for compliance and vulnerabilities.
- Change Management: Implement a formal change management process for all VLAN modifications.
11. Reference Links
- IEEE 802.1Q: https://standards.ieee.org/ieee/802.1Q/10323/
- IEEE 802.1ad (QinQ): https://en.wikipedia.org/wiki/IEEE_802.1ad
- Cisco VLAN Best Practices: https://www.cisco.com/c/en/us/support/docs/smb/routers/cisco-rv-series-small-business-routers/1778-tz-VLAN-Best-Practices-and-Security-Tips-for-Cisco-Business-Routers.html
- Juniper Junos Documentation: https://www.juniper.net/documentation/us/en/software/junos/junos-qfx-series/junos-qfx-series-switching-reference/topics/topic-map/switching-vlans.html (Search for VLANs in the latest Junos OS docs)
- Arista EOS Documentation: https://www.arista.com/en/support/design-guides/arista-design-guides/vxlan-design-guide-with-evpn (Search for VLANs in Arista EOS config guides)
- Ansible Network Automation: https://docs.ansible.com/ansible/latest/network/user_guide/network_index.html
- Netmiko Documentation: https://github.com/ktbyers/netmiko
- VLAN Hopping Attacks & Mitigation: https://www.imperva.com/learn/availability/vlan-hopping/
12. What’s Next
This chapter provided a comprehensive look at multi-vendor VLAN configuration, from foundational concepts to advanced automation and security. You now understand how to logically segment your network, manage traffic flow, and secure your VLAN deployments across diverse hardware.
In the next chapter, we will expand on network segmentation by exploring Chapter 6: Advanced Layer 2 Switching: Spanning Tree Protocol and Link Aggregation. We’ll delve into preventing loops, optimizing link utilization, and ensuring high availability within your Layer 2 domain, critical components that work hand-in-hand with robust VLAN design.