diff --git a/orchagent/aclorch.cpp b/orchagent/aclorch.cpp index de5035a0666f..7dc2bc2afe87 100644 --- a/orchagent/aclorch.cpp +++ b/orchagent/aclorch.cpp @@ -498,6 +498,11 @@ shared_ptr AclRule::makeShared(acl_table_type_t type, AclOrch *acl, Mir { return make_shared(acl, rule, table, type); } + /* Pfcwd rules can exist only in PFCWD table */ + else if (type == ACL_TABLE_PFCWD) + { + return make_shared(acl, rule, table, type); + } throw runtime_error("Wrong combination of table type and action in rule " + rule); } @@ -739,6 +744,23 @@ void AclRuleL3::update(SubjectType, void *) // Do nothing } + +AclRulePfcwd::AclRulePfcwd(AclOrch *aclOrch, string rule, string table, acl_table_type_t type) : + AclRuleL3(aclOrch, rule, table, type) +{ +} + +bool AclRulePfcwd::validateAddMatch(string attr_name, string attr_value) +{ + if (attr_name != MATCH_TC) + { + SWSS_LOG_ERROR("%s is not supported for the tables of type Pfcwd", attr_name.c_str()); + return false; + } + + return AclRule::validateAddMatch(attr_name, attr_value); +} + AclRuleL3V6::AclRuleL3V6(AclOrch *aclOrch, string rule, string table, acl_table_type_t type) : AclRuleL3(aclOrch, rule, table, type) { @@ -761,6 +783,7 @@ bool AclRuleL3V6::validateAddMatch(string attr_name, string attr_value) return AclRule::validateAddMatch(attr_name, attr_value); } + AclRuleMirror::AclRuleMirror(AclOrch *aclOrch, MirrorOrch *mirror, string rule, string table, acl_table_type_t type) : AclRule(aclOrch, rule, table, type), m_state(false), @@ -971,6 +994,26 @@ bool AclTable::create() attr.value.s32list.list = bpoint_list.data(); table_attrs.push_back(attr); + if (type == ACL_TABLE_PFCWD) + { + attr.id = SAI_ACL_TABLE_ATTR_FIELD_TC; + attr.value.booldata = true; + table_attrs.push_back(attr); + + attr.id = SAI_ACL_TABLE_ATTR_ACL_STAGE; + attr.value.s32 = stage == ACL_STAGE_INGRESS ? SAI_ACL_STAGE_INGRESS : SAI_ACL_STAGE_EGRESS; + table_attrs.push_back(attr); + + sai_status_t status = sai_acl_api->create_acl_table(&m_oid, gSwitchId, (uint32_t)table_attrs.size(), table_attrs.data()); + + if (status == SAI_STATUS_SUCCESS) + { + gCrmOrch->incCrmAclUsedCounter(CrmResourceType::CRM_ACL_TABLE, (sai_acl_stage_t) attr.value.s32, SAI_ACL_BIND_POINT_TYPE_PORT); + } + + return status == SAI_STATUS_SUCCESS; + } + attr.id = SAI_ACL_TABLE_ATTR_FIELD_ETHER_TYPE; attr.value.booldata = true; table_attrs.push_back(attr); diff --git a/orchagent/aclorch.h b/orchagent/aclorch.h index bfb6229f392f..c96dbd8d30bc 100644 --- a/orchagent/aclorch.h +++ b/orchagent/aclorch.h @@ -25,6 +25,7 @@ #define TABLE_TYPE_L3 "L3" #define TABLE_TYPE_L3V6 "L3V6" #define TABLE_TYPE_MIRROR "MIRROR" +#define TABLE_TYPE_PFCWD "PFCWD" #define TABLE_TYPE_CTRLPLANE "CTRLPLANE" #define RULE_PRIORITY "PRIORITY" @@ -69,6 +70,7 @@ typedef enum ACL_TABLE_L3, ACL_TABLE_L3V6, ACL_TABLE_MIRROR, + ACL_TABLE_PFCWD, ACL_TABLE_CTRLPLANE } acl_table_type_t; @@ -207,6 +209,14 @@ class AclRuleL3V6: public AclRuleL3 bool validateAddMatch(string attr_name, string attr_value); }; +class AclRulePfcwd: public AclRuleL3 +{ +public: + AclRulePfcwd(AclOrch *m_pAclOrch, string rule, string table, acl_table_type_t type); + bool validateAddMatch(string attr_name, string attr_value); +}; + + class AclRuleMirror: public AclRule { public: diff --git a/orchagent/pfcactionhandler.cpp b/orchagent/pfcactionhandler.cpp index 1dd04c36a743..e03f2b37a488 100644 --- a/orchagent/pfcactionhandler.cpp +++ b/orchagent/pfcactionhandler.cpp @@ -211,7 +211,7 @@ PfcWdAclHandler::PfcWdAclHandler(sai_object_id_t port, sai_object_id_t queue, { SWSS_LOG_ENTER(); - acl_table_type_t table_type = ACL_TABLE_L3; + acl_table_type_t table_type = ACL_TABLE_PFCWD; // There is one handler instance per queue ID string queuestr = to_string(queueId); @@ -224,7 +224,7 @@ PfcWdAclHandler::PfcWdAclHandler(sai_object_id_t port, sai_object_id_t queue, { // First time of handling PFC for this queue, create ACL table, and bind createPfcAclTable(port, m_strIngressTable, true); - shared_ptr newRule = make_shared(gAclOrch, m_strRule, m_strIngressTable, table_type); + shared_ptr newRule = make_shared(gAclOrch, m_strRule, m_strIngressTable, table_type); createPfcAclRule(newRule, queueId, m_strIngressTable); } else @@ -238,7 +238,7 @@ PfcWdAclHandler::PfcWdAclHandler(sai_object_id_t port, sai_object_id_t queue, { // First time of handling PFC for this queue, create ACL table, and bind createPfcAclTable(port, m_strEgressTable, false); - shared_ptr newRule = make_shared(gAclOrch, m_strRule, m_strEgressTable, table_type); + shared_ptr newRule = make_shared(gAclOrch, m_strRule, m_strEgressTable, table_type); createPfcAclRule(newRule, queueId, m_strEgressTable); } else @@ -281,14 +281,14 @@ void PfcWdAclHandler::createPfcAclTable(sai_object_id_t port, string strTable, b assert(inserted.second); AclTable& aclTable = inserted.first->second; - aclTable.type = ACL_TABLE_L3; + aclTable.type = ACL_TABLE_PFCWD; aclTable.link(port); aclTable.id = strTable; aclTable.stage = ingress ? ACL_STAGE_INGRESS : ACL_STAGE_EGRESS; gAclOrch->addAclTable(aclTable, strTable); } -void PfcWdAclHandler::createPfcAclRule(shared_ptr rule, uint8_t queueId, string strTable) +void PfcWdAclHandler::createPfcAclRule(shared_ptr rule, uint8_t queueId, string strTable) { SWSS_LOG_ENTER(); diff --git a/orchagent/pfcactionhandler.h b/orchagent/pfcactionhandler.h index d1450d50f3aa..75435dfe08ba 100644 --- a/orchagent/pfcactionhandler.h +++ b/orchagent/pfcactionhandler.h @@ -111,7 +111,7 @@ class PfcWdAclHandler: public PfcWdLossyHandler string m_strEgressTable; string m_strRule; void createPfcAclTable(sai_object_id_t port, string strTable, bool ingress); - void createPfcAclRule(shared_ptr rule, uint8_t queueId, string strTable); + void createPfcAclRule(shared_ptr rule, uint8_t queueId, string strTable); }; // PFC queue that implements drop action by draining queue with buffer of zero size