Skip to content

Commit

Permalink
[sai_redis_interface_query] Add sairedis support for sai_object_type_…
Browse files Browse the repository at this point in the history
…get_availability (#528)

* Add sai_object_type_get_availability to libsairedis
* Add handler for sai_object_type_get_availability to syncd
* Add sai_object_type_get_availability implementation to virtual switch

Signed-off-by: Danny Allen <daall@microsoft.com>
  • Loading branch information
daall authored and lguohan committed Oct 28, 2019
1 parent ff5306e commit d29760f
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/inc/sairedis.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ extern "C" {
#define ASIC_STATE_TABLE "ASIC_STATE"
#define TEMP_PREFIX "TEMP_"

// Messages for processing queries from libsairedis to syncd
const std::string attrEnumValuesCapabilityQuery("attr_enum_values_capability_query");
const std::string attrEnumValuesCapabilityResponse("attr_enum_values_capability_response");
const std::string objectTypeGetAvailabilityQuery("object_type_get_availability_query");
const std::string objectTypeGetAvailabilityResponse("object_type_get_availability_response");

typedef enum _sai_redis_notify_syncd_t
{
Expand Down
117 changes: 117 additions & 0 deletions lib/src/sai_redis_interfacequery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "sairedis.h"

#include "meta/sai_serialize.h"
#include "meta/saiattributelist.h"

#include "swss/selectableevent.h"
#include <string.h>
Expand Down Expand Up @@ -410,3 +411,119 @@ sai_status_t sai_query_attribute_enum_values_capability(
SWSS_LOG_ERROR("Failed to receive a response from syncd");
return SAI_STATUS_FAILURE;
}

sai_status_t sai_object_type_get_availability(
_In_ sai_object_id_t switch_id,
_In_ sai_object_type_t object_type,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list,
_Out_ uint64_t *count)
{
MUTEX();

SWSS_LOG_ENTER();

const std::string switch_id_str = sai_serialize_object_id(switch_id);
const std::string object_type_str = sai_serialize_object_type(object_type);
std::vector<swss::FieldValueTuple> query_arguments = SaiAttributeList::serialize_attr_list(
object_type,
attr_count,
attr_list,
false);

SWSS_LOG_DEBUG(
"Query arguments: switch: %s, object type: %s, attributes: %s",
switch_id_str.c_str(),
object_type_str.c_str(),
joinFieldValues(query_arguments).c_str()
);

// Syncd will pop this argument off before trying to deserialize the attribute list
query_arguments.push_back(swss::FieldValueTuple("OBJECT_TYPE", object_type_str));

if (g_record)
{
recordLine("q|object_type_get_availability|" + switch_id_str + "|" + joinFieldValues(query_arguments));
}

// This query will not put any data into the ASIC view, just into the
// message queue
g_asicState->set(switch_id_str, query_arguments, objectTypeGetAvailabilityQuery);

swss::Select callback;
callback.addSelectable(g_redisGetConsumer.get());

while (true)
{
SWSS_LOG_DEBUG("Waiting for a response");

swss::Selectable *sel;

auto result = callback.select(&sel, GET_RESPONSE_TIMEOUT);

if (result == swss::Select::OBJECT)
{
swss::KeyOpFieldsValuesTuple kco;

g_redisGetConsumer->pop(kco);

const std::string &message_type = kfvOp(kco);
const std::string &status_str = kfvKey(kco);

SWSS_LOG_DEBUG("Received response: op = %s, key = %s", message_type.c_str(), status_str.c_str());

// Ignore messages that are not in response to our query
if (message_type != objectTypeGetAvailabilityResponse)
{
continue;
}

sai_status_t status;
sai_deserialize_status(status_str, status);

if (status == SAI_STATUS_SUCCESS)
{
const std::vector<swss::FieldValueTuple> &values = kfvFieldsValues(kco);

if (values.size() != 1)
{
if (g_record)
{
recordLine("Q|object_type_get_availability|SAI_STATUS_FAILURE");
}

SWSS_LOG_ERROR("Invalid response from syncd: expected 1 value, received %d", values.size());
return SAI_STATUS_FAILURE;
}

const std::string &availability_str = fvValue(values[0]);
*count = std::stol(availability_str);

SWSS_LOG_DEBUG("Received payload: count = %lu", *count);

if (g_record)
{
recordLine("Q|object_type_get_availability|" + status_str + "|" + joinFieldValues(values));
}
}
else
{
if (g_record)
{
recordLine("Q|object_type_get_availability|" + status_str);
}
}

SWSS_LOG_DEBUG("Status: %s", status_str.c_str());
return status;
}
}

if (g_record)
{
recordLine("Q|object_type_get_availability|SAI_STATUS_FAILURE");
}

SWSS_LOG_ERROR("Failed to receive a response from syncd");
return SAI_STATUS_FAILURE;
}
55 changes: 55 additions & 0 deletions syncd/syncd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2933,6 +2933,57 @@ sai_status_t processAttrEnumValuesCapabilityQuery(
return status;
}

sai_status_t processObjectTypeGetAvailabilityQuery(
_In_ const swss::KeyOpFieldsValuesTuple &kco)
{
SWSS_LOG_ENTER();

const std::string &switch_str_id = kfvKey(kco);

sai_object_id_t switch_vid;
sai_deserialize_object_id(switch_str_id, switch_vid);

const sai_object_id_t switch_rid = translate_vid_to_rid(switch_vid);

std::vector<swss::FieldValueTuple> values = kfvFieldsValues(kco);

// Syncd needs to pop the object type off the end of the list in order to
// retrieve the attribute list
sai_object_type_t object_type;
sai_deserialize_object_type(fvValue(values.back()), object_type);
values.pop_back();

SaiAttributeList attr_list(object_type, values, false);

sai_attribute_t *sai_attr_list = attr_list.get_attr_list();
uint32_t attr_count = attr_list.get_attr_count();

translate_vid_to_rid_list(object_type, attr_count, sai_attr_list);

uint64_t count;
sai_status_t status = sai_object_type_get_availability(
switch_rid,
object_type,
attr_count,
sai_attr_list,
&count);

std::vector<swss::FieldValueTuple> response_payload;

if (status == SAI_STATUS_SUCCESS)
{
response_payload =
{
swss::FieldValueTuple("OBJECT_COUNT", std::to_string(count))
};

SWSS_LOG_DEBUG("Sending response: count = %lu", count);
}

getResponse->set(sai_serialize_status(status), response_payload, objectTypeGetAvailabilityResponse);
return status;
}

sai_status_t processEvent(
_In_ swss::ConsumerTable &consumer)
{
Expand Down Expand Up @@ -3029,6 +3080,10 @@ sai_status_t processEvent(
{
return processAttrEnumValuesCapabilityQuery(kco);
}
else if (op == objectTypeGetAvailabilityQuery)
{
return processObjectTypeGetAvailabilityQuery(kco);
}
else
{
SWSS_LOG_THROW("api '%s' is not implemented", op.c_str());
Expand Down
8 changes: 8 additions & 0 deletions tests/brcm.pl
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,13 @@ sub test_brcm_query_attr_enum_values_capability
play "query_attr_enum_values_capability.rec";
}

sub test_brcm_query_object_type_get_availability
{
fresh_start;

play "query_object_type_get_availability.rec";
}

# RUN TESTS

test_brcm_warm_boot_port_remove;
Expand Down Expand Up @@ -576,5 +583,6 @@ sub test_brcm_query_attr_enum_values_capability
test_brcm_full_to_empty_hostif_remove_segfault;
test_brcm_full_to_empty_no_queue_no_ipg_no_buffer_profile;
test_brcm_query_attr_enum_values_capability;
test_brcm_query_object_type_get_availability;

kill_syncd;
13 changes: 13 additions & 0 deletions tests/brcm/query_object_type_get_availability.rec
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
2019-10-25.17:56:23.794105|a|INIT_VIEW
2019-10-25.17:56:23.795120|A|SAI_STATUS_SUCCESS
2019-10-25.17:56:23.795362|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
2019-10-25.17:56:24.786816|q|object_type_get_availability|oid:0x21000000000000|SAI_DEBUG_COUNTER_ATTR_TYPE=SAI_DEBUG_COUNTER_TYPE_SWITCH_IN_DROP_REASONS|OBJECT_TYPE=SAI_OBJECT_TYPE_DEBUG_COUNTER
2019-10-25.17:56:24.789781|Q|object_type_get_availability|SAI_STATUS_SUCCESS|OBJECT_COUNT=3
2019-10-25.17:56:24.792839|q|object_type_get_availability|oid:0x21000000000000|SAI_DEBUG_COUNTER_ATTR_TYPE=SAI_DEBUG_COUNTER_TYPE_PORT_OUT_DROP_REASONS|OBJECT_TYPE=SAI_OBJECT_TYPE_DEBUG_COUNTER
2019-10-25.17:56:24.794665|Q|object_type_get_availability|SAI_STATUS_SUCCESS|OBJECT_COUNT=3
2019-10-25.17:56:24.795255|q|object_type_get_availability|oid:0x21000000000000|SAI_DEBUG_COUNTER_ATTR_TYPE=SAI_DEBUG_COUNTER_TYPE_SWITCH_OUT_DROP_REASONS|OBJECT_TYPE=SAI_OBJECT_TYPE_DEBUG_COUNTER
2019-10-25.17:56:24.796390|Q|object_type_get_availability|SAI_STATUS_SUCCESS|OBJECT_COUNT=3
2019-10-25.17:56:24.796704|q|object_type_get_availability|oid:0x21000000000000|SAI_DEBUG_COUNTER_ATTR_TYPE=SAI_DEBUG_COUNTER_TYPE_PORT_IN_DROP_REASONS|OBJECT_TYPE=SAI_OBJECT_TYPE_DEBUG_COUNTER
2019-10-25.17:56:24.797838|Q|object_type_get_availability|SAI_STATUS_SUCCESS|OBJECT_COUNT=3
2019-10-25.17:56:24.807699|a|APPLY_VIEW
2019-10-25.17:56:24.808521|A|SAI_STATUS_SUCCESS
19 changes: 19 additions & 0 deletions vslib/src/sai_vs_interfacequery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -963,3 +963,22 @@ sai_status_t sai_query_attribute_enum_values_capability(
return SAI_STATUS_NOT_SUPPORTED;
}
}

sai_status_t sai_object_type_get_availability(
_In_ sai_object_id_t switch_id,
_In_ sai_object_type_t object_type,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list,
_Out_ uint64_t *count)
{
SWSS_LOG_ENTER();

// TODO: We should generate this metadata for the virtual switch rather than hard-coding it here.
if (object_type == SAI_OBJECT_TYPE_DEBUG_COUNTER)
{
*count = 3;
return SAI_STATUS_SUCCESS;
}

return SAI_STATUS_NOT_SUPPORTED;
}

0 comments on commit d29760f

Please sign in to comment.