Skip to content

Commit

Permalink
[cbf] Add Class Based Forwarding support
Browse files Browse the repository at this point in the history
* Added support for MAP_LIST serialization and deserialization

* Added a UT to validate the changes

* Add NHG map API implementation

* Add VS object availability for NHG maps

Signed-off-by: Alexandru Banu <[email protected]>
  • Loading branch information
abanu-ms committed Aug 27, 2021
1 parent 1020de7 commit e9b43a4
Show file tree
Hide file tree
Showing 7 changed files with 206 additions and 3 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@ If you do not have libsai, you can build a debian package using:
./autogen.sh
fakeroot debian/rules binary-syncd-vs

#### Run meta UTs

The unit tests from the meta directory run during the build process, but can also be triggered manually. After building is done, go to the meta directory and run either:

make check

or directly:

./tests

to run the unit tests. The tests might complain about some missing libraries, which can be found under meta/.libs/ - just create some symbolic links to the libraries under /usr/lib.

## Need Help?

For general questions, setup help, or troubleshooting:
Expand Down
3 changes: 3 additions & 0 deletions lib/sai_redis_nexthopgroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ REDIS_BULK_CREATE(NEXT_HOP_GROUP_MEMBER,next_hop_group_members);
REDIS_BULK_REMOVE(NEXT_HOP_GROUP_MEMBER,next_hop_group_members);
REDIS_GENERIC_QUAD(NEXT_HOP_GROUP,next_hop_group);
REDIS_GENERIC_QUAD(NEXT_HOP_GROUP_MEMBER,next_hop_group_member);
REDIS_GENERIC_QUAD(NEXT_HOP_GROUP_MAP,next_hop_group_map);

const sai_next_hop_group_api_t redis_next_hop_group_api = {

Expand All @@ -12,4 +13,6 @@ const sai_next_hop_group_api_t redis_next_hop_group_api = {

redis_bulk_create_next_hop_group_members,
redis_bulk_remove_next_hop_group_members,

REDIS_GENERIC_QUAD_API(next_hop_group_map)
};
15 changes: 15 additions & 0 deletions meta/Meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3519,6 +3519,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:
Expand Down Expand Up @@ -4700,6 +4701,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;
Expand Down Expand Up @@ -5362,6 +5366,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;
Expand Down Expand Up @@ -5764,6 +5771,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;
Expand Down Expand Up @@ -6003,6 +6013,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;
Expand Down Expand Up @@ -6920,6 +6933,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:
Expand Down Expand Up @@ -7157,6 +7171,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:
Expand Down
118 changes: 118 additions & 0 deletions meta/SaiSerialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,10 @@ sai_status_t transfer_attribute(
RETURN_ON_ERROR(transfer_list(src_attr.value.qosmap, dst_attr.value.qosmap, countOnly));
break;

case SAI_ATTR_VALUE_TYPE_MAP_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.maplist, dst_attr.value.maplist, countOnly));
break;

case SAI_ATTR_VALUE_TYPE_ACL_RESOURCE_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.aclresource, dst_attr.value.aclresource, countOnly));
break;
Expand Down Expand Up @@ -1175,6 +1179,7 @@ static json sai_serialize_qos_map_params(
j["pg"] = params.pg;
j["qidx"] = params.queue_index;
j["mpls_exp"] = params.mpls_exp;
j["fc"] = params.fc;
j["color"] = sai_serialize_packet_color(params.color);

return j;
Expand Down Expand Up @@ -1237,6 +1242,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)
{
Expand Down Expand Up @@ -1609,6 +1658,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);

Expand Down Expand Up @@ -2366,6 +2418,16 @@ static void sai_deserialize_qos_map_params(
params.mpls_exp = j["mpls_exp"];
}

if (j.find("fc") == j.end())
{
// for backward compatibility
params.fc = 0;
}
else
{
params.fc = j["fc"];
}

sai_deserialize_packet_color(j["color"], params.color);
}

Expand All @@ -2379,6 +2441,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,
Expand Down Expand Up @@ -2418,6 +2490,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)
Expand Down Expand Up @@ -2998,6 +3109,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);

Expand Down Expand Up @@ -3620,6 +3734,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;
Expand Down
53 changes: 50 additions & 3 deletions meta/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3762,6 +3762,50 @@ void test_serialize_acl_action()
ASSERT_TRUE(s, "77");
}

