WireGuard Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH wireguard-tools v4 0/3] ipc: linux: kernel-side netdevice filtering
@ 2026-03-12 21:43 Asbjørn Sloth Tønnesen
  2026-03-12 21:43 ` [PATCH wireguard-tools v4 1/3] ipc: linux: filter netdevices kernel-side Asbjørn Sloth Tønnesen
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2026-03-12 21:43 UTC (permalink / raw)
  To: Jason A . Donenfeld; +Cc: Asbjørn Sloth Tønnesen, wireguard

Move device filtering to the kernel, thereby reducing netlink traffic.

The first patch request kernel-side filtering.

The second patch removes the old filtering code, as an
additional step, which breaks on earlier than Linux v4.6.

The third patch requests that the kernel doesn't include statistics
in netdevice dumps.

This bumps the minimum supported Linux kernel version to v4.6.

---
Changes:
v4:
- Remove #ifdef RTEXT_FILTER_SKIP_STATS.
- Sync changes to the embeddable C library.
- Now that Linux v4.6+ is fine, swap the order of patch 2 and 3.
- Dusted of the commit messages a bit.

v3: https://lists.zx2c4.com/pipermail/wireguard/2026-January/009471.html
- Added patch to set RTEXT_FILTER_SKIP_STATS
- Re-worked commit messages a bit.

v2: https://lists.zx2c4.com/pipermail/wireguard/2025-October/009080.html
- Added info about kernel-support to commit message
- Added another patch, for removing client-side filtering

v1: https://lists.zx2c4.com/pipermail/wireguard/2025-September/009004.html


Asbjørn Sloth Tønnesen (3):
  ipc: linux: filter netdevices kernel-side
  ipc: linux: remove user-space netdevice filtering
  ipc: linux: skip statistics on netdevice listing

 contrib/embeddable-wg-library/wireguard.c | 23 +++++++++--------------
 src/ipc-linux.h                           | 23 +++++++++--------------
 2 files changed, 18 insertions(+), 28 deletions(-)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH wireguard-tools v4 1/3] ipc: linux: filter netdevices kernel-side
  2026-03-12 21:43 [PATCH wireguard-tools v4 0/3] ipc: linux: kernel-side netdevice filtering Asbjørn Sloth Tønnesen
@ 2026-03-12 21:43 ` Asbjørn Sloth Tønnesen
  2026-03-12 21:44 ` [PATCH wireguard-tools v4 2/3] ipc: linux: remove user-space netdevice filtering Asbjørn Sloth Tønnesen
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2026-03-12 21:43 UTC (permalink / raw)
  To: Jason A . Donenfeld; +Cc: Asbjørn Sloth Tønnesen, wireguard

Tell the kernel that we are only interested in wireguard netdevices,
so the kernel don't have to dump all the other netdevices.

Kernel-side support for this was added in Linux v4.6 in
commit dc599f76c22b ("net: Add support for filtering link dump by
master device and kind").

Tested with 10000 netdevices (common with ISP BNG setups), and a
single wireguard netdevice.

Baseline:
  # time ./src/wg show
  real    0m0.342s
  user    0m0.013s
  sys     0m0.290s

With patch:
  # time ./src/wg show
  real    0m0.006s
  user    0m0.000s
  sys     0m0.005s

Despite the subject prefix, this patch also applies to the
embeddable C library, so the two implementations stay in sync.

Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
 contrib/embeddable-wg-library/wireguard.c | 6 ++++++
 src/ipc-linux.h                           | 6 ++++++
 2 files changed, 12 insertions(+)

diff --git a/contrib/embeddable-wg-library/wireguard.c b/contrib/embeddable-wg-library/wireguard.c
index 4941549..7ac0d6c 100644
--- a/contrib/embeddable-wg-library/wireguard.c
+++ b/contrib/embeddable-wg-library/wireguard.c
@@ -943,6 +943,7 @@ static int fetch_device_names(struct string_list *list)
 	int ret = 0;
 	struct nlmsghdr *nlh;
 	struct ifinfomsg *ifm;
+	struct nlattr *linkinfo_nest;
 
 	ret = -ENOMEM;
 	rtnl_buffer = calloc(mnl_ideal_socket_buffer_size(), 1);
@@ -968,6 +969,11 @@ static int fetch_device_names(struct string_list *list)
 	nlh->nlmsg_seq = seq;
 	ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
 	ifm->ifi_family = AF_UNSPEC;
+
+	linkinfo_nest = mnl_attr_nest_start(nlh, IFLA_LINKINFO);
+	mnl_attr_put_strz(nlh, IFLA_INFO_KIND, WG_GENL_NAME);
+	mnl_attr_nest_end(nlh, linkinfo_nest);
+
 	message_len = nlh->nlmsg_len;
 
 	if (mnl_socket_sendto(nl, rtnl_buffer, message_len) < 0) {
diff --git a/src/ipc-linux.h b/src/ipc-linux.h
index 01247f1..c56fede 100644
--- a/src/ipc-linux.h
+++ b/src/ipc-linux.h
@@ -80,6 +80,7 @@ static int kernel_get_wireguard_interfaces(struct string_list *list)
 	int ret = 0;
 	struct nlmsghdr *nlh;
 	struct ifinfomsg *ifm;
+	struct nlattr *linkinfo_nest;
 
 	ret = -ENOMEM;
 	rtnl_buffer = calloc(SOCKET_BUFFER_SIZE, 1);
@@ -105,6 +106,11 @@ static int kernel_get_wireguard_interfaces(struct string_list *list)
 	nlh->nlmsg_seq = seq;
 	ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
 	ifm->ifi_family = AF_UNSPEC;
+
+	linkinfo_nest = mnl_attr_nest_start(nlh, IFLA_LINKINFO);
+	mnl_attr_put_strz(nlh, IFLA_INFO_KIND, WG_GENL_NAME);
+	mnl_attr_nest_end(nlh, linkinfo_nest);
+
 	message_len = nlh->nlmsg_len;
 
 	if (mnl_socket_sendto(nl, rtnl_buffer, message_len) < 0) {
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH wireguard-tools v4 2/3] ipc: linux: remove user-space netdevice filtering
  2026-03-12 21:43 [PATCH wireguard-tools v4 0/3] ipc: linux: kernel-side netdevice filtering Asbjørn Sloth Tønnesen
  2026-03-12 21:43 ` [PATCH wireguard-tools v4 1/3] ipc: linux: filter netdevices kernel-side Asbjørn Sloth Tønnesen
