Skip to content

Commit a43f6be

Browse files
[crm] Add support for snat, dnat and ipmc crm resources (#1511)
What I did Added support for snat, dnat and ipmc resources under CRM module. Why I did it New feature NAT adds new resources snat_enty and dnat_entry that needs to be monitored. ipmc_entry tracks IP multicast resources used by switch. Associated PRs sonic-net/sonic-utilities/pull/1258 #6012 Signed-off-by: Prabhu Sreenivasan <prabhu.sreenivasan@broadcom.com>
1 parent 7fc3888 commit a43f6be

File tree

4 files changed

+139
-15
lines changed

4 files changed

+139
-15
lines changed

doc/Configuration.md

+10-1
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,16 @@ group name and IP ranges in **BGP_PEER_RANGE** table.
539539
"ipv4_neighbor_low_threshold": "70",
540540
"acl_group_threshold_type": "percentage",
541541
"ipv4_nexthop_high_threshold": "85",
542-
"ipv6_route_threshold_type": "percentage"
542+
"ipv6_route_threshold_type": "percentage",
543+
"snat_entry_threshold_type": "percentage",
544+
"snat_entry_high_threshold": "85",
545+
"snat_entry_low_threshold": "70",
546+
"dnat_entry_threshold_type": "percentage",
547+
"dnat_entry_high_threshold": "85",
548+
"dnat_entry_low_threshold": "70",
549+
"ipmc_entry_threshold_type": "percentage",
550+
"ipmc_entry_high_threshold": "85",
551+
"ipmc_entry_low_threshold": "70"
543552
}
544553
}
545554
}

orchagent/crmorch.cpp

+57-14
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ const map<CrmResourceType, string> crmResTypeNameMap =
3737
{ CrmResourceType::CRM_ACL_GROUP, "ACL_GROUP" },
3838
{ CrmResourceType::CRM_ACL_ENTRY, "ACL_ENTRY" },
3939
{ CrmResourceType::CRM_ACL_COUNTER, "ACL_COUNTER" },
40-
{ CrmResourceType::CRM_FDB_ENTRY, "FDB_ENTRY" }
40+
{ CrmResourceType::CRM_FDB_ENTRY, "FDB_ENTRY" },
41+
{ CrmResourceType::CRM_IPMC_ENTRY, "IPMC_ENTRY" },
42+
{ CrmResourceType::CRM_SNAT_ENTRY, "SNAT_ENTRY" },
43+
{ CrmResourceType::CRM_DNAT_ENTRY, "DNAT_ENTRY" }
4144
};
4245

4346
const map<CrmResourceType, uint32_t> crmResSaiAvailAttrMap =
@@ -54,7 +57,10 @@ const map<CrmResourceType, uint32_t> crmResSaiAvailAttrMap =
5457
{ CrmResourceType::CRM_ACL_GROUP, SAI_SWITCH_ATTR_AVAILABLE_ACL_TABLE_GROUP },
5558
{ CrmResourceType::CRM_ACL_ENTRY, SAI_ACL_TABLE_ATTR_AVAILABLE_ACL_ENTRY },
5659
{ CrmResourceType::CRM_ACL_COUNTER, SAI_ACL_TABLE_ATTR_AVAILABLE_ACL_COUNTER },
57-
{ CrmResourceType::CRM_FDB_ENTRY, SAI_SWITCH_ATTR_AVAILABLE_FDB_ENTRY }
60+
{ CrmResourceType::CRM_FDB_ENTRY, SAI_SWITCH_ATTR_AVAILABLE_FDB_ENTRY },
61+
{ CrmResourceType::CRM_IPMC_ENTRY, SAI_SWITCH_ATTR_AVAILABLE_IPMC_ENTRY},
62+
{ CrmResourceType::CRM_SNAT_ENTRY, SAI_SWITCH_ATTR_AVAILABLE_SNAT_ENTRY },
63+
{ CrmResourceType::CRM_DNAT_ENTRY, SAI_SWITCH_ATTR_AVAILABLE_DNAT_ENTRY }
5864
};
5965

