Skip to content

Commit 6e0fc85

Browse files
authored
[ACL] Support stage particular match fields (sonic-net#2341)
What I did This PR is to fix ACL table creation failure for certain types. We saw PFCWD table failed to be created at EGRESS stage. The error logs are Jun 21 07:00:03.409283 str2-7050cx3-acs-08 ERR syncd#syncd: [none] SAI_API_ACL:_brcm_sai_create_acl_table:11205 field group config create failed with error Feature unavailable (0xfffffff0). Jun 21 07:00:03.409738 str2-7050cx3-acs-08 ERR syncd#syncd: [none] SAI_API_ACL:brcm_sai_create_acl_table:298 create table entry failed with error -2. Jun 21 07:00:03.409738 str2-7050cx3-acs-08 ERR syncd#syncd: :- sendApiResponse: api SAI_COMMON_API_CREATE failed in syncd mode: SAI_STATUS_NOT_SUPPORTED Jun 21 07:00:03.409780 str2-7050cx3-acs-08 ERR syncd#syncd: :- processQuadEvent: attr: SAI_ACL_TABLE_ATTR_ACL_BIND_POINT_TYPE_LIST: 1:SAI_ACL_BIND_POINT_TYPE_PORT Jun 21 07:00:03.409820 str2-7050cx3-acs-08 ERR syncd#syncd: :- processQuadEvent: attr: SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS: true Jun 21 07:00:03.409820 str2-7050cx3-acs-08 ERR syncd#syncd: :- processQuadEvent: attr: SAI_ACL_TABLE_ATTR_FIELD_TC: true Jun 21 07:00:03.410144 str2-7050cx3-acs-08 ERR syncd#syncd: :- processQuadEvent: attr: SAI_ACL_TABLE_ATTR_ACL_ACTION_TYPE_LIST: 2:SAI_ACL_ACTION_TYPE_PACKET_ACTION,SAI_ACL_ACTION_TYPE_COUNTER Jun 21 07:00:03.410144 str2-7050cx3-acs-08 ERR syncd#syncd: :- processQuadEvent: attr: SAI_ACL_TABLE_ATTR_ACL_STAGE: SAI_ACL_STAGE_EGRESS Jun 21 07:00:03.410144 str2-7050cx3-acs-08 ERR swss#orchagent: :- create: create status: SAI_STATUS_NOT_SUPPORTED Jun 21 07:00:03.410144 str2-7050cx3-acs-08 ERR swss#orchagent: :- addAclTable: Failed to create ACL table pfcwd_egress The root cause for the issue is SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS is not supported at EGRESS stage. This PR addressed the issue by adding match field according to the stage. For ACL type TABLE_TYPE_PFCWD and TABLE_TYPE_DROP at INGRESS stage, the match field SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS is added, while for EGRESS the field is not added. Why I did it To fix ACL table creation issue. How I verified it Verified by vstest test_acl.py::TestAcl::test_AclTableMandatoryMatchFields[ingress] PASSED [ 87%] test_acl.py::TestAcl::test_AclTableMandatoryMatchFields[egress] PASSED [ 90%] Verified by building a new image and run on a TD3 device. Signed-off-by: bingwang <[email protected]>
1 parent efb4530 commit 6e0fc85

File tree

3 files changed

+104
-4
lines changed

3 files changed

+104
-4
lines changed

orchagent/aclorch.cpp

+68-2
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,38 @@ static acl_table_action_list_lookup_t defaultAclActionList =
323323
}
324324
};
325325

