Skip to content

Commit

Permalink
Add P4 enums to SAI types
Browse files Browse the repository at this point in the history
Signed-off-by: Marian Pritsak <[email protected]>
  • Loading branch information
marian-pritsak committed Mar 16, 2023
1 parent 608398e commit 2c2531b
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 26 deletions.
54 changes: 51 additions & 3 deletions dash-pipeline/SAI/sai_api_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
PARAM_ACTIONS = 'paramActions'
OBJECT_NAME_TAG = 'objectName'
SCOPE_TAG = 'scope'
TYPE_INFO_TAG = 'typeInfo'
SERIALIZABLE_ENUMS_TAG = 'serializableEnums'
MEMBERS_TAG = 'members'

def get_sai_key_type(key_size, key_header, key_field):
if key_size == 1:
Expand Down Expand Up @@ -128,6 +131,7 @@ def get_sai_key_data(key):

def extract_action_data(program):
action_data = {}
sai_enums = get_sai_enums(program)
for action in program[ACTIONS_TAG]:
preable = action[PREAMBLE_TAG]
id = preable['id']
Expand All @@ -139,6 +143,10 @@ def extract_action_data(program):
param['id'] = p['id']
param[NAME_TAG] = p[NAME_TAG]
param['type'], param['field'] = get_sai_key_type(int(p[BITWIDTH_TAG]), p[NAME_TAG], p[NAME_TAG])
for sai_enum in sai_enums:
if 'dash_' + param[NAME_TAG] == sai_enum['name']:
param['type'] = 'sai_dash_' + param[NAME_TAG] + '_t'
param['field'] = 's32'
param['bitwidth'] = p[BITWIDTH_TAG]
params.append(param)
action_data[id] = {'id': id, NAME_TAG: name, PARAMS_TAG: params}
Expand Down Expand Up @@ -176,10 +184,29 @@ def fill_action_params(table_params, param_names, action):
param2["v4_or_v6_id"] = param['id']
break


def get_sai_enums(program):
all_enums = program[TYPE_INFO_TAG][SERIALIZABLE_ENUMS_TAG]
sai_enums = []
for enum_name in all_enums:
sai_enum = dict()
sai_enum['name'] = enum_name
sai_enum['members'] = []
print(enum_name)
for enum_member in all_enums[enum_name][MEMBERS_TAG]:
member = dict()
member['sai_name'] = enum_member['name']
member['p4rt_value'] = enum_member['value']
sai_enum['members'].append(member)
sai_enums.append(sai_enum)

return sai_enums

def generate_sai_apis(program, ignore_tables):
sai_apis = []
table_names = []
all_actions = extract_action_data(program)
sai_enums = get_sai_enums(program)
tables = sorted(program[TABLES_TAG], key=lambda k: k[PREAMBLE_TAG][NAME_TAG])
for table in tables:
sai_table_data = dict()
Expand Down Expand Up @@ -250,7 +277,7 @@ def generate_sai_apis(program, ignore_tables):
new_api[TABLES_TAG] = [sai_table_data]
sai_apis.append(new_api)

return sai_apis, table_names
return sai_apis, table_names, sai_enums

def get_uniq_sai_api(sai_api):
""" Only keep one table per group(with same table name) """
Expand Down Expand Up @@ -375,7 +402,6 @@ def write_sai_files(sai_api):
f.write(''.join(new_lines))



# CLI
parser = argparse.ArgumentParser(description='P4 SAI API generator')
parser.add_argument('filepath', type=str, help='Path to P4 program RUNTIME JSON file')
Expand All @@ -394,7 +420,7 @@ def write_sai_files(sai_api):
with open(args.filepath) as json_program_file:
json_program = json.load(json_program_file)

sai_apis, all_table_names = generate_sai_apis(json_program, args.ignore_tables.split(','))
sai_apis, all_table_names, sai_enums = generate_sai_apis(json_program, args.ignore_tables.split(','))

sai_api_name_list = []
sai_api_full_name_list = []
Expand Down Expand Up @@ -422,6 +448,28 @@ def write_sai_files(sai_api):
sai_api_name_list.append(sai_api['app_name'].replace('_', ''))
sai_api_full_name_list.append(sai_api['app_name'])

