Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[aclorch] if vendor does not implement ACL action capability quieries… #1106

Merged
merged 3 commits into from
Oct 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 111 additions & 54 deletions orchagent/aclorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,20 @@ static acl_stage_type_lookup_t aclStageLookUp =
{STAGE_EGRESS, ACL_STAGE_EGRESS }
};

static const acl_capabilities_t defaultAclActionsSupported =
{
{
ACL_STAGE_INGRESS,
{
SAI_ACL_ACTION_TYPE_PACKET_ACTION,
SAI_ACL_ACTION_TYPE_MIRROR_INGRESS
}
},
{
ACL_STAGE_EGRESS, {}
}
};

static acl_ip_type_lookup_t aclIpTypeLookup =
{
{ IP_TYPE_ANY, SAI_ACL_IP_TYPE_ANY },
Expand Down Expand Up @@ -2129,68 +2143,59 @@ void AclOrch::queryAclActionCapability()
sai_status_t status {SAI_STATUS_FAILURE};
sai_attribute_t attr;
vector<int32_t> action_list;
vector<FieldValueTuple> fvVector;

attr.id = SAI_SWITCH_ATTR_MAX_ACL_ACTION_COUNT;
status = sai_switch_api->get_switch_attribute(gSwitchId, 1, &attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_THROW("AclOrch initialization failed: "
"failed to query maximum ACL action count");
}

const auto max_action_count = attr.value.u32;

for (auto stage_attr: {SAI_SWITCH_ATTR_ACL_STAGE_INGRESS, SAI_SWITCH_ATTR_ACL_STAGE_EGRESS})
if (status == SAI_STATUS_SUCCESS)
{
auto stage = (stage_attr == SAI_SWITCH_ATTR_ACL_STAGE_INGRESS ? ACL_STAGE_INGRESS : ACL_STAGE_EGRESS);
auto stage_str = (stage_attr == SAI_SWITCH_ATTR_ACL_STAGE_INGRESS ? STAGE_INGRESS : STAGE_EGRESS);
action_list.resize(static_cast<size_t>(max_action_count));

attr.id = stage_attr;
attr.value.aclcapability.action_list.list = action_list.data();
attr.value.aclcapability.action_list.count = max_action_count;
const auto max_action_count = attr.value.u32;

status = sai_switch_api->get_switch_attribute(gSwitchId, 1, &attr);
if (status != SAI_STATUS_SUCCESS)
for (auto stage_attr: {SAI_SWITCH_ATTR_ACL_STAGE_INGRESS, SAI_SWITCH_ATTR_ACL_STAGE_EGRESS})
{
SWSS_LOG_THROW("AclOrch initialization failed: "
"failed to query supported %s ACL actions", stage_str);
}
auto stage = (stage_attr == SAI_SWITCH_ATTR_ACL_STAGE_INGRESS ? ACL_STAGE_INGRESS : ACL_STAGE_EGRESS);
auto stage_str = (stage_attr == SAI_SWITCH_ATTR_ACL_STAGE_INGRESS ? STAGE_INGRESS : STAGE_EGRESS);
action_list.resize(static_cast<size_t>(max_action_count));

SWSS_LOG_INFO("Supported %s action count %d:", stage_str,
attr.value.aclcapability.action_list.count);
attr.id = stage_attr;
attr.value.aclcapability.action_list.list = action_list.data();
attr.value.aclcapability.action_list.count = max_action_count;

for (size_t i = 0; i < static_cast<size_t>(attr.value.aclcapability.action_list.count); i++)
{
auto action = static_cast<sai_acl_action_type_t>(action_list[i]);
m_aclCapabilities[stage].insert(action);
SWSS_LOG_INFO(" %s", sai_serialize_enum(action, &sai_metadata_enum_sai_acl_action_type_t).c_str());
}

// put capabilities in state DB
status = sai_switch_api->get_switch_attribute(gSwitchId, 1, &attr);
if (status == SAI_STATUS_SUCCESS)
{

auto field = std::string("ACL_ACTIONS") + '|' + stage_str;
auto& acl_action_set = m_aclCapabilities[stage];
SWSS_LOG_INFO("Supported %s action count %d:", stage_str,
attr.value.aclcapability.action_list.count);

string delimiter;
ostringstream acl_action_value_stream;

for (const auto& action_map: {aclL3ActionLookup, aclMirrorStageLookup, aclDTelActionLookup})
{
for (const auto& it: action_map)
{
auto saiAction = getAclActionFromAclEntry(it.second);
if (acl_action_set.find(saiAction) != acl_action_set.cend())
for (size_t i = 0; i < static_cast<size_t>(attr.value.aclcapability.action_list.count); i++)
{
acl_action_value_stream << delimiter << it.first;
delimiter = comma;
auto action = static_cast<sai_acl_action_type_t>(action_list[i]);
m_aclCapabilities[stage].insert(action);
SWSS_LOG_INFO(" %s", sai_serialize_enum(action, &sai_metadata_enum_sai_acl_action_type_t).c_str());
}
}
}
else
{
SWSS_LOG_WARN("Failed to query ACL %s action capabilities - "
"API assumed to be not implemented, using defaults",
stage_str);
initDefaultAclActionCapabilities(stage);
}

fvVector.emplace_back(field, acl_action_value_stream.str());
m_switchTable.set("switch", fvVector);
// put capabilities in state DB
putAclActionCapabilityInDB(stage);
}
}
else
{
SWSS_LOG_WARN("Failed to query maximum ACL action count - "
"API assumed to be not implemented, using defaults capabilities for both %s and %s",
STAGE_INGRESS, STAGE_EGRESS);
for (auto stage: {ACL_STAGE_INGRESS, ACL_STAGE_EGRESS})
{
initDefaultAclActionCapabilities(stage);
putAclActionCapabilityInDB(stage);
}
}

/* For those ACL action entry attributes for which acl parameter is enumeration (metadata->isenum == true)
Expand All @@ -2209,6 +2214,50 @@ void AclOrch::queryAclActionCapability()
aclDTelFlowOpTypeLookup);
}

void AclOrch::putAclActionCapabilityInDB(acl_stage_type_t stage)
{
vector<FieldValueTuple> fvVector;
auto stage_str = (stage == ACL_STAGE_INGRESS ? STAGE_INGRESS : STAGE_EGRESS);

auto field = std::string("ACL_ACTIONS") + '|' + stage_str;
auto& acl_action_set = m_aclCapabilities[stage];

string delimiter;
ostringstream acl_action_value_stream;

for (const auto& action_map: {aclL3ActionLookup, aclMirrorStageLookup, aclDTelActionLookup})
{
for (const auto& it: action_map)
{
auto saiAction = getAclActionFromAclEntry(it.second);
if (acl_action_set.find(saiAction) != acl_action_set.cend())
{
acl_action_value_stream << delimiter << it.first;
delimiter = comma;
}
}
}

fvVector.emplace_back(field, acl_action_value_stream.str());
m_switchTable.set("switch", fvVector);
}

void AclOrch::initDefaultAclActionCapabilities(acl_stage_type_t stage)
{
m_aclCapabilities[stage] = defaultAclActionsSupported.at(stage);

SWSS_LOG_INFO("Assumed %s %zu actions to be supported:",
stage == ACL_STAGE_INGRESS ? STAGE_INGRESS : STAGE_EGRESS,
m_aclCapabilities[stage].size());

for (auto action: m_aclCapabilities[stage])
{
SWSS_LOG_INFO(" %s", sai_serialize_enum(action, &sai_metadata_enum_sai_acl_action_type_t).c_str());
}
// put capabilities in state DB
putAclActionCapabilityInDB(stage);
}

template<typename AclActionAttrLookupT>
void AclOrch::queryAclActionAttrEnumValues(const string &action_name,
const acl_rule_attr_lookup_t& ruleAttrLookupMap,
Expand Down Expand Up @@ -2251,15 +2300,23 @@ void AclOrch::queryAclActionAttrEnumValues(const string &action_name,
SAI_OBJECT_TYPE_ACL_ENTRY,
acl_attr,
&values);
if (status != SAI_STATUS_SUCCESS)
if (status == SAI_STATUS_SUCCESS)
{
SWSS_LOG_THROW("sai_query_attribute_enum_values_capability failed for %s",
action_name.c_str());
for (size_t i = 0; i < values.count; i++)
{
m_aclEnumActionCapabilities[acl_action].insert(values.list[i]);
}
}

for (size_t i = 0; i < values.count; i++)
else
{
m_aclEnumActionCapabilities[acl_action].insert(values.list[i]);
SWSS_LOG_WARN("Failed to query enum values supported for ACL action %s - ",
"API is not implemented, assuming all values are supported for this action",
action_name.c_str());
/* assume all enum values are supported */
for (size_t i = 0; i < meta->enummetadata->valuescount; i++)
{
m_aclEnumActionCapabilities[acl_action].insert(meta->enummetadata->values[i]);
}
}
#else
/* assume all enum values are supported untill sai object api is available */
Expand Down
2 changes: 2 additions & 0 deletions orchagent/aclorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,8 @@ class AclOrch : public Orch, public Observer

void queryMirrorTableCapability();
void queryAclActionCapability();
void initDefaultAclActionCapabilities(acl_stage_type_t);
void putAclActionCapabilityInDB(acl_stage_type_t);

template<typename AclActionAttrLookupT>
void queryAclActionAttrEnumValues(const string& action_name,
Expand Down