Repository: sonic-net/DASH
Pull request #671: Add single_match_priority in SaiTable annotation
Author: login: jimmyzhai
Created: 2025-03-14T13:01:12Z | Merged: 2025-03-18T03:16:20Z

If at least one of the match fields is Optional, Ternary or Range, p4runtime v1 model requires 'priority' to be set for each table entry. But in some dash scenarios, 'priority' is not required and is not exposed to dash sai. For these special cases, we add a single_match_priority field in SaiTable annotation to mark it. If it is 'true', the behavior changes are: 

- Not generate attribute PRIORITY in SAI object
- Not generate field priority in SAI entry struct
- Set the priority of all table entries to a default (fixed) value 1 in dash p4 libsai

It also adds the set/get support of p4 match kind `range`.


Diff:
diff --git a/dash-pipeline/SAI/specs/dash_acl.yaml b/dash-pipeline/SAI/specs/dash_acl.yaml
index fabda4103..3383589c9 100644
--- a/dash-pipeline/SAI/specs/dash_acl.yaml
+++ b/dash-pipeline/SAI/specs/dash_acl.yaml
@@ -28,6 +28,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 37949057
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
@@ -211,6 +212,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 43936368
+      single_match_priority: false
       stage: acl.stage1
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
@@ -280,6 +282,7 @@ sai_apis:
           attr_params: {}
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 48549629
+      single_match_priority: false
       stage: acl.stage2
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
@@ -349,6 +352,7 @@ sai_apis:
           attr_params: {}
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 40869404
+      single_match_priority: false
       stage: acl.stage3
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
@@ -418,6 +422,7 @@ sai_apis:
           attr_params: {}
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 49672642
+      single_match_priority: false
       stage: acl.stage1
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
@@ -487,6 +492,7 @@ sai_apis:
           attr_params: {}
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 37932124
+      single_match_priority: false
       stage: acl.stage2
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
@@ -556,6 +562,7 @@ sai_apis:
           attr_params: {}
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 46113118
+      single_match_priority: false
       stage: acl.stage3
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
diff --git a/dash-pipeline/SAI/specs/dash_appliance.yaml b/dash-pipeline/SAI/specs/dash_appliance.yaml
index 7c3b1820a..646635a2e 100644
--- a/dash-pipeline/SAI/specs/dash_appliance.yaml
+++ b/dash-pipeline/SAI/specs/dash_appliance.yaml
@@ -28,6 +28,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 45177948
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
diff --git a/dash-pipeline/SAI/specs/dash_direction_lookup.yaml b/dash-pipeline/SAI/specs/dash_direction_lookup.yaml
index 7ae162c22..9720a8ca1 100644
--- a/dash-pipeline/SAI/specs/dash_direction_lookup.yaml
+++ b/dash-pipeline/SAI/specs/dash_direction_lookup.yaml
@@ -65,6 +65,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 49875338
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
diff --git a/dash-pipeline/SAI/specs/dash_eni.yaml b/dash-pipeline/SAI/specs/dash_eni.yaml
index 5900ae061..4bcc070d3 100644
--- a/dash-pipeline/SAI/specs/dash_eni.yaml
+++ b/dash-pipeline/SAI/specs/dash_eni.yaml
@@ -65,6 +65,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 39883185
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
@@ -1671,6 +1672,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 38483381
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
diff --git a/dash-pipeline/SAI/specs/dash_flow.yaml b/dash-pipeline/SAI/specs/dash_flow.yaml
index e8641d62d..04c5a984c 100644
--- a/dash-pipeline/SAI/specs/dash_flow.yaml
+++ b/dash-pipeline/SAI/specs/dash_flow.yaml
@@ -54,6 +54,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 38557285
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
@@ -601,6 +602,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 49035675
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
@@ -933,6 +935,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 38861669
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
@@ -1107,6 +1110,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 38230977
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
diff --git a/dash-pipeline/SAI/specs/dash_ha.yaml b/dash-pipeline/SAI/specs/dash_ha.yaml
index 676211ac3..e3847eadc 100644
--- a/dash-pipeline/SAI/specs/dash_ha.yaml
+++ b/dash-pipeline/SAI/specs/dash_ha.yaml
@@ -405,6 +405,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 45319666
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
@@ -622,6 +623,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 49681752
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
diff --git a/dash-pipeline/SAI/specs/dash_inbound_routing.yaml b/dash-pipeline/SAI/specs/dash_inbound_routing.yaml
index 6c59fb0b2..3167e055e 100644
--- a/dash-pipeline/SAI/specs/dash_inbound_routing.yaml
+++ b/dash-pipeline/SAI/specs/dash_inbound_routing.yaml
@@ -142,6 +142,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 35881437
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
diff --git a/dash-pipeline/SAI/specs/dash_meter.yaml b/dash-pipeline/SAI/specs/dash_meter.yaml
index 90efd0d71..1e7169ee7 100644
--- a/dash-pipeline/SAI/specs/dash_meter.yaml
+++ b/dash-pipeline/SAI/specs/dash_meter.yaml
@@ -84,6 +84,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 45482818
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
@@ -132,6 +133,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 40733610
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
@@ -243,6 +245,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 44484556
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
diff --git a/dash-pipeline/SAI/specs/dash_outbound_ca_to_pa.yaml b/dash-pipeline/SAI/specs/dash_outbound_ca_to_pa.yaml
index 945fecfc8..dbcdbe1c0 100644
--- a/dash-pipeline/SAI/specs/dash_outbound_ca_to_pa.yaml
+++ b/dash-pipeline/SAI/specs/dash_outbound_ca_to_pa.yaml
@@ -262,6 +262,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 48765007
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
diff --git a/dash-pipeline/SAI/specs/dash_outbound_routing.yaml b/dash-pipeline/SAI/specs/dash_outbound_routing.yaml
index ad6533117..ca06669f4 100644
--- a/dash-pipeline/SAI/specs/dash_outbound_routing.yaml
+++ b/dash-pipeline/SAI/specs/dash_outbound_routing.yaml
@@ -295,6 +295,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 38546097
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
@@ -521,6 +522,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 40572680
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
diff --git a/dash-pipeline/SAI/specs/dash_pa_validation.yaml b/dash-pipeline/SAI/specs/dash_pa_validation.yaml
index 9b115e6a4..b328b9c06 100644
--- a/dash-pipeline/SAI/specs/dash_pa_validation.yaml
+++ b/dash-pipeline/SAI/specs/dash_pa_validation.yaml
@@ -71,6 +71,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 49415809
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
diff --git a/dash-pipeline/SAI/specs/dash_tunnel.yaml b/dash-pipeline/SAI/specs/dash_tunnel.yaml
index 6cb76b8e1..c167852ae 100644
--- a/dash-pipeline/SAI/specs/dash_tunnel.yaml
+++ b/dash-pipeline/SAI/specs/dash_tunnel.yaml
@@ -80,6 +80,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 49206552
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
@@ -163,6 +164,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 41269458
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
@@ -215,6 +217,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 37329198
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
diff --git a/dash-pipeline/SAI/specs/dash_vip.yaml b/dash-pipeline/SAI/specs/dash_vip.yaml
index 58458e3ee..a58692f39 100644
--- a/dash-pipeline/SAI/specs/dash_vip.yaml
+++ b/dash-pipeline/SAI/specs/dash_vip.yaml
@@ -65,6 +65,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 36083221
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
diff --git a/dash-pipeline/SAI/specs/dash_vnet.yaml b/dash-pipeline/SAI/specs/dash_vnet.yaml
index 609d70462..33858b768 100644
--- a/dash-pipeline/SAI/specs/dash_vnet.yaml
+++ b/dash-pipeline/SAI/specs/dash_vnet.yaml
@@ -28,6 +28,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 39583935
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
diff --git a/dash-pipeline/SAI/specs/route.yaml b/dash-pipeline/SAI/specs/route.yaml
index bfef31e74..c24be1044 100644
--- a/dash-pipeline/SAI/specs/route.yaml
+++ b/dash-pipeline/SAI/specs/route.yaml
@@ -91,6 +91,7 @@ sai_apis:
     tables:
     - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaTable
       id: 49279256
