Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ST route type #308

Merged
merged 16 commits into from
Apr 12, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 53 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,11 @@ 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 param[NAME_TAG] == sai_enum['name']:
param['type'] = 'sai_' + param[NAME_TAG] + '_t'
param['field'] = 's32'
param['default'] = 'SAI_' + param[NAME_TAG].upper() + '_INVALID'
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 +185,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[:-2]
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 +278,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 +403,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 +421,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 +449,29 @@ 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 = new_lines[:-1]
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
2 changes: 2 additions & 0 deletions dash-pipeline/SAI/templates/saiapi.h.j2
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ typedef enum _sai_{{ table.name }}_attr_t
* @objects SAI_OBJECT_TYPE_{{ param.objectName | upper }}
* @allownull true
* @default SAI_NULL_OBJECT_ID
{% elif param.field == 's32' %}
* @default {{ param.default }}
{% else %}
* @default 0
{% endif %}
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 %}
10 changes: 10 additions & 0 deletions dash-pipeline/SAI/templates/utils.h.j2
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ void u32SetVal(const sai_attribute_value_t &value, T &t, int bits = 32){
t->set_value(&val, bytes);
}

template<typename T>
void s32SetVal(const sai_attribute_value_t &value, T &t, int bits = 32){
assert(bits <= 32);
uint32_t val = value.u32;
val = htonl(val);
val = val >> (32 - bits);
int bytes = (bits + 7) / 8;
t->set_value(&val, bytes);
}

