mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 17:25:38 +00:00
net: shaper: implement introspection support
The netlink op is a simple wrapper around the device callback. Extend the existing fetch_dev() helper adding an attribute argument for the requested device. Reuse such helper in the newly implemented operation. Reviewed-by: Jiri Pirko <jiri@nvidia.com> Reviewed-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Link: https://patch.msgid.link/66eb62f22b3a5ba06ca91d01ae77515e5f447e15.1728460186.git.pabeni@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
14bba9285a
commit
553ea9f1ef
@ -601,22 +601,29 @@ int net_shaper_nl_post_dumpit(struct netlink_callback *cb)
|
||||
int net_shaper_nl_cap_pre_doit(const struct genl_split_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
return net_shaper_generic_pre(info, NET_SHAPER_A_CAPS_IFINDEX);
|
||||
}
|
||||
|
||||
void net_shaper_nl_cap_post_doit(const struct genl_split_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
net_shaper_generic_post(info);
|
||||
}
|
||||
|
||||
int net_shaper_nl_cap_pre_dumpit(struct netlink_callback *cb)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
struct net_shaper_nl_ctx *ctx = (struct net_shaper_nl_ctx *)cb->ctx;
|
||||
|
||||
return net_shaper_ctx_setup(genl_info_dump(cb),
|
||||
NET_SHAPER_A_CAPS_IFINDEX, ctx);
|
||||
}
|
||||
|
||||
int net_shaper_nl_cap_post_dumpit(struct netlink_callback *cb)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
struct net_shaper_nl_ctx *ctx = (struct net_shaper_nl_ctx *)cb->ctx;
|
||||
|
||||
net_shaper_ctx_cleanup(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int net_shaper_nl_get_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
@ -1147,14 +1154,99 @@ int net_shaper_nl_group_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
goto free_leaves;
|
||||
}
|
||||
|
||||
static int
|
||||
net_shaper_cap_fill_one(struct sk_buff *msg,
|
||||
struct net_shaper_binding *binding,
|
||||
enum net_shaper_scope scope, unsigned long flags,
|
||||
const struct genl_info *info)
|
||||
{
|
||||
unsigned long cur;
|
||||
void *hdr;
|
||||
|
||||
hdr = genlmsg_iput(msg, info);
|
||||
if (!hdr)
|
||||
return -EMSGSIZE;
|
||||
|
||||
if (net_shaper_fill_binding(msg, binding, NET_SHAPER_A_CAPS_IFINDEX) ||
|
||||
nla_put_u32(msg, NET_SHAPER_A_CAPS_SCOPE, scope))
|
||||
goto nla_put_failure;
|
||||
|
||||
for (cur = NET_SHAPER_A_CAPS_SUPPORT_METRIC_BPS;
|
||||
cur <= NET_SHAPER_A_CAPS_MAX; ++cur) {
|
||||
if (flags & BIT(cur) && nla_put_flag(msg, cur))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
int net_shaper_nl_cap_get_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct net_shaper_binding *binding;
|
||||
const struct net_shaper_ops *ops;
|
||||
enum net_shaper_scope scope;
|
||||
unsigned long flags = 0;
|
||||
struct sk_buff *msg;
|
||||
int ret;
|
||||
|
||||
if (GENL_REQ_ATTR_CHECK(info, NET_SHAPER_A_CAPS_SCOPE))
|
||||
return -EINVAL;
|
||||
|
||||
binding = net_shaper_binding_from_ctx(info->ctx);
|
||||
scope = nla_get_u32(info->attrs[NET_SHAPER_A_CAPS_SCOPE]);
|
||||
ops = net_shaper_ops(binding);
|
||||
ops->capabilities(binding, scope, &flags);
|
||||
if (!flags)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
msg = genlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = net_shaper_cap_fill_one(msg, binding, scope, flags, info);
|
||||
if (ret)
|
||||
goto free_msg;
|
||||
|
||||
ret = genlmsg_reply(msg, info);
|
||||
if (ret)
|
||||
goto free_msg;
|
||||
return 0;
|
||||
|
||||
free_msg:
|
||||
nlmsg_free(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int net_shaper_nl_cap_get_dumpit(struct sk_buff *skb,
|
||||
struct netlink_callback *cb)
|
||||
{
|
||||
const struct genl_info *info = genl_info_dump(cb);
|
||||
struct net_shaper_binding *binding;
|
||||
const struct net_shaper_ops *ops;
|
||||
enum net_shaper_scope scope;
|
||||
int ret;
|
||||
|
||||
binding = net_shaper_binding_from_ctx(cb->ctx);
|
||||
ops = net_shaper_ops(binding);
|
||||
for (scope = 0; scope <= NET_SHAPER_SCOPE_MAX; ++scope) {
|
||||
unsigned long flags = 0;
|
||||
|
||||
ops->capabilities(binding, scope, &flags);
|
||||
if (!flags)
|
||||
continue;
|
||||
|
||||
ret = net_shaper_cap_fill_one(skb, binding, scope, flags,
|
||||
info);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user