6066
const map<string, CrmResourceType> crmThreshTypeResMap =
@@ -71,7 +77,10 @@ const map<string, CrmResourceType> crmThreshTypeResMap =
7177
{ "acl_group_threshold_type", CrmResourceType::CRM_ACL_GROUP },
7278
{ "acl_entry_threshold_type", CrmResourceType::CRM_ACL_ENTRY },
7379
{ "acl_counter_threshold_type", CrmResourceType::CRM_ACL_COUNTER },
74-
{ "fdb_entry_threshold_type", CrmResourceType::CRM_FDB_ENTRY }
80+
{ "fdb_entry_threshold_type", CrmResourceType::CRM_FDB_ENTRY },
81+
{ "ipmc_entry_threshold_type", CrmResourceType::CRM_IPMC_ENTRY },
82+
{ "snat_entry_threshold_type", CrmResourceType::CRM_SNAT_ENTRY },
83+
{ "dnat_entry_threshold_type", CrmResourceType::CRM_DNAT_ENTRY }
7584
};
7685

7786
const map<string, CrmResourceType> crmThreshLowResMap =
@@ -89,6 +98,9 @@ const map<string, CrmResourceType> crmThreshLowResMap =
8998
{"acl_entry_low_threshold", CrmResourceType::CRM_ACL_ENTRY },
9099
{"acl_counter_low_threshold", CrmResourceType::CRM_ACL_COUNTER },
91100
{"fdb_entry_low_threshold", CrmResourceType::CRM_FDB_ENTRY },
101+
{"ipmc_entry_low_threshold", CrmResourceType::CRM_IPMC_ENTRY },
102+
{"snat_entry_low_threshold", CrmResourceType::CRM_SNAT_ENTRY },
103+
{"dnat_entry_low_threshold", CrmResourceType::CRM_DNAT_ENTRY }
92104
};
93105

94106
const map<string, CrmResourceType> crmThreshHighResMap =
@@ -105,7 +117,10 @@ const map<string, CrmResourceType> crmThreshHighResMap =
105117
{"acl_group_high_threshold", CrmResourceType::CRM_ACL_GROUP },
106118
{"acl_entry_high_threshold", CrmResourceType::CRM_ACL_ENTRY },
107119
{"acl_counter_high_threshold", CrmResourceType::CRM_ACL_COUNTER },
108-
{"fdb_entry_high_threshold", CrmResourceType::CRM_FDB_ENTRY }
120+
{"fdb_entry_high_threshold", CrmResourceType::CRM_FDB_ENTRY },
121+
{"ipmc_entry_high_threshold", CrmResourceType::CRM_IPMC_ENTRY },
122+
{"snat_entry_high_threshold", CrmResourceType::CRM_SNAT_ENTRY },
123+
{"dnat_entry_high_threshold", CrmResourceType::CRM_DNAT_ENTRY }
109124
};
110125

111126
const map<string, CrmThresholdType> crmThreshTypeMap =
@@ -129,7 +144,10 @@ const map<string, CrmResourceType> crmAvailCntsTableMap =
129144
{ "crm_stats_acl_group_available", CrmResourceType::CRM_ACL_GROUP },
130145
{ "crm_stats_acl_entry_available", CrmResourceType::CRM_ACL_ENTRY },
131146
{ "crm_stats_acl_counter_available", CrmResourceType::CRM_ACL_COUNTER },
132-
{ "crm_stats_fdb_entry_available", CrmResourceType::CRM_FDB_ENTRY }
147+
{ "crm_stats_fdb_entry_available", CrmResourceType::CRM_FDB_ENTRY },
148+
{ "crm_stats_ipmc_entry_available", CrmResourceType::CRM_IPMC_ENTRY },
149+
{ "crm_stats_snat_entry_available", CrmResourceType::CRM_SNAT_ENTRY },
150+
{ "crm_stats_dnat_entry_available", CrmResourceType::CRM_DNAT_ENTRY }
133151
};
134152

135153
const map<string, CrmResourceType> crmUsedCntsTableMap =
@@ -146,7 +164,10 @@ const map<string, CrmResourceType> crmUsedCntsTableMap =
146164
{ "crm_stats_acl_group_used", CrmResourceType::CRM_ACL_GROUP },
147165
{ "crm_stats_acl_entry_used", CrmResourceType::CRM_ACL_ENTRY },
148166
{ "crm_stats_acl_counter_used", CrmResourceType::CRM_ACL_COUNTER },
149-
{ "crm_stats_fdb_entry_used", CrmResourceType::CRM_FDB_ENTRY }
167+
{ "crm_stats_fdb_entry_used", CrmResourceType::CRM_FDB_ENTRY },
168+
{ "crm_stats_ipmc_entry_used", CrmResourceType::CRM_IPMC_ENTRY },
169+
{ "crm_stats_snat_entry_used", CrmResourceType::CRM_SNAT_ENTRY },
170+
{ "crm_stats_dnat_entry_used", CrmResourceType::CRM_DNAT_ENTRY }
150171
};
151172

