Skip to content

Commit

Permalink
Merge branch 'devlink-use-spec-to-generate-split-ops'
Browse files Browse the repository at this point in the history
Jiri Pirko says:

====================
devlink: use spec to generate split ops

This is an outcome of the discussion in the following thread:
https://lore.kernel.org/netdev/20230720121829.566974-1-jiri@resnulli.us/
It serves as a dependency on the linked selector patchset.

There is an existing spec for devlink used for userspace part
generation. There are two commands supported there.

This patchset extends the spec so kernel split ops code could
be generated from it.
====================

Link: https://lore.kernel.org/r/20230803111340.1074067-1-jiri@resnulli.us
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Aug 4, 2023
2 parents 86b7e03 + 6e067d0 commit eef9630
Show file tree
Hide file tree
Showing 14 changed files with 230 additions and 60 deletions.
2 changes: 1 addition & 1 deletion Documentation/netlink/genetlink-c.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ properties:
description: Kernel attribute validation flags.
type: array
items:
enum: [ strict, dump ]
enum: [ strict, dump, dump-strict ]
do: &subop-type
description: Main command handler.
type: object
Expand Down
2 changes: 1 addition & 1 deletion Documentation/netlink/genetlink-legacy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ properties:
description: Kernel attribute validation flags.
type: array
items:
enum: [ strict, dump ]
enum: [ strict, dump, dump-strict ]
# Start genetlink-legacy
fixed-header: *fixed-header
# End genetlink-legacy
Expand Down
2 changes: 1 addition & 1 deletion Documentation/netlink/genetlink.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ properties:
description: Kernel attribute validation flags.
type: array
items:
enum: [ strict, dump ]
enum: [ strict, dump, dump-strict ]
do: &subop-type
description: Main command handler.
type: object
Expand Down
14 changes: 13 additions & 1 deletion Documentation/netlink/specs/devlink.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,13 @@ operations:
name: get
doc: Get devlink instances.
attribute-set: devlink
dont-validate:
- strict
- dump

do:
pre: devlink-nl-pre-doit
post: devlink-nl-post-doit
request:
value: 1
attributes: &dev-id-attrs
Expand All @@ -189,12 +194,17 @@ operations:
name: info-get
doc: Get device information, like driver name, hardware and firmware versions etc.
attribute-set: devlink
dont-validate:
- strict
- dump

do:
pre: devlink-nl-pre-doit
post: devlink-nl-post-doit
request:
value: 51
attributes: *dev-id-attrs
reply:
reply: &info-get-reply
value: 51
attributes:
- bus-name
Expand All @@ -204,3 +214,5 @@ operations:
- info-version-fixed
- info-version-running
- info-version-stored
dump:
reply: *info-get-reply
2 changes: 1 addition & 1 deletion net/devlink/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0

obj-y := leftover.o core.o netlink.o dev.o health.o
obj-y := leftover.o core.o netlink.o netlink_gen.o dev.o health.o
26 changes: 14 additions & 12 deletions net/devlink/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
}

int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
int devlink_nl_get_doit(struct sk_buff *skb, struct genl_info *info)
{
struct devlink *devlink = info->user_ptr[0];
struct sk_buff *msg;
Expand All @@ -217,17 +217,18 @@ int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
}

static int
devlink_nl_cmd_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
struct netlink_callback *cb)
devlink_nl_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
struct netlink_callback *cb)
{
return devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, NLM_F_MULTI);
}

const struct devlink_cmd devl_cmd_get = {
.dump_one = devlink_nl_cmd_get_dump_one,
};
int devlink_nl_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb)
{
return devlink_nl_dumpit(msg, cb, devlink_nl_get_dump_one);
}

static void devlink_reload_failed_set(struct devlink *devlink,
bool reload_failed)
Expand Down Expand Up @@ -804,7 +805,7 @@ devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
return err;
}