void test_serialize_map()
{
SWSS_LOG_ENTER();

clear_local();

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 = &map;

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}]}";

ASSERT_TRUE(s, ret);

s = sai_serialize_attr_value(*meta, attr, true);

std::string ret2 = "{\"count\":1,\"list\":null}";
ASSERT_TRUE(s, ret2);

// deserialize

memset(&attr, 0, sizeof(attr));

sai_deserialize_attr_value(ret, *meta, attr);

ASSERT_TRUE(attr.value.maplist.count, 1);

auto &l = attr.value.maplist.list[0];
ASSERT_TRUE(l.key, 1);

ASSERT_TRUE(l.value, 11);
}

void test_serialize_qos_map()
{
SWSS_LOG_ENTER();
Expand All @@ -3775,8 +3819,8 @@ void test_serialize_qos_map()
attr.id = SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST;

sai_qos_map_t qm = {
.key = { .tc = 1, .dscp = 2, .dot1p = 3, .prio = 4, .pg = 5, .queue_index = 6, .color = SAI_PACKET_COLOR_RED, .mpls_exp = 0 },
.value = { .tc = 11, .dscp = 22, .dot1p = 33, .prio = 44, .pg = 55, .queue_index = 66, .color = SAI_PACKET_COLOR_GREEN, .mpls_exp = 0 } };
.key = { .tc = 1, .dscp = 2, .dot1p = 3, .prio = 4, .pg = 5, .queue_index = 6, .color = SAI_PACKET_COLOR_RED, .mpls_exp = 0, .fc = 0 },
.value = { .tc = 11, .dscp = 22, .dot1p = 33, .prio = 44, .pg = 55, .queue_index = 66, .color = SAI_PACKET_COLOR_GREEN, .mpls_exp = 0, .fc = 0 } };

attr.value.qosmap.count = 1;
attr.value.qosmap.list = &qm;
Expand All @@ -3785,7 +3829,7 @@ void test_serialize_qos_map()

s = sai_serialize_attr_value(*meta, attr);

std::string ret = "{\"count\":1,\"list\":[{\"key\":{\"color\":\"SAI_PACKET_COLOR_RED\",\"dot1p\":3,\"dscp\":2,\"mpls_exp\":0,\"pg\":5,\"prio\":4,\"qidx\":6,\"tc\":1},\"value\":{\"color\":\"SAI_PACKET_COLOR_GREEN\",\"dot1p\":33,\"dscp\":22,\"mpls_exp\":0,\"pg\":55,\"prio\":44,\"qidx\":66,\"tc\":11}}]}";
std::string ret = "{\"count\":1,\"list\":[{\"key\":{\"color\":\"SAI_PACKET_COLOR_RED\",\"dot1p\":3,\"dscp\":2,\"fc\":0,\"mpls_exp\":0,\"pg\":5,\"prio\":4,\"qidx\":6,\"tc\":1},\"value\":{\"color\":\"SAI_PACKET_COLOR_GREEN\",\"dot1p\":33,\"dscp\":22,\"fc\":0,\"mpls_exp\":0,\"pg\":55,\"prio\":44,\"qidx\":66,\"tc\":11}}]}";

ASSERT_TRUE(s, ret);

Expand All @@ -3811,6 +3855,7 @@ void test_serialize_qos_map()
ASSERT_TRUE(l.key.queue_index, 6);
ASSERT_TRUE(l.key.color, SAI_PACKET_COLOR_RED);
ASSERT_TRUE(l.key.mpls_exp, 0);
ASSERT_TRUE(l.key.fc, 0);

ASSERT_TRUE(l.value.tc, 11);
ASSERT_TRUE(l.value.dscp, 22);
Expand All @@ -3820,6 +3865,7 @@ void test_serialize_qos_map()
ASSERT_TRUE(l.value.queue_index, 66);
ASSERT_TRUE(l.value.color, SAI_PACKET_COLOR_GREEN);
ASSERT_TRUE(l.value.mpls_exp, 0);
ASSERT_TRUE(l.value.fc, 0);
}

template<typename T>
Expand Down Expand Up @@ -3994,6 +4040,7 @@ int main()
test_serialize_oid();
test_serialize_oid_list();
test_serialize_acl_action();
test_serialize_map();
test_serialize_qos_map();

// attributes tests
Expand Down
5 changes: 5 additions & 0 deletions vslib/VirtualSwitchSaiInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Loading

0 comments on commit e9b43a4

Please sign in to comment.