summaryrefslogtreecommitdiff
path: root/net/devlink/netlink.c
diff options
context:
space:
mode:
authorCosmin Ratiu <cratiu@nvidia.com>2026-07-01 10:32:46 +0300
committerPaolo Abeni <pabeni@redhat.com>2026-07-07 11:31:26 +0200
commit58132b6fc4a58441d2b99c65a3548f6875cd52d0 (patch)
tree5ac0bf0a492e782bff07f13533f528bc0c65e629 /net/devlink/netlink.c
parentb5f90fd4580ce71aa24ac9afcf5c9b4fa8121518 (diff)
devlink: Allow parent dev for rate-set and rate-new
Currently, a devlink rate's parent device is assumed to be the same as the one where the devlink rate is created. This patch changes that to allow rate commands to accept an additional argument that specifies the parent dev. This will allow devlink rate groups with leafs from other devices. Example of the new usage with ynl: Creating a group on pci/0000:08:00.1 with a parent to an already existing pci/0000:08:00.1/group1: ./tools/net/ynl/pyynl/cli.py --spec \ Documentation/netlink/specs/devlink.yaml --do rate-new --json '{ "bus-name": "pci", "dev-name": "0000:08:00.1", "rate-node-name": "group2", "rate-parent-node-name": "group1", "parent-dev": { "bus-name": "pci", "dev-name": "0000:08:00.1" } }' Setting the parent of leaf node pci/0000:08:00.1/65537 to pci/0000:08:00.0/group1: ./tools/net/ynl/pyynl/cli.py --spec \ Documentation/netlink/specs/devlink.yaml --do rate-set --json '{ "bus-name": "pci", "dev-name": "0000:08:00.1", "port-index": 65537, "parent-dev": { "bus-name": "pci", "dev-name": "0000:08:00.0" }, "rate-parent-node-name": "group1" }' Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com> Reviewed-by: Carolina Jubran <cjubran@nvidia.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Tariq Toukan <tariqt@nvidia.com> Link: https://patch.msgid.link/20260701073254.754518-7-tariqt@nvidia.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'net/devlink/netlink.c')
-rw-r--r--net/devlink/netlink.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/net/devlink/netlink.c b/net/devlink/netlink.c
index 5a057dc86b0f..300580c1a217 100644
--- a/net/devlink/netlink.c
+++ b/net/devlink/netlink.c
@@ -243,7 +243,29 @@ found:
struct devlink *
devlink_get_parent_from_attrs_lock(struct net *net, struct nlattr **attrs)
{
- return ERR_PTR(-EOPNOTSUPP);
+ unsigned int maxtype = ARRAY_SIZE(devlink_dl_parent_dev_nl_policy) - 1;
+ struct devlink *devlink;
+ struct nlattr **tb;
+ int err;
+
+ if (!attrs[DEVLINK_ATTR_PARENT_DEV])
+ return ERR_PTR(-EINVAL);
+
+ tb = kcalloc(maxtype + 1, sizeof(*tb), GFP_KERNEL);
+ if (!tb)
+ return ERR_PTR(-ENOMEM);
+
+ err = nla_parse_nested(tb, maxtype, attrs[DEVLINK_ATTR_PARENT_DEV],
+ devlink_dl_parent_dev_nl_policy, NULL);
+ if (err)
+ goto out;
+
+ devlink = devlink_get_from_attrs_lock(net, tb, false);
+ kfree(tb);
+ return devlink;
+out:
+ kfree(tb);
+ return ERR_PTR(err);
}
static int __devlink_nl_pre_doit(struct sk_buff *skb, struct genl_info *info,
@@ -322,6 +344,14 @@ int devlink_nl_pre_doit_port_optional(const struct genl_split_ops *ops,
return __devlink_nl_pre_doit(skb, info, DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT);
}
+int devlink_nl_pre_doit_parent_dev_optional(const struct genl_split_ops *ops,
+ struct sk_buff *skb,
+ struct genl_info *info)
+{
+ return __devlink_nl_pre_doit(skb, info,
+ DEVLINK_NL_FLAG_OPTIONAL_PARENT_DEV);
+}
+
static void __devlink_nl_post_doit(struct sk_buff *skb, struct genl_info *info,
u8 flags)
{
@@ -348,6 +378,14 @@ devlink_nl_post_doit_dev_lock(const struct genl_split_ops *ops,
__devlink_nl_post_doit(skb, info, DEVLINK_NL_FLAG_NEED_DEV_LOCK);
}
+void
+devlink_nl_post_doit_parent_dev_optional(const struct genl_split_ops *ops,
+ struct sk_buff *skb,
+ struct genl_info *info)
+{
+ __devlink_nl_post_doit(skb, info, DEVLINK_NL_FLAG_OPTIONAL_PARENT_DEV);
+}
+
static int devlink_nl_inst_single_dumpit(struct sk_buff *msg,
struct netlink_callback *cb, int flags,
devlink_nl_dump_one_func_t *dump_one,