int devlink_nl_cmd_info_get_doit(struct sk_buff *skb, struct genl_info *info)
int devlink_nl_info_get_doit(struct sk_buff *skb, struct genl_info *info)
{
struct devlink *devlink = info->user_ptr[0];
struct sk_buff *msg;
Expand All @@ -826,8 +827,8 @@ int devlink_nl_cmd_info_get_doit(struct sk_buff *skb, struct genl_info *info)
}

static int
devlink_nl_cmd_info_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
struct netlink_callback *cb)
devlink_nl_info_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
struct netlink_callback *cb)
{
int err;

Expand All @@ -840,9 +841,10 @@ devlink_nl_cmd_info_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
return err;
}

const struct devlink_cmd devl_cmd_info_get = {
.dump_one = devlink_nl_cmd_info_get_dump_one,
};
int devlink_nl_info_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb)
{
return devlink_nl_dumpit(msg, cb, devlink_nl_info_get_dump_one);
}

static int devlink_nl_flash_update_fill(struct sk_buff *msg,
struct devlink *devlink,
Expand Down
20 changes: 11 additions & 9 deletions net/devlink/devl_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <net/devlink.h>
#include <net/net_namespace.h>

#include "netlink_gen.h"

#define DEVLINK_REGISTERED XA_MARK_1

#define DEVLINK_RELOAD_STATS_ARRAY_SIZE \
Expand Down Expand Up @@ -114,21 +116,25 @@ struct devlink_nl_dump_state {
};
};

typedef int devlink_nl_dump_one_func_t(struct sk_buff *msg,
struct devlink *devlink,
struct netlink_callback *cb);

struct devlink_cmd {
int (*dump_one)(struct sk_buff *msg, struct devlink *devlink,
struct netlink_callback *cb);
devlink_nl_dump_one_func_t *dump_one;
};

extern const struct genl_small_ops devlink_nl_ops[56];
extern const struct genl_small_ops devlink_nl_small_ops[54];

struct devlink *
devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs);

void devlink_notify_unregister(struct devlink *devlink);
void devlink_notify_register(struct devlink *devlink);

int devlink_nl_instance_iter_dumpit(struct sk_buff *msg,
struct netlink_callback *cb);
int devlink_nl_dumpit(struct sk_buff *msg, struct netlink_callback *cb,
devlink_nl_dump_one_func_t *dump_one);
int devlink_nl_instance_iter_dumpit(struct sk_buff *msg, struct netlink_callback *cb);

static inline struct devlink_nl_dump_state *
devlink_dump_state(struct netlink_callback *cb)
Expand All @@ -149,15 +155,13 @@ devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
}

/* Commands */
extern const struct devlink_cmd devl_cmd_get;
extern const struct devlink_cmd devl_cmd_port_get;
extern const struct devlink_cmd devl_cmd_sb_get;
extern const struct devlink_cmd devl_cmd_sb_pool_get;
extern const struct devlink_cmd devl_cmd_sb_port_pool_get;
extern const struct devlink_cmd devl_cmd_sb_tc_pool_bind_get;
extern const struct devlink_cmd devl_cmd_param_get;
extern const struct devlink_cmd devl_cmd_region_get;
extern const struct devlink_cmd devl_cmd_info_get;
extern const struct devlink_cmd devl_cmd_health_reporter_get;
extern const struct devlink_cmd devl_cmd_trap_get;
extern const struct devlink_cmd devl_cmd_trap_group_get;
Expand Down Expand Up @@ -214,11 +218,9 @@ struct devlink_rate *
devlink_rate_node_get_from_info(struct devlink *devlink,
struct genl_info *info);
/* Devlink nl cmds */
int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info);
int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info);
int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb, struct genl_info *info);
int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb, struct genl_info *info);
int devlink_nl_cmd_info_get_doit(struct sk_buff *skb, struct genl_info *info);
int devlink_nl_cmd_flash_update(struct sk_buff *skb, struct genl_info *info);
int devlink_nl_cmd_selftests_get_doit(struct sk_buff *skb, struct genl_info *info);
int devlink_nl_cmd_selftests_run(struct sk_buff *skb, struct genl_info *info);
Expand Down
16 changes: 1 addition & 15 deletions net/devlink/leftover.c
Original file line number Diff line number Diff line change
Expand Up @@ -6278,14 +6278,7 @@ static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb,
return devlink_trap_policer_set(devlink, policer_item, info);
}

