diff --git a/meta/Meta.cpp b/meta/Meta.cpp index c830f9af9287..bae66e7d0172 100644 --- a/meta/Meta.cpp +++ b/meta/Meta.cpp @@ -3417,6 +3417,7 @@ void Meta::meta_generic_validation_post_remove( case SAI_ATTR_VALUE_TYPE_UINT32_LIST: case SAI_ATTR_VALUE_TYPE_INT32_LIST: case SAI_ATTR_VALUE_TYPE_QOS_MAP_LIST: + case SAI_ATTR_VALUE_TYPE_MAP_LIST: case SAI_ATTR_VALUE_TYPE_IP_ADDRESS_LIST: case SAI_ATTR_VALUE_TYPE_UINT32_RANGE: case SAI_ATTR_VALUE_TYPE_INT32_RANGE: @@ -4657,6 +4658,9 @@ sai_status_t Meta::meta_generic_validation_create( case SAI_ATTR_VALUE_TYPE_QOS_MAP_LIST: VALIDATION_LIST(md, value.qosmap); break; + case SAI_ATTR_VALUE_TYPE_MAP_LIST: + VALIDATION_LIST(md, value.maplist); + break; case SAI_ATTR_VALUE_TYPE_ACL_RESOURCE_LIST: VALIDATION_LIST(md, value.aclresource); break; @@ -5307,6 +5311,9 @@ sai_status_t Meta::meta_generic_validation_set( case SAI_ATTR_VALUE_TYPE_QOS_MAP_LIST: VALIDATION_LIST(md, value.qosmap); break; + case SAI_ATTR_VALUE_TYPE_MAP_LIST: + VALIDATION_LIST(md, value.maplist); + break; case SAI_ATTR_VALUE_TYPE_ACL_RESOURCE_LIST: VALIDATION_LIST(md, value.aclresource); break; @@ -5715,6 +5722,9 @@ sai_status_t Meta::meta_generic_validation_get( case SAI_ATTR_VALUE_TYPE_QOS_MAP_LIST: VALIDATION_LIST(md, value.qosmap); break; + case SAI_ATTR_VALUE_TYPE_MAP_LIST: + VALIDATION_LIST(md, value.maplist); + break; case SAI_ATTR_VALUE_TYPE_ACL_RESOURCE_LIST: VALIDATION_LIST(md, value.aclresource); break; @@ -5958,6 +5968,9 @@ void Meta::meta_generic_validation_post_get( case SAI_ATTR_VALUE_TYPE_QOS_MAP_LIST: VALIDATION_LIST_GET(md, value.qosmap); break; + case SAI_ATTR_VALUE_TYPE_MAP_LIST: + VALIDATION_LIST_GET(md, value.maplist); + break; case SAI_ATTR_VALUE_TYPE_ACL_RESOURCE_LIST: VALIDATION_LIST_GET(md, value.aclresource); break; @@ -6861,6 +6874,7 @@ void Meta::meta_generic_validation_post_create( case SAI_ATTR_VALUE_TYPE_UINT32_LIST: case SAI_ATTR_VALUE_TYPE_INT32_LIST: case SAI_ATTR_VALUE_TYPE_QOS_MAP_LIST: + case SAI_ATTR_VALUE_TYPE_MAP_LIST: case SAI_ATTR_VALUE_TYPE_IP_ADDRESS_LIST: case SAI_ATTR_VALUE_TYPE_UINT32_RANGE: case SAI_ATTR_VALUE_TYPE_INT32_RANGE: @@ -7099,6 +7113,7 @@ void Meta::meta_generic_validation_post_set( case SAI_ATTR_VALUE_TYPE_UINT32_LIST: case SAI_ATTR_VALUE_TYPE_INT32_LIST: case SAI_ATTR_VALUE_TYPE_QOS_MAP_LIST: + case SAI_ATTR_VALUE_TYPE_MAP_LIST: case SAI_ATTR_VALUE_TYPE_IP_ADDRESS_LIST: case SAI_ATTR_VALUE_TYPE_UINT32_RANGE: case SAI_ATTR_VALUE_TYPE_INT32_RANGE: diff --git a/meta/SaiSerialize.cpp b/meta/SaiSerialize.cpp index 53f63fcfb1c5..2a3b22c15a4f 100644 --- a/meta/SaiSerialize.cpp +++ b/meta/SaiSerialize.cpp @@ -1296,6 +1296,50 @@ std::string sai_serialize_qos_map_list( return j.dump(); } +json sai_serialize_map( + _In_ const sai_map_t &map) +{ + SWSS_LOG_ENTER(); + + json j; + + j["key"] = map.key; + j["value"] = map.value; + + return j; +} + +std::string sai_serialize_map_list( + _In_ const sai_map_list_t &maplist, + _In_ bool countOnly) +{ + SWSS_LOG_ENTER(); + + json j; + + j["count"] = maplist.count; + + if (maplist.list == NULL || countOnly) + { + j["list"] = nullptr; + + return j.dump(); + } + + json arr = json::array(); + + for (uint32_t i = 0; i < maplist.count; ++i) + { + json item = sai_serialize_map(maplist.list[i]); + + arr.push_back(item); + } + + j["list"] = arr; + + return j.dump(); +} + json sai_serialize_acl_resource( _In_ const sai_acl_resource_t& aclresource) { @@ -1704,6 +1748,9 @@ std::string sai_serialize_attr_value( case SAI_ATTR_VALUE_TYPE_QOS_MAP_LIST: return sai_serialize_qos_map_list(attr.value.qosmap, countOnly); + case SAI_ATTR_VALUE_TYPE_MAP_LIST: + return sai_serialize_map_list(attr.value.maplist, countOnly); + case SAI_ATTR_VALUE_TYPE_ACL_RESOURCE_LIST: return sai_serialize_acl_resource_list(attr.value.aclresource, countOnly); @@ -2516,6 +2563,16 @@ static void sai_deserialize_qos_map( sai_deserialize_qos_map_params(j["value"], qosmap.value); } +void sai_deserialize_map( + _In_ const json &j, + _Out_ sai_map_t &map) +{ + SWSS_LOG_ENTER(); + + map.key = j["key"]; + map.value = j["value"]; +} + void sai_deserialize_qos_map_list( _In_ const std::string& s, _Out_ sai_qos_map_list_t& qosmap, @@ -2555,6 +2612,45 @@ void sai_deserialize_qos_map_list( } } +void sai_deserialize_map_list( + _In_ const std::string &s, + _Out_ sai_map_list_t &maplist, + _In_ bool countOnly) +{ + SWSS_LOG_ENTER(); + + json j = json::parse(s); + + maplist.count = j["count"]; + + if (countOnly) + { + return; + } + + if (j["list"] == nullptr) + { + maplist.list = NULL; + return; + } + + json arr = j["list"]; + + if (arr.size() != (size_t)maplist.count) + { + SWSS_LOG_THROW("map list count mismatch %lu vs %u", arr.size(), maplist.count); + } + + maplist.list = sai_alloc_n_of_ptr_type(maplist.count, maplist.list); + + for (uint32_t i = 0; i < maplist.count; ++i) + { + const json &item = arr[i]; + + sai_deserialize_map(item, maplist.list[i]); + } +} + void sai_deserialize_acl_stage( _In_ const std::string& s, _Out_ sai_acl_stage_t& stage) @@ -3186,6 +3282,9 @@ void sai_deserialize_attr_value( case SAI_ATTR_VALUE_TYPE_QOS_MAP_LIST: return sai_deserialize_qos_map_list(s, attr.value.qosmap, countOnly); + case SAI_ATTR_VALUE_TYPE_MAP_LIST: + return sai_deserialize_map_list(s, attr.value.maplist, countOnly); + case SAI_ATTR_VALUE_TYPE_ACL_RESOURCE_LIST: return sai_deserialize_acl_resource_list(s, attr.value.aclresource, countOnly); @@ -3912,6 +4011,10 @@ void sai_deserialize_free_attribute_value( sai_free_list(attr.value.qosmap); break; + case SAI_ATTR_VALUE_TYPE_MAP_LIST: + sai_free_list(attr.value.maplist); + break; + case SAI_ATTR_VALUE_TYPE_ACL_RESOURCE_LIST: sai_free_list(attr.value.aclresource); break; diff --git a/unittest/meta/TestSaiSerialize.cpp b/unittest/meta/TestSaiSerialize.cpp index aa4d36419e5c..2fc26d937be7 100644 --- a/unittest/meta/TestSaiSerialize.cpp +++ b/unittest/meta/TestSaiSerialize.cpp @@ -1076,6 +1076,46 @@ TEST(SaiSerialize, serialize_qos_map) EXPECT_EQ(l.value.fc, 2); } +TEST(SaiSerialize, serialize_map) +{ + sai_attribute_t attr; + const sai_attr_metadata_t* meta; + std::string s; + + attr.id = SAI_NEXT_HOP_GROUP_MAP_ATTR_MAP_TO_VALUE_LIST; + + sai_map_t map = { .key = 1, .value = 11 }; + + attr.value.maplist.count = 1; + attr.value.maplist.list = ↦ + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_NEXT_HOP_GROUP_MAP, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + std::string ret = "{\"count\":1,\"list\":[{\"key\":1,\"value\":11}]}"; + + EXPECT_EQ(s, ret); + + s = sai_serialize_attr_value(*meta, attr, true); + + std::string ret2 = "{\"count\":1,\"list\":null}"; + EXPECT_EQ(s, ret2); + + // deserialize + + memset(&attr, 0, sizeof(attr)); + + sai_deserialize_attr_value(ret, *meta, attr); + + EXPECT_EQ(attr.value.maplist.count, 1); + + auto &l = attr.value.maplist.list[0]; + EXPECT_EQ(l.key, 1); + + EXPECT_EQ(l.value, 11); +} + template static void deserialize_number( _In_ const std::string& s, diff --git a/vslib/VirtualSwitchSaiInterface.cpp b/vslib/VirtualSwitchSaiInterface.cpp index 7e78bf19d266..bffdf069f526 100644 --- a/vslib/VirtualSwitchSaiInterface.cpp +++ b/vslib/VirtualSwitchSaiInterface.cpp @@ -754,6 +754,11 @@ sai_status_t VirtualSwitchSaiInterface::objectTypeGetAvailability( } return SAI_STATUS_SUCCESS; } + else if (objectType == SAI_OBJECT_TYPE_NEXT_HOP_GROUP_MAP) + { + *count = 512; + return SAI_STATUS_SUCCESS; + } return SAI_STATUS_NOT_SUPPORTED; }