diff --git a/dash-pipeline/SAI/src/dashsai.cpp b/dash-pipeline/SAI/src/dashsai.cpp index e61a1914d..e329d5837 100644 --- a/dash-pipeline/SAI/src/dashsai.cpp +++ b/dash-pipeline/SAI/src/dashsai.cpp @@ -640,10 +640,12 @@ grpc::StatusCode DashSai::readTableEntry( entity = rep.mutable_entities(0); entry->CopyFrom(entity->table_entry()); } + else { + entity->release_table_entry(); + } auto status = client_reader->Finish(); -exit: if (status.ok()) { DASH_LOG_NOTICE("GRPC call Read OK %s", entry->ShortDebugString().c_str()); } @@ -1043,6 +1045,140 @@ sai_status_t DashSai::bulk_remove_objects( return agg_status; } +sai_status_t DashSai::create( + _In_ const P4MetaTable &meta_table, + _In_ sai_object_type_t objectType, + _Out_ sai_object_id_t* objectId, + _In_ sai_object_id_t switchId, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + DASH_LOG_ENTER(); + DASH_CHECK_API_INITIALIZED(); + + auto attrs = DashSai::populateDefaultAttributes(objectType, attr_count, attr_list); + attr_count = (uint32_t)attrs.size(); + attr_list = attrs.data(); + + std::shared_ptr matchActionEntry; + matchActionEntry = std::make_shared(); + matchActionEntry->set_table_id(meta_table.id); + + sai_object_id_t objId = getNextObjectId(objectType); + if (objId == SAI_NULL_OBJECT_ID) + { + DASH_LOG_ERROR("getNextObjectId failed for OBJECT_TYPE %u", objectType); + return SAI_STATUS_FAILURE; + } + + auto meta_object_key = meta_table.get_meta_object_key(); + assert(meta_object_key); + auto key_mf = matchActionEntry->add_match(); + auto key_mf_exact = key_mf->mutable_exact(); + key_mf->set_field_id(meta_object_key->id); + u16SetVal((uint16_t)objId, key_mf_exact, 16); + + pi_p4_id_t action_id = meta_table.find_action_id(attr_count, attr_list); + if (!action_id) { + DASH_LOG_ERROR("Not find p4 table action"); + return SAI_STATUS_FAILURE; + } + + auto action = matchActionEntry->mutable_action()->mutable_action(); + action->set_action_id(action_id); + + for (uint32_t i = 0; i < attr_count; i++) { + if (auto meta_param = meta_table.get_meta_action_param(action_id, attr_list[i].id)) { + // attr in table action params + set_attr_to_p4_action(meta_param, &attr_list[i], action); + } + else if (auto meta_key = meta_table.get_meta_key(attr_list[i].id)) { + // attr in table keys + set_attr_to_p4_match(meta_key, &attr_list[i], matchActionEntry); + } + else { + // FIXME: check extra fields + } + } + + if (insertInTable(matchActionEntry, objId)) { + *objectId = objId; + return SAI_STATUS_SUCCESS; + } + + return SAI_STATUS_FAILURE; +} + +sai_status_t DashSai::create( + _In_ const P4MetaTable &meta_table, + _In_ sai_object_type_t objectType, + _Inout_ std::shared_ptr matchActionEntry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + DASH_LOG_ENTER(); + DASH_CHECK_API_INITIALIZED(); + + auto attrs = DashSai::populateDefaultAttributes(objectType, attr_count, attr_list); + attr_count = (uint32_t)attrs.size(); + attr_list = attrs.data(); + + matchActionEntry->set_table_id(meta_table.id); + + pi_p4_id_t action_id = meta_table.find_action_id(attr_count, attr_list); + if (!action_id) { + DASH_LOG_ERROR("Not find p4 table action"); + return SAI_STATUS_FAILURE; + } + auto action = matchActionEntry->mutable_action()->mutable_action(); + action->set_action_id(action_id); + + for (uint32_t i = 0; i < attr_count; i++) { + if (auto meta_param = meta_table.get_meta_action_param(action_id, attr_list[i].id)) { + // attr in table action params + set_attr_to_p4_action(meta_param, &attr_list[i], action); + } + else { + // FIXME: check extra fields + } + } + + auto ret = mutateTableEntry(matchActionEntry, p4::v1::Update_Type_INSERT); + if (grpc::StatusCode::OK == ret) { + return SAI_STATUS_SUCCESS; + } + + return SAI_STATUS_FAILURE; +} + +sai_status_t DashSai::remove( + _In_ sai_object_id_t objectId) +{ + DASH_LOG_ENTER(); + DASH_CHECK_API_INITIALIZED(); + + if (removeFromTable(objectId)) { + return SAI_STATUS_SUCCESS; + } + + return SAI_STATUS_FAILURE; +} + +sai_status_t DashSai::remove( + _Inout_ std::shared_ptr matchActionEntry) +{ + DASH_LOG_ENTER(); + DASH_CHECK_API_INITIALIZED(); + + auto ret = mutateTableEntry(matchActionEntry, p4::v1::Update_Type_DELETE); + + if (grpc::StatusCode::OK == ret) { + return SAI_STATUS_SUCCESS; + } + + return SAI_STATUS_FAILURE; +} + sai_status_t DashSai::set( _In_ const P4MetaTable &meta_table, _In_ sai_object_id_t objectId, diff --git a/dash-pipeline/SAI/src/dashsai.h b/dash-pipeline/SAI/src/dashsai.h index 1d1517872..6b4a22743 100644 --- a/dash-pipeline/SAI/src/dashsai.h +++ b/dash-pipeline/SAI/src/dashsai.h @@ -53,6 +53,27 @@ namespace dash _Inout_ sai_attribute_t *attr_list); // QUAD api implementation, using p4 meta table + sai_status_t create( + _In_ const P4MetaTable &meta_table, + _In_ sai_object_type_t objectType, + _Out_ sai_object_id_t* objectId, + _In_ sai_object_id_t switchId, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + + sai_status_t create( + _In_ const P4MetaTable &meta_table, + _In_ sai_object_type_t objectType, + _Inout_ std::shared_ptr matchActionEntry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + + sai_status_t remove( + _In_ sai_object_id_t objectId); + + sai_status_t remove( + _Inout_ std::shared_ptr matchActionEntry); + sai_status_t set( _In_ const P4MetaTable &meta_table, _In_ sai_object_id_t objectId, diff --git a/dash-pipeline/SAI/src/p4meta.h b/dash-pipeline/SAI/src/p4meta.h index 219aab202..0617aaf44 100644 --- a/dash-pipeline/SAI/src/p4meta.h +++ b/dash-pipeline/SAI/src/p4meta.h @@ -81,6 +81,8 @@ namespace dash return u8SetVal(value, p4_key_or_param, bitwidth); if (field == "u16") return u16SetVal(value, p4_key_or_param, bitwidth); + if (field == "s32") + return s32SetVal(value, p4_key_or_param, bitwidth); if (field == "u32") return u32SetVal(value, p4_key_or_param, bitwidth); if (field == "u64") @@ -121,6 +123,10 @@ namespace dash uint16_t val = *(const uint16_t*)v; value.u16 = ntohs(val); } + else if (field == "s32") { + int32_t val = *(const int32_t*)v; + value.s32 = ntohl(val) >> (32 - bitwidth); + } else if (field == "u32") { uint32_t val = *(const uint32_t*)v; value.u32 = ntohl(val) >> (32 - bitwidth); diff --git a/dash-pipeline/SAI/templates/impls/p4_table_action.cpp.j2 b/dash-pipeline/SAI/templates/impls/p4_table_action.cpp.j2 deleted file mode 100644 index d0cbfec47..000000000 --- a/dash-pipeline/SAI/templates/impls/p4_table_action.cpp.j2 +++ /dev/null @@ -1,73 +0,0 @@ - {% if table.actions|length == 1 %} - {% for name, action in table.actions.items() %} - actionId = {{action.id}}; // {{name}} - //expectedParams = {{ action.attr_params|length }}; - {% endfor %} - {% else %} - // Search the action - for (uint32_t i = 0; i < attr_count; i++) - { - if (SAI_{{ api.name | upper }}_ATTR_ACTION == attr_list[i].id) - { - switch(attr_list[i].value.s32) - { - {% for name, action in table.actions.items() %} - case {{ name }}: - { - actionId = {{action.id}}; - //expectedParams = {{ action.attr_params|length }}; - break; - } - {% endfor %} - default: - DASH_LOG_ERROR("attribute value [%d] %d not supported yet", i, attr_list[i].value.s32); - break; - } - // only one action - break; - } - } - {% endif %} - action->set_action_id(actionId); - - for (uint32_t i = 0; i < attr_count; i++) - { - auto *md = sai_metadata_get_attr_metadata((sai_object_type_t)SAI_OBJECT_TYPE_{{ api.name | upper }}, attr_list[i].id); - - const char* attrName = md ? md->attridname : "unknown"; - - switch(attr_list[i].id) - { - {% set attr_id_list = [] %} - {% for name, action in table.actions.items() %} - {% for param_name, param in action.attr_params.items() %} - {% if param_name in attr_id_list %}{% continue %}{% endif %} - {% do attr_id_list.append( param_name ) %} - {% if param.skipattr == 'true' %} - {% else %} - case {{ param_name }}: - { - auto param = action->add_params(); - param->set_param_id({{param.id}}); - {{param.field}}SetVal(attr_list[i].value, param, {{param.bitwidth}}); - //matchedParams++; - {% if param.ip_is_v6_field_id != 0 %} - { - // set ip_is_v6_field_id field - auto param2 = action->add_params(); - param2->set_param_id({{param.ip_is_v6_field_id}}); - booldataSetVal((attr_list[i].value.ipaddr.addr_family == SAI_IP_ADDR_FAMILY_IPV4) ? 0 : 1, param2, 1); - //matchedParams++; - } - {% endif %} - break; - } - {% endif %} - {% endfor %} - {% endfor %} - default: - DASH_LOG_ERROR("attribute [%d] %d %s not supported yet", i, attr_list[i].id, attrName); - break; - } - } - diff --git a/dash-pipeline/SAI/templates/impls/p4_table_object_match.cpp.j2 b/dash-pipeline/SAI/templates/impls/p4_table_object_match.cpp.j2 deleted file mode 100644 index d6419e5f3..000000000 --- a/dash-pipeline/SAI/templates/impls/p4_table_object_match.cpp.j2 +++ /dev/null @@ -1,66 +0,0 @@ - {% import 'templates/impls/p4_table_util.cpp.j2' as util %} - {% for key in table['keys'] %} - {% if key.is_object_key %} - auto key_mf = matchActionEntry->add_match(); - key_mf->set_field_id({{key.id}}); - auto key_mf_exact = key_mf->mutable_exact(); - // {{key.field}}SetVal(objId, key_mf_exact, {{key.bitwidth}}); - {{key.field}}SetVal(static_cast(objId), key_mf_exact, {{ key.bitwidth }}); - {% endif %} - {% endfor %} - - // SAI object table with multiple P4 table keys - // Copy P4 table keys from appropriate SAI attributes - for (uint32_t i = 0; i < attr_count; i++) - { - auto *md = sai_metadata_get_attr_metadata((sai_object_type_t)SAI_OBJECT_TYPE_{{ api.name | upper }}, attr_list[i].id); - - const char* attrName = md ? md->attridname : "unknown"; - - switch(attr_list[i].id) - { - {% for key in table['keys'] %} - {% if not key.is_object_key %} - {% set value = 'attr_list[i].value' %} - case SAI_{{ api.name | upper }}_ATTR_{{ key.name | upper }}: - { - auto mf = matchActionEntry->add_match(); - mf->set_field_id({{key.id}}); - {% filter indent(8, True) %} - {% if key.match_type == 'exact' %}{{ util.set_key_in_attr_exact(key, value) }} - {% elif key.match_type == 'lpm' %}{{ util.set_key_lpm(key, value) }} - {% elif key.match_type == 'ternary' %}{{ util.set_key_in_attr_ternary(api, 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_list' %}{{ util.set_key_range_list(key, value) }} - {% endif %} - {% endfilter %} - {% if key.ip_is_v6_field_id != 0 %} - { - // set ip_is_v6_field_id field - auto mf = matchActionEntry->add_match(); - mf->set_field_id({{key.ip_is_v6_field_id}}); - auto mf_exact = mf->mutable_exact(); - booldataSetVal(({{value}}.ipaddr.addr_family == SAI_IP_ADDR_FAMILY_IPV4) ? 0 : 1, mf_exact, 1); - } - {% endif %} - break; - } - {% endif%} - {% 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_{{ api.name | upper }}_ATTR_PRIORITY: - { - matchActionEntry->set_priority(attr_list[i].value.u32); - break; - } - {% endif %} - {% endif %} - default: - DASH_LOG_ERROR("attribute [%d] %d %s not supported yet", i, attr_list[i].id, attrName); - break; - } - } - 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 6903f5b68..26469f0d6 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 @@ -20,99 +20,16 @@ static sai_status_t dash_sai_create_{{ api.name }}( _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list) { - DASH_LOG_ENTER(); - - auto attrs = dash::DashSai::populateDefaultAttributes((sai_object_type_t)SAI_OBJECT_TYPE_{{ api.name | upper }}, attr_count, attr_list); - attr_count = (uint32_t)attrs.size(); - attr_list = attrs.data(); + auto obj_type = (sai_object_type_t)SAI_OBJECT_TYPE_{{ api.name | upper }}; {% if api.is_object %} - std::shared_ptr matchActionEntry; - pi_p4_id_t tableId = 0; - // There shall be one and only one action_type - p4::v1::TableAction* entry = nullptr; - p4::v1::Action* action = nullptr; - //auto expectedParams = 0; - //auto matchedParams = 0; - sai_object_id_t objId = 0; - // Search the action - pi_p4_id_t actionId = 0; - - {% for table in api.p4_meta.tables %} - {% if table.stage != None %} - // For stage {{ table.stage }} - {% endif %} - matchActionEntry = std::make_shared(); - tableId = {{table.id}}; - entry = matchActionEntry->mutable_action(); - action = entry->mutable_action(); - //expectedParams = 0; - //matchedParams = 0; - objId = dashSai->getNextObjectId((sai_object_type_t)SAI_OBJECT_TYPE_{{ api.name | upper }}); - - if (objId == SAI_NULL_OBJECT_ID) - { - DASH_LOG_ERROR("getNextObjectId failed for SAI_OBJECT_TYPE_{{ api.name | upper }}"); - // TODO clean resources - return SAI_STATUS_FAILURE; - } - - matchActionEntry->set_table_id(tableId); - - {% include 'templates/impls/p4_table_object_match.cpp.j2' %} - - // If there is only one action, simply set it. - // Else, search in the attrs. - {% include 'templates/impls/p4_table_action.cpp.j2' %} - - //assert((matchedParams == expectedParams)); - - //if (matchedParams != expectedParams) { - // goto ErrRet; - //} - if (false == dashSai->insertInTable(matchActionEntry, objId)) { - goto ErrRet; - } - - {% endfor %} - - *{{ api.name }}_id = objId; - return SAI_STATUS_SUCCESS; -ErrRet: - dashSai->removeFromTable(*{{ api.name }}_id); - return SAI_STATUS_FAILURE; + return dashSai->create({{meta_table}}, obj_type, {{ api.name }}_id, switch_id, attr_count, attr_list); {% else %} std::shared_ptr matchActionEntry = std::make_shared(); - pi_p4_id_t tableId = {{table.id}}; - matchActionEntry->set_table_id(tableId); - auto tableEntry = {{ api.name }}; - // There shall be one and only one action_type - auto entry = matchActionEntry->mutable_action(); - auto action = entry->mutable_action(); - //auto expectedParams = 0; - //auto matchedParams = 0; - pi_p4_id_t actionId; - grpc::StatusCode retCode; - - {% include 'templates/impls/p4_table_entry_match.cpp.j2' %} - - - {% include 'templates/impls/p4_table_action.cpp.j2' %} - - //assert((matchedParams == expectedParams)); - - //if (matchedParams != expectedParams) { - // goto ErrRet; - //} - // TODO: ternaly needs to set priority - retCode = dashSai->mutateTableEntry(matchActionEntry, p4::v1::Update_Type_INSERT); + matchActionEntry->set_table_id({{meta_table}}.id); - if (grpc::StatusCode::OK == retCode) - { - return SAI_STATUS_SUCCESS; - } -ErrRet: - return SAI_STATUS_FAILURE; + table_{{api.name}}_add_keys({{ api.name }}, matchActionEntry); + return dashSai->create({{meta_table}}, obj_type, matchActionEntry, attr_count, attr_list); {% endif %} } @@ -120,35 +37,13 @@ static sai_status_t dash_sai_remove_{{ api.name }}( {% include 'templates/headers/sai_api_param_object_id.j2' %}) { {% if api.is_object %} - DASH_LOG_ENTER(); - - if (dashSai->removeFromTable({{ api.name }}_id)) - { - return SAI_STATUS_SUCCESS; - } - - return SAI_STATUS_FAILURE; + return dashSai->remove({{ api.name }}_id); {% else %} - DASH_LOG_ENTER(); - std::shared_ptr matchActionEntry = std::make_shared(); - pi_p4_id_t tableId = {{table.id}}; - matchActionEntry->set_table_id(tableId); - auto tableEntry = {{ api.name }}; - grpc::StatusCode retCode; - - {% include 'templates/impls/p4_table_entry_match.cpp.j2' %} - - retCode = dashSai->mutateTableEntry(matchActionEntry, p4::v1::Update_Type_DELETE); - - if (grpc::StatusCode::OK == retCode) - { - return SAI_STATUS_SUCCESS; - } - -ErrRet: + matchActionEntry->set_table_id({{meta_table}}.id); - return SAI_STATUS_FAILURE; + table_{{api.name}}_add_keys({{ api.name }}, matchActionEntry); + return dashSai->remove(matchActionEntry); {% endif %} }