const struct genl_small_ops devlink_nl_ops[56] = {
{
.cmd = DEVLINK_CMD_GET,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_get_doit,
.dumpit = devlink_nl_instance_iter_dumpit,
/* can be retrieved by unprivileged users */
},
const struct genl_small_ops devlink_nl_small_ops[54] = {
{
.cmd = DEVLINK_CMD_PORT_GET,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Expand Down Expand Up @@ -6533,13 +6526,6 @@ const struct genl_small_ops devlink_nl_ops[56] = {
.dumpit = devlink_nl_cmd_region_read_dumpit,
.flags = GENL_ADMIN_PERM,
},
{
.cmd = DEVLINK_CMD_INFO_GET,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_info_get_doit,
.dumpit = devlink_nl_instance_iter_dumpit,
/* can be retrieved by unprivileged users */
},
{
.cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Expand Down
35 changes: 20 additions & 15 deletions net/devlink/netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs)
return ERR_PTR(-ENODEV);
}

static int devlink_nl_pre_doit(const struct genl_split_ops *ops,
struct sk_buff *skb, struct genl_info *info)
int devlink_nl_pre_doit(const struct genl_split_ops *ops,
struct sk_buff *skb, struct genl_info *info)
{
struct devlink_linecard *linecard;
struct devlink_port *devlink_port;
Expand Down Expand Up @@ -167,8 +167,8 @@ static int devlink_nl_pre_doit(const struct genl_split_ops *ops,
return err;
}

static void devlink_nl_post_doit(const struct genl_split_ops *ops,
struct sk_buff *skb, struct genl_info *info)
void devlink_nl_post_doit(const struct genl_split_ops *ops,
struct sk_buff *skb, struct genl_info *info)
{
struct devlink *devlink;

Expand All @@ -178,15 +178,13 @@ static void devlink_nl_post_doit(const struct genl_split_ops *ops,
}

static const struct devlink_cmd *devl_cmds[] = {
[DEVLINK_CMD_GET] = &devl_cmd_get,
[DEVLINK_CMD_PORT_GET] = &devl_cmd_port_get,
[DEVLINK_CMD_SB_GET] = &devl_cmd_sb_get,
[DEVLINK_CMD_SB_POOL_GET] = &devl_cmd_sb_pool_get,
[DEVLINK_CMD_SB_PORT_POOL_GET] = &devl_cmd_sb_port_pool_get,
[DEVLINK_CMD_SB_TC_POOL_BIND_GET] = &devl_cmd_sb_tc_pool_bind_get,
[DEVLINK_CMD_PARAM_GET] = &devl_cmd_param_get,
[DEVLINK_CMD_REGION_GET] = &devl_cmd_region_get,
[DEVLINK_CMD_INFO_GET] = &devl_cmd_info_get,
[DEVLINK_CMD_HEALTH_REPORTER_GET] = &devl_cmd_health_reporter_get,
[DEVLINK_CMD_TRAP_GET] = &devl_cmd_trap_get,
[DEVLINK_CMD_TRAP_GROUP_GET] = &devl_cmd_trap_group_get,
Expand All @@ -196,23 +194,19 @@ static const struct devlink_cmd *devl_cmds[] = {
[DEVLINK_CMD_SELFTESTS_GET] = &devl_cmd_selftests_get,
};

int devlink_nl_instance_iter_dumpit(struct sk_buff *msg,
struct netlink_callback *cb)
int devlink_nl_dumpit(struct sk_buff *msg, struct netlink_callback *cb,
devlink_nl_dump_one_func_t *dump_one)
{
const struct genl_dumpit_info *info = genl_dumpit_info(cb);
struct devlink_nl_dump_state *state = devlink_dump_state(cb);
const struct devlink_cmd *cmd;
struct devlink *devlink;
int err = 0;

cmd = devl_cmds[info->op.cmd];

while ((devlink = devlinks_xa_find_get(sock_net(msg->sk),
&state->instance))) {
devl_lock(devlink);

if (devl_is_registered(devlink))
err = cmd->dump_one(msg, devlink, cb);
err = dump_one(msg, devlink, cb);
else
err = 0;

Expand All @@ -233,6 +227,15 @@ int devlink_nl_instance_iter_dumpit(struct sk_buff *msg,
return msg->len;
}

int devlink_nl_instance_iter_dumpit(struct sk_buff *msg,
struct netlink_callback *cb)
{
const struct genl_dumpit_info *info = genl_dumpit_info(cb);
const struct devlink_cmd *cmd = devl_cmds[info->op.cmd];

return devlink_nl_dumpit(msg, cb, cmd->dump_one);
}

struct genl_family devlink_nl_family __ro_after_init = {
.name = DEVLINK_GENL_NAME,
.version = DEVLINK_GENL_VERSION,
Expand All @@ -243,8 +246,10 @@ struct genl_family devlink_nl_family __ro_after_init = {
.pre_doit = devlink_nl_pre_doit,
.post_doit = devlink_nl_post_doit,
.module = THIS_MODULE,
.small_ops = devlink_nl_ops,
.n_small_ops = ARRAY_SIZE(devlink_nl_ops),
.small_ops = devlink_nl_small_ops,
.n_small_ops = ARRAY_SIZE(devlink_nl_small_ops),
.split_ops = devlink_nl_ops,
.n_split_ops = ARRAY_SIZE(devlink_nl_ops),
.resv_start_op = DEVLINK_CMD_SELFTESTS_RUN + 1,
.mcgrps = devlink_nl_mcgrps,
.n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps),
Expand Down
59 changes: 59 additions & 0 deletions net/devlink/netlink_gen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
/* Do not edit directly, auto-generated from: */
/* Documentation/netlink/specs/devlink.yaml */
/* YNL-GEN kernel source */

#include <net/netlink.h>
#include <net/genetlink.h>

#include "netlink_gen.h"

#include <uapi/linux/devlink.h>

/* DEVLINK_CMD_GET - do */
static const struct nla_policy devlink_get_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
};

/* DEVLINK_CMD_INFO_GET - do */
static const struct nla_policy devlink_info_get_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
};

/* Ops table for devlink */
const struct genl_split_ops devlink_nl_ops[4] = {
{
.cmd = DEVLINK_CMD_GET,
.validate = GENL_DONT_VALIDATE_STRICT,
.pre_doit = devlink_nl_pre_doit,
.doit = devlink_nl_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_get_nl_policy,
.maxattr = DEVLINK_ATTR_DEV_NAME,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = DEVLINK_CMD_GET,
.validate = GENL_DONT_VALIDATE_DUMP,
.dumpit = devlink_nl_get_dumpit,
.flags = GENL_CMD_CAP_DUMP,
},
{
.cmd = DEVLINK_CMD_INFO_GET,
.validate = GENL_DONT_VALIDATE_STRICT,
.pre_doit = devlink_nl_pre_doit,
.doit = devlink_nl_info_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_info_get_nl_policy,
.maxattr = DEVLINK_ATTR_DEV_NAME,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = DEVLINK_CMD_INFO_GET,
.validate = GENL_DONT_VALIDATE_DUMP,
.dumpit = devlink_nl_info_get_dumpit,
.flags = GENL_CMD_CAP_DUMP,
},
};
Loading

0 comments on commit eef9630

Please sign in to comment.