Skip to content

Commit 9d38fbc

Browse files
bingwang-msStormLiangMS
authored andcommitted
[ACL] Write ACL table/rule creation status into STATE_DB (#2662)
* Add status for ACL_TABLE and ACL_RULE in STATE_DB
1 parent 317f43a commit 9d38fbc

File tree

4 files changed

+305
-6
lines changed

4 files changed

+305
-6
lines changed

orchagent/aclorch.cpp

+100
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,14 @@ static map<sai_acl_counter_attr_t, sai_acl_counter_attr_t> aclCounterLookup =
375375
{SAI_ACL_COUNTER_ATTR_ENABLE_PACKET_COUNT, SAI_ACL_COUNTER_ATTR_PACKETS},
376376
};
377377

378+
static map<AclObjectStatus, string> aclObjectStatusLookup =
379+
{
380+
{AclObjectStatus::ACTIVE, "Active"},
381+
{AclObjectStatus::INACTIVE, "Inactive"},
382+
{AclObjectStatus::PENDING_CREATION, "Pending creation"},
383+
{AclObjectStatus::PENDING_REMOVAL, "Pending removal"}
384+
};
385+
378386
static sai_acl_table_attr_t AclEntryFieldToAclTableField(sai_acl_entry_attr_t attr)
379387
{
380388
if (!IS_ATTR_ID_IN_RANGE(attr, ACL_ENTRY, FIELD))
@@ -2900,6 +2908,10 @@ void AclOrch::init(vector<TableConnector>& connectors, PortsOrch *portOrch, Mirr
29002908
{
29012909
SWSS_LOG_ENTER();
29022910

2911+
// Clear ACL_TABLE and ACL_RULE status from STATE_DB
2912+
removeAllAclTableStatus();
2913+
removeAllAclRuleStatus();
2914+
29032915
// TODO: Query SAI to get mirror table capabilities
29042916
// Right now, verified platforms that support mirroring IPv6 packets are
29052917
// Broadcom and Mellanox. Virtual switch is also supported for testing
@@ -3407,6 +3419,8 @@ AclOrch::AclOrch(vector<TableConnector>& connectors, DBConnector* stateDb, Switc
34073419
PortsOrch *portOrch, MirrorOrch *mirrorOrch, NeighOrch *neighOrch, RouteOrch *routeOrch, DTelOrch *dtelOrch) :
34083420
Orch(connectors),
34093421
m_aclStageCapabilityTable(stateDb, STATE_ACL_STAGE_CAPABILITY_TABLE_NAME),
3422+
m_aclTableStateTable(stateDb, STATE_ACL_TABLE_TABLE_NAME),
3423+
m_aclRuleStateTable(stateDb, STATE_ACL_RULE_TABLE_NAME),
34103424
m_switchOrch(switchOrch),
34113425
m_mirrorOrch(mirrorOrch),
34123426
m_neighOrch(neighOrch),
@@ -4230,6 +4244,8 @@ void AclOrch::doAclTableTask(Consumer &consumer)
42304244
{
42314245
SWSS_LOG_NOTICE("Successfully updated existing ACL table %s",
42324246
table_id.c_str());
4247+
// Mark ACL table as ACTIVE
4248+
setAclTableStatus(table_id, AclObjectStatus::ACTIVE);
42334249
it = consumer.m_toSync.erase(it);
42344250
}
42354251
else
@@ -4242,24 +4258,41 @@ void AclOrch::doAclTableTask(Consumer &consumer)
42424258
else
42434259
{
42444260
if (addAclTable(newTable))
4261+
{
4262+
// Mark ACL table as ACTIVE
4263+
setAclTableStatus(table_id, AclObjectStatus::ACTIVE);
42454264
it = consumer.m_toSync.erase(it);
4265+
}
42464266
else
4267+
{
4268+
setAclTableStatus(table_id, AclObjectStatus::PENDING_CREATION);
42474269
it++;
4270+
}
42484271
}
42494272
}
42504273
else
42514274
{
42524275
it = consumer.m_toSync.erase(it);
4276+
// Mark the ACL table as inactive if the configuration is invalid
4277+
setAclTableStatus(table_id, AclObjectStatus::INACTIVE);
42534278
SWSS_LOG_ERROR("Failed to create ACL table %s, invalid configuration",
42544279
table_id.c_str());
42554280
}
42564281
}
42574282
else if (op == DEL_COMMAND)
42584283
{
42594284
if (removeAclTable(table_id))
4285+
{
4286+
// Remove ACL table status from STATE_DB
4287+
removeAclTableStatus(table_id);
42604288
it = consumer.m_toSync.erase(it);
4289+
}
42614290
else
4291+
{
4292+
// Set the status of ACL_TABLE to pending removal if removeAclTable returns error
4293+
setAclTableStatus(table_id, AclObjectStatus::PENDING_REMOVAL);
42624294
it++;
4295+
}
42634296
}
42644297
else
42654298
{
@@ -4399,22 +4432,37 @@ void AclOrch::doAclRuleTask(Consumer &consumer)
43994432
if (bAllAttributesOk && newRule->validate())
44004433
{
44014434
if (addAclRule(newRule, table_id))
4435+
{
4436+
setAclRuleStatus(table_id, rule_id, AclObjectStatus::ACTIVE);
44024437
it = consumer.m_toSync.erase(it);
4438+
}
44034439
else
4440+
{
4441+
setAclRuleStatus(table_id, rule_id, AclObjectStatus::PENDING_CREATION);
44044442
it++;
4443+
}
44054444
}
44064445
else
44074446
{
44084447
it = consumer.m_toSync.erase(it);
4448+
// Mark the rule inactive if the configuration is invalid
4449+
setAclRuleStatus(table_id, rule_id, AclObjectStatus::INACTIVE);
44094450
SWSS_LOG_ERROR("Failed to create ACL rule. Rule configuration is invalid");
44104451
}
44114452
}
44124453
else if (op == DEL_COMMAND)
44134454
{
44144455
if (removeAclRule(table_id, rule_id))
4456+
{
4457+
removeAclRuleStatus(table_id, rule_id);
44154458
it = consumer.m_toSync.erase(it);
4459+
}
44164460
else
4461+
{
4462+
// Mark pending removal status if removeAclRule returns error
4463+
setAclRuleStatus(table_id, rule_id, AclObjectStatus::PENDING_REMOVAL);
44174464
it++;
4465+
}
44184466
}
44194467
else
44204468
{
@@ -4770,3 +4818,55 @@ bool AclOrch::getAclBindPortId(Port &port, sai_object_id_t &port_id)
47704818

47714819
return true;
47724820
}
4821+
4822+
// Set the status of ACL table in STATE_DB
4823+
void AclOrch::setAclTableStatus(string table_name, AclObjectStatus status)
4824+
{
4825+
vector<FieldValueTuple> fvVector;
4826+
fvVector.emplace_back("status", aclObjectStatusLookup[status]);
4827+
m_aclTableStateTable.set(table_name, fvVector);
4828+
}
4829+
4830+
// Remove the status record of given ACL table from STATE_DB
4831+
void AclOrch::removeAclTableStatus(string table_name)
4832+
{
4833+
m_aclTableStateTable.del(table_name);
4834+
}
4835+
4836+
// Set the status of ACL rule in STATE_DB
4837+
void AclOrch::setAclRuleStatus(string table_name, string rule_name, AclObjectStatus status)
4838+
{
4839+
vector<FieldValueTuple> fvVector;
4840+
fvVector.emplace_back("status", aclObjectStatusLookup[status]);
4841+
m_aclRuleStateTable.set(table_name + string("|") + rule_name, fvVector);
4842+
}
4843+
4844+
// Remove the status record of given ACL rule from STATE_DB
4845+
void AclOrch::removeAclRuleStatus(string table_name, string rule_name)
4846+
{
4847+
m_aclRuleStateTable.del(table_name + string("|") + rule_name);
4848+
}
4849+
4850+
// Remove all ACL table status from STATE_DB
4851+
void AclOrch::removeAllAclTableStatus()
4852+
{
4853+
vector<string> keys;
4854+
m_aclTableStateTable.getKeys(keys);
4855+
4856+
for (auto key : keys)
4857+
{
4858+
m_aclTableStateTable.del(key);
4859+
}
4860+
}
4861+
4862+
// Remove all ACL rule status from STATE_DB
4863+
void AclOrch::removeAllAclRuleStatus()
4864+
{
4865+
vector<string> keys;
4866+
m_aclRuleStateTable.getKeys(keys);
4867+
for (auto key : keys)
4868+
{
4869+
m_aclRuleStateTable.del(key);
4870+
}
4871+
}
4872+

orchagent/aclorch.h

+20
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,14 @@
9898

9999
#define ACL_COUNTER_FLEX_COUNTER_GROUP "ACL_STAT_COUNTER"
100100

101+
enum AclObjectStatus
102+
{
103+
ACTIVE = 0,
104+
INACTIVE,
105+
PENDING_CREATION,
106+
PENDING_REMOVAL
107+
};
108+
101109
struct AclActionCapabilities
102110
{
103111
set<sai_acl_action_type_t> actionList;
@@ -548,6 +556,15 @@ class AclOrch : public Orch, public Observer
548556

549557
string generateAclRuleIdentifierInCountersDb(const AclRule& rule) const;
550558

559+
void setAclTableStatus(string table_name, AclObjectStatus status);
560+
void setAclRuleStatus(string table_name, string rule_name, AclObjectStatus status);
561+
562+
void removeAclTableStatus(string table_name);
563+
void removeAclRuleStatus(string table_name, string rule_name);
564+
565+
void removeAllAclTableStatus();
566+
void removeAllAclRuleStatus();
567+
551568
map<sai_object_id_t, AclTable> m_AclTables;
552569
// TODO: Move all ACL tables into one map: name -> instance
553570
map<string, AclTable> m_ctrlAclTables;
@@ -558,6 +575,9 @@ class AclOrch : public Orch, public Observer
558575

559576
Table m_aclStageCapabilityTable;
560577

578+
Table m_aclTableStateTable;
579+
Table m_aclRuleStateTable;
580+
561581
map<acl_stage_type_t, string> m_mirrorTableId;
562582
map<acl_stage_type_t, string> m_mirrorV6TableId;
563583

tests/dvslib/dvs_acl.py

+44-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Utilities for interacting with ACLs when writing VS tests."""
22
from typing import Callable, Dict, List
3-
3+
from swsscommon import swsscommon
44

55
class DVSAcl:
66
"""Manage ACL tables and rules on the virtual switch."""
@@ -18,6 +18,9 @@ class DVSAcl:
1818
ADB_ACL_GROUP_MEMBER_TABLE_NAME = "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE_GROUP_MEMBER"
1919
ADB_ACL_COUNTER_TABLE_NAME = "ASIC_STATE:SAI_OBJECT_TYPE_ACL_COUNTER"
2020

21+
STATE_DB_ACL_TABLE_TABLE_NAME = "ACL_TABLE_TABLE"
22+
STATE_DB_ACL_RULE_TABLE_NAME = "ACL_RULE_TABLE"
23+
2124
ADB_ACL_STAGE_LOOKUP = {
2225
"ingress": "SAI_ACL_STAGE_INGRESS",
2326
"egress": "SAI_ACL_STAGE_EGRESS"
@@ -717,3 +720,43 @@ def _check_acl_entry_counters_map(self, acl_entry_oid: str):
717720
rule_to_counter_map = self.counters_db.get_entry("ACL_COUNTER_RULE_MAP", "")
718721
counter_to_rule_map = {v: k for k, v in rule_to_counter_map.items()}
719722
assert counter_oid in counter_to_rule_map
723+
724+
def verify_acl_table_status(
725+
self,
726+
acl_table_name,
727+
expected_status
728+
) -> None:
729+
"""Verify that the STATE_DB status of ACL table is as expected.
730+
731+
Args:
732+
acl_table_name: The name of ACL table to check
733+
expected_status: The expected status in STATE_DB
734+
"""
735+
if expected_status:
736+
fvs = self.state_db.wait_for_entry(self.STATE_DB_ACL_TABLE_TABLE_NAME, acl_table_name)
737+
assert len(fvs) > 0
738+
assert (fvs['status'] == expected_status)
739+
else:
740+
self.state_db.wait_for_deleted_entry(self.STATE_DB_ACL_TABLE_TABLE_NAME, acl_table_name)
741+
742+
def verify_acl_rule_status(
743+
self,
744+
acl_table_name,
745+
acl_rule_name,
746+
expected_status
747+
) -> None:
748+
"""Verify that the STATE_DB status of ACL rule is as expected.
749+
750+
Args:
751+
acl_table_name: The name of ACL table to check
752+
acl_rule_name: The name of ACL rule to check
753+
expected_status: The expected status in STATE_DB
754+
"""
755+
key = acl_table_name + "|" + acl_rule_name
756+
if expected_status:
757+
fvs = self.state_db.wait_for_entry(self.STATE_DB_ACL_RULE_TABLE_NAME, key)
758+
assert len(fvs) > 0
759+
assert (fvs['status'] == expected_status)
760+
else:
761+
self.state_db.wait_for_deleted_entry(self.STATE_DB_ACL_TABLE_TABLE_NAME, key)
762+

0 commit comments

Comments
 (0)