Skip to content

Commit

Permalink
Dash Routing: Direct, Vnet_direct and Drop action support (#141)
Browse files Browse the repository at this point in the history
* Dash Routing: Direct, Vnet_direct and Drop action support

* Fix generated SAI header comments and SAI implementation expectedParams count for shared P4 action params
  • Loading branch information
mukeshmv authored Jul 29, 2022
1 parent f70ce23 commit eddbc03
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 18 deletions.
22 changes: 21 additions & 1 deletion dash-pipeline/SAI/sai_api_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
TABLES_TAG = 'tables'
BITWIDTH_TAG = 'bitwidth'
ACTIONS_TAG = 'actions'
ACTION_PARAMS_TAG = 'actionParams'
PREAMBLE_TAG = 'preamble'
OTHER_MATCH_TYPE_TAG = 'otherMatchType'
MATCH_TYPE_TAG = 'matchType'
Expand All @@ -22,6 +23,7 @@
MATCH_FIELDS_TAG = 'matchFields'
NOACTION = 'NoAction'
STAGES_TAG = 'stages'
PARAM_ACTIONS = 'paramActions'

def get_sai_key_type(key_size, key_header, key_field):
if key_size == 1:
Expand Down Expand Up @@ -97,7 +99,7 @@ def get_sai_key_data(key):
sai_key_data['sai_key_name'] = sai_key_name

key_size = key[BITWIDTH_TAG]

if OTHER_MATCH_TYPE_TAG in key:
sai_key_data['match_type'] = key[OTHER_MATCH_TYPE_TAG].lower()
elif MATCH_TYPE_TAG in key:
Expand Down Expand Up @@ -145,6 +147,21 @@ def table_with_counters(program, table_id):
return 'true'
return 'false'

def fill_action_params(table_params, param_names, action):
for param in action[PARAMS_TAG]:
# skip v4/v6 selector
if 'v4_or_v6' in param[NAME_TAG]:
continue
if param[NAME_TAG] not in param_names:
param_names.append(param[NAME_TAG])
param[PARAM_ACTIONS] = [action[NAME_TAG]]
table_params.append(param)
else:
# ensure that same param passed to multiple actions of the
# same P4 table does not generate more than 1 SAI attribute
for tbl_param in table_params:
if tbl_param[NAME_TAG] == param[NAME_TAG]:
tbl_param[PARAM_ACTIONS].append(action[NAME_TAG])

def generate_sai_apis(program, ignore_tables):
sai_apis = []
Expand All @@ -155,6 +172,7 @@ def generate_sai_apis(program, ignore_tables):
sai_table_data['keys'] = []
sai_table_data[ACTIONS_TAG] = []
sai_table_data[STAGES_TAG] = []
sai_table_data[ACTION_PARAMS_TAG] = []

table_control, table_name = table[PREAMBLE_TAG][NAME_TAG].split('.', 1)
if table_name in ignore_tables:
Expand Down Expand Up @@ -189,9 +207,11 @@ def generate_sai_apis(program, ignore_tables):
continue
sai_table_data['keys'].append(get_sai_key_data(key))

param_names = []
for action in table[ACTION_REFS_TAG]:
action_id = action["id"]
if all_actions[action_id][NAME_TAG] != NOACTION:
fill_action_params(sai_table_data[ACTION_PARAMS_TAG], param_names, all_actions[action_id])
sai_table_data[ACTIONS_TAG].append(all_actions[action_id])

if len(sai_table_data['keys']) == 1 and sai_table_data['keys'][0]['sai_key_name'].endswith(table_name.split('.')[-1] + '_id'):
Expand Down
8 changes: 2 additions & 6 deletions dash-pipeline/SAI/templates/saiapi.cpp.j2
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,7 @@ sai_status_t sai_create_{{ table.name }}(

for (uint32_t i = 0; i < attr_count; i++) {
switch(attr_list[i].id) {
{% for action in table.actions %}
{% for param in action.params %}
{% for param in table.actionParams %}
case SAI_{{ table.name | upper }}_ATTR_{{ param.name | upper }}: {
auto param = action->add_params();
param->set_param_id({{param.id}});
Expand All @@ -113,7 +112,6 @@ sai_status_t sai_create_{{ table.name }}(
break;
}
{% endfor %}
{% endfor %}
}
}

Expand Down Expand Up @@ -222,8 +220,7 @@ sai_status_t sai_create_{{ table.name }}(

for (uint32_t i = 0; i < attr_count; i++) {
switch(attr_list[i].id) {
{% for action in table.actions %}
{% for param in action.params %}
{% for param in table.actionParams %}
case SAI_{{ table.name | upper }}_ATTR_{{ param.name | upper }}: {
auto param = action->add_params();
param->set_param_id({{param.id}});
Expand All @@ -232,7 +229,6 @@ sai_status_t sai_create_{{ table.name }}(
break;
}
{% endfor %}
{% endfor %}
}
}

Expand Down
15 changes: 8 additions & 7 deletions dash-pipeline/SAI/templates/saiapi.h.j2
Original file line number Diff line number Diff line change
Expand Up @@ -151,19 +151,15 @@ typedef enum _sai_{{ table.name }}_attr_t

{% endfor %}
{% endif %}
{% for action in table.actions %}
{% for param in action.params %}
{% for param in table.actionParams %}
/**
* @brief Action {{ action.name }} parameter {{ param.name | upper }}
* @brief Action {% for action in param.paramActions %}{{ action }}{{ ", " if not loop.last else "" }}{% endfor %} parameter {{ param.name | upper }}
*
* @type {{ param.type }}
* @flags CREATE_AND_SET
{% if param.type == 'sai_uint16_t' %}
* @isvlan false
{% endif %}
{% if table.actions | length > 1 %}
* @condition SAI_{{ table.name | upper }}_ATTR_ACTION == SAI_{{ table.name | upper }}_ACTION_{{ action.name | upper }}
{% endif %}
{% if param.type == 'sai_ip_address_t' %}
* @default 0.0.0.0
{% elif param.type == 'sai_mac_t' %}
Expand All @@ -176,6 +172,12 @@ typedef enum _sai_{{ table.name }}_attr_t
* @default SAI_NULL_OBJECT_ID
{% else %}
* @default 0
{% endif %}
{% if table.actions | length > 1 %}
{% if param.paramActions | length > 0 %}
* @validonly {% for action in param.paramActions %}SAI_{{ table.name | upper }}_ATTR_ACTION == SAI_{{ table.name | upper }}_ACTION_{{ action | upper }}{{ " or " if not loop.last else "" }}{% endfor %}

{% endif %}
{% endif %}
*/
{% if not ns.firstattr %}
Expand All @@ -185,7 +187,6 @@ typedef enum _sai_{{ table.name }}_attr_t
SAI_{{ table.name | upper }}_ATTR_{{ param.name | upper }},
{% endif %}

{% endfor %}
{% endfor %}
{% if table.stages | length > 0 %}
/**
Expand Down
2 changes: 2 additions & 0 deletions dash-pipeline/bmv2/dash_metadata.p4
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ struct metadata_t {
bit<16> inbound_vm_id;
bit<8> appliance_id;
bit<1> is_dst_ip_v6;
bit<1> is_lkup_dst_ip_v6;
IPv4ORv6Address dst_ip_addr;
IPv4ORv6Address lkup_dst_ip_addr;
conntrack_data_t conntrack_data;
}

Expand Down
27 changes: 25 additions & 2 deletions dash-pipeline/bmv2/dash_outbound.p4
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ control outbound(inout headers_t hdr,
meta.encap_data.dest_vnet_vni = dest_vnet_vni;
}

action route_vnet_direct(bit<24> dest_vnet_vni,
bit<1> is_overlay_nh_ip_v4_or_v6,
IPv4ORv6Address overlay_nh_ip) {
meta.encap_data.dest_vnet_vni = dest_vnet_vni;
meta.lkup_dst_ip_addr = overlay_nh_ip;
meta.is_lkup_dst_ip_v6 = is_overlay_nh_ip_v4_or_v6;
}

action route_direct() {
/* send to underlay router without any encap */
}

action drop() {
meta.dropped = true;
}

direct_counter(CounterType.packets_and_bytes) routing_counter;

@name("routing|dash_vnet")
Expand All @@ -40,7 +56,11 @@ control outbound(inout headers_t hdr,

actions = {
route_vnet; /* for expressroute - ecmp of overlay */
route_vnet_direct;
route_direct;
drop;
}
const default_action = drop;

counters = routing_counter;
}
Expand All @@ -66,8 +86,8 @@ control outbound(inout headers_t hdr,
key = {
/* Flow for express route */
meta.encap_data.dest_vnet_vni : exact @name("meta.encap_data.dest_vnet_vni:dest_vni");
meta.is_dst_ip_v6 : exact @name("meta.is_dst_ip_v6:v4_or_v6");
meta.dst_ip_addr : exact @name("meta.dst_ip_addr:dip");
meta.is_lkup_dst_ip_v6 : exact @name("meta.is_lkup_dst_ip_v6:v4_or_v6");
meta.lkup_dst_ip_addr : exact @name("meta.lkup_dst_ip_addr:dip");
}

actions = {
Expand Down Expand Up @@ -101,6 +121,9 @@ control outbound(inout headers_t hdr,
ConntrackIn.apply(hdr, meta);
#endif // PNA_CONNTRACK

meta.lkup_dst_ip_addr = meta.dst_ip_addr;
meta.is_lkup_dst_ip_v6 = meta.is_dst_ip_v6;

switch (routing.apply().action_run) {
route_vnet: {
ca_to_pa.apply();
Expand Down
8 changes: 6 additions & 2 deletions dash-pipeline/bmv2/dash_pipeline.p4
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,12 @@ control dash_ingress(inout headers_t hdr,

eni_meter.apply();

/* Send packet to port 1 by default if we reached the end of pipeline */
standard_metadata.egress_spec = 1;
if (meta.dropped) {
drop_action();
} else {
/* Send packet to port 1 by default if we reached the end of pipeline */
standard_metadata.egress_spec = 1;
}
}
}

Expand Down

0 comments on commit eddbc03

Please sign in to comment.