Set Up RSPAN on OS10

Source port for span is Switch 1, 1/1/9 Our goal is to move the traffic through switch 2, which is just an intermediary switch, to port 1/1/11 on switch 3 which will finally move it out port 1/1/12 where our laptop is listening.
We will use VLAN 99 to transport our RSPAN traffic
Explanation
Section titled “Explanation”One of the things that’s different about the Dell configuration is the use of ACLs in the configuration. The way OS10 sees RSPAN is on the source side you grab whatever source you want and then you push that to a special “remote” VLAN. This is indicated only on the source switch itself. Then, each other intermediate and destination switch uses an ACL to indicate what traffic should be captured from that VLAN and subsequently forwarded. Finally, on the destination a regular local monitor session is used to pull the traffic from the RSPAN VLAN and push it t o network sensors.
Switch 1
Section titled “Switch 1”Version
Section titled “Version”OS10# show versionDell EMC Networking OS10 EnterpriseCopyright (c) 1999-2020 by Dell Inc. All Rights Reserved.OS Version: 10.5.1.3Build Version: 10.5.1.3.190Build Time: 2020-06-19T21:48:07+0000System Type: S4112F-ONArchitecture: x86_64Up Time: 18 weeks 3 days 11:10:52configure terminalinterface vlan 99description remote_spanremote-spanexitinterface ethernet 1/1/13:1no shutdownswitchport mode trunkswitchport trunk allowed vlan 99exitmonitor session 18 type rpm-sourcesource interface ethernet 1/1/9 bothdestination remote-vlan 99no shutSwitch 2
Section titled “Switch 2”Version
Section titled “Version”Dell EMC Networking OS10 EnterpriseCopyright (c) 1999-2020 by Dell Inc. All Rights Reserved.OS Version: 10.5.1.3Build Version: 10.5.1.3.190Build Time: 2020-06-19T21:48:07+0000System Type: S4112F-ONArchitecture: x86_64Up Time: 00:48:32configure terminalinterface vlan 99exitinterface range ethernet 1/1/11switchport mode trunkswitchport trunk allowed vlan 99exitinterface ethernet 1/1/12mac access-group rspan inswitchport mode trunkswitchport trunk allowed vlan 99exitmonitor session 1destination interface ethernet1/1/11flow-based enablesource interface ethernet1/1/12no shutmac access-list rspanseq 10 permit any any capture session 1 vlan 99Switch 3
Section titled “Switch 3”Version
Section titled “Version”OS10# show versionDell EMC Networking OS10 EnterpriseCopyright (c) 1999-2020 by Dell Inc. All Rights Reserved.OS Version: 10.5.1.3Build Version: 10.5.1.3.190Build Time: 2020-06-19T21:48:07+0000System Type: S4112F-ONArchitecture: x86_64Up Time: 03:00:15configure terminalinterface vlan 99no shutexitmac access-list rpanseq 10 permit any any capture session 1 vlan 99interface ethernet 1/1/11switchport mode trunkswitchport trunk allowed vlan 99mac access-group rpan inexitinterface ethernet 1/1/12no shutexitmonitor session 1destination interface ethernet1/1/12flow-based enablesource interface ethernet1/1/11no shutNotice here that there is an access list which captures the traffic on the inbound trunk interface. This access list is required. Also notice that on our monitor session we have flow-based enable which is also a requirement.
How RSPAN Works Under the Hood
Section titled “How RSPAN Works Under the Hood”-
When you run commands in OS10 what you’re really doing is calling into wrapper functions which ultimately do two things: configure the NPU and configure Debian. The commands you run are actually governed by a series of YANG files which exhaustively define what commands are acceptable and in what contexts. For example, the
rpm-sourcecommand is defined in an enum here in/alt/opt/dell/os10/share/yang-models/dell-span.yang:typedef monitoring-types {type enumeration {enum "local" {value 1;description"PM local session.";}enum "rpm-source" {value 2;description"RPM source session.";}enum "erpm-source" {value 3;description"ERPM source session.";}}description"Monitor session types.";} -
These definitions are combined with XML files which ultimately define the exact syntax of each command. For example,
/alt/opt/dell/os10/clisystem/command-tree/span.xmldefines the syntax for SPAN commands (note how the yang_name key references ):<!-- monitor session <id> type [local|rpm-source|rpm-destination|erpm-source]--><PARAM name="type" help="Monitor session type" optional="true" ptype="SUBCOMMAND" mode="subcommand"><PARAM name="spantype" help="PM/RPM/ERPM sessions" default="local" ptype="SPANMODE" yang_name="/sessions/session/monitortype=${spantype}"> </PARAM></PARAM> -
I didn’t exhaustively reverse engineer this part but at some point those commands and their arguments are interpreted and pushed to a series of Python modules. You’ll see below how VLANs are set up using
brctl. That setup seems to be handled by/alt/opt/dell/os10/lib/python/dn_base_br_tool.py. Ex:def create_br(bname):"""Method to create a bridge.Args:bname (str): Name of the BridgeReturns:bool: The return value. True for success, False otherwise"""res = []if run_command([BRCTL_CMD, 'addbr', bname], res) == 0:return Truereturn False -
Remote SPAN VLAN gets setup as a bridge and a new dummy interface is created which is a member of that bridge:
admin@OS10:/home/admin$ ip a s.....38: br99: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000link/ether 50:9a:4c:d6:0a:a1 brd ff:ff:ff:ff:ff:ffinet6 fe80::529a:4cff:fed6:aa1/64 scope linkvalid_lft forever preferred_lft forever39: e101-013-1.99@e101-013-1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br99 state UP group default qlen 1000link/ether 50:9a:4c:d6:0a:7d brd ff:ff:ff:ff:ff:ffroot@OS10:~# brctl show br99bridge name bridge id STP enabled interfacesbr99 8000.509a4cd60aa1 no e101-013-1.99 -
Under the hood the NPU is instructed to push traffic coming in on port 1/1/9 to this bridge which will then forward it. If you really want to dig under the covers this is how that works. CPS (the userland tool which interacts with a database for configuring the switch) will receive the command. You can drop to command line with
system bashand then go take a look at/alt/opt/dell/os10/bin/cps_config_mirror.pyand actually see where the call to NAS is made. Note: The NAS (Network Abstraction Service) is responsible for abstracting the chipset (broadcom) API from the rest of the OS above.
-
This is the definition for nas_mirror_add_source and nas_mirror_op:
def nas_mirror_op(op, data_dict,commit=True):obj = cps_utils.CPSObject(module="base-mirror/entry",data=data_dict)if commit:nas_common.get_cb_method(op)(obj)else:return objdef nas_mirror_add_source(obj,intf,direction):l = ["intf","0","src"]obj.add_embed_attr(l,nas_os_utils.if_nametoindex(intf))l[2]="direction"obj.add_embed_attr(l,direction_type[direction]) -
if commitis referring to a commit to the CPS database. The definition forget_cb_methodis in/alt/opt/dell/os10/lib/python/nas_common_utils.pystr_to_cps_cb = {"create": create,"set": set,"delete": delete,"get": get,"rpc": rpc,}def get_cb_method(op):return str_to_cps_cb[op] -
What’s happening here is it’s taking the CPS object which has our instructions which basically say “make me an RSPAN” and the argument (op) will be either create or set. What this is going to do is update the CPS database with our new configuration.
-
This is the NAS’ Northbound CPS APi being called here. on the southbound end it will call into the SAI which is the actual manufacturer’s (Broadcom in our case) API. This process is described in detail here.
-
The NDI represents this call to the SAI API. For remote mirrors that is defined here. You can explore it function by function but the TLDR version is it’s going to create a struct with the info relevant to creating the monitor session and it’s going to feed that info the SAI. That magic happens in this function:
t_std_error ndi_mirror_create_session(ndi_mirror_entry_t * entry){
if(entry == NULL ){NDI_MIRROR_LOG(ERR,0,"NDI Mirror entry passed to create Mirror session is NULL");return STD_ERR(MIRROR,PARAM,0);}sai_status_t sai_ret;sai_attribute_t sai_mirror_attr_list[MAX_MIRROR_SAI_ATTR];unsigned int ndi_mirror_attr_count = 0;if(!ndi_mirror_fill_common_attr(entry,sai_mirror_attr_list,ndi_mirror_attr_count)){return STD_ERR(MIRROR,PARAM,0);}if(entry->mode == BASE_MIRROR_MODE_RSPAN || entry->mode == BASE_MIRROR_MODE_ERSPAN){ndi_mirror_fill_rspan_attr(entry,sai_mirror_attr_list,ndi_mirror_attr_count);}if(entry->mode == BASE_MIRROR_MODE_ERSPAN){ndi_mirror_fill_erspan_attr(entry,sai_mirror_attr_list,ndi_mirror_attr_count);}nas_ndi_db_t *ndi_db_ptr = ndi_db_ptr_get(entry->dst_port.npu_id);if ((sai_ret = ndi_mirror_api_get(ndi_db_ptr)->create_mirror_session((sai_object_id_t *)&entry->ndi_mirror_id,ndi_switch_id_get(),ndi_mirror_attr_count,sai_mirror_attr_list))!= SAI_STATUS_SUCCESS) {NDI_MIRROR_LOG(ERR,0,"Failed to create a new Mirroring Session");return STD_ERR(MIRROR, FAIL, sai_ret);}NDI_MIRROR_LOG(INFO,3,"Created new mirroring session with Id %" PRIu64 " ",entry->ndi_mirror_id);return STD_ERR_OK;}
-
What’s going on here is the function
ndi_mirror_create_sessionis going to receive a pointer to a struct of type ndi_mirror_entry_t. That struct contains all the relevant info for creating the mirror, port ID, mode (RSPAN), VLAN, etc. That struct is going to be filled out by two functions -ndi_mirror_fill_common_attrandndi_mirror_fill_rspan_attr. Finally it will be fed into the code at line 199 and this is where we lose track of it. -
This is where we drop off because below this is Broadcom’s API and they don’t publicly publish that stuff. At this point though you’re calling into Broadcom’s SDK which is going to program the NPU to behave a certain way.