Skip to content

Commit

Permalink
Dash outbound pipeline packet test (sonic-net#193)
Browse files Browse the repository at this point in the history
* Dash outbound pipeline packet test
- Fix issues in sonic-net#185

* Fix p4c switch statement fallthrough action
  • Loading branch information
mukeshmv authored Aug 25, 2022
1 parent 9f0de3c commit e5e461a
Show file tree
Hide file tree
Showing 11 changed files with 311 additions and 72 deletions.
2 changes: 1 addition & 1 deletion dash-pipeline/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ PWD := $(shell pwd)
DOCKER_GRPC_IMG ?=chrissommers/dash-grpc:1.43.2

# Slimmed-down version bmv2 backend only 632MB - works:
DOCKER_P4C_BMV2_IMG ?=chrissommers/dash-p4c-bmv2:220701
DOCKER_P4C_BMV2_IMG ?=chrissommers/dash-p4c-bmv2:220819

# Builds sai-P4rt clients to run inside bmvs process
DOCKER_BMV2_BLDR_IMG ?=chrissommers/dash-bmv2-bldr:220630
Expand Down
2 changes: 1 addition & 1 deletion dash-pipeline/SAI/generate_dash_api.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
sudo ./sai_api_gen.py \
/bmv2/dash_pipeline.bmv2/dash_pipeline_p4rt.json \
--ignore-tables=appliance,eni_meter,slb_decap \
dash
dash
18 changes: 18 additions & 0 deletions dash-pipeline/SAI/sai_api_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,15 @@ def fill_action_params(table_params, param_names, action):
if tbl_param[NAME_TAG] == param[NAME_TAG]:
tbl_param[PARAM_ACTIONS].append(action[NAME_TAG])

for param in action[PARAMS_TAG]:
# mark presence of v4/v6 selector in the parent param
if 'v4_or_v6' in param[NAME_TAG]:
v4_or_v6_param_name = param[NAME_TAG]
for param2 in action[PARAMS_TAG]:
if "is_" + param2[NAME_TAG] + "_v4_or_v6" == param[NAME_TAG]:
param2["v4_or_v6_id"] = param['id']
break

def generate_sai_apis(program, ignore_tables):
sai_apis = []
table_names = []
Expand Down Expand Up @@ -213,6 +222,15 @@ def generate_sai_apis(program, ignore_tables):
continue
sai_table_data['keys'].append(get_sai_key_data(key))

for key in table[MATCH_FIELDS_TAG]:
# mark presence of v4/v6 selector in the parent key field
if 'v4_or_v6' in key[NAME_TAG]:
_, v4_or_v6_key_name = key[NAME_TAG].split(':')
for key2 in sai_table_data['keys']:
if "is_" + key2['sai_key_name'] + "_v4_or_v6" == v4_or_v6_key_name:
key2["v4_or_v6_id"] = key['id']
break

param_names = []
for action in table[ACTION_REFS_TAG]:
action_id = action["id"]
Expand Down
63 changes: 59 additions & 4 deletions dash-pipeline/SAI/templates/saiapi.cpp.j2
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,34 @@ sai_status_t sai_create_{{ table.name }}(
{% elif key.match_type == 'range_list' %}
goto ErrRet;
assert(0 && "range_list is not supported");
// TODO: if it is ternary, need to set the mask
// auto mf1_list = mf1->mutable_xxx();
//{{key.sai_range_list_field}}SetVal(attr_list[i].value, mf1_list, {{key.bitwidth}});
{% elif key.match_type == 'optional' %}
auto mf_optional = mf->mutable_optional();
{{key.sai_key_field}}SetVal(attr_list[i].value, mf_optional, {{key.bitwidth}});
{% endif %}
{% if 'v4_or_v6_id' in key %}
{
// set v4_or_v6 field
auto mf = matchActionEntry->add_match();
mf->set_field_id({{key.v4_or_v6_id}});
auto mf_exact = mf->mutable_exact();
booldataSetVal((attr_list[i].value.ipaddr.addr_family == SAI_IP_ADDR_FAMILY_IPV4) ? 0 : 1, mf_exact, 1);
}
{% endif %}
// TODO: if it is ternary, need to set the mask
break;
}
{% endfor %}
{% if table['keys'] | selectattr('match_type', 'ne', 'exact') | list | length > 0 %}
{% if table['keys'] | selectattr('match_type', 'eq', 'lpm') | list | length == 0 %}
// Table has non lpm ternary keys - add priority field
case SAI_{{ table.name | upper }}_ATTR_PRIORITY: {
matchActionEntry->set_priority(attr_list[i].value.u32);
break;
}
{% endif %}
{% endif %}
}
}
{% endif %}
Expand Down Expand Up @@ -121,6 +142,15 @@ sai_status_t sai_create_{{ table.name }}(
param->set_param_id({{param.id}});
{{param.field}}SetVal(attr_list[i].value, param, {{param.bitwidth}});
matchedParams++;
{% if 'v4_or_v6_id' in param %}
{
// set v4_or_v6 field
auto param = action->add_params();
param->set_param_id({{param.v4_or_v6_id}});
booldataSetVal((attr_list[i].value.ipaddr.addr_family == SAI_IP_ADDR_FAMILY_IPV4) ? 0 : 1, param, 1);
matchedParams++;
}
{% endif %}
break;
}
{% endfor %}
Expand All @@ -132,7 +162,6 @@ sai_status_t sai_create_{{ table.name }}(
if (matchedParams != expectedParams) {
goto ErrRet;
}
// TODO: ternaly needs to set priority
if (true == InsertInTable(matchActionEntry, &objId)) {
*{{ table.name }}_id = objId;
return 0;
Expand Down Expand Up @@ -198,11 +227,20 @@ sai_status_t sai_create_{{ table.name }}(
{% elif key.match_type == 'range_list' %}
assert(0 && "range_list is not supported");
goto ErrRet;
// TODO: if it is ternary, need to set the mask
// auto mf1_list = mf1->mutable_xxx();
//{{key.sai_range_list_field}}SetVal(attr_list[i].value, mf1_list, {{key.bitwidth}});
{% endif %}
// TODO: if it is ternary, need to set the mask
}
{% if 'v4_or_v6_id' in key %}
{
// set v4_or_v6 field
auto mf = matchActionEntry->add_match();
mf->set_field_id({{key.v4_or_v6_id}});
auto mf_exact = mf->mutable_exact();
booldataSetVal((tableEntry->{{ key.sai_key_name | lower }}.addr_family == SAI_IP_ADDR_FAMILY_IPV4) ? 0 : 1, mf_exact, 1);
}
{% endif %}
{% endfor %}


Expand Down Expand Up @@ -237,6 +275,15 @@ sai_status_t sai_create_{{ table.name }}(
param->set_param_id({{param.id}});
{{param.field}}SetVal(attr_list[i].value, param, {{param.bitwidth}});
matchedParams++;
{% if 'v4_or_v6_id' in param %}
{
// set v4_or_v6 field
auto param = action->add_params();
param->set_param_id({{param.v4_or_v6_id}});
booldataSetVal((attr_list[i].value.ipaddr.addr_family == SAI_IP_ADDR_FAMILY_IPV4) ? 0 : 1, param, 1);
matchedParams++;
}
{% endif %}
break;
}
{% endfor %}
Expand Down Expand Up @@ -288,8 +335,16 @@ sai_status_t sai_remove_{{ table.name }}(
// auto mf1_list = mf1->mutable_xxx();
//{{key.sai_range_list_field}}SetVal(attr_list[i].value, mf1_list, {{key.bitwidth}});
{% endif %}
// TODO: if it is ternary, need to set the mask
}
{% if 'v4_or_v6_id' in key %}
{
// set v4_or_v6 field
auto mf = matchActionEntry->add_match();
mf->set_field_id({{key.v4_or_v6_id}});
auto mf_exact = mf->mutable_exact();
booldataSetVal((tableEntry->{{ key.sai_key_name | lower }}.addr_family == SAI_IP_ADDR_FAMILY_IPV4) ? 0 : 1, mf_exact, 1);
}
{% endif %}
{% endfor %}

retCode = MutateTableEntry(matchActionEntry, p4::v1::Update_Type_DELETE);
Expand Down
2 changes: 1 addition & 1 deletion dash-pipeline/SAI/templates/utils.cpp.j2
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ grpc::StatusCode MutateTableEntry(p4::v1::TableEntry *entry, p4::v1::Update_Type
grpc::ClientContext context;
grpc::Status status = stub->Write(&context, request, &rep);
if (status.ok()) {
LOG("GRPC call Write::" << updateTypeStr(updateType) << " OK" << std::endl);
LOG("GRPC call Write::" << updateTypeStr(updateType) << " OK" << entry->ShortDebugString() << std::endl);
}
else {
LOG("GRPC ERROR["<< status.error_code() <<"]: " << status.error_message() << ", " << status.error_details());
Expand Down
9 changes: 4 additions & 5 deletions dash-pipeline/SAI/templates/utils.h.j2
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ template<typename T>
void u32SetVal(const sai_attribute_value_t &value, T &t, int bits = 32){
assert(bits <= 32);
uint32_t val = value.u32;
val = htons(val);
val = htonl(val);
val = val >> (32 - bits);
int bytes = (bits + 7) / 8;
t->set_value(&val, bytes);
Expand All @@ -75,7 +75,7 @@ template<typename T>
void u32SetVal(const sai_uint32_t &value, T &t, int bits = 32){
assert(bits <= 32);
uint32_t val = value;
val = htons(val);
val = htonl(val);
val = val >> (32 - bits);
int bytes = (bits + 7) / 8;
t->set_value(&val, bytes);
Expand Down Expand Up @@ -118,7 +118,6 @@ void ipaddrSetVal(const sai_ip_address_t &value, T &t, int bits = -1){
switch(value.addr_family) {
case SAI_IP_ADDR_FAMILY_IPV4: {
uint32_t val = value.addr.ip4;
val = htonl(val);
t->set_value(&val, 4);
}
break;
Expand Down Expand Up @@ -154,9 +153,9 @@ void ipPrefixSetVal(const sai_ip_prefix_t &value, T &t, int bits = -1){
switch(value.addr_family) {
case SAI_IP_ADDR_FAMILY_IPV4: {
uint32_t val = value.addr.ip4;
val = htonl(val);
t->set_value(&val, 4);
t->set_prefix_len(leadingNonZeroBits(value.addr.ip4));
val = htonl(val);
t->set_prefix_len(leadingNonZeroBits(val)+96);
}
break;
case SAI_IP_ADDR_FAMILY_IPV6: {
Expand Down
4 changes: 3 additions & 1 deletion dash-pipeline/bmv2/dash_acl.p4
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ match_kind {
}

#define ACL_STAGE_APPLY(table_name) \
if ( meta. ## table_name ##_dash_acl_group_id != 0) { \
switch (table_name.apply().action_run) { \
permit: {return;} \
deny: {return;} \
}
} \
} \

/*
* This control results in a new set of tables every time
Expand Down
8 changes: 4 additions & 4 deletions dash-pipeline/bmv2/dash_outbound.p4
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ control outbound(inout headers_t hdr,
table routing {
key = {
meta.eni_id : exact @name("meta.eni_id:eni_id");
meta.is_dst_ip_v6 : exact @name("meta.is_dst_ip_v6:v4_or_v6");
meta.is_dst_ip_v6 : exact @name("meta.is_dst_ip_v6:is_destination_v4_or_v6");
meta.dst_ip_addr : lpm @name("meta.dst_ip_addr:destination");
}

Expand Down Expand Up @@ -66,7 +66,7 @@ control outbound(inout headers_t hdr,
key = {
/* Flow for express route */
meta.dst_vnet_id: exact @name("meta.dst_vnet_id:dst_vnet_id");
meta.is_lkup_dst_ip_v6 : exact @name("meta.is_lkup_dst_ip_v6:v4_or_v6");
meta.is_lkup_dst_ip_v6 : exact @name("meta.is_lkup_dst_ip_v6:is_dip_v4_or_v6");
meta.lkup_dst_ip_addr : exact @name("meta.lkup_dst_ip_addr:dip");
}

Expand Down Expand Up @@ -118,8 +118,8 @@ control outbound(inout headers_t hdr,
meta.is_lkup_dst_ip_v6 = meta.is_dst_ip_v6;

switch (routing.apply().action_run) {
route_vnet:
route_vnet_direct: {
route_vnet_direct:
route_vnet: {
ca_to_pa.apply();
vnet.apply();

Expand Down
3 changes: 0 additions & 3 deletions dash-pipeline/bmv2/dash_pipeline.p4
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,6 @@ control dash_ingress(inout headers_t hdr,

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
6 changes: 3 additions & 3 deletions dash-pipeline/dockerfiles/Dockerfile.p4c-bmv2
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# This Dockerfile builds an image used to compile P4 programs for the bmv2 backend only
# It's based on public p4lang/p4c docker but strips out uneeded backends.
# See https://docs.docker.com/develop/develop-images/multistage-build/
# FROM p4lang/p4c:stable as p4lang-p4c
# :stable on 2022-07-03:
FROM p4lang/p4c@sha256:e4e8aa3f38e84cc51acb7df60257309a6ddfd77a2d0a05e0db445750f209be93 as p4lang-p4c
# FROM p4lang/p4c:latest as p4lang-p4c
# :latest on 2022-08-19:
FROM p4lang/p4c@sha256:39a2eb7374f94b899ef75f5ad9fb0bad170ef7697adf2d54ac10286488ad4490 as p4lang-p4c
LABEL maintainer="SONIC-DASH Community"
LABEL description="DASH p4c-bmv2 compiler, minimal"

Expand Down
Loading

0 comments on commit e5e461a

Please sign in to comment.