Skip to content

Route freq stats #1

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

Open
wants to merge 11 commits into
base: rel_3.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion fpmsyncd/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ fpmsyncd_SOURCES = fpmsyncd.cpp fpmlink.cpp routesync.cpp $(top_srcdir)/warmrest

fpmsyncd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON)
fpmsyncd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON)
fpmsyncd_LDADD = -lnl-3 -lnl-route-3 -lswsscommon
fpmsyncd_LDADD = -lnl-3 -lnl-route-3 -lswsscommon -lpthread
128 changes: 128 additions & 0 deletions fpmsyncd/routesync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "macaddress.h"
#include <string.h>
#include <arpa/inet.h>
#include <chrono>
#include <thread>

using namespace std;
using namespace swss;
Expand Down Expand Up @@ -41,6 +43,13 @@ using namespace swss;

#define ETHER_ADDR_STRLEN (3*ETH_ALEN)


/* helper function for time */
uint64_t getTimeEpochMsec() {
using namespace std::chrono;
return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
}

RouteSync::RouteSync(RedisPipeline *pipeline) :
m_routeTable(pipeline, APP_ROUTE_TABLE_NAME, true),
m_vnet_routeTable(pipeline, APP_VNET_RT_TABLE_NAME, true),
Expand All @@ -51,8 +60,112 @@ RouteSync::RouteSync(RedisPipeline *pipeline) :
m_nl_sock = nl_socket_alloc();
nl_connect(m_nl_sock, NETLINK_ROUTE);
rtnl_link_alloc_cache(m_nl_sock, AF_UNSPEC, &m_link_cache);

/* Initailize with defaults*/
m_routePeriod = 5;
m_countroute = 0;
m_totalRtUpdates = 0;
m_resetRtUpdates = true;
m_runRtUpdateThread = true;

/* update the time at start */
m_lastUpdated = getTimeEpochMsec();

/* READ THESHOLD CONFIG from BGP_ROUTE_THRESHOLD Table*/
this->m_cfgDb = new DBConnector("CONFIG_DB", 0);
this->m_cfgRouteThTable = new Table(this->m_cfgDb, "BGP_ROUTE_THRESHOLD");

/* WRITE STATS in BGP_ROUTE_UPDATE_FREQUENCY Table STATE DB*/
this->m_stateDb = new DBConnector("STATE_DB", 0);
this->m_bgpRouteFreqTable = new Table(this->m_stateDb, "BGP_ROUTE_UPDATE_FREQUENCY");

/* start route update thread*/
m_rtUpdateThread = thread(RouteSync::updateRouteThread, this);
}

RouteSync::~RouteSync() {
delete m_cfgRouteThTable;
delete m_bgpRouteFreqTable;
delete m_cfgDb;
delete m_stateDb;

/* stop route freq update thread */
m_runRtUpdateThread = false;
m_rtUpdateThread.join();
}

void RouteSync::updateRouteFrequencyStats(bool updateDb=false) {

/* if updateDb is false, then called just for counter update */
if (!updateDb) {
++m_countroute;
++m_totalRtUpdates;
return;
}

uint64_t curTime = getTimeEpochMsec();
if (m_countroute > 0 || m_resetRtUpdates) {

/* find timediff */
double timeDiff = (double)(curTime-m_lastUpdated)/1000.00;

string KEY = "ROUTE_UPDATE_FREQUENCY";
SWSS_LOG_NOTICE("%lu routes are updated in %.3f secs. Total route updates: %lu\n", \
m_countroute, timeDiff, m_totalRtUpdates);

/* create data */
vector<FieldValueTuple> fvVector;
FieldValueTuple tTtUp("TOTAL_ROUTE_UPDATES", std::to_string(m_totalRtUpdates).c_str());
fvVector.push_back(tTtUp);
FieldValueTuple rtUp("ROUTE_UPDATES", std::to_string(m_countroute).c_str());
fvVector.push_back(rtUp);
FieldValueTuple tiPe("TIME_PERIOD", std::to_string(timeDiff).c_str());
fvVector.push_back(tiPe);

/* if countroute > 0, we need to reset later */
if (m_countroute > 0)
m_resetRtUpdates = true;
/* else, this is a reset, make it false for next timer */
else
m_resetRtUpdates = false;

/* reset counter on update */
m_countroute = 0;

/* update state db & set expire TTL */
m_bgpRouteFreqTable->set(KEY, fvVector);
}
/* change lastUpdated with each timer */
m_lastUpdated = curTime;

}

void RouteSync::updateRouteThread(RouteSync *sync) {

while (sync->m_runRtUpdateThread) {
/* Read the Config */
sync->readBgpRouteThresholdCfg();

/* update stats in DB */
sync->updateRouteFrequencyStats(true);

/* sleep, thx god, it is not busy */
std::this_thread::sleep_for(std::chrono::seconds(sync->m_routePeriod));
}
}

