Add PW initiation pipeline
Changes:
- Adds a reusable utility function to test all scenarios;
- Updates the missing code related to the extensions;
- Adds the missing utility functions to fill the single tables;
- Fix function to pack experimenter fields
Change-Id: Ic36fd4279fad18e22756fa307b154c9ce7ed483f
diff --git a/ofdpa/flows.py b/ofdpa/flows.py
index 675b284..fa4decd 100755
--- a/ofdpa/flows.py
+++ b/ofdpa/flows.py
@@ -1924,4 +1924,3 @@
delete_all_flows( self.controller )
delete_groups( self.controller, groups )
delete_all_groups( self.controller )
-
diff --git a/ofdpa/utils.py b/ofdpa/utils.py
index 7fd78a0..0a41645 100644
--- a/ofdpa/utils.py
+++ b/ofdpa/utils.py
@@ -1,8 +1,79 @@
import Queue
+import itertools
from oftest.testutils import *
from accton_util import *
+"""
+MISC
+"""
+
+def print_port_stats(test, port):
+ entries = get_port_stats(test, port)
+ for item in entries:
+ packet_rcv = item.rx_packets
+ packet_rcv_dropped = item.rx_dropped
+ packet_rcv_errors = item.rx_errors
+
+ packet_sent = item.tx_packets
+ packet_sent_dropped = item.tx_dropped
+ packet_sent_errors = item.tx_errors
+
+ print "Port %d stats count: tx %d rx %d - tx_dropped %d rx_dropped %d - tx_errors %d rx_errors %d" % (
+ port, packet_sent, packet_rcv, packet_sent_dropped, packet_rcv_dropped, packet_sent_errors, packet_rcv_errors
+ )
+
+def filter_dhcp(controller):
+ match = ofp.match( )
+ match.oxm_list.append( ofp.oxm.eth_type( 0x0800 ) )
+ match.oxm_list.append( ofp.oxm.ip_proto( 17 ) )
+ match.oxm_list.append( ofp.oxm.udp_src( 68 ) )
+ match.oxm_list.append( ofp.oxm.udp_dst( 67 ))
+ request = ofp.message.flow_add(
+ table_id=60,
+ cookie=42,
+ match=match,
+ instructions=[ofp.instruction.clear_actions( )],
+ buffer_id=ofp.OFP_NO_BUFFER,
+ priority=1
+ )
+ controller.message_send( request )
+ do_barrier( controller )
+
+def filter_ipv6(controller):
+ match = ofp.match( )
+ match.oxm_list.append( ofp.oxm.eth_type( 0x86dd ) )
+ request = ofp.message.flow_add(
+ table_id=60,
+ cookie=42,
+ match=match,
+ instructions=[ofp.instruction.clear_actions( )],
+ buffer_id=ofp.OFP_NO_BUFFER,
+ priority=1
+ )
+ controller.message_send( request )
+ do_barrier( controller )
+
+def filter_igmp(controller):
+ match = ofp.match( )
+ match.oxm_list.append( ofp.oxm.eth_type( 0x0800 ) )
+ match.oxm_list.append( ofp.oxm.ip_proto( 2 ) )
+ request = ofp.message.flow_add(
+ table_id=60,
+ cookie=42,
+ match=match,
+ instructions=[ofp.instruction.clear_actions( )],
+ buffer_id=ofp.OFP_NO_BUFFER,
+ priority=1
+ )
+ controller.message_send( request )
+ do_barrier( controller )
+
+
+"""
+MULTICAST Pipelines
+"""
+
def fill_mcast_pipeline_L3toL2(
controller,
logging,
@@ -219,4 +290,221 @@
port_to_src_ip_str,
port_to_intf_src_mac_str,
Groups
- )
\ No newline at end of file
+ )
+
+"""
+VPWS Pipeline
+"""
+
+OF_DPA_MPLS_L2_VPN_Label = 1
+OF_DPA_MPLS_Tunnel_Label_1 = 3
+OF_DPA_MPLS_Tunnel_Label_2 = 4
+
+EGRESS_UNTAGGED = 1
+EGRESS_TAGGED = 2
+EGRESS_TAGGED_TRANS = 3
+
+
+def fill_pw_initiation_pipeline(
+ controller,
+ logging,
+ in_port,
+ out_port,
+ ingress_tags,
+ egress_tag,
+ mpls_labels
+ ):
+ """
+ This method, according to the scenario, fills properly
+ the pw pipeline. The method generates using ports data the
+ necessary information to fill the pw pipeline and
+ fills properly the pipeline which consists into:
+
+ """
+
+ Groups = Queue.LifoQueue( )
+ out_vlan = 4094
+ port_to_in_vlan_1 = {}
+ port_to_in_vlan_2 = {}
+ port_to_in_vlan_3 = {}
+ port_to_src_mac = {}
+ port_to_src_mac_str = {}
+ port_to_dst_mac = {}
+ port_to_dst_mac_str = {}
+ mpls_labels_to_port = []
+ port_to_mpls_label_1 = {}
+ port_to_mpls_label_2 = {}
+ port_to_mpls_label_pw = {}
+ ports = [in_port, out_port]
+
+ for port in ports:
+ in_vlan_id_1 = port + 1
+ in_vlan_id_2 = port + 100
+ in_vlan_id_3 = port + 300
+ mpls_label_1 = port + 100
+ mpls_label_2 = port + 200
+ mpls_label_pw = port + 300
+ port_to_in_vlan_1[port] = in_vlan_id_1
+ port_to_in_vlan_2[port] = in_vlan_id_2
+ port_to_in_vlan_3[port] = in_vlan_id_3
+ src_mac = [ 0x00, 0x00, 0x00, 0x00, 0x11, port ]
+ src_mac_str = ':'.join( [ '%02X' % x for x in src_mac ] )
+ dst_mac = [ 0x00, 0x00, 0x00, 0x11, 0x11, port ]
+ dst_mac_str = ':'.join( [ '%02X' % x for x in dst_mac ] )
+ port_to_src_mac[port] = src_mac
+ port_to_src_mac_str[port] = src_mac_str
+ port_to_dst_mac[port] = dst_mac
+ port_to_dst_mac_str[port] = dst_mac_str
+ port_to_mpls_label_1[port] = mpls_label_1
+ port_to_mpls_label_2[port] = mpls_label_2
+ port_to_mpls_label_pw[port] = mpls_label_pw
+
+ # add l2 interface group, we have to pop the VLAN;
+ l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
+ ctrl=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=controller,
+ ref_gid=l2_intf_gid,
+ dst_mac=port_to_dst_mac[in_port],
+ src_mac=port_to_src_mac[out_port],
+ vid=out_vlan,
+ index=in_port
+ )
+ Groups._put( mpls_intf_gid )
+ mpls_gid = mpls_intf_gid
+ # add MPLS tunnel label groups, the number depends on the labels
+ if mpls_labels == 2:
+ mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
+ ctrl=controller,
+ ref_gid=mpls_intf_gid,
+ subtype=OF_DPA_MPLS_Tunnel_Label_2,
+ index=in_port,
+ label=port_to_mpls_label_2[in_port]
+ )
+ Groups._put( mpls_tunnel_gid )
+ mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
+ ctrl=controller,
+ ref_gid=mpls_tunnel_gid,
+ subtype=OF_DPA_MPLS_Tunnel_Label_1,
+ index=in_port,
+ label=port_to_mpls_label_1[in_port]
+ )
+ Groups._put( mpls_tunnel_gid )
+ mpls_gid = mpls_tunnel_gid
+ elif mpls_labels == 1:
+ mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
+ ctrl=controller,
+ ref_gid=mpls_intf_gid,
+ subtype=OF_DPA_MPLS_Tunnel_Label_1,
+ index=in_port,
+ label=port_to_mpls_label_1[in_port]
+ )
+ Groups._put( mpls_tunnel_gid )
+ mpls_gid = mpls_tunnel_gid
+
+ # add MPLS L2 VPN group
+ mpls_l2_vpn_gid, mpls_l2_vpn_msg = add_mpls_label_group(
+ ctrl=controller,
+ subtype=OF_DPA_MPLS_L2_VPN_Label,
+ index=in_port,
+ ref_gid=mpls_gid,
+ push_l2_header=True,
+ push_vlan=True,
+ push_mpls_header=True,
+ push_cw=True,
+ set_mpls_label=port_to_mpls_label_pw[in_port],
+ set_bos=1,
+ cpy_ttl_outward=True
+ )
+
+ Groups._put( mpls_l2_vpn_gid )
+ # add MPLS L2 port flow
+ add_mpls_l2_port_flow(
+ ctrl=controller,
+ of_port=in_port,
+ mpls_l2_port=in_port,
+ tunnel_index=1,
+ ref_gid=mpls_l2_vpn_gid
+ )
+ # add VLAN flows table
+ if ingress_tags == 2:
+ if egress_tag == EGRESS_TAGGED:
+ add_one_vlan_1_table_flow_pw(
+ ctrl=controller,
+ of_port=in_port,
+ tunnel_index=1,
+ new_outer_vlan_id=-1,
+ outer_vlan_id=port_to_in_vlan_2[in_port],
+ inner_vlan_id=port_to_in_vlan_1[in_port],
+ )
+ elif egress_tag == EGRESS_TAGGED_TRANS:
+ add_one_vlan_1_table_flow_pw(
+ ctrl=controller,
+ of_port=in_port,
+ tunnel_index=1,
+ new_outer_vlan_id=port_to_in_vlan_3[in_port],
+ outer_vlan_id=port_to_in_vlan_2[in_port],
+ inner_vlan_id=port_to_in_vlan_1[in_port],
+ )
+ add_one_vlan_table_flow(
+ ctrl=controller,
+ of_port=in_port,
+ vlan_id=port_to_in_vlan_2[in_port],
+ flag=VLAN_TABLE_FLAG_ONLY_STACKED,
+ )
+ elif ingress_tags == 1:
+ if egress_tag == EGRESS_TAGGED:
+ add_one_vlan_table_flow_pw(
+ ctrl=controller,
+ of_port=in_port,
+ tunnel_index=1,
+ vlan_id=port_to_in_vlan_1[in_port],
+ flag=VLAN_TABLE_FLAG_ONLY_TAG,
+ )
+ elif egress_tag == EGRESS_TAGGED_TRANS:
+ add_one_vlan_table_flow_pw(
+ ctrl=controller,
+ of_port=in_port,
+ tunnel_index=1,
+ vlan_id=port_to_in_vlan_1[in_port],
+ new_vlan_id=port_to_in_vlan_3[in_port],
+ flag=VLAN_TABLE_FLAG_ONLY_TAG,
+ )
+ elif ingress_tags == 0:
+ filter_dhcp(controller)
+ filter_ipv6(controller)
+ filter_igmp(controller)
+ if egress_tag == EGRESS_UNTAGGED:
+ add_one_vlan_table_flow_pw(
+ ctrl=controller,
+ of_port=in_port,
+ tunnel_index=1,
+ flag=VLAN_TABLE_FLAG_ONLY_UNTAG,
+ )
+ elif egress_tag == EGRESS_TAGGED:
+ add_one_vlan_table_flow_pw(
+ ctrl=controller,
+ of_port=in_port,
+ tunnel_index=1,
+ vlan_id=port_to_in_vlan_1[in_port],
+ flag=VLAN_TABLE_FLAG_ONLY_UNTAG,
+ )
+
+ return (
+ 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
+ )