Skip to content

Commit a9dbc83

Browse files
authored
[aclorch] Add support for creating ingress and egress MIRROR tables concurrently (#1286)
Signed-off-by: Danny Allen <[email protected]>
1 parent 69a980e commit a9dbc83

File tree

3 files changed

+107
-39
lines changed

3 files changed

+107
-39
lines changed

orchagent/aclorch.cpp

+47-33
Original file line numberDiff line numberDiff line change
@@ -2213,6 +2213,12 @@ void AclOrch::init(vector<TableConnector>& connectors, PortsOrch *portOrch, Mirr
22132213

22142214
queryAclActionCapability();
22152215

2216+
for (auto stage: {ACL_STAGE_INGRESS, ACL_STAGE_EGRESS})
2217+
{
2218+
m_mirrorTableId[stage] = "";
2219+
m_mirrorV6TableId[stage] = "";
2220+
}
2221+
22162222
// Attach observers
22172223
m_mirrorOrch->attach(this);
22182224
gPortsOrch->attach(this);
@@ -2666,6 +2672,7 @@ bool AclOrch::addAclTable(AclTable &newTable)
26662672
}
26672673

26682674
sai_object_id_t table_oid = getTableById(table_id);
2675+
auto table_stage = newTable.stage;
26692676

26702677
if (table_oid != SAI_NULL_OBJECT_ID)
26712678
{
@@ -2685,19 +2692,23 @@ bool AclOrch::addAclTable(AclTable &newTable)
26852692
if (table_type == ACL_TABLE_MIRROR || table_type == ACL_TABLE_MIRRORV6)
26862693
{
26872694
string mirror_type;
2688-
if ((table_type == ACL_TABLE_MIRROR && !m_mirrorTableId.empty()))
2695+
if (table_type == ACL_TABLE_MIRROR && !m_mirrorTableId[table_stage].empty())
26892696
{
26902697
mirror_type = TABLE_TYPE_MIRROR;
26912698
}
26922699

2693-
if (table_type == ACL_TABLE_MIRRORV6 && !m_mirrorV6TableId.empty())
2700+
if (table_type == ACL_TABLE_MIRRORV6 && !m_mirrorV6TableId[table_stage].empty())
26942701
{
26952702
mirror_type = TABLE_TYPE_MIRRORV6;
26962703
}
26972704

26982705
if (!mirror_type.empty())
26992706
{
2700-
SWSS_LOG_ERROR("Mirror table %s has already been created", mirror_type.c_str());
2707+
string stage_str = table_stage == ACL_STAGE_INGRESS ? "INGRESS" : "EGRESS";
2708+
SWSS_LOG_ERROR(
2709+
"Mirror table %s (%s) has already been created",
2710+
mirror_type.c_str(),
2711+
stage_str.c_str());
27012712
return false;
27022713
}
27032714
}
@@ -2706,23 +2717,22 @@ bool AclOrch::addAclTable(AclTable &newTable)
27062717
// Check if a separate mirror table is needed or not based on the platform
27072718
if (newTable.type == ACL_TABLE_MIRROR || newTable.type == ACL_TABLE_MIRRORV6)
27082719
{
2709-
27102720
if (m_isCombinedMirrorV6Table &&
2711-
(!m_mirrorTableId.empty() || !m_mirrorV6TableId.empty())) {
2712-
2721+
(!m_mirrorTableId[table_stage].empty() ||
2722+
!m_mirrorV6TableId[table_stage].empty())) {
27132723
string orig_table_name;
27142724

27152725
// If v4 table is created, mark v6 table is created
2716-
if (!m_mirrorTableId.empty())
2726+
if (!m_mirrorTableId[table_stage].empty())
27172727
{
2718-
orig_table_name = m_mirrorTableId;
2719-
m_mirrorV6TableId = newTable.id;
2728+
orig_table_name = m_mirrorTableId[table_stage];
2729+
m_mirrorV6TableId[table_stage] = newTable.id;
27202730
}
27212731
// If v6 table is created, mark v4 table is created
27222732
else
27232733
{
2724-
orig_table_name = m_mirrorV6TableId;
2725-
m_mirrorTableId = newTable.id;
2734+
orig_table_name = m_mirrorV6TableId[table_stage];
2735+
m_mirrorTableId[table_stage] = newTable.id;
27262736
}
27272737

27282738
SWSS_LOG_NOTICE("Created ACL table %s as a sibling of %s",
@@ -2741,11 +2751,11 @@ bool AclOrch::addAclTable(AclTable &newTable)
27412751
// Mark the existence of the mirror table
27422752
if (newTable.type == ACL_TABLE_MIRROR)
27432753
{
2744-
m_mirrorTableId = table_id;
2754+
m_mirrorTableId[table_stage] = table_id;
27452755
}
27462756
else if (newTable.type == ACL_TABLE_MIRRORV6)
27472757
{
2748-
m_mirrorV6TableId = table_id;
2758+
m_mirrorV6TableId[table_stage] = table_id;
27492759
}
27502760

27512761
return true;
@@ -2774,29 +2784,30 @@ bool AclOrch::removeAclTable(string table_id)
27742784

27752785
if (deleteUnbindAclTable(table_oid) == SAI_STATUS_SUCCESS)
27762786
{
2777-
sai_acl_stage_t stage = (m_AclTables[table_oid].stage == ACL_STAGE_INGRESS) ? SAI_ACL_STAGE_INGRESS : SAI_ACL_STAGE_EGRESS;
2778-
gCrmOrch->decCrmAclUsedCounter(CrmResourceType::CRM_ACL_TABLE, stage, SAI_ACL_BIND_POINT_TYPE_PORT, table_oid);
2787+
auto stage = m_AclTables[table_oid].stage;
2788+
sai_acl_stage_t sai_stage = (stage == ACL_STAGE_INGRESS) ? SAI_ACL_STAGE_INGRESS : SAI_ACL_STAGE_EGRESS;
2789+
gCrmOrch->decCrmAclUsedCounter(CrmResourceType::CRM_ACL_TABLE, sai_stage, SAI_ACL_BIND_POINT_TYPE_PORT, table_oid);
27792790

27802791
SWSS_LOG_NOTICE("Successfully deleted ACL table %s", table_id.c_str());
27812792
m_AclTables.erase(table_oid);
27822793

27832794
// Clear mirror table information
27842795
// If the v4 and v6 ACL mirror tables are combined together,
27852796
// remove both of them.
2786-
if (table_id == m_mirrorTableId)
2797+
if (m_mirrorTableId[stage] == table_id)
27872798
{
2788-
m_mirrorTableId.clear();
2799+
m_mirrorTableId[stage].clear();
27892800
if (m_isCombinedMirrorV6Table)
27902801
{
2791-
m_mirrorV6TableId.clear();
2802+
m_mirrorV6TableId[stage].clear();
27922803
}
27932804
}
2794-
else if (table_id == m_mirrorV6TableId)
2805+
else if (m_mirrorV6TableId[stage] == table_id)
27952806
{
2796-
m_mirrorV6TableId.clear();
2807+
m_mirrorV6TableId[stage].clear();
27972808
if (m_isCombinedMirrorV6Table)
27982809
{
2799-
m_mirrorTableId.clear();
2810+
m_mirrorTableId[stage].clear();
28002811
}
28012812
}
28022813

@@ -3042,9 +3053,10 @@ void AclOrch::doAclRuleTask(Consumer &consumer)
30423053
}
30433054

30443055
auto type = m_AclTables[table_oid].type;
3056+
auto stage = m_AclTables[table_oid].stage;
30453057
if (type == ACL_TABLE_MIRROR || type == ACL_TABLE_MIRRORV6)
30463058
{
3047-
type = table_id == m_mirrorTableId ? ACL_TABLE_MIRROR : ACL_TABLE_MIRRORV6;
3059+
type = table_id == m_mirrorTableId[stage] ? ACL_TABLE_MIRROR : ACL_TABLE_MIRRORV6;
30483060
}
30493061

30503062

@@ -3212,18 +3224,20 @@ sai_object_id_t AclOrch::getTableById(string table_id)
32123224
}
32133225

32143226
// Check if the table is a mirror table and a sibling mirror table is created
3215-
if (m_isCombinedMirrorV6Table &&
3216-
(table_id == m_mirrorTableId || table_id == m_mirrorV6TableId))
3217-
{
3218-
// If the table is v4, the corresponding v6 table is already created
3219-
if (table_id == m_mirrorTableId)
3220-
{
3221-
return getTableById(m_mirrorV6TableId);
3222-
}
3223-
// If the table is v6, the corresponding v4 table is already created
3224-
else
3227+
for (auto stage: {ACL_STAGE_INGRESS, ACL_STAGE_EGRESS}) {
3228+
if (m_isCombinedMirrorV6Table &&
3229+
(table_id == m_mirrorTableId[stage] || table_id == m_mirrorV6TableId[stage]))
32253230
{
3226-
return getTableById(m_mirrorTableId);
3231+
// If the table is v4, the corresponding v6 table is already created
3232+
if (table_id == m_mirrorTableId[stage])
3233+
{
3234+
return getTableById(m_mirrorV6TableId[stage]);
3235+
}
3236+
// If the table is v6, the corresponding v4 table is already created
3237+
else
3238+
{
3239+
return getTableById(m_mirrorTableId[stage]);
3240+
}
32273241
}
32283242
}
32293243

orchagent/aclorch.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,8 @@ class AclOrch : public Orch, public Observer
477477
static DBConnector m_db;
478478
static Table m_countersTable;
479479

480-
string m_mirrorTableId;
481-
string m_mirrorV6TableId;
480+
map<acl_stage_type_t, string> m_mirrorTableId;
481+
map<acl_stage_type_t, string> m_mirrorV6TableId;
482482

483483
acl_capabilities_t m_aclCapabilities;
484484
acl_action_enum_values_capabilities_t m_aclEnumActionCapabilities;

tests/test_mirror_ipv6_separate.py

+58-4
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,15 @@ def get_mirror_session_state(self, name):
9999
assert len(fvs) > 0
100100
return { fv[0]: fv[1] for fv in fvs }
101101

102-
def create_acl_table(self, table, interfaces, type):
102+
def create_acl_table(self, table, interfaces, type, stage=None):
103+
attrs = [("policy_desc", "mirror_test"),
104+
("type", type),
105+
("ports", ",".join(interfaces))]
106+
if stage:
107+
attrs.append(("stage", stage))
108+
103109
tbl = swsscommon.Table(self.cdb, "ACL_TABLE")
104-
fvs = swsscommon.FieldValuePairs([("policy_desc", "mirror_test"),
105-
("type", type),
106-
("ports", ",".join(interfaces))])
110+
fvs = swsscommon.FieldValuePairs(attrs)
107111
tbl.set(table, fvs)
108112
time.sleep(1)
109113

@@ -268,6 +272,56 @@ def test_MirrorV6TableCreation(self, dvs, testlog):
268272
# Delete the V6 table
269273
self.remove_acl_table(acl_table_v6)
270274

275+
def test_CreateMirrorIngressAndEgress(self, dvs, testlog):
276+
self.setup_db(dvs)
277+
asic_db = dvs.get_asic_db()
278+
279+
ingress_table = "INGRESS_TABLE"
280+
duplicate_ingress_table = "INGRESS_TABLE_2"
281+
ports = ["Ethernet0", "Ethernet4"]
282+
283+
# Create the table
284+
self.create_acl_table(ingress_table, ports, "MIRROR")
285+
286+
# Check that the table has been created
287+
table_ids = asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE",
288+
len(asic_db.default_acl_tables) + 1)
289+
table_entries = [oid for oid in table_ids if oid not in asic_db.default_acl_tables]
290+
original_entry = table_entries[0]
291+
292+
# Attempt to create another MIRROR table with ingress ACLs
293+
self.create_acl_table(duplicate_ingress_table, ports, "MIRROR")
294+
295+
# Check that there is still only one table, and that it is the original table
296+
table_ids = asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE",
297+
len(asic_db.default_acl_tables) + 1)
298+
table_entries = [oid for oid in table_ids if oid not in asic_db.default_acl_tables]
299+
assert table_entries[0] == original_entry
300+
301+
egress_table = "EGRESS_TABLE"
302+
duplicate_egress_table = "EGRESS_TABLE_2"
303+
304+
# Create the egress table
305+
self.create_acl_table(egress_table, ports, "MIRROR", "egress")
306+
307+
# Check that there are two tables
308+
asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE",
309+
len(asic_db.default_acl_tables) + 2)
310+
311+
# Attempt to create another MIRROR table with egress ACLs
312+
self.create_acl_table(duplicate_egress_table, ports, "MIRROR", "egress")
313+
314+
# Check that there are still only two tables
315+
asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE",
316+
len(asic_db.default_acl_tables) + 2)
317+
318+
self.remove_acl_table(ingress_table)
319+
self.remove_acl_table(egress_table)
320+
self.remove_acl_table(duplicate_ingress_table)
321+
self.remove_acl_table(duplicate_egress_table)
322+
323+
asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE", len(asic_db.default_acl_tables))
324+
271325
# Test case - create a MIRROR table and a MIRRORV6 table in separated mode
272326
# 0. predefine the VS platform: mellanox platform
273327
# 1. create a mirror session

0 commit comments

Comments
 (0)