@ 2026-03-12 21:44 ` Asbjørn Sloth Tønnesen
  2026-03-12 21:44 ` [PATCH wireguard-tools v4 3/3] ipc: linux: skip statistics on netdevice listing Asbjørn Sloth Tønnesen
  2026-11-10 16:32 ` [PATCH wireguard-tools v4 0/3] ipc: linux: kernel-side netdevice filtering Jason A. Donenfeld
  3 siblings, 0 replies; 5+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2026-03-12 21:44 UTC (permalink / raw)
  To: Jason A . Donenfeld; +Cc: Asbjørn Sloth Tønnesen, wireguard

Since the devices are now filtered kernel-side, we can remove
the code for filtering in user-space.

This breaks device listing for kernels earlier than Linux v4.6,
device-specific commands will continue to work.

Despite the subject prefix, this patch also applies to the
embeddable C library, so the two implementations stay in sync.

Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
 contrib/embeddable-wg-library/wireguard.c | 16 ++--------------
 src/ipc-linux.h                           | 16 ++--------------
 2 files changed, 4 insertions(+), 28 deletions(-)

diff --git a/contrib/embeddable-wg-library/wireguard.c b/contrib/embeddable-wg-library/wireguard.c
index 7ac0d6c..eff441b 100644
--- a/contrib/embeddable-wg-library/wireguard.c
+++ b/contrib/embeddable-wg-library/wireguard.c
@@ -892,25 +892,13 @@ static int string_list_add(struct string_list *list, const char *str)
 
 struct interface {
 	const char *name;
-	bool is_wireguard;
 };
 
-static int parse_linkinfo(const struct nlattr *attr, void *data)
-{
-	struct interface *interface = data;
-
-	if (mnl_attr_get_type(attr) == IFLA_INFO_KIND && !strcmp(WG_GENL_NAME, mnl_attr_get_str(attr)))
-		interface->is_wireguard = true;
-	return MNL_CB_OK;
-}
-
 static int parse_infomsg(const struct nlattr *attr, void *data)
 {
 	struct interface *interface = data;
 
-	if (mnl_attr_get_type(attr) == IFLA_LINKINFO)
-		return mnl_attr_parse_nested(attr, parse_linkinfo, data);
-	else if (mnl_attr_get_type(attr) == IFLA_IFNAME)
+	if (mnl_attr_get_type(attr) == IFLA_IFNAME)
 		interface->name = mnl_attr_get_str(attr);
 	return MNL_CB_OK;
 }
@@ -924,7 +912,7 @@ static int read_devices_cb(const struct nlmsghdr *nlh, void *data)
 	ret = mnl_attr_parse(nlh, sizeof(struct ifinfomsg), parse_infomsg, &interface);
 	if (ret != MNL_CB_OK)
 		return ret;
-	if (interface.name && interface.is_wireguard)
+	if (interface.name)
 		ret = string_list_add(list, interface.name);
 	if (ret < 0)
 		return ret;
diff --git a/src/ipc-linux.h b/src/ipc-linux.h
index c56fede..45bb55c 100644
--- a/src/ipc-linux.h
+++ b/src/ipc-linux.h
@@ -29,25 +29,13 @@
 
 struct interface {
 	const char *name;
-	bool is_wireguard;
 };
 
-static int parse_linkinfo(const struct nlattr *attr, void *data)
-{
-	struct interface *interface = data;
-
-	if (mnl_attr_get_type(attr) == IFLA_INFO_KIND && !strcmp(WG_GENL_NAME, mnl_attr_get_str(attr)))
-		interface->is_wireguard = true;
-	return MNL_CB_OK;
-}
-
 static int parse_infomsg(const struct nlattr *attr, void *data)
 {
 	struct interface *interface = data;
 
-	if (mnl_attr_get_type(attr) == IFLA_LINKINFO)
-		return mnl_attr_parse_nested(attr, parse_linkinfo, data);
-	else if (mnl_attr_get_type(attr) == IFLA_IFNAME)
+	if (mnl_attr_get_type(attr) == IFLA_IFNAME)
 		interface->name = mnl_attr_get_str(attr);
 	return MNL_CB_OK;
 }
@@ -61,7 +49,7 @@ static int read_devices_cb(const struct nlmsghdr *nlh, void *data)
 	ret = mnl_attr_parse(nlh, sizeof(struct ifinfomsg), parse_infomsg, &interface);
 	if (ret != MNL_CB_OK)
 		return ret;
-	if (interface.name && interface.is_wireguard)
+	if (interface.name)
 		ret = string_list_add(list, interface.name);
 	if (ret < 0)
 		return ret;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH wireguard-tools v4 3/3] ipc: linux: skip statistics on netdevice listing
  2026-03-12 21:43 [PATCH wireguard-tools v4 0/3] ipc: linux: kernel-side netdevice filtering Asbjørn Sloth Tønnesen
  2026-03-12 21:43 ` [PATCH wireguard-tools v4 1/3] ipc: linux: filter netdevices kernel-side Asbjørn Sloth Tønnesen
  2026-03-12 21:44 ` [PATCH wireguard-tools v4 2/3] ipc: linux: remove user-space netdevice filtering Asbjørn Sloth Tønnesen
@ 2026-03-12 21:44 ` Asbjørn Sloth Tønnesen
  2026-11-10 16:32 ` [PATCH wireguard-tools v4 0/3] ipc: linux: kernel-side netdevice filtering Jason A. Donenfeld
  3 siblings, 0 replies; 5+ messages in thread
From: Asbjørn Sloth Tønnesen @ 2026-03-12 21:44 UTC (permalink / raw)
  To: Jason A . Donenfeld; +Cc: Asbjørn Sloth Tønnesen, wireguard

Gathering interface statistics can be a relatively expensive operation
on certain systems as it requires iterating over all the cpus.

This patch instructs the kernel to not include netdevice statistics,
in the netdevice listing.

Kernel-side support for this was added in Linux v4.4 in commit
d5566fd72ec1 ("rtnetlink: RTEXT_FILTER_SKIP_STATS support to avoid
dumping inet/inet6 stats"), this saves 368 bytes of statistics.

In the Linux v6.19 commit 105bae321862 ("rtnetlink: honor
RTEXT_FILTER_SKIP_STATS in IFLA_STATS"), it is expanded to skip more
statistics bringing the savings to 800 bytes per netdevice.

Despite the subject prefix, this patch also applies to the
embeddable C library, so the two implementations stay in sync.

Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
 contrib/embeddable-wg-library/wireguard.c | 1 +
 src/ipc-linux.h                           | 1 +
 2 files changed, 2 insertions(+)

diff --git a/contrib/embeddable-wg-library/wireguard.c b/contrib/embeddable-wg-library/wireguard.c
index eff441b..686cd3a 100644
--- a/contrib/embeddable-wg-library/wireguard.c
+++ b/contrib/embeddable-wg-library/wireguard.c
@@ -957,6 +957,7 @@ static int fetch_device_names(struct string_list *list)
 	nlh->nlmsg_seq = seq;
 	ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
 	ifm->ifi_family = AF_UNSPEC;
+	mnl_attr_put_u32(nlh, IFLA_EXT_MASK, RTEXT_FILTER_SKIP_STATS);
 
 	linkinfo_nest = mnl_attr_nest_start(nlh, IFLA_LINKINFO);
 	mnl_attr_put_strz(nlh, IFLA_INFO_KIND, WG_GENL_NAME);
diff --git a/src/ipc-linux.h b/src/ipc-linux.h
index 45bb55c..791eb84 100644
--- a/src/ipc-linux.h
+++ b/src/ipc-linux.h
@@ -94,6 +94,7 @@ static int kernel_get_wireguard_interfaces(struct string_list *list)
 	nlh->nlmsg_seq = seq;
 	ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
 	ifm->ifi_family = AF_UNSPEC;
+	mnl_attr_put_u32(nlh, IFLA_EXT_MASK, RTEXT_FILTER_SKIP_STATS);
 
 	linkinfo_nest = mnl_attr_nest_start(nlh, IFLA_LINKINFO);
 	mnl_attr_put_strz(nlh, IFLA_INFO_KIND, WG_GENL_NAME);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH wireguard-tools v4 0/3] ipc: linux: kernel-side netdevice filtering
  2026-03-12 21:43 [PATCH wireguard-tools v4 0/3] ipc: linux: kernel-side netdevice filtering Asbjørn Sloth Tønnesen
                   ` (2 preceding siblings ...)
  2026-03-12 21:44 ` [PATCH wireguard-tools v4 3/3] ipc: linux: skip statistics on netdevice listing Asbjørn Sloth Tønnesen
@ 2026-11-10 16:32 ` Jason A. Donenfeld
  3 siblings, 0 replies; 5+ messages in thread
