mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-16 02:14:58 +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,
|
int net_shaper_nl_cap_pre_doit(const struct genl_split_ops *ops,
|
||||||
struct sk_buff *skb, struct genl_info *info)
|
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,
|
void net_shaper_nl_cap_post_doit(const struct genl_split_ops *ops,
|
||||||
struct sk_buff *skb, struct genl_info *info)
|
struct sk_buff *skb, struct genl_info *info)
|
||||||
{
|
{
|
||||||
|
net_shaper_generic_post(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_shaper_nl_cap_pre_dumpit(struct netlink_callback *cb)
|
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)
|
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)
|
int net_shaper_nl_get_doit(struct sk_buff *skb, struct genl_info *info)
|
||||||
@ -1147,14 +1154,99 @@ free_msg:
|
|||||||
goto free_leaves;
|
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)
|
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;
|
return 0;
|
||||||
|
|
||||||
|
free_msg:
|
||||||
|
nlmsg_free(msg);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_shaper_nl_cap_get_dumpit(struct sk_buff *skb,
|
int net_shaper_nl_cap_get_dumpit(struct sk_buff *skb,
|
||||||
struct netlink_callback *cb)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user