diff --git a/dash-pipeline/SAI/sai_api_gen.py b/dash-pipeline/SAI/sai_api_gen.py
index 9e056ed63..0eda8fd5a 100755
--- a/dash-pipeline/SAI/sai_api_gen.py
+++ b/dash-pipeline/SAI/sai_api_gen.py
@@ -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:
@@ -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']
@@ -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']
diff --git a/dash-pipeline/bmv2/README.md b/dash-pipeline/bmv2/README.md
index 8ecf246f4..b7d75e56d 100644
--- a/dash-pipeline/bmv2/README.md
+++ b/dash-pipeline/bmv2/README.md
@@ -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 P416 with BMv2 v1model. For specs, please find the referenced docs here:
+
+- P416, P4Runtime, PNA specs:
+- V1Model:
+
### 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 `.
+- `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).
\ No newline at end of file
diff --git a/dash-pipeline/bmv2/dash_acl.p4 b/dash-pipeline/bmv2/dash_acl.p4
index 481f2ea1e..9e96e1e4f 100644
--- a/dash-pipeline/bmv2/dash_acl.p4
+++ b/dash-pipeline/bmv2/dash_acl.p4
@@ -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"); \
diff --git a/dash-pipeline/bmv2/dash_pipeline.p4 b/dash-pipeline/bmv2/dash_pipeline.p4
index a39641ea0..ab21a345e 100644
--- a/dash-pipeline/bmv2/dash_pipeline.p4
+++ b/dash-pipeline/bmv2/dash_pipeline.p4
@@ -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,
@@ -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;
@@ -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");
@@ -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");
}
@@ -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");
@@ -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;
diff --git a/dash-pipeline/bmv2/underlay.p4 b/dash-pipeline/bmv2/underlay.p4
index f00d4e7ba..de23a87e9 100644
--- a/dash-pipeline/bmv2/underlay.p4
+++ b/dash-pipeline/bmv2/underlay.p4
@@ -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");