Skip to content

Commit e72d660

Browse files
committed
[fpmsyncd]: Linux netlink runtime option
1 parent 3226163 commit e72d660

3 files changed

Lines changed: 76 additions & 11 deletions

File tree

fpmsyncd/fpmsyncd.cpp

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <getopt.h>
12
#include <iostream>
23
#include <inttypes.h>
34
#include "logger.h"
@@ -7,6 +8,7 @@
78
#include "warmRestartHelper.h"
89
#include "fpmsyncd/fpmlink.h"
910
#include "fpmsyncd/routesync.h"
11+
#include "netlink.h"
1012

1113

1214
using namespace std;
@@ -44,12 +46,54 @@ static bool eoiuFlagsSet(Table &bgpStateTable)
4446
return true;
4547
}
4648

49+
static void usage()
50+
{
51+
cout << "Usage: fpmsyncd [ -l ( fpm | net) ]" << endl;
52+
cout << " fpm = FpmLink (default)" << endl;
53+
cout << " net = NetLink" << endl;
54+
}
55+
4756
int main(int argc, char **argv)
4857
{
58+
bool useFpmLink = true;
59+
int opt;
60+
while ((opt = getopt(argc, argv, "l:h")) != -1 )
61+
{
62+
switch (opt)
63+
{
64+
case 'l':
65+
{
66+
string linkmode(optarg);
67+
if (linkmode == "net")
68+
{
69+
useFpmLink = false;
70+
}
71+
else if (linkmode == "fpm")
72+
{
73+
useFpmLink = true;
74+
}
75+
else
76+
{
77+
usage();
78+
return EXIT_FAILURE;
79+
}
80+
break;
81+
}
82+
83+
case 'h':
84+
usage();
85+
return 1;
86+
87+
default: /* '?' */
88+
usage();
89+
return EXIT_FAILURE;
90+
}
91+
}
92+
4993
swss::Logger::linkToDbNative("fpmsyncd");
5094
DBConnector db("APPL_DB", 0);
5195
RedisPipeline pipeline(&db);
52-
RouteSync sync(&pipeline);
96+
RouteSync sync(&pipeline, useFpmLink);
5397

5498
DBConnector stateDb("STATE_DB", 0);
5599
Table bgpStateTable(&stateDb, STATE_BGP_TABLE_NAME);
@@ -61,7 +105,6 @@ int main(int argc, char **argv)
61105
{
62106
try
63107
{
64-
FpmLink fpm(&sync);
65108
Select s;
66109
SelectableTimer warmStartTimer(timespec{0, 0});
67110
// Before eoiu flags detected, check them periodically. It also stop upon detection of reconciliation done.
@@ -75,11 +118,30 @@ int main(int argc, char **argv)
75118
*/
76119
pipeline.flush();
77120

78-
cout << "Waiting for fpm-client connection..." << endl;
79-
fpm.accept();
80-
cout << "Connected!" << endl;
121+
shared_ptr<Selectable> link;
122+
if (useFpmLink)
123+
{
124+
shared_ptr<FpmLink> fpm = make_shared<FpmLink>(&sync);
125+
126+
cout << "Waiting for fpm-client connection..." << endl;
127+
fpm->accept();
128+
cout << "Connected!" << endl;
81129

82-
s.addSelectable(&fpm);
130+
link = fpm;
131+
}
132+
else
133+
{
134+
shared_ptr<NetLink> netlink = make_shared<NetLink>();
135+
136+
netlink->registerGroup(RTNLGRP_IPV4_ROUTE);
137+
netlink->registerGroup(RTNLGRP_IPV6_ROUTE);
138+
netlink->registerGroup(RTNLGRP_MPLS_ROUTE);
139+
cout << "NetLink listening for route messages..." << endl;
140+
netlink->dumpRequest(RTM_GETROUTE);
141+
142+
link = netlink;
143+
}
144+
s.addSelectable(link.get());
83145

84146
/* If warm-restart feature is enabled, execute 'restoration' logic */
85147
bool warmStartEnabled = sync.m_warmStartHelper.checkAndStart();

fpmsyncd/routesync.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,13 @@ using namespace swss;
4242

4343
#define ETHER_ADDR_STRLEN (3*ETH_ALEN)
4444

45-
RouteSync::RouteSync(RedisPipeline *pipeline) :
45+
RouteSync::RouteSync(RedisPipeline *pipeline, bool useFpmLink) :
4646
m_routeTable(pipeline, APP_ROUTE_TABLE_NAME, true),
4747
m_vnet_routeTable(pipeline, APP_VNET_RT_TABLE_NAME, true),
4848
m_vnet_tunnelTable(pipeline, APP_VNET_RT_TUNNEL_TABLE_NAME, true),
4949
m_warmStartHelper(pipeline, &m_routeTable, APP_ROUTE_TABLE_NAME, "bgp", "bgp"),
50-
m_nl_sock(NULL), m_link_cache(NULL)
50+
m_nl_sock(NULL), m_link_cache(NULL),
51+
m_usingFpmLink(useFpmLink)
5152
{
5253
m_nl_sock = nl_socket_alloc();
5354
nl_connect(m_nl_sock, NETLINK_ROUTE);
@@ -582,7 +583,9 @@ void RouteSync::onMsg(int nlmsg_type, struct nl_object *obj)
582583
char master_name[IFNAMSIZ] = {0};
583584

584585
/* if the table_id is not set in the route obj then route is for default vrf. */
585-
if (master_index)
586+
/* Linux Netlink connection does not substitute VRF ifindex for RTTABLE_ID
587+
* so VRF not supported in Linux NetLink mode */
588+
if (m_usingFpmLink && master_index)
586589
{
587590
/* Get the name of the master device */
588591
getIfName(master_index, master_name, IFNAMSIZ);
@@ -598,7 +601,6 @@ void RouteSync::onMsg(int nlmsg_type, struct nl_object *obj)
598601
{
599602
onRouteMsg(nlmsg_type, obj, master_name);
600603
}
601-
602604
}
603605
else
604606
{

fpmsyncd/routesync.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class RouteSync : public NetMsg
2121
public:
2222
enum { MAX_ADDR_SIZE = 64 };
2323

24-
RouteSync(RedisPipeline *pipeline);
24+
RouteSync(RedisPipeline *pipeline, bool usingFpmLink);
2525

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

@@ -37,6 +37,7 @@ class RouteSync : public NetMsg
3737
ProducerStateTable m_vnet_tunnelTable;
3838
struct nl_cache *m_link_cache;
3939
struct nl_sock *m_nl_sock;
40+
bool m_usingFpmLink;
4041

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

0 commit comments

Comments
 (0)