diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2025-12-01 20:33:06 -0800 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2025-12-01 20:33:07 -0800 |
| commit | 31a3ed492dd41908b60b57d82f0ba878eae685fd (patch) | |
| tree | 25be20c4c977bcd611712fb38b217ed698b2dc5d /drivers | |
| parent | cbc19b3229f1d509b45816a5afd42cc34c03d284 (diff) | |
| parent | 3fd2f3d2f4259df19eec3ea5a188d7c50a37e216 (diff) | |
Merge tag 'wireguard-6.19-rc1-for-jakub' of https://git.kernel.org/pub/scm/linux/kernel/git/zx2c4/wireguard-linux
Jason A. Donenfeld says:
====================
WireGuard updates for Linux 6.19-rc1.
Please find here Asbjørn's ynl series. This has been sitting in my
testing for the last week or so, since he sent out the latest series.
I've dropped the yml sample code, as he found an issue in that last
minute, but otherwise, we've sat on this code for long enough, so
let's see how it goes.
* tag 'wireguard-6.19-rc1-for-jakub' of https://git.kernel.org/pub/scm/linux/kernel/git/zx2c4/wireguard-linux:
wireguard: netlink: generate netlink code
wireguard: uapi: generate header with ynl-gen
wireguard: uapi: move flag enums
wireguard: uapi: move enum wg_cmd
wireguard: netlink: add YNL specification
wireguard: netlink: lower .maxattr for WG_CMD_GET_DEVICE
wireguard: netlink: convert to split ops
wireguard: netlink: use WG_KEY_LEN in policies
wireguard: netlink: validate nested arrays in policy
wireguard: netlink: enable strict genetlink validation
====================
Link: https://patch.msgid.link/
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/wireguard/Makefile | 2 | ||||
| -rw-r--r-- | drivers/net/wireguard/generated/netlink.c | 73 | ||||
| -rw-r--r-- | drivers/net/wireguard/generated/netlink.h | 30 | ||||
| -rw-r--r-- | drivers/net/wireguard/netlink.c | 68 |
4 files changed, 116 insertions, 57 deletions
diff --git a/drivers/net/wireguard/Makefile b/drivers/net/wireguard/Makefile index dbe1f8514efc..00cbcc9ab69d 100644 --- a/drivers/net/wireguard/Makefile +++ b/drivers/net/wireguard/Makefile @@ -13,5 +13,5 @@ wireguard-y += peerlookup.o wireguard-y += allowedips.o wireguard-y += ratelimiter.o wireguard-y += cookie.o -wireguard-y += netlink.o +wireguard-y += netlink.o generated/netlink.o obj-$(CONFIG_WIREGUARD) := wireguard.o diff --git a/drivers/net/wireguard/generated/netlink.c b/drivers/net/wireguard/generated/netlink.c new file mode 100644 index 000000000000..3ef8c29908c2 --- /dev/null +++ b/drivers/net/wireguard/generated/netlink.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/wireguard.yaml */ +/* YNL-GEN kernel source */ +/* YNL-ARG --function-prefix wg */ +/* To regenerate run: tools/net/ynl/ynl-regen.sh */ + +#include <net/netlink.h> +#include <net/genetlink.h> + +#include "netlink.h" + +#include <uapi/linux/wireguard.h> +#include <linux/time_types.h> + +/* Common nested types */ +const struct nla_policy wireguard_wgallowedip_nl_policy[WGALLOWEDIP_A_FLAGS + 1] = { + [WGALLOWEDIP_A_FAMILY] = { .type = NLA_U16, }, + [WGALLOWEDIP_A_IPADDR] = NLA_POLICY_MIN_LEN(4), + [WGALLOWEDIP_A_CIDR_MASK] = { .type = NLA_U8, }, + [WGALLOWEDIP_A_FLAGS] = NLA_POLICY_MASK(NLA_U32, 0x1), +}; + +const struct nla_policy wireguard_wgpeer_nl_policy[WGPEER_A_PROTOCOL_VERSION + 1] = { + [WGPEER_A_PUBLIC_KEY] = NLA_POLICY_EXACT_LEN(WG_KEY_LEN), + [WGPEER_A_PRESHARED_KEY] = NLA_POLICY_EXACT_LEN(WG_KEY_LEN), + [WGPEER_A_FLAGS] = NLA_POLICY_MASK(NLA_U32, 0x7), + [WGPEER_A_ENDPOINT] = NLA_POLICY_MIN_LEN(16), + [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NLA_U16, }, + [WGPEER_A_LAST_HANDSHAKE_TIME] = NLA_POLICY_EXACT_LEN(16), + [WGPEER_A_RX_BYTES] = { .type = NLA_U64, }, + [WGPEER_A_TX_BYTES] = { .type = NLA_U64, }, + [WGPEER_A_ALLOWEDIPS] = NLA_POLICY_NESTED_ARRAY(wireguard_wgallowedip_nl_policy), + [WGPEER_A_PROTOCOL_VERSION] = { .type = NLA_U32, }, +}; + +/* WG_CMD_GET_DEVICE - dump */ +static const struct nla_policy wireguard_get_device_nl_policy[WGDEVICE_A_IFNAME + 1] = { + [WGDEVICE_A_IFINDEX] = { .type = NLA_U32, }, + [WGDEVICE_A_IFNAME] = { .type = NLA_NUL_STRING, .len = 15, }, +}; + +/* WG_CMD_SET_DEVICE - do */ +static const struct nla_policy wireguard_set_device_nl_policy[WGDEVICE_A_PEERS + 1] = { + [WGDEVICE_A_IFINDEX] = { .type = NLA_U32, }, + [WGDEVICE_A_IFNAME] = { .type = NLA_NUL_STRING, .len = 15, }, + [WGDEVICE_A_PRIVATE_KEY] = NLA_POLICY_EXACT_LEN(WG_KEY_LEN), + [WGDEVICE_A_PUBLIC_KEY] = NLA_POLICY_EXACT_LEN(WG_KEY_LEN), + [WGDEVICE_A_FLAGS] = NLA_POLICY_MASK(NLA_U32, 0x1), + [WGDEVICE_A_LISTEN_PORT] = { .type = NLA_U16, }, + [WGDEVICE_A_FWMARK] = { .type = NLA_U32, }, + [WGDEVICE_A_PEERS] = NLA_POLICY_NESTED_ARRAY(wireguard_wgpeer_nl_policy), +}; + +/* Ops table for wireguard */ +const struct genl_split_ops wireguard_nl_ops[2] = { + { + .cmd = WG_CMD_GET_DEVICE, + .start = wg_get_device_start, + .dumpit = wg_get_device_dumpit, + .done = wg_get_device_done, + .policy = wireguard_get_device_nl_policy, + .maxattr = WGDEVICE_A_IFNAME, + .flags = GENL_UNS_ADMIN_PERM | GENL_CMD_CAP_DUMP, + }, + { + .cmd = WG_CMD_SET_DEVICE, + .doit = wg_set_device_doit, + .policy = wireguard_set_device_nl_policy, + .maxattr = WGDEVICE_A_PEERS, + .flags = GENL_UNS_ADMIN_PERM | GENL_CMD_CAP_DO, + }, +}; diff --git a/drivers/net/wireguard/generated/netlink.h b/drivers/net/wireguard/generated/netlink.h new file mode 100644 index 000000000000..5dc977ee9e7c --- /dev/null +++ b/drivers/net/wireguard/generated/netlink.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/wireguard.yaml */ +/* YNL-GEN kernel header */ +/* YNL-ARG --function-prefix wg */ +/* To regenerate run: tools/net/ynl/ynl-regen.sh */ + +#ifndef _LINUX_WIREGUARD_GEN_H +#define _LINUX_WIREGUARD_GEN_H + +#include <net/netlink.h> +#include <net/genetlink.h> + +#include <uapi/linux/wireguard.h> +#include <linux/time_types.h> + +/* Common nested types */ +extern const struct nla_policy wireguard_wgallowedip_nl_policy[WGALLOWEDIP_A_FLAGS + 1]; +extern const struct nla_policy wireguard_wgpeer_nl_policy[WGPEER_A_PROTOCOL_VERSION + 1]; + +/* Ops table for wireguard */ +extern const struct genl_split_ops wireguard_nl_ops[2]; + +int wg_get_device_start(struct netlink_callback *cb); +int wg_get_device_done(struct netlink_callback *cb); + +int wg_get_device_dumpit(struct sk_buff *skb, struct netlink_callback *cb); +int wg_set_device_doit(struct sk_buff *skb, struct genl_info *info); + +#endif /* _LINUX_WIREGUARD_GEN_H */ diff --git a/drivers/net/wireguard/netlink.c b/drivers/net/wireguard/netlink.c index 67f962eb8b46..1da7e98d0d50 100644 --- a/drivers/net/wireguard/netlink.c +++ b/drivers/net/wireguard/netlink.c @@ -9,6 +9,7 @@ #include "socket.h" #include "queueing.h" #include "messages.h" +#include "generated/netlink.h" #include <uapi/linux/wireguard.h> @@ -19,37 +20,6 @@ static struct genl_family genl_family; -static const struct nla_policy device_policy[WGDEVICE_A_MAX + 1] = { - [WGDEVICE_A_IFINDEX] = { .type = NLA_U32 }, - [WGDEVICE_A_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 }, - [WGDEVICE_A_PRIVATE_KEY] = NLA_POLICY_EXACT_LEN(NOISE_PUBLIC_KEY_LEN), - [WGDEVICE_A_PUBLIC_KEY] = NLA_POLICY_EXACT_LEN(NOISE_PUBLIC_KEY_LEN), - [WGDEVICE_A_FLAGS] = NLA_POLICY_MASK(NLA_U32, __WGDEVICE_F_ALL), - [WGDEVICE_A_LISTEN_PORT] = { .type = NLA_U16 }, - [WGDEVICE_A_FWMARK] = { .type = NLA_U32 }, - [WGDEVICE_A_PEERS] = { .type = NLA_NESTED } -}; - -static const struct nla_policy peer_policy[WGPEER_A_MAX + 1] = { - [WGPEER_A_PUBLIC_KEY] = NLA_POLICY_EXACT_LEN(NOISE_PUBLIC_KEY_LEN), - [WGPEER_A_PRESHARED_KEY] = NLA_POLICY_EXACT_LEN(NOISE_SYMMETRIC_KEY_LEN), - [WGPEER_A_FLAGS] = NLA_POLICY_MASK(NLA_U32, __WGPEER_F_ALL), - [WGPEER_A_ENDPOINT] = NLA_POLICY_MIN_LEN(sizeof(struct sockaddr)), - [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NLA_U16 }, - [WGPEER_A_LAST_HANDSHAKE_TIME] = NLA_POLICY_EXACT_LEN(sizeof(struct __kernel_timespec)), - [WGPEER_A_RX_BYTES] = { .type = NLA_U64 }, - [WGPEER_A_TX_BYTES] = { .type = NLA_U64 }, - [WGPEER_A_ALLOWEDIPS] = { .type = NLA_NESTED }, - [WGPEER_A_PROTOCOL_VERSION] = { .type = NLA_U32 } -}; - -static const struct nla_policy allowedip_policy[WGALLOWEDIP_A_MAX + 1] = { - [WGALLOWEDIP_A_FAMILY] = { .type = NLA_U16 }, - [WGALLOWEDIP_A_IPADDR] = NLA_POLICY_MIN_LEN(sizeof(struct in_addr)), - [WGALLOWEDIP_A_CIDR_MASK] = { .type = NLA_U8 }, - [WGALLOWEDIP_A_FLAGS] = NLA_POLICY_MASK(NLA_U32, __WGALLOWEDIP_F_ALL), -}; - static struct wg_device *lookup_interface(struct nlattr **attrs, struct sk_buff *skb) { @@ -197,7 +167,7 @@ err: return -EMSGSIZE; } -static int wg_get_device_start(struct netlink_callback *cb) +int wg_get_device_start(struct netlink_callback *cb) { struct wg_device *wg; @@ -208,7 +178,7 @@ static int wg_get_device_start(struct netlink_callback *cb) return 0; } -static int wg_get_device_dump(struct sk_buff *skb, struct netlink_callback *cb) +int wg_get_device_dumpit(struct sk_buff *skb, struct netlink_callback *cb) { struct wg_peer *peer, *next_peer_cursor; struct dump_ctx *ctx = DUMP_CTX(cb); @@ -302,7 +272,7 @@ out: */ } -static int wg_get_device_done(struct netlink_callback *cb) +int wg_get_device_done(struct netlink_callback *cb) { struct dump_ctx *ctx = DUMP_CTX(cb); @@ -467,7 +437,7 @@ static int set_peer(struct wg_device *wg, struct nlattr **attrs) nla_for_each_nested(attr, attrs[WGPEER_A_ALLOWEDIPS], rem) { ret = nla_parse_nested(allowedip, WGALLOWEDIP_A_MAX, - attr, allowedip_policy, NULL); + attr, NULL, NULL); if (ret < 0) goto out; ret = set_allowedip(peer, allowedip); @@ -500,7 +470,7 @@ out: return ret; } -static int wg_set_device(struct sk_buff *skb, struct genl_info *info) +int wg_set_device_doit(struct sk_buff *skb, struct genl_info *info) { struct wg_device *wg = lookup_interface(info->attrs, skb); u32 flags = 0; @@ -593,7 +563,7 @@ skip_set_private_key: nla_for_each_nested(attr, info->attrs[WGDEVICE_A_PEERS], rem) { ret = nla_parse_nested(peer, WGPEER_A_MAX, attr, - peer_policy, NULL); + NULL, NULL); if (ret < 0) goto out; ret = set_peer(wg, peer); @@ -614,34 +584,20 @@ out_nodev: return ret; } -static const struct genl_ops genl_ops[] = { - { - .cmd = WG_CMD_GET_DEVICE, - .start = wg_get_device_start, - .dumpit = wg_get_device_dump, - .done = wg_get_device_done, - .flags = GENL_UNS_ADMIN_PERM - }, { - .cmd = WG_CMD_SET_DEVICE, - .doit = wg_set_device, - .flags = GENL_UNS_ADMIN_PERM - } -}; - static struct genl_family genl_family __ro_after_init = { - .ops = genl_ops, - .n_ops = ARRAY_SIZE(genl_ops), - .resv_start_op = WG_CMD_SET_DEVICE + 1, + .split_ops = wireguard_nl_ops, + .n_split_ops = ARRAY_SIZE(wireguard_nl_ops), .name = WG_GENL_NAME, .version = WG_GENL_VERSION, - .maxattr = WGDEVICE_A_MAX, .module = THIS_MODULE, - .policy = device_policy, .netnsok = true }; int __init wg_genetlink_init(void) { + BUILD_BUG_ON(WG_KEY_LEN != NOISE_PUBLIC_KEY_LEN); + BUILD_BUG_ON(WG_KEY_LEN != NOISE_SYMMETRIC_KEY_LEN); + return genl_register_family(&genl_family); } |
