Skip to content

Commit 0f43351

Browse files
keboliuqiluo-msft
authored andcommitted
[AclOrch] aclOrch enhancement to handle LAG port not configured case (sonic-net#494)
* enhance acl orch to handle the LAG port not configured case * rename variable, function; redunce redundant code; fix memory issue * revise according to comments * one more blank line * add new VS test cases for acl on LAG * update with PR comments fix * rename getValidPortId and move it to portOrch * fix indent * fix test case comments
1 parent a1b6fa3 commit 0f43351

File tree

9 files changed

+566
-89
lines changed

9 files changed

+566
-89
lines changed

orchagent/aclorch.cpp

+118-36
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@ bool AclTable::validate()
936936
{
937937
// Control plane ACLs are handled by a separate process
938938
if (type == ACL_TABLE_UNKNOWN || type == ACL_TABLE_CTRLPLANE) return false;
939-
if (ports.empty()) return false;
939+
if (portSet.empty()) return false;
940940
return true;
941941
}
942942

@@ -1365,8 +1365,8 @@ bool AclRange::remove()
13651365
return true;
13661366
}
13671367

1368-
AclOrch::AclOrch(DBConnector *db, vector<string> tableNames, PortsOrch *portOrch, MirrorOrch *mirrorOrch, NeighOrch *neighOrch, RouteOrch *routeOrch) :
1369-
Orch(db, tableNames),
1368+
AclOrch::AclOrch(vector<TableConnector>& connectors, PortsOrch *portOrch, MirrorOrch *mirrorOrch, NeighOrch *neighOrch, RouteOrch *routeOrch) :
1369+
Orch(connectors),
13701370
m_mirrorOrch(mirrorOrch),
13711371
m_neighOrch(neighOrch),
13721372
m_routeOrch(routeOrch)
@@ -1449,6 +1449,11 @@ void AclOrch::doTask(Consumer &consumer)
14491449
unique_lock<mutex> lock(m_countersMutex);
14501450
doAclRuleTask(consumer);
14511451
}
1452+
else if (table_name == STATE_LAG_TABLE_NAME)
1453+
{
1454+
unique_lock<mutex> lock(m_countersMutex);
1455+
doAclTablePortUpdateTask(consumer);
1456+
}
14521457
else
14531458
{
14541459
SWSS_LOG_ERROR("Invalid table %s", table_name.c_str());
@@ -1549,7 +1554,7 @@ void AclOrch::doAclTableTask(Consumer &consumer)
15491554
{
15501555
KeyOpFieldsValuesTuple t = it->second;
15511556
string key = kfvKey(t);
1552-
size_t found = key.find('|');
1557+
size_t found = key.find(consumer.getConsumerTable()->getTableNameSeparator().c_str());
15531558
string table_id = key.substr(0, found);
15541559
string op = kfvOp(t);
15551560

@@ -1584,7 +1589,7 @@ void AclOrch::doAclTableTask(Consumer &consumer)
15841589
}
15851590
else if (attr_name == TABLE_PORTS)
15861591
{
1587-
bool suc = processPorts(attr_value, [&](sai_object_id_t portOid) {
1592+
bool suc = processPorts(newTable, attr_value, [&](sai_object_id_t portOid) {
15881593
newTable.link(portOid);
15891594
});
15901595

@@ -1649,7 +1654,7 @@ void AclOrch::doAclRuleTask(Consumer &consumer)
16491654
{
16501655
KeyOpFieldsValuesTuple t = it->second;
16511656
string key = kfvKey(t);
1652-
size_t found = key.find('|');
1657+
size_t found = key.find(consumer.getConsumerTable()->getTableNameSeparator().c_str());
16531658
string table_id = key.substr(0, found);
16541659
string rule_id = key.substr(found + 1);
16551660
string op = kfvOp(t);
@@ -1729,17 +1734,79 @@ void AclOrch::doAclRuleTask(Consumer &consumer)
17291734
}
17301735
}
17311736

1732-
bool AclOrch::processPorts(string portsList, std::function<void (sai_object_id_t)> inserter)
1737+
void AclOrch::doAclTablePortUpdateTask(Consumer &consumer)
1738+
{
1739+
SWSS_LOG_ENTER();
1740+
1741+
auto it = consumer.m_toSync.begin();
1742+
while (it != consumer.m_toSync.end())
1743+
{
1744+
KeyOpFieldsValuesTuple t = it->second;
1745+
string key = kfvKey(t);
1746+
size_t found = key.find(consumer.getConsumerTable()->getTableNameSeparator().c_str());
1747+
string port_alias = key.substr(0, found);
1748+
string op = kfvOp(t);
1749+
1750+
SWSS_LOG_INFO("doAclTablePortUpdateTask: OP: %s, port_alias: %s", op.c_str(), port_alias.c_str());
1751+
1752+
if (op == SET_COMMAND)
1753+
{
1754+
for (auto itmap : m_AclTables)
1755+
{
1756+
auto table = itmap.second;
1757+
if (table.pendingPortSet.find(port_alias) != table.pendingPortSet.end())
1758+
{
1759+
SWSS_LOG_INFO("found the port: %s in ACL table: %s pending port list, bind it to ACL table.", port_alias.c_str(), table.description.c_str());
1760+
1761+
bool suc = processPendingPort(table, port_alias, [&](sai_object_id_t portOid) {
1762+
table.link(portOid);
1763+
});
1764+
1765+
if (!suc)
1766+
{
1767+
SWSS_LOG_ERROR("Failed to bind the ACL table: %s to port: %s", table.description.c_str(), port_alias.c_str());
1768+
}
1769+
else
1770+
{
1771+
table.pendingPortSet.erase(port_alias);
1772+
SWSS_LOG_DEBUG("port: %s bound to ACL table table: %s, remove it from pending list", port_alias.c_str(), table.description.c_str());
1773+
}
1774+
}
1775+
}
1776+
}
1777+
else if (op == DEL_COMMAND)
1778+
{
1779+
for (auto itmap : m_AclTables)
1780+
{
1781+
auto table = itmap.second;
1782+
if (table.portSet.find(port_alias) != table.portSet.end())
1783+
{
1784+
/*TODO: update the ACL table after port/lag deleted*/
1785+
table.pendingPortSet.emplace(port_alias);
1786+
SWSS_LOG_INFO("Add deleted port: %s to the pending list of ACL table: %s", port_alias.c_str(), table.description.c_str());
1787+
}
1788+
}
1789+
}
1790+
else
1791+
{
1792+
SWSS_LOG_ERROR("Unknown operation type %s", op.c_str());
1793+
}
1794+
it = consumer.m_toSync.erase(it);
1795+
}
1796+
}
1797+
1798+
bool AclOrch::processPorts(AclTable &aclTable, string portsList, std::function<void (sai_object_id_t)> inserter)
17331799
{
17341800
SWSS_LOG_ENTER();
17351801

17361802
vector<string> strList;
17371803

1738-
SWSS_LOG_INFO("Processing ACL table port list %s", portsList.c_str());
1804+
SWSS_LOG_DEBUG("Processing ACL table port list %s", portsList.c_str());
17391805

17401806
split(portsList, strList, ',');
17411807

17421808
set<string> strSet(strList.begin(), strList.end());
1809+
aclTable.portSet = strSet;
17431810

17441811
if (strList.size() != strSet.size())
17451812
{
@@ -1755,33 +1822,52 @@ bool AclOrch::processPorts(string portsList, std::function<void (sai_object_id_t
17551822

17561823
for (const auto& alias : strList)
17571824
{
1825+
sai_object_id_t port_id;
17581826
Port port;
17591827
if (!gPortsOrch->getPort(alias, port))
17601828
{
1761-
SWSS_LOG_ERROR("Failed to process port. Port %s doesn't exist", alias.c_str());
1762-
return false;
1829+
SWSS_LOG_INFO("Port %s not configured yet, add it to ACL table %s pending list", alias.c_str(), aclTable.description.c_str());
1830+
aclTable.pendingPortSet.emplace(alias);
1831+
continue;
17631832
}
17641833

1765-
switch (port.m_type)
1834+
if (gPortsOrch->getAclBindPortId(alias, port_id))
17661835
{
1767-
case Port::PHY:
1768-
if (port.m_lag_member_id != SAI_NULL_OBJECT_ID)
1769-
{
1770-
SWSS_LOG_ERROR("Failed to process port. Bind table to LAG member %s is not allowed", alias.c_str());
1771-
return false;
1772-
}
1773-
inserter(port.m_port_id);
1774-
break;
1775-
case Port::LAG:
1776-
inserter(port.m_lag_id);
1777-
break;
1778-
case Port::VLAN:
1779-
inserter(port.m_vlan_info.vlan_oid);
1780-
break;
1781-
default:
1782-
SWSS_LOG_ERROR("Failed to process port. Incorrect port %s type %d", alias.c_str(), port.m_type);
1783-
return false;
1784-
}
1836+
inserter(port_id);
1837+
}
1838+
else
1839+
{
1840+
return false;
1841+
}
1842+
}
1843+
1844+
return true;
1845+
}
1846+
1847+
bool AclOrch::processPendingPort(AclTable &aclTable, string portAlias, std::function<void (sai_object_id_t)> inserter)
1848+
{
1849+
SWSS_LOG_ENTER();
1850+
1851+
SWSS_LOG_DEBUG("Processing ACL table port %s", portAlias.c_str());
1852+
1853+
sai_object_id_t port_id;
1854+
1855+
Port port;
1856+
if (!gPortsOrch->getPort(portAlias, port))
1857+
{
1858+
SWSS_LOG_INFO("Port %s not configured yet, add it to ACL table %s pending list", portAlias.c_str(), aclTable.description.c_str());
1859+
aclTable.pendingPortSet.insert(portAlias);
1860+
return true;
1861+
}
1862+
1863+
if (gPortsOrch->getAclBindPortId(portAlias, port_id))
1864+
{
1865+
inserter(port_id);
1866+
aclTable.bind(port_id);
1867+
}
1868+
else
1869+
{
1870+
return false;
17851871
}
17861872

17871873
return true;
@@ -1898,18 +1984,14 @@ sai_status_t AclOrch::bindAclTable(sai_object_id_t table_oid, AclTable &aclTable
18981984
sai_status_t status = SAI_STATUS_SUCCESS;
18991985

19001986
SWSS_LOG_INFO("%s table %s to ports", bind ? "Bind" : "Unbind", aclTable.id.c_str());
1901-
1987+
19021988
if (aclTable.ports.empty())
19031989
{
19041990
if (bind)
19051991
{
1906-
SWSS_LOG_ERROR("Port list is not configured for %s table", aclTable.id.c_str());
1907-
return SAI_STATUS_FAILURE;
1908-
}
1909-
else
1910-
{
1911-
return SAI_STATUS_SUCCESS;
1992+
SWSS_LOG_WARN("Binding port list is empty for %s table", aclTable.id.c_str());
19121993
}
1994+
return SAI_STATUS_SUCCESS;
19131995
}
19141996

19151997
if (bind)

orchagent/aclorch.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,10 @@ class AclTable {
248248
std::map<sai_object_id_t, sai_object_id_t> ports;
249249
// Map rule name to rule data
250250
map<string, shared_ptr<AclRule>> rules;
251+
// Set to store the ACL table port alias
252+
set<string> portSet;
253+
// Set to store the not cofigured ACL table port alias
254+
set<string> pendingPortSet;
251255

252256
AclTable()
253257
: type(ACL_TABLE_UNKNOWN)
@@ -294,7 +298,7 @@ inline void split(string str, Iterable& out, char delim = ' ')
294298
class AclOrch : public Orch, public Observer
295299
{
296300
public:
297-
AclOrch(DBConnector *db, vector<string> tableNames, PortsOrch *portOrch, MirrorOrch *mirrorOrch, NeighOrch *neighOrch, RouteOrch *routeOrch);
301+
AclOrch(vector<TableConnector>& connectors, PortsOrch *portOrch, MirrorOrch *mirrorOrch, NeighOrch *neighOrch, RouteOrch *routeOrch);
298302
~AclOrch();
299303
void update(SubjectType, void *);
300304

@@ -319,6 +323,7 @@ class AclOrch : public Orch, public Observer
319323
void doTask(Consumer &consumer);
320324
void doAclTableTask(Consumer &consumer);
321325
void doAclRuleTask(Consumer &consumer);
326+
void doAclTablePortUpdateTask(Consumer &consumer);
322327
void doTask(SelectableTimer &timer);
323328

324329
static void collectCountersThread(AclOrch *pAclOrch);
@@ -329,7 +334,8 @@ class AclOrch : public Orch, public Observer
329334

330335
bool processAclTableType(string type, acl_table_type_t &table_type);
331336
bool processAclTableStage(string stage, acl_stage_type_t &acl_stage);
332-
bool processPorts(string portsList, std::function<void (sai_object_id_t)> inserter);
337+
bool processPorts(AclTable &aclTable, string portsList, std::function<void (sai_object_id_t)> inserter);
338+
bool processPendingPort(AclTable &aclTable, string portAlias, std::function<void (sai_object_id_t)> inserter);
333339
bool validateAclTable(AclTable &aclTable);
334340

335341
//vector <AclTable> m_AclTables;

orchagent/main.cpp

+7-3
Original file line numberDiff line numberDiff line change
@@ -251,13 +251,15 @@ int main(int argc, char **argv)
251251
SWSS_LOG_NOTICE("Created underlay router interface ID %lx", gUnderlayIfId);
252252

253253
/* Initialize orchestration components */
254-
DBConnector *appl_db = new DBConnector(APPL_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
255-
DBConnector *config_db = new DBConnector(CONFIG_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
254+
DBConnector appl_db(APPL_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
255+
DBConnector config_db(CONFIG_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
256+
DBConnector state_db(STATE_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
256257

257-
OrchDaemon *orchDaemon = new OrchDaemon(appl_db, config_db);
258+
OrchDaemon *orchDaemon = new OrchDaemon(&appl_db, &config_db, &state_db);
258259
if (!orchDaemon->init())
259260
{
260261
SWSS_LOG_ERROR("Failed to initialize orchstration daemon");
262+
delete orchDaemon;
261263
exit(EXIT_FAILURE);
262264
}
263265

@@ -272,6 +274,7 @@ int main(int argc, char **argv)
272274
if (status != SAI_STATUS_SUCCESS)
273275
{
274276
SWSS_LOG_ERROR("Failed to notify syncd APPLY_VIEW %d", status);
277+
delete orchDaemon;
275278
exit(EXIT_FAILURE);
276279
}
277280

@@ -286,5 +289,6 @@ int main(int argc, char **argv)
286289
SWSS_LOG_ERROR("Failed due to exception: %s", e.what());
287290
}
288291

292+
delete orchDaemon;
289293
return 0;
290294
}

orchagent/orch.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ bool Orch::parseIndexRange(const string &input, sai_uint32_t &range_low, sai_uin
358358

359359
void Orch::addConsumer(DBConnector *db, string tableName)
360360
{
361-
if (db->getDB() == CONFIG_DB)
361+
if (db->getDB() == CONFIG_DB || db->getDB() == STATE_DB)
362362
{
363363
addExecutor(tableName, new Consumer(new SubscriberStateTable(db, tableName), this));
364364
}

orchagent/orchdaemon.cpp

+13-9
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ RouteOrch *gRouteOrch;
2727
AclOrch *gAclOrch;
2828
CrmOrch *gCrmOrch;
2929

30-
OrchDaemon::OrchDaemon(DBConnector *applDb, DBConnector *configDb) :
30+
OrchDaemon::OrchDaemon(DBConnector *applDb, DBConnector *configDb, DBConnector *stateDb) :
3131
m_applDb(applDb),
32-
m_configDb(configDb)
32+
m_configDb(configDb),
33+
m_stateDb(stateDb)
3334
{
3435
SWSS_LOG_ENTER();
3536
}
@@ -39,9 +40,6 @@ OrchDaemon::~OrchDaemon()
3940
SWSS_LOG_ENTER();
4041
for (Orch *o : m_orchList)
4142
delete(o);
42-
43-
delete(m_configDb);
44-
delete(m_applDb);
4543
}
4644

4745
bool OrchDaemon::init()
@@ -97,11 +95,17 @@ bool OrchDaemon::init()
9795
MirrorOrch *mirror_orch = new MirrorOrch(appDbMirrorSession, confDbMirrorSession, gPortsOrch, gRouteOrch, gNeighOrch, gFdbOrch);
9896
VRFOrch *vrf_orch = new VRFOrch(m_configDb, CFG_VRF_TABLE_NAME);
9997

100-
vector<string> acl_tables = {
101-
CFG_ACL_TABLE_NAME,
102-
CFG_ACL_RULE_TABLE_NAME
98+
TableConnector confDbAclTable(m_configDb, CFG_ACL_TABLE_NAME);
99+
TableConnector confDbAclRuleTable(m_configDb, CFG_ACL_RULE_TABLE_NAME);
100+
TableConnector stateDbLagTable(m_stateDb, STATE_LAG_TABLE_NAME);
101+
102+
vector<TableConnector> acl_table_connectors = {
103+
confDbAclTable,
104+
confDbAclRuleTable,
105+
stateDbLagTable
103106
};
104-
gAclOrch = new AclOrch(m_configDb, acl_tables, gPortsOrch, mirror_orch, gNeighOrch, gRouteOrch);
107+
108+
gAclOrch = new AclOrch(acl_table_connectors, gPortsOrch, mirror_orch, gNeighOrch, gRouteOrch);
105109

106110
m_orchList = { switch_orch, gCrmOrch, gPortsOrch, intfs_orch, gNeighOrch, gRouteOrch, copp_orch, tunnel_decap_orch, qos_orch, buffer_orch, mirror_orch, gAclOrch, gFdbOrch, vrf_orch };
107111
m_select = new Select();

orchagent/orchdaemon.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,15 @@ using namespace swss;
2828
class OrchDaemon
2929
{
3030
public:
31-
OrchDaemon(DBConnector *, DBConnector *);
31+
OrchDaemon(DBConnector *, DBConnector *, DBConnector *);
3232
~OrchDaemon();
3333

3434
bool init();
3535
void start();
3636
private:
3737
DBConnector *m_applDb;
3838
DBConnector *m_configDb;
39+
DBConnector *m_stateDb;
3940

4041
std::vector<Orch *> m_orchList;
4142
Select *m_select;

0 commit comments

Comments
 (0)