Skip to content

Commit ff5306e

Browse files
daalllguohan
authored andcommitted
[sai_redis_interface_query] Add sairedis support for sai_query_attribute_enum_values_capability (#525)
* [sai_redis_interface_query] Add sairedis support for sai_query_attribute_enum_values_capability * Add sai_query_attribute_enum_values_capability to libsairedis * Add handler for sai_query_attribute_enum_values_capability to syncd * Add sai_query_attribute_enum_values_capability implementation to virtual switch Signed-off-by: Danny Allen <[email protected]>
1 parent d9faa58 commit ff5306e

File tree

7 files changed

+289
-0
lines changed

7 files changed

+289
-0
lines changed

lib/inc/sairedis.h

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ extern "C" {
1111
#define ASIC_STATE_TABLE "ASIC_STATE"
1212
#define TEMP_PREFIX "TEMP_"
1313

14+
const std::string attrEnumValuesCapabilityQuery("attr_enum_values_capability_query");
15+
const std::string attrEnumValuesCapabilityResponse("attr_enum_values_capability_response");
16+
1417
typedef enum _sai_redis_notify_syncd_t
1518
{
1619
SAI_REDIS_NOTIFY_SYNCD_INIT_VIEW,

lib/src/sai_redis_interfacequery.cpp

+152
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "sai_redis.h"
22
#include "sairedis.h"
33

4+
#include "meta/sai_serialize.h"
5+
46
#include "swss/selectableevent.h"
57
#include <string.h>
68

@@ -258,3 +260,153 @@ sai_status_t sai_api_query(
258260
return SAI_STATUS_INVALID_PARAMETER;
259261
}
260262
}
263+
264+
sai_status_t sai_query_attribute_enum_values_capability(
265+
_In_ sai_object_id_t switch_id,
266+
_In_ sai_object_type_t object_type,
267+
_In_ sai_attr_id_t attr_id,
268+
_Inout_ sai_s32_list_t *enum_values_capability)
269+
{
270+
MUTEX();
271+
272+
SWSS_LOG_ENTER();
273+
274+
const std::string switch_id_str = sai_serialize_object_id(switch_id);
275+
const std::string object_type_str = sai_serialize_object_type(object_type);
276+
277+
auto meta = sai_metadata_get_attr_metadata(object_type, attr_id);
278+
if (meta == NULL)
279+
{
280+
SWSS_LOG_ERROR("Failed to find attribute metadata: object type %s, attr id %d", object_type_str.c_str(), attr_id);
281+
return SAI_STATUS_INVALID_PARAMETER;
282+
}
283+
284+
const std::string attr_id_str = sai_serialize_attr_id(*meta);
285+
const std::string list_size = std::to_string(enum_values_capability->count);
286+
287+
const std::vector<swss::FieldValueTuple> query_arguments =
288+
{
289+
swss::FieldValueTuple("OBJECT_TYPE", object_type_str),
290+
swss::FieldValueTuple("ATTR_ID", attr_id_str),
291+
swss::FieldValueTuple("LIST_SIZE", list_size)
292+
};
293+
294+
SWSS_LOG_DEBUG(
295+
"Query arguments: switch %s, object type: %s, attribute: %s, count: %s",
296+
switch_id_str.c_str(),
297+
object_type_str.c_str(),
298+
attr_id_str.c_str(),
299+
list_size.c_str()
300+
);
301+
302+
if (g_record)
303+
{
304+
recordLine("q|attribute_enum_values_capability|" + switch_id_str + "|" + joinFieldValues(query_arguments));
305+
}
306+
307+
// This query will not put any data into the ASIC view, just into the
308+
// message queue
309+
g_asicState->set(switch_id_str, query_arguments, attrEnumValuesCapabilityQuery);
310+
311+
swss::Select callback;
312+
callback.addSelectable(g_redisGetConsumer.get());
313+
314+
while (true)
315+
{
316+
SWSS_LOG_DEBUG("Waiting for a response");
317+
318+
swss::Selectable *sel;
319+
320+
auto result = callback.select(&sel, GET_RESPONSE_TIMEOUT);
321+
322+
if (result == swss::Select::OBJECT)
323+
{
324+
swss::KeyOpFieldsValuesTuple kco;
325+
326+
g_redisGetConsumer->pop(kco);
327+
328+
const std::string &message_type = kfvOp(kco);
329+
const std::string &status_str = kfvKey(kco);
330+
331+
SWSS_LOG_DEBUG("Received response: op = %s, key = %s", message_type.c_str(), status_str.c_str());
332+
333+
// Ignore messages that are not in response to our query
334+
if (message_type != attrEnumValuesCapabilityResponse)
335+
{
336+
continue;
337+
}
338+
339+
sai_status_t status;
340+
sai_deserialize_status(status_str, status);
341+
342+
if (status == SAI_STATUS_SUCCESS)
343+
{
344+
const std::vector<swss::FieldValueTuple> &values = kfvFieldsValues(kco);
345+
346+
if (values.size() != 2)
347+
{
348+
if (g_record)
349+
{
350+
recordLine("Q|attribute_enum_values_capability|SAI_STATUS_FAILURE");
351+
}
352+
353+
SWSS_LOG_ERROR("Invalid response from syncd: expected 2 values, received %d", values.size());
354+
return SAI_STATUS_FAILURE;
355+
}
356+
357+
const std::string &capability_str = fvValue(values[0]);
358+
const uint32_t num_capabilities = std::stoi(fvValue(values[1]));
359+
360+
SWSS_LOG_DEBUG("Received payload: capabilites = '%s', count = %d", capability_str.c_str(), num_capabilities);
361+
362+
enum_values_capability->count = num_capabilities;
363+
364+
size_t position = 0;
365+
for (uint32_t i = 0; i < num_capabilities; i++)
366+
{
367+
size_t old_position = position;
368+
position = capability_str.find(",", old_position);
369+
std::string capability = capability_str.substr(old_position, position - old_position);
370+
enum_values_capability->list[i] = std::stoi(capability);
371+
372+
// We have run out of values to add to our list
373+
if (position == std::string::npos)
374+
{
375+
if (num_capabilities != i + 1)
376+
{
377+
SWSS_LOG_WARN("Query returned less attributes than expected: expected %d, recieved %d");
378+
}
379+
380+
break;
381+
}
382+
383+
// Skip the commas
384+
position++;
385+
}
386+
387+
if (g_record)
388+
{
389+
recordLine("Q|attribute_enum_values_capability|" + status_str + "|" + joinFieldValues(values));
390+
}
391+
}
392+
else
393+
{
394+
if (g_record)
395+
{
396+
recordLine("Q|attribute_enum_values_capability|" + status_str);
397+
}
398+
}
399+
400+
SWSS_LOG_DEBUG("Status: %s", status_str.c_str());
401+
return status;
402+
}
403+
}
404+
405+
if (g_record)
406+
{
407+
recordLine("Q|attribute_enum_values_capability|SAI_STATUS_FAILURE");
408+
}
409+
410+
SWSS_LOG_ERROR("Failed to receive a response from syncd");
411+
return SAI_STATUS_FAILURE;
412+
}

saiplayer/saiplayer.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,11 @@ int replay(int argc, char **argv)
12101210
case 'g':
12111211
api = SAI_COMMON_API_GET;
12121212
break;
1213+
case 'q':
1214+
// TODO: implement SAI player support for query commands
1215+
continue;
1216+
case 'Q':
1217+
continue; // skip over query responses
12131218
case '#':
12141219
case 'n':
12151220
continue; // skip comment and notification

syncd/syncd.cpp

+70
Original file line numberDiff line numberDiff line change
@@ -2867,6 +2867,72 @@ sai_status_t processFdbFlush(
28672867
return status;
28682868
}
28692869

2870+
sai_status_t processAttrEnumValuesCapabilityQuery(
2871+
_In_ const swss::KeyOpFieldsValuesTuple &kco)
2872+
{
2873+
SWSS_LOG_ENTER();
2874+
2875+
const std::string &switch_str_id = kfvKey(kco);
2876+
2877+
sai_object_id_t switch_vid;
2878+
sai_deserialize_object_id(switch_str_id, switch_vid);
2879+
2880+
const sai_object_id_t switch_rid = translate_vid_to_rid(switch_vid);
2881+
2882+
const std::vector<swss::FieldValueTuple> &values = kfvFieldsValues(kco);
2883+
2884+
if (values.size() != 3)
2885+
{
2886+
SWSS_LOG_ERROR("Invalid input: expected 3 arguments, received %d", values.size());
2887+
getResponse->set(sai_serialize_status(SAI_STATUS_INVALID_PARAMETER), {}, attrEnumValuesCapabilityResponse);
2888+
return SAI_STATUS_INVALID_PARAMETER;
2889+
}
2890+
2891+
sai_object_type_t object_type;
2892+
sai_deserialize_object_type(fvValue(values[0]), object_type);
2893+
2894+
sai_attr_id_t attr_id;
2895+
sai_deserialize_attr_id(fvValue(values[1]), attr_id);
2896+
2897+
const uint32_t list_size = std::stoi(fvValue(values[2]));
2898+
std::vector<int32_t> enum_capabilities_list(list_size);
2899+
2900+
sai_s32_list_t enum_values_capability;
2901+
enum_values_capability.count = list_size;
2902+
enum_values_capability.list = enum_capabilities_list.data();
2903+
2904+
sai_status_t status = sai_query_attribute_enum_values_capability(switch_rid, object_type, attr_id, &enum_values_capability);
2905+
2906+
std::vector<swss::FieldValueTuple> response_payload;
2907+
2908+
if (status == SAI_STATUS_SUCCESS)
2909+
{
2910+
std::string serialized_enum_capabilities;
2911+
for (uint32_t i = 0; i < enum_values_capability.count; i++)
2912+
{
2913+
// We will remove the leading comma before sending the response
2914+
serialized_enum_capabilities += ',';
2915+
serialized_enum_capabilities += std::to_string(enum_capabilities_list[i]);
2916+
}
2917+
2918+
if (!serialized_enum_capabilities.empty())
2919+
{
2920+
serialized_enum_capabilities = serialized_enum_capabilities.substr(1);
2921+
}
2922+
2923+
response_payload =
2924+
{
2925+
swss::FieldValueTuple("ENUM_CAPABILITIES", serialized_enum_capabilities),
2926+
swss::FieldValueTuple("ENUM_COUNT", std::to_string(enum_values_capability.count))
2927+
};
2928+
2929+
SWSS_LOG_DEBUG("Sending response: capabilities = '%s', count = %d", serialized_enum_capabilities.substr(1).c_str(), enum_values_capability.count);
2930+
}
2931+
2932+
getResponse->set(sai_serialize_status(status), response_payload, attrEnumValuesCapabilityResponse);
2933+
return status;
2934+
}
2935+
28702936
sai_status_t processEvent(
28712937
_In_ swss::ConsumerTable &consumer)
28722938
{
@@ -2959,6 +3025,10 @@ sai_status_t processEvent(
29593025
{
29603026
return processFdbFlush(kco);
29613027
}
3028+
else if (op == attrEnumValuesCapabilityQuery)
3029+
{
3030+
return processAttrEnumValuesCapabilityQuery(kco);
3031+
}
29623032
else
29633033
{
29643034
SWSS_LOG_THROW("api '%s' is not implemented", op.c_str());

tests/brcm.pl

+8
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,13 @@ sub test_brcm_warm_boot_port_create
518518
request_warm_shutdown;
519519
}
520520

521+
sub test_brcm_query_attr_enum_values_capability
522+
{
523+
fresh_start;
524+
525+
play "query_attr_enum_values_capability.rec";
526+
}
527+
521528
# RUN TESTS
522529

523530
test_brcm_warm_boot_port_remove;
@@ -568,5 +575,6 @@ sub test_brcm_warm_boot_port_create
568575
test_brcm_full_to_empty_no_queue_no_ipg;
569576
test_brcm_full_to_empty_hostif_remove_segfault;
570577
test_brcm_full_to_empty_no_queue_no_ipg_no_buffer_profile;
578+
test_brcm_query_attr_enum_values_capability;
571579

572580
kill_syncd;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2019-10-25.04:21:31.884173|a|INIT_VIEW
2+
2019-10-25.04:21:31.884636|A|SAI_STATUS_SUCCESS
3+
2019-10-25.04:21:31.884882|c|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_INIT_SWITCH=true|SAI_SWITCH_ATTR_SRC_MAC_ADDRESS=02:42:AC:11:00:02
4+
2019-10-25.04:21:32.853334|q|attribute_enum_values_capability|oid:0x21000000000000|OBJECT_TYPE=SAI_OBJECT_TYPE_DEBUG_COUNTER|ATTR_ID=SAI_DEBUG_COUNTER_ATTR_IN_DROP_REASON_LIST|LIST_SIZE=100
5+
2019-10-25.04:21:32.854651|Q|attribute_enum_values_capability|SAI_STATUS_SUCCESS|ENUM_CAPABILITIES=0,11,41|ENUM_COUNT=3
6+
2019-10-25.04:21:32.854730|q|attribute_enum_values_capability|oid:0x21000000000000|OBJECT_TYPE=SAI_OBJECT_TYPE_DEBUG_COUNTER|ATTR_ID=SAI_DEBUG_COUNTER_ATTR_OUT_DROP_REASON_LIST|LIST_SIZE=100
7+
2019-10-25.04:21:32.855398|Q|attribute_enum_values_capability|SAI_STATUS_SUCCESS|ENUM_CAPABILITIES=0,2|ENUM_COUNT=2
8+
2019-10-25.04:21:32.862373|a|APPLY_VIEW
9+
2019-10-25.04:21:32.863487|A|SAI_STATUS_SUCCESS

vslib/src/sai_vs_interfacequery.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -921,3 +921,45 @@ sai_status_t sai_api_query(
921921
return SAI_STATUS_INVALID_PARAMETER;
922922
}
923923
}
924+
925+
sai_status_t sai_query_attribute_enum_values_capability(
926+
_In_ sai_object_id_t switch_id,
927+
_In_ sai_object_type_t object_type,
928+
_In_ sai_attr_id_t attr_id,
929+
_Inout_ sai_s32_list_t *enum_values_capability)
930+
{
931+
SWSS_LOG_ENTER();
932+
933+
// TODO: We should generate this metadata for the virtual switch rather than hard-coding it here.
934+
if (object_type == SAI_OBJECT_TYPE_DEBUG_COUNTER && attr_id == SAI_DEBUG_COUNTER_ATTR_IN_DROP_REASON_LIST)
935+
{
936+
if (enum_values_capability->count < 3)
937+
{
938+
return SAI_STATUS_BUFFER_OVERFLOW;
939+
}
940+
941+
enum_values_capability->count = 3;
942+
enum_values_capability->list[0] = SAI_IN_DROP_REASON_L2_ANY;
943+
enum_values_capability->list[1] = SAI_IN_DROP_REASON_L3_ANY;
944+
enum_values_capability->list[2] = SAI_IN_DROP_REASON_ACL_ANY;
945+
946+
return SAI_STATUS_SUCCESS;
947+
}
948+
else if (object_type == SAI_OBJECT_TYPE_DEBUG_COUNTER && attr_id == SAI_DEBUG_COUNTER_ATTR_OUT_DROP_REASON_LIST)
949+
{
950+
if (enum_values_capability->count < 2)
951+
{
952+
return SAI_STATUS_BUFFER_OVERFLOW;
953+
}
954+
955+
enum_values_capability->count = 2;
956+
enum_values_capability->list[0] = SAI_OUT_DROP_REASON_L2_ANY;
957+
enum_values_capability->list[1] = SAI_OUT_DROP_REASON_L3_ANY;
958+
959+
return SAI_STATUS_SUCCESS;
960+
}
961+
else
962+
{
963+
return SAI_STATUS_NOT_SUPPORTED;
964+
}
965+
}

0 commit comments

Comments
 (0)