netdev-genl: spec: Extend netdev netlink spec in YAML for NAPI

Add support in netlink spec(netdev.yaml) for napi related information.
Add code generated from the spec.

Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
Link: https://lore.kernel.org/r/170147333119.5260.7050639053080529108.stgit@anambiarhost.jf.intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Amritha Nambiar 2023-12-01 15:28:51 -08:00 committed by Jakub Kicinski
parent 6b6171db7f
commit ff9991499f
8 changed files with 283 additions and 0 deletions

View file

@ -213,6 +213,19 @@ attribute-sets:
name: recycle-released-refcnt
type: uint
-
name: napi
attributes:
-
name: ifindex
doc: ifindex of the netdevice to which NAPI instance belongs.
type: u32
checks:
min: 1
-
name: id
doc: ID of the NAPI instance.
type: u32
-
name: queue
attributes:
@ -359,6 +372,23 @@ operations:
attributes:
- ifindex
reply: *queue-get-op
-
name: napi-get
doc: Get information about NAPI instances configured on the system.
attribute-set: napi
do:
request:
attributes:
- id
reply: &napi-get-op
attributes:
- id
- ifindex
dump:
request:
attributes:
- ifindex
reply: *napi-get-op
mcast-groups:
list:

View file

@ -109,6 +109,14 @@ enum {
NETDEV_A_PAGE_POOL_STATS_MAX = (__NETDEV_A_PAGE_POOL_STATS_MAX - 1)
};
enum {
NETDEV_A_NAPI_IFINDEX = 1,
NETDEV_A_NAPI_ID,
__NETDEV_A_NAPI_MAX,
NETDEV_A_NAPI_MAX = (__NETDEV_A_NAPI_MAX - 1)
};
enum {
NETDEV_A_QUEUE_ID = 1,
NETDEV_A_QUEUE_IFINDEX,
@ -130,6 +138,7 @@ enum {
NETDEV_CMD_PAGE_POOL_CHANGE_NTF,
NETDEV_CMD_PAGE_POOL_STATS_GET,
NETDEV_CMD_QUEUE_GET,
NETDEV_CMD_NAPI_GET,
__NETDEV_CMD_MAX,
NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)

View file

@ -58,6 +58,16 @@ static const struct nla_policy netdev_queue_get_dump_nl_policy[NETDEV_A_QUEUE_IF
[NETDEV_A_QUEUE_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1),
};
/* NETDEV_CMD_NAPI_GET - do */
static const struct nla_policy netdev_napi_get_do_nl_policy[NETDEV_A_NAPI_ID + 1] = {
[NETDEV_A_NAPI_ID] = { .type = NLA_U32, },
};
/* NETDEV_CMD_NAPI_GET - dump */
static const struct nla_policy netdev_napi_get_dump_nl_policy[NETDEV_A_NAPI_IFINDEX + 1] = {
[NETDEV_A_NAPI_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1),
};
/* Ops table for netdev */
static const struct genl_split_ops netdev_nl_ops[] = {
{
@ -114,6 +124,20 @@ static const struct genl_split_ops netdev_nl_ops[] = {
.maxattr = NETDEV_A_QUEUE_IFINDEX,
.flags = GENL_CMD_CAP_DUMP,
},
{
.cmd = NETDEV_CMD_NAPI_GET,
.doit = netdev_nl_napi_get_doit,
.policy = netdev_napi_get_do_nl_policy,
.maxattr = NETDEV_A_NAPI_ID,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = NETDEV_CMD_NAPI_GET,
.dumpit = netdev_nl_napi_get_dumpit,
.policy = netdev_napi_get_dump_nl_policy,
.maxattr = NETDEV_A_NAPI_IFINDEX,
.flags = GENL_CMD_CAP_DUMP,
},
};
static const struct genl_multicast_group netdev_nl_mcgrps[] = {

View file

@ -26,6 +26,8 @@ int netdev_nl_page_pool_stats_get_dumpit(struct sk_buff *skb,
int netdev_nl_queue_get_doit(struct sk_buff *skb, struct genl_info *info);
int netdev_nl_queue_get_dumpit(struct sk_buff *skb,
struct netlink_callback *cb);
int netdev_nl_napi_get_doit(struct sk_buff *skb, struct genl_info *info);
int netdev_nl_napi_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
enum {
NETDEV_NLGRP_MGMT,

View file

@ -155,6 +155,16 @@ int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}
int netdev_nl_napi_get_doit(struct sk_buff *skb, struct genl_info *info)
{
return -EOPNOTSUPP;
}
int netdev_nl_napi_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
{
return -EOPNOTSUPP;
}
static int
netdev_nl_queue_fill_one(struct sk_buff *rsp, struct net_device *netdev,
u32 q_idx, u32 q_type, const struct genl_info *info)

View file

@ -109,6 +109,14 @@ enum {
NETDEV_A_PAGE_POOL_STATS_MAX = (__NETDEV_A_PAGE_POOL_STATS_MAX - 1)
};
enum {
NETDEV_A_NAPI_IFINDEX = 1,
NETDEV_A_NAPI_ID,
__NETDEV_A_NAPI_MAX,
NETDEV_A_NAPI_MAX = (__NETDEV_A_NAPI_MAX - 1)
};
enum {
NETDEV_A_QUEUE_ID = 1,
NETDEV_A_QUEUE_IFINDEX,
@ -130,6 +138,7 @@ enum {
NETDEV_CMD_PAGE_POOL_CHANGE_NTF,
NETDEV_CMD_PAGE_POOL_STATS_GET,
NETDEV_CMD_QUEUE_GET,
NETDEV_CMD_NAPI_GET,
__NETDEV_CMD_MAX,
NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)

View file

@ -24,6 +24,7 @@ static const char * const netdev_op_strmap[] = {
[NETDEV_CMD_PAGE_POOL_CHANGE_NTF] = "page-pool-change-ntf",
[NETDEV_CMD_PAGE_POOL_STATS_GET] = "page-pool-stats-get",
[NETDEV_CMD_QUEUE_GET] = "queue-get",
[NETDEV_CMD_NAPI_GET] = "napi-get",
};
const char *netdev_op_str(int op)
@ -160,6 +161,16 @@ struct ynl_policy_nest netdev_queue_nest = {
.table = netdev_queue_policy,
};
struct ynl_policy_attr netdev_napi_policy[NETDEV_A_NAPI_MAX + 1] = {
[NETDEV_A_NAPI_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, },
[NETDEV_A_NAPI_ID] = { .name = "id", .type = YNL_PT_U32, },
};
struct ynl_policy_nest netdev_napi_nest = {
.max_attr = NETDEV_A_NAPI_MAX,
.table = netdev_napi_policy,
};
/* Common nested types */
void netdev_page_pool_info_free(struct netdev_page_pool_info *obj)
{
@ -770,6 +781,119 @@ netdev_queue_get_dump(struct ynl_sock *ys,
return NULL;
}
/* ============== NETDEV_CMD_NAPI_GET ============== */
/* NETDEV_CMD_NAPI_GET - do */
void netdev_napi_get_req_free(struct netdev_napi_get_req *req)
{
free(req);
}
void netdev_napi_get_rsp_free(struct netdev_napi_get_rsp *rsp)
{
free(rsp);
}
int netdev_napi_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
{
struct ynl_parse_arg *yarg = data;
struct netdev_napi_get_rsp *dst;
const struct nlattr *attr;
dst = yarg->data;
mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
unsigned int type = mnl_attr_get_type(attr);
if (type == NETDEV_A_NAPI_ID) {
if (ynl_attr_validate(yarg, attr))
return MNL_CB_ERROR;
dst->_present.id = 1;
dst->id = mnl_attr_get_u32(attr);
} else if (type == NETDEV_A_NAPI_IFINDEX) {
if (ynl_attr_validate(yarg, attr))
return MNL_CB_ERROR;
dst->_present.ifindex = 1;
dst->ifindex = mnl_attr_get_u32(attr);
}
}
return MNL_CB_OK;
}
struct netdev_napi_get_rsp *
netdev_napi_get(struct ynl_sock *ys, struct netdev_napi_get_req *req)
{
struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
struct netdev_napi_get_rsp *rsp;
struct nlmsghdr *nlh;
int err;
nlh = ynl_gemsg_start_req(ys, ys->family_id, NETDEV_CMD_NAPI_GET, 1);
ys->req_policy = &netdev_napi_nest;
yrs.yarg.rsp_policy = &netdev_napi_nest;
if (req->_present.id)
mnl_attr_put_u32(nlh, NETDEV_A_NAPI_ID, req->id);
rsp = calloc(1, sizeof(*rsp));
yrs.yarg.data = rsp;
yrs.cb = netdev_napi_get_rsp_parse;
yrs.rsp_cmd = NETDEV_CMD_NAPI_GET;
err = ynl_exec(ys, nlh, &yrs);
if (err < 0)
goto err_free;
return rsp;
err_free:
netdev_napi_get_rsp_free(rsp);
return NULL;
}
/* NETDEV_CMD_NAPI_GET - dump */
void netdev_napi_get_list_free(struct netdev_napi_get_list *rsp)
{
struct netdev_napi_get_list *next = rsp;
while ((void *)next != YNL_LIST_END) {
rsp = next;
next = rsp->next;
free(rsp);
}
}
struct netdev_napi_get_list *
netdev_napi_get_dump(struct ynl_sock *ys, struct netdev_napi_get_req_dump *req)
{
struct ynl_dump_state yds = {};
struct nlmsghdr *nlh;
int err;
yds.ys = ys;
yds.alloc_sz = sizeof(struct netdev_napi_get_list);
yds.cb = netdev_napi_get_rsp_parse;
yds.rsp_cmd = NETDEV_CMD_NAPI_GET;
yds.rsp_policy = &netdev_napi_nest;
nlh = ynl_gemsg_start_dump(ys, ys->family_id, NETDEV_CMD_NAPI_GET, 1);
ys->req_policy = &netdev_napi_nest;
if (req->_present.ifindex)
mnl_attr_put_u32(nlh, NETDEV_A_NAPI_IFINDEX, req->ifindex);
err = ynl_exec_dump(ys, nlh, &yds);
if (err < 0)
goto free_list;
return yds.first;
free_list:
netdev_napi_get_list_free(yds.first);
return NULL;
}
static const struct ynl_ntf_info netdev_ntf_info[] = {
[NETDEV_CMD_DEV_ADD_NTF] = {
.alloc_sz = sizeof(struct netdev_dev_get_ntf),

View file

@ -360,4 +360,79 @@ struct netdev_queue_get_list *
netdev_queue_get_dump(struct ynl_sock *ys,
struct netdev_queue_get_req_dump *req);
/* ============== NETDEV_CMD_NAPI_GET ============== */
/* NETDEV_CMD_NAPI_GET - do */
struct netdev_napi_get_req {
struct {
__u32 id:1;
} _present;
__u32 id;
};
static inline struct netdev_napi_get_req *netdev_napi_get_req_alloc(void)
{
return calloc(1, sizeof(struct netdev_napi_get_req));
}
void netdev_napi_get_req_free(struct netdev_napi_get_req *req);
static inline void
netdev_napi_get_req_set_id(struct netdev_napi_get_req *req, __u32 id)
{
req->_present.id = 1;
req->id = id;
}
struct netdev_napi_get_rsp {
struct {
__u32 id:1;
__u32 ifindex:1;
} _present;
__u32 id;
__u32 ifindex;
};
void netdev_napi_get_rsp_free(struct netdev_napi_get_rsp *rsp);
/*
* Get information about NAPI instances configured on the system.
*/
struct netdev_napi_get_rsp *
netdev_napi_get(struct ynl_sock *ys, struct netdev_napi_get_req *req);
/* NETDEV_CMD_NAPI_GET - dump */
struct netdev_napi_get_req_dump {
struct {
__u32 ifindex:1;
} _present;
__u32 ifindex;
};
static inline struct netdev_napi_get_req_dump *
netdev_napi_get_req_dump_alloc(void)
{
return calloc(1, sizeof(struct netdev_napi_get_req_dump));
}
void netdev_napi_get_req_dump_free(struct netdev_napi_get_req_dump *req);
static inline void
netdev_napi_get_req_dump_set_ifindex(struct netdev_napi_get_req_dump *req,
__u32 ifindex)
{
req->_present.ifindex = 1;
req->ifindex = ifindex;
}
struct netdev_napi_get_list {
struct netdev_napi_get_list *next;
struct netdev_napi_get_rsp obj __attribute__((aligned(8)));
};
void netdev_napi_get_list_free(struct netdev_napi_get_list *rsp);
struct netdev_napi_get_list *
netdev_napi_get_dump(struct ynl_sock *ys, struct netdev_napi_get_req_dump *req);
#endif /* _LINUX_NETDEV_GEN_H */