void RouteSync::readBgpRouteThresholdCfg() {
/* Read Config DB for Threshold Value */
string value = " ";
string CONFIG_KEY = "ROUTE_UPDATE_THRESHOLD";
bool ret = m_cfgRouteThTable->hget(CONFIG_KEY, "ROUTE_PERIOD", value);
if (ret)
m_routePeriod = (u_int16_t)std::stoi(value);

SWSS_LOG_DEBUG("ret:%d value:%s ROUTE_PERIOD: %d\n", ret, value.c_str(), m_routePeriod);
}


char *RouteSync::prefixMac2Str(char *mac, char *buf, int size)
{
char *ptr = buf;
Expand Down Expand Up @@ -443,6 +556,8 @@ void RouteSync::onEvpnRouteMsg(struct nlmsghdr *h, int len)

if (nlmsg_type == RTM_DELROUTE)
{
/* update route change frequency */
updateRouteFrequencyStats();
if (!warmRestartInProgress)
{
m_routeTable.del(destipprefix);
Expand Down Expand Up @@ -519,6 +634,8 @@ void RouteSync::onEvpnRouteMsg(struct nlmsghdr *h, int len)
fvVector.push_back(intf);
fvVector.push_back(vni);
fvVector.push_back(mac);
/* update route change frequency */
updateRouteFrequencyStats();

if (!warmRestartInProgress)
{
Expand Down Expand Up @@ -643,6 +760,8 @@ void RouteSync::onRouteMsg(int nlmsg_type, struct nl_object *obj, char *vrf)

if (nlmsg_type == RTM_DELROUTE)
{
/* update route change frequency */
updateRouteFrequencyStats();
if (!warmRestartInProgress)
{
m_routeTable.del(destipprefix);
Expand Down Expand Up @@ -723,6 +842,9 @@ void RouteSync::onRouteMsg(int nlmsg_type, struct nl_object *obj, char *vrf)
fvVector.push_back(nh);
fvVector.push_back(idx);

/* update route change frequency */
updateRouteFrequencyStats();

if (!warmRestartInProgress)
{
m_routeTable.set(destipprefix, fvVector);
Expand Down Expand Up @@ -775,6 +897,9 @@ void RouteSync::onVnetRouteMsg(int nlmsg_type, struct nl_object *obj, string vne

if (nlmsg_type == RTM_DELROUTE)
{
/* update route change frequency */
updateRouteFrequencyStats();

/* Duplicated delete as we do not know if it is a VXLAN tunnel route*/
m_vnet_routeTable.del(vnet_dip);
m_vnet_tunnelTable.del(vnet_dip);
Expand Down Expand Up @@ -813,6 +938,9 @@ void RouteSync::onVnetRouteMsg(int nlmsg_type, struct nl_object *obj, string vne
return;
}

/* update route change frequency */
updateRouteFrequencyStats();

/* Get nexthop lists */
string nexthops = getNextHopGw(route_obj);
string ifnames = getNextHopIf(route_obj);
Expand Down
41 changes: 41 additions & 0 deletions fpmsyncd/routesync.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "warmRestartHelper.h"
#include <string.h>
#include <bits/stdc++.h>
#include <thread>

using namespace std;

Expand All @@ -22,10 +23,12 @@ class RouteSync : public NetMsg
enum { MAX_ADDR_SIZE = 64 };

RouteSync(RedisPipeline *pipeline);
virtual ~RouteSync();

virtual void onMsg(int nlmsg_type, struct nl_object *obj);

virtual void onMsgRaw(struct nlmsghdr *obj);

WarmStartHelper m_warmStartHelper;

private:
Expand All @@ -38,6 +41,44 @@ class RouteSync : public NetMsg
struct nl_cache *m_link_cache;
struct nl_sock *m_nl_sock;

/* thread for route update frequency */
thread m_rtUpdateThread;

/* run thread for route update, till true */
bool m_runRtUpdateThread;

/* User Configured Threshold */
uint16_t m_routePeriod;

/* reset Route Updates to zero, if true */
bool m_resetRtUpdates;

/* Current route updates count */
uint64_t m_countroute;

/* Total route updates count */
uint64_t m_totalRtUpdates;

/* timestamp for last frequency update */
uint64_t m_lastUpdated;

/* Read Config from below Table in CONFIG_DB*/
DBConnector *m_cfgDb;
Table *m_cfgRouteThTable;

/* Write Frequency updates to below Table in STATE_DB*/
DBConnector *m_stateDb;
Table *m_bgpRouteFreqTable;

/* update route updates, counter\DB */
void updateRouteFrequencyStats(bool updateDb);

/* read Config for Route Updates */
void readBgpRouteThresholdCfg();

/* thread for route updates*/
static void updateRouteThread(RouteSync *sync);

/* Handle regular route (include VRF route) */
void onRouteMsg(int nlmsg_type, struct nl_object *obj, char *vrf);

Expand Down