+      single_match_priority: false
       stage: null
       keys:
       - !!python/object:utils.sai_spec.sai_api_p4_meta.SaiApiP4MetaKey
diff --git a/dash-pipeline/SAI/src/p4meta.cpp b/dash-pipeline/SAI/src/p4meta.cpp
index 57b6c787e..aa41c8ebc 100644
--- a/dash-pipeline/SAI/src/p4meta.cpp
+++ b/dash-pipeline/SAI/src/p4meta.cpp
@@ -128,6 +128,16 @@ namespace dash
         return ipPrefixSetVal(value, mf_lpm, bitwidth);
     }
 
+    void  set_attr_value_to_p4(
+            _In_ const std::string &field,
+            _In_ uint32_t bitwidth,
+            _In_ const sai_attribute_value_t &value,
+            _Inout_ p4::v1::FieldMatch_Range *mf_range)
+    {
+        assert (field == "u32range");
+        return u32rangeSetVal(value, mf_range, bitwidth);
+    }
+
     void get_attr_value_from_p4(
             _In_ const std::string &field,
             _In_ uint32_t bitwidth,
@@ -160,6 +170,20 @@ namespace dash
         }
     }
 
+    void get_attr_value_from_p4(
+            _In_ const std::string &field,
+            _In_ uint32_t bitwidth,
+            _In_ const p4::v1::FieldMatch_Range *mf_range,
+            _Out_ sai_attribute_value_t &value)
+    {
+        assert (field == "u32range");
+
+        uint32_t val = *(const uint32_t*)mf_range->low().c_str();
+        value.u32range.min = ntohl(val) >> (32 - bitwidth);
+
+        val = *(const uint32_t*)mf_range->high().c_str();
+        value.u32range.max = ntohl(val) >> (32 - bitwidth);
+    }
 
     void set_attr_value_mask_to_p4_ternary(
             _In_ const std::string &field,
@@ -252,6 +276,11 @@ namespace dash
             auto mf_optional = mf->mutable_optional();
             set_attr_value_to_p4(key.field, key.bitwidth, value, mf_optional);
         }
+        else if (key.match_type == "range")
+        {
+            auto mf_range = mf->mutable_range();
+            set_attr_value_to_p4(key.field, key.bitwidth, value, mf_range);
+        }
         else if (key.match_type == "list")
         {
             // BMv2 doesn't support "list" match type, and we are using "optional" match in v1model as our implementation.
@@ -308,6 +337,11 @@ namespace dash
             auto mf_optional = mf->mutable_optional();
             get_attr_value_from_p4(key.field, key.bitwidth, mf_optional, value);
         }
+        else if (key.match_type == "range")
+        {
+            auto mf_range = mf->mutable_range();
+            get_attr_value_from_p4(key.field, key.bitwidth, mf_range, value);
+        }
         else if (key.match_type == "list")
         {
             auto mf_optional = mf->mutable_optional();
diff --git a/dash-pipeline/SAI/src/p4meta.h b/dash-pipeline/SAI/src/p4meta.h
index 71d9a23ec..1de153548 100644
--- a/dash-pipeline/SAI/src/p4meta.h
+++ b/dash-pipeline/SAI/src/p4meta.h
@@ -120,6 +120,12 @@ namespace dash
             _In_ const sai_attribute_value_t &value,
             _Inout_ p4::v1::FieldMatch_LPM *mf_lpm);
 
+    void  set_attr_value_to_p4(
+            _In_ const std::string &field,
+            _In_ uint32_t bitwidth,
+            _In_ const sai_attribute_value_t &value,
+            _Inout_ p4::v1::FieldMatch_Range *mf_range);
+
     template<typename T>
     static inline
     void get_attr_value_from_p4(
@@ -196,6 +202,12 @@ namespace dash
             _In_ const p4::v1::FieldMatch_LPM *mf_lpm,
             _Out_ sai_attribute_value_t &value);
 
+    void get_attr_value_from_p4(
+            _In_ const std::string &field,
+            _In_ uint32_t bitwidth,
+            _In_ const p4::v1::FieldMatch_Range *mf_range,
+            _Out_ sai_attribute_value_t &value);
+
     // set/get only for value.ipaddr.addr_family
     template<typename T>
     static inline
diff --git a/dash-pipeline/SAI/src/utils.h b/dash-pipeline/SAI/src/utils.h
index 0ffe068f1..775d396d0 100644
--- a/dash-pipeline/SAI/src/utils.h
+++ b/dash-pipeline/SAI/src/utils.h
@@ -282,6 +282,29 @@ namespace dash
                 ipPrefixSetVal(value.ipprefix, t);
             }
 