326+
// The match fields for certain ACL table type are not exactly the same between INGRESS and EGRESS.
327+
// For example, we can only match IN_PORT for PFCWD table type at INGRESS.
328+
// Hence we need to specify stage particular matching fields in stageMandatoryMatchFields
329+
static acl_table_match_field_lookup_t stageMandatoryMatchFields =
330+
{
331+
{
332+
// TABLE_TYPE_PFCWD
333+
TABLE_TYPE_PFCWD,
334+
{
335+
{
336+
ACL_STAGE_INGRESS,
337+
{
338+
SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS
339+
}
340+
}
341+
}
342+
},
343+
{
344+
// TABLE_TYPE_DROP
345+
TABLE_TYPE_DROP,
346+
{
347+
{
348+
ACL_STAGE_INGRESS,
349+
{
350+
SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS
351+
}
352+
}
353+
}
354+
}
355+
356+
};
357+
326358
static acl_ip_type_lookup_t aclIpTypeLookup =
327359
{
328360
{ IP_TYPE_ANY, SAI_ACL_IP_TYPE_ANY },
@@ -477,6 +509,12 @@ bool AclTableType::addAction(sai_acl_action_type_t action)
477509
return true;
478510
}
479511

512+
bool AclTableType::addMatch(shared_ptr<AclTableMatchInterface> match)
513+
{
514+
m_matches.emplace(match->getId(), match);
515+
return true;
516+
}
517+
480518
AclTableTypeBuilder& AclTableTypeBuilder::withName(string name)
481519
{
482520
m_tableType.m_name = name;
@@ -2020,6 +2058,34 @@ bool AclTable::addMandatoryActions()
20202058
return true;
20212059
}
20222060

2061+
bool AclTable::addStageMandatoryMatchFields()
2062+
{
2063+
SWSS_LOG_ENTER();
2064+
2065+
if (stage == ACL_STAGE_UNKNOWN)
2066+
{
2067+
return false;
2068+
}
2069+
2070+
if (stageMandatoryMatchFields.count(type.getName()) != 0)
2071+
{
2072+
auto &fields_for_stage = stageMandatoryMatchFields[type.getName()];
2073+
if (fields_for_stage.count(stage) != 0)
2074+
{
2075+
// Add the stage particular matching fields
2076+
for (auto match : fields_for_stage[stage])
2077+
{
2078+
type.addMatch(make_shared<AclTableMatch>(match));
2079+
SWSS_LOG_INFO("Added mandatory match field %s for table type %s stage %d",
2080+
sai_serialize_enum(match, &sai_metadata_enum_sai_acl_table_attr_t).c_str(),
2081+
type.getName().c_str(), stage);
2082+
}
2083+
}
2084+
}
2085+
2086+
return true;
2087+
}
2088+
20232089
bool AclTable::validateAddType(const AclTableType &tableType)
20242090
{
20252091
SWSS_LOG_ENTER();
@@ -2983,15 +3049,13 @@ void AclOrch::initDefaultTableTypes()
29833049
builder.withName(TABLE_TYPE_PFCWD)
29843050
.withBindPointType(SAI_ACL_BIND_POINT_TYPE_PORT)
29853051
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_TC))
2986-
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS))
29873052
.build()
29883053
);
29893054

29903055
addAclTableType(
29913056
builder.withName(TABLE_TYPE_DROP)
29923057
.withBindPointType(SAI_ACL_BIND_POINT_TYPE_PORT)
29933058
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_TC))
2994-
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS))
29953059
.build()
29963060
);
29973061

@@ -4108,6 +4172,8 @@ void AclOrch::doAclTableTask(Consumer &consumer)
41084172

41094173
newTable.validateAddType(*tableType);
41104174

4175+
newTable.addStageMandatoryMatchFields();
4176+
41114177
newTable.addMandatoryActions();
41124178

41134179
// validate and create/update ACL Table

orchagent/aclorch.h

+7
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ typedef map<sai_acl_action_type_t, set<int32_t>> acl_action_enum_values_capabili
116116
typedef map<acl_stage_type_t, set<sai_acl_action_type_t> > acl_stage_action_list_t;
117117
typedef map<string, acl_stage_action_list_t> acl_table_action_list_lookup_t;
118118