From: Jason A. Donenfeld @ 2026-11-10 16:32 UTC (permalink / raw)
  To: Asbjørn Sloth Tønnesen; +Cc: wireguard

On Thu, Mar 12, 2026 at 09:43:58PM +0000, Asbjørn Sloth Tønnesen wrote:
> Move device filtering to the kernel, thereby reducing netlink traffic.
> 
> The first patch request kernel-side filtering.
> 
> The second patch removes the old filtering code, as an
> additional step, which breaks on earlier than Linux v4.6.
> 
> The third patch requests that the kernel doesn't include statistics
> in netdevice dumps.
> 
> This bumps the minimum supported Linux kernel version to v4.6.

Sorry for the delay. Applied with one small cleanup:
https://git.zx2c4.com/wireguard-tools/commit/?id=522f583d5304f93f71a95b81870db5fe0a74cfd6

Thank you for this!

Jason

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-11-10 16:35 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-12 21:43 [PATCH wireguard-tools v4 0/3] ipc: linux: kernel-side netdevice filtering Asbjørn Sloth Tønnesen
2026-03-12 21:43 ` [PATCH wireguard-tools v4 1/3] ipc: linux: filter netdevices kernel-side Asbjørn Sloth Tønnesen
2026-03-12 21:44 ` [PATCH wireguard-tools v4 2/3] ipc: linux: remove user-space netdevice filtering Asbjørn Sloth Tønnesen
2026-03-12 21:44 ` [PATCH wireguard-tools v4 3/3] ipc: linux: skip statistics on netdevice listing Asbjørn Sloth Tønnesen
2026-11-10 16:32 ` [PATCH wireguard-tools v4 0/3] ipc: linux: kernel-side netdevice filtering Jason A. Donenfeld

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox