Adding pseudo wire tests
Change-Id: If72e67e7bf1fa81b370c96696196fc575a453557
diff --git a/ofdpa/pw_flows.py b/ofdpa/pw_flows.py
index 42f8476..5713a94 100644
--- a/ofdpa/pw_flows.py
+++ b/ofdpa/pw_flows.py
@@ -199,6 +199,7 @@
verify_packet( self, pkt, out_port )
verify_no_packet( self, pkt, in_port )
verify_no_other_packets( self )
+
# Flush all the rules for the next couple
delete_all_flows( self.controller )
delete_groups( self.controller, Groups )
@@ -474,6 +475,7 @@
verify_packet( self, pkt, out_port )
verify_no_packet( self, pkt, in_port )
verify_no_other_packets( self )
+
delete_all_flows( self.controller )
delete_groups( self.controller, Groups )
delete_groups( self.controller, Groups2 )
@@ -567,6 +569,7 @@
verify_packet( self, pkt, out_port )
verify_no_packet( self, pkt, in_port )
verify_no_other_packets( self )
+
delete_all_flows( self.controller )
delete_groups( self.controller, Groups )
delete_groups( self.controller, Groups2 )
@@ -1156,6 +1159,7 @@
delete_groups( self.controller, Groups2 )
delete_all_groups( self.controller )
+
class IntraCO_2_Labels( base_tests.SimpleDataPlane ):
"""
This is meant to test the PW intermediate transport.
@@ -1463,13 +1467,16 @@
return
ports = config[ "port_map" ].keys( )
for pair in itertools.product(ports, ports):
+
# we generate all possible products
in_port = pair[0]
out_port = pair[1]
if out_port == in_port:
continue
+
# we fill the pipeline for the pw initiation
# on the reverse path
+
(
port_to_mpls_label_2,
port_to_mpls_label_1,
@@ -1488,7 +1495,7 @@
egress_tag=EGRESS_TAGGED,
mpls_labels=1
)
- # we fill the pipeline for the pw termination
+ # we fill the pipeline for the pw termination
(
port_to_mpls_label_pw,
port_to_in_vlan_2,
@@ -1523,12 +1530,13 @@
verify_packet( self, pkt, out_port )
verify_no_packet( self, pkt, in_port )
verify_no_other_packets( self )
- delete_all_flows( self.controller )
+
+ delete_all_flows( self.controller )
delete_groups( self.controller, Groups )
delete_groups( self.controller, Groups2 )
delete_all_groups( self.controller )
finally:
- delete_all_flows( self.controller )
+ delete_all_flows( self.controller )
delete_groups( self.controller, Groups )
delete_groups( self.controller, Groups2 )
delete_all_groups( self.controller )
@@ -1613,6 +1621,7 @@
verify_packet( self, pkt, out_port )
verify_no_packet( self, pkt, in_port )
verify_no_other_packets( self )
+
delete_all_flows( self.controller )
delete_groups( self.controller, Groups )
delete_groups( self.controller, Groups2 )
@@ -1717,6 +1726,323 @@
delete_groups( self.controller, Groups2 )
delete_all_groups( self.controller )
+class IntermediateTransport( base_tests.SimpleDataPlane ):
+ """
+ This test is meant to verify that the alternative approach for handling
+ pseudowires in spine switches. Specifically, in the mpls table we install
+ 2 rules , the match(SR1, BoS=1) and match(SR2, BoS=0). The match(SR2, BoS=0)
+ should match and the packet should be forwarded through the port and the label
+ for SR2 should be removed.
+ """
+ def runTest( self ):
+ Groups = Queue.LifoQueue( )
+ try:
+ if len( config[ "port_map" ] ) < 1:
+ logging.info( "Port count less than 1, can't run this case" )
+ assert (False)
+ return
+ ports = config[ "port_map" ].keys( )
+ in_port = ports[0]
+ out_port = ports[1]
+ out_vlan = 4094
+ src_mac = [ 0x00, 0x00, 0x00, 0x00, 0x11, 0x01 ]
+ src_mac_str = ':'.join( [ '%02X' % x for x in src_mac ] )
+ dst_mac = [ 0x00, 0x00, 0x00, 0x11, 0x11, 0x01 ]
+ dst_mac_str = ':'.join( [ '%02X' % x for x in dst_mac ] )
+ mpls_label = 100
+ mpls_label_SR1 = 100 + 5
+ mpls_label_SR2 = 100 + 10
+ mpls_label_PW = 100 + 15
+
+ # Add l2 interface group, we have to pop the VLAN;
+ l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
+ ctrl=self.controller,
+ port=out_port,
+ vlan_id=out_vlan,
+ is_tagged=False,
+ send_barrier=False
+ )
+ Groups._put( l2_intf_gid )
+
+ # add MPLS interface group
+ mpls_intf_gid, mpls_intf_msg = add_mpls_intf_group(
+ ctrl=self.controller,
+ ref_gid=l2_intf_gid,
+ dst_mac=dst_mac,
+ src_mac=src_mac,
+ vid=out_vlan,
+ index=in_port
+ )
+ Groups._put( mpls_intf_gid )
+
+ # Add L3 Unicast group
+ l3_msg = add_l3_unicast_group(
+ ctrl=self.controller,
+ port=out_port,
+ vlanid=out_vlan,
+ id=in_port,
+ src_mac=src_mac,
+ dst_mac=dst_mac
+ )
+ Groups._put( l3_msg.group_id )
+
+ # Add L3 ecmp group
+ ecmp_msg = add_l3_ecmp_group(
+ ctrl=self.controller,
+ id=in_port,
+ l3_ucast_groups=[ l3_msg.group_id ]
+ )
+ Groups._put( ecmp_msg.group_id )
+
+ # Add MPLS flow with BoS=1
+ add_mpls_flow(
+ ctrl=self.controller,
+ action_group_id=ecmp_msg.group_id,
+ label=mpls_label_SR1
+ )
+
+ # add MPLS flow with BoS=0
+ add_mpls_flow_pw(
+ ctrl=self.controller,
+ action_group_id=mpls_intf_gid,
+ label=mpls_label_SR2,
+ ethertype=0x8847,
+ tunnel_index=1,
+ bos=0
+ )
+
+ # add Termination flow
+ add_termination_flow(
+ ctrl=self.controller,
+ in_port=in_port,
+ eth_type=0x8847,
+ dst_mac=src_mac,
+ vlanid=out_vlan,
+ goto_table=23
+ )
+ # add VLAN flows
+ add_one_vlan_table_flow(
+ ctrl=self.controller,
+ of_port=in_port,
+ vlan_id=out_vlan,
+ flag=VLAN_TABLE_FLAG_ONLY_TAG,
+ )
+ add_one_vlan_table_flow(
+ ctrl=self.controller,
+ of_port=in_port,
+ vlan_id=out_vlan,
+ flag=VLAN_TABLE_FLAG_ONLY_UNTAG
+ )
+ # Packet generation with sleep
+ time.sleep(2)
+ label_SR1 = (mpls_label_SR1, 0, 1, 32)
+ label_SR2 = (mpls_label_SR2, 0, 0, 32)
+ label_2 = (mpls_label_PW, 0, 1, 32)
+
+ # set to false to test if routing traffic
+ # comes through
+
+ pw = True
+ if pw:
+ parsed_pkt = mpls_packet(
+ pktlen=104,
+ ip_ttl=63,
+ eth_dst=src_mac_str,
+ label=[label_SR2, label_2],
+ encapsulated_ethernet = True
+ )
+ pkt = str( parsed_pkt )
+ self.dataplane.send( in_port, pkt )
+
+
+ expected_label = (mpls_label_PW, 0, 1, 31)
+ # we geneate the expected pw packet
+ parsed_pkt = mpls_packet(
+ pktlen=100,
+ ip_ttl=63,
+ eth_dst=dst_mac_str,
+ eth_src=src_mac_str,
+ label=[ expected_label ],
+ encapsulated_ethernet = True
+ )
+
+ pkt = str( parsed_pkt )
+ verify_packet( self, pkt, out_port )
+ verify_no_packet( self, pkt, in_port )
+ else:
+ # packet for routing traffic
+ parsed_pkt_2 = mpls_packet(
+ pktlen=104,
+ ip_ttl=63,
+ eth_dst=src_mac_str,
+ label=[ label_SR1 ]
+ )
+ pkt_2 = str(parsed_pkt_2)
+ self.dataplane.send( in_port, pkt_2 )
+
+ # we geneate the expected routed packet
+ parsed_pkt_2 = simple_tcp_packet(
+ pktlen=100,
+ ip_ttl=31,
+ eth_dst=dst_mac_str,
+ eth_src=src_mac_str,
+ )
+ pkt_2 = str(parsed_pkt_2)
+
+ verify_packet( self, pkt_2, out_port)
+ verify_no_packet( self, pkt_2, in_port )
+
+ verify_no_other_packets( self )
+ finally:
+
+ delete_all_flows( self.controller )
+ delete_groups( self.controller, Groups )
+ delete_all_groups( self.controller )
+
+class PseudowireSpineTerminationBug( base_tests.SimpleDataPlane ):
+ """
+ This is meant to demonstrate a bug observed in the termination of
+ Leaf-Spine pseudowires, where the termination point at the spine
+ is a port connecting to another leaf switch.
+ In this case, there exist two L2 interface groups in the device for the
+ same port :
+
+ L2 interface for routing : POP_VLAN, output to port
+ L2 interface for pseudowire : outpute to port
+
+ The choice of the l2 interface group is associated with the vlan id of the packet.
+ In both cases, packets arrive with untagged vlan and are associated with vlan-id 4094.
+ However, in pw case the outer l2 is popped, and the vlan-id changes (that of the original
+ traffic) which matches the L2 interface group for the pw.
+
+ The bug is that still the group that is chossen is that for routing, which pops the vlan,
+ and thus the pseudowire results with untagged traffic.
+ """
+ def runTest( self ):
+
+ Groups = Queue.LifoQueue( )
+ Groups2 = Queue.LifoQueue( )
+ try:
+ if len( config[ "port_map" ] ) < 1:
+ logging.info( "Port count less than 1, can't run this case" )
+ assert (False)
+ return
+ ports = config[ "port_map" ].keys( )
+ for pair in itertools.product(ports, ports):
+ # we generate all possible products
+ in_port = pair[0]
+ out_port = pair[1]
+ if out_port == in_port:
+ continue
+ # we fill the pipeline for the pw initiation
+ # on the reverse path
+ (
+ port_to_mpls_label_2,
+ port_to_mpls_label_1,
+ port_to_mpls_label_pw,
+ port_to_in_vlan_3,
+ port_to_in_vlan_2,
+ port_to_in_vlan_1,
+ port_to_src_mac_str,
+ port_to_dst_mac_str,
+ Groups ) = fill_pw_initiation_pipeline(
+ controller=self.controller,
+ logging=logging,
+ in_port=out_port,
+ out_port=in_port,
+ ingress_tags=1,
+ egress_tag=EGRESS_TAGGED,
+ mpls_labels=1
+ )
+ # we fill the pipeline for the pw termination
+ (
+ port_to_mpls_label_pw,
+ port_to_in_vlan_2,
+ port_to_in_vlan_1,
+ port_to_dst_mac_str,
+ Groups2 ) = fill_pw_termination_pipeline(
+ controller=self.controller,
+ logging=logging,
+ in_port=in_port,
+ out_port=out_port,
+ egress_tags=1
+ )
+
+ print('''\nBefore adding the l2 interface group that pops the vlan we expect to see tagged packets at the output. ''')
+
+ # we generate the pw packet
+ label_pw = (port_to_mpls_label_pw[out_port], 0, 1, 63)
+ cw = (0, 0, 0, 0)
+ parsed_pkt = pw_packet(
+ pktlen=104,
+ out_eth_dst=port_to_dst_mac_str[in_port],
+ label=[label_pw],
+ cw=cw,
+ out_dl_vlan_enable=True,
+ out_vlan_vid=port_to_in_vlan_1[out_port],
+ )
+ pkt = str( parsed_pkt )
+ self.dataplane.send( in_port, pkt )
+ # we generate the expected tcp packet
+ # with a vlan tag
+ parsed_pkt = simple_tcp_packet(
+ pktlen=82,
+ dl_vlan_enable=True,
+ vlan_vid=port_to_in_vlan_1[out_port]
+ )
+ pkt = str( parsed_pkt )
+
+ # Assertions
+ verify_packet( self, pkt, out_port )
+ verify_no_packet( self, pkt, in_port )
+ verify_no_other_packets( self )
+
+ print('''After adding the l2 interface group that pops the vlan, packets will come out UNTAGGED and test will fail. Check logs for details.''')
+ # we create an l2 interface group for routing that
+ # pops the vlan tags
+ l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
+ ctrl=self.controller,
+ port=out_port,
+ vlan_id=4094,
+ is_tagged=False,
+ send_barrier=False
+ )
+ Groups._put( l2_intf_gid )
+
+ parsed_pkt = pw_packet(
+ pktlen=104,
+ out_eth_dst=port_to_dst_mac_str[in_port],
+ label=[label_pw],
+ cw=cw,
+ out_dl_vlan_enable=True,
+ out_vlan_vid=port_to_in_vlan_1[out_port],
+ )
+ pkt = str( parsed_pkt )
+ self.dataplane.send( in_port, pkt )
+
+ parsed_pkt = simple_tcp_packet(
+ pktlen=82,
+ dl_vlan_enable=True,
+ vlan_vid=port_to_in_vlan_1[out_port]
+ )
+ pkt = str( parsed_pkt )
+
+ # send the packet, test should fail now
+ verify_packet( self, pkt, out_port )
+ verify_no_packet( self, pkt, in_port )
+ verify_no_other_packets( self )
+
+ delete_all_flows( self.controller )
+ delete_groups( self.controller, Groups )
+ delete_groups( self.controller, Groups2 )
+ delete_all_groups( self.controller )
+ finally:
+ delete_all_flows( self.controller )
+ delete_groups( self.controller, Groups )
+ delete_groups( self.controller, Groups2 )
+ delete_all_groups( self.controller )
+
+
class BoSBug( base_tests.SimpleDataPlane ):
"""
This test is meant to verify the forwarding of the default traffic
@@ -1819,13 +2145,13 @@
)
# Packet generation with sleep
time.sleep(2)
- label = (mpls_label, 0, 1, 32)
+ label = (mpls_label, 0, 0, 32)
parsed_pkt = mpls_packet(
pktlen=104,
vlan_vid=out_vlan,
ip_ttl=63,
eth_dst=src_mac_str,
- label=[ label]
+ label=[ label ]
)
pkt = str( parsed_pkt )
self.dataplane.send( in_port, pkt )
@@ -1843,6 +2169,17 @@
verify_no_packet( self, pkt, in_port )
verify_no_other_packets( self )
finally:
- delete_all_flows( self.controller )
- delete_groups( self.controller, Groups )
- delete_all_groups( self.controller )
\ No newline at end of file
+ print("SHOULD CLEAR STATE HERE")
+ # delete_all_flows( self.controller )
+ # delete_groups( self.controller, Groups )
+ # delete_all_groups( self.controller )
+
+class ClearAll( base_tests.SimpleDataPlane ):
+
+ def runTest( self ):
+ delete_all_flows( self.controller )
+ delete_all_groups( self.controller )
+
+
+
+