env = Environment(loader=FileSystemLoader('.'), trim_blocks=True, lstrip_blocks=True)
env.add_extension('jinja2.ext.loopcontrols')
env.add_extension('jinja2.ext.do')
sai_enums_tm = env.get_template('templates/saienums.j2')
sai_enums_str = sai_enums_tm.render(sai_enums = sai_enums)
sai_enums_lines = sai_enums_str.split('\n')

# The SAI object struct for entries
with open('./SAI/experimental/saitypesextensions.h', 'r') as f:
lines = f.readlines()

new_lines = []
for line in lines:
if '/* __SAITYPESEXTENSIONS_H_ */' in line:
for enum_line in sai_enums_lines:
new_lines.append(enum_line + '\n')
new_lines.append(line)

with open('./SAI/experimental/saitypesextensions.h', 'w') as f:
f.write(''.join(new_lines))


write_sai_makefile(sai_api_name_list, sai_api_full_name_list)
write_sai_fixed_api_files(sai_api_full_name_list)

Expand Down
10 changes: 10 additions & 0 deletions dash-pipeline/SAI/templates/saienums.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{% for enum in sai_enums %}
typedef enum _sai_{{ enum.name }}_t
{
{% for member in enum.members %}
SAI_{{ enum.name | upper }}_{{ member.sai_name | upper }},

{% endfor %}
} sai_{{ enum.name }}_t;

{% endfor %}
2 changes: 1 addition & 1 deletion dash-pipeline/bmv2/dash_headers.p4
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ struct headers_t {
tcp_t inner_tcp;
}

