* [RFC net-next 01/14] wireguard: netlink: use WG_KEY_LEN in policies
2025-09-04 22:02 [RFC net-next 00/14] wireguard: netlink: ynl conversion Asbjørn Sloth Tønnesen
@ 2025-09-04 22:02 ` Asbjørn Sloth Tønnesen
2025-09-04 22:02 ` [RFC net-next 02/14] wireguard: netlink: validate nested arrays in policy Asbjørn Sloth Tønnesen
` (13 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2025-09-04 22:02 UTC (permalink / raw)
To: Jason A. Donenfeld, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Asbjørn Sloth Tønnesen, Donald Hunter, Simon Horman,
Jacob Keller, Andrew Lunn, wireguard, netdev, linux-kernel
When converting the netlink policies to YNL, then the constants
used in the policy has to be visible to user-space.
As NOISE_*_KEY_LEN isn't visible for userspace, then change to
use WG_KEY_LEN, as is also documented in the UAPI header:
$ grep WG_KEY_LEN include/uapi/linux/wireguard.h
* WGDEVICE_A_PRIVATE_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
* WGDEVICE_A_PUBLIC_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
* WGPEER_A_PUBLIC_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
* WGPEER_A_PRESHARED_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
[...]
Add a couple of BUILD_BUG_ON() to ensure that they stay in sync.
No behavioural changes intended.
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
drivers/net/wireguard/netlink.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireguard/netlink.c b/drivers/net/wireguard/netlink.c
index 67f962eb8b46..086edd4bb33b 100644
--- a/drivers/net/wireguard/netlink.c
+++ b/drivers/net/wireguard/netlink.c
@@ -22,8 +22,8 @@ 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_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, __WGDEVICE_F_ALL),
[WGDEVICE_A_LISTEN_PORT] = { .type = NLA_U16 },
[WGDEVICE_A_FWMARK] = { .type = NLA_U32 },
@@ -31,8 +31,8 @@ static const struct nla_policy device_policy[WGDEVICE_A_MAX + 1] = {
};
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_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, __WGPEER_F_ALL),
[WGPEER_A_ENDPOINT] = NLA_POLICY_MIN_LEN(sizeof(struct sockaddr)),
[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NLA_U16 },
@@ -642,6 +642,9 @@ static struct genl_family genl_family __ro_after_init = {
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);
}
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* [RFC net-next 02/14] wireguard: netlink: validate nested arrays in policy
2025-09-04 22:02 [RFC net-next 00/14] wireguard: netlink: ynl conversion Asbjørn Sloth Tønnesen
2025-09-04 22:02 ` [RFC net-next 01/14] wireguard: netlink: use WG_KEY_LEN in policies Asbjørn Sloth Tønnesen
@ 2025-09-04 22:02 ` Asbjørn Sloth Tønnesen
2025-09-04 22:02 ` [RFC net-next 03/14] netlink: specs: add specification for wireguard Asbjørn Sloth Tønnesen
` (12 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2025-09-04 22:02 UTC (permalink / raw)
To: Jason A. Donenfeld, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Asbjørn Sloth Tønnesen, Donald Hunter, Simon Horman,
Jacob Keller, Andrew Lunn, wireguard, netdev, linux-kernel
Use NLA_POLICY_NESTED_ARRAY() to add nested array validation.
No behavioural changes intended, as the nested policy is already
enforced through nla_parse_nested().
This patch is an incremental step towards adopting a policy
generated by ynl-gen.
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
drivers/net/wireguard/netlink.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireguard/netlink.c b/drivers/net/wireguard/netlink.c
index 086edd4bb33b..742d3f88d132 100644
--- a/drivers/net/wireguard/netlink.c
+++ b/drivers/net/wireguard/netlink.c
@@ -27,7 +27,7 @@ static const struct nla_policy device_policy[WGDEVICE_A_MAX + 1] = {
[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 }
+ [WGDEVICE_A_PEERS] = NLA_POLICY_NESTED_ARRAY(peer_policy),
};
static const struct nla_policy peer_policy[WGPEER_A_MAX + 1] = {
@@ -39,7 +39,7 @@ static const struct nla_policy peer_policy[WGPEER_A_MAX + 1] = {
[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_ALLOWEDIPS] = NLA_POLICY_NESTED_ARRAY(allowedip_policy),
[WGPEER_A_PROTOCOL_VERSION] = { .type = NLA_U32 }
};
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* [RFC net-next 03/14] netlink: specs: add specification for wireguard
2025-09-04 22:02 [RFC net-next 00/14] wireguard: netlink: ynl conversion Asbjørn Sloth Tønnesen
2025-09-04 22:02 ` [RFC net-next 01/14] wireguard: netlink: use WG_KEY_LEN in policies Asbjørn Sloth Tønnesen
2025-09-04 22:02 ` [RFC net-next 02/14] wireguard: netlink: validate nested arrays in policy Asbjørn Sloth Tønnesen
@ 2025-09-04 22:02 ` Asbjørn Sloth Tønnesen
2025-09-04 22:02 ` [RFC net-next 04/14] netlink: specs: wireguard: add remaining checks Asbjørn Sloth Tønnesen
` (11 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2025-09-04 22:02 UTC (permalink / raw)
To: Jason A. Donenfeld, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Asbjørn Sloth Tønnesen, Donald Hunter, Simon Horman,
Jacob Keller, Andrew Lunn, wireguard, netdev, linux-kernel
This patch adds an almost complete specification for wireguard,
only missing a few checks which will be added in the next patch.
This makes the documentation in the UAPI header redundant, and
is therefore removed. Once the header is generated from YNL,
then it will include a pointer towards the spec as well.
Generate wireguard.rst from this spec:
$ make -C tools/net/ynl/generated/ wireguard.rst
Query wireguard interface through pyynl:
$ sudo ./tools/net/ynl/pyynl/cli.py --family wireguard \
--dump get-device \
--json '{"ifindex":3}'
[{'fwmark': 0,
'ifindex': 3,
'ifname': 'wg-test',
'listen-port': 54318,
'peers': [{0: {'allowedips': [{0: {'cidr-mask': 0,
'family': 2,
'ipaddr': '0.0.0.0'}},
{0: {'cidr-mask': 0,
'family': 10,
'ipaddr': '::'}}],
'endpoint': b'[...]',
'last-handshake-time': {'nsec': 42, 'sec': 42},
'persistent-keepalive-interval': 42,
'preshared-key': '[...]',
'protocol-version': 1,
'public-key': '[...]',
'rx-bytes': 42,
'tx-bytes': 42}}],
'private-key': '[...]',
'public-key': '[...]'}]
Add another allowed IP prefix:
$ sudo ./tools/net/ynl/pyynl/cli.py --family wireguard \
--do set-device --json '{"ifindex":3,"peers":[
{"public-key":"6a df b1 83 a4 ..","allowedips":[
{"cidr-mask":0,"family":10,"ipaddr":"::"}]}]}'
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
Documentation/netlink/specs/wireguard.yaml | 281 +++++++++++++++++++++
MAINTAINERS | 1 +
include/uapi/linux/wireguard.h | 129 ----------
3 files changed, 282 insertions(+), 129 deletions(-)
create mode 100644 Documentation/netlink/specs/wireguard.yaml
diff --git a/Documentation/netlink/specs/wireguard.yaml b/Documentation/netlink/specs/wireguard.yaml
new file mode 100644
index 000000000000..c6db3bbf0985
--- /dev/null
+++ b/Documentation/netlink/specs/wireguard.yaml
@@ -0,0 +1,281 @@
+# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
+---
+name: wireguard
+protocol: genetlink-legacy
+
+doc: |
+ Netlink protocol to control WireGuard network devices.
+
+ The below enums and macros are for interfacing with WireGuard, using generic
+ netlink, with family WG_GENL_NAME and version WG_GENL_VERSION. It defines two
+ commands: get and set. Note that while they share many common attributes,
+ these two commands actually accept a slightly different set of inputs and
+ outputs. These differences are noted under the individual attributes.
+c-family-name: wg-genl-name
+c-version-name: wg-genl-version
+max-by-define: true
+
+definitions:
+ -
+ name-prefix: wg-
+ name: key-len
+ type: const
+ value: 32
+ -
+ name: --kernel-timespec
+ type: struct
+ header: linux/time_types.h
+ members:
+ -
+ name: sec
+ type: u64
+ doc: Number of seconds, since UNIX epoch.
+ -
+ name: nsec
+ type: u64
+ doc: Number of nanoseconds, after the second began.
+ -
+ name: wgdevice-flags
+ name-prefix: wgdevice-f-
+ enum-name: wgdevice-flag
+ type: flags
+ entries:
+ - replace-peers
+ -
+ name: wgpeer-flags
+ name-prefix: wgpeer-f-
+ enum-name: wgpeer-flag
+ type: flags
+ entries:
+ - remove-me
+ - replace-allowedips
+ - update-only
+ -
+ name: wgallowedip-flags
+ name-prefix: wgallowedip-f-
+ enum-name: wgallowedip-flag
+ type: flags
+ entries:
+ - remove-me
+
+attribute-sets:
+ -
+ name: wgdevice
+ enum-name: wgdevice-attribute
+ name-prefix: wgdevice-a-
+ attributes:
+ -
+ name: unspec
+ type: unused
+ value: 0
+ -
+ name: ifindex
+ type: u32
+ -
+ name: ifname
+ type: string
+ -
+ name: private-key
+ type: binary
+ doc: Set to all zeros to remove.
+ display-hint: hex
+ checks:
+ exact-len: wg-key-len
+ -
+ name: public-key
+ type: binary
+ display-hint: hex
+ checks:
+ exact-len: wg-key-len
+ -
+ name: flags
+ doc: |
+ 0 or WGDEVICE_F_REPLACE_PEERS if all current peers
+ should be removed prior to adding the list below.
+ type: u32
+ enum: wgdevice-flags
+ checks:
+ flags-mask: wgdevice-flags
+ -
+ name: listen-port
+ type: u16
+ doc: Set as 0 to choose randomly.
+ -
+ name: fwmark
+ type: u32
+ doc: Set as 0 to disable.
+ -
+ name: peers
+ type: indexed-array
+ sub-type: nest
+ nested-attributes: wgpeer
+ -
+ name: wgpeer
+ enum-name: wgpeer-attribute
+ name-prefix: wgpeer-a-
+ attributes:
+ -
+ name: unspec
+ type: unused
+ value: 0
+ -
+ name: public-key
+ type: binary
+ display-hint: hex
+ checks:
+ exact-len: wg-key-len
+ -
+ name: preshared-key
+ type: binary
+ doc: Set as all zeros to remove.
+ display-hint: hex
+ checks:
+ exact-len: wg-key-len
+ -
+ name: flags
+ doc: |
+ 0 and/or WGPEER_F_REMOVE_ME if the specified peer should not
+ exist at the end of the operation, rather than added/updated
+ and/or WGPEER_F_REPLACE_ALLOWEDIPS if all current allowed IPs
+ of this peer should be removed prior to adding the list below
+ and/or WGPEER_F_UPDATE_ONLY if the peer should only be set if
+ it already exists.
+ type: u32
+ enum: wgpeer-flags
+ checks:
+ flags-mask: wgpeer-flags
+ -
+ name: endpoint
+ doc: struct sockaddr_in or struct sockaddr_in6
+ type: binary
+ -
+ name: persistent-keepalive-interval
+ type: u16
+ doc: Set as 0 to disable.
+ -
+ name: last-handshake-time
+ type: binary
+ struct: --kernel-timespec
+ -
+ name: rx-bytes
+ type: u64
+ -
+ name: tx-bytes
+ type: u64
+ -
+ name: allowedips
+ type: indexed-array
+ sub-type: nest
+ nested-attributes: wgallowedip
+ -
+ name: protocol-version
+ type: u32
+ doc: |
+ should not be set or used at all by most users of this API,
+ as the most recent protocol will be used when this is unset.
+ Otherwise, must be set to 1.
+ -
+ name: wgallowedip
+ enum-name: wgallowedip-attribute
+ name-prefix: wgallowedip-a-
+ attributes:
+ -
+ name: unspec
+ type: unused
+ value: 0
+ -
+ name: family
+ type: u16
+ -
+ name: ipaddr
+ type: binary
+ doc: struct in_addr or struct in6_add
+ display-hint: ipv4-or-v6
+ -
+ name: cidr-mask
+ type: u8
+ -
+ name: flags
+ type: u32
+ doc: |
+ WGALLOWEDIP_F_REMOVE_ME if the specified IP should be removed;
+ otherwise, this IP will be added if it is not already present.
+ enum: wgallowedip-flags
+ checks:
+ flags-mask: wgallowedip-flags
+
+operations:
+ enum-name: wg-cmd
+ name-prefix: wg-cmd-
+ list:
+ -
+ name: get-device
+ value: 0
+ doc: |
+ Retrieve WireGuard device.
+
+ The command should be called with one but not both of:
+ * WGDEVICE_A_IFINDEX
+ * WGDEVICE_A_IFNAME
+
+ The kernel will then return several messages (NLM_F_MULTI).
+ It is possible that all of the allowed IPs of a single peer will not
+ fit within a single netlink message. In that case, the same peer will
+ be written in the following message, except it will only contain
+ WGPEER_A_PUBLIC_KEY and WGPEER_A_ALLOWEDIPS. This may occur several
+ times in a row for the same peer. It is then up to the receiver to
+ coalesce adjacent peers. Likewise, it is possible that all peers will
+ not fit within a single message. So, subsequent peers will be sent
+ in following messages, except those will only contain
+ WGDEVICE_A_IFNAME and WGDEVICE_A_PEERS. It is then up to the receiver
+ to coalesce these messages to form the complete list of peers.
+
+ Since this is an NLA_F_DUMP command, the final message will always be
+ NLMSG_DONE, even if an error occurs. However, this NLMSG_DONE message
+ contains an integer error code. It is either zero or a negative error
+ code corresponding to the errno.
+ attribute-set: wgdevice
+ flags: [uns-admin-perm]
+
+ dump:
+ pre: wireguard-nl-get-device-start
+ post: wireguard-nl-get-device-done
+ # request only accepts ifindex | ifname, but keep .maxattr as is
+ request: &all-attrs
+ attributes:
+ - ifindex
+ - ifname
+ - private-key
+ - public-key
+ - flags
+ - listen-port
+ - fwmark
+ - peers
+ reply: *all-attrs
+ -
+ name: set-device
+ value: 1
+ doc: |
+ Set WireGuard device.
+
+ This command should be called with a wgdevice set, containing one but
+ not both of WGDEVICE_A_IFINDEX and WGDEVICE_A_IFNAME.
+
+ It is possible that the amount of configuration data exceeds that of
+ the maximum message length accepted by the kernel. In that case,
+ several messages should be sent one after another, with each
+ successive one filling in information not contained in the prior.
+ Note that if WGDEVICE_F_REPLACE_PEERS is specified in the first
+ message, it probably should not be specified in fragments that come
+ after, so that the list of peers is only cleared the first time but
+ appended after.
+ Likewise for peers, if WGPEER_F_REPLACE_ALLOWEDIPS is specified in
+ the first message of a peer, it likely should not be specified in
+ subsequent fragments.
+
+ If an error occurs, NLMSG_ERROR will reply containing an errno.
+ attribute-set: wgdevice
+ flags: [uns-admin-perm]
+
+ do:
+ request: *all-attrs
diff --git a/MAINTAINERS b/MAINTAINERS
index b81595e9ea95..1540aa22d152 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -27168,6 +27168,7 @@ M: Jason A. Donenfeld <Jason@zx2c4.com>
L: wireguard@lists.zx2c4.com
L: netdev@vger.kernel.org
S: Maintained
+F: Documentation/netlink/specs/wireguard.yaml
F: drivers/net/wireguard/
F: tools/testing/selftests/wireguard/
diff --git a/include/uapi/linux/wireguard.h b/include/uapi/linux/wireguard.h
index 8c26391196d5..dee4401e0b5d 100644
--- a/include/uapi/linux/wireguard.h
+++ b/include/uapi/linux/wireguard.h
@@ -1,135 +1,6 @@
/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT */
/*
* Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
- *
- * Documentation
- * =============
- *
- * The below enums and macros are for interfacing with WireGuard, using generic
- * netlink, with family WG_GENL_NAME and version WG_GENL_VERSION. It defines two
- * methods: get and set. Note that while they share many common attributes,
- * these two functions actually accept a slightly different set of inputs and
- * outputs.
- *
- * WG_CMD_GET_DEVICE
- * -----------------
- *
- * May only be called via NLM_F_REQUEST | NLM_F_DUMP. The command should contain
- * one but not both of:
- *
- * WGDEVICE_A_IFINDEX: NLA_U32
- * WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMSIZ - 1
- *
- * The kernel will then return several messages (NLM_F_MULTI) containing the
- * following tree of nested items:
- *
- * WGDEVICE_A_IFINDEX: NLA_U32
- * WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMSIZ - 1
- * WGDEVICE_A_PRIVATE_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
- * WGDEVICE_A_PUBLIC_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
- * WGDEVICE_A_LISTEN_PORT: NLA_U16
- * WGDEVICE_A_FWMARK: NLA_U32
- * WGDEVICE_A_PEERS: NLA_NESTED
- * 0: NLA_NESTED
- * WGPEER_A_PUBLIC_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
- * WGPEER_A_PRESHARED_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
- * WGPEER_A_ENDPOINT: NLA_MIN_LEN(struct sockaddr), struct sockaddr_in or struct sockaddr_in6
- * WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL: NLA_U16
- * WGPEER_A_LAST_HANDSHAKE_TIME: NLA_EXACT_LEN, struct __kernel_timespec
- * WGPEER_A_RX_BYTES: NLA_U64
- * WGPEER_A_TX_BYTES: NLA_U64
- * WGPEER_A_ALLOWEDIPS: NLA_NESTED
- * 0: NLA_NESTED
- * WGALLOWEDIP_A_FAMILY: NLA_U16
- * WGALLOWEDIP_A_IPADDR: NLA_MIN_LEN(struct in_addr), struct in_addr or struct in6_addr
- * WGALLOWEDIP_A_CIDR_MASK: NLA_U8
- * 0: NLA_NESTED
- * ...
- * 0: NLA_NESTED
- * ...
- * ...
- * WGPEER_A_PROTOCOL_VERSION: NLA_U32
- * 0: NLA_NESTED
- * ...
- * ...
- *
- * It is possible that all of the allowed IPs of a single peer will not
- * fit within a single netlink message. In that case, the same peer will
- * be written in the following message, except it will only contain
- * WGPEER_A_PUBLIC_KEY and WGPEER_A_ALLOWEDIPS. This may occur several
- * times in a row for the same peer. It is then up to the receiver to
- * coalesce adjacent peers. Likewise, it is possible that all peers will
- * not fit within a single message. So, subsequent peers will be sent
- * in following messages, except those will only contain WGDEVICE_A_IFNAME
- * and WGDEVICE_A_PEERS. It is then up to the receiver to coalesce these
- * messages to form the complete list of peers.
- *
- * Since this is an NLA_F_DUMP command, the final message will always be
- * NLMSG_DONE, even if an error occurs. However, this NLMSG_DONE message
- * contains an integer error code. It is either zero or a negative error
- * code corresponding to the errno.
- *
- * WG_CMD_SET_DEVICE
- * -----------------
- *
- * May only be called via NLM_F_REQUEST. The command should contain the
- * following tree of nested items, containing one but not both of
- * WGDEVICE_A_IFINDEX and WGDEVICE_A_IFNAME:
- *
- * WGDEVICE_A_IFINDEX: NLA_U32
- * WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMSIZ - 1
- * WGDEVICE_A_FLAGS: NLA_U32, 0 or WGDEVICE_F_REPLACE_PEERS if all current
- * peers should be removed prior to adding the list below.
- * WGDEVICE_A_PRIVATE_KEY: len WG_KEY_LEN, all zeros to remove
- * WGDEVICE_A_LISTEN_PORT: NLA_U16, 0 to choose randomly
- * WGDEVICE_A_FWMARK: NLA_U32, 0 to disable
- * WGDEVICE_A_PEERS: NLA_NESTED
- * 0: NLA_NESTED
- * WGPEER_A_PUBLIC_KEY: len WG_KEY_LEN
- * WGPEER_A_FLAGS: NLA_U32, 0 and/or WGPEER_F_REMOVE_ME if the
- * specified peer should not exist at the end of the
- * operation, rather than added/updated and/or
- * WGPEER_F_REPLACE_ALLOWEDIPS if all current allowed
- * IPs of this peer should be removed prior to adding
- * the list below and/or WGPEER_F_UPDATE_ONLY if the
- * peer should only be set if it already exists.
- * WGPEER_A_PRESHARED_KEY: len WG_KEY_LEN, all zeros to remove
- * WGPEER_A_ENDPOINT: struct sockaddr_in or struct sockaddr_in6
- * WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL: NLA_U16, 0 to disable
- * WGPEER_A_ALLOWEDIPS: NLA_NESTED
- * 0: NLA_NESTED
- * WGALLOWEDIP_A_FAMILY: NLA_U16
- * WGALLOWEDIP_A_IPADDR: struct in_addr or struct in6_addr
- * WGALLOWEDIP_A_CIDR_MASK: NLA_U8
- * WGALLOWEDIP_A_FLAGS: NLA_U32, WGALLOWEDIP_F_REMOVE_ME if
- * the specified IP should be removed;
- * otherwise, this IP will be added if
- * it is not already present.
- * 0: NLA_NESTED
- * ...
- * 0: NLA_NESTED
- * ...
- * ...
- * WGPEER_A_PROTOCOL_VERSION: NLA_U32, should not be set or used at
- * all by most users of this API, as the
- * most recent protocol will be used when
- * this is unset. Otherwise, must be set
- * to 1.
- * 0: NLA_NESTED
- * ...
- * ...
- *
- * It is possible that the amount of configuration data exceeds that of
- * the maximum message length accepted by the kernel. In that case, several
- * messages should be sent one after another, with each successive one
- * filling in information not contained in the prior. Note that if
- * WGDEVICE_F_REPLACE_PEERS is specified in the first message, it probably
- * should not be specified in fragments that come after, so that the list
- * of peers is only cleared the first time but appended after. Likewise for
- * peers, if WGPEER_F_REPLACE_ALLOWEDIPS is specified in the first message
- * of a peer, it likely should not be specified in subsequent fragments.
- *
- * If an error occurs, NLMSG_ERROR will reply containing an errno.
*/
#ifndef _WG_UAPI_WIREGUARD_H
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* [RFC net-next 04/14] netlink: specs: wireguard: add remaining checks
2025-09-04 22:02 [RFC net-next 00/14] wireguard: netlink: ynl conversion Asbjørn Sloth Tønnesen
` (2 preceding siblings ...)
2025-09-04 22:02 ` [RFC net-next 03/14] netlink: specs: add specification for wireguard Asbjørn Sloth Tønnesen
@ 2025-09-04 22:02 ` Asbjørn Sloth Tønnesen
2025-09-04 22:02 ` [RFC net-next 05/14] uapi: wireguard: use __*_A_MAX in enums Asbjørn Sloth Tønnesen
` (10 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2025-09-04 22:02 UTC (permalink / raw)
To: Jason A. Donenfeld, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Asbjørn Sloth Tønnesen, Donald Hunter, Simon Horman,
Jacob Keller, Andrew Lunn, wireguard, netdev, linux-kernel
This patch adds the remaining checks from the existing
policy code, and thereby completes the wireguard spec.
These are added separately in this RFC mainly to showcase
two difference approaches to convert them.
They require a sizeof() operations or arithmetics, both of
which can't be expressed in YNL currently.
In order to keep the C code 1:1, then in this patch they are
added as an additional UAPI header wireguard_params.h,
defining them so that ynl-gen can reference them as constants.
This approach could also allow a selftest to validate that
the value of the constant in the YNL spec, is the same as the
value in the header file.
In patch 12 in this series, this patch is reverted, and replaced
with magic numbers in the YNL checks, as an alternative.
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
Documentation/netlink/specs/wireguard.yaml | 36 ++++++++++++++++++++++
MAINTAINERS | 1 +
include/uapi/linux/wireguard_params.h | 18 +++++++++++
3 files changed, 55 insertions(+)
create mode 100644 include/uapi/linux/wireguard_params.h
diff --git a/Documentation/netlink/specs/wireguard.yaml b/Documentation/netlink/specs/wireguard.yaml
index c6db3bbf0985..37011c3f158b 100644
--- a/Documentation/netlink/specs/wireguard.yaml
+++ b/Documentation/netlink/specs/wireguard.yaml
@@ -21,6 +21,34 @@ definitions:
name: key-len
type: const
value: 32
+ -
+ name-prefix: --wg-
+ name: inaddr-sz
+ type: const
+ doc: Equivalent of ``sizeof(struct in_addr)``.
+ header: linux/wireguard_params.h
+ value: 4
+ -
+ name-prefix: --wg-
+ name: sockaddr-sz
+ type: const
+ doc: Equivalent of ``sizeof(struct sockaddr)``.
+ header: linux/wireguard_params.h
+ value: 16
+ -
+ name-prefix: --wg-
+ name: timespec-sz
+ type: const
+ doc: Equivalent of ``sizeof(struct __kernel_timespec)``.
+ header: linux/wireguard_params.h
+ value: 16
+ -
+ name-prefix: --wg-
+ name: ifnamlen
+ type: const
+ doc: Equivalent of ``IFNAMSIZ - 1``.
+ header: linux/wireguard_params.h
+ value: 15
-
name: --kernel-timespec
type: struct
@@ -74,6 +102,8 @@ attribute-sets:
-
name: ifname
type: string
+ checks:
+ max-len: --wg-ifnamlen
-
name: private-key
type: binary
@@ -148,6 +178,8 @@ attribute-sets:
name: endpoint
doc: struct sockaddr_in or struct sockaddr_in6
type: binary
+ checks:
+ min-len: --wg-sockaddr-sz
-
name: persistent-keepalive-interval
type: u16
@@ -156,6 +188,8 @@ attribute-sets:
name: last-handshake-time
type: binary
struct: --kernel-timespec
+ checks:
+ exact-len: --wg-timespec-sz
-
name: rx-bytes
type: u64
@@ -191,6 +225,8 @@ attribute-sets:
type: binary
doc: struct in_addr or struct in6_add
display-hint: ipv4-or-v6
+ checks:
+ min-len: --wg-inaddr-sz
-
name: cidr-mask
type: u8
diff --git a/MAINTAINERS b/MAINTAINERS
index 1540aa22d152..e8360e4b55c6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -27170,6 +27170,7 @@ L: netdev@vger.kernel.org
S: Maintained
F: Documentation/netlink/specs/wireguard.yaml
F: drivers/net/wireguard/
+F: include/uapi/linux/wireguard_params.h
F: tools/testing/selftests/wireguard/
WISTRON LAPTOP BUTTON DRIVER
diff --git a/include/uapi/linux/wireguard_params.h b/include/uapi/linux/wireguard_params.h
new file mode 100644
index 000000000000..c218e4b8042f
--- /dev/null
+++ b/include/uapi/linux/wireguard_params.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
+
+#ifndef _UAPI_LINUX_WIREGUARD_PARAMS_H
+#define _UAPI_LINUX_WIREGUARD_PARAMS_H
+
+#include <linux/time_types.h>
+#include <linux/if.h>
+#include <linux/in.h>
+
+/* These definitions are currently needed for definitions which can't
+ * be expressed directly in Documentation/netlink/specs/wireguard.yaml
+ */
+#define __WG_INADDR_SZ (sizeof(struct in_addr))
+#define __WG_SOCKADDR_SZ (sizeof(struct sockaddr))
+#define __WG_TIMESPEC_SZ (sizeof(struct __kernel_timespec))
+#define __WG_IFNAMLEN (IFNAMSIZ - 1)
+
+#endif /* _UAPI_LINUX_WIREGUARD_PARAMS_H */
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* [RFC net-next 05/14] uapi: wireguard: use __*_A_MAX in enums
2025-09-04 22:02 [RFC net-next 00/14] wireguard: netlink: ynl conversion Asbjørn Sloth Tønnesen
` (3 preceding siblings ...)
2025-09-04 22:02 ` [RFC net-next 04/14] netlink: specs: wireguard: add remaining checks Asbjørn Sloth Tønnesen
@ 2025-09-04 22:02 ` Asbjørn Sloth Tønnesen
2025-09-04 22:02 ` [RFC net-next 06/14] uapi: wireguard: move enum wg_cmd Asbjørn Sloth Tønnesen
` (9 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2025-09-04 22:02 UTC (permalink / raw)
To: Jason A. Donenfeld, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Asbjørn Sloth Tønnesen, Donald Hunter, Simon Horman,
Jacob Keller, Andrew Lunn, wireguard, netdev, linux-kernel
This patch renames enum members from __*_A_LAST to __*_A_MAX.
This is an incremental step towards adopting an UAPI header
generated by YNL.
This is a trivial patch with no behavioural changes intended.
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
include/uapi/linux/wireguard.h | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/include/uapi/linux/wireguard.h b/include/uapi/linux/wireguard.h
index dee4401e0b5d..c2bb2463211a 100644
--- a/include/uapi/linux/wireguard.h
+++ b/include/uapi/linux/wireguard.h
@@ -32,9 +32,10 @@ enum wgdevice_attribute {
WGDEVICE_A_LISTEN_PORT,
WGDEVICE_A_FWMARK,
WGDEVICE_A_PEERS,
- __WGDEVICE_A_LAST
+
+ __WGDEVICE_A_MAX
};
-#define WGDEVICE_A_MAX (__WGDEVICE_A_LAST - 1)
+#define WGDEVICE_A_MAX (__WGDEVICE_A_MAX - 1)
enum wgpeer_flag {
WGPEER_F_REMOVE_ME = 1U << 0,
@@ -55,9 +56,10 @@ enum wgpeer_attribute {
WGPEER_A_TX_BYTES,
WGPEER_A_ALLOWEDIPS,
WGPEER_A_PROTOCOL_VERSION,
- __WGPEER_A_LAST
+
+ __WGPEER_A_MAX
};
-#define WGPEER_A_MAX (__WGPEER_A_LAST - 1)
+#define WGPEER_A_MAX (__WGPEER_A_MAX - 1)
enum wgallowedip_flag {
WGALLOWEDIP_F_REMOVE_ME = 1U << 0,
@@ -69,8 +71,9 @@ enum wgallowedip_attribute {
WGALLOWEDIP_A_IPADDR,
WGALLOWEDIP_A_CIDR_MASK,
WGALLOWEDIP_A_FLAGS,
- __WGALLOWEDIP_A_LAST
+
+ __WGALLOWEDIP_A_MAX
};
-#define WGALLOWEDIP_A_MAX (__WGALLOWEDIP_A_LAST - 1)
+#define WGALLOWEDIP_A_MAX (__WGALLOWEDIP_A_MAX - 1)
#endif /* _WG_UAPI_WIREGUARD_H */
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* [RFC net-next 06/14] uapi: wireguard: move enum wg_cmd
2025-09-04 22:02 [RFC net-next 00/14] wireguard: netlink: ynl conversion Asbjørn Sloth Tønnesen
` (4 preceding siblings ...)
2025-09-04 22:02 ` [RFC net-next 05/14] uapi: wireguard: use __*_A_MAX in enums Asbjørn Sloth Tønnesen
@ 2025-09-04 22:02 ` Asbjørn Sloth Tønnesen
2025-09-04 22:02 ` [RFC net-next 07/14] uapi: wireguard: move flag enums Asbjørn Sloth Tønnesen
` (8 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2025-09-04 22:02 UTC (permalink / raw)
To: Jason A. Donenfeld, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Asbjørn Sloth Tønnesen, Donald Hunter, Simon Horman,
Jacob Keller, Andrew Lunn, wireguard, netdev, linux-kernel
This patch moves enum wg_cmd to the end of the file, where
ynl-gen would like to generate it.
This is an incremental step towards adopting an UAPI header
generated by ynl-gen.
This is a trivial patch with no behavioural changes intended.
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
include/uapi/linux/wireguard.h | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/include/uapi/linux/wireguard.h b/include/uapi/linux/wireguard.h
index c2bb2463211a..ee63aba7f98f 100644
--- a/include/uapi/linux/wireguard.h
+++ b/include/uapi/linux/wireguard.h
@@ -11,13 +11,6 @@
#define WG_KEY_LEN 32
-enum wg_cmd {
- WG_CMD_GET_DEVICE,
- WG_CMD_SET_DEVICE,
- __WG_CMD_MAX
-};
-#define WG_CMD_MAX (__WG_CMD_MAX - 1)
-
enum wgdevice_flag {
WGDEVICE_F_REPLACE_PEERS = 1U << 0,
__WGDEVICE_F_ALL = WGDEVICE_F_REPLACE_PEERS
@@ -76,4 +69,12 @@ enum wgallowedip_attribute {
};
#define WGALLOWEDIP_A_MAX (__WGALLOWEDIP_A_MAX - 1)
+enum wg_cmd {
+ WG_CMD_GET_DEVICE,
+ WG_CMD_SET_DEVICE,
+
+ __WG_CMD_MAX
+};
+#define WG_CMD_MAX (__WG_CMD_MAX - 1)
+
#endif /* _WG_UAPI_WIREGUARD_H */
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* [RFC net-next 07/14] uapi: wireguard: move flag enums
2025-09-04 22:02 [RFC net-next 00/14] wireguard: netlink: ynl conversion Asbjørn Sloth Tønnesen
` (5 preceding siblings ...)
2025-09-04 22:02 ` [RFC net-next 06/14] uapi: wireguard: move enum wg_cmd Asbjørn Sloth Tønnesen
@ 2025-09-04 22:02 ` Asbjørn Sloth Tønnesen
2025-09-04 22:02 ` [RFC net-next 08/14] uapi: wireguard: generate header with ynl-gen Asbjørn Sloth Tønnesen
` (7 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2025-09-04 22:02 UTC (permalink / raw)
To: Jason A. Donenfeld, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Asbjørn Sloth Tønnesen, Donald Hunter, Simon Horman,
Jacob Keller, Andrew Lunn, wireguard, netdev, linux-kernel
Move the wg*_flag enums, so that they are defined above the
attribute set enums, as ynl-gen would place them.
While touching these lines, also pre-compute bitshifted flag
values, like ynl-gen would generate them.
This is an incremental step towards adopting an UAPI header
generated by ynl-gen.
This is a trivial patch with no behavioural changes intended.
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
include/uapi/linux/wireguard.h | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/include/uapi/linux/wireguard.h b/include/uapi/linux/wireguard.h
index ee63aba7f98f..623ec9527e22 100644
--- a/include/uapi/linux/wireguard.h
+++ b/include/uapi/linux/wireguard.h
@@ -15,6 +15,20 @@ enum wgdevice_flag {
WGDEVICE_F_REPLACE_PEERS = 1U << 0,
__WGDEVICE_F_ALL = WGDEVICE_F_REPLACE_PEERS
};
+
+enum wgpeer_flag {
+ WGPEER_F_REMOVE_ME = 1,
+ WGPEER_F_REPLACE_ALLOWEDIPS = 2,
+ WGPEER_F_UPDATE_ONLY = 4,
+ __WGPEER_F_ALL = WGPEER_F_REMOVE_ME | WGPEER_F_REPLACE_ALLOWEDIPS |
+ WGPEER_F_UPDATE_ONLY
+};
+
+enum wgallowedip_flag {
+ WGALLOWEDIP_F_REMOVE_ME = 1,
+ __WGALLOWEDIP_F_ALL = WGALLOWEDIP_F_REMOVE_ME
+};
+
enum wgdevice_attribute {
WGDEVICE_A_UNSPEC,
WGDEVICE_A_IFINDEX,
@@ -30,13 +44,6 @@ enum wgdevice_attribute {
};
#define WGDEVICE_A_MAX (__WGDEVICE_A_MAX - 1)
-enum wgpeer_flag {
- WGPEER_F_REMOVE_ME = 1U << 0,
- WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1,
- WGPEER_F_UPDATE_ONLY = 1U << 2,
- __WGPEER_F_ALL = WGPEER_F_REMOVE_ME | WGPEER_F_REPLACE_ALLOWEDIPS |
- WGPEER_F_UPDATE_ONLY
-};
enum wgpeer_attribute {
WGPEER_A_UNSPEC,
WGPEER_A_PUBLIC_KEY,
@@ -54,10 +61,6 @@ enum wgpeer_attribute {
};
#define WGPEER_A_MAX (__WGPEER_A_MAX - 1)
-enum wgallowedip_flag {
- WGALLOWEDIP_F_REMOVE_ME = 1U << 0,
- __WGALLOWEDIP_F_ALL = WGALLOWEDIP_F_REMOVE_ME
-};
enum wgallowedip_attribute {
WGALLOWEDIP_A_UNSPEC,
WGALLOWEDIP_A_FAMILY,
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* [RFC net-next 08/14] uapi: wireguard: generate header with ynl-gen
2025-09-04 22:02 [RFC net-next 00/14] wireguard: netlink: ynl conversion Asbjørn Sloth Tønnesen
` (6 preceding siblings ...)
2025-09-04 22:02 ` [RFC net-next 07/14] uapi: wireguard: move flag enums Asbjørn Sloth Tønnesen
@ 2025-09-04 22:02 ` Asbjørn Sloth Tønnesen
2025-09-04 22:02 ` [RFC net-next 09/14] wireguard: netlink: convert to split ops Asbjørn Sloth Tønnesen
` (6 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2025-09-04 22:02 UTC (permalink / raw)
To: Jason A. Donenfeld, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Asbjørn Sloth Tønnesen, Donald Hunter, Simon Horman,
Jacob Keller, Andrew Lunn, wireguard, netdev, linux-kernel
Use ynl-gen to generate the UAPI header for wireguard.
Changes in generated header:
* As __*_F_ALL are not generated by ynl-gen:
* All users have been replaced by their current value.
* Once the policies are also generated, then the
NLA_POLICY_MASK() policies will be kept in sync.
* Convert the last bit-shifted flag value in enum wgdevice_flag.
* Trivial include guard rename.
* Trivial white space changes.
No behavioural changes intended.
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
drivers/net/wireguard/netlink.c | 6 +++---
include/uapi/linux/wireguard.h | 26 +++++++++++---------------
2 files changed, 14 insertions(+), 18 deletions(-)
diff --git a/drivers/net/wireguard/netlink.c b/drivers/net/wireguard/netlink.c
index 742d3f88d132..5dae2aa51346 100644
--- a/drivers/net/wireguard/netlink.c
+++ b/drivers/net/wireguard/netlink.c
@@ -24,7 +24,7 @@ static const struct nla_policy device_policy[WGDEVICE_A_MAX + 1] = {
[WGDEVICE_A_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 },
[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, __WGDEVICE_F_ALL),
+ [WGDEVICE_A_FLAGS] = NLA_POLICY_MASK(NLA_U32, 1),
[WGDEVICE_A_LISTEN_PORT] = { .type = NLA_U16 },
[WGDEVICE_A_FWMARK] = { .type = NLA_U32 },
[WGDEVICE_A_PEERS] = NLA_POLICY_NESTED_ARRAY(peer_policy),
@@ -33,7 +33,7 @@ static const struct nla_policy device_policy[WGDEVICE_A_MAX + 1] = {
static const struct nla_policy peer_policy[WGPEER_A_MAX + 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, __WGPEER_F_ALL),
+ [WGPEER_A_FLAGS] = NLA_POLICY_MASK(NLA_U32, 7),
[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)),
@@ -47,7 +47,7 @@ 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),
+ [WGALLOWEDIP_A_FLAGS] = NLA_POLICY_MASK(NLA_U32, 1),
};
static struct wg_device *lookup_interface(struct nlattr **attrs,
diff --git a/include/uapi/linux/wireguard.h b/include/uapi/linux/wireguard.h
index 623ec9527e22..b83973aed9f8 100644
--- a/include/uapi/linux/wireguard.h
+++ b/include/uapi/linux/wireguard.h
@@ -1,32 +1,28 @@
-/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT */
-/*
- * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
- */
+/* 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 uapi header */
-#ifndef _WG_UAPI_WIREGUARD_H
-#define _WG_UAPI_WIREGUARD_H
+#ifndef _UAPI_LINUX_WIREGUARD_H
+#define _UAPI_LINUX_WIREGUARD_H
-#define WG_GENL_NAME "wireguard"
-#define WG_GENL_VERSION 1
+#define WG_GENL_NAME "wireguard"
+#define WG_GENL_VERSION 1
-#define WG_KEY_LEN 32
+#define WG_KEY_LEN 32
enum wgdevice_flag {
- WGDEVICE_F_REPLACE_PEERS = 1U << 0,
- __WGDEVICE_F_ALL = WGDEVICE_F_REPLACE_PEERS
+ WGDEVICE_F_REPLACE_PEERS = 1,
};
enum wgpeer_flag {
WGPEER_F_REMOVE_ME = 1,
WGPEER_F_REPLACE_ALLOWEDIPS = 2,
WGPEER_F_UPDATE_ONLY = 4,
- __WGPEER_F_ALL = WGPEER_F_REMOVE_ME | WGPEER_F_REPLACE_ALLOWEDIPS |
- WGPEER_F_UPDATE_ONLY
};
enum wgallowedip_flag {
WGALLOWEDIP_F_REMOVE_ME = 1,
- __WGALLOWEDIP_F_ALL = WGALLOWEDIP_F_REMOVE_ME
};
enum wgdevice_attribute {
@@ -80,4 +76,4 @@ enum wg_cmd {
};
#define WG_CMD_MAX (__WG_CMD_MAX - 1)
-#endif /* _WG_UAPI_WIREGUARD_H */
+#endif /* _UAPI_LINUX_WIREGUARD_H */
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* [RFC net-next 09/14] wireguard: netlink: convert to split ops
2025-09-04 22:02 [RFC net-next 00/14] wireguard: netlink: ynl conversion Asbjørn Sloth Tønnesen
` (7 preceding siblings ...)
2025-09-04 22:02 ` [RFC net-next 08/14] uapi: wireguard: generate header with ynl-gen Asbjørn Sloth Tønnesen
@ 2025-09-04 22:02 ` Asbjørn Sloth Tønnesen
2025-09-04 22:02 ` [RFC net-next 10/14] wireguard: netlink: rename netlink handlers Asbjørn Sloth Tønnesen
` (5 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2025-09-04 22:02 UTC (permalink / raw)
To: Jason A. Donenfeld, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Asbjørn Sloth Tønnesen, Donald Hunter, Simon Horman,
Jacob Keller, Andrew Lunn, wireguard, netdev, linux-kernel
This patch converts wireguard from using legacy struct genl_ops
to struct genl_split_ops, by applying the same transformation
as genl_cmd_full_to_split() does.
WGDEVICE_A_MAX is swapped for WGDEVICE_A_PEERS, which is
currently equivalent and is what ynl-gen would generate.
This is an incremental step towards adopting netlink policy
code generated by ynl-gen.
This is a trivial patch with no behavioural changes intended.
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
drivers/net/wireguard/netlink.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireguard/netlink.c b/drivers/net/wireguard/netlink.c
index 5dae2aa51346..1311f64d9fcf 100644
--- a/drivers/net/wireguard/netlink.c
+++ b/drivers/net/wireguard/netlink.c
@@ -614,29 +614,31 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
return ret;
}
-static const struct genl_ops genl_ops[] = {
+static const struct genl_split_ops wireguard_nl_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
+ .policy = device_policy,
+ .maxattr = WGDEVICE_A_PEERS,
+ .flags = GENL_UNS_ADMIN_PERM | GENL_CMD_CAP_DUMP,
}, {
.cmd = WG_CMD_SET_DEVICE,
.doit = wg_set_device,
- .flags = GENL_UNS_ADMIN_PERM
+ .policy = device_policy,
+ .maxattr = WGDEVICE_A_PEERS,
+ .flags = GENL_UNS_ADMIN_PERM | GENL_CMD_CAP_DO,
}
};
static struct genl_family genl_family __ro_after_init = {
- .ops = genl_ops,
- .n_ops = ARRAY_SIZE(genl_ops),
+ .split_ops = wireguard_nl_ops,
+ .n_split_ops = ARRAY_SIZE(wireguard_nl_ops),
.resv_start_op = WG_CMD_SET_DEVICE + 1,
.name = WG_GENL_NAME,
.version = WG_GENL_VERSION,
- .maxattr = WGDEVICE_A_MAX,
.module = THIS_MODULE,
- .policy = device_policy,
.netnsok = true
};
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* [RFC net-next 10/14] wireguard: netlink: rename netlink handlers
2025-09-04 22:02 [RFC net-next 00/14] wireguard: netlink: ynl conversion Asbjørn Sloth Tønnesen
` (8 preceding siblings ...)
2025-09-04 22:02 ` [RFC net-next 09/14] wireguard: netlink: convert to split ops Asbjørn Sloth Tønnesen
@ 2025-09-04 22:02 ` Asbjørn Sloth Tønnesen
2025-09-04 22:02 ` [RFC net-next 11/14] wireguard: netlink: generate netlink code Asbjørn Sloth Tønnesen
` (4 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2025-09-04 22:02 UTC (permalink / raw)
To: Jason A. Donenfeld, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Asbjørn Sloth Tønnesen, Donald Hunter, Simon Horman,
Jacob Keller, Andrew Lunn, wireguard, netdev, linux-kernel
Rename netlink handlers to use the naming expected by ynl-gen.
This is an incremental step towards adopting netlink command
definitions generated by ynl-gen.
This is a trivial patch with no behavioural changes intended.
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
drivers/net/wireguard/netlink.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireguard/netlink.c b/drivers/net/wireguard/netlink.c
index 1311f64d9fcf..a61e1c5c7850 100644
--- a/drivers/net/wireguard/netlink.c
+++ b/drivers/net/wireguard/netlink.c
@@ -197,7 +197,7 @@ get_peer(struct wg_peer *peer, struct sk_buff *skb, struct dump_ctx *ctx)
return -EMSGSIZE;
}
-static int wg_get_device_start(struct netlink_callback *cb)
+static int wireguard_nl_get_device_start(struct netlink_callback *cb)
{
struct wg_device *wg;
@@ -208,7 +208,8 @@ 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)
+static int wireguard_nl_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 +303,7 @@ static int wg_get_device_dump(struct sk_buff *skb, struct netlink_callback *cb)
*/
}
-static int wg_get_device_done(struct netlink_callback *cb)
+static int wireguard_nl_get_device_done(struct netlink_callback *cb)
{
struct dump_ctx *ctx = DUMP_CTX(cb);
@@ -500,7 +501,8 @@ static int set_peer(struct wg_device *wg, struct nlattr **attrs)
return ret;
}
-static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
+static int wireguard_nl_set_device_doit(struct sk_buff *skb,
+ struct genl_info *info)
{
struct wg_device *wg = lookup_interface(info->attrs, skb);
u32 flags = 0;
@@ -617,15 +619,15 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
static const struct genl_split_ops wireguard_nl_ops[] = {
{
.cmd = WG_CMD_GET_DEVICE,
- .start = wg_get_device_start,
- .dumpit = wg_get_device_dump,
- .done = wg_get_device_done,
+ .start = wireguard_nl_get_device_start,
+ .dumpit = wireguard_nl_get_device_dumpit,
+ .done = wireguard_nl_get_device_done,
.policy = device_policy,
.maxattr = WGDEVICE_A_PEERS,
.flags = GENL_UNS_ADMIN_PERM | GENL_CMD_CAP_DUMP,
}, {
.cmd = WG_CMD_SET_DEVICE,
- .doit = wg_set_device,
+ .doit = wireguard_nl_set_device_doit,
.policy = device_policy,
.maxattr = WGDEVICE_A_PEERS,
.flags = GENL_UNS_ADMIN_PERM | GENL_CMD_CAP_DO,
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* [RFC net-next 11/14] wireguard: netlink: generate netlink code
2025-09-04 22:02 [RFC net-next 00/14] wireguard: netlink: ynl conversion Asbjørn Sloth Tønnesen
` (9 preceding siblings ...)
2025-09-04 22:02 ` [RFC net-next 10/14] wireguard: netlink: rename netlink handlers Asbjørn Sloth Tønnesen
@ 2025-09-04 22:02 ` Asbjørn Sloth Tønnesen
2025-09-04 22:02 ` [RFC net-next 12/14] netlink: specs: wireguard: alternative to wireguard_params.h Asbjørn Sloth Tønnesen
` (3 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2025-09-04 22:02 UTC (permalink / raw)
To: Jason A. Donenfeld, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Asbjørn Sloth Tønnesen, Donald Hunter, Simon Horman,
Jacob Keller, Andrew Lunn, wireguard, netdev, linux-kernel
This patch adopts netlink policy and command definitions
as generated by ynl-gen.
No behavioural changes intended.
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
drivers/net/wireguard/Makefile | 1 +
drivers/net/wireguard/netlink.c | 69 +++++--------------------
drivers/net/wireguard/netlink_gen.c | 78 +++++++++++++++++++++++++++++
drivers/net/wireguard/netlink_gen.h | 30 +++++++++++
4 files changed, 121 insertions(+), 57 deletions(-)
create mode 100644 drivers/net/wireguard/netlink_gen.c
create mode 100644 drivers/net/wireguard/netlink_gen.h
diff --git a/drivers/net/wireguard/Makefile b/drivers/net/wireguard/Makefile
index dbe1f8514efc..ae4b479cddbd 100644
--- a/drivers/net/wireguard/Makefile
+++ b/drivers/net/wireguard/Makefile
@@ -14,4 +14,5 @@ wireguard-y += allowedips.o
wireguard-y += ratelimiter.o
wireguard-y += cookie.o
wireguard-y += netlink.o
+wireguard-y += netlink_gen.o
obj-$(CONFIG_WIREGUARD) := wireguard.o
diff --git a/drivers/net/wireguard/netlink.c b/drivers/net/wireguard/netlink.c
index a61e1c5c7850..0e34817126b9 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 "netlink_gen.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(WG_KEY_LEN),
- [WGDEVICE_A_PUBLIC_KEY] = NLA_POLICY_EXACT_LEN(WG_KEY_LEN),
- [WGDEVICE_A_FLAGS] = NLA_POLICY_MASK(NLA_U32, 1),
- [WGDEVICE_A_LISTEN_PORT] = { .type = NLA_U16 },
- [WGDEVICE_A_FWMARK] = { .type = NLA_U32 },
- [WGDEVICE_A_PEERS] = NLA_POLICY_NESTED_ARRAY(peer_policy),
-};
-
-static const struct nla_policy peer_policy[WGPEER_A_MAX + 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, 7),
- [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] = NLA_POLICY_NESTED_ARRAY(allowedip_policy),
- [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, 1),
-};
-
static struct wg_device *lookup_interface(struct nlattr **attrs,
struct sk_buff *skb)
{
@@ -197,7 +167,7 @@ get_peer(struct wg_peer *peer, struct sk_buff *skb, struct dump_ctx *ctx)
return -EMSGSIZE;
}
-static int wireguard_nl_get_device_start(struct netlink_callback *cb)
+int wireguard_nl_get_device_start(struct netlink_callback *cb)
{
struct wg_device *wg;
@@ -208,8 +178,8 @@ static int wireguard_nl_get_device_start(struct netlink_callback *cb)
return 0;
}
-static int wireguard_nl_get_device_dumpit(struct sk_buff *skb,
- struct netlink_callback *cb)
+int wireguard_nl_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);
@@ -303,7 +273,7 @@ static int wireguard_nl_get_device_dumpit(struct sk_buff *skb,
*/
}
-static int wireguard_nl_get_device_done(struct netlink_callback *cb)
+int wireguard_nl_get_device_done(struct netlink_callback *cb)
{
struct dump_ctx *ctx = DUMP_CTX(cb);
@@ -468,7 +438,9 @@ 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,
+ wireguard_wgallowedip_nl_policy,
+ NULL);
if (ret < 0)
goto out;
ret = set_allowedip(peer, allowedip);
@@ -501,8 +473,8 @@ static int set_peer(struct wg_device *wg, struct nlattr **attrs)
return ret;
}
-static int wireguard_nl_set_device_doit(struct sk_buff *skb,
- struct genl_info *info)
+int wireguard_nl_set_device_doit(struct sk_buff *skb,
+ struct genl_info *info)
{
struct wg_device *wg = lookup_interface(info->attrs, skb);
u32 flags = 0;
@@ -595,7 +567,8 @@ static int wireguard_nl_set_device_doit(struct sk_buff *skb,
nla_for_each_nested(attr, info->attrs[WGDEVICE_A_PEERS], rem) {
ret = nla_parse_nested(peer, WGPEER_A_MAX, attr,
- peer_policy, NULL);
+ wireguard_wgpeer_nl_policy,
+ NULL);
if (ret < 0)
goto out;
ret = set_peer(wg, peer);
@@ -616,24 +589,6 @@ static int wireguard_nl_set_device_doit(struct sk_buff *skb,
return ret;
}
-static const struct genl_split_ops wireguard_nl_ops[] = {
- {
- .cmd = WG_CMD_GET_DEVICE,
- .start = wireguard_nl_get_device_start,
- .dumpit = wireguard_nl_get_device_dumpit,
- .done = wireguard_nl_get_device_done,
- .policy = device_policy,
- .maxattr = WGDEVICE_A_PEERS,
- .flags = GENL_UNS_ADMIN_PERM | GENL_CMD_CAP_DUMP,
- }, {
- .cmd = WG_CMD_SET_DEVICE,
- .doit = wireguard_nl_set_device_doit,
- .policy = device_policy,
- .maxattr = WGDEVICE_A_PEERS,
- .flags = GENL_UNS_ADMIN_PERM | GENL_CMD_CAP_DO,
- }
-};
-
static struct genl_family genl_family __ro_after_init = {
.split_ops = wireguard_nl_ops,
.n_split_ops = ARRAY_SIZE(wireguard_nl_ops),
diff --git a/drivers/net/wireguard/netlink_gen.c b/drivers/net/wireguard/netlink_gen.c
new file mode 100644
index 000000000000..75f5b4b297a9
--- /dev/null
+++ b/drivers/net/wireguard/netlink_gen.c
@@ -0,0 +1,78 @@
+// 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 */
+
+#include <net/netlink.h>
+#include <net/genetlink.h>
+
+#include "netlink_gen.h"
+
+#include <uapi/linux/wireguard.h>
+#include <linux/wireguard_params.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(__WG_INADDR_SZ),
+ [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(__WG_SOCKADDR_SZ),
+ [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NLA_U16, },
+ [WGPEER_A_LAST_HANDSHAKE_TIME] = NLA_POLICY_EXACT_LEN(__WG_TIMESPEC_SZ),
+ [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_PEERS + 1] = {
+ [WGDEVICE_A_IFINDEX] = { .type = NLA_U32, },
+ [WGDEVICE_A_IFNAME] = { .type = NLA_NUL_STRING, .len = __WG_IFNAMLEN, },
+ [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),
+};
+
+/* 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 = __WG_IFNAMLEN, },
+ [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 = wireguard_nl_get_device_start,
+ .dumpit = wireguard_nl_get_device_dumpit,
+ .done = wireguard_nl_get_device_done,
+ .policy = wireguard_get_device_nl_policy,
+ .maxattr = WGDEVICE_A_PEERS,
+ .flags = GENL_UNS_ADMIN_PERM | GENL_CMD_CAP_DUMP,
+ },
+ {
+ .cmd = WG_CMD_SET_DEVICE,
+ .doit = wireguard_nl_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/netlink_gen.h b/drivers/net/wireguard/netlink_gen.h
new file mode 100644
index 000000000000..a067ab0d61b6
--- /dev/null
+++ b/drivers/net/wireguard/netlink_gen.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 */
+
+#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/wireguard_params.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 wireguard_nl_get_device_start(struct netlink_callback *cb);
+int wireguard_nl_get_device_done(struct netlink_callback *cb);
+
+int wireguard_nl_get_device_dumpit(struct sk_buff *skb,
+ struct netlink_callback *cb);
+int wireguard_nl_set_device_doit(struct sk_buff *skb, struct genl_info *info);
+
+#endif /* _LINUX_WIREGUARD_GEN_H */
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* [RFC net-next 12/14] netlink: specs: wireguard: alternative to wireguard_params.h
2025-09-04 22:02 [RFC net-next 00/14] wireguard: netlink: ynl conversion Asbjørn Sloth Tønnesen
` (10 preceding siblings ...)
2025-09-04 22:02 ` [RFC net-next 11/14] wireguard: netlink: generate netlink code Asbjørn Sloth Tønnesen
@ 2025-09-04 22:02 ` Asbjørn Sloth Tønnesen
2025-09-04 22:02 ` [RFC net-next 13/14] wireguard: netlink: enable strict genetlink validation Asbjørn Sloth Tønnesen
` (2 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2025-09-04 22:02 UTC (permalink / raw)
To: Jason A. Donenfeld, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Asbjørn Sloth Tønnesen, Donald Hunter, Simon Horman,
Jacob Keller, Andrew Lunn, wireguard, netdev, linux-kernel
This is an alternative to the approach taken in patch 04,
Use magic constants in C as well, and thereby obfuscate
their origin.
If this is preferred then I will split and squash this
patch into the previous commits, so that it's done like
this in the original specification patch.
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
Documentation/netlink/specs/wireguard.yaml | 36 +++-------------------
drivers/net/wireguard/netlink_gen.c | 11 +++----
drivers/net/wireguard/netlink_gen.h | 1 -
include/uapi/linux/wireguard_params.h | 18 -----------
4 files changed, 9 insertions(+), 57 deletions(-)
delete mode 100644 include/uapi/linux/wireguard_params.h
diff --git a/Documentation/netlink/specs/wireguard.yaml b/Documentation/netlink/specs/wireguard.yaml
index 37011c3f158b..bb44171d9ac5 100644
--- a/Documentation/netlink/specs/wireguard.yaml
+++ b/Documentation/netlink/specs/wireguard.yaml
@@ -21,34 +21,6 @@ definitions:
name: key-len
type: const
value: 32
- -
- name-prefix: --wg-
- name: inaddr-sz
- type: const
- doc: Equivalent of ``sizeof(struct in_addr)``.
- header: linux/wireguard_params.h
- value: 4
- -
- name-prefix: --wg-
- name: sockaddr-sz
- type: const
- doc: Equivalent of ``sizeof(struct sockaddr)``.
- header: linux/wireguard_params.h
- value: 16
- -
- name-prefix: --wg-
- name: timespec-sz
- type: const
- doc: Equivalent of ``sizeof(struct __kernel_timespec)``.
- header: linux/wireguard_params.h
- value: 16
- -
- name-prefix: --wg-
- name: ifnamlen
- type: const
- doc: Equivalent of ``IFNAMSIZ - 1``.
- header: linux/wireguard_params.h
- value: 15
-
name: --kernel-timespec
type: struct
@@ -103,7 +75,7 @@ attribute-sets:
name: ifname
type: string
checks:
- max-len: --wg-ifnamlen
+ max-len: 15
-
name: private-key
type: binary
@@ -179,7 +151,7 @@ attribute-sets:
doc: struct sockaddr_in or struct sockaddr_in6
type: binary
checks:
- min-len: --wg-sockaddr-sz
+ min-len: 16
-
name: persistent-keepalive-interval
type: u16
@@ -189,7 +161,7 @@ attribute-sets:
type: binary
struct: --kernel-timespec
checks:
- exact-len: --wg-timespec-sz
+ exact-len: 16
-
name: rx-bytes
type: u64
@@ -226,7 +198,7 @@ attribute-sets:
doc: struct in_addr or struct in6_add
display-hint: ipv4-or-v6
checks:
- min-len: --wg-inaddr-sz
+ min-len: 4
-
name: cidr-mask
type: u8
diff --git a/drivers/net/wireguard/netlink_gen.c b/drivers/net/wireguard/netlink_gen.c
index 75f5b4b297a9..f95fa133778f 100644
--- a/drivers/net/wireguard/netlink_gen.c
+++ b/drivers/net/wireguard/netlink_gen.c
@@ -9,13 +9,12 @@
#include "netlink_gen.h"
#include <uapi/linux/wireguard.h>
-#include <linux/wireguard_params.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(__WG_INADDR_SZ),
+ [WGALLOWEDIP_A_IPADDR] = NLA_POLICY_MIN_LEN(4),
[WGALLOWEDIP_A_CIDR_MASK] = { .type = NLA_U8, },
[WGALLOWEDIP_A_FLAGS] = NLA_POLICY_MASK(NLA_U32, 0x1),
};
@@ -24,9 +23,9 @@ 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(__WG_SOCKADDR_SZ),
+ [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(__WG_TIMESPEC_SZ),
+ [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),
@@ -36,7 +35,7 @@ const struct nla_policy wireguard_wgpeer_nl_policy[WGPEER_A_PROTOCOL_VERSION + 1
/* WG_CMD_GET_DEVICE - dump */
static const struct nla_policy wireguard_get_device_nl_policy[WGDEVICE_A_PEERS + 1] = {
[WGDEVICE_A_IFINDEX] = { .type = NLA_U32, },
- [WGDEVICE_A_IFNAME] = { .type = NLA_NUL_STRING, .len = __WG_IFNAMLEN, },
+ [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),
@@ -48,7 +47,7 @@ static const struct nla_policy wireguard_get_device_nl_policy[WGDEVICE_A_PEERS +
/* 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 = __WG_IFNAMLEN, },
+ [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),
diff --git a/drivers/net/wireguard/netlink_gen.h b/drivers/net/wireguard/netlink_gen.h
index a067ab0d61b6..e635b1f5f0df 100644
--- a/drivers/net/wireguard/netlink_gen.h
+++ b/drivers/net/wireguard/netlink_gen.h
@@ -10,7 +10,6 @@
#include <net/genetlink.h>
#include <uapi/linux/wireguard.h>
-#include <linux/wireguard_params.h>
#include <linux/time_types.h>
/* Common nested types */
diff --git a/include/uapi/linux/wireguard_params.h b/include/uapi/linux/wireguard_params.h
deleted file mode 100644
index c218e4b8042f..000000000000
--- a/include/uapi/linux/wireguard_params.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
-
-#ifndef _UAPI_LINUX_WIREGUARD_PARAMS_H
-#define _UAPI_LINUX_WIREGUARD_PARAMS_H
-
-#include <linux/time_types.h>
-#include <linux/if.h>
-#include <linux/in.h>
-
-/* These definitions are currently needed for definitions which can't
- * be expressed directly in Documentation/netlink/specs/wireguard.yaml
- */
-#define __WG_INADDR_SZ (sizeof(struct in_addr))
-#define __WG_SOCKADDR_SZ (sizeof(struct sockaddr))
-#define __WG_TIMESPEC_SZ (sizeof(struct __kernel_timespec))
-#define __WG_IFNAMLEN (IFNAMSIZ - 1)
-
-#endif /* _UAPI_LINUX_WIREGUARD_PARAMS_H */
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* [RFC net-next 13/14] wireguard: netlink: enable strict genetlink validation
2025-09-04 22:02 [RFC net-next 00/14] wireguard: netlink: ynl conversion Asbjørn Sloth Tønnesen
` (11 preceding siblings ...)
2025-09-04 22:02 ` [RFC net-next 12/14] netlink: specs: wireguard: alternative to wireguard_params.h Asbjørn Sloth Tønnesen
@ 2025-09-04 22:02 ` Asbjørn Sloth Tønnesen
2025-09-04 22:02 ` [RFC net-next 14/14] tools: ynl: add sample for wireguard Asbjørn Sloth Tønnesen
2025-09-16 15:51 ` [RFC net-next 00/14] wireguard: netlink: ynl conversion Jason A. Donenfeld
14 siblings, 0 replies; 17+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2025-09-04 22:02 UTC (permalink / raw)
To: Jason A. Donenfeld, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Asbjørn Sloth Tønnesen, Donald Hunter, Simon Horman,
Jacob Keller, Andrew Lunn, wireguard, netdev, linux-kernel
Wireguard is a modern enough genetlink family, that it doesn't
need resv_start_op. It already had policies in place when it was
first merged, it has also never used reserved fields, or other
things toggled by resv_start_op.
[TODO: before v1, also test with ancient wireguard-tools versions]
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
drivers/net/wireguard/netlink.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/net/wireguard/netlink.c b/drivers/net/wireguard/netlink.c
index 0e34817126b9..67c448eef25d 100644
--- a/drivers/net/wireguard/netlink.c
+++ b/drivers/net/wireguard/netlink.c
@@ -592,7 +592,6 @@ int wireguard_nl_set_device_doit(struct sk_buff *skb,
static struct genl_family genl_family __ro_after_init = {
.split_ops = wireguard_nl_ops,
.n_split_ops = ARRAY_SIZE(wireguard_nl_ops),
- .resv_start_op = WG_CMD_SET_DEVICE + 1,
.name = WG_GENL_NAME,
.version = WG_GENL_VERSION,
.module = THIS_MODULE,
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* [RFC net-next 14/14] tools: ynl: add sample for wireguard
2025-09-04 22:02 [RFC net-next 00/14] wireguard: netlink: ynl conversion Asbjørn Sloth Tønnesen
` (12 preceding siblings ...)
2025-09-04 22:02 ` [RFC net-next 13/14] wireguard: netlink: enable strict genetlink validation Asbjørn Sloth Tønnesen
@ 2025-09-04 22:02 ` Asbjørn Sloth Tønnesen
2025-09-16 15:51 ` [RFC net-next 00/14] wireguard: netlink: ynl conversion Jason A. Donenfeld
14 siblings, 0 replies; 17+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2025-09-04 22:02 UTC (permalink / raw)
To: Jason A. Donenfeld, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Asbjørn Sloth Tønnesen, Donald Hunter, Simon Horman,
Jacob Keller, Andrew Lunn, wireguard, netdev, linux-kernel
Add a sample application using the generated C library.
Example:
[install uapi headers, then]
$ make -C tools/net/ynl/lib
$ make -C tools/net/ynl/generated
$ make -C tools/net/ynl/samples wireguard
$ ./tools/net/ynl/samples/wireguard
usage: ./tools/net/ynl/samples/wireguard <ifindex|ifname>
$ sudo ./tools/net/ynl/samples/wireguard wg-test
Interface 3: wg-test
Peer 6adfb183a4a2c94a2f92dab5ade762a4788[...]:
Data: rx: 42 / tx: 42 bytes
Allowed IPs:
0.0.0.0/0
::/0
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
MAINTAINERS | 1 +
tools/net/ynl/samples/.gitignore | 1 +
tools/net/ynl/samples/wireguard.c | 104 ++++++++++++++++++++++++++++++
3 files changed, 106 insertions(+)
create mode 100644 tools/net/ynl/samples/wireguard.c
diff --git a/MAINTAINERS b/MAINTAINERS
index e8360e4b55c6..dafc374b25d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -27171,6 +27171,7 @@ S: Maintained
F: Documentation/netlink/specs/wireguard.yaml
F: drivers/net/wireguard/
F: include/uapi/linux/wireguard_params.h
+F: tools/net/ynl/samples/wireguard.c
F: tools/testing/selftests/wireguard/
WISTRON LAPTOP BUTTON DRIVER
diff --git a/tools/net/ynl/samples/.gitignore b/tools/net/ynl/samples/.gitignore
index 7f5fca7682d7..09c61e4c18cd 100644
--- a/tools/net/ynl/samples/.gitignore
+++ b/tools/net/ynl/samples/.gitignore
@@ -7,3 +7,4 @@ rt-addr
rt-link
rt-route
tc
+wireguard
diff --git a/tools/net/ynl/samples/wireguard.c b/tools/net/ynl/samples/wireguard.c
new file mode 100644
index 000000000000..f1549e585949
--- /dev/null
+++ b/tools/net/ynl/samples/wireguard.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <arpa/inet.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <ynl.h>
+
+#include "wireguard-user.h"
+
+static void print_allowed_ip(const struct wireguard_wgallowedip *aip)
+{
+ char addr_out[INET6_ADDRSTRLEN];
+
+ if (!inet_ntop(aip->family, aip->ipaddr, addr_out, sizeof(addr_out))) {
+ addr_out[0] = '?';
+ addr_out[1] = '\0';
+ }
+ printf("\t\t\t%s/%u\n", addr_out, aip->cidr_mask);
+}
+
+/* Only printing public key in this demo. For better key formatting,
+ * use constant-time implementation as found in wireguard-tools.
+ */
+static void print_peer_header(const struct wireguard_wgpeer *peer)
+{
+ unsigned int i;
+ uint8_t *key = peer->public_key;
+ unsigned int len = peer->_len.public_key;
+
+ if (len != 32)
+ return;
+ printf("\tPeer ");
+ for (i = 0; i < len; i++)
+ printf("%02x", key[i]);
+ printf(":\n");
+}
+
+static void print_peer(const struct wireguard_wgpeer *peer)
+{
+ unsigned int i;
+
+ print_peer_header(peer);
+ printf("\t\tData: rx: %llu / tx: %llu bytes\n",
+ peer->rx_bytes, peer->tx_bytes);
+ printf("\t\tAllowed IPs:\n");
+ for (i = 0; i < peer->_count.allowedips; i++)
+ print_allowed_ip(&peer->allowedips[i]);
+}
+
+static void build_request(struct wireguard_get_device_req *req, char *arg)
+{
+ char *endptr;
+ int ifindex;
+
+ ifindex = strtol(arg, &endptr, 0);
+ if (endptr != arg + strlen(arg) || errno != 0)
+ ifindex = 0;
+ if (ifindex > 0)
+ wireguard_get_device_req_set_ifindex(req, ifindex);
+ else
+ wireguard_get_device_req_set_ifname(req, arg);
+}
+
+int main(int argc, char **argv)
+{
+ struct wireguard_get_device_list *devs;
+ struct wireguard_get_device_req *req;
+ struct ynl_sock *ys;
+
+ if (argc < 2) {
+ fprintf(stderr, "usage: %s <ifindex|ifname>\n", argv[0]);
+ return 1;
+ }
+
+ req = wireguard_get_device_req_alloc();
+ build_request(req, argv[1]);
+
+ ys = ynl_sock_create(&ynl_wireguard_family, NULL);
+ if (!ys)
+ return 2;
+
+ devs = wireguard_get_device_dump(ys, req);
+ if (!devs)
+ goto err_close;
+
+ ynl_dump_foreach(devs, d) {
+ unsigned int i;
+
+ printf("Interface %d: %s\n", d->ifindex, d->ifname);
+ for (i = 0; i < d->_count.peers; i++)
+ print_peer(&d->peers[i]);
+ }
+ wireguard_get_device_list_free(devs);
+ wireguard_get_device_req_free(req);
+ ynl_sock_destroy(ys);
+
+ return 0;
+
+err_close:
+ fprintf(stderr, "YNL (%d): %s\n", ys->err.code, ys->err.msg);
+ wireguard_get_device_req_free(req);
+ ynl_sock_destroy(ys);
+ return 3;
+}
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [RFC net-next 00/14] wireguard: netlink: ynl conversion
2025-09-04 22:02 [RFC net-next 00/14] wireguard: netlink: ynl conversion Asbjørn Sloth Tønnesen
` (13 preceding siblings ...)
2025-09-04 22:02 ` [RFC net-next 14/14] tools: ynl: add sample for wireguard Asbjørn Sloth Tønnesen
@ 2025-09-16 15:51 ` Jason A. Donenfeld
2025-09-17 11:52 ` Asbjørn Sloth Tønnesen
14 siblings, 1 reply; 17+ messages in thread
From: Jason A. Donenfeld @ 2025-09-16 15:51 UTC (permalink / raw)
To: Asbjørn Sloth Tønnesen
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Donald Hunter, Simon Horman, Jacob Keller, Andrew Lunn, wireguard,
netdev, linux-kernel
Hi Asbjorn,
On Fri, Sep 5, 2025 at 12:03 AM Asbjørn Sloth Tønnesen <ast@fiberby.net> wrote:
>
> This series contains the wireguard changes needed to adopt
> an YNL-based generated netlink code.
>
> This RFC series is posted for reference, as it is referenced
> from the current v1 series of ynl preparations, which has to
> go in before this series can be submitted for net-next.
I'm not actually convinced this makes anything better. It seems like
the code becomes more complicated and less obvious. What is the
benefit here? As is, I really don't like this direction.
Jason
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [RFC net-next 00/14] wireguard: netlink: ynl conversion
2025-09-16 15:51 ` [RFC net-next 00/14] wireguard: netlink: ynl conversion Jason A. Donenfeld
@ 2025-09-17 11:52 ` Asbjørn Sloth Tønnesen
0 siblings, 0 replies; 17+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2025-09-17 11:52 UTC (permalink / raw)
To: Jason A. Donenfeld
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Donald Hunter, Simon Horman, Jacob Keller, Andrew Lunn, wireguard,
netdev, linux-kernel
On 9/16/25 3:51 PM, Jason A. Donenfeld wrote:
> On Fri, Sep 5, 2025 at 12:03 AM Asbjørn Sloth Tønnesen <ast@fiberby.net> wrote:
>>
>> This series contains the wireguard changes needed to adopt
>> an YNL-based generated netlink code.
>>
>> This RFC series is posted for reference, as it is referenced
>> from the current v1 series of ynl preparations, which has to
>> go in before this series can be submitted for net-next.
>
> I'm not actually convinced this makes anything better. It seems like
> the code becomes more complicated and less obvious. What is the
> benefit here? As is, I really don't like this direction.
By adding an YNL spec, we lower the barrier for implementing and
using the protocol especially from non-C languages.
The specs are currently used for:
- Documentation generation [1].
- Optional UAPI header generation.
- Optional kernel netlink code generation.
- In-tree user-space clients:
- Auto-generated C library code.
- Optional sample program using above C library.
- Python client - ./tools/net/ynl/pyynl/cli.py.
The generated kernel code is still committed in git,
and is thus protected from accidental changes.
When we can generate the UAPI from the spec., with only cosmetic
differences it proves that the spec is correct. Same goes for generating
the netlink policy generation.
I have split up adopting the generated UAPI and netlink code, over many
patches mostly to keep the diff readable, as the code moves would
otherwise become interlaced.
Including a sample program, makes it trivial to exercise the generated
C library.
This RFC is a bit more complicated, than v1 will be, as it includes an
alternative implementation for patch 4 in patch 12, I had hoped those
patches would have generated some comments. Right now it looks like,
they will both be squashed into patch 3 in v1.
I can also split this series up further, if you would prefer that.
[1] https://docs.kernel.org/networking/netlink_spec/
^ permalink raw reply [flat|nested] 17+ messages in thread