Skip to content

Commit

Permalink
Add support for BFD notification (#903)
Browse files Browse the repository at this point in the history
Add sairedis and syncd support to handle and send back BFD session state change notifications.
  • Loading branch information
shi-su authored Aug 25, 2021
1 parent 6ff9100 commit 5349a9d
Show file tree
Hide file tree
Showing 22 changed files with 428 additions and 2 deletions.
5 changes: 5 additions & 0 deletions lib/Switch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ void Switch::updateNotifications(
(sai_queue_pfc_deadlock_notification_fn)attr.value.ptr;
break;

case SAI_SWITCH_ATTR_BFD_SESSION_STATE_CHANGE_NOTIFY:
m_switchNotifications.on_bfd_session_state_change =
(sai_bfd_session_state_change_notification_fn)attr.value.ptr;
break;

default:
SWSS_LOG_ERROR("pointer for %s is not handled, FIXME!", meta->attridname);
break;
Expand Down
1 change: 1 addition & 0 deletions meta/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ libsaimeta_la_SOURCES = \
NotificationQueuePfcDeadlock.cpp \
NotificationSwitchShutdownRequest.cpp \
NotificationSwitchStateChange.cpp \
NotificationBfdSessionStateChange.cpp \
OidRefCounter.cpp \
PerformanceIntervalTimer.cpp \
PortRelatedSet.cpp \
Expand Down
59 changes: 59 additions & 0 deletions meta/Meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7745,6 +7745,65 @@ void Meta::meta_sai_on_queue_pfc_deadlock_notification(
}
}

void Meta::meta_sai_on_bfd_session_state_change_single(
_In_ const sai_bfd_session_state_notification_t& data)
{
SWSS_LOG_ENTER();

auto ot = objectTypeQuery(data.bfd_session_id);

bool valid = false;

switch (ot)
{
// TODO hardcoded types, must advance SAI repository commit to get metadata for this
case SAI_OBJECT_TYPE_BFD_SESSION:

valid = true;
break;

default:

SWSS_LOG_ERROR("data.bfd_session_id %s has unexpected type: %s, expected BFD_SESSION",
sai_serialize_object_id(data.bfd_session_id).c_str(),
sai_serialize_object_type(ot).c_str());
break;
}

if (valid && !m_oids.objectReferenceExists(data.bfd_session_id))
{
SWSS_LOG_NOTICE("data.bfd_session_id new object spotted %s not present in local DB (snoop!)",
sai_serialize_object_id(data.bfd_session_id).c_str());

sai_object_meta_key_t key = { .objecttype = ot, .objectkey = { .key = { .object_id = data.bfd_session_id } } };

m_oids.objectReferenceInsert(data.bfd_session_id);

if (!m_saiObjectCollection.objectExists(key))
{
m_saiObjectCollection.createObject(key);
}
}
}

void Meta::meta_sai_on_bfd_session_state_change(
_In_ uint32_t count,
_In_ const sai_bfd_session_state_notification_t *data)
{
SWSS_LOG_ENTER();

if (count && data == NULL)
{
SWSS_LOG_ERROR("sai_bfd_session_state_notification_t pointer is NULL but count is %u", count);
return;
}

for (uint32_t i = 0; i < count; ++i)
{
meta_sai_on_bfd_session_state_change_single(data[i]);
}
}

int32_t Meta::getObjectReferenceCount(
_In_ sai_object_id_t oid) const
{
Expand Down
7 changes: 7 additions & 0 deletions meta/Meta.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ namespace saimeta
_In_ uint32_t count,
_In_ const sai_queue_deadlock_notification_data_t *data);

void meta_sai_on_bfd_session_state_change(
_In_ uint32_t count,
_In_ const sai_bfd_session_state_notification_t *data);

private: // notifications helpers

void meta_sai_on_fdb_flush_event_consolidated(
Expand All @@ -201,6 +205,9 @@ namespace saimeta
void meta_sai_on_queue_pfc_deadlock_notification_single(
_In_ const sai_queue_deadlock_notification_data_t& data);

void meta_sai_on_bfd_session_state_change_single(
_In_ const sai_bfd_session_state_notification_t& data);

private: // validation helpers

sai_status_t meta_generic_validation_objlist(
Expand Down
77 changes: 77 additions & 0 deletions meta/NotificationBfdSessionStateChange.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#include "NotificationBfdSessionStateChange.h"

#include "swss/logger.h"

#include "meta/sai_serialize.h"

using namespace sairedis;

NotificationBfdSessionStateChange::NotificationBfdSessionStateChange(
_In_ const std::string& serializedNotification):
Notification(
SAI_SWITCH_NOTIFICATION_TYPE_BFD_SESSION_STATE_CHANGE,
serializedNotification),
m_bfdSessionStateNotificationData(nullptr)
{
SWSS_LOG_ENTER();

sai_deserialize_bfd_session_state_ntf(
serializedNotification,
m_count,
&m_bfdSessionStateNotificationData);
}

NotificationBfdSessionStateChange::~NotificationBfdSessionStateChange()
{
SWSS_LOG_ENTER();

sai_deserialize_free_bfd_session_state_ntf(m_count, m_bfdSessionStateNotificationData);
}

sai_object_id_t NotificationBfdSessionStateChange::getSwitchId() const
{
SWSS_LOG_ENTER();

// this notification don't contain switch id field

return SAI_NULL_OBJECT_ID;
}

sai_object_id_t NotificationBfdSessionStateChange::getAnyObjectId() const
{
SWSS_LOG_ENTER();

if (m_bfdSessionStateNotificationData == nullptr)
{
return SAI_NULL_OBJECT_ID;
}

for (uint32_t idx = 0; idx < m_count; idx++)
{
if (m_bfdSessionStateNotificationData[idx].bfd_session_id != SAI_NULL_OBJECT_ID)
{
return m_bfdSessionStateNotificationData[idx].bfd_session_id;
}
}

return SAI_NULL_OBJECT_ID;
}

void NotificationBfdSessionStateChange::processMetadata(
_In_ std::shared_ptr<saimeta::Meta> meta) const
{
SWSS_LOG_ENTER();

meta->meta_sai_on_bfd_session_state_change(m_count, m_bfdSessionStateNotificationData);
}

void NotificationBfdSessionStateChange::executeCallback(
_In_ const sai_switch_notifications_t& switchNotifications) const
{
SWSS_LOG_ENTER();

if (switchNotifications.on_bfd_session_state_change)
{
switchNotifications.on_bfd_session_state_change(m_count, m_bfdSessionStateNotificationData);
}
}
35 changes: 35 additions & 0 deletions meta/NotificationBfdSessionStateChange.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

#include "Notification.h"

namespace sairedis
{
class NotificationBfdSessionStateChange:
public Notification
{
public:

NotificationBfdSessionStateChange(
_In_ const std::string& serializedNotification);

virtual ~NotificationBfdSessionStateChange();

public:

virtual sai_object_id_t getSwitchId() const override;

virtual sai_object_id_t getAnyObjectId() const override;

virtual void processMetadata(
_In_ std::shared_ptr<saimeta::Meta> meta) const override;

virtual void executeCallback(
_In_ const sai_switch_notifications_t& switchNotifications) const override;

private:

uint32_t m_count;

sai_bfd_session_state_notification_t *m_bfdSessionStateNotificationData;
};
}
4 changes: 4 additions & 0 deletions meta/NotificationFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "NotificationQueuePfcDeadlock.h"
#include "NotificationSwitchShutdownRequest.h"
#include "NotificationSwitchStateChange.h"
#include "NotificationBfdSessionStateChange.h"
#include "sairediscommon.h"

#include "swss/logger.h"
Expand Down Expand Up @@ -31,6 +32,9 @@ std::shared_ptr<Notification> NotificationFactory::deserialize(
if (name == SAI_SWITCH_NOTIFICATION_NAME_SWITCH_STATE_CHANGE)
return std::make_shared<NotificationSwitchStateChange>(serializedNotification);

if (name == SAI_SWITCH_NOTIFICATION_NAME_BFD_SESSION_STATE_CHANGE)
return std::make_shared<NotificationBfdSessionStateChange>(serializedNotification);

SWSS_LOG_ERROR("unknown notification: '%s', FIXME", name.c_str());

return nullptr;
Expand Down
75 changes: 75 additions & 0 deletions meta/SaiSerialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1756,6 +1756,14 @@ static json sai_serialize_json_fdb_event_notification_data(
return j;
}

std::string sai_serialize_bfd_session_state(
_In_ sai_bfd_session_state_t status)
{
SWSS_LOG_ENTER();

return sai_serialize_enum(status, &sai_metadata_enum_sai_bfd_session_state_t);
}

std::string sai_serialize_fdb_event_ntf(
_In_ uint32_t count,
_In_ const sai_fdb_event_notification_data_t* fdb_event)
Expand Down Expand Up @@ -1834,6 +1842,33 @@ std::string sai_serialize_queue_deadlock_ntf(
return j.dump();
}

std::string sai_serialize_bfd_session_state_ntf(
_In_ uint32_t count,
_In_ const sai_bfd_session_state_notification_t* bfd_session_state)
{
SWSS_LOG_ENTER();

if (bfd_session_state == NULL)
{
SWSS_LOG_THROW("bfd_session_state pointer is null");
}

json j = json::array();

for (uint32_t i = 0; i < count; ++i)
{
json item;

item["bfd_session_id"] = sai_serialize_object_id(bfd_session_state[i].bfd_session_id);
item["session_state"] = sai_serialize_bfd_session_state(bfd_session_state[i].session_state);

j.push_back(item);
}

// we don't need count since it can be deduced
return j.dump();
}

json sai_serialize_nat_entry_key(
_In_ const sai_nat_entry_key_t& nat_entry_key)
{
Expand Down Expand Up @@ -3062,6 +3097,15 @@ void sai_deserialize_fdb_event(
sai_deserialize_enum(s, &sai_metadata_enum_sai_fdb_event_t, (int32_t&)event);
}

void sai_deserialize_bfd_session_state(
_In_ const std::string& s,
_Out_ sai_bfd_session_state_t& state)
{
SWSS_LOG_ENTER();

sai_deserialize_enum(s, &sai_metadata_enum_sai_bfd_session_state_t, (int32_t&)state);
}

void sai_deserialize_switch_oper_status(
_In_ const std::string& s,
_Out_ sai_object_id_t &switch_id,
Expand Down Expand Up @@ -3483,6 +3527,28 @@ void sai_deserialize_queue_deadlock_ntf(
*deadlock_data = data;
}

void sai_deserialize_bfd_session_state_ntf(
_In_ const std::string& s,
_Out_ uint32_t &count,
_Out_ sai_bfd_session_state_notification_t** bfd_session_state)
{
SWSS_LOG_ENTER();

json j = json::parse(s);

count = (uint32_t)j.size();

auto data = new sai_bfd_session_state_notification_t[count];

for (uint32_t i = 0; i < count; ++i)
{
sai_deserialize_object_id(j[i]["bfd_session_id"], data[i].bfd_session_id);
sai_deserialize_bfd_session_state(j[i]["session_state"], data[i].session_state);
}

*bfd_session_state = data;
}

// deserialize free

void sai_deserialize_free_attribute_value(
Expand Down Expand Up @@ -3684,6 +3750,15 @@ void sai_deserialize_free_queue_deadlock_ntf(
delete[] queue_deadlock;
}

void sai_deserialize_free_bfd_session_state_ntf(
_In_ uint32_t count,
_In_ sai_bfd_session_state_notification_t* bfd_session_state)
{
SWSS_LOG_ENTER();

delete[] bfd_session_state;
}

void sai_deserialize_ingress_priority_group_attr(
_In_ const std::string& s,
_Out_ sai_ingress_priority_group_attr_t& attr)
Expand Down
13 changes: 13 additions & 0 deletions meta/sai_serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ std::string sai_serialize_queue_deadlock_ntf(
_In_ uint32_t count,
_In_ const sai_queue_deadlock_notification_data_t* deadlock_data);

std::string sai_serialize_bfd_session_state_ntf(
_In_ uint32_t count,
_In_ const sai_bfd_session_state_notification_t* bfd_session_state);

// sairedis

std::string sai_serialize(
Expand Down Expand Up @@ -341,6 +345,11 @@ void sai_deserialize_queue_deadlock_ntf(
_Out_ uint32_t &count,
_Out_ sai_queue_deadlock_notification_data_t** deadlock_data);

void sai_deserialize_bfd_session_state_ntf(
_In_ const std::string& s,
_Out_ uint32_t &count,
_Out_ sai_bfd_session_state_notification_t** bfdsession);

// free methods

void sai_deserialize_free_attribute_value(
Expand All @@ -361,6 +370,10 @@ void sai_deserialize_free_queue_deadlock_ntf(
_In_ uint32_t count,
_In_ sai_queue_deadlock_notification_data_t* deadlock_data);

void sai_deserialize_free_bfd_session_state_ntf(
_In_ uint32_t count,
_In_ sai_bfd_session_state_notification_t* bfdsessionstate);

void sai_deserialize_ingress_priority_group_attr(
_In_ const std::string& s,
_Out_ sai_ingress_priority_group_attr_t& attr);
Expand Down
Loading

0 comments on commit 5349a9d

Please sign in to comment.