enum bit<16> dash_encapsulation_t {
enum bit<16> dash_encapsulation {
INVALID = 0,
VXLAN = 1,
NVGRE = 2
Expand Down
8 changes: 4 additions & 4 deletions dash-pipeline/bmv2/dash_metadata.p4
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ struct encap_data_t {
EthernetAddress underlay_smac;
EthernetAddress underlay_dmac;
EthernetAddress overlay_dmac;
dash_encapsulation_t encap_type;
bit<24> service_tunnel_id;
dash_encapsulation dash_encapsulation;
bit<24> service_tunnel_key;
IPv4Address original_overlay_sip;
IPv4Address original_overlay_dip;
}

enum bit<16> direction_t {
enum bit<16> dash_direction {
INVALID = 0,
OUTBOUND = 1,
INBOUND = 2
Expand All @@ -37,7 +37,7 @@ struct eni_data_t {

struct metadata_t {
bool dropped;
direction_t direction;
dash_direction direction;
encap_data_t encap_data;
EthernetAddress eni_addr;
bit<16> vnet_id;
Expand Down
18 changes: 9 additions & 9 deletions dash-pipeline/bmv2/dash_outbound.p4
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ control outbound(inout headers_t hdr,
IPv4ORv6Address underlay_dip,
bit<1> is_underlay_sip_v4_or_v6,
IPv4ORv6Address underlay_sip,
dash_encapsulation_t encap_type,
bit<24> tunnel_id) {
dash_encapsulation encapsulation,
bit<24> tunnel_key) {
/* Assume the overlay addresses provided are always IPv6 and the original are IPv4 */
assert(is_overlay_dip_v4_or_v6 == 1 && is_overlay_sip_v4_or_v6 == 1);
assert(is_overlay_dip_mask_v4_or_v6 == 1 && is_overlay_sip_mask_v4_or_v6 == 1);
Expand All @@ -57,12 +57,12 @@ control outbound(inout headers_t hdr,
overlay_sip,
overlay_sip_mask);

/* encapsulation will be done in apply block based on encap_type */
/* encapsulation will be done in apply block based on dash_encapsulation */
meta.encap_data.underlay_dip = underlay_dip == 0 ? meta.encap_data.original_overlay_dip : (IPv4Address)underlay_dip;
meta.encap_data.underlay_sip = underlay_sip == 0 ? meta.encap_data.original_overlay_sip : (IPv4Address)underlay_sip;
meta.encap_data.overlay_dmac = hdr.ethernet.dst_addr;
meta.encap_data.encap_type = encap_type;
meta.encap_data.service_tunnel_id = tunnel_id;
meta.encap_data.dash_encapsulation = encapsulation;
meta.encap_data.service_tunnel_key = tunnel_key;
}

direct_counter(CounterType.packets_and_bytes) routing_counter;
Expand Down Expand Up @@ -171,22 +171,22 @@ control outbound(inout headers_t hdr,
meta.encap_data.vni);
}
route_service_tunnel: {
if (meta.encap_data.encap_type == dash_encapsulation_t.VXLAN) {
if (meta.encap_data.dash_encapsulation == dash_encapsulation.VXLAN) {
vxlan_encap(hdr,
meta.encap_data.underlay_dmac,
meta.encap_data.underlay_smac,
meta.encap_data.underlay_dip,
meta.encap_data.underlay_sip,
meta.encap_data.overlay_dmac,
meta.encap_data.service_tunnel_id);
} else if (meta.encap_data.encap_type == dash_encapsulation_t.NVGRE) {
meta.encap_data.service_tunnel_key);
} else if (meta.encap_data.dash_encapsulation == dash_encapsulation.NVGRE) {
nvgre_encap(hdr,
meta.encap_data.underlay_dmac,
meta.encap_data.underlay_smac,
meta.encap_data.underlay_dip,
meta.encap_data.underlay_sip,
meta.encap_data.overlay_dmac,
meta.encap_data.service_tunnel_id);
meta.encap_data.service_tunnel_key);
} else {
drop();
}
Expand Down
18 changes: 9 additions & 9 deletions dash-pipeline/bmv2/dash_pipeline.p4
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ control dash_ingress(inout headers_t hdr,
}

action set_outbound_direction() {
meta.direction = direction_t.OUTBOUND;
meta.direction = dash_direction.OUTBOUND;
}

action set_inbound_direction() {
meta.direction = direction_t.INBOUND;
meta.direction = dash_direction.INBOUND;
}

@name("direction_lookup|dash_direction_lookup")
Expand Down Expand Up @@ -125,13 +125,13 @@ control dash_ingress(inout headers_t hdr,
meta.vnet_id = vnet_id;

if (meta.is_overlay_ip_v6 == 1) {
if (meta.direction == direction_t.OUTBOUND) {
if (meta.direction == dash_direction.OUTBOUND) {
ACL_GROUPS_COPY_TO_META(outbound_v6);
} else {
ACL_GROUPS_COPY_TO_META(inbound_v6);
}
} else {
if (meta.direction == direction_t.OUTBOUND) {
if (meta.direction == dash_direction.OUTBOUND) {
ACL_GROUPS_COPY_TO_META(outbound_v4);
} else {
ACL_GROUPS_COPY_TO_META(inbound_v4);
Expand Down Expand Up @@ -261,9 +261,9 @@ control dash_ingress(inout headers_t hdr,

/* Outer header processing */

if (meta.direction == direction_t.OUTBOUND) {
if (meta.direction == dash_direction.OUTBOUND) {
vxlan_decap(hdr);
} else if (meta.direction == direction_t.INBOUND) {
} else if (meta.direction == dash_direction.INBOUND) {
switch (inbound_routing.apply().action_run) {
vxlan_decap_pa_validate: {
pa_validation.apply();
Expand Down Expand Up @@ -298,7 +298,7 @@ control dash_ingress(inout headers_t hdr,
/* At this point the processing is done on customer headers */

/* Put VM's MAC in the direction agnostic metadata field */
meta.eni_addr = meta.direction == direction_t.OUTBOUND ?
meta.eni_addr = meta.direction == dash_direction.OUTBOUND ?
hdr.ethernet.src_addr :
hdr.ethernet.dst_addr;
eni_ether_address_map.apply();
Expand All @@ -308,9 +308,9 @@ control dash_ingress(inout headers_t hdr,
}
acl_group.apply();

if (meta.direction == direction_t.OUTBOUND) {
if (meta.direction == dash_direction.OUTBOUND) {
outbound.apply(hdr, meta, standard_metadata);
} else if (meta.direction == direction_t.INBOUND) {
} else if (meta.direction == dash_direction.INBOUND) {
inbound.apply(hdr, meta, standard_metadata);
}

Expand Down

0 comments on commit 2c2531b

Please sign in to comment.