Initial set of Fabric switch test cases
Change-Id: I86fd2b67d3b773aa496f5ef61f1e1fdf51fd9925
diff --git a/Fabric/Utilities/src/python/oftest/utils.py b/Fabric/Utilities/src/python/oftest/utils.py
new file mode 100644
index 0000000..ebc168d
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/utils.py
@@ -0,0 +1,779 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+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 "\nPort %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,
+ ports,
+ is_ingress_tagged,
+ is_egress_tagged,
+ is_vlan_translated,
+ is_max_vlan
+ ):
+ """
+ This method, according to the scenario, fills properly
+ the pipeline. The method generates using ports data the
+ necessary information to fill the multicast pipeline and
+ fills properly the pipeline which consists in this scenario:
+
+ i) to create l2 interface groups;
+ ii) to create l3 multicast groups;
+ iii) to add multicast flows;
+ iv) to add termination; flows;
+ v) to add vlan flows
+
+ Scenarios:
+ 1) ingress untagged, egress untagged
+ 2) ingress untagged, egress tagged
+ 3) ingress tagged, egress untagged
+ 4) ingress tagged, egress tagged, no translation
+ 5) ingress tagged, egress tagged, translation
+ """
+
+ MAX_INTERNAL_VLAN = 4094
+ # Used for no translation
+ FIXED_VLAN = 300
+ Groups = Queue.LifoQueue( )
+ L2_Groups = []
+ port_to_in_vlan = {}
+ port_to_out_vlan = {}
+ port_to_src_mac = {}
+ port_to_src_mac_str = {}
+ port_to_dst_mac = {}
+ port_to_dst_mac_str = {}
+ port_to_src_ip = {}
+ port_to_src_ip_str = {}
+ src_ip_0 = 0xc0a80100
+ src_ip_0_str = "192.168.1.%s"
+ dst_ip = 0xe0000001
+ switch_mac = [ 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 ]
+
+ for port in ports:
+ in_vlan_id = port + 1
+ out_vlan_id = MAX_INTERNAL_VLAN - port
+ if is_max_vlan and not is_vlan_translated:
+ in_vlan_id = MAX_INTERNAL_VLAN
+ out_vlan_id = MAX_INTERNAL_VLAN
+ elif not is_max_vlan and not is_vlan_translated:
+ in_vlan_id = FIXED_VLAN
+ out_vlan_id = FIXED_VLAN
+ src_mac = [ 0x00, 0x11, 0x11, 0x11, 0x11, port ]
+ src_mac_str = ':'.join( [ '%02X' % x for x in src_mac ] )
+ dst_mac = [ 0x01, 0x00, 0x5e, 0x01, 0x01, port ]
+ dst_mac_str = ':'.join( [ '%02X' % x for x in dst_mac ] )
+ src_ip = src_ip_0 + port
+ src_ip_str = src_ip_0_str % port
+ port_to_in_vlan[port] = in_vlan_id
+ port_to_out_vlan[port] = out_vlan_id
+ 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_src_ip[port] = src_ip
+ port_to_src_ip_str[port] = src_ip_str
+
+ for in_port in ports:
+
+ L2_Groups = []
+ # add vlan flows table
+ add_one_vlan_table_flow( controller, in_port, 1, port_to_in_vlan[in_port], flag=VLAN_TABLE_FLAG_ONLY_TAG )
+ if not is_ingress_tagged:
+ add_one_vlan_table_flow( controller, in_port, 1, port_to_in_vlan[in_port], flag=VLAN_TABLE_FLAG_ONLY_UNTAG )
+ elif is_vlan_translated:
+ add_one_vlan_table_flow_translation( controller, in_port, port_to_in_vlan[in_port], port_to_out_vlan[in_port], flag=VLAN_TABLE_FLAG_ONLY_TAG)
+ # add termination flow
+ if not is_vlan_translated:
+ add_termination_flow( controller, in_port, 0x0800, switch_mac, port_to_in_vlan[in_port] )
+ else:
+ add_termination_flow( controller, in_port, 0x0800, switch_mac, port_to_out_vlan[in_port] )
+
+ for out_port in ports:
+ if out_port == in_port:
+ continue
+ # add l2 interface group, vlan_id equals for each port and must coincide with mcast_group vlan_id
+ if not is_vlan_translated:
+ l2gid, msg = add_one_l2_interface_group( controller, out_port, vlan_id=port_to_in_vlan[in_port],
+ is_tagged=is_egress_tagged, send_barrier=True )
+ else:
+ l2gid, msg = add_one_l2_interface_group( controller, out_port, vlan_id=port_to_out_vlan[in_port],
+ is_tagged=is_egress_tagged, send_barrier=True )
+ Groups._put( l2gid )
+ L2_Groups.append( l2gid )
+
+ # add l3 mcast group
+ if not is_vlan_translated:
+ mcat_group_msg = add_l3_mcast_group( controller, port_to_in_vlan[in_port], in_port, L2_Groups )
+ else:
+ mcat_group_msg = add_l3_mcast_group( controller, port_to_out_vlan[in_port], in_port, L2_Groups )
+ Groups._put( mcat_group_msg.group_id )
+ # add mcast routing flow
+ if not is_vlan_translated:
+ add_mcast4_routing_flow( controller, port_to_in_vlan[in_port], port_to_src_ip[in_port], 0, dst_ip, mcat_group_msg.group_id )
+ else:
+ add_mcast4_routing_flow( controller, port_to_out_vlan[in_port], port_to_src_ip[in_port], 0, dst_ip, mcat_group_msg.group_id )
+
+ return (
+ port_to_in_vlan,
+ port_to_out_vlan,
+ port_to_src_mac_str,
+ port_to_dst_mac_str,
+ port_to_src_ip,
+ port_to_src_ip_str,
+ Groups
+ )
+
+def fill_mcast_pipeline_L3toL3(
+ controller,
+ logging,
+ ports,
+ is_ingress_tagged,
+ is_egress_tagged,
+ is_vlan_translated,
+ is_max_vlan
+ ):
+ """
+ This method, according to the scenario, fills properly
+ the pipeline. The method generates using ports data the
+ necessary information to fill the multicast pipeline and
+ fills properly the pipeline which consists in this scenario:
+
+ i) to create l2 interface groups;
+ ii)to create l3 interface groups;
+ iii) to create l3 multicast groups;
+ iv) to add multicast flows;
+ v) to add termination; flows;
+ vi) to add vlan flows
+
+ Scenarios:
+ 1) ingress tagged, egress tagged, translation
+ """
+
+ Groups = Queue.LifoQueue( )
+ MAX_INTERNAL_VLAN = 4094
+ port_to_in_vlan = {}
+ port_to_out_vlan = {}
+ port_to_src_mac = {}
+ port_to_src_mac_str = {}
+ port_to_dst_mac = {}
+ port_to_dst_mac_str = {}
+ port_to_src_ip = {}
+ port_to_src_ip_str = {}
+ port_to_intf_src_mac = {}
+ port_to_intf_src_mac_str = {}
+ src_ip_0 = 0xc0a80100
+ src_ip_0_str = "192.168.1.%s"
+ dst_ip = 0xe0000001
+ switch_mac = [ 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 ]
+
+ for port in ports:
+ in_vlan_id = port + 1
+ out_vlan_id = MAX_INTERNAL_VLAN - port
+ src_mac = [ 0x00, 0x11, 0x11, 0x11, 0x11, port ]
+ src_mac_str = ':'.join( [ '%02X' % x for x in src_mac ] )
+ dst_mac = [ 0x01, 0x00, 0x5e, 0x01, 0x01, port ]
+ dst_mac_str = ':'.join( [ '%02X' % x for x in dst_mac ] )
+ src_ip = src_ip_0 + port
+ src_ip_str = src_ip_0_str % port
+ intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, port ]
+ intf_src_mac_str = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+ port_to_in_vlan[port] = in_vlan_id
+ port_to_out_vlan[port] = out_vlan_id
+ 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_src_ip[port] = src_ip
+ port_to_src_ip_str[port] = src_ip_str
+ port_to_intf_src_mac[port] = intf_src_mac
+ port_to_intf_src_mac_str[port] = intf_src_mac_str
+
+ for port in ports:
+ L3_Groups = []
+ for other_port in ports:
+ # add l2 interface group
+ l2gid, msg = add_one_l2_interface_group( controller, other_port, vlan_id=port_to_out_vlan[other_port],
+ is_tagged=True, send_barrier=True )
+ Groups._put( l2gid )
+ # add l3 interface group
+ l3group_ucast_msg = add_l3_interface_group( controller, other_port, port_to_out_vlan[other_port], port_to_in_vlan[other_port],
+ port_to_intf_src_mac[other_port] )
+ L3_Groups.append(l3group_ucast_msg.group_id)
+ Groups._put( l3group_ucast_msg.group_id )
+
+ # add mcast group
+ mcat_group_msg = add_l3_mcast_group( controller, port_to_in_vlan[port], port_to_in_vlan[port], L3_Groups )
+ do_barrier(controller)
+ Groups._put( mcat_group_msg.group_id )
+ # add mcast flow
+ add_mcast4_routing_flow( controller, port_to_in_vlan[port], port_to_src_ip[port], 0, dst_ip, mcat_group_msg.group_id, True )
+ # add termination flow
+ add_termination_flow( controller, port, 0x0800, switch_mac, port_to_in_vlan[port] )
+ # add vlan flow table
+ add_one_vlan_table_flow( controller, port, 1, port_to_in_vlan[port], flag=VLAN_TABLE_FLAG_ONLY_TAG )
+
+ return (
+ port_to_in_vlan,
+ port_to_out_vlan,
+ port_to_src_mac_str,
+ port_to_dst_mac_str,
+ port_to_src_ip,
+ port_to_src_ip_str,
+ port_to_intf_src_mac_str,
+ Groups
+ )
+
+"""
+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 = {}
+ 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
+ )
+
+MPLS_FLOW_TABLE_0 = 23
+OF_DPA_MPLS_SWAP_Label = 5
+
+def fill_pw_intermediate_transport_pipeline(
+ controller,
+ logging,
+ ports,
+ 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_src_mac = {}
+ port_to_src_mac_str = {}
+ port_to_dst_mac = {}
+ port_to_dst_mac_str = {}
+ port_to_mpls_label_2 = {}
+ port_to_mpls_label_1 = {}
+ port_to_mpls_label_pw = {}
+ port_to_switch_mac = {}
+ port_to_switch_mac_str = {}
+
+ for port in ports:
+ mpls_label_1 = port + 10
+ mpls_label_2 = port + 100
+ mpls_label_pw = port + 300
+ 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 ] )
+ switch_mac = [ 0x00, 0x00, 0x00, 0x00, 0x00, port ]
+ switch_mac_str = ':'.join( [ '%02X' % x for x in switch_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
+ port_to_switch_mac[port] = switch_mac
+ port_to_switch_mac_str[port] = switch_mac_str
+
+ for pair in itertools.product(ports, ports):
+ in_port = pair[0]
+ out_port = pair[1]
+ if out_port == in_port:
+ continue
+ # 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 )
+ # add MPLS flows
+ if mpls_labels >=2:
+ add_mpls_flow_pw(
+ ctrl=controller,
+ action_group_id=mpls_intf_gid,
+ label=port_to_mpls_label_2[in_port],
+ ethertype=0x8847,
+ tunnel_index=1,
+ bos=0
+ )
+ else:
+ 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_swap_gid, mpls_tunnel_msg = add_mpls_swap_label_group(
+ ctrl=controller,
+ ref_gid=mpls_tunnel_gid,
+ subtype=OF_DPA_MPLS_SWAP_Label,
+ index=in_port,
+ label=port_to_mpls_label_pw[in_port]
+ )
+ Groups._put( mpls_swap_gid )
+ add_mpls_flow_pw(
+ ctrl=controller,
+ action_group_id=mpls_swap_gid,
+ label=port_to_mpls_label_pw[in_port],
+ ethertype=0x8847,
+ tunnel_index=1,
+ bos=1,
+ popMPLS=False,
+ popL2=False
+ )
+ # add Termination flow
+ add_termination_flow(
+ ctrl=controller,
+ in_port=in_port,
+ eth_type=0x8847,
+ dst_mac=port_to_switch_mac[in_port],
+ vlanid=out_vlan,
+ goto_table=MPLS_FLOW_TABLE_0)
+ # add VLAN flows
+ add_one_vlan_table_flow(
+ ctrl=controller,
+ of_port=in_port,
+ vlan_id=out_vlan,
+ flag=VLAN_TABLE_FLAG_ONLY_TAG,
+ )
+ add_one_vlan_table_flow(
+ ctrl=controller,
+ of_port=in_port,
+ vlan_id=out_vlan,
+ flag=VLAN_TABLE_FLAG_ONLY_UNTAG
+ )
+
+ return (
+ port_to_mpls_label_2,
+ port_to_mpls_label_1,
+ port_to_mpls_label_pw,
+ port_to_switch_mac_str,
+ port_to_src_mac_str,
+ port_to_dst_mac_str,
+ Groups
+ )
+
+def fill_pw_termination_pipeline(
+ controller,
+ logging,
+ in_port,
+ out_port,
+ egress_tags
+ ):
+ """
+ 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_mpls_label_pw = {}
+ port_to_vlan_2 = {}
+ port_to_vlan_1 = {}
+ port_to_switch_mac = {}
+ port_to_switch_mac_str = {}
+ ports = [in_port, out_port]
+
+ for port in ports:
+ mpls_label_pw = port + 300
+ in_vlan_id_1 = port + 1
+ in_vlan_id_2 = port + 100
+ switch_mac = [ 0x00, 0x00, 0x00, 0x00, 0x11, port ]
+ switch_mac_str = ':'.join( [ '%02X' % x for x in switch_mac ] )
+ port_to_mpls_label_pw[port] = mpls_label_pw
+ port_to_vlan_2[port] = in_vlan_id_2
+ port_to_vlan_1[port] = in_vlan_id_1
+ port_to_switch_mac[port] = switch_mac
+ port_to_switch_mac_str[port] = switch_mac_str
+
+ # add l2 interface group;
+ if egress_tags == 2:
+ l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
+ ctrl=controller,
+ port=out_port,
+ vlan_id=port_to_vlan_2[out_port],
+ is_tagged=True,
+ send_barrier=False
+ )
+ elif egress_tags == 1:
+ l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
+ ctrl=controller,
+ port=out_port,
+ vlan_id=port_to_vlan_1[out_port],
+ is_tagged=True,
+ send_barrier=False
+ )
+ elif egress_tags == 0:
+ l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
+ ctrl=controller,
+ port=out_port,
+ vlan_id=port_to_vlan_1[out_port],
+ is_tagged=False,
+ send_barrier=False
+ )
+
+ Groups._put( l2_intf_gid )
+ add_mpls_flow_pw(
+ ctrl=controller,
+ action_group_id=l2_intf_gid,
+ label=port_to_mpls_label_pw[out_port],
+ ethertype=0x6558,
+ bos=1,
+ tunnel_index=1,
+ popMPLS=True,
+ popL2=True,
+ of_port=in_port
+ )
+ # add Termination flow
+ add_termination_flow(
+ ctrl=controller,
+ in_port=in_port,
+ eth_type=0x8847,
+ dst_mac=port_to_switch_mac[in_port],
+ vlanid=out_vlan,
+ goto_table=MPLS_FLOW_TABLE_0)
+ # add VLAN flows
+ add_one_vlan_table_flow(
+ ctrl=controller,
+ of_port=in_port,
+ vlan_id=out_vlan,
+ flag=VLAN_TABLE_FLAG_ONLY_TAG,
+ )
+ add_one_vlan_table_flow(
+ ctrl=controller,
+ of_port=in_port,
+ vlan_id=out_vlan,
+ flag=VLAN_TABLE_FLAG_ONLY_UNTAG
+ )
+
+ return (
+ port_to_mpls_label_pw,
+ port_to_vlan_2,
+ port_to_vlan_1,
+ port_to_switch_mac_str,
+ Groups
+ )