Mirroring traffic with SPAN, RSPAN and ERSPAN

These features allow us copy the traffic of a switchport or an entire VLAN and send the copied frames to another switchport. This destination port (where we send the copied frames to) can be on the same switch (SPAN), on a different switch in the same L2 segment (RSAPN), or in a completely different network (ERSPAN).

Topology, yellow links are in the forwarding state for each STP instance
Topology, the yellow links are in the forwarding state for each STP instance

We're going to use the topology above, I've already modified the Spanning Tree, and made SW1 the Root Bridge for every VLAN:

SW1(config)#spanning-tree vlan 10,20,30 priority 0

So all of the traffic now go through SW1, the yellow links are trunks in the forwarding state, and the other trunks between the switches are in the blocking state. The other interfaces towards the routers are in access mode configured in their respective VLAN. Here is the configuration of SW1 for example:

SW1(config)#int range g0/0 - 2
SW1(config-if-range)#switchport trunk encapsulation dot1q
SW1(config-if-range)#switchport mode trunk
SW1(config-if-range)#int g0/3
SW1(config-if)#switchport mode access
SW1(config-if)#switchport access vlan 30
% Access VLAN does not exist. Creating vlan 30
SW1(config-if)#exit
SW1(config)#vlan 10,20
SW1(config-vlan)#exit

We do the inter-VLAN routing on SW1 using SVIs:

SW1(config)#ip routing 
SW1(config)#int vlan 10
SW1(config-if)#ip address 10.10.10.254 255.255.255.0
SW1(config-if)#no shut
SW1(config-if)#int vlan 20
SW1(config-if)#ip address 10.20.20.254 255.255.255.0
SW1(config-if)#no shut
SW1(config-if)#int vlan 30
SW1(config-if)#ip address 10.30.30.254 255.255.255.0
SW1(config-if)#no shut

SPAN

Now let's mirror the traffic on interface G0/2 and send it to G0/3:

SW1(config)#monitor session 1 source ?
  interface  SPAN source interface
  remote     SPAN source Remote
  vlan       SPAN source VLAN

SW1(config)#monitor session 1 source interface g0/2 ?
  ,     Specify another range of interfaces
  -     Specify a range of interfaces
  both  Monitor received and transmitted traffic
  rx    Monitor received traffic only
  tx    Monitor transmitted traffic only
  <cr>

SW1(config)#monitor session 1 source interface g0/2 both

With SPAN we have to define a source and a destination. The source can be a single (or multiple) interface or an entire VLAN. Here we configured the interface G0/2 as the source. The source interface can be a trunk or an access port. We can also choose which direction (rx/tx) we want the traffic to be captured (both is the default option). If we have a trunk link (using 802.1q VLAN tags) as the source we can also restrict which VLAN we want to capture like this:

SW1(config)#monitor session 1 filter vlan 10

Here we only copy the frames tagged with VLAN 10. And finally we configure the SPAN destination:

SW1(config)#monitor session 1 destination interface g0/3 

The SPAN destination port is only used to forward the SPAN traffic, it cannot be used as a regular access port anymore. Ingress frames sent from the "desktop-0" are dropped by dafult. If we want to send and receive traffic from the destination port we can use the ingress keyword with the monitor session X destination command. Unfortunately this feature wasn't supported on the IOSv_L2 image I used in this lab. If I ping R4 from R1 the traffic is copied from the trunk and sent to the desktop PC on G0/3:

No dot1q by default
By default the 802.1q VLAN tag is removed

Notice that the dot1q VLAN tag is not preserved when the copied traffic is sent to G0/3. By default SW1 removes the dot1q tag when it copies the traffic, also SW1 doesn't copy any Layer 2 protocol (STP/CDP/DTP etc.), just regular IP traffic. To change this we can use the following command:

SW1(config)#monitor session 1 destination interface Gi0/3 encapsulation replicate