152173
CrmOrch::CrmOrch(DBConnector *db, string tableName):
@@ -429,10 +450,18 @@ void CrmOrch::getResAvailableCounters()
429450
case SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_MEMBER_ENTRY:
430451
case SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_ENTRY:
431452
case SAI_SWITCH_ATTR_AVAILABLE_FDB_ENTRY:
453+
case SAI_SWITCH_ATTR_AVAILABLE_IPMC_ENTRY:
454+
case SAI_SWITCH_ATTR_AVAILABLE_SNAT_ENTRY:
455+
case SAI_SWITCH_ATTR_AVAILABLE_DNAT_ENTRY:
432456
{
433457
sai_status_t status = sai_switch_api->get_switch_attribute(gSwitchId, 1, &attr);
434458
if (status != SAI_STATUS_SUCCESS)
435459
{
460+
if(status == SAI_STATUS_NOT_SUPPORTED)
461+
{
462+
// remove unsupported resources from map
463+
m_resourcesMap.erase(res.first);
464+
}
436465
SWSS_LOG_ERROR("Failed to get switch attribute %u , rv:%d", attr.id, status);
437466
break;
438467
}
@@ -504,22 +533,36 @@ void CrmOrch::updateCrmCountersTable()
504533
// Update CRM used counters in COUNTERS_DB
505534
for (const auto &i : crmUsedCntsTableMap)
506535
{
507-
for (const auto &cnt : m_resourcesMap.at(i.second).countersMap)
536+
try
537+
{
538+
for (const auto &cnt : m_resourcesMap.at(i.second).countersMap)
539+
{
540+
FieldValueTuple attr(i.first, to_string(cnt.second.usedCounter));
541+
vector<FieldValueTuple> attrs = { attr };
542+
m_countersCrmTable->set(cnt.first, attrs);
543+
}
544+
}
545+
catch(const out_of_range &e)
508546
{
509-
FieldValueTuple attr(i.first, to_string(cnt.second.usedCounter));
510-
vector<FieldValueTuple> attrs = { attr };
511-
m_countersCrmTable->set(cnt.first, attrs);
547+
// expected when a resource is unavailable
512548
}
513549
}
514550

515551
// Update CRM available counters in COUNTERS_DB
516552
for (const auto &i : crmAvailCntsTableMap)
517553
{
518-
for (const auto &cnt : m_resourcesMap.at(i.second).countersMap)
554+
try
555+
{
556+
for (const auto &cnt : m_resourcesMap.at(i.second).countersMap)
557+
{
558+
FieldValueTuple attr(i.first, to_string(cnt.second.availableCounter));
559+
vector<FieldValueTuple> attrs = { attr };
560+
m_countersCrmTable->set(cnt.first, attrs);
561+
}
562+
}
563+
catch(const out_of_range &e)
519564
{
520-
FieldValueTuple attr(i.first, to_string(cnt.second.availableCounter));
521-
vector<FieldValueTuple> attrs = { attr };
522-
m_countersCrmTable->set(cnt.first, attrs);
565+
// expected when a resource is unavailable
523566
}
524567
}
525568
}

orchagent/crmorch.h

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ enum class CrmResourceType
2525
CRM_ACL_ENTRY,
2626
CRM_ACL_COUNTER,
2727
CRM_FDB_ENTRY,
28+
CRM_IPMC_ENTRY,
29+
CRM_SNAT_ENTRY,
30+
CRM_DNAT_ENTRY,
2831
};
2932

3033
enum class CrmThresholdType

tests/test_crm.py

+69
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,31 @@ def test_CrmAclGroup(self, dvs, testlog):
702702
#table_used_counter = getCrmCounterValue(dvs, 'ACL_STATS:INGRESS:PORT', 'crm_stats_acl_group_used')
703703
#assert table_used_counter == 0
704704

