diff --git a/orchagent/main.cpp b/orchagent/main.cpp index 34506f8dbf01..0e83f2b41c15 100644 --- a/orchagent/main.cpp +++ b/orchagent/main.cpp @@ -42,6 +42,7 @@ sai_scheduler_group_api_t* sai_scheduler_group_api; sai_wred_api_t* sai_wred_api; sai_qos_map_api_t* sai_qos_map_api; sai_buffer_api_t* sai_buffer_api; +sai_acl_api_t* sai_acl_api; /* Global variables */ map gProfileMap; @@ -105,6 +106,7 @@ void initSaiApi() sai_api_query(SAI_API_QOS_MAPS, (void **)&sai_qos_map_api); sai_api_query(SAI_API_BUFFERS, (void **)&sai_buffer_api); sai_api_query(SAI_API_SCHEDULER_GROUP, (void **)&sai_scheduler_group_api); + sai_api_query(SAI_API_ACL, (void **)&sai_acl_api); sai_log_set(SAI_API_SWITCH, SAI_LOG_NOTICE); sai_log_set(SAI_API_VIRTUAL_ROUTER, SAI_LOG_NOTICE); @@ -125,6 +127,7 @@ void initSaiApi() sai_log_set(SAI_API_QOS_MAPS, SAI_LOG_NOTICE); sai_log_set(SAI_API_BUFFERS, SAI_LOG_NOTICE); sai_log_set(SAI_API_SCHEDULER_GROUP, SAI_LOG_NOTICE); + sai_log_set(SAI_API_ACL, SAI_LOG_NOTICE); } int main(int argc, char **argv) diff --git a/orchagent/qosorch.cpp b/orchagent/qosorch.cpp index 9e5a065e425e..ba7235c5c21b 100644 --- a/orchagent/qosorch.cpp +++ b/orchagent/qosorch.cpp @@ -14,6 +14,7 @@ extern sai_wred_api_t *sai_wred_api; extern sai_qos_map_api_t *sai_qos_map_api; extern sai_scheduler_group_api_t *sai_scheduler_group_api; extern sai_switch_api_t *sai_switch_api; +extern sai_acl_api_t* sai_acl_api; extern PortsOrch *gPortsOrch; @@ -555,6 +556,9 @@ task_process_status QosOrch::handlePfcToQueueTable(Consumer& consumer) QosOrch::QosOrch(DBConnector *db, vector &tableNames) : Orch(db, tableNames) { SWSS_LOG_ENTER(); + + // add ACLs to support Sonic WRED profile. + initColorAcl(); // FIXME: Should be removed as soon as we have ACL configuration support initTableHandlers(); }; @@ -564,6 +568,105 @@ type_map& QosOrch::getTypeMap() return m_qos_type_maps; } +void QosOrch::initColorAcl() +{ + SWSS_LOG_ENTER(); + sai_object_id_t acl_table_id; + + // init ACL system table + acl_table_id = initSystemAclTable(); + + // Add entry to match packets with dscp=8, ecn=0 and set yellow color to them + initAclEntryForEcn(acl_table_id, 1000, 0x00, 0x08, SAI_PACKET_COLOR_YELLOW); + // Add entry to match packets with dscp=0, ecn=0 and set yellow color to them + initAclEntryForEcn(acl_table_id, 999, 0x00, 0x00, SAI_PACKET_COLOR_YELLOW); +} + +sai_object_id_t QosOrch::initSystemAclTable() +{ + SWSS_LOG_ENTER(); + vector attrs; + sai_attribute_t attr; + sai_object_id_t acl_table_id; + sai_status_t status; + + // create system acl table + attr.id = SAI_ACL_TABLE_ATTR_STAGE; + attr.value.s32 = SAI_ACL_STAGE_INGRESS; + attrs.push_back(attr); + + attr.id = SAI_ACL_TABLE_ATTR_PRIORITY; + attr.value.u32 = 10; + attrs.push_back(attr); + + attr.id = SAI_ACL_TABLE_ATTR_FIELD_ECN; + attr.value.booldata = true; + attrs.push_back(attr); + + attr.id = SAI_ACL_TABLE_ATTR_FIELD_DSCP; + attr.value.booldata = true; + attrs.push_back(attr); + + status = sai_acl_api->create_acl_table(&acl_table_id, attrs.size(), &attrs[0]); + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_NOTICE("Successfully created ACL table for ECN coloring"); + } + else + { + SWSS_LOG_ERROR("create system acl table. sai_acl_api->create_acl_table failed: %d", status); + throw runtime_error("Failed to create system acl table"); + } + + return acl_table_id; +} + +void QosOrch::initAclEntryForEcn(sai_object_id_t acl_table_id, sai_uint32_t priority, + sai_uint8_t ecn_field, sai_uint8_t dscp_field, sai_int32_t color) +{ + SWSS_LOG_ENTER(); + vector attrs; + sai_attribute_t attr; + sai_object_id_t acl_entry_id; + sai_status_t status; + + attr.id = SAI_ACL_ENTRY_ATTR_TABLE_ID; + attr.value.oid = acl_table_id; + attrs.push_back(attr); + + attr.id = SAI_ACL_ENTRY_ATTR_PRIORITY; + attr.value.u32 = priority; + attrs.push_back(attr); + + attr.id = SAI_ACL_TABLE_ATTR_FIELD_ECN; + attr.value.aclfield.enable = true; + attr.value.aclfield.data.u8 = ecn_field; + attr.value.aclfield.mask.u8 = 0xff; + attrs.push_back(attr); + + attr.id = SAI_ACL_TABLE_ATTR_FIELD_DSCP; + attr.value.aclfield.enable = true; + attr.value.aclfield.data.u8 = dscp_field; + attr.value.aclfield.mask.u8 = 0xff; + attrs.push_back(attr); + + attr.id = SAI_ACL_ENTRY_ATTR_ACTION_SET_COLOR; + attr.value.aclaction.enable = true; + attr.value.aclaction.parameter.s32 = color; + attrs.push_back(attr); + + status = sai_acl_api->create_acl_entry(&acl_entry_id, attrs.size(), &attrs[0]); + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_NOTICE("Successfully created ACL entry for ECN coloring. dscp=%d, ecn=%d", ecn_field, dscp_field); + } + else + { + SWSS_LOG_ERROR("dscp=%d, ecn=%d. sai_acl_api->create_acl_entry() failed: %d", ecn_field, dscp_field, status); + throw runtime_error("Failed to create color acl entry"); + } +} + void QosOrch::initTableHandlers() { SWSS_LOG_ENTER(); diff --git a/orchagent/qosorch.h b/orchagent/qosorch.h index 67d0183aadef..5e53a7114acb 100644 --- a/orchagent/qosorch.h +++ b/orchagent/qosorch.h @@ -112,6 +112,11 @@ class QosOrch : public Orch typedef map qos_table_handler_map; typedef pair qos_handler_pair; + void initColorAcl(); + sai_object_id_t initSystemAclTable(); + void initAclEntryForEcn(sai_object_id_t acl_table_id, sai_uint32_t priority, + sai_uint8_t ecn_field, sai_uint8_t dscp_field, sai_int32_t color); + void initTableHandlers(); task_process_status handleDscpToTcTable(Consumer& consumer);