Skip to content

Commit

Permalink
[sai-gen] Update Sai attribute doc to include the latest support valu…
Browse files Browse the repository at this point in the history
…es, also split it into SaiVal and SaiTable for better clarity. (#477)
  • Loading branch information
r12f authored Dec 11, 2023
1 parent 2721864 commit b8750ef
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 21 deletions.
9 changes: 6 additions & 3 deletions dash-pipeline/SAI/sai_api_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
STRUCTURED_ANNOTATIONS_TAG = 'structuredAnnotations'
KV_PAIRS_TAG = 'kvPairs'
KV_PAIR_LIST_TAG = 'kvPairList'
SAI_TAG = 'Sai'
SAI_VAL_TAG = 'SaiVal'
SAI_TABLE_TAG = 'SaiTable'

#
# SAI parser decorators:
Expand Down Expand Up @@ -252,9 +253,11 @@ def _parse_sai_object_annotation(self, p4rt_anno_list):
]
}
}
Whenever a new attribute is introduced, please update the doc here to get it captured: dash-pipeline/bmv2/README.md.
'''
for anno in p4rt_anno_list[STRUCTURED_ANNOTATIONS_TAG]:
if anno[NAME_TAG] == SAI_TAG:
if anno[NAME_TAG] == SAI_VAL_TAG:
for kv in anno[KV_PAIR_LIST_TAG][KV_PAIRS_TAG]:
if kv['key'] == 'type':
self.type = kv['value']['stringValue']
Expand Down Expand Up @@ -568,7 +571,7 @@ def __parse_sai_table_annotations(self, p4rt_table_preamble):
return

for anno in p4rt_table_preamble[STRUCTURED_ANNOTATIONS_TAG]:
if anno[NAME_TAG] == SAI_TAG:
if anno[NAME_TAG] == SAI_TABLE_TAG:
for kv in anno[KV_PAIR_LIST_TAG][KV_PAIRS_TAG]:
if kv['key'] == 'isobject':
self.is_object = kv['value']['stringValue']
Expand Down
48 changes: 42 additions & 6 deletions dash-pipeline/bmv2/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,48 @@
# DASH Pipeline BM

This directory contains the P4/BMv2-based behavior model implementation of the DASH Pipeline.

At a high level, the DASH pipeline BM serves 2 purposes:

1. It provides a behavior model for DASH pipeline, which can be used for testing in a simulated environment.
2. It provides a generated P4 runtime definition, which can be used to generate the SAI API and SAI adapter code to the behavior model.

## Writing P4/BMv2 code

The workflow of developing the DASH pipeline BM is described in the [DASH workflows doc](../README-dash-workflows.md).

The DASH pipeline BM is written in P4<sub>16</sub> with BMv2 v1model. For specs, please find the referenced docs here:

- P4<sub>16</sub>, P4Runtime, PNA specs: <https://p4.org/specs/>
- V1Model: <https://github.com/p4lang/p4c/blob/main/p4include/v1model.p4>

### P4 annotations for SAI code generation

SAI API generation now supports P4 annotations for documenting/providing necessary metadata to keys and action parameters.
Currently, some of the SAI generation behavior is either controlled by using the `@name` attribute with a non-formalized format, or simplifying guessing in the `sai_api_gen.py`. This is hard to maintain and extend and highly not recommended.

To deprecate the complicated `@name` attribute, we are moving towards using structured annotations in P4. This annotation can apply on keys, action parameters and tables to document and provide necessary metadata for SAI API generation.

Use `@Sai["tag"="value", ...]` format for annotating attributes. Old mode, where `sai_api_gen.py` is guessing this information, is still supported.
The old mode is still supported, but no more new features will be added to it and it will be deprecated in the future.

#### `@SaiVal`: Keys and action parameters

Use `@SaiVal["tag"="value", ...]` format for annotating keys and action parameters.

Available tags are:

- `type`: Specify which SAI object type should be used in generation, e.g. `sai_uint32_t`.
- `isresourcetype`: When set to "true", we generate a corresponding SAI tag in SAI APIs: `@isresourcetype true`.
- `objects`: Space separated list of SAI object type this value accepts. When set, we force this value to be a SAI object id, and generate a corresponding SAI tag in SAI APIs: `@objects <list>`.
- `isreadonly`: When set to "true", we generate force this value to be read-only in SAI API using: `@flags READ_ONLY`, otherwise, we generate `@flags CREATE_AND_SET`.
- `skipattr`: When set to "true", we skip this attribute in SAI API generation.

#### `@SaiTable`: Tables

Use `@SaiTable["tag"="value", ...]` format for annotating tables.

Available tags are:
* type - SAI type
* isresourcetype - generates a corresponding SAI tag
* objects - space separated list of SAI object types this attribute accepts

More annotations may be added in the future. The infrastructure is extendable.
- `isobject`: When set to "true", a top level objects in SAI that attached to switch will be generated. Otherwise, a new type of entry will be generated, if nothing else helps us to determine this table is an object table.
- `ignoretable`: When set to "true", we skip this table in SAI API generation.

For more details, please check the SAI API generation script: [sai_api_gen.py](../SAI/sai_api_gen.py).
2 changes: 1 addition & 1 deletion dash-pipeline/bmv2/dash_acl.p4
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ match_kind {
table table_name { \
key = { \
meta. ## table_name ##_dash_acl_group_id : exact @name("meta.dash_acl_group_id:dash_acl_group_id") \
@Sai[type="sai_object_id_t", isresourcetype="true", objects="SAI_OBJECT_TYPE_DASH_ACL_GROUP"]; \
@SaiVal[type="sai_object_id_t", isresourcetype="true", objects="SAI_OBJECT_TYPE_DASH_ACL_GROUP"]; \
meta.dst_ip_addr : LIST_MATCH @name("meta.dst_ip_addr:dip"); \
meta.src_ip_addr : LIST_MATCH @name("meta.src_ip_addr:sip"); \
meta.ip_protocol : LIST_MATCH @name("meta.ip_protocol:protocol"); \
Expand Down
20 changes: 10 additions & 10 deletions dash-pipeline/bmv2/dash_pipeline.p4
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ control dash_ingress(
bit<32> flows,
bit<1> admin_state,
IPv4Address vm_underlay_dip,
@Sai[type="sai_uint32_t"]
@SaiVal[type="sai_uint32_t"]
bit<24> vm_vni,
bit<16> vnet_id,
IPv6Address pl_sip,
Expand Down Expand Up @@ -242,7 +242,7 @@ control dash_ingress(
const default_action = deny;
}

action check_ip_addr_family(@Sai[type="sai_ip_addr_family_t", isresourcetype="true"] bit<32> ip_addr_family) {
action check_ip_addr_family(@SaiVal[type="sai_ip_addr_family_t", isresourcetype="true"] bit<32> ip_addr_family) {
if (ip_addr_family == 0) /* SAI_IP_ADDR_FAMILY_IPV4 */ {
if (meta.is_overlay_ip_v6 == 1) {
meta.dropped = true;
Expand All @@ -255,7 +255,7 @@ control dash_ingress(
}

@name("meter_policy|dash_meter")
@Sai[isobject="true"]
@SaiTable[isobject="true"]
table meter_policy {
key = {
meta.meter_policy_id : exact @name("meta.meter_policy_id:meter_policy_id");
Expand All @@ -270,10 +270,10 @@ control dash_ingress(
}

@name("meter_rule|dash_meter")
@Sai[isobject="true"]
@SaiTable[isobject="true"]
table meter_rule {
key = {
meta.meter_policy_id: exact @name("meta.meter_policy_id:meter_policy_id") @Sai[type="sai_object_id_t", isresourcetype="true", objects="METER_POLICY"];
meta.meter_policy_id: exact @name("meta.meter_policy_id:meter_policy_id") @SaiVal[type="sai_object_id_t", isresourcetype="true", objects="METER_POLICY"];
hdr.ipv4.dst_addr : ternary @name("hdr.ipv4.dst_addr:dip");
}

Expand All @@ -291,15 +291,15 @@ control dash_ingress(
counter(MAX_METER_BUCKETS, CounterType.bytes) meter_bucket_outbound;
#endif // TARGET_BMV2_V1MODEL
action meter_bucket_action(
@Sai[type="sai_uint64_t", isreadonly="true"] bit<64> outbound_bytes_counter,
@Sai[type="sai_uint64_t", isreadonly="true"] bit<64> inbound_bytes_counter,
@Sai[type="sai_uint32_t", skipattr="true"] bit<32> meter_bucket_index) {
@SaiVal[type="sai_uint64_t", isreadonly="true"] bit<64> outbound_bytes_counter,
@SaiVal[type="sai_uint64_t", isreadonly="true"] bit<64> inbound_bytes_counter,
@SaiVal[type="sai_uint32_t", skipattr="true"] bit<32> meter_bucket_index) {
// read only counters for SAI api generation only
meta.meter_bucket_index = meter_bucket_index;
}

@name("meter_bucket|dash_meter")
@Sai[isobject="true"]
@SaiTable[isobject="true"]
table meter_bucket {
key = {
meta.eni_id: exact @name("meta.eni_id:eni_id");
Expand Down Expand Up @@ -329,7 +329,7 @@ control dash_ingress(
const default_action = deny;
}

action set_acl_group_attrs(@Sai[type="sai_ip_addr_family_t", isresourcetype="true"] bit<32> ip_addr_family) {
action set_acl_group_attrs(@SaiVal[type="sai_ip_addr_family_t", isresourcetype="true"] bit<32> ip_addr_family) {
if (ip_addr_family == 0) /* SAI_IP_ADDR_FAMILY_IPV4 */ {
if (meta.is_overlay_ip_v6 == 1) {
meta.dropped = true;
Expand Down
2 changes: 1 addition & 1 deletion dash-pipeline/bmv2/underlay.p4
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ control underlay(
}

@name("route|route")
// TODO: To add structural annotations (example: @Sai[skipHeaderGen=true])
// TODO: To add structural annotations (example: @SaiTable[skipHeaderGen=true])
table underlay_routing {
key = {
meta.dst_ip_addr : lpm @name("meta.dst_ip_addr:destination");
Expand Down

0 comments on commit b8750ef

Please sign in to comment.