diff --git a/doc/Configuration.md b/doc/Configuration.md index 3e4195011f83..7a1941fc3189 100644 --- a/doc/Configuration.md +++ b/doc/Configuration.md @@ -539,7 +539,16 @@ group name and IP ranges in **BGP_PEER_RANGE** table. "ipv4_neighbor_low_threshold": "70", "acl_group_threshold_type": "percentage", "ipv4_nexthop_high_threshold": "85", - "ipv6_route_threshold_type": "percentage" + "ipv6_route_threshold_type": "percentage", + "snat_entry_threshold_type": "percentage", + "snat_entry_high_threshold": "85", + "snat_entry_low_threshold": "70", + "dnat_entry_threshold_type": "percentage", + "dnat_entry_high_threshold": "85", + "dnat_entry_low_threshold": "70", + "ipmc_entry_threshold_type": "percentage", + "ipmc_entry_high_threshold": "85", + "ipmc_entry_low_threshold": "70" } } } diff --git a/orchagent/crmorch.cpp b/orchagent/crmorch.cpp index 14ded73d3946..60c9e0a621ca 100644 --- a/orchagent/crmorch.cpp +++ b/orchagent/crmorch.cpp @@ -37,7 +37,10 @@ const map crmResTypeNameMap = { CrmResourceType::CRM_ACL_GROUP, "ACL_GROUP" }, { CrmResourceType::CRM_ACL_ENTRY, "ACL_ENTRY" }, { CrmResourceType::CRM_ACL_COUNTER, "ACL_COUNTER" }, - { CrmResourceType::CRM_FDB_ENTRY, "FDB_ENTRY" } + { CrmResourceType::CRM_FDB_ENTRY, "FDB_ENTRY" }, + { CrmResourceType::CRM_IPMC_ENTRY, "IPMC_ENTRY" }, + { CrmResourceType::CRM_SNAT_ENTRY, "SNAT_ENTRY" }, + { CrmResourceType::CRM_DNAT_ENTRY, "DNAT_ENTRY" } }; const map crmResSaiAvailAttrMap = @@ -54,7 +57,10 @@ const map crmResSaiAvailAttrMap = { CrmResourceType::CRM_ACL_GROUP, SAI_SWITCH_ATTR_AVAILABLE_ACL_TABLE_GROUP }, { CrmResourceType::CRM_ACL_ENTRY, SAI_ACL_TABLE_ATTR_AVAILABLE_ACL_ENTRY }, { CrmResourceType::CRM_ACL_COUNTER, SAI_ACL_TABLE_ATTR_AVAILABLE_ACL_COUNTER }, - { CrmResourceType::CRM_FDB_ENTRY, SAI_SWITCH_ATTR_AVAILABLE_FDB_ENTRY } + { CrmResourceType::CRM_FDB_ENTRY, SAI_SWITCH_ATTR_AVAILABLE_FDB_ENTRY }, + { CrmResourceType::CRM_IPMC_ENTRY, SAI_SWITCH_ATTR_AVAILABLE_IPMC_ENTRY}, + { CrmResourceType::CRM_SNAT_ENTRY, SAI_SWITCH_ATTR_AVAILABLE_SNAT_ENTRY }, + { CrmResourceType::CRM_DNAT_ENTRY, SAI_SWITCH_ATTR_AVAILABLE_DNAT_ENTRY } }; const map crmThreshTypeResMap = @@ -71,7 +77,10 @@ const map crmThreshTypeResMap = { "acl_group_threshold_type", CrmResourceType::CRM_ACL_GROUP }, { "acl_entry_threshold_type", CrmResourceType::CRM_ACL_ENTRY }, { "acl_counter_threshold_type", CrmResourceType::CRM_ACL_COUNTER }, - { "fdb_entry_threshold_type", CrmResourceType::CRM_FDB_ENTRY } + { "fdb_entry_threshold_type", CrmResourceType::CRM_FDB_ENTRY }, + { "ipmc_entry_threshold_type", CrmResourceType::CRM_IPMC_ENTRY }, + { "snat_entry_threshold_type", CrmResourceType::CRM_SNAT_ENTRY }, + { "dnat_entry_threshold_type", CrmResourceType::CRM_DNAT_ENTRY } }; const map crmThreshLowResMap = @@ -89,6 +98,9 @@ const map crmThreshLowResMap = {"acl_entry_low_threshold", CrmResourceType::CRM_ACL_ENTRY }, {"acl_counter_low_threshold", CrmResourceType::CRM_ACL_COUNTER }, {"fdb_entry_low_threshold", CrmResourceType::CRM_FDB_ENTRY }, + {"ipmc_entry_low_threshold", CrmResourceType::CRM_IPMC_ENTRY }, + {"snat_entry_low_threshold", CrmResourceType::CRM_SNAT_ENTRY }, + {"dnat_entry_low_threshold", CrmResourceType::CRM_DNAT_ENTRY } }; const map crmThreshHighResMap = @@ -105,7 +117,10 @@ const map crmThreshHighResMap = {"acl_group_high_threshold", CrmResourceType::CRM_ACL_GROUP }, {"acl_entry_high_threshold", CrmResourceType::CRM_ACL_ENTRY }, {"acl_counter_high_threshold", CrmResourceType::CRM_ACL_COUNTER }, - {"fdb_entry_high_threshold", CrmResourceType::CRM_FDB_ENTRY } + {"fdb_entry_high_threshold", CrmResourceType::CRM_FDB_ENTRY }, + {"ipmc_entry_high_threshold", CrmResourceType::CRM_IPMC_ENTRY }, + {"snat_entry_high_threshold", CrmResourceType::CRM_SNAT_ENTRY }, + {"dnat_entry_high_threshold", CrmResourceType::CRM_DNAT_ENTRY } }; const map crmThreshTypeMap = @@ -129,7 +144,10 @@ const map crmAvailCntsTableMap = { "crm_stats_acl_group_available", CrmResourceType::CRM_ACL_GROUP }, { "crm_stats_acl_entry_available", CrmResourceType::CRM_ACL_ENTRY }, { "crm_stats_acl_counter_available", CrmResourceType::CRM_ACL_COUNTER }, - { "crm_stats_fdb_entry_available", CrmResourceType::CRM_FDB_ENTRY } + { "crm_stats_fdb_entry_available", CrmResourceType::CRM_FDB_ENTRY }, + { "crm_stats_ipmc_entry_available", CrmResourceType::CRM_IPMC_ENTRY }, + { "crm_stats_snat_entry_available", CrmResourceType::CRM_SNAT_ENTRY }, + { "crm_stats_dnat_entry_available", CrmResourceType::CRM_DNAT_ENTRY } }; const map crmUsedCntsTableMap = @@ -146,7 +164,10 @@ const map crmUsedCntsTableMap = { "crm_stats_acl_group_used", CrmResourceType::CRM_ACL_GROUP }, { "crm_stats_acl_entry_used", CrmResourceType::CRM_ACL_ENTRY }, { "crm_stats_acl_counter_used", CrmResourceType::CRM_ACL_COUNTER }, - { "crm_stats_fdb_entry_used", CrmResourceType::CRM_FDB_ENTRY } + { "crm_stats_fdb_entry_used", CrmResourceType::CRM_FDB_ENTRY }, + { "crm_stats_ipmc_entry_used", CrmResourceType::CRM_IPMC_ENTRY }, + { "crm_stats_snat_entry_used", CrmResourceType::CRM_SNAT_ENTRY }, + { "crm_stats_dnat_entry_used", CrmResourceType::CRM_DNAT_ENTRY } }; CrmOrch::CrmOrch(DBConnector *db, string tableName): @@ -429,10 +450,18 @@ void CrmOrch::getResAvailableCounters() case SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_MEMBER_ENTRY: case SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_ENTRY: case SAI_SWITCH_ATTR_AVAILABLE_FDB_ENTRY: + case SAI_SWITCH_ATTR_AVAILABLE_IPMC_ENTRY: + case SAI_SWITCH_ATTR_AVAILABLE_SNAT_ENTRY: + case SAI_SWITCH_ATTR_AVAILABLE_DNAT_ENTRY: { sai_status_t status = sai_switch_api->get_switch_attribute(gSwitchId, 1, &attr); if (status != SAI_STATUS_SUCCESS) { + if(status == SAI_STATUS_NOT_SUPPORTED) + { + // remove unsupported resources from map + m_resourcesMap.erase(res.first); + } SWSS_LOG_ERROR("Failed to get switch attribute %u , rv:%d", attr.id, status); break; } @@ -504,22 +533,36 @@ void CrmOrch::updateCrmCountersTable() // Update CRM used counters in COUNTERS_DB for (const auto &i : crmUsedCntsTableMap) { - for (const auto &cnt : m_resourcesMap.at(i.second).countersMap) + try + { + for (const auto &cnt : m_resourcesMap.at(i.second).countersMap) + { + FieldValueTuple attr(i.first, to_string(cnt.second.usedCounter)); + vector attrs = { attr }; + m_countersCrmTable->set(cnt.first, attrs); + } + } + catch(const out_of_range &e) { - FieldValueTuple attr(i.first, to_string(cnt.second.usedCounter)); - vector attrs = { attr }; - m_countersCrmTable->set(cnt.first, attrs); + // expected when a resource is unavailable } } // Update CRM available counters in COUNTERS_DB for (const auto &i : crmAvailCntsTableMap) { - for (const auto &cnt : m_resourcesMap.at(i.second).countersMap) + try + { + for (const auto &cnt : m_resourcesMap.at(i.second).countersMap) + { + FieldValueTuple attr(i.first, to_string(cnt.second.availableCounter)); + vector attrs = { attr }; + m_countersCrmTable->set(cnt.first, attrs); + } + } + catch(const out_of_range &e) { - FieldValueTuple attr(i.first, to_string(cnt.second.availableCounter)); - vector attrs = { attr }; - m_countersCrmTable->set(cnt.first, attrs); + // expected when a resource is unavailable } } } diff --git a/orchagent/crmorch.h b/orchagent/crmorch.h index 488a18b3a7ff..21d039396c89 100644 --- a/orchagent/crmorch.h +++ b/orchagent/crmorch.h @@ -25,6 +25,9 @@ enum class CrmResourceType CRM_ACL_ENTRY, CRM_ACL_COUNTER, CRM_FDB_ENTRY, + CRM_IPMC_ENTRY, + CRM_SNAT_ENTRY, + CRM_DNAT_ENTRY, }; enum class CrmThresholdType diff --git a/tests/test_crm.py b/tests/test_crm.py index 96bf56d4e3fa..38b0de7a0c3c 100644 --- a/tests/test_crm.py +++ b/tests/test_crm.py @@ -702,6 +702,31 @@ def test_CrmAclGroup(self, dvs, testlog): #table_used_counter = getCrmCounterValue(dvs, 'ACL_STATS:INGRESS:PORT', 'crm_stats_acl_group_used') #assert table_used_counter == 0 + def test_CrmSnatEntry(self, dvs, testlog): + + # get counters + used_counter = getCrmCounterValue(dvs, 'STATS', 'crm_stats_snat_entry_used') + avail_counter = getCrmCounterValue(dvs, 'STATS', 'crm_stats_snat_entry_available') + assert used_counter == 0 + assert avail_counter != 0 + + def test_CrmDnatEntry(self, dvs, testlog): + + # get counters + used_counter = getCrmCounterValue(dvs, 'STATS', 'crm_stats_dnat_entry_used') + avail_counter = getCrmCounterValue(dvs, 'STATS', 'crm_stats_dnat_entry_available') + assert used_counter == 0 + assert avail_counter != 0 + +# commented ipmc test case till vslib is updated +# def test_CrmIpmcEntry(self, dvs, testlog): +# +# # get counters +# used_counter = getCrmCounterValue(dvs, 'STATS', 'crm_stats_ipmc_entry_used') +# avail_counter = getCrmCounterValue(dvs, 'STATS', 'crm_stats_ipmc_entry_available') +# assert used_counter == 0 +# assert avail_counter != 0 + def test_Configure(self, dvs, testlog): #polling interval @@ -905,6 +930,50 @@ def test_Configure_fdb(self, dvs, testlog): threshold_type = getCrmConfigStr(dvs, 'Config', 'fdb_entry_threshold_type') assert threshold_type == 'percentage' + def test_Configure_snat(self, dvs, testlog): + + #thresholds snat low/high threshold/type + dvs.runcmd("crm config thresholds snat low 50") + dvs.runcmd("crm config thresholds snat high 90") + dvs.runcmd("crm config thresholds snat type percentage") + + time.sleep(2) + threshold_low = getCrmConfigValue(dvs, 'Config', 'snat_entry_low_threshold') + assert threshold_low == 50 + threshold_high = getCrmConfigValue(dvs, 'Config', 'snat_entry_high_threshold') + assert threshold_high == 90 + threshold_type = getCrmConfigStr(dvs, 'Config', 'snat_entry_threshold_type') + assert threshold_type == 'percentage' + + def test_Configure_dnat(self, dvs, testlog): + + #thresholds dnat low/high threshold/type + dvs.runcmd("crm config thresholds dnat low 50") + dvs.runcmd("crm config thresholds dnat high 90") + dvs.runcmd("crm config thresholds dnat type percentage") + + time.sleep(2) + threshold_low = getCrmConfigValue(dvs, 'Config', 'dnat_entry_low_threshold') + assert threshold_low == 50 + threshold_high = getCrmConfigValue(dvs, 'Config', 'dnat_entry_high_threshold') + assert threshold_high == 90 + threshold_type = getCrmConfigStr(dvs, 'Config', 'dnat_entry_threshold_type') + assert threshold_type == 'percentage' + + def test_Configure_ipmc(self, dvs, testlog): + + #thresholds ipmc low/high threshold/type + dvs.runcmd("crm config thresholds ipmc low 50") + dvs.runcmd("crm config thresholds ipmc high 90") + dvs.runcmd("crm config thresholds ipmc type percentage") + + time.sleep(2) + threshold_low = getCrmConfigValue(dvs, 'Config', 'ipmc_entry_low_threshold') + assert threshold_low == 50 + threshold_high = getCrmConfigValue(dvs, 'Config', 'ipmc_entry_high_threshold') + assert threshold_high == 90 + threshold_type = getCrmConfigStr(dvs, 'Config', 'ipmc_entry_threshold_type') + assert threshold_type == 'percentage' # Add Dummy always-pass test at end as workaroud # for issue when Flaky fail on final test it invokes module tear-down before retrying