Skip to content

Commit 1acf60e

Browse files
minionatworkvedganesvganesan-nokia
authored
Implementation of System ports initialization, Interface & Neighbor Synchronization... (sonic-net#1431)
This PR includes implementation of System ports initialization & orchestration, Interface & Neighbor Synchronization using GLOBAL_APP_DB, Inband Interface Configuration. HLD: sonic-net/SONiC#639 Dependency PR's (sonic-swss-common): sonic-net/sonic-swss-common#380 (sonic-sairedis): sonic-net/sonic-sairedis#657 * [voq] Redis instance for global app db * [voq] System port init and orchestration * [voq] Router interface for system ports, global app db sync * [voq] Inband interface config * [voq] System port neighbors Kernel programming of static neigh and full mask static route for system neighbors is moved to nbrmgr since orchagent should not own kernel objects to avoid complication in warmboot reconciliation The orchagent programs only SAI object for the system neighbors and signals the completion of SAI programming by setting mac address in SYSTE_NEIGH table of STATE_DB. Nbrmgr subscribes to these state entries to program kernel entries corresponding to the system neighs * [swss]VS tests for VOQ system ports The following tests are added as part of virtual chassis tests - VOQ switch objects verification - System port object syncing with chassis app db by checking presence of system port RIFs in chassis app db in supervisor card - Creation of system port RIF record creation in ASIC_DB Following changes are done for the above tests: - SYSTEM_PORT table is added in default_config.json of line cards. These are loaded as part of config_db loading - Core and Port index mapping file is added in line card directories. - use dvs_database.py lib to connect to redis databases instead of using raw connection via swsscommon DBConnectors. - call dvs apis to get access to databases for the local redis instances. - Default handling for speed of the system port is removed in addSystemPorts() - Comment added to clarify types of rif-s synced to chassis app db - vs tests: connection to chassis app dp uses chassis app db id defined in dvs lib instead of using the id from swsscommon Using the chassis app db id from swsscommon instead of chassis app db id from dvd lib . This is to avoid python lgtm alert and test failure. Co-authored-by: vedganes <vedavinayagam.ganesan@nokia.com> Co-authored-by: vganesan-nokia <67648637+vganesan-nokia@users.noreply.github.com>
1 parent 36f7332 commit 1acf60e

27 files changed

+3634
-704
lines changed

cfgmgr/intfmgr.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,8 @@ void IntfMgr::doTask(Consumer &consumer)
707707
SWSS_LOG_ENTER();
708708
static bool replayDone = false;
709709

710+
string table_name = consumer.getTableName();
711+
710712
auto it = consumer.m_toSync.begin();
711713
while (it != consumer.m_toSync.end())
712714
{
@@ -718,6 +720,16 @@ void IntfMgr::doTask(Consumer &consumer)
718720

719721
if (keys.size() == 1)
720722
{
723+
if((table_name == CFG_VOQ_INBAND_INTERFACE_TABLE_NAME) &&
724+
(op == SET_COMMAND))
725+
{
726+
//No further processing needed. Just relay to orchagent
727+
m_appIntfTableProducer.set(keys[0], data);
728+
m_stateIntfTable.hset(keys[0], "vrf", "");
729+
730+
it = consumer.m_toSync.erase(it);
731+
continue;
732+
}
721733
if (!doIntfGeneralTask(keys, data, op))
722734
{
723735
it++;

cfgmgr/intfmgrd.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ int main(int argc, char **argv)
4747
CFG_VLAN_INTF_TABLE_NAME,
4848
CFG_LOOPBACK_INTERFACE_TABLE_NAME,
4949
CFG_VLAN_SUB_INTF_TABLE_NAME,
50+
CFG_VOQ_INBAND_INTERFACE_TABLE_NAME,
5051
};
5152

5253
DBConnector cfgDb("CONFIG_DB", 0);

cfgmgr/nbrmgr.cpp

+261-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "nbrmgr.h"
1212
#include "exec.h"
1313
#include "shellcmd.h"
14+
#include "subscriberstatetable.h"
1415

1516
using namespace swss;
1617

@@ -64,6 +65,20 @@ NbrMgr::NbrMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, con
6465
TableConsumable::DEFAULT_POP_BATCH_SIZE, default_orch_pri);
6566
auto consumer = new Consumer(consumerStateTable, this, APP_NEIGH_RESOLVE_TABLE_NAME);
6667
Orch::addExecutor(consumer);
68+
69+
string swtype;
70+
Table cfgDeviceMetaDataTable(cfgDb, CFG_DEVICE_METADATA_TABLE_NAME);
71+
if(cfgDeviceMetaDataTable.hget("localhost", "switch_type", swtype))
72+
{
73+
//If this is voq system, let the neighbor manager subscribe to state of SYSTEM_NEIGH
74+
//entries. This is used to program static neigh and static route in kernel for remote neighbors.
75+
if(swtype == "voq")
76+
{
77+
string tableName = STATE_SYSTEM_NEIGH_TABLE_NAME;
78+
Orch::addExecutor(new Consumer(new SubscriberStateTable(stateDb, tableName, TableConsumable::DEFAULT_POP_BATCH_SIZE, 0), this, tableName));
79+
m_cfgVoqInbandInterfaceTable = unique_ptr<Table>(new Table(cfgDb, CFG_VOQ_INBAND_INTERFACE_TABLE_NAME));
80+
}
81+
}
6782
}
6883

6984
bool NbrMgr::isIntfStateOk(const string &alias)
@@ -294,8 +309,253 @@ void NbrMgr::doTask(Consumer &consumer)
294309
} else if (table_name == APP_NEIGH_RESOLVE_TABLE_NAME)
295310
{
296311
doResolveNeighTask(consumer);
297-
} else
312+
} else if(table_name == STATE_SYSTEM_NEIGH_TABLE_NAME)
313+
{
314+
doStateSystemNeighTask(consumer);
315+
}
316+
else
298317
{
299318
SWSS_LOG_ERROR("Unknown REDIS table %s ", table_name.c_str());
300319
}
301320
}
321+
322+
void NbrMgr::doStateSystemNeighTask(Consumer &consumer)
323+
{
324+
SWSS_LOG_ENTER();
325+
326+
//Get the name of the device on which the neigh and route are
327+
//going to be programmed.
328+
string nbr_odev;
329+
if(!getVoqInbandInterfaceName(nbr_odev))
330+
{
331+
//The inband interface is not available yet
332+
return;
333+
}
334+
335+
auto it = consumer.m_toSync.begin();
336+
while (it != consumer.m_toSync.end())
337+
{
338+
KeyOpFieldsValuesTuple t = it->second;
339+
string key = kfvKey(t);
340+
string op = kfvOp(t);
341+
342+
size_t found = key.find_last_of(state_db_key_delimiter);
343+
if (found == string::npos)
344+
{
345+
SWSS_LOG_ERROR("Failed to parse key %s", key.c_str());
346+
it = consumer.m_toSync.erase(it);
347+
continue;
348+
}
349+
350+
IpAddress ip_address(key.substr(found+1));
351+
if (op == SET_COMMAND)
352+
{
353+
MacAddress mac_address;
354+
for (auto i = kfvFieldsValues(t).begin();
355+
i != kfvFieldsValues(t).end(); i++)
356+
{
357+
if (fvField(*i) == "neigh")
358+
mac_address = MacAddress(fvValue(*i));
359+
}
360+
361+
if (!isIntfStateOk(nbr_odev))
362+
{
363+
SWSS_LOG_DEBUG("Interface %s is not ready, skipping system neigh %s'", nbr_odev.c_str(), kfvKey(t).c_str());
364+
it++;
365+
continue;
366+
}
367+
368+
if (!addKernelNeigh(nbr_odev, ip_address, mac_address))
369+
{
370+
SWSS_LOG_ERROR("Neigh entry add on dev %s failed for '%s'", nbr_odev.c_str(), kfvKey(t).c_str());
371+
it++;
372+
continue;
373+
}
374+
else
375+
{
376+
SWSS_LOG_NOTICE("Neigh entry added on dev %s for '%s'", nbr_odev.c_str(), kfvKey(t).c_str());
377+
}
378+
379+
if (!addKernelRoute(nbr_odev, ip_address))
380+
{
381+
SWSS_LOG_ERROR("Route entry add on dev %s failed for '%s'", nbr_odev.c_str(), kfvKey(t).c_str());
382+
delKernelNeigh(nbr_odev, ip_address);
383+
it++;
384+
continue;
385+
}
386+
else
387+
{
388+
SWSS_LOG_NOTICE("Route entry added on dev %s for '%s'", nbr_odev.c_str(), kfvKey(t).c_str());
389+
}
390+
SWSS_LOG_NOTICE("Added voq neighbor %s to kernel", kfvKey(t).c_str());
391+
}
392+
else if (op == DEL_COMMAND)
393+
{
394+
if (!delKernelRoute(ip_address))
395+
{
396+
SWSS_LOG_ERROR("Route entry on dev %s delete failed for '%s'", nbr_odev.c_str(), kfvKey(t).c_str());
397+
}
398+
else
399+
{
400+
SWSS_LOG_NOTICE("Route entry on dev %s deleted for '%s'", nbr_odev.c_str(), kfvKey(t).c_str());
401+
}
402+
403+
if (!delKernelNeigh(nbr_odev, ip_address))
404+
{
405+
SWSS_LOG_ERROR("Neigh entry on dev %s delete failed for '%s'", nbr_odev.c_str(), kfvKey(t).c_str());
406+
}
407+
else
408+
{
409+
SWSS_LOG_NOTICE("Neigh entry on dev %s deleted for '%s'", nbr_odev.c_str(), kfvKey(t).c_str());
410+
}
411+
SWSS_LOG_DEBUG("Deleted voq neighbor %s from kernel", kfvKey(t).c_str());
412+
}
413+
414+
it = consumer.m_toSync.erase(it);
415+
}
416+
}
417+
418+
bool NbrMgr::getVoqInbandInterfaceName(string &ibif)
419+
{
420+
421+
vector<string> keys;
422+
m_cfgVoqInbandInterfaceTable->getKeys(keys);
423+
424+
if (keys.empty())
425+
{
426+
SWSS_LOG_NOTICE("Voq Inband interface is not configured!");
427+
return false;
428+
}
429+
//key:"alias" = inband interface name
430+
vector<string> if_keys = tokenize(keys[0], config_db_key_delimiter);
431+
ibif = if_keys[0];
432+
return true;
433+
}
434+
435+
bool NbrMgr::addKernelRoute(string odev, IpAddress ip_addr)
436+
{
437+
string cmd, res;
438+
439+
SWSS_LOG_ENTER();
440+
441+
string ip_str = ip_addr.to_string();
442+
443+
if(ip_addr.isV4())
444+
{
445+
cmd = string("") + IP_CMD + " route add " + ip_str + "/32 dev " + odev;
446+
SWSS_LOG_NOTICE("IPv4 Route Add cmd: %s",cmd.c_str());
447+
}
448+
else
449+
{
450+
cmd = string("") + IP_CMD + " -6 route add " + ip_str + "/128 dev " + odev;
451+
SWSS_LOG_NOTICE("IPv6 Route Add cmd: %s",cmd.c_str());
452+
}
453+
454+
int32_t ret = swss::exec(cmd, res);
455+
456+
if(ret)
457+
{
458+
/* Just log error and return */
459+
SWSS_LOG_ERROR("Failed to add route for %s, error: %d", ip_str.c_str(), ret);
460+
return false;
461+
}
462+
463+
SWSS_LOG_INFO("Added route for %s on device %s", ip_str.c_str(), odev.c_str());
464+
return true;
465+
}
466+
467+
bool NbrMgr::delKernelRoute(IpAddress ip_addr)
468+
{
469+
string cmd, res;
470+
471+
SWSS_LOG_ENTER();
472+
473+
string ip_str = ip_addr.to_string();
474+
475+
if(ip_addr.isV4())
476+
{
477+
cmd = string("") + IP_CMD + " route del " + ip_str + "/32";
478+
SWSS_LOG_NOTICE("IPv4 Route Del cmd: %s",cmd.c_str());
479+
}
480+
else
481+
{
482+
cmd = string("") + IP_CMD + " -6 route del " + ip_str + "/128";
483+
SWSS_LOG_NOTICE("IPv6 Route Del cmd: %s",cmd.c_str());
484+
}
485+
486+
int32_t ret = swss::exec(cmd, res);
487+
488+
if(ret)
489+
{
490+
/* Just log error and return */
491+
SWSS_LOG_ERROR("Failed to delete route for %s, error: %d", ip_str.c_str(), ret);
492+
return false;
493+
}
494+
495+
SWSS_LOG_INFO("Deleted route for %s", ip_str.c_str());
496+
return true;
497+
}
498+
499+
bool NbrMgr::addKernelNeigh(string odev, IpAddress ip_addr, MacAddress mac_addr)
500+
{
501+
SWSS_LOG_ENTER();
502+
503+
string cmd, res;
504+
string ip_str = ip_addr.to_string();
505+
string mac_str = mac_addr.to_string();
506+
507+
if(ip_addr.isV4())
508+
{
509+
cmd = string("") + IP_CMD + " neigh add " + ip_str + " lladdr " + mac_str + " dev " + odev;
510+
SWSS_LOG_NOTICE("IPv4 Nbr Add cmd: %s",cmd.c_str());
511+
}
512+
else
513+
{
514+
cmd = string("") + IP_CMD + " -6 neigh add " + ip_str + " lladdr " + mac_str + " dev " + odev;
515+
SWSS_LOG_NOTICE("IPv6 Nbr Add cmd: %s",cmd.c_str());
516+
}
517+
518+
int32_t ret = swss::exec(cmd, res);
519+
520+
if(ret)
521+
{
522+
/* Just log error and return */
523+
SWSS_LOG_ERROR("Failed to add Nbr for %s, error: %d", ip_str.c_str(), ret);
524+
return false;
525+
}
526+
527+
SWSS_LOG_INFO("Added Nbr for %s on interface %s", ip_str.c_str(), odev.c_str());
528+
return true;
529+
}
530+
531+
bool NbrMgr::delKernelNeigh(string odev, IpAddress ip_addr)
532+
{
533+
string cmd, res;
534+
535+
SWSS_LOG_ENTER();
536+
537+
string ip_str = ip_addr.to_string();
538+
539+
if(ip_addr.isV4())
540+
{
541+
cmd = string("") + IP_CMD + " neigh del " + ip_str + " dev " + odev;
542+
SWSS_LOG_NOTICE("IPv4 Nbr Del cmd: %s",cmd.c_str());
543+
}
544+
else
545+
{
546+
cmd = string("") + IP_CMD + " -6 neigh del " + ip_str + " dev " + odev;
547+
SWSS_LOG_NOTICE("IPv6 Nbr Del cmd: %s",cmd.c_str());
548+
}
549+
550+
int32_t ret = swss::exec(cmd, res);
551+
552+
if(ret)
553+
{
554+
/* Just log error and return */
555+
SWSS_LOG_ERROR("Failed to delete Nbr for %s, error: %d", ip_str.c_str(), ret);
556+
return false;
557+
}
558+
559+
SWSS_LOG_INFO("Deleted Nbr for %s on interface %s", ip_str.c_str(), odev.c_str());
560+
return true;
561+
}

cfgmgr/nbrmgr.h

+7
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ class NbrMgr : public Orch
2929
void doResolveNeighTask(Consumer &consumer);
3030
void doSetNeighTask(Consumer &consumer);
3131
void doTask(Consumer &consumer);
32+
void doStateSystemNeighTask(Consumer &consumer);
33+
bool getVoqInbandInterfaceName(string &nbr_odev);
34+
bool addKernelRoute(string odev, IpAddress ip_addr);
35+
bool delKernelRoute(IpAddress ip_addr);
36+
bool addKernelNeigh(string odev, IpAddress ip_addr, MacAddress mac_addr);
37+
bool delKernelNeigh(string odev, IpAddress ip_addr);
38+
unique_ptr<Table> m_cfgVoqInbandInterfaceTable;
3239

3340
Table m_statePortTable, m_stateLagTable, m_stateVlanTable, m_stateIntfTable, m_stateNeighRestoreTable;
3441
struct nl_sock *m_nl_sock;

0 commit comments

Comments
 (0)