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

Add tunterm acl plugin support. #122

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

dypet
Copy link

@dypet dypet commented Oct 15, 2024

Overview:

These changes add support for the recently added tunterm_acl vpp plugin (#114) in sonic-vpp.

Changes:

Added API calls to the new plugin in SaiVppXlate.c, and added logic to SwitchStateBaseAcl.cpp so that the new plugin is called with the appropriate fields instead of the regular ACL plugin when SAI_ACL_ENTRY_ATTR_FIELD_TUNNEL_TERMINATED is received. Ports are recorded in m_acl_tbl_hw_ports_map at table creation so that they may be passed to the tunterm_acl plugin and bound by the new plugin the first time an ACE with SAI_ACL_ENTRY_ATTR_FIELD_TUNNEL_TERMINATED is configured. tunterm_acl ACLs are tracked in m_tunterm_acl_swindex_map similarly to m_acl_swindex_map for a given tbl_oid.

Copy link

linux-foundation-easycla bot commented Oct 15, 2024

CLA Signed

The committers listed above are authorized under a signed CLA.

platform/saivpp/vpplib/SwitchStateBaseAcl.cpp Show resolved Hide resolved
platform/saivpp/vpplib/SwitchStateBaseAcl.cpp Outdated Show resolved Hide resolved
platform/saivpp/vpplib/SwitchStateBaseAcl.cpp Outdated Show resolved Hide resolved
platform/saivpp/vpplib/SwitchStateBaseAcl.cpp Outdated Show resolved Hide resolved
platform/saivpp/vpplib/SwitchStateBaseAcl.cpp Outdated Show resolved Hide resolved
platform/saivpp/vpplib/SwitchStateBaseAcl.cpp Outdated Show resolved Hide resolved
platform/saivpp/vpplib/SwitchStateBaseAcl.cpp Outdated Show resolved Hide resolved
platform/saivpp/vpplib/vppxlate/SaiVppXlate.c Outdated Show resolved Hide resolved
Copy link
Contributor

@AkeelAli AkeelAli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If not already done, can you please re-run the basic ACL redirect tests with the latest plugin (as some changes were made before it was merged). You can wait until the final version of this review to do that.

platform/saivpp/vpplib/SwitchStateBaseAcl.cpp Outdated Show resolved Hide resolved
platform/saivpp/vpplib/SwitchStateBaseAcl.cpp Outdated Show resolved Hide resolved
ret = vpp_acl_interface_unbind(hwif_name.c_str(), acl_swindex, is_input);

if(ret == 0) {
hwif_list.remove(hwif_name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the unbind case, wouldn't hwif_list always be empty?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

@@ -1290,6 +1639,11 @@ sai_status_t SwitchStateBase::aclBindUnbindPorts(
is_bind ? "bound to": "unbound from", hwif_name.c_str());
}

for(auto hwif: hwif_list) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this correctly update the ports_map in the unbind case?

Copy link
Author

@dypet dypet Oct 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved the ports_map unbind update above directly in the unbind case

for (uint32_t i = 0; i < p_ace->attrs_count; i++) {
attr = &p_ace->attrs[i];
if(attr->id == SAI_ACL_ENTRY_ATTR_FIELD_TUNNEL_TERMINATED) {
if(attr->value.aclfield.data.booldata == true) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Collapse these into a single if statement as they are part of the same check.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case want to still break out of the loop when SAI_ACL_ENTRY_ATTR_FIELD_TUNNEL_TERMINATED is false - updated the same check later on to be in a single 'if' statement.

platform/saivpp/vpplib/SwitchStateBaseAcl.cpp Outdated Show resolved Hide resolved
platform/saivpp/vpplib/vppxlate/SaiVppXlate.h Outdated Show resolved Hide resolved
platform/saivpp/vpplib/SwitchStateBaseAcl.cpp Outdated Show resolved Hide resolved
} else {
acl_swindex = vpp_idx_it->second;
acl_replace = true;
if(acl->count > 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block shouldn't have changed, yet it's marked as a diff here due to indentation changes. Please revert this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check for acl->count > 0 was added here to skip this block for the cases where there are only tunterm acl rules and no standard acl rules

@@ -563,6 +825,30 @@ sai_status_t SwitchStateBase::AclTblConfig(
ordered_aces.sort(cmp_priority);
// SWSS_LOG_NOTICE("# aces %u after sort", ordered_aces.size());

size_t n_entries = 0;
size_t n_tunterm_entries = 0;
for (auto ace: ordered_aces) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is too long. We'd better break it into a few smaller functions. For example, for the part that converting ACE to acl_tbl_entries_t and sort can be one function. From sorted acl_tbl_entries_t to vpp_acl_t and vpp_tunerm_acl_t can be another function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conceptually with tunterm feature, each ACL table can have 1 or 2 ACL objects in VPP: one for regular ACL and one for tunterm ACL. In the create/update request, we go through the ACEs and convert them to 2 lists of vpp_acl_t and vpp_tunterm_acl_t (you can create a super data structure including the 2 lists). Then we pass the 2 lists along with table_id to a function. The function reads acl_swindex and tunterm_acl_swindex from table_id and does necessary operation to create/update/delete acl or tunterm acl from vpp.


if(update_tunterm_rule) {
if(acl->count>0 && (rule<(&acl->rules[0]+n_entries))) {
memset(rule, 0, sizeof(*rule)); // clear any fields that were added to regular rule
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When iterating through the incoming rule's sai attributes we don't know if it's a tunterm acl or regular acl until SAI_ACL_ENTRY_ATTR_FIELD_TUNNEL_TERMINATED is encountered. There are common attr between the two, like SAI_ACL_ENTRY_ATTR_FIELD_DST_IP, which would need to be populated in both cases. Both rules (regular acl and tunterm acl) are updated in parallel while looping through the sai attributes, and then at the end once we know if it's a tunterm rule or not we clear the other rule which potentially had fields populated.

@@ -1016,6 +1018,12 @@ namespace saivpp
_In_ sai_object_id_t tbl_oid,
_In_ bool is_add);

sai_status_t tbl_hw_ports_map_delete(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some documents to explain these new functions

SWSS_LOG_NOTICE("Tunterm ACL table %s %s status %d", tbl_sid.c_str(),
acl_replace ? "replace" : "add", status);
} else {
SWSS_LOG_NOTICE("ACL plugin operation failed, skipping tunterm configuration.");;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be an error

auto it_hw_ports = m_acl_tbl_hw_ports_map.find(tbl_oid);
if (it_hw_ports == m_acl_tbl_hw_ports_map.end()) {
auto sid = sai_serialize_object_id(tbl_oid);
SWSS_LOG_WARN("Tunterm acl - no ports bound for table id %s", sid.c_str());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a warning? It is normal that an ACL not attached to any ports, right?

SWSS_LOG_NOTICE("ACL table %s %s status %d", tbl_sid.c_str(),
acl_replace ? "replace" : "add", status);

if(status == SAI_STATUS_SUCCESS) {
status = tunterm_acl_add_replace(tunterm_acl, tbl_oid);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what will happen if tunterm ACEs removed from ACL? Do you need to call tunterm_acl_delete?

@@ -778,6 +1081,8 @@ sai_status_t SwitchStateBase::AclTblRemove(
m_acl_tbl_rules_map.erase(it);
}

status = tunterm_acl_delete(tbl_oid);

auto vpp_idx_it = m_acl_swindex_map.find(tbl_oid);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the ACL has tunterm only, will you see below error?

@@ -563,6 +825,30 @@ sai_status_t SwitchStateBase::AclTblConfig(
ordered_aces.sort(cmp_priority);
// SWSS_LOG_NOTICE("# aces %u after sort", ordered_aces.size());

size_t n_entries = 0;
size_t n_tunterm_entries = 0;
for (auto ace: ordered_aces) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conceptually with tunterm feature, each ACL table can have 1 or 2 ACL objects in VPP: one for regular ACL and one for tunterm ACL. In the create/update request, we go through the ACEs and convert them to 2 lists of vpp_acl_t and vpp_tunterm_acl_t (you can create a super data structure including the 2 lists). Then we pass the 2 lists along with table_id to a function. The function reads acl_swindex and tunterm_acl_swindex from table_id and does necessary operation to create/update/delete acl or tunterm acl from vpp.

sin = &ip_mask->addr.ip4;
sin->sin_addr.s_addr = value->aclfield.mask.ip4;
vpp_ip_addr_t_to_string(ip_addr, dst_ip_str, INET6_ADDRSTRLEN);
SWSS_LOG_NOTICE("Tunterm acl rule has dst IP: %s", dst_ip_str);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change all NOTICE to INFO except very few important one like tunterm acl created/modify/deleted successfully. See issue #116 .

@@ -992,7 +992,9 @@ namespace saivpp

private:
std::map<sai_object_id_t, std::list<sai_object_id_t>> m_acl_tbl_rules_map;
std::map<sai_object_id_t, std::list<std::string>> m_acl_tbl_hw_ports_map;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is already m_acl_tbl_grp_ports_map. If we see acl and tunterm_acl as two objects created from the same acl_table, it is possible to share the same mapping. even m_acl_swindex_map and m_tunterm_acl_swindex_map can be combined to one if we use std::pair or std::Array to keep both indexes in one

return -EINVAL;
}
}
mp->context = store_ptr(tunterm_index);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need it in context? Is it already passed in with tunterm_acl_index?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants