12
12
#include " macaddress.h"
13
13
#include < string.h>
14
14
#include < arpa/inet.h>
15
+ #include < chrono>
15
16
16
17
using namespace std ;
17
18
using namespace swss ;
@@ -41,6 +42,13 @@ using namespace swss;
41
42
42
43
#define ETHER_ADDR_STRLEN (3 *ETH_ALEN)
43
44
45
+
46
+ /* helper function for time */
47
+ uint64_t getTimeEpochMsec () {
48
+ using namespace std ::chrono;
49
+ return duration_cast<milliseconds>(system_clock::now ().time_since_epoch ()).count ();
50
+ }
51
+
44
52
RouteSync::RouteSync (RedisPipeline *pipeline) :
45
53
m_routeTable(pipeline, APP_ROUTE_TABLE_NAME, true ),
46
54
m_vnet_routeTable(pipeline, APP_VNET_RT_TABLE_NAME, true ),
@@ -51,6 +59,34 @@ RouteSync::RouteSync(RedisPipeline *pipeline) :
51
59
m_nl_sock = nl_socket_alloc ();
52
60
nl_connect (m_nl_sock, NETLINK_ROUTE);
53
61
rtnl_link_alloc_cache (m_nl_sock, AF_UNSPEC, &m_link_cache);
62
+
63
+ /* Initailize with defaults*/
64
+ RED_THRESHOLD = 500 ;
65
+ ORANGE_THRESHOLD = 100 ;
66
+ countRedroute = 0 ;
67
+ countOrangeroute = 0 ;
68
+
69
+ /* update the time at start */
70
+ lastRedUpdated = getTimeEpochMsec ();
71
+ lastOrangeUpdated = lastRedUpdated;
72
+
73
+ /* READ THESHOLD CONFIG from BGP_ROUTE_THRESHOLD Table*/
74
+ this ->cfgDb = new DBConnector (" CONFIG_DB" , 0 );
75
+ this ->cfgRouteThTable = new Table (this ->cfgDb , " BGP_ROUTE_THRESHOLD" );
76
+
77
+ /* WRITE STATS in BGP_ROUTE_UPDATE_FREQUENCY Table STATE DB*/
78
+ this ->stateDb = new DBConnector (" STATE_DB" , 0 );
79
+ this ->bgpRouteFreqTable = new Table (this ->stateDb , " BGP_ROUTE_UPDATE_FREQUENCY" );
80
+
81
+ /* Remove later */
82
+ SWSS_LOG_NOTICE (" PC: fpmsyncd debug image" );
83
+ }
84
+
85
+ RouteSync::~RouteSync () {
86
+ delete cfgRouteThTable;
87
+ delete bgpRouteFreqTable;
88
+ delete cfgDb;
89
+ delete stateDb;
54
90
}
55
91
56
92
char *RouteSync::prefixMac2Str (char *mac, char *buf, int size)
@@ -443,6 +479,8 @@ void RouteSync::onEvpnRouteMsg(struct nlmsghdr *h, int len)
443
479
444
480
if (nlmsg_type == RTM_DELROUTE)
445
481
{
482
+ /* update route change frequency */
483
+ updateRouteFrequencyStats ();
446
484
if (!warmRestartInProgress)
447
485
{
448
486
m_routeTable.del (destipprefix);
@@ -519,6 +557,8 @@ void RouteSync::onEvpnRouteMsg(struct nlmsghdr *h, int len)
519
557
fvVector.push_back (intf);
520
558
fvVector.push_back (vni);
521
559
fvVector.push_back (mac);
560
+ /* update route change frequency */
561
+ updateRouteFrequencyStats ();
522
562
523
563
if (!warmRestartInProgress)
524
564
{
@@ -643,6 +683,8 @@ void RouteSync::onRouteMsg(int nlmsg_type, struct nl_object *obj, char *vrf)
643
683
644
684
if (nlmsg_type == RTM_DELROUTE)
645
685
{
686
+ /* update route change frequency */
687
+ updateRouteFrequencyStats ();
646
688
if (!warmRestartInProgress)
647
689
{
648
690
m_routeTable.del (destipprefix);
@@ -723,6 +765,9 @@ void RouteSync::onRouteMsg(int nlmsg_type, struct nl_object *obj, char *vrf)
723
765
fvVector.push_back (nh);
724
766
fvVector.push_back (idx);
725
767
768
+ /* update route change frequency */
769
+ updateRouteFrequencyStats ();
770
+
726
771
if (!warmRestartInProgress)
727
772
{
728
773
m_routeTable.set (destipprefix, fvVector);
@@ -775,6 +820,9 @@ void RouteSync::onVnetRouteMsg(int nlmsg_type, struct nl_object *obj, string vne
775
820
776
821
if (nlmsg_type == RTM_DELROUTE)
777
822
{
823
+ /* update route change frequency */
824
+ updateRouteFrequencyStats ();
825
+
778
826
/* Duplicated delete as we do not know if it is a VXLAN tunnel route*/
779
827
m_vnet_routeTable.del (vnet_dip);
780
828
m_vnet_tunnelTable.del (vnet_dip);
@@ -813,6 +861,9 @@ void RouteSync::onVnetRouteMsg(int nlmsg_type, struct nl_object *obj, string vne
813
861
return ;
814
862
}
815
863
864
+ /* update route change frequency */
865
+ updateRouteFrequencyStats ();
866
+
816
867
/* Get nexthop lists */
817
868
string nexthops = getNextHopGw (route_obj);
818
869
string ifnames = getNextHopIf (route_obj);
@@ -962,3 +1013,40 @@ string RouteSync::getNextHopIf(struct rtnl_route *route_obj)
962
1013
963
1014
return result;
964
1015
}
1016
+
1017
+ void RouteSync::updateRouteFrequencyStats () {
1018
+
1019
+ ++countRedroute;
1020
+ ++countOrangeroute;
1021
+
1022
+ /* Read Config DB for Threshold Value */
1023
+ string value;
1024
+ string CONFIG_KEY = " ROUTE_UPDATE_THRESHOLD" ;
1025
+ bool ret = cfgRouteThTable->hget (CONFIG_KEY, " RED_THRESHOLD" , value);
1026
+ if (ret)
1027
+ RED_THRESHOLD = (u_int16_t )std::stoi (value);
1028
+ ret = cfgRouteThTable->hget (CONFIG_KEY, " ORANGE_THRESHOLD" , value);
1029
+ if (ret)
1030
+ ORANGE_THRESHOLD = (u_int16_t )std::stoi (value);
1031
+
1032
+
1033
+ string STATE_DB_KEY = " ROUTE_UPDATE_FREQUENCY" ;
1034
+ if (countRedroute >= RED_THRESHOLD) {
1035
+ uint64_t curTime = getTimeEpochMsec ();
1036
+ double timeDiff = (double )(curTime-lastRedUpdated)/1000.00 ;
1037
+ /* TODO: change log level*/
1038
+ SWSS_LOG_NOTICE (" Red TH: %d routes are updated in %.3f secs\n " , countRedroute, timeDiff);
1039
+ bgpRouteFreqTable->hset (STATE_DB_KEY, " RED_THRESHOLD" , std::to_string (countRedroute/timeDiff));
1040
+ lastRedUpdated = curTime;
1041
+ countRedroute = 0 ;
1042
+ }
1043
+
1044
+ if (countOrangeroute >= ORANGE_THRESHOLD) {
1045
+ uint64_t curTime = getTimeEpochMsec ();
1046
+ double timeDiff = (double )(curTime-lastOrangeUpdated)/1000.00 ;
1047
+ SWSS_LOG_NOTICE (" Orange TH: %d routes are updated in %.3f secs\n " , countOrangeroute, timeDiff);
1048
+ bgpRouteFreqTable->hset (STATE_DB_KEY, " ORANGE_THRESHOLD" , std::to_string (countOrangeroute/timeDiff));
1049
+ lastOrangeUpdated = curTime;
1050
+ countOrangeroute = 0 ;
1051
+ }
1052
+ }
0 commit comments