Skip to content

Commit

Permalink
[FPMSYNCD] EVPN Type5 prefix handling in FPMSYNCD (#1326)
Browse files Browse the repository at this point in the history
EVPN Type5 prefix handling in FPMSYNCD.
Add raw netlink msg processing for EVPN routes since rt_nl doesn't provide support to extract custom msg from the netlink msg.
  • Loading branch information
kishorekunal01 authored Nov 4, 2020
1 parent d9ca6e2 commit 582beae
Show file tree
Hide file tree
Showing 5 changed files with 656 additions and 8 deletions.
122 changes: 118 additions & 4 deletions fpmsyncd/fpmlink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,104 @@
using namespace swss;
using namespace std;

FpmLink::FpmLink(unsigned short port) :
void netlink_parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta,
int len)
{
while (RTA_OK(rta, len))
{
if (rta->rta_type <= max)
{
tb[rta->rta_type] = rta;
}
rta = RTA_NEXT(rta, len);
}
}

bool FpmLink::isRawProcessing(struct nlmsghdr *h)
{
int len;
short encap_type = 0;
struct rtmsg *rtm;
struct rtattr *tb[RTA_MAX + 1];

rtm = (struct rtmsg *)NLMSG_DATA(h);

if (h->nlmsg_type != RTM_NEWROUTE && h->nlmsg_type != RTM_DELROUTE)
{
return false;
}

len = (int)(h->nlmsg_len - NLMSG_LENGTH(sizeof(struct rtmsg)));
if (len < 0)
{
return false;
}

memset(tb, 0, sizeof(tb));
netlink_parse_rtattr(tb, RTA_MAX, RTM_RTA(rtm), len);

if (!tb[RTA_MULTIPATH])
{
if (tb[RTA_ENCAP_TYPE])
{
encap_type = *(short *)RTA_DATA(tb[RTA_ENCAP_TYPE]);
}
}
else
{
/* This is a multipath route */
int len;
struct rtnexthop *rtnh = (struct rtnexthop *)RTA_DATA(tb[RTA_MULTIPATH]);
len = (int)RTA_PAYLOAD(tb[RTA_MULTIPATH]);
struct rtattr *subtb[RTA_MAX + 1];

for (;;)
{
if (len < (int)sizeof(*rtnh) || rtnh->rtnh_len > len)
{
break;
}

if (rtnh->rtnh_len > sizeof(*rtnh))
{
memset(subtb, 0, sizeof(subtb));
netlink_parse_rtattr(subtb, RTA_MAX, RTNH_DATA(rtnh),
(int)(rtnh->rtnh_len - sizeof(*rtnh)));
if (subtb[RTA_ENCAP_TYPE])
{
encap_type = *(uint16_t *)RTA_DATA(subtb[RTA_ENCAP_TYPE]);
break;
}
}

if (rtnh->rtnh_len == 0)
{
break;
}

len -= NLMSG_ALIGN(rtnh->rtnh_len);
rtnh = RTNH_NEXT(rtnh);
}
}

SWSS_LOG_INFO("Rx MsgType:%d Encap:%d", h->nlmsg_type, encap_type);

if (encap_type > 0)
{
return true;
}

return false;
}

FpmLink::FpmLink(RouteSync *rsync, unsigned short port) :
MSG_BATCH_SIZE(256),
m_bufSize(FPM_MAX_MSG_LEN * MSG_BATCH_SIZE),
m_messageBuffer(NULL),
m_pos(0),
m_connected(false),
m_server_up(false)
m_server_up(false),
m_routesync(rsync)
{
struct sockaddr_in addr;
int true_val = 1;
Expand Down Expand Up @@ -120,12 +211,35 @@ uint64_t FpmLink::readData()

if (hdr->msg_type == FPM_MSG_TYPE_NETLINK)
{
nl_msg *msg = nlmsg_convert((nlmsghdr *)fpm_msg_data(hdr));
bool isRaw = false;

nlmsghdr *nl_hdr = (nlmsghdr *)fpm_msg_data(hdr);

/*
* EVPN Type5 Add Routes need to be process in Raw mode as they contain
* RMAC, VLAN and L3VNI information.
* Where as all other route will be using rtnl api to extract information
* from the netlink msg.
* */
isRaw = isRawProcessing(nl_hdr);

nl_msg *msg = nlmsg_convert(nl_hdr);
if (msg == NULL)
{
throw system_error(make_error_code(errc::bad_message), "Unable to convert nlmsg");
}

nlmsg_set_proto(msg, NETLINK_ROUTE);
NetDispatcher::getInstance().onNetlinkMessage(msg);

if (isRaw)
{
/* EVPN Type5 Add route processing */
processRawMsg(nl_hdr);
}
else
{
NetDispatcher::getInstance().onNetlinkMessage(msg);
}
nlmsg_free(msg);
}
start += msg_len;
Expand Down
10 changes: 9 additions & 1 deletion fpmsyncd/fpmlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@

#include "selectable.h"
#include "fpm/fpm.h"
#include "fpmsyncd/routesync.h"

namespace swss {

class FpmLink : public Selectable {
public:
const int MSG_BATCH_SIZE;
FpmLink(unsigned short port = FPM_DEFAULT_PORT);
FpmLink(RouteSync *rsync, unsigned short port = FPM_DEFAULT_PORT);
virtual ~FpmLink();

/* Wait for connection (blocking) */
Expand All @@ -32,7 +33,14 @@ class FpmLink : public Selectable {
{
};

bool isRawProcessing(struct nlmsghdr *h);
void processRawMsg(struct nlmsghdr *h)
{
m_routesync->onMsgRaw(h);
};

private:
RouteSync *m_routesync;
unsigned int m_bufSize;
char *m_messageBuffer;
unsigned int m_pos;
Expand Down
3 changes: 1 addition & 2 deletions fpmsyncd/fpmsyncd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
using namespace std;
using namespace swss;


/*
* Default warm-restart timer interval for routing-stack app. To be used only if
* no explicit value has been defined in configuration.
Expand Down Expand Up @@ -61,7 +60,7 @@ int main(int argc, char **argv)
{
try
{
FpmLink fpm;
FpmLink fpm(&sync);
Select s;
SelectableTimer warmStartTimer(timespec{0, 0});
// Before eoiu flags detected, check them periodically. It also stop upon detection of reconciliation done.
Expand Down
Loading

0 comments on commit 582beae

Please sign in to comment.