-
Notifications
You must be signed in to change notification settings - Fork 26
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
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this 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.
ret = vpp_acl_interface_unbind(hwif_name.c_str(), acl_swindex, is_input); | ||
|
||
if(ret == 0) { | ||
hwif_list.remove(hwif_name); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
} else { | ||
acl_swindex = vpp_idx_it->second; | ||
acl_replace = true; | ||
if(acl->count > 0) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain this?
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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.");; |
There was a problem hiding this comment.
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()); |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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?
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.