+        template<typename T>
+            void u32rangeSetVal(const sai_u32_range_t &range, T &t, int bits = 32)
+            {
+                assert(bits <= 32);
+
+                uint32_t val;
+                int bytes = (bits + 7) / 8;
+
+                val = htonl(range.min);
+                val = val >> (32 - bits);
+                t->set_low(&val, bytes);
+
+                val = htonl(range.max);
+                val = val >> (32 - bits);
+                t->set_high(&val, bytes);
+            }
+
+        template<typename T>
+            void u32rangeSetVal(const sai_attribute_value_t &value, T &t, int bits = 32)
+            {
+                u32rangeSetVal(value.u32range, t, bits);
+            }
+
         template<typename T>
             void u8listSetVal(const sai_attribute_value_t &value, T &t, int bits = -1)
             {
diff --git a/dash-pipeline/SAI/templates/impls/p4_table_entry_match.cpp.j2 b/dash-pipeline/SAI/templates/impls/p4_table_entry_match.cpp.j2
index ba5ff7c08..0573bfe70 100644
--- a/dash-pipeline/SAI/templates/impls/p4_table_entry_match.cpp.j2
+++ b/dash-pipeline/SAI/templates/impls/p4_table_entry_match.cpp.j2
@@ -9,6 +9,7 @@
         {% elif key.match_type == 'ternary' %}{{ util.set_key_ternary(key, value) }}
         {% elif key.match_type == 'optional' %}{{ util.set_key_optional(key, value) }}
         {% elif key.match_type == 'list' %}{{ util.set_key_list(key, value) }}
+        {% elif key.match_type == 'range' %}{{ util.set_key_range(table, key, value) }}
         {% elif key.match_type == 'range_list' %}{{ util.set_key_range_list(key, value) }}
         {% endif %}
     }
diff --git a/dash-pipeline/SAI/templates/impls/p4_table_util.cpp.j2 b/dash-pipeline/SAI/templates/impls/p4_table_util.cpp.j2
index 42528793c..fe5cc5c66 100644
--- a/dash-pipeline/SAI/templates/impls/p4_table_util.cpp.j2
+++ b/dash-pipeline/SAI/templates/impls/p4_table_util.cpp.j2
@@ -61,6 +61,16 @@
     {%- endif %}
 {%- endmacro -%}
 
+{% macro set_key_range(table, key, value) %}
+        auto mf_range = mf->mutable_range();
+        {{key.field}}SetVal({{value}}, mf_range, {{key.bitwidth}});
+    {% if table.single_match_priority %}
+        matchActionEntry->set_priority(1); // set default priority
+    {%- else %}
+        matchActionEntry->set_priority(tableEntry->priority);
+    {%- endif %}
+{%- endmacro -%}
+
 {% macro set_key_range_list(key, value) %}
         // BMv2 doesn't support "range_list" match type, and we are using "optional" match in v1model as our implementation.
         // Hence, here we only take the first item from the list and program the range start as optional match.
diff --git a/dash-pipeline/SAI/utils/dash_p4/dash_p4_table.py b/dash-pipeline/SAI/utils/dash_p4/dash_p4_table.py
index a2c01f5a9..618cf57c5 100644
--- a/dash-pipeline/SAI/utils/dash_p4/dash_p4_table.py
+++ b/dash-pipeline/SAI/utils/dash_p4/dash_p4_table.py
@@ -33,6 +33,7 @@ def __init__(self):
         self.stage: Optional[str] = None
         self.is_object: Optional[str] = None
         self.api_type: Optional[str] = None
