Intermediate transport support
Changes:
- Adds a procedure to fill the pipeline in different use cases;
- Adds a new utility function to fill the MPLS flow tables;
- Adds an utility function to print the ports stats
Change-Id: I8928b177ac93e4c05ced4573be87c1c9361d35b5
diff --git a/accton/accton_util.py b/accton/accton_util.py
index 2a8eba3..75a1df5 100755
--- a/accton/accton_util.py
+++ b/accton/accton_util.py
@@ -674,6 +674,8 @@
actions=[]
if vrf!=0:
actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
+ if mpls_type!=None:
+ actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=mpls_type)))
#actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(value=vlan_id)))
@@ -1086,6 +1088,7 @@
match.oxm_list.append(ofp.oxm.eth_type(0x8847))
match.oxm_list.append(ofp.oxm.mpls_label(label))
match.oxm_list.append(ofp.oxm.mpls_bos(bos))
+ actions = []
actions = [ofp.action.dec_mpls_ttl(),
ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf))]
if (goto_table == 29):
@@ -1114,6 +1117,38 @@
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):
+ match = ofp.match()
+ match.oxm_list.append(ofp.oxm.eth_type(0x8847))
+ match.oxm_list.append(ofp.oxm.mpls_label(label))
+ match.oxm_list.append(ofp.oxm.mpls_bos(bos))
+
+ actions = []
+ actions.append(ofp.action.dec_mpls_ttl())
+ if pop == True:
+ actions.append(ofp.action.copy_ttl_in())
+ actions.append(ofp.action.pop_mpls(ethertype))
+ actions.append(ofp.action.group(action_group_id))
+
+ request = ofp.message.flow_add(
+ table_id=24,
+ cookie=43,
+ match=match,
+ instructions=[
+ ofp.instruction.apply_actions(actions=actions),
+ ofp.instruction.goto_table(goto_table)
+ ],
+ buffer_id=ofp.OFP_NO_BUFFER,
+ priority=1
+ )
+ logging.info("Inserting MPLS flow , label %ld", label)
+ ctrl.message_send(request)
+
+ if send_barrier:
+ do_barrier(ctrl)
+
+ return request
+
def add_mcast4_routing_flow(ctrl, vlan_id, src_ip, src_ip_mask, dst_ip, action_group_id, send_barrier=False):
match = ofp.match()
match.oxm_list.append(ofp.oxm.eth_type(0x0800))
@@ -1571,6 +1606,28 @@
return mpls_group_id, request
+def add_mpls_swap_label_group(
+ ctrl,
+ ref_gid,
+ subtype,
+ index,
+ label,
+ ):
+
+ action=[]
+ action.append(ofp.action.set_field(ofp.oxm.mpls_label(label)))
+ action.append(ofp.action.group(ref_gid))
+ buckets = [ofp.bucket(actions=action)]
+
+ mpls_group_id = encode_mpls_label_group_id(subtype, index)
+ request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+ group_id=mpls_group_id,
+ buckets=buckets
+ )
+ ctrl.message_send(request)
+
+ return mpls_group_id, request
+
def add_mpls_label_group(ctrl, subtype, index, ref_gid,
lmep_id=-1,
qos_index=-1,
diff --git a/ofdpa/utils.py b/ofdpa/utils.py
index 0a41645..be7e869 100644
--- a/ofdpa/utils.py
+++ b/ofdpa/utils.py
@@ -331,7 +331,7 @@
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 = {}
@@ -508,3 +508,154 @@
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,
+ 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_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
+ )
diff --git a/src/python/loxi/of13/oxm.py b/src/python/loxi/of13/oxm.py
index 193ff6f..9b46aab 100755
--- a/src/python/loxi/of13/oxm.py
+++ b/src/python/loxi/of13/oxm.py
@@ -6152,6 +6152,7 @@
VPWS = 1
TUNNEL_ID_BASE = 0x10000
+L3_PHP = 32
class exp1ByteValue(oxm):
type_len = 0xffff0005