Skip to content
37 changes: 36 additions & 1 deletion common/netdispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,45 @@ void NetDispatcher::unregisterMessageHandler(int nlmsg_type)
m_handlers.erase(it);
}

void NetDispatcher::registerRawMessageHandler(int nlmsg_type, NetMsg *callback)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is m_rawhandlers protected by m_mutex? as well as unregisterRawMessageHandler() function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, Sure I will put this in mutex as well.

{
if (m_rawhandlers.find(nlmsg_type) != m_rawhandlers.end())
throw "Trying to registered on already registerd netlink message";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to throw specific exception type like runtime_error instead of string literals.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is similar to the method registerMessageHandler. Hence similar error handling is done.


m_rawhandlers[nlmsg_type] = callback;
}

void NetDispatcher::unregisterRawMessageHandler(int nlmsg_type)
{
auto it = m_rawhandlers.find(nlmsg_type);

if (it == m_rawhandlers.end())
throw "Trying to unregister non existing handler";

m_rawhandlers.erase(it);

}

void NetDispatcher::nlCallback(struct nl_object *obj, void *context)
{
NetMsg *callback = (NetMsg *)context;
callback->onMsg(nl_object_get_msgtype(obj), obj);
}

void NetDispatcher::onNetlinkMessageRaw(struct nl_msg *msg)
{
struct nlmsghdr *nlmsghdr = nlmsg_hdr(msg);
NetMsg *reg_callback = NULL;
auto callback = m_rawhandlers.find(nlmsghdr->nlmsg_type);

/* Drop not registered messages */
if (callback == m_rawhandlers.end())
return;

reg_callback = (NetMsg *)callback->second;
reg_callback->onMsgRaw(nlmsghdr);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If m_rawhandlers[nlmsg_type] somehow contains nullptr, this will segfault.

}

NetMsg* NetDispatcher::getCallback(int nlmsg_type)
{
MUTEX;
Expand All @@ -61,7 +94,9 @@ void NetDispatcher::onNetlinkMessage(struct nl_msg *msg)

/* Drop not registered messages */
if (callback == nullptr)
{
onNetlinkMessageRaw(msg);
return;

}
nl_msg_parse(msg, NetDispatcher::nlCallback, (callback));
}
17 changes: 17 additions & 0 deletions common/netdispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,24 @@ namespace swss
*/
void registerMessageHandler(int nlmsg_type, NetMsg *callback);

/*
* Register callback class according to message-type.
*
* Throw exception if
*/
void registerRawMessageHandler(int nlmsg_type, NetMsg *callback);

void unregisterRawMessageHandler(int nlmsg_type);


/** Called by NetLink or FpmLink classes as indication of new packet arrival. */
void onNetlinkMessage(struct nl_msg *msg);

/*
* Called by NetLink or FpmLink classes as indication of new packet arrival
*/
void onNetlinkMessageRaw(struct nl_msg *msg);

/**
* Unregister callback according to message-type.
*
Expand All @@ -48,6 +63,8 @@ namespace swss

std::map<int, NetMsg*> m_handlers;

std::map<int, NetMsg * > m_rawhandlers;

/** Mutex protecting register, unregister and get callback methods. */
std::mutex m_mutex;
};
Expand Down
5 changes: 5 additions & 0 deletions common/netmsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,10 @@ namespace swss
public:
/* Called by NetDispatcher when netmsg matches filters */
virtual void onMsg(int nlmsg_type, struct nl_object *obj) = 0;

/* Called by NetDispatcher when raw msg is send for matches filters */
virtual void onMsgRaw(struct nlmsghdr *)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Class has virtual methods but no virtual destructor.

  • If a derived class is deleted through a NetMsg* pointer, undefined behavior occurs
  • Memory leaks or incorrect destructor calls in derived classes

{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Empty default implementation means:

  • Caller registers a raw handler but forgets to override onMsgRaw() → silently does nothing
  • No compile-time or runtime error/warning
  • Hard to debug missing implementation
virtual void onMsgRaw(struct nlmsghdr *) {
    SWSS_LOG_WARN("onMsgRaw called but not overridden in derived class");
}

or

virtual void onMsgRaw(struct nlmsghdr *) = 0;

}
};
}
2 changes: 2 additions & 0 deletions common/schema.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ namespace swss {

#define APP_VNET_MONITOR_TABLE_NAME "VNET_MONITOR_TABLE"

#define APP_L2_NEXTHOP_GROUP_TABLE_NAME "L2_NEXTHOP_GROUP_TABLE"

/***** ASIC DATABASE *****/
#define ASIC_TEMPERATURE_INFO_TABLE_NAME "ASIC_TEMPERATURE_INFO"

Expand Down