119+
typedef map<acl_stage_type_t, set<sai_acl_table_attr_t> > acl_stage_match_field_t;
120+
typedef map<string, acl_stage_match_field_t> acl_table_match_field_lookup_t;
121+
119122
class AclRule;
120123

121124
class AclTableMatchInterface
@@ -160,6 +163,7 @@ class AclTableType
160163
const set<sai_acl_action_type_t>& getActions() const;
161164

162165
bool addAction(sai_acl_action_type_t action);
166+
bool addMatch(shared_ptr<AclTableMatchInterface> match);
163167

164168
private:
165169
friend class AclTableTypeBuilder;
@@ -384,6 +388,9 @@ class AclTable
384388
// Add actions to ACL table if mandatory action list is required on table creation.
385389
bool addMandatoryActions();
386390

391+
// Add stage mandatory matching fields to ACL table
392+
bool addStageMandatoryMatchFields();
393+
387394
// validate AclRule match attribute against rule and table configuration
388395
bool validateAclRuleMatch(sai_acl_entry_attr_t matchId, const AclRule& rule) const;
389396
// validate AclRule action attribute against rule and table configuration

tests/test_acl.py

+29-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import pytest
2+
from requests import request
23

34
L3_TABLE_TYPE = "L3"
45
L3_TABLE_NAME = "L3_TEST"
@@ -20,6 +21,9 @@
2021
MIRROR_BIND_PORTS = ["Ethernet0", "Ethernet4", "Ethernet8", "Ethernet12"]
2122
MIRROR_RULE_NAME = "MIRROR_TEST_RULE"
2223

24+
PFCWD_TABLE_TYPE = "PFCWD"
25+
PFCWD_TABLE_NAME = "PFCWD_TEST"
26+
PFCWD_BIND_PORTS = ["Ethernet0", "Ethernet4", "Ethernet8", "Ethernet12"]
2327
class TestAcl:
2428
@pytest.yield_fixture
2529
def l3_acl_table(self, dvs_acl):
@@ -59,6 +63,15 @@ def mirror_acl_table(self, dvs_acl):
5963
dvs_acl.remove_acl_table(MIRROR_TABLE_NAME)
6064
dvs_acl.verify_acl_table_count(0)
6165

66+
@pytest.fixture(params=['ingress', 'egress'])
67+
def pfcwd_acl_table(self, dvs_acl, request):
68+
try:
69+
dvs_acl.create_acl_table(PFCWD_TABLE_NAME, PFCWD_TABLE_TYPE, PFCWD_BIND_PORTS, request.param)
70+
yield dvs_acl.get_acl_table_ids(1)[0], request.param
71+
finally:
72+
dvs_acl.remove_acl_table(PFCWD_TABLE_NAME)
73+
dvs_acl.verify_acl_table_count(0)
74+
6275
@pytest.yield_fixture
6376
def setup_teardown_neighbor(self, dvs):
6477
try:
@@ -548,8 +561,22 @@ def test_AclRuleRedirect(self, dvs, dvs_acl, l3_acl_table, setup_teardown_neighb
548561

549562
dvs_acl.remove_acl_rule(L3_TABLE_NAME, L3_RULE_NAME)
550563
dvs_acl.verify_no_acl_rules()
551-
552-
564+
565+
def test_AclTableMandatoryMatchFields(self, dvs, pfcwd_acl_table):
566+
"""
567+
The test case is to verify stage particular matching fields is applied
568+
"""
569+
table_oid, stage = pfcwd_acl_table
570+
match_in_ports = False
571+
entry = dvs.asic_db.wait_for_entry("ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE", table_oid)
572+
for k, v in entry.items():
573+
if k == "SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS" and v == "true":
574+
match_in_ports = True
575+
576+
if stage == "ingress":
577+
assert match_in_ports
578+
else:
579+
assert not match_in_ports
553580
class TestAclCrmUtilization:
554581
@pytest.fixture(scope="class", autouse=True)
555582
def configure_crm_polling_interval_for_test(self, dvs):

0 commit comments

Comments
 (0)