diff --git a/Documentation/netlink/specs/team.yaml b/Documentation/netlink/specs/team.yaml new file mode 100644 index 000000000000..c13529e011c9 --- /dev/null +++ b/Documentation/netlink/specs/team.yaml @@ -0,0 +1,204 @@ +# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) + +name: team + +protocol: genetlink-legacy + +doc: | + Network team device driver. + +c-family-name: team-genl-name +c-version-name: team-genl-version +kernel-policy: global +uapi-header: linux/if_team.h + +definitions: + - + name: string-max-len + type: const + value: 32 + - + name: genl-change-event-mc-grp-name + type: const + value: change_event + +attribute-sets: + - + name: team + doc: + The team nested layout of get/set msg looks like + [TEAM_ATTR_LIST_OPTION] + [TEAM_ATTR_ITEM_OPTION] + [TEAM_ATTR_OPTION_*], ... + [TEAM_ATTR_ITEM_OPTION] + [TEAM_ATTR_OPTION_*], ... + ... + [TEAM_ATTR_LIST_PORT] + [TEAM_ATTR_ITEM_PORT] + [TEAM_ATTR_PORT_*], ... + [TEAM_ATTR_ITEM_PORT] + [TEAM_ATTR_PORT_*], ... + ... + name-prefix: team-attr- + attributes: + - + name: unspec + type: unused + value: 0 + - + name: team-ifindex + type: u32 + - + name: list-option + type: nest + nested-attributes: item-option + - + name: list-port + type: nest + nested-attributes: item-port + - + name: item-option + name-prefix: team-attr-item- + attr-cnt-name: __team-attr-item-option-max + attr-max-name: team-attr-item-option-max + attributes: + - + name: option-unspec + type: unused + value: 0 + - + name: option + type: nest + nested-attributes: attr-option + - + name: attr-option + name-prefix: team-attr-option- + attributes: + - + name: unspec + type: unused + value: 0 + - + name: name + type: string + checks: + max-len: string-max-len + unterminated-ok: true + - + name: changed + type: flag + - + name: type + type: u8 + - + name: data + type: binary + - + name: removed + type: flag + - + name: port-ifindex + type: u32 + doc: for per-port options + - + name: array-index + type: u32 + doc: for array options + - + name: item-port + name-prefix: team-attr-item- + attr-cnt-name: __team-attr-item-port-max + attr-max-name: team-attr-item-port-max + attributes: + - + name: port-unspec + type: unused + value: 0 + - + name: port + type: nest + nested-attributes: attr-port + - + name: attr-port + name-prefix: team-attr-port- + attributes: + - + name: unspec + type: unused + value: 0 + - + name: ifindex + type: u32 + - + name: changed + type: flag + - + name: linkup + type: flag + - + name: speed + type: u32 + - + name: duplex + type: u8 + - + name: removed + type: flag + +operations: + list: + - + name: noop + doc: No operation + value: 0 + attribute-set: team + dont-validate: [ strict ] + + do: + # Actually it only reply the team netlink family + reply: + attributes: + - team-ifindex + + - + name: options-set + doc: Set team options + attribute-set: team + dont-validate: [ strict ] + flags: [ admin-perm ] + + do: + request: &option_attrs + attributes: + - team-ifindex + - list-option + reply: *option_attrs + + - + name: options-get + doc: Get team options info + attribute-set: team + dont-validate: [ strict ] + flags: [ admin-perm ] + + do: + request: + attributes: + - team-ifindex + reply: *option_attrs + + - + name: port-list-get + doc: Get team ports info + attribute-set: team + dont-validate: [ strict ] + flags: [ admin-perm ] + + do: + request: + attributes: + - team-ifindex + reply: &port_attrs + attributes: + - team-ifindex + - list-port diff --git a/MAINTAINERS b/MAINTAINERS index 6a233e1a3cf2..909c2c531d8e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -21665,6 +21665,7 @@ TEAM DRIVER M: Jiri Pirko L: netdev@vger.kernel.org S: Supported +F: Documentation/netlink/specs/team.yaml F: drivers/net/team/ F: include/linux/if_team.h F: include/uapi/linux/if_team.h diff --git a/drivers/net/team/Makefile b/drivers/net/team/Makefile index f582d81a5091..7a5aa20d286b 100644 --- a/drivers/net/team/Makefile +++ b/drivers/net/team/Makefile @@ -3,6 +3,7 @@ # Makefile for the network team driver # +team-y:= team_core.o team_nl.o obj-$(CONFIG_NET_TEAM) += team.o obj-$(CONFIG_NET_TEAM_MODE_BROADCAST) += team_mode_broadcast.o obj-$(CONFIG_NET_TEAM_MODE_ROUNDROBIN) += team_mode_roundrobin.o diff --git a/drivers/net/team/team.c b/drivers/net/team/team_core.c similarity index 97% rename from drivers/net/team/team.c rename to drivers/net/team/team_core.c index 0a44bbdcfb7b..4e3c8d404957 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team_core.c @@ -27,6 +27,8 @@ #include #include +#include "team_nl.h" + #define DRV_NAME "team" @@ -2254,28 +2256,7 @@ static struct rtnl_link_ops team_link_ops __read_mostly = { static struct genl_family team_nl_family; -static const struct nla_policy team_nl_policy[TEAM_ATTR_MAX + 1] = { - [TEAM_ATTR_UNSPEC] = { .type = NLA_UNSPEC, }, - [TEAM_ATTR_TEAM_IFINDEX] = { .type = NLA_U32 }, - [TEAM_ATTR_LIST_OPTION] = { .type = NLA_NESTED }, - [TEAM_ATTR_LIST_PORT] = { .type = NLA_NESTED }, -}; - -static const struct nla_policy -team_nl_option_policy[TEAM_ATTR_OPTION_MAX + 1] = { - [TEAM_ATTR_OPTION_UNSPEC] = { .type = NLA_UNSPEC, }, - [TEAM_ATTR_OPTION_NAME] = { - .type = NLA_STRING, - .len = TEAM_STRING_MAX_LEN, - }, - [TEAM_ATTR_OPTION_CHANGED] = { .type = NLA_FLAG }, - [TEAM_ATTR_OPTION_TYPE] = { .type = NLA_U8 }, - [TEAM_ATTR_OPTION_DATA] = { .type = NLA_BINARY }, - [TEAM_ATTR_OPTION_PORT_IFINDEX] = { .type = NLA_U32 }, - [TEAM_ATTR_OPTION_ARRAY_INDEX] = { .type = NLA_U32 }, -}; - -static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info) +int team_nl_noop_doit(struct sk_buff *skb, struct genl_info *info) { struct sk_buff *msg; void *hdr; @@ -2513,7 +2494,7 @@ errout: return err; } -static int team_nl_cmd_options_get(struct sk_buff *skb, struct genl_info *info) +int team_nl_options_get_doit(struct sk_buff *skb, struct genl_info *info) { struct team *team; struct team_option_inst *opt_inst; @@ -2538,7 +2519,7 @@ static int team_nl_cmd_options_get(struct sk_buff *skb, struct genl_info *info) static int team_nl_send_event_options_get(struct team *team, struct list_head *sel_opt_inst_list); -static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) +int team_nl_options_set_doit(struct sk_buff *skb, struct genl_info *info) { struct team *team; int err = 0; @@ -2579,7 +2560,7 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) err = nla_parse_nested_deprecated(opt_attrs, TEAM_ATTR_OPTION_MAX, nl_option, - team_nl_option_policy, + team_attr_option_nl_policy, info->extack); if (err) goto team_put; @@ -2802,8 +2783,8 @@ errout: return err; } -static int team_nl_cmd_port_list_get(struct sk_buff *skb, - struct genl_info *info) +int team_nl_port_list_get_doit(struct sk_buff *skb, + struct genl_info *info) { struct team *team; int err; @@ -2820,32 +2801,6 @@ static int team_nl_cmd_port_list_get(struct sk_buff *skb, return err; } -static const struct genl_small_ops team_nl_ops[] = { - { - .cmd = TEAM_CMD_NOOP, - .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, - .doit = team_nl_cmd_noop, - }, - { - .cmd = TEAM_CMD_OPTIONS_SET, - .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, - .doit = team_nl_cmd_options_set, - .flags = GENL_ADMIN_PERM, - }, - { - .cmd = TEAM_CMD_OPTIONS_GET, - .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, - .doit = team_nl_cmd_options_get, - .flags = GENL_ADMIN_PERM, - }, - { - .cmd = TEAM_CMD_PORT_LIST_GET, - .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, - .doit = team_nl_cmd_port_list_get, - .flags = GENL_ADMIN_PERM, - }, -}; - static const struct genl_multicast_group team_nl_mcgrps[] = { { .name = TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME, }, }; @@ -2853,7 +2808,7 @@ static const struct genl_multicast_group team_nl_mcgrps[] = { static struct genl_family team_nl_family __ro_after_init = { .name = TEAM_GENL_NAME, .version = TEAM_GENL_VERSION, - .maxattr = TEAM_ATTR_MAX, + .maxattr = ARRAY_SIZE(team_nl_policy), .policy = team_nl_policy, .netnsok = true, .module = THIS_MODULE, diff --git a/drivers/net/team/team_nl.c b/drivers/net/team/team_nl.c new file mode 100644 index 000000000000..208424ab78f5 --- /dev/null +++ b/drivers/net/team/team_nl.c @@ -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/team.yaml */ +/* YNL-GEN kernel source */ + +#include +#include + +#include "team_nl.h" + +#include + +/* Common nested types */ +const struct nla_policy team_attr_option_nl_policy[TEAM_ATTR_OPTION_ARRAY_INDEX + 1] = { + [TEAM_ATTR_OPTION_NAME] = { .type = NLA_STRING, .len = TEAM_STRING_MAX_LEN, }, + [TEAM_ATTR_OPTION_CHANGED] = { .type = NLA_FLAG, }, + [TEAM_ATTR_OPTION_TYPE] = { .type = NLA_U8, }, + [TEAM_ATTR_OPTION_DATA] = { .type = NLA_BINARY, }, + [TEAM_ATTR_OPTION_REMOVED] = { .type = NLA_FLAG, }, + [TEAM_ATTR_OPTION_PORT_IFINDEX] = { .type = NLA_U32, }, + [TEAM_ATTR_OPTION_ARRAY_INDEX] = { .type = NLA_U32, }, +}; + +const struct nla_policy team_item_option_nl_policy[TEAM_ATTR_ITEM_OPTION + 1] = { + [TEAM_ATTR_ITEM_OPTION] = NLA_POLICY_NESTED(team_attr_option_nl_policy), +}; + +/* Global operation policy for team */ +const struct nla_policy team_nl_policy[TEAM_ATTR_LIST_OPTION + 1] = { + [TEAM_ATTR_TEAM_IFINDEX] = { .type = NLA_U32, }, + [TEAM_ATTR_LIST_OPTION] = NLA_POLICY_NESTED(team_item_option_nl_policy), +}; + +/* Ops table for team */ +const struct genl_small_ops team_nl_ops[4] = { + { + .cmd = TEAM_CMD_NOOP, + .validate = GENL_DONT_VALIDATE_STRICT, + .doit = team_nl_noop_doit, + }, + { + .cmd = TEAM_CMD_OPTIONS_SET, + .validate = GENL_DONT_VALIDATE_STRICT, + .doit = team_nl_options_set_doit, + .flags = GENL_ADMIN_PERM, + }, + { + .cmd = TEAM_CMD_OPTIONS_GET, + .validate = GENL_DONT_VALIDATE_STRICT, + .doit = team_nl_options_get_doit, + .flags = GENL_ADMIN_PERM, + }, + { + .cmd = TEAM_CMD_PORT_LIST_GET, + .validate = GENL_DONT_VALIDATE_STRICT, + .doit = team_nl_port_list_get_doit, + .flags = GENL_ADMIN_PERM, + }, +}; diff --git a/drivers/net/team/team_nl.h b/drivers/net/team/team_nl.h new file mode 100644 index 000000000000..c9ec1b22ac4d --- /dev/null +++ b/drivers/net/team/team_nl.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/team.yaml */ +/* YNL-GEN kernel header */ + +#ifndef _LINUX_TEAM_GEN_H +#define _LINUX_TEAM_GEN_H + +#include +#include + +#include + +/* Common nested types */ +extern const struct nla_policy team_attr_option_nl_policy[TEAM_ATTR_OPTION_ARRAY_INDEX + 1]; +extern const struct nla_policy team_item_option_nl_policy[TEAM_ATTR_ITEM_OPTION + 1]; + +/* Global operation policy for team */ +extern const struct nla_policy team_nl_policy[TEAM_ATTR_LIST_OPTION + 1]; + +/* Ops table for team */ +extern const struct genl_small_ops team_nl_ops[4]; + +int team_nl_noop_doit(struct sk_buff *skb, struct genl_info *info); +int team_nl_options_set_doit(struct sk_buff *skb, struct genl_info *info); +int team_nl_options_get_doit(struct sk_buff *skb, struct genl_info *info); +int team_nl_port_list_get_doit(struct sk_buff *skb, struct genl_info *info); + +#endif /* _LINUX_TEAM_GEN_H */ diff --git a/include/uapi/linux/if_team.h b/include/uapi/linux/if_team.h index 13c61fecb78b..a5c06243a435 100644 --- a/include/uapi/linux/if_team.h +++ b/include/uapi/linux/if_team.h @@ -1,23 +1,69 @@ -/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ -/* - * include/linux/if_team.h - Network team device driver header - * Copyright (c) 2011 Jiri Pirko - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/team.yaml */ +/* YNL-GEN uapi header */ -#ifndef _UAPI_LINUX_IF_TEAM_H_ -#define _UAPI_LINUX_IF_TEAM_H_ +#ifndef _UAPI_LINUX_IF_TEAM_H +#define _UAPI_LINUX_IF_TEAM_H +#define TEAM_GENL_NAME "team" +#define TEAM_GENL_VERSION 1 -#define TEAM_STRING_MAX_LEN 32 +#define TEAM_STRING_MAX_LEN 32 +#define TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME "change_event" -/********************************** - * NETLINK_GENERIC netlink family. - **********************************/ +enum { + TEAM_ATTR_UNSPEC, + TEAM_ATTR_TEAM_IFINDEX, + TEAM_ATTR_LIST_OPTION, + TEAM_ATTR_LIST_PORT, + + __TEAM_ATTR_MAX, + TEAM_ATTR_MAX = (__TEAM_ATTR_MAX - 1) +}; + +enum { + TEAM_ATTR_ITEM_OPTION_UNSPEC, + TEAM_ATTR_ITEM_OPTION, + + __TEAM_ATTR_ITEM_OPTION_MAX, + TEAM_ATTR_ITEM_OPTION_MAX = (__TEAM_ATTR_ITEM_OPTION_MAX - 1) +}; + +enum { + TEAM_ATTR_OPTION_UNSPEC, + TEAM_ATTR_OPTION_NAME, + TEAM_ATTR_OPTION_CHANGED, + TEAM_ATTR_OPTION_TYPE, + TEAM_ATTR_OPTION_DATA, + TEAM_ATTR_OPTION_REMOVED, + TEAM_ATTR_OPTION_PORT_IFINDEX, + TEAM_ATTR_OPTION_ARRAY_INDEX, + + __TEAM_ATTR_OPTION_MAX, + TEAM_ATTR_OPTION_MAX = (__TEAM_ATTR_OPTION_MAX - 1) +}; + +enum { + TEAM_ATTR_ITEM_PORT_UNSPEC, + TEAM_ATTR_ITEM_PORT, + + __TEAM_ATTR_ITEM_PORT_MAX, + TEAM_ATTR_ITEM_PORT_MAX = (__TEAM_ATTR_ITEM_PORT_MAX - 1) +}; + +enum { + TEAM_ATTR_PORT_UNSPEC, + TEAM_ATTR_PORT_IFINDEX, + TEAM_ATTR_PORT_CHANGED, + TEAM_ATTR_PORT_LINKUP, + TEAM_ATTR_PORT_SPEED, + TEAM_ATTR_PORT_DUPLEX, + TEAM_ATTR_PORT_REMOVED, + + __TEAM_ATTR_PORT_MAX, + TEAM_ATTR_PORT_MAX = (__TEAM_ATTR_PORT_MAX - 1) +}; enum { TEAM_CMD_NOOP, @@ -26,83 +72,7 @@ enum { TEAM_CMD_PORT_LIST_GET, __TEAM_CMD_MAX, - TEAM_CMD_MAX = (__TEAM_CMD_MAX - 1), + TEAM_CMD_MAX = (__TEAM_CMD_MAX - 1) }; -enum { - TEAM_ATTR_UNSPEC, - TEAM_ATTR_TEAM_IFINDEX, /* u32 */ - TEAM_ATTR_LIST_OPTION, /* nest */ - TEAM_ATTR_LIST_PORT, /* nest */ - - __TEAM_ATTR_MAX, - TEAM_ATTR_MAX = __TEAM_ATTR_MAX - 1, -}; - -/* Nested layout of get/set msg: - * - * [TEAM_ATTR_LIST_OPTION] - * [TEAM_ATTR_ITEM_OPTION] - * [TEAM_ATTR_OPTION_*], ... - * [TEAM_ATTR_ITEM_OPTION] - * [TEAM_ATTR_OPTION_*], ... - * ... - * [TEAM_ATTR_LIST_PORT] - * [TEAM_ATTR_ITEM_PORT] - * [TEAM_ATTR_PORT_*], ... - * [TEAM_ATTR_ITEM_PORT] - * [TEAM_ATTR_PORT_*], ... - * ... - */ - -enum { - TEAM_ATTR_ITEM_OPTION_UNSPEC, - TEAM_ATTR_ITEM_OPTION, /* nest */ - - __TEAM_ATTR_ITEM_OPTION_MAX, - TEAM_ATTR_ITEM_OPTION_MAX = __TEAM_ATTR_ITEM_OPTION_MAX - 1, -}; - -enum { - TEAM_ATTR_OPTION_UNSPEC, - TEAM_ATTR_OPTION_NAME, /* string */ - TEAM_ATTR_OPTION_CHANGED, /* flag */ - TEAM_ATTR_OPTION_TYPE, /* u8 */ - TEAM_ATTR_OPTION_DATA, /* dynamic */ - TEAM_ATTR_OPTION_REMOVED, /* flag */ - TEAM_ATTR_OPTION_PORT_IFINDEX, /* u32 */ /* for per-port options */ - TEAM_ATTR_OPTION_ARRAY_INDEX, /* u32 */ /* for array options */ - - __TEAM_ATTR_OPTION_MAX, - TEAM_ATTR_OPTION_MAX = __TEAM_ATTR_OPTION_MAX - 1, -}; - -enum { - TEAM_ATTR_ITEM_PORT_UNSPEC, - TEAM_ATTR_ITEM_PORT, /* nest */ - - __TEAM_ATTR_ITEM_PORT_MAX, - TEAM_ATTR_ITEM_PORT_MAX = __TEAM_ATTR_ITEM_PORT_MAX - 1, -}; - -enum { - TEAM_ATTR_PORT_UNSPEC, - TEAM_ATTR_PORT_IFINDEX, /* u32 */ - TEAM_ATTR_PORT_CHANGED, /* flag */ - TEAM_ATTR_PORT_LINKUP, /* flag */ - TEAM_ATTR_PORT_SPEED, /* u32 */ - TEAM_ATTR_PORT_DUPLEX, /* u8 */ - TEAM_ATTR_PORT_REMOVED, /* flag */ - - __TEAM_ATTR_PORT_MAX, - TEAM_ATTR_PORT_MAX = __TEAM_ATTR_PORT_MAX - 1, -}; - -/* - * NETLINK_GENERIC related info - */ -#define TEAM_GENL_NAME "team" -#define TEAM_GENL_VERSION 0x1 -#define TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME "change_event" - -#endif /* _UAPI_LINUX_IF_TEAM_H_ */ +#endif /* _UAPI_LINUX_IF_TEAM_H */