Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SAI NAT aging notification #987

Merged
merged 14 commits into from
Oct 6, 2022
5 changes: 5 additions & 0 deletions lib/Switch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ void Switch::updateNotifications(
(sai_fdb_event_notification_fn)attr.value.ptr;
break;

case SAI_SWITCH_ATTR_NAT_EVENT_NOTIFY:
m_switchNotifications.on_nat_event =
(sai_nat_event_notification_fn)attr.value.ptr;
break;

case SAI_SWITCH_ATTR_PORT_STATE_CHANGE_NOTIFY:
m_switchNotifications.on_port_state_change =
(sai_port_state_change_notification_fn)attr.value.ptr;
Expand Down
1 change: 1 addition & 0 deletions meta/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ libsaimeta_la_SOURCES = \
Notification.cpp \
NotificationFactory.cpp \
NotificationFdbEvent.cpp \
NotificationNatEvent.cpp \
NotificationPortStateChange.cpp \
NotificationQueuePfcDeadlock.cpp \
NotificationSwitchShutdownRequest.cpp \
Expand Down
46 changes: 46 additions & 0 deletions meta/Meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7594,6 +7594,52 @@ void Meta::meta_sai_on_fdb_event(
}
}

void Meta::meta_sai_on_nat_event_single(
_In_ const sai_nat_event_notification_data_t& data)
{
SWSS_LOG_ENTER();

const sai_object_meta_key_t meta_key_nat = { .objecttype = SAI_OBJECT_TYPE_NAT_ENTRY, .objectkey = { .key = { .nat_entry = data.nat_entry } } };

switch (data.event_type)
{
case SAI_NAT_EVENT_AGED:

arvbb marked this conversation as resolved.
Show resolved Hide resolved
if (!m_saiObjectCollection.objectExists(meta_key_nat))
{
SWSS_LOG_WARN("object key %s doesn't exist but received AGED event",
sai_serialize_object_meta_key(meta_key_nat).c_str());
break;
}

break;

case SAI_NAT_EVENT_NONE:
default:

SWSS_LOG_ERROR("got NAT_ENTRY notification with unknown event_type %d, bug?", data.event_type);
break;
}
}

void Meta::meta_sai_on_nat_event(
_In_ uint32_t count,
_In_ const sai_nat_event_notification_data_t *data)
{
SWSS_LOG_ENTER();

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

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

void Meta::meta_sai_on_switch_state_change(
_In_ sai_object_id_t switch_id,
_In_ sai_switch_oper_status_t switch_oper_status)
Expand Down
7 changes: 7 additions & 0 deletions meta/Meta.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@ namespace saimeta
_In_ uint32_t count,
_In_ const sai_fdb_event_notification_data_t *data);

void meta_sai_on_nat_event(
_In_ uint32_t count,
_In_ const sai_nat_event_notification_data_t *data);

void meta_sai_on_switch_state_change(
_In_ sai_object_id_t switch_id,
_In_ sai_switch_oper_status_t switch_oper_status);
Expand Down Expand Up @@ -227,6 +231,9 @@ namespace saimeta
void meta_sai_on_fdb_event_single(
_In_ const sai_fdb_event_notification_data_t& data);

void meta_sai_on_nat_event_single(
_In_ const sai_nat_event_notification_data_t& data);

void meta_sai_on_port_state_change_single(
_In_ const sai_port_oper_status_notification_t& data);

Expand Down
2 changes: 1 addition & 1 deletion meta/MetaKeyHasher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ static inline std::size_t sai_get_hash(

// TODO revisit - may depend on nat_type

return ne.data.key.src_ip ^ ne.data.key.dst_ip;
return ne.data.key.src_ip ^ ne.data.key.dst_ip ^ ne.data.key.proto ^ ne.data.key.l4_src_port ^ ne.data.key.l4_dst_port;
}

static inline std::size_t sai_get_hash(
Expand Down
4 changes: 4 additions & 0 deletions meta/NotificationFactory.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "NotificationFactory.h"
#include "NotificationFdbEvent.h"
#include "NotificationNatEvent.h"
#include "NotificationPortStateChange.h"
#include "NotificationQueuePfcDeadlock.h"
#include "NotificationSwitchShutdownRequest.h"
Expand All @@ -20,6 +21,9 @@ std::shared_ptr<Notification> NotificationFactory::deserialize(
if (name == SAI_SWITCH_NOTIFICATION_NAME_FDB_EVENT)
return std::make_shared<NotificationFdbEvent>(serializedNotification);

if (name == SAI_SWITCH_NOTIFICATION_NAME_NAT_EVENT)
return std::make_shared<NotificationNatEvent>(serializedNotification);

if (name == SAI_SWITCH_NOTIFICATION_NAME_PORT_STATE_CHANGE)
return std::make_shared<NotificationPortStateChange>(serializedNotification);

Expand Down
97 changes: 97 additions & 0 deletions meta/NotificationNatEvent.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#include "NotificationNatEvent.h"

#include "swss/logger.h"

#include "sai_serialize.h"

using namespace sairedis;

NotificationNatEvent::NotificationNatEvent(
_In_ const std::string& serializedNotification):
Notification(
SAI_SWITCH_NOTIFICATION_TYPE_NAT_EVENT,
serializedNotification),
m_natEventNotificationData(nullptr)
{
SWSS_LOG_ENTER();

sai_deserialize_nat_event_ntf(
serializedNotification,
m_count,
&m_natEventNotificationData);
}

NotificationNatEvent::~NotificationNatEvent()
{
SWSS_LOG_ENTER();

sai_deserialize_free_nat_event_ntf(m_count, m_natEventNotificationData);
}

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

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

for (uint32_t idx = 0; idx < m_count; idx++)
{
auto& nat = m_natEventNotificationData[idx].nat_entry;

if (nat.switch_id != SAI_NULL_OBJECT_ID)
{
return nat.switch_id;
}
}

return SAI_NULL_OBJECT_ID;
}

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

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

for (uint32_t idx = 0; idx < m_count; idx++)
{
auto& nat = m_natEventNotificationData[idx].nat_entry;

if (nat.switch_id != SAI_NULL_OBJECT_ID)
{
return nat.switch_id;
}

if (nat.vr_id != SAI_NULL_OBJECT_ID)
{
return nat.vr_id;
}
}

return SAI_NULL_OBJECT_ID;
}

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

