Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
cc155c6
Adding link event damping support
sivat6 May 22, 2026
23b1b0f
Revert "Adding link event damping support"
sivat6 May 22, 2026
93fdb1a
Adding link event damping support
sivat6 May 22, 2026
87532d6
Addressing review comments
sivat6 May 27, 2026
19280cf
Wrongly checked !=0 instead of ==0
sivat6 May 27, 2026
2994c4d
Fixing indentation issues
sivat6 May 27, 2026
ad9c7a5
Fix build errors
sivat6 May 28, 2026
9afd382
Fixing build error
sivat6 May 28, 2026
cd749d5
Fixing unit test failure
sivat6 May 28, 2026
c8346d2
Fixing white space error and missing SWSS_LOG_ENTER
sivat6 May 28, 2026
970d0db
Fixing dpkg dependency problems for libswsscommon
sivat6 May 28, 2026
4f5c4ba
Removing my changes in build-template.yml file
sivat6 May 29, 2026
ec4e09f
Fixing spell check failures
sivat6 May 29, 2026
c31cabd
Removing the fix added to build-swss-template.yml
sivat6 Jun 1, 2026
bc9def2
Adding more test cases to increase coverage
sivat6 Jun 1, 2026
2091034
Fixing the failed UT case
sivat6 Jun 1, 2026
9114102
Fixing the typo in the last commit
sivat6 Jun 1, 2026
cbe865b
Removing few test cases
sivat6 Jun 1, 2026
1e5a182
Removing similar tests
sivat6 Jun 2, 2026
e275429
Removing the notification from timer thread to main thread
sivat6 Jun 3, 2026
479f546
Test purpose to see PR# 1925 fixes current build issue
sivat6 Jun 3, 2026
a17d402
Remove the code of PR# 1925
sivat6 Jun 3, 2026
e162b57
Fixing build issue
sivat6 Jun 4, 2026
1b2802c
SWSS_LOG_ENTER missed in new API
sivat6 Jun 4, 2026
9a037f5
Adding suppress and reuse threshold invalid config check
sivat6 Jun 8, 2026
564e2b1
Adding tests to increase coverage
sivat6 Jun 9, 2026
a864f51
Added SWSS_LOG_ENTER() in the APIs in test file
sivat6 Jun 9, 2026
0e31ec1
Addressed review comments
sivat6 Jun 10, 2026
7401665
Addressed code review comments
sivat6 Jun 10, 2026
030fa7d
Adding tests under unittest and removing the unnecessary tests from s…
sivat6 Jun 11, 2026
0cce42b
Trigger pipeline
sivat6 Jun 11, 2026
8a2b883
Adding SWSS_LOG_ENTER()
sivat6 Jun 11, 2026
c59f614
Debugging the test case
sivat6 Jun 11, 2026
55d92c3
Tweaking some timing value in one test
sivat6 Jun 12, 2026
6fc0dd4
Tweaking params
sivat6 Jun 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/ClientSai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,8 @@ sai_status_t ClientSai::set(
SWSS_LOG_ENTER();
REDIS_CHECK_API_INITIALIZED();

if (RedisRemoteSaiInterface::isRedisAttribute(objectType, attr))
if (RedisRemoteSaiInterface::isRedisAttribute(objectType, attr) ||
RedisRemoteSaiInterface::isRedisPortAttribute(objectType, attr))
Comment thread
sivat6 marked this conversation as resolved.
{
SWSS_LOG_ERROR("sairedis extension attributes are not supported in CLIENT mode");

Expand Down
96 changes: 96 additions & 0 deletions lib/RedisRemoteSaiInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,83 @@ sai_status_t RedisRemoteSaiInterface::setRedisExtensionAttribute(
return SAI_STATUS_FAILURE;
}

sai_status_t RedisRemoteSaiInterface::setLinkEventDampingConfig(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId,
_In_ const std::vector<swss::FieldValueTuple> &values)
{
SWSS_LOG_ENTER();

std::string key = sai_serialize_object_type(objectType) + ":" + sai_serialize_object_id(objectId);

m_communicationChannel->set(key, values, REDIS_ASIC_STATE_COMMAND_DAMPING_CONFIG_SET);

if (m_syncMode)
{
swss::KeyOpFieldsValuesTuple kco;
auto status = m_communicationChannel->wait(REDIS_ASIC_STATE_COMMAND_DAMPING_CONFIG_SET, kco);

m_recorder->recordGenericSetResponse(status);

return status;
}

return SAI_STATUS_SUCCESS;
}

sai_status_t RedisRemoteSaiInterface::setRedisPortExtensionAttribute(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId,
_In_ const sai_attribute_t *attr)
{
SWSS_LOG_ENTER();

if (attr == nullptr)
{
SWSS_LOG_ERROR("attr pointer is null");

return SAI_STATUS_INVALID_PARAMETER;
}

std::string str_attr_id = sai_serialize_redis_port_attr_id(
static_cast<sai_redis_port_attr_t>(attr->id));

switch (attr->id)
{
case SAI_REDIS_PORT_ATTR_LINK_EVENT_DAMPING_ALGORITHM:
{
std::string str_attr_value = sai_serialize_redis_link_event_damping_algorithm(
static_cast<sai_redis_link_event_damping_algorithm_t>(attr->value.s32));

return setLinkEventDampingConfig(
objectType, objectId, {swss::FieldValueTuple(str_attr_id, str_attr_value)});
}
case SAI_REDIS_PORT_ATTR_LINK_EVENT_DAMPING_ALGO_AIED_CONFIG:
{
sai_redis_link_event_damping_algo_aied_config_t *config =
(sai_redis_link_event_damping_algo_aied_config_t *)attr->value.ptr;

if (config == NULL)
{
SWSS_LOG_ERROR("invalid link damping config attr value NULL");

return SAI_STATUS_INVALID_PARAMETER;
}

std::string str_attr_value = sai_serialize_redis_link_event_damping_aied_config(*config);

return setLinkEventDampingConfig(
objectType, objectId, {swss::FieldValueTuple(str_attr_id, str_attr_value)});
}
default:
break;
}

SWSS_LOG_ERROR("unknown redis port extension attribute: %d", attr->id);

return SAI_STATUS_INVALID_PARAMETER;
}

bool RedisRemoteSaiInterface::isSaiS8ListValidString(
_In_ const sai_s8_list_t &s8list)
{
Expand Down Expand Up @@ -666,6 +743,11 @@ sai_status_t RedisRemoteSaiInterface::set(
return setRedisExtensionAttribute(objectType, objectId, attr);
}

if (RedisRemoteSaiInterface::isRedisPortAttribute(objectType, attr))
{
return setRedisPortExtensionAttribute(objectType, objectId, attr);
}

auto status = set(
objectType,
sai_serialize_object_id(objectId),
Expand Down Expand Up @@ -2201,6 +2283,20 @@ bool RedisRemoteSaiInterface::isRedisAttribute(
return true;
}

bool RedisRemoteSaiInterface::isRedisPortAttribute(
_In_ sai_object_type_t objectType,
_In_ const sai_attribute_t* attr)
{
SWSS_LOG_ENTER();

if ((objectType != SAI_OBJECT_TYPE_PORT) || (attr == nullptr) || (attr->id < SAI_PORT_ATTR_CUSTOM_RANGE_START) || (attr->id >= SAI_PORT_ATTR_EXTENSIONS_RANGE_BASE))
{
return false;
}

return true;
}
Comment thread
sivat6 marked this conversation as resolved.

void RedisRemoteSaiInterface::handleNotification(
_In_ const std::string &name,
_In_ const std::string &serializedNotification,
Expand Down
19 changes: 19 additions & 0 deletions lib/RedisRemoteSaiInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,15 @@ namespace sairedis
_In_ sai_object_id_t switchId,
_In_ const sai_attribute_t* attr);

/**
* @brief Checks whether attribute is custom SAI_REDIS_PORT attribute.
*
* This function should only be used on port_api set function.
*/
static bool isRedisPortAttribute(
_In_ sai_object_type_t objectType,
_In_ const sai_attribute_t* attr);
Comment thread
sivat6 marked this conversation as resolved.

void setMeta(
_In_ std::weak_ptr<saimeta::Meta> meta);

Expand Down Expand Up @@ -401,6 +410,11 @@ namespace sairedis
_In_ sai_object_id_t objectId,
_In_ const sai_attribute_t *attr);

sai_status_t setRedisPortExtensionAttribute(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId,
_In_ const sai_attribute_t *attr);

bool isSaiS8ListValidString(
_In_ const sai_s8_list_t &s8list);

Expand Down Expand Up @@ -428,6 +442,11 @@ namespace sairedis
_In_ sai_object_id_t switchId,
_In_ const sai_attribute_t *attr);

sai_status_t setLinkEventDampingConfig(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId,
_In_ const std::vector<swss::FieldValueTuple> &values);

void clear_local_state();

sai_switch_notifications_t processNotification(
Expand Down
6 changes: 6 additions & 0 deletions lib/Sai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,12 @@ sai_status_t Sai::set(

REDIS_CHECK_CONTEXT(objectId);

if (RedisRemoteSaiInterface::isRedisPortAttribute(objectType, attr))
{
// skip metadata if attribute is redis extension port attribute.
return context->m_redisSai->set(objectType, objectId, attr);
}

return context->m_meta->set(objectType, objectId, attr);
}

Expand Down
2 changes: 2 additions & 0 deletions lib/sairediscommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
#define REDIS_ASIC_STATE_COMMAND_OBJECT_TYPE_GET_AVAILABILITY_QUERY "object_type_get_availability_query"
#define REDIS_ASIC_STATE_COMMAND_OBJECT_TYPE_GET_AVAILABILITY_RESPONSE "object_type_get_availability_response"

#define REDIS_ASIC_STATE_COMMAND_DAMPING_CONFIG_SET "link_event_damping_config_set"

#define REDIS_FLEX_COUNTER_COMMAND_START_POLL "start_poll"
#define REDIS_FLEX_COUNTER_COMMAND_STOP_POLL "stop_poll"
#define REDIS_FLEX_COUNTER_COMMAND_SET_GROUP "set_counter_group"
Expand Down
46 changes: 40 additions & 6 deletions syncd/NotificationProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ using namespace saimeta;
NotificationProcessor::NotificationProcessor(
_In_ std::shared_ptr<NotificationProducerBase> producer,
_In_ std::shared_ptr<BaseRedisClient> client,
_In_ std::function<void(const swss::KeyOpFieldsValuesTuple&)> synchronizer):
_In_ std::function<void(const swss::KeyOpFieldsValuesTuple&)> synchronizer,
_In_ std::function<bool(sai_object_id_t, sai_port_oper_status_t)> linkEventDampingApplier):
m_synchronizer(synchronizer),
m_linkEventDampingApplier(linkEventDampingApplier),
m_client(client),
m_notifications(producer)
{
Expand Down Expand Up @@ -494,6 +496,9 @@ void NotificationProcessor::process_on_port_state_change(

SWSS_LOG_DEBUG("port notification count: %u", count);

// Vector to store filtered notifications (after damping applied)
std::vector<sai_port_oper_status_notification_t> filtered_notifications;

for (uint32_t i = 0; i < count; i++)
{
sai_port_oper_status_notification_t *oper_stat = &data[i];
Expand All @@ -520,14 +525,43 @@ void NotificationProcessor::process_on_port_state_change(
* Port may be in process of removal. OA may receive notification for VID either
* SAI_NULL_OBJECT_ID or non exist at time of processing
*/
SWSS_LOG_INFO("Port VID %s state change notification: %s",
sai_serialize_object_id(oper_stat->port_id).c_str(),
sai_serialize_port_oper_status(oper_stat->port_state).c_str());

SWSS_LOG_INFO("Port VID %s state change notification",
sai_serialize_object_id(oper_stat->port_id).c_str());
}
// Apply link event damping if configured
bool should_suppress = false;
if (m_linkEventDampingApplier != nullptr && oper_stat->port_id != SAI_NULL_OBJECT_ID)
{
should_suppress = m_linkEventDampingApplier(oper_stat->port_id, oper_stat->port_state);
}

std::string s = sai_serialize_port_oper_status_ntf(count, data);
if (!should_suppress)
{
// Add to filtered notifications
filtered_notifications.push_back(*oper_stat);
SWSS_LOG_INFO("Port state change PROPAGATED: %s -> %s",
sai_serialize_object_id(oper_stat->port_id).c_str(),
sai_serialize_port_oper_status(oper_stat->port_state).c_str());
}
else
{
SWSS_LOG_INFO("Port state change SUPPRESSED by damping: %s -> %s",
sai_serialize_object_id(oper_stat->port_id).c_str(),
sai_serialize_port_oper_status(oper_stat->port_state).c_str());
}
}

sendNotification(SAI_SWITCH_NOTIFICATION_NAME_PORT_STATE_CHANGE, s);
// Send only non-suppressed (filtered) notifications
if (!filtered_notifications.empty())
{
std::string s = sai_serialize_port_oper_status_ntf((uint32_t)filtered_notifications.size(), filtered_notifications.data());
sendNotification(SAI_SWITCH_NOTIFICATION_NAME_PORT_STATE_CHANGE, s);
}
else
{
SWSS_LOG_DEBUG("All port state changes were suppressed by damping, no notification sent");
}
}

void NotificationProcessor::process_on_bfd_session_state_change(
Expand Down
9 changes: 8 additions & 1 deletion syncd/NotificationProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ namespace syncd
NotificationProcessor(
_In_ std::shared_ptr<NotificationProducerBase> producer,
_In_ std::shared_ptr<BaseRedisClient> client,
_In_ std::function<void(const swss::KeyOpFieldsValuesTuple&)> synchronizer);
_In_ std::function<void(const swss::KeyOpFieldsValuesTuple&)> synchronizer,
_In_ std::function<bool(sai_object_id_t, sai_port_oper_status_t)> linkEventDampingApplier = nullptr);

virtual ~NotificationProcessor();

Expand Down Expand Up @@ -211,6 +212,12 @@ namespace syncd

std::function<void(const swss::KeyOpFieldsValuesTuple&)> m_synchronizer;

/**
* @brief Callback function to apply link event damping to port state changes
* Returns true if notification should be suppressed, false if it should be propagated
*/
std::function<bool(sai_object_id_t, sai_port_oper_status_t)> m_linkEventDampingApplier;

std::shared_ptr<BaseRedisClient> m_client;

std::shared_ptr<NotificationProducerBase> m_notifications;
Expand Down
Loading
Loading