From Jean-Alexandre.CHRONE at stormshield.eu Fri Mar 6 10:05:15 2026 From: Jean-Alexandre.CHRONE at stormshield.eu (Jean-Alexandre CHRONE) Date: Fri, 6 Mar 2026 10:05:15 +0000 Subject: [PATCH] api: use mutex when removing instance on close adapter In-Reply-To: <7ef930c54a4b4aa5bd3ecd9cf01fe12a@stormshield.eu> References: <7ef930c54a4b4aa5bd3ecd9cf01fe12a@stormshield.eu> Message-ID: <2bc053cc1dcc4f87973c9a84826e49b9@stormshield.eu> Hello, Did anyone have the same issue as mentioned in the earlier message? We encountered it any time we had to reset an adapter multiple times in a short lapse of time. Best Regards, Jean-Alexandre -----Original message----- >From 298267d3ead7110880a5dc0f5d0e8822600d30c0 Mon Sep 17 00:00:00 2001 From: "jean-alexandre.chrone" Date: Mon, 2 Feb 2026 15:24:12 +0100 Subject: [PATCH] api: use mutex when removing instance on close adapter on successive create and close there might be some error logged --- api/adapter.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/api/adapter.c b/api/adapter.c index 0dd8c42..042645c 100644 --- a/api/adapter.c +++ b/api/adapter.c @@ -158,7 +158,8 @@ VOID AdapterCleanupOrphanedDevices(VOID) continue; } ULONG Status, Code; - if (CM_Get_DevNode_Status(&Status, &Code, DevInfoData.DevInst, 0) == CR_SUCCESS && !(Status & DN_HAS_PROBLEM)) + CONFIGRET Ret = CM_Get_DevNode_Status(&Status, &Code, DevInfoData.DevInst, 0); + if ((Ret == CR_SUCCESS && !(Status & DN_HAS_PROBLEM)) || Ret == + CR_NO_SUCH_DEVNODE) continue; DEVPROPTYPE PropType; @@ -195,8 +196,16 @@ WintunCloseAdapter(WINTUN_ADAPTER *Adapter) SwDeviceClose(Adapter->SwDevice); if (Adapter->DevInfo) { + HANDLE DeviceInstallationMutex = NamespaceTakeDeviceInstallationMutex(); + if (DeviceInstallationMutex == NULL) + LOG_LAST_ERROR(L"Failed to take device installation + mutex"); + if (!AdapterRemoveInstance(Adapter->DevInfo, &Adapter->DevInfoData)) LOG_LAST_ERROR(L"Failed to remove adapter when closing"); + + if (DeviceInstallationMutex != NULL) + NamespaceReleaseMutex(DeviceInstallationMutex); + SetupDiDestroyDeviceInfoList(Adapter->DevInfo); } Free(Adapter); -- 2.52.0.windows.1 From syzbot+f2fbf7478a35a94c8b7c at syzkaller.appspotmail.com Sun Mar 8 14:56:21 2026 From: syzbot+f2fbf7478a35a94c8b7c at syzkaller.appspotmail.com (syzbot) Date: Sun, 08 Mar 2026 07:56:21 -0700 Subject: [syzbot] [wireguard?] INFO: task hung in wg_netns_pre_exit (5) In-Reply-To: <66f49736.050a0220.211276.0036.GAE@google.com> Message-ID: <69ad8e15.050a0220.310d8.000d.GAE@google.com> syzbot has found a reproducer for the following issue on: HEAD commit: c113d5e32678 Merge branch 'net-spacemit-a-few-error-handli.. git tree: net console output: https://syzkaller.appspot.com/x/log.txt?x=13a4875a580000 kernel config: https://syzkaller.appspot.com/x/.config?x=779072223d02a312 dashboard link: https://syzkaller.appspot.com/bug?extid=f2fbf7478a35a94c8b7c compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8 syz repro: https://syzkaller.appspot.com/x/repro.syz?x=10cf3fe6580000 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=16b5c8ba580000 Downloadable assets: disk image: https://storage.googleapis.com/syzbot-assets/a1a0aa684791/disk-c113d5e3.raw.xz vmlinux: https://storage.googleapis.com/syzbot-assets/6d0461aed5ba/vmlinux-c113d5e3.xz kernel image: https://storage.googleapis.com/syzbot-assets/05b26502bb1f/bzImage-c113d5e3.xz The issue was bisected to: commit d4dfc5700e867b22ab94f960f9a9972696a637d5 Author: Andrii Nakryiko Date: Tue Mar 19 23:38:49 2024 +0000 bpf: pass whole link instead of prog when triggering raw tracepoint bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=17ccbc58580000 final oops: https://syzkaller.appspot.com/x/report.txt?x=142cbc58580000 console output: https://syzkaller.appspot.com/x/log.txt?x=102cbc58580000 IMPORTANT: if you fix the issue, please add the following tag to the commit: Reported-by: syzbot+f2fbf7478a35a94c8b7c at syzkaller.appspotmail.com Fixes: d4dfc5700e86 ("bpf: pass whole link instead of prog when triggering raw tracepoint") INFO: task kworker/u8:7:1016 blocked for more than 143 seconds. Not tainted syzkaller #0 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:kworker/u8:7 state:D stack:25664 pid:1016 tgid:1016 ppid:2 task_flags:0x4208060 flags:0x00080000 Workqueue: netns cleanup_net Call Trace: context_switch kernel/sched/core.c:5295 [inline] __schedule+0x15dd/0x52d0 kernel/sched/core.c:6908 __schedule_loop kernel/sched/core.c:6990 [inline] schedule+0x164/0x360 kernel/sched/core.c:7005 schedule_preempt_disabled+0x13/0x30 kernel/sched/core.c:7062 __mutex_lock_common kernel/locking/mutex.c:692 [inline] __mutex_lock+0x7fe/0x1300 kernel/locking/mutex.c:776 wg_netns_pre_exit+0x1c/0x200 drivers/net/wireguard/device.c:419 ops_pre_exit_list net/core/net_namespace.c:161 [inline] ops_undo_list+0x187/0x940 net/core/net_namespace.c:234 cleanup_net+0x56b/0x800 net/core/net_namespace.c:704 process_one_work kernel/workqueue.c:3275 [inline] process_scheduled_works+0xb02/0x1830 kernel/workqueue.c:3358 worker_thread+0xa50/0xfc0 kernel/workqueue.c:3439 kthread+0x388/0x470 kernel/kthread.c:436 ret_from_fork+0x51e/0xb90 arch/x86/kernel/process.c:158 --- If you want syzbot to run the reproducer, reply with: #syz test: git://repo/address.git branch-or-commit-hash If you attach or paste a git patch, syzbot will apply it before testing. From Jason at zx2c4.com Wed Mar 11 22:59:43 2026 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Wed, 11 Mar 2026 23:59:43 +0100 Subject: [PATCH wireguard] wireguard: prevent ipv6 addrconf via IFF_NO_ADDRCONF flag In-Reply-To: <20260208170545.31942-1-valentin@spreckels.dev> References: <20260208170545.31942-1-valentin@spreckels.dev> Message-ID: Hi Valentin, On Sun, Feb 08, 2026 at 06:05:45PM +0100, Valentin Spreckels wrote: > Use the flag introduced in commit 8a321cf7becc6 ("net: add > IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf") > instead of mangling the addr_gen_mode to prevent ipv6 addrconf. Can you give some more context here? Why was IFF_NO_ADDRCONF added when the IN6_ADDR_GEN_MODE_NONE method has been working fine? What's the difference between these approaches? I don't doubt that your patch is correct, but I would like to better understand this. Jason From Jason at zx2c4.com Wed Mar 11 23:02:52 2026 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Thu, 12 Mar 2026 00:02:52 +0100 Subject: [PATCH wireguard-tools v3 0/3] ipc: linux: kernel-side netdevice filtering In-Reply-To: <20260130191058.5123-1-ast@fiberby.net> References: <20260130191058.5123-1-ast@fiberby.net> Message-ID: On Fri, Jan 30, 2026 at 07:10:52PM +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 requests that the kernel doesn't include statistics > in netdevice dumps. > > The third patch removes the old filtering code, as an > additional step, which breaks on earlier than Linux v4.6. > > I assume that a dependency on Linux v4.6+ is acceptable for wg-tools > now, as wireguard-linux-compat haven't been updated for 3 years. Interesting series. If I'm going to apply this, I'm going to apply it, and so the ifdefs you've added won't matter much; this will still break wireguard-linux-compat. But maybe it's time to do so. So if you're up for sending a v4, just do it like there's no yesterday. Also, does this filtering need to also be added to the embeddable c library contrib code? Thanks for this patch. I'll start thinking seriously about wireguard-linux-compat sunsetting. Jason From katz.oded at gmail.com Wed Mar 11 23:35:25 2026 From: katz.oded at gmail.com (Oded Katz) Date: Wed, 11 Mar 2026 16:35:25 -0700 Subject: [PATCH 1/1] in order to prevent buffer overrun (which was observed while sending multiple high throughput UDP streams from different threads) I move the driver spinlock to protect Ring buffer Head. In-Reply-To: <8e797830-9851-47f3-8e10-4126e295b4b9@amebis.si> References: <20260219193255.14334-1-katz.oded@gmail.com> <20260219193255.14334-2-katz.oded@gmail.com> <8e797830-9851-47f3-8e10-4126e295b4b9@amebis.si> Message-ID: Hi Simon, I still haven't heard from you guys, neither saw a ticket in the mailing list. is there any update ? regards, Oded On Thu, Feb 19, 2026 at 11:28?PM Simon Rozman wrote: > > Hi, Oded! > > First and foremost, thank you very much for taking time to look into > this and troubleshoot it. > > It was believed, that ReadULongAcquire() and WriteULongRelease() alone > provide atomic manipulation with Ring->Head on all modern platforms. > Hence, these calls were made outside the spinlock, to squeeze an extra > micrometer of performance. > > I could not directly apply your patch to the wintun repo, since it does > not follow our code style, commit message conventions and is not > Signed-off-by you. > > However, it would have been a terrible waste of your research if your > contribution wouldn't get into wintun, so I reworked your PR and applied > it here: > https://git.zx2c4.com/wintun/commit/?id=607c181ea9fa0036d23598038e6019ad54db5ce4 > > Please, stay tuned for an official WHQL-signed release. > > Lep pozdrav | Best regards, > Simon Rozman > Amebis, d. o. o., Kamnik > > On 19. 2. 2026 20.32, odedkatz wrote: > > I observed that the Ring->Head was taken and manipulated later on with just a `ReadULongAcquire` which isn't OK when 2 are trying to manipulate it later on based on the same received value. > > --- > > driver/wintun.c | 11 ++++++----- > > 1 file changed, 6 insertions(+), 5 deletions(-) > > > > diff --git a/driver/wintun.c b/driver/wintun.c > > index d1f3b9f..65cd97e 100644 > > --- a/driver/wintun.c > > +++ b/driver/wintun.c > > @@ -284,13 +284,14 @@ TunSendNetBufferLists( > > TUN_RING *Ring = Ctx->Device.Send.Ring; > > ULONG RingCapacity = Ctx->Device.Send.Capacity; > > > > + KLOCK_QUEUE_HANDLE LockHandle; > > + KeAcquireInStackQueuedSpinLock(&Ctx->Device.Send.Lock, &LockHandle); > > /* Allocate space for packets in the ring. */ > > ULONG RingHead = ReadULongAcquire(&Ring->Head); > > - if (Status = NDIS_STATUS_ADAPTER_NOT_READY, RingHead >= RingCapacity) > > + if (Status = NDIS_STATUS_ADAPTER_NOT_READY, RingHead >= RingCapacity) { > > + KeReleaseInStackQueuedSpinLock(&LockHandle); > > goto skipNbl; > > - > > - KLOCK_QUEUE_HANDLE LockHandle; > > - KeAcquireInStackQueuedSpinLock(&Ctx->Device.Send.Lock, &LockHandle); > > + } > > > > ULONG RingTail = Ctx->Device.Send.RingTail; > > ASSERT(RingTail < RingCapacity); > > @@ -419,8 +420,8 @@ TunReturnNetBufferLists(NDIS_HANDLE MiniportAdapterContext, PNET_BUFFER_LIST Net > > Ctx->Device.Receive.ActiveNbls.Head = NET_BUFFER_LIST_NEXT_NBL_EX(CompletedNbl); > > if (!Ctx->Device.Receive.ActiveNbls.Head) > > KeSetEvent(&Ctx->Device.Receive.ActiveNbls.Empty, IO_NO_INCREMENT, FALSE); > > - KeReleaseInStackQueuedSpinLock(&LockHandle); > > WriteULongRelease(&Ring->Head, TunNblGetOffset(CompletedNbl)); > > + KeReleaseInStackQueuedSpinLock(&LockHandle); > > const MDL *TargetMdl = Ctx->Device.Receive.Mdl; > > for (MDL *Mdl = NET_BUFFER_FIRST_MDL(NET_BUFFER_LIST_FIRST_NB(CompletedNbl)); Mdl; Mdl = Mdl->Next) > > { > From Jason at zx2c4.com Thu Mar 12 13:48:48 2026 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Thu, 12 Mar 2026 14:48:48 +0100 Subject: [PATCH 05/10 net-next v2] drivers: net: drop ipv6_stub usage and use direct function calls In-Reply-To: <20260310153506.5181-6-fmancera@suse.de> References: <20260310153506.5181-1-fmancera@suse.de> <20260310153506.5181-6-fmancera@suse.de> Message-ID: On Tue, Mar 10, 2026 at 04:34:28PM +0100, Fernando Fernandez Mancera wrote: > diff --git a/drivers/net/wireguard/socket.c b/drivers/net/wireguard/socket.c > index 253488f8c00f..c362c78d908e 100644 > --- a/drivers/net/wireguard/socket.c > +++ b/drivers/net/wireguard/socket.c > @@ -136,8 +136,7 @@ static int send6(struct wg_device *wg, struct sk_buff *skb, > if (cache) > dst_cache_reset(cache); > } > - dst = ipv6_stub->ipv6_dst_lookup_flow(sock_net(sock), sock, &fl, > - NULL); > + dst = ip6_dst_lookup_flow(sock_net(sock), sock, &fl, NULL); > if (IS_ERR(dst)) { > ret = PTR_ERR(dst); > net_dbg_ratelimited("%s: No route to %pISpfsc, error %d\n", Rest in peace, stub. For the WireGuard part, Reviewed-by: Jason A. Donenfeld From ast at fiberby.net Thu Mar 12 21:43:58 2026 From: ast at fiberby.net (=?UTF-8?q?Asbj=C3=B8rn=20Sloth=20T=C3=B8nnesen?=) Date: Thu, 12 Mar 2026 21:43:58 +0000 Subject: [PATCH wireguard-tools v4 0/3] ipc: linux: kernel-side netdevice filtering Message-ID: <20260312214405.589127-1-ast@fiberby.net> 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 From ast at fiberby.net Thu Mar 12 21:43:59 2026 From: ast at fiberby.net (=?UTF-8?q?Asbj=C3=B8rn=20Sloth=20T=C3=B8nnesen?=) Date: Thu, 12 Mar 2026 21:43:59 +0000 Subject: [PATCH wireguard-tools v4 1/3] ipc: linux: filter netdevices kernel-side In-Reply-To: <20260312214405.589127-1-ast@fiberby.net> References: <20260312214405.589127-1-ast@fiberby.net> Message-ID: <20260312214405.589127-2-ast@fiberby.net> 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 --- 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 From ast at fiberby.net Thu Mar 12 21:44:01 2026 From: ast at fiberby.net (=?UTF-8?q?Asbj=C3=B8rn=20Sloth=20T=C3=B8nnesen?=) Date: Thu, 12 Mar 2026 21:44:01 +0000 Subject: [PATCH wireguard-tools v4 3/3] ipc: linux: skip statistics on netdevice listing In-Reply-To: <20260312214405.589127-1-ast@fiberby.net> References: <20260312214405.589127-1-ast@fiberby.net> Message-ID: <20260312214405.589127-4-ast@fiberby.net> 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 --- 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 From ast at fiberby.net Thu Mar 12 21:44:00 2026 From: ast at fiberby.net (=?UTF-8?q?Asbj=C3=B8rn=20Sloth=20T=C3=B8nnesen?=) Date: Thu, 12 Mar 2026 21:44:00 +0000 Subject: [PATCH wireguard-tools v4 2/3] ipc: linux: remove user-space netdevice filtering In-Reply-To: <20260312214405.589127-1-ast@fiberby.net> References: <20260312214405.589127-1-ast@fiberby.net> Message-ID: <20260312214405.589127-3-ast@fiberby.net> 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 --- 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 From syzbot+4ca9a7b9d61b76d0177c at syzkaller.appspotmail.com Thu Mar 19 17:27:20 2026 From: syzbot+4ca9a7b9d61b76d0177c at syzkaller.appspotmail.com (syzbot) Date: Thu, 19 Mar 2026 10:27:20 -0700 Subject: [syzbot] [wireguard?] KCSAN: data-race in wg_expired_retransmit_handshake / wg_packet_send_queued_handshake_initiation (4) Message-ID: <69bc31f8.050a0220.18f14c.0050.GAE@google.com> Hello, syzbot found the following issue on: HEAD commit: 5ee8dbf54602 Merge tag 'fsverity-for-linus' of git://git.k.. git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=123477e6580000 kernel config: https://syzkaller.appspot.com/x/.config?x=6b32b22d8934c136 dashboard link: https://syzkaller.appspot.com/bug?extid=4ca9a7b9d61b76d0177c compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8 Unfortunately, I don't have any reproducer for this issue yet. Downloadable assets: disk image: https://storage.googleapis.com/syzbot-assets/dacfe44e33b2/disk-5ee8dbf5.raw.xz vmlinux: https://storage.googleapis.com/syzbot-assets/10e825a65a06/vmlinux-5ee8dbf5.xz kernel image: https://storage.googleapis.com/syzbot-assets/b2fe6914587d/bzImage-5ee8dbf5.xz IMPORTANT: if you fix the issue, please add the following tag to the commit: Reported-by: syzbot+4ca9a7b9d61b76d0177c at syzkaller.appspotmail.com ================================================================== BUG: KCSAN: data-race in wg_expired_retransmit_handshake / wg_packet_send_queued_handshake_initiation read to 0xffff88810b667808 of 4 bytes by interrupt on cpu 0: wg_expired_retransmit_handshake+0x2a/0x160 drivers/net/wireguard/timers.c:46 call_timer_fn+0x3b/0x2a0 kernel/time/timer.c:1748 expire_timers kernel/time/timer.c:1799 [inline] __run_timers kernel/time/timer.c:2373 [inline] __run_timer_base+0x426/0x620 kernel/time/timer.c:2385 run_timer_base kernel/time/timer.c:2394 [inline] run_timer_softirq+0x31/0x70 kernel/time/timer.c:2404 handle_softirqs+0xb9/0x2a0 kernel/softirq.c:622 __do_softirq kernel/softirq.c:656 [inline] invoke_softirq kernel/softirq.c:496 [inline] __irq_exit_rcu+0x39/0xc0 kernel/softirq.c:723 instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1056 [inline] sysvec_apic_timer_interrupt+0x74/0x80 arch/x86/kernel/apic/apic.c:1056 asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:697 native_safe_halt arch/x86/include/asm/irqflags.h:48 [inline] pv_native_safe_halt+0xf/0x20 arch/x86/kernel/paravirt.c:62 arch_safe_halt arch/x86/kernel/process.c:766 [inline] default_idle+0x9/0x20 arch/x86/kernel/process.c:767 default_idle_call+0x3b/0x60 kernel/sched/idle.c:122 cpuidle_idle_call kernel/sched/idle.c:191 [inline] do_idle+0xcd/0x230 kernel/sched/idle.c:332 cpu_startup_entry+0x24/0x30 kernel/sched/idle.c:430 rest_init+0xee/0xf0 init/main.c:760 start_kernel+0x49a/0x4c0 init/main.c:1210 x86_64_start_reservations+0x24/0x30 arch/x86/kernel/head64.c:310 x86_64_start_kernel+0xfc/0x100 arch/x86/kernel/head64.c:291 common_startup_64+0x13e/0x147 write to 0xffff88810b667808 of 4 bytes by interrupt on cpu 1: wg_packet_send_queued_handshake_initiation+0x32/0x180 drivers/net/wireguard/send.c:59 wg_expired_new_handshake+0x26/0x30 drivers/net/wireguard/timers.c:104 call_timer_fn+0x3b/0x2a0 kernel/time/timer.c:1748 expire_timers kernel/time/timer.c:1799 [inline] __run_timers kernel/time/timer.c:2373 [inline] __run_timer_base+0x426/0x620 kernel/time/timer.c:2385 run_timer_base kernel/time/timer.c:2394 [inline] run_timer_softirq+0x31/0x70 kernel/time/timer.c:2404 handle_softirqs+0xb9/0x2a0 kernel/softirq.c:622 __do_softirq kernel/softirq.c:656 [inline] invoke_softirq kernel/softirq.c:496 [inline] __irq_exit_rcu+0x39/0xc0 kernel/softirq.c:723 instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1056 [inline] sysvec_apic_timer_interrupt+0x74/0x80 arch/x86/kernel/apic/apic.c:1056 asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:697 native_safe_halt arch/x86/include/asm/irqflags.h:48 [inline] pv_native_safe_halt+0xf/0x20 arch/x86/kernel/paravirt.c:62 arch_safe_halt arch/x86/kernel/process.c:766 [inline] default_idle+0x9/0x20 arch/x86/kernel/process.c:767 default_idle_call+0x3b/0x60 kernel/sched/idle.c:122 cpuidle_idle_call kernel/sched/idle.c:191 [inline] do_idle+0xcd/0x230 kernel/sched/idle.c:332 cpu_startup_entry+0x24/0x30 kernel/sched/idle.c:430 start_secondary+0x95/0xa0 arch/x86/kernel/smpboot.c:312 common_startup_64+0x13e/0x147 value changed: 0x00000002 -> 0x00000003 Reported by Kernel Concurrency Sanitizer on: CPU: 1 UID: 0 PID: 0 Comm: swapper/1 Tainted: G W syzkaller #0 PREEMPT(full) Tainted: [W]=WARN Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2026 ================================================================== --- This report is generated by a bot. It may contain errors. See https://goo.gl/tpsmEJ for more information about syzbot. syzbot engineers can be reached at syzkaller at googlegroups.com. syzbot will keep track of this issue. See: https://goo.gl/tpsmEJ#status for how to communicate with syzbot. If the report is already addressed, let syzbot know by replying with: #syz fix: exact-commit-title If you want to overwrite report's subsystems, reply with: #syz set subsystems: new-subsystem (See the list of subsystem names on the web dashboard) If the report is a duplicate of another one, reply with: #syz dup: exact-subject-of-another-report If you want to undo deduplication, reply with: #syz undup From syzbot+listb2717bb6410baba389f7 at syzkaller.appspotmail.com Thu Mar 19 21:35:21 2026 From: syzbot+listb2717bb6410baba389f7 at syzkaller.appspotmail.com (syzbot) Date: Thu, 19 Mar 2026 14:35:21 -0700 Subject: [syzbot] Monthly wireguard report (Mar 2026) Message-ID: <69bc6c19.050a0220.3bf4de.0000.GAE@google.com> Hello wireguard maintainers/developers, This is a 31-day syzbot report for the wireguard subsystem. All related reports/information can be found at: https://syzkaller.appspot.com/upstream/s/wireguard During the period, 1 new issues were detected and 0 were fixed. In total, 3 issues are still open and 20 have already been fixed. Some of the still happening issues: Ref Crashes Repro Title <1> 787 No INFO: task hung in netdev_run_todo (4) https://syzkaller.appspot.com/bug?extid=894cca71fa925aabfdb2 <2> 391 Yes INFO: task hung in wg_netns_pre_exit (5) https://syzkaller.appspot.com/bug?extid=f2fbf7478a35a94c8b7c <3> 1 No KCSAN: data-race in wg_expired_retransmit_handshake / wg_packet_send_queued_handshake_initiation (4) https://syzkaller.appspot.com/bug?extid=4ca9a7b9d61b76d0177c --- This report is generated by a bot. It may contain errors. See https://goo.gl/tpsmEJ for more information about syzbot. syzbot engineers can be reached at syzkaller at googlegroups.com. To disable reminders for individual bugs, reply with the following command: #syz set no-reminders To change bug's subsystems, reply with: #syz set subsystems: new-subsystem You may send multiple commands in a single email message. From valentin at spreckels.dev Sat Mar 21 19:20:53 2026 From: valentin at spreckels.dev (Valentin Spreckels) Date: Sat, 21 Mar 2026 20:20:53 +0100 Subject: [PATCH wireguard] wireguard: prevent ipv6 addrconf via IFF_NO_ADDRCONF flag In-Reply-To: References: <20260208170545.31942-1-valentin@spreckels.dev> Message-ID: Hi Jason, On 11/03/2026 23:59, Jason A. Donenfeld wrote: > Hi Valentin, > > On Sun, Feb 08, 2026 at 06:05:45PM +0100, Valentin Spreckels wrote: >> Use the flag introduced in commit 8a321cf7becc6 ("net: add >> IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf") >> instead of mangling the addr_gen_mode to prevent ipv6 addrconf. > > Can you give some more context here? Why was IFF_NO_ADDRCONF added when > the IN6_ADDR_GEN_MODE_NONE method has been working fine? What's the > difference between these approaches? I don't doubt that your patch is > correct, but I would like to better understand this. Only wireguard configures addr_gen_mode inside the kernel, otherwise it is only set by userspace; userspace is also able to overwrite the IFF_NO_ADDRCONF set by wireguard. Commit 8a321cf7becc ("net: add IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf") introduces the private interface flag IFF_NO_ADDRCONF, which isn't accessible by userspace. Thus use the IFF_NO_ADDRCONF flag in wireguard. Does that answer your questions? If yes, I will submit a v2 with this as commit message. Best regards Valentin From Jason at zx2c4.com Mon Mar 23 17:09:26 2026 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Mon, 23 Mar 2026 18:09:26 +0100 Subject: Sunsetting support for old Windows versions Message-ID: Hey everyone, The time has finally come. Future releases of WireGuard for Windows will support Windows ?10 and Windows Server ?2016. With Windows 10 first released to manufacturing on July 15, 2015, that's supporting an operating system that's 3,904 days old, as opposed to supporting an operating system that's 6,088 days old. Nonetheless, supporting an OS that's over 10 years old is still a long time, even if it's not an OS that's over 16 years old. I must admit, however, that I am a bit sad about this. After coding up [1] this dialog box for the installer, I felt a few pangs of sadness when testing it for the first time on Windows 7 and seeing the tragic result: https://data.zx2c4.com/bye-bye-wg-win7.png . But it was a familiar feeling. For, long ago, I'd already watched the beauty of Windows fall to pieces. To me, Windows 2000 is the most beautiful of Windows operating systems. Yes, we can all ogle at the engineering marvel that was NT 3.51. But Windows 2000 really elevated that whole vision to perfection, and was also the pinnacle of the classic UI design. I can't think of a classier OS released since. Though, I must say, it was Windows XP that captured my heart and formed the basis of my childhood, the new style and all; I would switch between classic theme and the XP theme frequently, and later flirted a bit with the MCE themes. It was just a very nice OS, had everything one could want, a great suite of software, really good stability, ever widening hardware support, sane and consistent interfaces. It came pre-installed on my Dell Inspiron 8100 and I loved it. At some point I switched to running Linux on my laptop, but would still sneak down to the family computer to fiddle around with Windows development on our XP machine. I could go on and on. Then Vista was released, and it was annoying and introduced inconsistencies, which Windows 7 tried to smooth out and succeeded to some degree, but it was just never the same to me. And we all remember what happened next with 8, 8.1, 10, and 11. So, it's sad to make this change, but it's far less sad than what already happened in the Windows world post 2000 and post XP. On the plus side, this has enabled a lot of significant cleanups throughout the code, and will be yielding more and more as this process continues. Windows programming is as fun as ever -- arguably more fun, as the archaeological dumpster heap of historic Microsoft APIs, each one filled with a unique history and competing corporate and technical vision of operating system futurism, only ever gets deeper to dive in. So I'm relatively happy to make this change, even if somewhat wistful about it. I had first asked the mailing list whether this was acceptable in 2020 and then again in 2021. Fast forward 5 years and the ecosystem has changed a lot, and our upstream dependencies have similarly dropped support. I realize this leaves the still-technically-supported Server 2012 and 2012R2 out in the cold, but 8 and 8.1 haven't been supported in two years, and I think most realistic users have similarly dropped the corresponding server editions. In other words, I don't anticipate any real fallout. However, I know that Windows 7 and Server 2008 and 2008R2 users are usually pretty committed to their ways and can be vocal. So, by all means pipe up to sing an elegy if you'd like. But we're moving forward with the sunsetting. I hope this all seems reasonable enough. Let's pour one out for Blackcomb/Vienna, and while we're at it, for Whistler long before that. Jason [1] https://git.zx2c4.com/wireguard-windows/tree/installer/customactions.c#n101 From jeroen at robben.io Wed Mar 18 23:06:38 2026 From: jeroen at robben.io (Jeroen Robben) Date: Wed, 18 Mar 2026 23:06:38 +0000 Subject: [PATCH] wireguard: use memzero_explicit() when zeroing handshake key material Message-ID: <20260318230635.227291-1-jeroen@robben.io> Replace memset() calls in handshake_zero() with memzero_explicit() to ensure clearing handshake state is not optimized away by the compiler. Signed-off-by: Jeroen Robben --- drivers/net/wireguard/noise.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireguard/noise.c b/drivers/net/wireguard/noise.c index 7eb9a23a3d4d..b8be04549fa6 100644 --- a/drivers/net/wireguard/noise.c +++ b/drivers/net/wireguard/noise.c @@ -77,10 +77,10 @@ void wg_noise_handshake_init(struct noise_handshake *handshake, static void handshake_zero(struct noise_handshake *handshake) { - memset(&handshake->ephemeral_private, 0, NOISE_PUBLIC_KEY_LEN); - memset(&handshake->remote_ephemeral, 0, NOISE_PUBLIC_KEY_LEN); - memset(&handshake->hash, 0, NOISE_HASH_LEN); - memset(&handshake->chaining_key, 0, NOISE_HASH_LEN); + memzero_explicit(&handshake->ephemeral_private, NOISE_PUBLIC_KEY_LEN); + memzero_explicit(&handshake->remote_ephemeral, NOISE_PUBLIC_KEY_LEN); + memzero_explicit(&handshake->hash, NOISE_HASH_LEN); + memzero_explicit(&handshake->chaining_key, NOISE_HASH_LEN); handshake->remote_index = 0; handshake->state = HANDSHAKE_ZEROED; } -- 2.53.0 From technerder at gmail.com Thu Mar 19 17:50:31 2026 From: technerder at gmail.com (Technerder) Date: Thu, 19 Mar 2026 13:50:31 -0400 Subject: Question regarding packet forwarding in wireguard-go Inbox Message-ID: Hello all, I'm trying to setup a network with a main hub/router and numerous nodes. The general idea is to adapt the `http_server.go`/`http_client.go` netstack example to something akin to a hub-spoke like model. The general network structure can be described like so: - 1 wireguard node acting as the central node (10.0.0.1) (code provided below under "Hub") - N nodes connecting to the main central node and either accessing an HTTP server on the network or providing one to other nodes on the network - For the sake of this example I've just gone ahead and adapted the previously mentioned `http_server.go`/`http_client.go` netstack examples like so: - 10.0.0.2 as an HTTP server (code provided below under "HTTP Server") - 10.0.0.3 as an HTTP client (code provided below under "HTTP Client") Hub: ```go package main import ( "encoding/json" "log" "net" "net/netip" "os" "os/signal" "syscall" "time" "golang.zx2c4.com/wireguard/conn " "golang.zx2c4.com/wireguard/device " "golang.zx2c4.com/wireguard/ipc " "golang.zx2c4.com/wireguard/tun/netstack " "golang.zx2c4.com/wireguard/wgctrl " "golang.zx2c4.com/wireguard/wgctrl/wgtypes " ) type Config struct { InterfaceName string `json:"interface_name"` ListenPort int `json:"listen_port"` ListenAddress string `json:"listen_address"` PublicKey string `json:"public_key"` PrivateKey string `json:"private_key"` Peers []struct { Identifier string `json:"identifier"` PublicKey string `json:"public_key"` PresharedKey string `json:"preshared_key"` Address string `json:"address"` PersistentKeepAliveInterval int `json:"persistent_keepalive_interval"` } `json:"peers"` } func Load(path string) (Config, error) { var config Config contents, err := os.ReadFile(path) if err != nil { return config, err } return config, json.Unmarshal(contents, &config) } func main() { // Parse raw config config, err := Load("config.json") if err != nil { log.Printf("Error loading config: %v", err) return } // Parse peers peerDNSMappings := make(map[string]string) peers := make([]wgtypes.PeerConfig, 0) for _, peer := range config.Peers { publicKey, err := wgtypes.ParseKey(peer.PublicKey) if err != nil { log.Printf("Error parsing public key: %v", err) continue } keepAliveInterval := time.Duration(peer.PersistentKeepAliveInterval) peers = append(peers, wgtypes.PeerConfig{ PublicKey: publicKey, AllowedIPs: []net.IPNet{ { IP: net.ParseIP(peer.Address), Mask: net.CIDRMask(32, 32), }, }, PersistentKeepaliveInterval: &keepAliveInterval, }) peerDNSMappings[peer.Identifier] = peer.Address } // Create tunnel and device addresses := []netip.Addr{netip.MustParsePrefix(config.ListenAddress).Addr()} tunnelDev, tnet, err := netstack.CreateNetTUN(addresses, nil, device.DefaultMTU) if err != nil { log.Printf("Error creating TUN: %v", err) return } logger := device.NewLogger(device.LogLevelError, "WG") dev := device.NewDevice(tunnelDev, conn.NewDefaultBind(), logger) // -------- Enable forwarding through custom function -------- tnet.EnableForwarding() // ----------------------------------------------------------- if err := dev.Up(); err != nil { log.Printf("An error occurred while setting up device: %v\n", err) return } uapi, err := ipc.UAPIOpen(config.InterfaceName) if err != nil { log.Printf("Error opening uapi: %v", err) return } uapiListener, err := ipc.UAPIListen(config.InterfaceName, uapi) if err != nil { log.Printf("Failed to listen on uapi socket: %v\n", err) return } go func() { for { con, err := uapiListener.Accept() if err != nil { log.Printf("Error accepting connection: %v\n", err) return } go dev.IpcHandle(con) } }() client, err := wgctrl.New () if err != nil { log.Printf("Failed to create client: %v", err) return } // Setup gateway privateKey, err := wgtypes.ParseKey(config.PrivateKey) if err != nil { log.Printf("Failed to parse private key: %v", err) return } err = client.ConfigureDevice(config.InterfaceName, wgtypes.Config{ PrivateKey: &privateKey, ListenPort: &config.ListenPort, FirewallMark: nil, ReplacePeers: false, Peers: peers, }) if err != nil { log.Printf("Failed to configure device: %v\n", err) return } log.Printf("Listening for connections...") // Wait for exit signal sc := make(chan os.Signal, 1) signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt) <-sc // Cleanup uapi.Close() dev.Close() } ``` HTTP Client: ```go package main import ( "encoding/base64" "encoding/hex" "fmt" "io" "log" "net/http" "net/netip" "time" "golang.zx2c4.com/wireguard/conn " "golang.zx2c4.com/wireguard/device " "golang.zx2c4.com/wireguard/tun/netstack " ) const ( ClientPrivateKey = "" // HTTP client private key ServerPublicKey = "" // Hub public key ) func DecodeBase64StringToHex(base64String string) string { data, _ := base64.StdEncoding.DecodeString(base64String) return hex.EncodeToString(data) } func main() { tun, tnet, err := netstack.CreateNetTUN([]netip.Addr{netip.MustParseAddr("10.10.10.3")}, []netip.Addr{}, 1420) if err != nil { log.Panic(err) } dev := device.NewDevice(tun, conn.NewDefaultBind(), device.NewLogger(device.LogLevelVerbose, "")) configString := fmt.Sprintf("private_key=%s\npublic_key=%s\nallowed_ip=10.10.10.0/24\nendpoint=127.0.0.1:4444\npersistent_keepalive_interval=2", DecodeBase64StringToHex(ClientPrivateKey), DecodeBase64StringToHex(ServerPublicKey), ) err = dev.IpcSet(configString) if err != nil { log.Panic(err) } err = dev.Up() if err != nil { log.Panic(err) } client := http.Client{ Transport: &http.Transport{ DialContext: tnet.DialContext, }, Timeout: 3 * time.Second, } for { resp, err := client.Get("http://10.10.10.2/") if err != nil { log.Printf("Error: %v\n", err) continue } body, err := io.ReadAll(resp.Body) if err != nil { log.Printf("Error: %v\n", err) continue } log.Println(string(body)) } } ``` HTTP Server: ```go package main import ( "encoding/base64" "encoding/hex" "fmt" "io" "log" "net" "net/http" "net/netip" "golang.zx2c4.com/wireguard/conn " "golang.zx2c4.com/wireguard/device " "golang.zx2c4.com/wireguard/tun/netstack " ) const ( ClientPrivateKey = "" // HTTP server private key ServerPublicKey = "" // Hub public key ) func DecodeBase64StringToHex(base64String string) string { data, _ := base64.StdEncoding.DecodeString(base64String) return hex.EncodeToString(data) } func main() { tun, tnet, err := netstack.CreateNetTUN([]netip.Addr{netip.MustParseAddr("10.10.10.2")}, []netip.Addr{}, 1420) if err != nil { log.Panic(err) } dev := device.NewDevice(tun, conn.NewDefaultBind(), device.NewLogger(device.LogLevelVerbose, "")) configString := fmt.Sprintf("private_key=%s\npublic_key=%s\nallowed_ip=10.10.10.0/24\nendpoint=127.0.0.1:4444\npersistent_keepalive_interval=2\n", DecodeBase64StringToHex(ClientPrivateKey), DecodeBase64StringToHex(ServerPublicKey), ) err = dev.IpcSet(configString) if err != nil { log.Panic(err) } err = dev.Up() if err != nil { log.Panic(err) } listener, err := tnet.ListenTCP(&net.TCPAddr{Port: 80}) if err != nil { log.Panicln(err) } http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { log.Printf("> %s - %s - %s", request.RemoteAddr, request.URL.String(), request.UserAgent()) io.WriteString(writer, "Hello!") }) log.Printf("Listening for connections...") err = http.Serve(listener, nil) if err != nil { log.Panicln(err) } } ``` Now on to the problem I was facing: when I initially had this setup both http client/server programs were able to connect to the main hub server, but were not able to communicate with each another. I suspected this was an issue with packet forwarding being disabled but enabling it through the usual system route (`sysctl -w net.ipv4.ip_forward=1`) didn't appear to enable forwarding for my tunnel. After digging around the source of wireguard-go and seeing `tun/netstack/tun.go` and its usage of `gvisor.dev/gvisor/pkg/tcpip/stack ` I did some experimenting and added some code to call `SetForwardingDefaultAndAllNICs` as shown in the code snippets below, which appears to have resolved the internode communication issues I was running into. ```go func (net *Net) EnableForwarding() { if net.hasV4 { net.stack.SetForwardingDefaultAndAllNICs(ipv4.ProtocolNumber, true) } if net.hasV6 { net.stack.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, true) } } ``` My question is about whether this was the correct approach to resolve my internode connectivity issues, and furthermore if this solution has any other unintended consequences I might not immediately be seeing. I'd appreciate any and all help, thank you! Kind Regards, Tech From Jason at zx2c4.com Mon Mar 23 17:43:35 2026 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Mon, 23 Mar 2026 18:43:35 +0100 Subject: =?UTF-8?Q?Re=3A_gutd_=E2=80=94_WireGuard_traffic_obfuscator_via_TC=2FXDP?= =?UTF-8?Q?_eBPF_=28no_kernel_patches=29?= In-Reply-To: References: Message-ID: Hi sh0rch, This is an awesome project! It seems like doing this with eBPF and TC/XDP is exactly the right way to do this, and lets you just drop it in on top of an existing configuration. I really like this architecture. I'll try to find some time to look at the internals in proper detail. But I think this is basically the right direction. Thank you for implementing it! Jason From Jason at zx2c4.com Mon Mar 23 18:31:28 2026 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Mon, 23 Mar 2026 19:31:28 +0100 Subject: [PATCH] wireguard: use memzero_explicit() when zeroing handshake key material In-Reply-To: <20260318230635.227291-1-jeroen@robben.io> References: <20260318230635.227291-1-jeroen@robben.io> Message-ID: On Mon, Mar 23, 2026 at 6:42?PM Jeroen Robben wrote: > > Replace memset() calls in handshake_zero() with memzero_explicit() > to ensure clearing handshake state is not optimized away by the compiler. Why would the compiler do this? These aren't some stack variables that are never touched again subsequently. It's zeroing out some members of a pointer that lives elsewhere. From Jason at zx2c4.com Mon Mar 23 18:38:50 2026 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Mon, 23 Mar 2026 19:38:50 +0100 Subject: Sunsetting support for old Windows versions In-Reply-To: References: Message-ID: On Mon, Mar 23, 2026 at 7:34?PM Jeffrey Walton wrote: > WIndows 7 market share dropped to around 1% in January 2026. I think it is a good decision. Confer, . What do you suppose accounts for that December->January change? Some large operator enabled a TLS configuration not supported by the OS / by Chrome 109? From Jason at zx2c4.com Mon Mar 23 18:47:56 2026 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Mon, 23 Mar 2026 19:47:56 +0100 Subject: Sunsetting support for old Windows versions In-Reply-To: References: Message-ID: On Mon, Mar 23, 2026 at 7:38?PM Jason A. Donenfeld wrote: > > On Mon, Mar 23, 2026 at 7:34?PM Jeffrey Walton wrote: > > WIndows 7 market share dropped to around 1% in January 2026. I think it is a good decision. Confer, . > > What do you suppose accounts for that December->January change? Some > large operator enabled a TLS configuration not supported by the OS / > by Chrome 109? Ahh, the reason is that Server 2008R2 ESU ended January 13, 2026, and enterprising users, god bless them, had previously hacked the update mechanism on 7 to get those updates. From noloader at gmail.com Mon Mar 23 18:34:18 2026 From: noloader at gmail.com (Jeffrey Walton) Date: Mon, 23 Mar 2026 14:34:18 -0400 Subject: Sunsetting support for old Windows versions In-Reply-To: References: Message-ID: On Mon, Mar 23, 2026 at 1:09?PM Jason A. Donenfeld wrote: > Hey everyone, > > The time has finally come. Future releases of WireGuard for Windows > will support Windows ?10 and Windows Server ?2016. > > With Windows 10 first released to manufacturing on July 15, 2015, > that's supporting an operating system that's 3,904 days old, as > opposed to supporting an operating system that's 6,088 days old. > Nonetheless, supporting an OS that's over 10 years old is still a long > time, even if it's not an OS that's over 16 years old. > > I must admit, however, that I am a bit sad about this. After coding up > [1] this dialog box for the installer, I felt a few pangs of sadness > when testing it for the first time on Windows 7 and seeing the tragic > result: https://data.zx2c4.com/bye-bye-wg-win7.png . But it was a > familiar feeling. For, long ago, I'd already watched the beauty of > Windows fall to pieces. To me, Windows 2000 is the most beautiful of > Windows operating systems. Yes, we can all ogle at the engineering > marvel that was NT 3.51. But Windows 2000 really elevated that whole > vision to perfection, and was also the pinnacle of the classic UI > design. I can't think of a classier OS released since. Though, I must > say, it was Windows XP that captured my heart and formed the basis of > my childhood, the new style and all; I would switch between classic > theme and the XP theme frequently, and later flirted a bit with the > MCE themes. It was just a very nice OS, had everything one could want, > a great suite of software, really good stability, ever widening > hardware support, sane and consistent interfaces. It came > pre-installed on my Dell Inspiron 8100 and I loved it. At some point I > switched to running Linux on my laptop, but would still sneak down to > the family computer to fiddle around with Windows development on our > XP machine. I could go on and on. Then Vista was released, and it was > annoying and introduced inconsistencies, which Windows 7 tried to > smooth out and succeeded to some degree, but it was just never the > same to me. And we all remember what happened next with 8, 8.1, 10, > and 11. > > So, it's sad to make this change, but it's far less sad than what > already happened in the Windows world post 2000 and post XP. > > On the plus side, this has enabled a lot of significant cleanups > throughout the code, and will be yielding more and more as this > process continues. Windows programming is as fun as ever -- arguably > more fun, as the archaeological dumpster heap of historic Microsoft > APIs, each one filled with a unique history and competing corporate > and technical vision of operating system futurism, only ever gets > deeper to dive in. So I'm relatively happy to make this change, even > if somewhat wistful about it. > > I had first asked the mailing list whether this was acceptable in 2020 > and then again in 2021. Fast forward 5 years and the ecosystem has > changed a lot, and our upstream dependencies have similarly dropped > support. I realize this leaves the still-technically-supported Server > 2012 and 2012R2 out in the cold, but 8 and 8.1 haven't been supported > in two years, and I think most realistic users have similarly dropped > the corresponding server editions. In other words, I don't anticipate > any real fallout. However, I know that Windows 7 and Server 2008 and > 2008R2 users are usually pretty committed to their ways and can be > vocal. So, by all means pipe up to sing an elegy if you'd like. But > we're moving forward with the sunsetting. > > I hope this all seems reasonable enough. Let's pour one out for > Blackcomb/Vienna, and while we're at it, for Whistler long before > that. > > Jason > > [1] > https://git.zx2c4.com/wireguard-windows/tree/installer/customactions.c#n101 WIndows 7 market share dropped to around 1% in January 2026. I think it is a good decision. Confer, < https://gs.statcounter.com/os-version-market-share/windows/desktop/worldwide >. It's a damn shame, though. I think Windows 7 is one of the best Windows releases from Redmond. If Windows 7 had a 3% market share, I would argue to keep the support. But going below 3% was a death knell. Jeff From sh0rch at iwl.dev Mon Mar 23 22:41:07 2026 From: sh0rch at iwl.dev (sh0rch) Date: Mon, 23 Mar 2026 22:41:07 +0000 Subject: =?utf-8?B?UkU6IGd1dGQg4oCUIFdpcmVHdWFyZCB0cmFmZmljIG9iZnVzY2F0b3Igdmlh?= =?utf-8?Q?_TC/XDP_eBPF_(no_kernel_patches)?= In-Reply-To: References: Message-ID: Hi Jason, Thanks a lot for the kind words, really means a lot. I?m very happy the approach makes sense from your perspective. The whole idea was to keep it simple to deploy on top of existing WireGuard setups, without touching the kernel, while still getting the benefits of eBPF. And also huge thanks to you for WireGuard itself. It?s honestly an amazing protocol: simple, secure, fast, and so cleanly designed that sometimes it feels like even the whole world isn?t enough for it :) If you do find time to investigate the internals, I?d really appreciate any thoughts or feedback you might have. Thanks again! With best wishes, Danila Makeev -----Original Message----- From: Jason A. Donenfeld Sent: 23 March 2026 20:44 To: sh0rch Cc: wireguard at lists.zx2c4.com Subject: Re: gutd ? WireGuard traffic obfuscator via TC/XDP eBPF (no kernel patches) Hi sh0rch, This is an awesome project! It seems like doing this with eBPF and TC/XDP is exactly the right way to do this, and lets you just drop it in on top of an existing configuration. I really like this architecture. I'll try to find some time to look at the internals in proper detail. But I think this is basically the right direction. Thank you for implementing it! Jason From toke at toke.dk Tue Mar 24 10:42:23 2026 From: toke at toke.dk (Toke =?utf-8?Q?H=C3=B8iland-J=C3=B8rgensen?=) Date: Tue, 24 Mar 2026 11:42:23 +0100 Subject: gutd =?utf-8?Q?=E2=80=94?= WireGuard traffic obfuscator via TC/XDP eBPF (no kernel patches) In-Reply-To: References: Message-ID: <87qzp9mru8.fsf@toke.dk> > Would appreciate any feedback - especially on the BPF approach, Cool project! A couple of comments on the BPF side: - It looks like you're using libbpf_rs to load the BPF programs. Have you considered using the (pure rust) Aya library instead (https://github.com/aya-rs/aya)? If so, what was the reason for choosing the libbpf wrapper instead? - From a quick look at the architecture doc, I don't understand why you need the veth pair? You're just rewriting packet contents, this could just as well be done in the TC hook (egress and ingress) of the physical NIC, and from the wireguard PoV it would just look like wg itself is speaking directly to the other tunnel peer? -Toke From fmancera at suse.de Wed Mar 25 12:08:47 2026 From: fmancera at suse.de (Fernando Fernandez Mancera) Date: Wed, 25 Mar 2026 13:08:47 +0100 Subject: [PATCH 06/11 net-next v5] drivers: net: drop ipv6_stub usage and use direct function calls In-Reply-To: <20260325120928.15848-1-fmancera@suse.de> References: <20260325120928.15848-1-fmancera@suse.de> Message-ID: <20260325120928.15848-7-fmancera@suse.de> As IPv6 is built-in only, the ipv6_stub infrastructure is no longer necessary. Convert all drivers currently utilizing ipv6_stub to make direct function calls. The fallback functions introduced previously will prevent linkage errors when CONFIG_IPV6 is disabled. Signed-off-by: Fernando Fernandez Mancera Tested-by: Ricardo B. Marli?re Reviewed-by: Jason A. Donenfeld Reviewed-by: Antonio Quartulli Reviewed-by: Edward Cree --- drivers/infiniband/core/addr.c | 3 +-- drivers/infiniband/sw/rxe/rxe_net.c | 6 +++--- .../ethernet/mellanox/mlx5/core/en/rep/neigh.c | 9 +++++---- .../net/ethernet/mellanox/mlx5/core/en/tc_tun.c | 3 +-- .../mellanox/mlx5/core/en/tc_tun_encap.c | 2 +- .../mellanox/mlx5/core/en_accel/ipsec.c | 1 - .../net/ethernet/mellanox/mlx5/core/en_rep.c | 1 - drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 1 - .../net/ethernet/netronome/nfp/flower/action.c | 2 +- .../ethernet/netronome/nfp/flower/tunnel_conf.c | 7 +++---- drivers/net/ethernet/sfc/tc_counters.c | 2 +- drivers/net/ethernet/sfc/tc_encap_actions.c | 5 ++--- drivers/net/geneve.c | 1 - drivers/net/gtp.c | 2 +- drivers/net/ovpn/peer.c | 3 +-- drivers/net/ovpn/udp.c | 3 +-- drivers/net/usb/cdc_mbim.c | 17 +++++++++-------- drivers/net/vxlan/vxlan_core.c | 11 +++++------ drivers/net/vxlan/vxlan_multicast.c | 6 ++---- drivers/net/wireguard/socket.c | 3 +-- drivers/net/wireless/intel/ipw2x00/ipw2100.c | 2 +- net/bridge/br_arp_nd_proxy.c | 3 +-- 22 files changed, 40 insertions(+), 53 deletions(-) diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 866746695712..48d4b06384ec 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -411,7 +410,7 @@ static int addr6_resolve(struct sockaddr *src_sock, fl6.saddr = src_in->sin6_addr; fl6.flowi6_oif = addr->bound_dev_if; - dst = ipv6_stub->ipv6_dst_lookup_flow(addr->net, NULL, &fl6, NULL); + dst = ip6_dst_lookup_flow(addr->net, NULL, &fl6, NULL); if (IS_ERR(dst)) return PTR_ERR(dst); diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c index 0bd0902b11f7..cbc646a30003 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.c +++ b/drivers/infiniband/sw/rxe/rxe_net.c @@ -138,9 +138,9 @@ static struct dst_entry *rxe_find_route6(struct rxe_qp *qp, memcpy(&fl6.daddr, daddr, sizeof(*daddr)); fl6.flowi6_proto = IPPROTO_UDP; - ndst = ipv6_stub->ipv6_dst_lookup_flow(sock_net(recv_sockets.sk6->sk), - recv_sockets.sk6->sk, &fl6, - NULL); + ndst = ip6_dst_lookup_flow(sock_net(recv_sockets.sk6->sk), + recv_sockets.sk6->sk, &fl6, + NULL); if (IS_ERR(ndst)) { rxe_dbg_qp(qp, "no route to %pI6\n", daddr); return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c index d220b045b331..648f4521c096 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "neigh.h" #include "tc.h" #include "en_rep.h" @@ -18,8 +19,8 @@ static unsigned long mlx5e_rep_ipv6_interval(void) { - if (IS_ENABLED(CONFIG_IPV6) && ipv6_stub->nd_tbl) - return NEIGH_VAR(&ipv6_stub->nd_tbl->parms, DELAY_PROBE_TIME); + if (IS_ENABLED(CONFIG_IPV6) && ipv6_mod_enabled()) + return NEIGH_VAR(&nd_tbl.parms, DELAY_PROBE_TIME); return ~0UL; } @@ -217,7 +218,7 @@ static int mlx5e_rep_netevent_event(struct notifier_block *nb, case NETEVENT_NEIGH_UPDATE: n = ptr; #if IS_ENABLED(CONFIG_IPV6) - if (n->tbl != ipv6_stub->nd_tbl && n->tbl != &arp_tbl) + if (n->tbl != &nd_tbl && n->tbl != &arp_tbl) #else if (n->tbl != &arp_tbl) #endif @@ -238,7 +239,7 @@ static int mlx5e_rep_netevent_event(struct notifier_block *nb, * done per device delay prob time parameter. */ #if IS_ENABLED(CONFIG_IPV6) - if (!p->dev || (p->tbl != ipv6_stub->nd_tbl && p->tbl != &arp_tbl)) + if (!p->dev || (p->tbl != &nd_tbl && p->tbl != &arp_tbl)) #else if (!p->dev || p->tbl != &arp_tbl) #endif diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c index a14f216048cd..de74dbfe7b20 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c @@ -453,8 +453,7 @@ static int mlx5e_route_lookup_ipv6_get(struct mlx5e_priv *priv, if (tunnel && tunnel->get_remote_ifindex) attr->fl.fl6.flowi6_oif = tunnel->get_remote_ifindex(dev); - dst = ipv6_stub->ipv6_dst_lookup_flow(dev_net(dev), NULL, &attr->fl.fl6, - NULL); + dst = ip6_dst_lookup_flow(dev_net(dev), NULL, &attr->fl.fl6, NULL); if (IS_ERR(dst)) return PTR_ERR(dst); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c index bfd401bee9e8..8b827201935e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c @@ -402,7 +402,7 @@ void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe) tbl = &arp_tbl; #if IS_ENABLED(CONFIG_IPV6) else if (m_neigh->family == AF_INET6) - tbl = ipv6_stub->nd_tbl; + tbl = &nd_tbl; #endif else return; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c index 64e13747084e..a52e12c3c95a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c @@ -36,7 +36,6 @@ #include #include #include -#include #include "en.h" #include "eswitch.h" diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 8992f0f7a870..ba6c0f38cc73 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -38,7 +38,6 @@ #include #include #include -#include #include "eswitch.h" #include "en.h" diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 397a93584fd6..a9001d1c902f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c index aca2a7417af3..ae2f8b31adfb 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/action.c +++ b/drivers/net/ethernet/netronome/nfp/flower/action.c @@ -470,7 +470,7 @@ nfp_fl_set_tun(struct nfp_app *app, struct nfp_fl_set_tun *set_tun, flow.daddr = ip_tun->key.u.ipv6.dst; flow.flowi4_proto = IPPROTO_UDP; - dst = ipv6_stub->ipv6_dst_lookup_flow(net, NULL, &flow, NULL); + dst = ip6_dst_lookup_flow(net, NULL, &flow, NULL); if (!IS_ERR(dst)) { set_tun->ttl = ip6_dst_hoplimit(dst); dst_release(dst); diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c index 0cef0e2b85d0..ca30702f8878 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c +++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c @@ -650,7 +650,7 @@ static void nfp_tun_neigh_update(struct work_struct *work) flow6.daddr = *(struct in6_addr *)n->primary_key; if (!neigh_invalid) { struct dst_entry *dst; - /* Use ipv6_dst_lookup_flow to populate flow6->saddr + /* Use ip6_dst_lookup_flow to populate flow6->saddr * and other fields. This information is only needed * for new entries, lookup can be skipped when an entry * gets invalidated - as only the daddr is needed for @@ -730,7 +730,7 @@ nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event, return NOTIFY_DONE; } #if IS_ENABLED(CONFIG_IPV6) - if (n->tbl != ipv6_stub->nd_tbl && n->tbl != &arp_tbl) + if (n->tbl != &nd_tbl && n->tbl != &arp_tbl) #else if (n->tbl != &arp_tbl) #endif @@ -815,8 +815,7 @@ void nfp_tunnel_request_route_v6(struct nfp_app *app, struct sk_buff *skb) flow.flowi6_proto = IPPROTO_UDP; #if IS_ENABLED(CONFIG_INET) && IS_ENABLED(CONFIG_IPV6) - dst = ipv6_stub->ipv6_dst_lookup_flow(dev_net(netdev), NULL, &flow, - NULL); + dst = ip6_dst_lookup_flow(dev_net(netdev), NULL, &flow, NULL); if (IS_ERR(dst)) goto fail_rcu_unlock; #else diff --git a/drivers/net/ethernet/sfc/tc_counters.c b/drivers/net/ethernet/sfc/tc_counters.c index d168282f30bf..b84235e93ffe 100644 --- a/drivers/net/ethernet/sfc/tc_counters.c +++ b/drivers/net/ethernet/sfc/tc_counters.c @@ -112,7 +112,7 @@ static void efx_tc_counter_work(struct work_struct *work) encap->neigh->egdev); else #if IS_ENABLED(CONFIG_IPV6) - n = neigh_lookup(ipv6_stub->nd_tbl, + n = neigh_lookup(&nd_tbl, &encap->neigh->dst_ip6, encap->neigh->egdev); #else diff --git a/drivers/net/ethernet/sfc/tc_encap_actions.c b/drivers/net/ethernet/sfc/tc_encap_actions.c index da35705cc5e1..db222abef53b 100644 --- a/drivers/net/ethernet/sfc/tc_encap_actions.c +++ b/drivers/net/ethernet/sfc/tc_encap_actions.c @@ -149,8 +149,7 @@ static int efx_bind_neigh(struct efx_nic *efx, #if IS_ENABLED(CONFIG_IPV6) struct dst_entry *dst; - dst = ipv6_stub->ipv6_dst_lookup_flow(net, NULL, &flow6, - NULL); + dst = ip6_dst_lookup_flow(net, NULL, &flow6, NULL); rc = PTR_ERR_OR_ZERO(dst); if (rc) { NL_SET_ERR_MSG_MOD(extack, "Failed to lookup route for IPv6 encap"); @@ -531,7 +530,7 @@ static int efx_neigh_event(struct efx_nic *efx, struct neighbour *n) if (n->tbl == &arp_tbl) { keysize = sizeof(keys.dst_ip); #if IS_ENABLED(CONFIG_IPV6) - } else if (n->tbl == ipv6_stub->nd_tbl) { + } else if (n->tbl == &nd_tbl) { ipv6 = true; keysize = sizeof(keys.dst_ip6); #endif diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 01cdd06102e0..c6563367d382 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index e8949f556209..70b9e58b9b78 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -374,7 +374,7 @@ static struct rt6_info *ip6_route_output_gtp(struct net *net, fl6->saddr = *saddr; fl6->flowi6_proto = sk->sk_protocol; - dst = ipv6_stub->ipv6_dst_lookup_flow(net, sk, fl6, NULL); + dst = ip6_dst_lookup_flow(net, sk, fl6, NULL); if (IS_ERR(dst)) return ERR_PTR(-ENETUNREACH); diff --git a/drivers/net/ovpn/peer.c b/drivers/net/ovpn/peer.c index 26b55d813f0e..c02dfab51a6e 100644 --- a/drivers/net/ovpn/peer.c +++ b/drivers/net/ovpn/peer.c @@ -827,8 +827,7 @@ static struct in6_addr ovpn_nexthop_from_rt6(struct ovpn_priv *ovpn, .daddr = dest, }; - entry = ipv6_stub->ipv6_dst_lookup_flow(dev_net(ovpn->dev), NULL, &fl, - NULL); + entry = ip6_dst_lookup_flow(dev_net(ovpn->dev), NULL, &fl, NULL); if (IS_ERR(entry)) { net_dbg_ratelimited("%s: no route to host %pI6c\n", netdev_name(ovpn->dev), &dest); diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c index 272b535ecaad..059e896b4a2f 100644 --- a/drivers/net/ovpn/udp.c +++ b/drivers/net/ovpn/udp.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -251,7 +250,7 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, dst_cache_reset(cache); } - dst = ipv6_stub->ipv6_dst_lookup_flow(sock_net(sk), sk, &fl, NULL); + dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl, NULL); if (IS_ERR(dst)) { ret = PTR_ERR(dst); net_dbg_ratelimited("%s: no route to host %pISpc: %d\n", diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c index dbf01210b0e7..877fb0ed7d3d 100644 --- a/drivers/net/usb/cdc_mbim.c +++ b/drivers/net/usb/cdc_mbim.c @@ -20,7 +20,6 @@ #include #include #include -#include #include /* alternative VLAN for IP session 0 if not untagged */ @@ -302,6 +301,7 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb return NULL; } +#if IS_ENABLED(CONFIG_IPV6) /* Some devices are known to send Neighbor Solicitation messages and * require Neighbor Advertisement replies. The IPv6 core will not * respond since IFF_NOARP is set, so we must handle them ourselves. @@ -342,12 +342,11 @@ static void do_neigh_solicit(struct usbnet *dev, u8 *buf, u16 tci) is_router = !!READ_ONCE(in6_dev->cnf.forwarding); in6_dev_put(in6_dev); - /* ipv6_stub != NULL if in6_dev_get returned an inet6_dev */ - ipv6_stub->ndisc_send_na(netdev, &iph->saddr, &msg->target, - is_router /* router */, - true /* solicited */, - false /* override */, - true /* inc_opt */); + ndisc_send_na(netdev, &iph->saddr, &msg->target, + is_router /* router */, + true /* solicited */, + false /* override */, + true /* inc_opt */); out: dev_put(netdev); } @@ -362,7 +361,7 @@ static bool is_neigh_solicit(u8 *buf, size_t len) msg->icmph.icmp6_code == 0 && msg->icmph.icmp6_type == NDISC_NEIGHBOUR_SOLICITATION); } - +#endif /* IPV6 */ static struct sk_buff *cdc_mbim_process_dgram(struct usbnet *dev, u8 *buf, size_t len, u16 tci) { @@ -378,8 +377,10 @@ static struct sk_buff *cdc_mbim_process_dgram(struct usbnet *dev, u8 *buf, size_ proto = htons(ETH_P_IP); break; case 0x60: +#if IS_ENABLED(CONFIG_IPV6) if (is_neigh_solicit(buf, len)) do_neigh_solicit(dev, buf, tci); +#endif proto = htons(ETH_P_IPV6); break; default: diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c index 17c941aac32d..b5fbd03418b6 100644 --- a/drivers/net/vxlan/vxlan_core.c +++ b/drivers/net/vxlan/vxlan_core.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -2045,7 +2044,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni) ipv6_addr_is_multicast(&msg->target)) goto out; - n = neigh_lookup(ipv6_stub->nd_tbl, &msg->target, dev); + n = neigh_lookup(&nd_tbl, &msg->target, dev); if (n) { struct vxlan_rdst *rdst = NULL; @@ -2130,15 +2129,15 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb) { struct ipv6hdr *pip6; - /* check if nd_tbl is not initiliazed due to - * ipv6.disable=1 set during boot + /* check if ipv6.disable=1 set during boot was set + * during booting so nd_tbl is not initialized */ - if (!ipv6_stub->nd_tbl) + if (!ipv6_mod_enabled()) return false; if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) return false; pip6 = ipv6_hdr(skb); - n = neigh_lookup(ipv6_stub->nd_tbl, &pip6->daddr, dev); + n = neigh_lookup(&nd_tbl, &pip6->daddr, dev); if (!n && (vxlan->cfg.flags & VXLAN_F_L3MISS)) { union vxlan_addr ipa = { .sin6.sin6_addr = pip6->daddr, diff --git a/drivers/net/vxlan/vxlan_multicast.c b/drivers/net/vxlan/vxlan_multicast.c index a7f2d67dc61b..b0e80bca855c 100644 --- a/drivers/net/vxlan/vxlan_multicast.c +++ b/drivers/net/vxlan/vxlan_multicast.c @@ -39,8 +39,7 @@ int vxlan_igmp_join(struct vxlan_dev *vxlan, union vxlan_addr *rip, sk = sock6->sock->sk; lock_sock(sk); - ret = ipv6_stub->ipv6_sock_mc_join(sk, ifindex, - &ip->sin6.sin6_addr); + ret = ipv6_sock_mc_join(sk, ifindex, &ip->sin6.sin6_addr); release_sock(sk); #endif } @@ -73,8 +72,7 @@ int vxlan_igmp_leave(struct vxlan_dev *vxlan, union vxlan_addr *rip, sk = sock6->sock->sk; lock_sock(sk); - ret = ipv6_stub->ipv6_sock_mc_drop(sk, ifindex, - &ip->sin6.sin6_addr); + ret = ipv6_sock_mc_drop(sk, ifindex, &ip->sin6.sin6_addr); release_sock(sk); #endif } diff --git a/drivers/net/wireguard/socket.c b/drivers/net/wireguard/socket.c index 253488f8c00f..c362c78d908e 100644 --- a/drivers/net/wireguard/socket.c +++ b/drivers/net/wireguard/socket.c @@ -136,8 +136,7 @@ static int send6(struct wg_device *wg, struct sk_buff *skb, if (cache) dst_cache_reset(cache); } - dst = ipv6_stub->ipv6_dst_lookup_flow(sock_net(sock), sock, &fl, - NULL); + dst = ip6_dst_lookup_flow(sock_net(sock), sock, &fl, NULL); if (IS_ERR(dst)) { ret = PTR_ERR(dst); net_dbg_ratelimited("%s: No route to %pISpfsc, error %d\n", diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c index 248a051da52d..c11428485dcc 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c @@ -4838,7 +4838,7 @@ static int ipw2100_system_config(struct ipw2100_priv *priv, int batch_mode) /* If IPv6 is configured in the kernel then we don't want to filter out all * of the multicast packets as IPv6 needs some. */ -#if !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE) +#if !defined(CONFIG_IPV6) cmd.host_command = ADD_MULTICAST; cmd.host_command_sequence = 0; cmd.host_command_length = 0; diff --git a/net/bridge/br_arp_nd_proxy.c b/net/bridge/br_arp_nd_proxy.c index 1e2b51769eec..c06386eda47f 100644 --- a/net/bridge/br_arp_nd_proxy.c +++ b/net/bridge/br_arp_nd_proxy.c @@ -17,7 +17,6 @@ #include #include #include -#include #if IS_ENABLED(CONFIG_IPV6) #include #endif @@ -455,7 +454,7 @@ void br_do_suppress_nd(struct sk_buff *skb, struct net_bridge *br, return; } - n = neigh_lookup(ipv6_stub->nd_tbl, &msg->target, vlandev); + n = neigh_lookup(&nd_tbl, &msg->target, vlandev); if (n) { struct net_bridge_fdb_entry *f; -- 2.53.0 From toke at toke.dk Thu Mar 26 16:30:44 2026 From: toke at toke.dk (Toke =?utf-8?Q?H=C3=B8iland-J=C3=B8rgensen?=) Date: Thu, 26 Mar 2026 17:30:44 +0100 Subject: gutd =?utf-8?Q?=E2=80=94?= WireGuard traffic obfuscator via TC/XDP eBPF (no kernel patches) In-Reply-To: References: <87qzp9mru8.fsf@toke.dk> Message-ID: <871ph6o8nf.fsf@toke.dk> sh0rch writes: > Hi Toke, > > Thanks a lot for taking a look, really appreciate it! > > I actually started with Aya, but ended up losing some hair fighting > the verifier :) libbpf_rs just worked for me in the end. Yeah, writing the BPF code in Rust is hard, still, but you could still use Aya to load, and avoid the extra dependency on libbpf? Not sure how much of a difference that makes in practice (I just noted you were chasing small binaries, so maybe that would help?) > About the veth. I?m trying to keep things compatible with stock > WireGuard and also need proper routing through a relay/gateway. Inside > my perimeter I can use plain WG, but to get traffic out I rely on a > gateway, so I need packets to go through the normal networking stack. > If everything happens in eBPF, it won?t even reach netfilter. That?s > why I went with veth, also gives a bit more flexibility than tun/tap. Hmm, not sure I undestrand what you mean by "rely on a gateway"? What breaks if it's run only on TC, exactly? In any case, if you need the extra step you could still have the BPF programs run on the other side of the veth device, but still just as a pair of TC ingress/egress programs? That would still simplify the BPF side of things, and make the usage of veth devices optional. > Ideally this would all live in AF_XDP + userspace, but that?s hard to > rely on in VPS environments where AF_XDP support is still limited. Don't think you'd get very good performance doing that, AF_XDP has a pretty severe performance penalty if you want to re-inject packets into the kernel. So unless you're actually creating an obfuscating middlebox, going with BPF like you did here seems like a better solution :) -Toke From david.laight.linux at gmail.com Thu Mar 26 20:18:36 2026 From: david.laight.linux at gmail.com (david.laight.linux at gmail.com) Date: Thu, 26 Mar 2026 20:18:36 +0000 Subject: [PATCH next] wireguard: selftests: Remove spurious precision from banner printf Message-ID: <20260326201836.3957-1-david.laight.linux@gmail.com> From: David Laight Change ("%*.s", len, "") to ("%*s", len, ""). The former is equivalent to "%*.0s" but is really a typing mistake. No actual change to the output. Signed-off-by: David Laight --- tools/testing/selftests/wireguard/qemu/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/wireguard/qemu/init.c b/tools/testing/selftests/wireguard/qemu/init.c index 3e49924dd77e..c87570494d30 100644 --- a/tools/testing/selftests/wireguard/qemu/init.c +++ b/tools/testing/selftests/wireguard/qemu/init.c @@ -53,7 +53,7 @@ static void print_banner(void) panic("uname"); len = strlen(" WireGuard Test Suite on ") + strlen(utsname.sysname) + strlen(utsname.release) + strlen(utsname.machine); - printf("\x1b[45m\x1b[33m\x1b[1m%*.s\x1b[0m\n\x1b[45m\x1b[33m\x1b[1m WireGuard Test Suite on %s %s %s \x1b[0m\n\x1b[45m\x1b[33m\x1b[1m%*.s\x1b[0m\n\n", len, "", utsname.sysname, utsname.release, utsname.machine, len, ""); + printf("\x1b[45m\x1b[33m\x1b[1m%*s\x1b[0m\n\x1b[45m\x1b[33m\x1b[1m WireGuard Test Suite on %s %s %s \x1b[0m\n\x1b[45m\x1b[33m\x1b[1m%*s\x1b[0m\n\n", len, "", utsname.sysname, utsname.release, utsname.machine, len, ""); } static void seed_rng(void) -- 2.39.5 From ebiggers at kernel.org Tue Mar 31 00:13:58 2026 From: ebiggers at kernel.org (Eric Biggers) Date: Mon, 30 Mar 2026 17:13:58 -0700 Subject: Kernel ML-KEM implementation plans In-Reply-To: <5F9ACD7A-F3B8-463A-A00E-28F68819A66C@gmail.com> References: <5F9ACD7A-F3B8-463A-A00E-28F68819A66C@gmail.com> Message-ID: <20260331001358.GA5190@sol> On Mon, Mar 30, 2026 at 06:41:46PM -0500, Ryan Appel wrote: > Hello all, > > Looking through the mail archives I see no information on an > implementation of ML-KEM that has been planned, except for leancrypto > attempting to make a Key-Agreement Scheme a Key-Encapsulation > Mechanism. > > Is there a plan to implement a KEM interface at this point? Is this > something that needs support? How could someone contribute to this? We don't add new algorithms preemptively, but rather only when an in-kernel user comes along. Otherwise there's a risk that the code will never be used. Do you have a specific in-kernel user in mind? I haven't actually heard anyone specifically say they need ML-KEM in the kernel yet. I guess the obvious use case would be WireGuard. But that would require a new WireGuard protocol version that replaces X25519 with something like X25519MLKEM768. It's going to be up to the WireGuard author (Jason) to decide whether that's in the roadmap for WireGuard. Also maybe Bluetooth, though it seems the spec for that is yet to be defined? Anyway, point is, before it makes sense to consider possible implementation strategies, there needs to be a plan to actually use it. - Eric From ebiggers at kernel.org Tue Mar 31 01:11:33 2026 From: ebiggers at kernel.org (Eric Biggers) Date: Mon, 30 Mar 2026 18:11:33 -0700 Subject: Kernel ML-KEM implementation plans In-Reply-To: <7507DE2E-1507-4D03-B6EF-9C139BBF34F8@gmail.com> References: <20260331001358.GA5190@sol> <7507DE2E-1507-4D03-B6EF-9C139BBF34F8@gmail.com> Message-ID: <20260331011133.GB5190@sol> On Mon, Mar 30, 2026 at 07:44:55PM -0500, Ryan Appel wrote: > WireGuard was my big implementation user. Any more details on this? Googling for research papers shows that there have indeed been several proposals for quantum-resistant WireGuard. But some use algorithms other than ML-KEM. Others don't modify the kernel code but rather do the key establishment in userspace. I haven't looked into the details, but it also sounds like it's not as simple as swapping out the algorithm, either. I think step 1 is work out some plan with the WireGuard folks. Which may or may not turn out to involve in-kernel ML-KEM. > I also know that VMware uses the kernel crypto space for many of its > crypto operations. I do not know when they will want ML-KEM and if > they will want it only within BoringCrypto or OpenSSL, but if there is > need for it in the market before it can be developed then that makes > sense. That code isn't upstream though, right? So even if hypothetically they (will?) need ML-KEM in the kernel (for what?), that doesn't count for upstream purposes. - Eric From syzbot+b0ae8f1abf7d891e0426 at syzkaller.appspotmail.com Tue Mar 31 17:17:27 2026 From: syzbot+b0ae8f1abf7d891e0426 at syzkaller.appspotmail.com (syzbot) Date: Tue, 31 Mar 2026 10:17:27 -0700 Subject: [syzbot] [net] INFO: task hung in tun_chr_close (5) In-Reply-To: <000000000000bd671b06222de427@google.com> Message-ID: <69cc01a7.050a0220.183828.002d.GAE@google.com> syzbot has found a reproducer for the following issue on: HEAD commit: 47ab2c12c87a Merge branch 'correct-bd-length-masks-and-bql.. git tree: net console output: https://syzkaller.appspot.com/x/log.txt?x=153aed02580000 kernel config: https://syzkaller.appspot.com/x/.config?x=6754c86e8d9e4c91 dashboard link: https://syzkaller.appspot.com/bug?extid=b0ae8f1abf7d891e0426 compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8 syz repro: https://syzkaller.appspot.com/x/repro.syz?x=1286e8d2580000 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=106df5da580000 Downloadable assets: disk image: https://storage.googleapis.com/syzbot-assets/289234295ce6/disk-47ab2c12.raw.xz vmlinux: https://storage.googleapis.com/syzbot-assets/b3f30eb7dc01/vmlinux-47ab2c12.xz kernel image: https://storage.googleapis.com/syzbot-assets/62a0f5642c08/bzImage-47ab2c12.xz The issue was bisected to: commit 5a781ccbd19e4664babcbe4b4ead7aa2b9283d22 Author: Vinicius Costa Gomes Date: Sat Sep 29 00:59:43 2018 +0000 tc: Add support for configuring the taprio scheduler bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=11535418580000 final oops: https://syzkaller.appspot.com/x/report.txt?x=13535418580000 console output: https://syzkaller.appspot.com/x/log.txt?x=15535418580000 IMPORTANT: if you fix the issue, please add the following tag to the commit: Reported-by: syzbot+b0ae8f1abf7d891e0426 at syzkaller.appspotmail.com Fixes: 5a781ccbd19e ("tc: Add support for configuring the taprio scheduler") INFO: task syz-executor:5978 blocked for more than 143 seconds. Not tainted syzkaller #0 Blocked by coredump. "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:syz-executor state:D stack:22400 pid:5978 tgid:5978 ppid:1 task_flags:0x40054c flags:0x00080003 Call Trace: context_switch kernel/sched/core.c:5298 [inline] __schedule+0x15dd/0x52d0 kernel/sched/core.c:6911 __schedule_loop kernel/sched/core.c:6993 [inline] schedule+0x164/0x360 kernel/sched/core.c:7008 schedule_preempt_disabled+0x13/0x30 kernel/sched/core.c:7065 __mutex_lock_common kernel/locking/mutex.c:692 [inline] __mutex_lock+0x7fe/0x1300 kernel/locking/mutex.c:776 tun_detach drivers/net/tun.c:634 [inline] tun_chr_close+0x3e/0x1c0 drivers/net/tun.c:3436 --- If you want syzbot to run the reproducer, reply with: #syz test: git://repo/address.git branch-or-commit-hash If you attach or paste a git patch, syzbot will apply it before testing. From mail at aparcar.org Tue Mar 31 20:14:51 2026 From: mail at aparcar.org (Paul Spooren) Date: Tue, 31 Mar 2026 22:14:51 +0200 Subject: Export noise primitives for additional "chain key ratcheting" Message-ID: <9E8ACE91-126B-41BD-BCE2-8B54DCE78B97@aparcar.org> Hi, I?m looking into hardening WireGuard against quantum computers, specifically how to extend the Noise-based handshake. A bit of background, while PSK injection with external daemons for forward secrecy, exists, that?s extra software running, exposing extra ports etc. Modifying a Rust/Go implementation is easier than the Kernel, but my background is running things on WiFi routers, so Kernel is preferred. That said, I?d like to extend the current WireGuard message format and attach PQC without exceeding the IPv6 MTU of 1280 bytes. In literature I don?t find definitive a PQC handshake standard, however combining ML-KEM512 for forward secrecy and McEliece460896 for static long-term keys does exist in practice[1] and fits into WireGuard init and response messages. Alternatively, sntrup653 could be used for forward secrecy without PQ authentication, similar to Signal's PQXDH[2]. Possibly new primitives/schemes are developed, with smaller public keys and ciphertexts. Just today I read an email about ML-KEM and the Kernel; none of these cryptographic primitives are (to my knowledge) part of the Linux Kernel, making a ?new? protocol version of WireGuard more difficult to implement and further out in the future. I wondered if WireGuard could export some of the noise primitives like mix_hash and mix_key to allow ?one way? (ratchet) modifications of the chaining key and ?append only" bytes to the outgoing packet (PQ pubkey, ciphertext). After appending bytes, WireGuard takes over again and calculates the MAC, proceeding as usual. The "ratcheting? Kernel module would work similar to the existing PSK approach, it adds additional data to the chaining key, however it can?t downgrade it (except crashing the Kernel). Another approach could be to add netlink handling for an active daemon, this would at least reduce the open ports and network complexity. Yet another way to have PQ WireGuard could be to produce one's own modules like WolfGuard did the recently[3] with AES/FIPS, however I thought to ask anyway. Thanks, Paul [1]: https://rosenpass.eu/docs/rosenpass-project/whitepaper/ [2]: https://signal.org/docs/specifications/pqxdh/ [3]: https://github.com/wolfSSL/wolfGuard From ryan.appel.333 at gmail.com Tue Mar 31 00:44:55 2026 From: ryan.appel.333 at gmail.com (Ryan Appel) Date: Mon, 30 Mar 2026 19:44:55 -0500 Subject: Kernel ML-KEM implementation plans In-Reply-To: <20260331001358.GA5190@sol> References: <20260331001358.GA5190@sol> Message-ID: <7507DE2E-1507-4D03-B6EF-9C139BBF34F8@gmail.com> WireGuard was my big implementation user. I also know that VMware uses the kernel crypto space for many of its crypto operations. I do not know when they will want ML-KEM and if they will want it only within BoringCrypto or OpenSSL, but if there is need for it in the market before it can be developed then that makes sense. Thank you, Ryan Appel > On Mar 30, 2026, at 7:15?PM, Eric Biggers wrote: > > ?On Mon, Mar 30, 2026 at 06:41:46PM -0500, Ryan Appel wrote: >> Hello all, >> >> Looking through the mail archives I see no information on an >> implementation of ML-KEM that has been planned, except for leancrypto >> attempting to make a Key-Agreement Scheme a Key-Encapsulation >> Mechanism. >> >> Is there a plan to implement a KEM interface at this point? Is this >> something that needs support? How could someone contribute to this? > > We don't add new algorithms preemptively, but rather only when an > in-kernel user comes along. Otherwise there's a risk that the code will > never be used. > > Do you have a specific in-kernel user in mind? I haven't actually heard > anyone specifically say they need ML-KEM in the kernel yet. > > I guess the obvious use case would be WireGuard. But that would require > a new WireGuard protocol version that replaces X25519 with something > like X25519MLKEM768. It's going to be up to the WireGuard author > (Jason) to decide whether that's in the roadmap for WireGuard. > > Also maybe Bluetooth, though it seems the spec for that is yet to be > defined? > > Anyway, point is, before it makes sense to consider possible > implementation strategies, there needs to be a plan to actually use it. > > - Eric