meta->meta_sai_on_nat_event(m_count, m_natEventNotificationData);
}

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

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

#include "Notification.h"

namespace sairedis
{
class NotificationNatEvent:
public Notification
{
public:

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

virtual ~NotificationNatEvent();

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_nat_event_notification_data_t* m_natEventNotificationData;
};
}
106 changes: 106 additions & 0 deletions meta/SaiSerialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1940,6 +1940,28 @@ static json sai_serialize_json_fdb_event_notification_data(
return j;
}

std::string sai_serialize_nat_event(
_In_ sai_nat_event_t event)
{
SWSS_LOG_ENTER();

return sai_serialize_enum(event, &sai_metadata_enum_sai_nat_event_t);
}

static json sai_serialize_json_nat_event_notification_data(
_In_ const sai_nat_event_notification_data_t& nat_event)
{
SWSS_LOG_ENTER();

json j;

j["nat_event"] = sai_serialize_nat_event(nat_event.event_type);
kcudnik marked this conversation as resolved.
Show resolved Hide resolved
j["nat_entry"] = sai_serialize_nat_entry(nat_event.nat_entry);

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

std::string sai_serialize_bfd_session_state(
_In_ sai_bfd_session_state_t status)
{
Expand Down Expand Up @@ -1972,6 +1994,30 @@ std::string sai_serialize_fdb_event_ntf(
return j.dump();
}

std::string sai_serialize_nat_event_ntf(
_In_ uint32_t count,
_In_ const sai_nat_event_notification_data_t* nat_event)
{
SWSS_LOG_ENTER();

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

json j = json::array();

for (uint32_t i = 0; i < count; ++i)
{
json item = sai_serialize_json_nat_event_notification_data(nat_event[i]);

j.push_back(item);
}

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

std::string sai_serialize_port_oper_status_ntf(
_In_ uint32_t count,
_In_ const sai_port_oper_status_notification_t* port_oper_status)
Expand Down Expand Up @@ -3444,6 +3490,15 @@ void sai_deserialize_fdb_event(
sai_deserialize_enum(s, &sai_metadata_enum_sai_fdb_event_t, (int32_t&)event);
}

void sai_deserialize_nat_event(
_In_ const std::string& s,
_Out_ sai_nat_event_t& event)
{
SWSS_LOG_ENTER();

sai_deserialize_enum(s, &sai_metadata_enum_sai_nat_event_t, (int32_t&)event);
}

void sai_deserialize_bfd_session_state(
_In_ const std::string& s,
_Out_ sai_bfd_session_state_t& state)
Expand Down Expand Up @@ -3906,6 +3961,37 @@ void sai_deserialize_fdb_event_ntf(
*fdb_event = data;
}

static void sai_deserialize_json_nat_event_notification_data(
_In_ const json& j,
_Out_ sai_nat_event_notification_data_t& nat)
{
SWSS_LOG_ENTER();

sai_deserialize_nat_event(j["nat_event"], nat.event_type);
arvbb marked this conversation as resolved.
Show resolved Hide resolved
sai_deserialize_nat_entry(j["nat_entry"], nat.nat_entry);
}

void sai_deserialize_nat_event_ntf(
_In_ const std::string& s,
_Out_ uint32_t &count,
_Out_ sai_nat_event_notification_data_t** nat_event)
{
SWSS_LOG_ENTER();

json j = json::parse(s);

count = (uint32_t)j.size();

auto data = new sai_nat_event_notification_data_t[count];

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

*nat_event = data;
}

void sai_deserialize_port_oper_status_ntf(
_In_ const std::string& s,
_Out_ uint32_t &count,
Expand Down Expand Up @@ -4170,6 +4256,26 @@ void sai_deserialize_free_fdb_event_ntf(
delete[] fdb_event;
}

void sai_deserialize_free_nat_event(
_In_ sai_nat_event_notification_data_t& nat_event)
{
SWSS_LOG_ENTER();
}

void sai_deserialize_free_nat_event_ntf(
_In_ uint32_t count,
_In_ sai_nat_event_notification_data_t* nat_event)
{
SWSS_LOG_ENTER();

for (uint32_t i = 0; i < count; ++i)
{
sai_deserialize_free_nat_event(nat_event[i]);
}

delete[] nat_event;
}

void sai_deserialize_free_port_oper_status_ntf(
_In_ uint32_t count,
_In_ sai_port_oper_status_notification_t* port_oper_status)
Expand Down
Loading