705+
def test_CrmSnatEntry(self, dvs, testlog):
706+
707+
# get counters
708+
used_counter = getCrmCounterValue(dvs, 'STATS', 'crm_stats_snat_entry_used')
709+
avail_counter = getCrmCounterValue(dvs, 'STATS', 'crm_stats_snat_entry_available')
710+
assert used_counter == 0
711+
assert avail_counter != 0
712+
713+
def test_CrmDnatEntry(self, dvs, testlog):
714+
715+
# get counters
716+
used_counter = getCrmCounterValue(dvs, 'STATS', 'crm_stats_dnat_entry_used')
717+
avail_counter = getCrmCounterValue(dvs, 'STATS', 'crm_stats_dnat_entry_available')
718+
assert used_counter == 0
719+
assert avail_counter != 0
720+
721+
# commented ipmc test case till vslib is updated
722+
# def test_CrmIpmcEntry(self, dvs, testlog):
723+
#
724+
# # get counters
725+
# used_counter = getCrmCounterValue(dvs, 'STATS', 'crm_stats_ipmc_entry_used')
726+
# avail_counter = getCrmCounterValue(dvs, 'STATS', 'crm_stats_ipmc_entry_available')
727+
# assert used_counter == 0
728+
# assert avail_counter != 0
729+
705730
def test_Configure(self, dvs, testlog):
706731

707732
#polling interval
@@ -905,6 +930,50 @@ def test_Configure_fdb(self, dvs, testlog):
905930
threshold_type = getCrmConfigStr(dvs, 'Config', 'fdb_entry_threshold_type')
906931
assert threshold_type == 'percentage'
907932

933+
def test_Configure_snat(self, dvs, testlog):
934+
935+
#thresholds snat low/high threshold/type
936+
dvs.runcmd("crm config thresholds snat low 50")
937+
dvs.runcmd("crm config thresholds snat high 90")
938+
dvs.runcmd("crm config thresholds snat type percentage")
939+
940+
time.sleep(2)
941+
threshold_low = getCrmConfigValue(dvs, 'Config', 'snat_entry_low_threshold')
942+
assert threshold_low == 50
943+
threshold_high = getCrmConfigValue(dvs, 'Config', 'snat_entry_high_threshold')
944+
assert threshold_high == 90
945+
threshold_type = getCrmConfigStr(dvs, 'Config', 'snat_entry_threshold_type')
946+
assert threshold_type == 'percentage'
947+
948+
def test_Configure_dnat(self, dvs, testlog):
949+
950+
#thresholds dnat low/high threshold/type
951+
dvs.runcmd("crm config thresholds dnat low 50")
952+
dvs.runcmd("crm config thresholds dnat high 90")
953+
dvs.runcmd("crm config thresholds dnat type percentage")
954+
955+
time.sleep(2)
956+
threshold_low = getCrmConfigValue(dvs, 'Config', 'dnat_entry_low_threshold')
957+
assert threshold_low == 50
958+
threshold_high = getCrmConfigValue(dvs, 'Config', 'dnat_entry_high_threshold')
959+
assert threshold_high == 90
960+
threshold_type = getCrmConfigStr(dvs, 'Config', 'dnat_entry_threshold_type')
961+
assert threshold_type == 'percentage'
962+
963+
def test_Configure_ipmc(self, dvs, testlog):
964+
965+
#thresholds ipmc low/high threshold/type
966+
dvs.runcmd("crm config thresholds ipmc low 50")
967+
dvs.runcmd("crm config thresholds ipmc high 90")
968+
dvs.runcmd("crm config thresholds ipmc type percentage")
969+
970+
time.sleep(2)
971+
threshold_low = getCrmConfigValue(dvs, 'Config', 'ipmc_entry_low_threshold')
972+
assert threshold_low == 50
973+
threshold_high = getCrmConfigValue(dvs, 'Config', 'ipmc_entry_high_threshold')
974+
assert threshold_high == 90
975+
threshold_type = getCrmConfigStr(dvs, 'Config', 'ipmc_entry_threshold_type')
976+
assert threshold_type == 'percentage'
908977

909978
# Add Dummy always-pass test at end as workaroud
910979
# for issue when Flaky fail on final test it invokes module tear-down before retrying

0 commit comments

Comments
 (0)