Termination support
Changes:
- Adds a procedure to fill the pipeline in different use cases;
- Adds a new utility function to fill the MPLS flow tables;
Change-Id: I1f4fa377681fc2a4b4aa106746de6bd8e1717860
diff --git a/accton/accton_util.py b/accton/accton_util.py
index 75a1df5..15e6e99 100755
--- a/accton/accton_util.py
+++ b/accton/accton_util.py
@@ -164,6 +164,26 @@
return group_id_list, msgs
+def add_one_l2_unfiltered_group(ctrl, of_port, send_barrier=False):
+ # group table
+ # set up untag groups for each port
+ group_id = encode_l2_unfiltered_group_id(of_port)
+ actions = [ofp.action.output(of_port)]
+ actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=1)))
+
+ buckets = [ofp.bucket(actions=actions)]
+ request = ofp.message.group_add(
+ group_type=ofp.OFPGT_INDIRECT,
+ group_id=group_id,
+ buckets=buckets
+ )
+ ctrl.message_send(request)
+
+ if send_barrier:
+ do_barrier(ctrl)
+
+ return group_id, request
+
def add_l2_interface_group(ctrl, ports, vlan_id=1, is_tagged=False, send_barrier=False):
# group table
# set up untag groups for each port
@@ -1117,7 +1137,7 @@
return request
-def add_mpls_flow_pw(ctrl, action_group_id, label, ethertype, bos, goto_table=MPLS_TYPE_FLOW_TABLE, pop=True, send_barrier=False):
+def add_mpls_flow_pw(ctrl, action_group_id, label, ethertype, bos, tunnel_index, goto_table=MPLS_TYPE_FLOW_TABLE, popMPLS=True, popL2=False, of_port=0, send_barrier=False):
match = ofp.match()
match.oxm_list.append(ofp.oxm.eth_type(0x8847))
match.oxm_list.append(ofp.oxm.mpls_label(label))
@@ -1125,9 +1145,16 @@
actions = []
actions.append(ofp.action.dec_mpls_ttl())
- if pop == True:
+ if popMPLS == True:
actions.append(ofp.action.copy_ttl_in())
actions.append(ofp.action.pop_mpls(ethertype))
+ if bos==1 and popL2 == True:
+ actions.append(ofp.action.ofdpa_pop_l2_header())
+ actions.append(ofp.action.ofdpa_pop_cw())
+ actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
+ # 0x0002nnnn is for UNI interfaces
+ actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00020000 + of_port)))
+ actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
actions.append(ofp.action.group(action_group_id))
request = ofp.message.flow_add(
diff --git a/ofdpa/flows.py b/ofdpa/flows.py
index fa4decd..dd04fa9 100755
--- a/ofdpa/flows.py
+++ b/ofdpa/flows.py
@@ -1924,3 +1924,6 @@
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 be7e869..cf797e8 100644
--- a/ofdpa/utils.py
+++ b/ofdpa/utils.py
@@ -659,3 +659,107 @@
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,
+ mpls_type=None
+ )
+ 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_in_vlan_1,
+ port_to_switch_mac_str,
+ Groups
+ )