template<typename T>
void u32SetVal(const sai_uint32_t &value, T &t, int bits = 32){
assert(bits <= 32);
Expand Down
7 changes: 7 additions & 0 deletions dash-pipeline/bmv2/dash_conntrack.p4
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ bit<16> directionNeutralPort (
control ConntrackIn(inout headers_t hdr,
inout metadata_t meta)
{
Register<IPv4Address> original_overlay_sip(1024);
Register<IPv4Address> original_overlay_dip(1024);

action conntrackIn_allow () {
/* Invalidate entry based on TCP flags */
if (hdr.tcp.flags & 0x101 /* FIN/RST */) {
Expand All @@ -46,12 +49,16 @@ control ConntrackIn(inout headers_t hdr,
}
restart_expire_timer(); // reset expiration timer for entry
meta.conntrack_data.allow_in = true;
meta.encap_data.original_overly_sip = original_overly_sip.read(get_rule_prio();
meta.encap_data.original_overly_dip = original_overly_dip.read(get_rule_prio();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compilation error - missing parenthesis.

}

action conntrackIn_miss() {
if (hdr.tcp.flags == 0x2 /* SYN */) {
if (meta.direction == direction_t.OUTBOUND) {
add_entry("conntrackIn_allow"); // New PNA Extern
original_overly_sip.write(meta.encap_data.original_overly_sip);
original_overly_dip.write(meta.encap_data.original_overly_dip);
//adding failiure to be eventually handled
set_entry_expire_time(EXPIRE_TIME_PROFILE_LONG);
}
Expand Down
18 changes: 18 additions & 0 deletions dash-pipeline/bmv2/dash_headers.p4
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ header vxlan_t {

const bit<16> VXLAN_HDR_SIZE=64/8;

header nvgre_t {
bit<4> flags;
bit<9> reserved;
bit<3> version;
bit<16> protocol_type;
bit<24> vsid;
bit<8> flow_id;
}

const bit<16> NVGRE_HDR_SIZE=64/8;

header tcp_t {
bit<16> src_port;
bit<16> dst_port;
Expand Down Expand Up @@ -90,11 +101,18 @@ struct headers_t {
udp_t udp;
tcp_t tcp;
vxlan_t vxlan;
nvgre_t nvgre;
ethernet_t inner_ethernet;
ipv4_t inner_ipv4;
ipv6_t inner_ipv6;
udp_t inner_udp;
tcp_t inner_tcp;
}

enum bit<16> dash_encapsulation_t {
INVALID = 0,
VXLAN = 1,
NVGRE = 2
}

#endif /* _SIRIUS_HEADERS_P4_ */
6 changes: 6 additions & 0 deletions dash-pipeline/bmv2/dash_inbound.p4
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ control inbound(inout headers_t hdr,
#endif /* STATEFUL_P4 */
#ifdef PNA_CONNTRACK
ConntrackIn.apply(hdr, meta);

if (meta.encap_data.original_overly_sip != 0) {
service_tunnel_decode(hdr,
meta.encap_data.original_overly_sip,
meta.encap_data.original_overly_dip);
}
#endif // PNA_CONNTRACK

/* ACL */
Expand Down
8 changes: 6 additions & 2 deletions dash-pipeline/bmv2/dash_metadata.p4
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ struct encap_data_t {
EthernetAddress underlay_smac;
EthernetAddress underlay_dmac;
EthernetAddress overlay_dmac;
dash_encapsulation_t 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_t {
INVALID = 0,
OUTBOUND = 1,
INBOUND = 2
Expand All @@ -33,7 +37,7 @@ struct eni_data_t {

struct metadata_t {
bool dropped;
direction_t direction;
dash_direction_t direction;
encap_data_t encap_data;
EthernetAddress eni_addr;
bit<16> vnet_id;
Expand Down
60 changes: 60 additions & 0 deletions dash-pipeline/bmv2/dash_nvgre.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#ifndef _DASH_NVGRE_P4_
#define _DASH_NVGRE_P4_

#include "dash_headers.p4"

action nvgre_encap(inout headers_t hdr,
in EthernetAddress underlay_dmac,
in EthernetAddress underlay_smac,
in IPv4Address underlay_dip,
in IPv4Address underlay_sip,
in EthernetAddress overlay_dmac,
in bit<24> vsid) {
hdr.inner_ethernet = hdr.ethernet;
hdr.inner_ethernet.dst_addr = overlay_dmac;
hdr.ethernet.setInvalid();

hdr.inner_ipv4 = hdr.ipv4;
hdr.ipv4.setInvalid();
hdr.inner_ipv6 = hdr.ipv6;
hdr.ipv6.setInvalid();
hdr.inner_tcp = hdr.tcp;
hdr.tcp.setInvalid();
hdr.inner_udp = hdr.udp;
hdr.udp.setInvalid();

hdr.ethernet.setValid();
hdr.ethernet.dst_addr = underlay_dmac;
hdr.ethernet.src_addr = underlay_smac;
hdr.ethernet.ether_type = IPV4_ETHTYPE;

hdr.ipv4.setValid();
hdr.ipv4.version = 4;
hdr.ipv4.ihl = 5;
hdr.ipv4.diffserv = 0;
hdr.ipv4.total_len = hdr.inner_ipv4.total_len*(bit<16>)(bit<1>)hdr.inner_ipv4.isValid() + \
hdr.inner_ipv6.payload_length*(bit<16>)(bit<1>)hdr.inner_ipv6.isValid() + \
IPV6_HDR_SIZE*(bit<16>)(bit<1>)hdr.inner_ipv6.isValid() + \
ETHER_HDR_SIZE + \
IPV4_HDR_SIZE + \
NVGRE_HDR_SIZE;
hdr.ipv4.identification = 1;
hdr.ipv4.flags = 0;
hdr.ipv4.frag_offset = 0;
hdr.ipv4.ttl = 64;
hdr.ipv4.protocol = NVGRE_PROTO;
hdr.ipv4.dst_addr = underlay_dip;
hdr.ipv4.src_addr = underlay_sip;
hdr.ipv4.hdr_checksum = 0;

hdr.nvgre.setValid();
hdr.nvgre.flags = 4;
hdr.nvgre.reserved = 0;
hdr.nvgre.version = 0;
hdr.nvgre.protocol_type = 0x6558;
hdr.nvgre.vsid = vsid;
hdr.nvgre.flow_id = 0;

}

#endif /* _DASH_NVGRE_P4_ */
Loading