Now SW1 copies everything and also preserves the VLAN tags, so we can even see the STP BPDUs on the desktop machine (this feature is also not available on certain platforms):

encapsulation replicate
STP BPDUs copied with the dot1q tag preserved

Notice that these BPDUs were sent on the link between SW1 and SW4 and copied to interface G0/3. STP is disabled on the destination port, and SW1 doesn't send any BPDUs on G0/3. To manually disable BPDUs we can use the following command:

SW1(config-if)#spanning-tree bpdufilter enable 

Using this command is generally not recommended, since it can cause loops, use it with great care!

RSPAN

With SPAN the destination port must be located on the same switch, but RSPAN makes it possible to move the destination port to a different switch. To send the mirrored traffic to a different switch we have to designate a VLAN to RPSAN traffic. This VLAN cannot be used to forward regular traffic anymore. In this example we copy the traffic of G0/2 on SW2 (which is an access port) and send to the same port on SW1. First I delete the current session and create the RSPAN VLAN on both switches (if we have multiple switches between the source and the destination we have to create the RSPAN VLAN on ALL switches):

SW1(config)#no monitor session 1
SW1(config)#vlan 99       
SW1(config-vlan)#remote-span

SW2(config)#vlan 99
SW2(config-vlan)#remote-span

The difference from SPAN is that on SW2 the RPSAN VLAN is configured as the destination, and on SW1 the source is the RSPAN VLAN, basically everything else is the same concept.

SW2(config)#monitor session 1 source int g0/2 
SW2(config)#monitor session 1 destination remote vlan 99 

SW1(config)#monitor session 1 source remote vlan 99
SW1(config)#monitor session 1 destination int g0/3

Notice that this time we can't preserve the dot1q tags, not just because the source is an access port, but because RSPAN doesn't allow it, the traffic is already tagged with the RSPAN VLAN when it is sent though the trunk between SW2 and SW2.

ERSPAN

If we want to send the traffic to a completely different network we have to use RSPAN. This feature is not supported on all platforms, it also wasn't supported on the IOSv_L2 images I used, so I also deployed a CSR1000v router as well (CSR1). In this example I send the traffic of G1 to the desktop machine.

CSR1(config)#monitor session 1 type erspan-source   
CSR1(config-mon-erspan-src)#description Testing ERSPAN on the CSR
CSR1(config-mon-erspan-src)#source ?
  cpu               SPAN source CPU
  drop-cause        SPAN source DROP-CAUSE
  interface         SPAN source interface
  service instance  SPAN source EFP
  vlan              SPAN source VLAN

CSR1(config-mon-erspan-src)#source interface g1
CSR1(config-mon-erspan-src)#filter ?
  access-group  Filter access-list
  vlan          SPAN source VLAN

CSR1(config-mon-erspan-src)#filter access-group ?
  <1-199>      IP access-list reference (standard or extended)
  <1300-2699>  IP access-list reference (expanded range)
  WORD         Access-list name

On the CSR we have many options available to define the ERSPAN source: besides the interface or VLAN we can also use a service instance as a source for example. And we can also filter the traffic based on ACLs. Finally we define the destination as an IP address of the remote host where we want to send the mirrored traffic to and a unique ERSPAN-ID:

CSR1(config-mon-erspan-src)#no shut
CSR1(config-mon-erspan-src)#destination 
CSR1(config-mon-erspan-src-dst)#ip address 10.30.30.5 
CSR1(config-mon-erspan-src-dst)#erspan-id 10
CSR1(config-mon-erspan-src-dst)#origin ip address 10.10.10.6
CSR1(config-mon-erspan-src-dst)#exit

The traffic sent to the remote machine is encapsulated in ERSPAN GRE, note that the ERSPAN-ID (10) is also present in the ERSPAN header. In this example we send a copy of the Echo Request sent from R2 (10.20.20.2) to CSR1 (10.10.10.6) based on the inner IP header.

ERSPAN with GRE encapsulation
ERSPAN GRE encapsulated packet sent to the desktop machine