Skip to content

Commit 6bfcdf1

Browse files
committed
net-shapers: implement delete support for NODE scope shaper
JIRA: https://issues.redhat.com/browse/RHEL-89973 commit bf230c4 Author: Paolo Abeni <pabeni@redhat.com> Date: Wed Oct 9 10:09:52 2024 +0200 net-shapers: implement delete support for NODE scope shaper Leverage the previously introduced group operation to implement the removal of NODE scope shaper, re-linking its leaves under the the parent node before actually deleting the specified NODE scope shaper. Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Link: https://patch.msgid.link/763d484b5b69e365acccfd8031b183c647a367a4.1728460186.git.pabeni@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
1 parent 4079943 commit 6bfcdf1

File tree

1 file changed

+74
-12
lines changed

1 file changed

+74
-12
lines changed

net/shaper/shaper.c

Lines changed: 74 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,8 @@ static int net_shaper_parent_from_leaves(int leaves_count,
785785
}
786786

787787
static int __net_shaper_group(struct net_shaper_binding *binding,
788-
int leaves_count, struct net_shaper *leaves,
788+
bool update_node, int leaves_count,
789+
struct net_shaper *leaves,
789790
struct net_shaper *node,
790791
struct netlink_ext_ack *extack)
791792
{
@@ -831,12 +832,14 @@ static int __net_shaper_group(struct net_shaper_binding *binding,
831832
}
832833
}
833834

834-
/* For newly created node scope shaper, the following will update
835-
* the handle, due to id allocation.
836-
*/
837-
ret = net_shaper_pre_insert(binding, &node->handle, extack);
838-
if (ret)
839-
return ret;
835+
if (update_node) {
836+
/* For newly created node scope shaper, the following will
837+
* update the handle, due to id allocation.
838+
*/
839+
ret = net_shaper_pre_insert(binding, &node->handle, extack);
840+
if (ret)
841+
return ret;
842+
}
840843

841844
for (i = 0; i < leaves_count; ++i) {
842845
leaf_handle = leaves[i].handle;
@@ -864,7 +867,8 @@ static int __net_shaper_group(struct net_shaper_binding *binding,
864867
*/
865868
if (new_node && parent)
866869
parent->leaves++;
867-
net_shaper_commit(binding, 1, node);
870+
if (update_node)
871+
net_shaper_commit(binding, 1, node);
868872
net_shaper_commit(binding, leaves_count, leaves);
869873
return 0;
870874

@@ -873,6 +877,64 @@ static int __net_shaper_group(struct net_shaper_binding *binding,
873877
return ret;
874878
}
875879

880+
static int net_shaper_pre_del_node(struct net_shaper_binding *binding,
881+
const struct net_shaper *shaper,
882+
struct netlink_ext_ack *extack)
883+
{
884+
struct net_shaper_hierarchy *hierarchy = net_shaper_hierarchy(binding);
885+
struct net_shaper *cur, *leaves, node = {};
886+
int ret, leaves_count = 0;
887+
unsigned long index;
888+
bool update_node;
889+
890+
if (!shaper->leaves)
891+
return 0;
892+
893+
/* Fetch the new node information. */
894+
node.handle = shaper->parent;
895+
cur = net_shaper_lookup(binding, &node.handle);
896+
if (cur) {
897+
node = *cur;
898+
} else {
899+
/* A scope NODE shaper can be nested only to the NETDEV scope
900+
* shaper without creating the latter, this check may fail only
901+
* if the data is in inconsistent status.
902+
*/
903+
if (WARN_ON_ONCE(node.handle.scope != NET_SHAPER_SCOPE_NETDEV))
904+
return -EINVAL;
905+
}
906+
907+
leaves = kcalloc(shaper->leaves, sizeof(struct net_shaper),
908+
GFP_KERNEL);
909+
if (!leaves)
910+
return -ENOMEM;
911+
912+
/* Build the leaves arrays. */
913+
xa_for_each(&hierarchy->shapers, index, cur) {
914+
if (net_shaper_handle_cmp(&cur->parent, &shaper->handle))
915+
continue;
916+
917+
if (WARN_ON_ONCE(leaves_count == shaper->leaves)) {
918+
ret = -EINVAL;
919+
goto free;
920+
}
921+
922+
leaves[leaves_count++] = *cur;
923+
}
924+
925+
/* When re-linking to the netdev shaper, avoid the eventual, implicit,
926+
* creation of the new node, would be surprising since the user is
927+
* doing a delete operation.
928+
*/
929+
update_node = node.handle.scope != NET_SHAPER_SCOPE_NETDEV;
930+
ret = __net_shaper_group(binding, update_node, leaves_count,
931+
leaves, &node, extack);
932+
933+
free:
934+
kfree(leaves);
935+
return ret;
936+
}
937+
876938
int net_shaper_nl_delete_doit(struct sk_buff *skb, struct genl_info *info)
877939
{
878940
struct net_shaper_hierarchy *hierarchy;
@@ -905,9 +967,9 @@ int net_shaper_nl_delete_doit(struct sk_buff *skb, struct genl_info *info)
905967
}
906968

907969
if (handle.scope == NET_SHAPER_SCOPE_NODE) {
908-
/* TODO: implement support for scope NODE delete. */
909-
ret = -EINVAL;
910-
goto unlock;
970+
ret = net_shaper_pre_del_node(binding, shaper, info->extack);
971+
if (ret)
972+
goto unlock;
911973
}
912974

913975
ret = __net_shaper_delete(binding, shaper, info->extack);
@@ -1027,7 +1089,7 @@ int net_shaper_nl_group_doit(struct sk_buff *skb, struct genl_info *info)
10271089
}
10281090
}
10291091

1030-
ret = __net_shaper_group(binding, leaves_count, leaves, &node,
1092+
ret = __net_shaper_group(binding, true, leaves_count, leaves, &node,
10311093
info->extack);
10321094
if (ret)
10331095
goto free_msg;

0 commit comments

Comments
 (0)