+        self.single_match_priority: Optional[bool] = False
 
     def parse_p4rt(
         self,
@@ -113,6 +114,8 @@ def __parse_sai_table_annotations(
                         self.api_name = str(kv["value"]["stringValue"])
                     elif kv["key"] == "api_type":
                         self.api_type = str(kv["value"]["stringValue"])
+                    elif kv["key"] == "single_match_priority":
+                        self.single_match_priority = kv["value"]["stringValue"] == "true"
 
         if self.is_object == None:
             self.is_object = "false"
@@ -265,7 +268,7 @@ def __build_sai_attributes_after_parsing(self):
     #
     def to_sai(self) -> SaiApi:
         sai_api = SaiApi(self.name, self.name.replace('_', ' '), self.is_object != "false")
-        sai_api.p4_meta.tables.append(SaiApiP4MetaTable(self.id, self.stage))
+        sai_api.p4_meta.tables.append(SaiApiP4MetaTable(self.id, self.single_match_priority, self.stage))
 
         self.create_sai_action_enum(sai_api)
         self.create_sai_structs(sai_api)
@@ -367,7 +370,7 @@ def create_sai_structs(self, sai_api: SaiApi) -> None:
         # If any match key in this table supports priority, we need to add a priority attribute.
         if any([key.match_type != "exact" for key in self.keys]) and all(
             [key.match_type != "lpm" for key in self.keys]
-        ):
+        ) and not self.single_match_priority:
             priority_entry = SaiStructEntry(
                 name="priority",
                 description="Rule priority in table",
@@ -423,7 +426,7 @@ def create_sai_attributes(self, sai_api: SaiApi) -> None:
             # If any match key in this table supports priority, we need to add a priority attribute.
             if any([key.match_type != "exact" for key in self.keys]) and all(
                 [key.match_type != "lpm" for key in self.keys]
-            ):
+            ) and not self.single_match_priority:
                 priority_attr = SaiAttribute(
                     name=f"SAI_{self.name.upper()}_ATTR_PRIORITY",
                     description="Rule priority in table",
diff --git a/dash-pipeline/SAI/utils/sai_spec/sai_api_p4_meta.py b/dash-pipeline/SAI/utils/sai_spec/sai_api_p4_meta.py
index cfe9fe4cd..dd32c862b 100644
--- a/dash-pipeline/SAI/utils/sai_spec/sai_api_p4_meta.py
+++ b/dash-pipeline/SAI/utils/sai_spec/sai_api_p4_meta.py
@@ -29,8 +29,9 @@ def __init__(self, name: str, id: int, match_type: str,
         self.is_object_key: bool = is_object_key
 
 class SaiApiP4MetaTable:
-    def __init__(self, id: int, stage: Optional[str] = None):
+    def __init__(self, id: int, single_match_priority: bool, stage: Optional[str] = None):
         self.id: int = id
+        self.single_match_priority: bool = single_match_priority
         self.stage: Optional[str] = stage
         self.keys: List[SaiApiP4MetaKey] = []
         self.actions: Dict[str, SaiApiP4MetaAction] = {}


Reviews:
user: login: r12f
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-15T23:24:45Z
user: login: jimmyzhai
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T16:06:26Z
user: login: r12f
body: thanks Junhua! It looks good to me! Nothing in existing API is changed, which is great!
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-18T03:16:14Z

Review comments:
diff_hunk: @@ -419,19 +413,18 @@ def create_sai_attributes(self, sai_api: SaiApi) -> None:
 
             sai_api.attributes.append(counter_attr)
 
-        if self.is_object == "true":
-            # If any match key in this table supports priority, we need to add a priority attribute.
-            if any([key.match_type != "exact" for key in self.keys]) and all(
-                [key.match_type != "lpm" for key in self.keys]
-            ):
-                priority_attr = SaiAttribute(
-                    name=f"SAI_{self.name.upper()}_ATTR_PRIORITY",
-                    description="Rule priority in table",
-                    type="sai_uint32_t",
-                    flags="MANDATORY_ON_CREATE | CREATE_ONLY",
-                )
+        # If any match key in this table supports priority, we need to add a priority attribute.
path: dash-pipeline/SAI/utils/dash_p4/dash_p4_table.py
user: login: r12f
body: this code only covers the attribute part, but not the structure part, hence it results in existing priority entry being removed.
created_at: 2025-03-15T23:24:45Z
author_association: COLLABORATOR
diff_hunk: @@ -419,19 +413,18 @@ def create_sai_attributes(self, sai_api: SaiApi) -> None:
 
             sai_api.attributes.append(counter_attr)
 
-        if self.is_object == "true":
-            # If any match key in this table supports priority, we need to add a priority attribute.
-            if any([key.match_type != "exact" for key in self.keys]) and all(
-                [key.match_type != "lpm" for key in self.keys]
-            ):
-                priority_attr = SaiAttribute(
-                    name=f"SAI_{self.name.upper()}_ATTR_PRIORITY",
-                    description="Rule priority in table",
-                    type="sai_uint32_t",
-                    flags="MANDATORY_ON_CREATE | CREATE_ONLY",
-                )
+        # If any match key in this table supports priority, we need to add a priority attribute.
path: dash-pipeline/SAI/utils/dash_p4/dash_p4_table.py
user: login: jimmyzhai
body: Updated. Also cover structure part.
created_at: 2025-03-17T16:06:26Z
author_association: COLLABORATOR

PR comments:
user: login: mssonicbld
created_at: 2025-03-14T13:01:15Z
body: /azp run
author_association: NONE
user: login: azure-pipelines[bot]
created_at: 2025-03-14T13:01:21Z
body: <samp>
Commenter does not have sufficient privileges for PR 671 in repo sonic-net/DASH<br>

</samp>
author_association: NONE
user: login: mssonicbld
created_at: 2025-03-17T13:47:37Z
body: /azp run
author_association: NONE
user: login: azure-pipelines[bot]
created_at: 2025-03-17T13:47:43Z
body: <samp>
Commenter does not have sufficient privileges for PR 671 in repo sonic-net/DASH<br>

</samp>
author_association: NONE
user: login: mssonicbld
created_at: 2025-03-17T15:51:08Z
body: /azp run
author_association: NONE
user: login: azure-pipelines[bot]
created_at: 2025-03-17T15:51:14Z
body: <samp>
Commenter does not have sufficient privileges for PR 671 in repo sonic-net/DASH<br>

</samp>
author_association: NONE