Skip to content

Commit 4df9c28

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 44a8845 commit 4df9c28

File tree

9 files changed

+453
-89
lines changed

9 files changed

+453
-89
lines changed

orchagent/aclorch.cpp

Lines changed: 118 additions & 36 deletions
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

@@ -1361,8 +1361,8 @@ bool AclRange::remove()
13611361
return true;
13621362
}
13631363

1364-
AclOrch::AclOrch(DBConnector *db, vector<string> tableNames, PortsOrch *portOrch, MirrorOrch *mirrorOrch, NeighOrch *neighOrch, RouteOrch *routeOrch) :
1365-
Orch(db, tableNames),
1364+
AclOrch::AclOrch(vector<TableConnector>& connectors, PortsOrch *portOrch, MirrorOrch *mirrorOrch, NeighOrch *neighOrch, RouteOrch *routeOrch) :
1365+
Orch(connectors),
13661366
m_mirrorOrch(mirrorOrch),
13671367
m_neighOrch(neighOrch),
13681368
m_routeOrch(routeOrch)
@@ -1445,6 +1445,11 @@ void AclOrch::doTask(Consumer &consumer)
14451445
unique_lock<mutex> lock(m_countersMutex);
14461446
doAclRuleTask(consumer);
14471447
}
1448+
else if (table_name == STATE_LAG_TABLE_NAME)
1449+
{
1450+
unique_lock<mutex> lock(m_countersMutex);
1451+
doAclTablePortUpdateTask(consumer);
1452+
}
14481453
else
14491454
{
14501455
SWSS_LOG_ERROR("Invalid table %s", table_name.c_str());
@@ -1545,7 +1550,7 @@ void AclOrch::doAclTableTask(Consumer &consumer)
15451550
{
15461551
KeyOpFieldsValuesTuple t = it->second;
15471552
string key = kfvKey(t);
1548-
size_t found = key.find('|');
1553+
size_t found = key.find(consumer.getConsumerTable()->getTableNameSeparator().c_str());
15491554
string table_id = key.substr(0, found);
15501555
string op = kfvOp(t);
15511556

@@ -1580,7 +1585,7 @@ void AclOrch::doAclTableTask(Consumer &consumer)
15801585
}
15811586
else if (attr_name == TABLE_PORTS)
15821587
{
1583-
bool suc = processPorts(attr_value, [&](sai_object_id_t portOid) {
1588+
bool suc = processPorts(newTable, attr_value, [&](sai_object_id_t portOid) {
15841589
newTable.link(portOid);
15851590
});
15861591

@@ -1645,7 +1650,7 @@ void AclOrch::doAclRuleTask(Consumer &consumer)
16451650
{
16461651
KeyOpFieldsValuesTuple t = it->second;
16471652
string key = kfvKey(t);
1648-
size_t found = key.find('|');
1653+
size_t found = key.find(consumer.getConsumerTable()->getTableNameSeparator().c_str());
16491654
string table_id = key.substr(0, found);
16501655
string rule_id = key.substr(found + 1);
16511656
string op = kfvOp(t);
@@ -1725,17 +1730,79 @@ void AclOrch::doAclRuleTask(Consumer &consumer)
17251730
}
17261731
}
17271732

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

17321798
vector<string> strList;
17331799

1734-
SWSS_LOG_INFO("Processing ACL table port list %s", portsList.c_str());
1800+
SWSS_LOG_DEBUG("Processing ACL table port list %s", portsList.c_str());
17351801

17361802
split(portsList, strList, ',');
17371803

17381804
set<string> strSet(strList.begin(), strList.end());
1805+
aclTable.portSet = strSet;
17391806

17401807
if (strList.size() != strSet.size())
17411808
{
@@ -1751,33 +1818,52 @@ bool AclOrch::processPorts(string portsList, std::function<void (sai_object_id_t
17511818

17521819
for (const auto& alias : strList)
17531820
{
1821+
sai_object_id_t port_id;
17541822
Port port;
17551823
if (!gPortsOrch->getPort(alias, port))
17561824
{
1757-
SWSS_LOG_ERROR("Failed to process port. Port %s doesn't exist", alias.c_str());
1758-
return false;
1825+
SWSS_LOG_INFO("Port %s not configured yet, add it to ACL table %s pending list", alias.c_str(), aclTable.description.c_str());
1826+
aclTable.pendingPortSet.emplace(alias);
1827+
continue;
17591828
}
17601829

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

17831869
return true;
@@ -1894,18 +1980,14 @@ sai_status_t AclOrch::bindAclTable(sai_object_id_t table_oid, AclTable &aclTable
18941980
sai_status_t status = SAI_STATUS_SUCCESS;
18951981

18961982
SWSS_LOG_INFO("%s table %s to ports", bind ? "Bind" : "Unbind", aclTable.id.c_str());
1897-
1983+
18981984
if (aclTable.ports.empty())
18991985
{
19001986
if (bind)
19011987
{
1902-
SWSS_LOG_ERROR("Port list is not configured for %s table", aclTable.id.c_str());
1903-
return SAI_STATUS_FAILURE;
1904-
}
1905-
else
1906-
{
1907-
return SAI_STATUS_SUCCESS;
1988+
SWSS_LOG_WARN("Binding port list is empty for %s table", aclTable.id.c_str());
19081989
}
1990+
return SAI_STATUS_SUCCESS;
19091991
}
19101992

19111993
if (bind)

orchagent/aclorch.h

Lines changed: 8 additions & 2 deletions
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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,13 +247,15 @@ int main(int argc, char **argv)
247247
SWSS_LOG_NOTICE("Created underlay router interface ID %lx", gUnderlayIfId);
248248

249249
/* Initialize orchestration components */
250-
DBConnector *appl_db = new DBConnector(APPL_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
251-
DBConnector *config_db = new DBConnector(CONFIG_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
250+
DBConnector appl_db(APPL_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
251+
DBConnector config_db(CONFIG_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
252+
DBConnector state_db(STATE_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
252253

253-
OrchDaemon *orchDaemon = new OrchDaemon(appl_db, config_db);
254+
OrchDaemon *orchDaemon = new OrchDaemon(&appl_db, &config_db, &state_db);
254255
if (!orchDaemon->init())
255256
{
256257
SWSS_LOG_ERROR("Failed to initialize orchstration daemon");
258+
delete orchDaemon;
257259
exit(EXIT_FAILURE);
258260
}
259261

@@ -268,6 +270,7 @@ int main(int argc, char **argv)
268270
if (status != SAI_STATUS_SUCCESS)
269271
{
270272
SWSS_LOG_ERROR("Failed to notify syncd APPLY_VIEW %d", status);
273+
delete orchDaemon;
271274
exit(EXIT_FAILURE);
272275
}
273276

@@ -282,5 +285,6 @@ int main(int argc, char **argv)
282285
SWSS_LOG_ERROR("Failed due to exception: %s", e.what());
283286
}
284287

288+
delete orchDaemon;
285289
return 0;
286290
}

orchagent/orch.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ bool Orch::parseIndexRange(const string &input, sai_uint32_t &range_low, sai_uin
360360

361361
void Orch::addConsumer(DBConnector *db, string tableName, int pri)
362362
{
363-
if (db->getDbId() == CONFIG_DB)
363+
if (db->getDbId() == CONFIG_DB || db->getDbId() == STATE_DB)
364364
{
365365
addExecutor(tableName, new Consumer(new SubscriberStateTable(db, tableName, TableConsumable::DEFAULT_POP_BATCH_SIZE, pri), this));
366366
}

orchagent/orchdaemon.cpp

Lines changed: 13 additions & 9 deletions
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()
@@ -99,11 +97,17 @@ bool OrchDaemon::init()
9997
MirrorOrch *mirror_orch = new MirrorOrch(appDbMirrorSession, confDbMirrorSession, gPortsOrch, gRouteOrch, gNeighOrch, gFdbOrch);
10098
VRFOrch *vrf_orch = new VRFOrch(m_configDb, CFG_VRF_TABLE_NAME);
10199

102-
vector<string> acl_tables = {
103-
CFG_ACL_TABLE_NAME,
104-
CFG_ACL_RULE_TABLE_NAME
100+
TableConnector confDbAclTable(m_configDb, CFG_ACL_TABLE_NAME);
101+
TableConnector confDbAclRuleTable(m_configDb, CFG_ACL_RULE_TABLE_NAME);
102+
TableConnector stateDbLagTable(m_stateDb, STATE_LAG_TABLE_NAME);
103+
104+
vector<TableConnector> acl_table_connectors = {
105+
confDbAclTable,
106+
confDbAclRuleTable,
107+
stateDbLagTable
105108
};
106-
gAclOrch = new AclOrch(m_configDb, acl_tables, gPortsOrch, mirror_orch, gNeighOrch, gRouteOrch);
109+
110+
gAclOrch = new AclOrch(acl_table_connectors, gPortsOrch, mirror_orch, gNeighOrch, gRouteOrch);
107111

108112
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 };
109113
m_select = new Select();

orchagent/orchdaemon.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@ using namespace swss;
2929
class OrchDaemon
3030
{
3131
public:
32-
OrchDaemon(DBConnector *, DBConnector *);
32+
OrchDaemon(DBConnector *, DBConnector *, DBConnector *);
3333
~OrchDaemon();
3434

3535
bool init();
3636
void start();
3737
private:
3838
DBConnector *m_applDb;
3939
DBConnector *m_configDb;
40+
DBConnector *m_stateDb;
4041

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

0 commit comments

Comments
 (0)