From 8b334c3ce46778eefbd5b96c26b182bd65a97e61 Mon Sep 17 00:00:00 2001 From: Junhua Zhai Date: Fri, 20 Dec 2024 13:48:20 +0000 Subject: [PATCH] Add meta sibling tables to handle multi-stage tables --- dash-pipeline/SAI/src/dashsai.cpp | 55 +++++++++++++++++-- dash-pipeline/SAI/src/dashsai.h | 10 ++++ dash-pipeline/SAI/src/p4meta.h | 13 ++++- .../templates/impls/sai_api_func_quad.cpp.j2 | 4 +- .../SAI/templates/impls/sai_api_group.cpp.j2 | 14 +++++ 5 files changed, 88 insertions(+), 8 deletions(-) diff --git a/dash-pipeline/SAI/src/dashsai.cpp b/dash-pipeline/SAI/src/dashsai.cpp index 7829a859a..12195f0d6 100644 --- a/dash-pipeline/SAI/src/dashsai.cpp +++ b/dash-pipeline/SAI/src/dashsai.cpp @@ -1104,6 +1104,7 @@ sai_status_t DashSai::create( } if (insertInTable(matchActionEntry, objId)) { + mutateSiblingTablesEntry(meta_table, matchActionEntry, p4::v1::Update_Type_INSERT, action_id); *objectId = objId; return SAI_STATUS_SUCCESS; } @@ -1148,6 +1149,7 @@ sai_status_t DashSai::create( auto ret = mutateTableEntry(matchActionEntry, p4::v1::Update_Type_INSERT); if (grpc::StatusCode::OK == ret) { + mutateSiblingTablesEntry(meta_table, matchActionEntry, p4::v1::Update_Type_INSERT, action_id); return SAI_STATUS_SUCCESS; } @@ -1155,12 +1157,19 @@ sai_status_t DashSai::create( } sai_status_t DashSai::remove( - _In_ sai_object_id_t objectId) + _In_ const P4MetaTable &meta_table, + _In_ sai_object_id_t objectId) { DASH_LOG_ENTER(); DASH_CHECK_API_INITIALIZED(); + std::shared_ptr matchActionEntry = nullptr; + if (!getFromTable(objectId, matchActionEntry)) { + return SAI_STATUS_FAILURE; + } + if (removeFromTable(objectId)) { + mutateSiblingTablesEntry(meta_table, matchActionEntry, p4::v1::Update_Type_DELETE); return SAI_STATUS_SUCCESS; } @@ -1168,7 +1177,8 @@ sai_status_t DashSai::remove( } sai_status_t DashSai::remove( - _Inout_ std::shared_ptr matchActionEntry) + _In_ const P4MetaTable &meta_table, + _Inout_ std::shared_ptr matchActionEntry) { DASH_LOG_ENTER(); DASH_CHECK_API_INITIALIZED(); @@ -1176,6 +1186,7 @@ sai_status_t DashSai::remove( auto ret = mutateTableEntry(matchActionEntry, p4::v1::Update_Type_DELETE); if (grpc::StatusCode::OK == ret) { + mutateSiblingTablesEntry(meta_table, matchActionEntry, p4::v1::Update_Type_DELETE); return SAI_STATUS_SUCCESS; } @@ -1209,6 +1220,9 @@ sai_status_t DashSai::set( set_attr_value_to_p4(meta_param->field, meta_param->bitwidth, attr->value, pair_param.first); auto ret = mutateTableEntry(matchActionEntry, p4::v1::Update_Type_MODIFY); + if (ret == grpc::StatusCode::OK) { + mutateSiblingTablesEntry(meta_table, matchActionEntry, p4::v1::Update_Type_MODIFY, action_id); + } return ret == grpc::StatusCode::OK ? SAI_STATUS_SUCCESS : SAI_STATUS_FAILURE; } @@ -1233,8 +1247,12 @@ sai_status_t DashSai::set( } removeFromTable(objectId); - auto ret = insertInTable(new_entry, objectId); - return ret ? SAI_STATUS_SUCCESS : SAI_STATUS_FAILURE; + mutateSiblingTablesEntry(meta_table, matchActionEntry, p4::v1::Update_Type_DELETE); + + if (insertInTable(new_entry, objectId)) { + mutateSiblingTablesEntry(meta_table, new_entry, p4::v1::Update_Type_INSERT, action_id); + return SAI_STATUS_SUCCESS; + } } return SAI_STATUS_FAILURE; @@ -1266,6 +1284,9 @@ sai_status_t DashSai::set( set_attr_value_to_p4(meta_param->field, meta_param->bitwidth, attr->value, pair_param.first); auto ret = mutateTableEntry(matchActionEntry, p4::v1::Update_Type_MODIFY); + if (ret == grpc::StatusCode::OK) { + mutateSiblingTablesEntry(meta_table, matchActionEntry, p4::v1::Update_Type_MODIFY, action_id); + } return ret == grpc::StatusCode::OK ? SAI_STATUS_SUCCESS : SAI_STATUS_FAILURE; } @@ -1359,3 +1380,29 @@ sai_status_t DashSai::get( return SAI_STATUS_SUCCESS; } +void DashSai::mutateSiblingTablesEntry( + _In_ const P4MetaTable &meta_table, + _In_ std::shared_ptr matchActionEntry, + _In_ p4::v1::Update_Type updateType, + _In_ uint32_t action_id) +{ + if (meta_table.sibling_tables.empty()) { + return; + } + + std::shared_ptr entry = std::make_shared(); + entry->CopyFrom(*matchActionEntry); + auto action = entry->mutable_action()->mutable_action(); + + for (auto &sibling: meta_table.sibling_tables) { + entry->set_table_id(sibling.id); + + if (updateType != p4::v1::Update_Type_DELETE) { + auto enum_id = meta_table.find_action_enum_id(action_id); + auto sibling_action_id = sibling.actions.at(enum_id); + action->set_action_id(sibling_action_id); + } + + mutateTableEntry(entry, updateType); + } +} diff --git a/dash-pipeline/SAI/src/dashsai.h b/dash-pipeline/SAI/src/dashsai.h index 6b4a22743..ccda64c12 100644 --- a/dash-pipeline/SAI/src/dashsai.h +++ b/dash-pipeline/SAI/src/dashsai.h @@ -69,9 +69,11 @@ namespace dash _In_ const sai_attribute_t *attr_list); sai_status_t remove( + _In_ const P4MetaTable &meta_table, _In_ sai_object_id_t objectId); sai_status_t remove( + _In_ const P4MetaTable &meta_table, _Inout_ std::shared_ptr matchActionEntry); sai_status_t set( @@ -147,6 +149,14 @@ namespace dash _In_ sai_object_id_t id, _Out_ std::shared_ptr &entry); + private: // private helper methods + + void mutateSiblingTablesEntry( + _In_ const P4MetaTable &meta_table, + _In_ std::shared_ptr, + _In_ p4::v1::Update_Type updateType, + _In_ uint32_t action_id = 0); + public: // default attributes helper static std::vector populateDefaultAttributes( diff --git a/dash-pipeline/SAI/src/p4meta.h b/dash-pipeline/SAI/src/p4meta.h index 9fba28bef..6c815fdd1 100644 --- a/dash-pipeline/SAI/src/p4meta.h +++ b/dash-pipeline/SAI/src/p4meta.h @@ -34,18 +34,27 @@ namespace dash std::vector params; }; + struct P4MetaSiblingTable { + uint32_t id; + // action enum id -> p4 action id + std::map actions; + }; + struct P4MetaTable { uint32_t id; std::vector keys; std::map actions; std::map extra_fields; + std::vector sibling_tables; P4MetaTable( uint32_t table_id, std::initializer_list init_keys, std::initializer_list::value_type> init_actions, - std::initializer_list::value_type> extras - ) : id(table_id), keys(init_keys), actions(init_actions), extra_fields(extras) + std::initializer_list::value_type> extras, + std::initializer_list sibling_list = {} + ) : id(table_id), keys(init_keys), actions(init_actions), + extra_fields(extras), sibling_tables(sibling_list) {} diff --git a/dash-pipeline/SAI/templates/impls/sai_api_func_quad.cpp.j2 b/dash-pipeline/SAI/templates/impls/sai_api_func_quad.cpp.j2 index 26469f0d6..41be79ab2 100644 --- a/dash-pipeline/SAI/templates/impls/sai_api_func_quad.cpp.j2 +++ b/dash-pipeline/SAI/templates/impls/sai_api_func_quad.cpp.j2 @@ -37,13 +37,13 @@ static sai_status_t dash_sai_remove_{{ api.name }}( {% include 'templates/headers/sai_api_param_object_id.j2' %}) { {% if api.is_object %} - return dashSai->remove({{ api.name }}_id); + return dashSai->remove({{meta_table}}, {{ api.name }}_id); {% else %} std::shared_ptr matchActionEntry = std::make_shared(); matchActionEntry->set_table_id({{meta_table}}.id); table_{{api.name}}_add_keys({{ api.name }}, matchActionEntry); - return dashSai->remove(matchActionEntry); + return dashSai->remove({{meta_table}}, matchActionEntry); {% endif %} } diff --git a/dash-pipeline/SAI/templates/impls/sai_api_group.cpp.j2 b/dash-pipeline/SAI/templates/impls/sai_api_group.cpp.j2 index 8308ecc49..1e2b7095f 100644 --- a/dash-pipeline/SAI/templates/impls/sai_api_group.cpp.j2 +++ b/dash-pipeline/SAI/templates/impls/sai_api_group.cpp.j2 @@ -90,6 +90,20 @@ static dash::P4MetaTable {{meta_table}} ( {% endfor %} {% endif%} } +{% if api.p4_meta.tables|length > 1 %} + ,{ // sibling table list for multiple stages + {% for sibling_table in api.p4_meta.tables[1:] %} + { + {{sibling_table.id}}, // {{ sibling_table.stage }} + { // map of action enum id -> action id + {% for name, action in sibling_table.actions.items() %} + { {{name}}, {{action.id}} }, + {% endfor %} + } + }, + {% endfor %} + } +{% endif %} ); {% include 'templates/impls/sai_api_func_quad.cpp.j2' %}