From khaberz at gmail.com Sat Apr 1 11:38:02 2023 From: khaberz at gmail.com (Kai Haberzettl) Date: Sat, 1 Apr 2023 13:38:02 +0200 Subject: Nw Android version crashes on Android TV / Google TV In-Reply-To: References: Message-ID: Can confirm. Thanks! On Fri, Mar 31, 2023 at 6:06?PM Jason A. Donenfeld wrote: > > The fix has now been released by Google, so just update and the crash > will go away. From dnlcrwfrd at gmail.com Sun Apr 2 01:14:45 2023 From: dnlcrwfrd at gmail.com (Dan Crawford) Date: Sun, 02 Apr 2023 11:14:45 +1000 Subject: Possible regression between 5.18.2 and 6.2.1 In-Reply-To: References: Message-ID: Thanks for the suggestions. I've done some bisecting and I've found that the issue appears due to wg-quick, which means I can easily work around it. First, apologies but there's a typo in my original email, I upgraded from 5.12.8, not 5.18.2. On versions prior to 5.14.0, wg-quick correctly adds routes for the appropriate addresses (line 341 and then line 177). However, on versions after 5.14.0, the condition doesn't work quite right and the ip route add command does not run (line 177). To investigate this I print ip -4 route show dev wg1 match 192.168.1.3, on both 5.13.0 and 5.14.0, at line 177. On 5.13.0 I get no output, and the ip route add command runs. However, on 5.14.0 the output is 192.168.1.0/24 proto kernel scope link src 192.168.1.0 and so the ip route add command does not run. Obviously I can easily work around the issue by patching the conditional out of wg-quick. But I don't have any clue why the output of ip varies between 5.13 and 5.14. I'm also surprised no-one has encountered this issue either (unless I missed something while searching). Possibly one way to resolve the issue is to replace the conditional with [[ -n $(ip $proto route show dev "$INTERFACE" match "$1" proto boot 2>/dev/null) ]] Thanks Dan On Fri Mar 31, 2023 at 1:39 AM AEDT, Jason A. Donenfeld wrote: > Hi Dan, > > Hard to imagine that this is a WireGuard bug, but more likely > something having to do with SNAT or something. > > What is the unallowed src IP when you get that error? Can you debug > further? Maybe bisect a bit? Otherwise, not much I can do. > > The diff between those versions you listed is pretty minimal, so I > suspect your bug is elsewhere. > > Jason From unit193 at unit193.net Mon Apr 3 21:51:17 2023 From: unit193 at unit193.net (Unit 193) Date: Mon, 3 Apr 2023 17:51:17 -0400 Subject: [PATCH] wg-quick@.service: Add deps on wg-quick.target Message-ID: <20230403215117.766701-1-unit193@unit193.net> From: Doug Freed These dependencies ensure that instances of this service are started before wg-quick.target is considered started, allowing other services to depend on wg-quick.target to mean "all wg-quick services are started" Signed-off-by: Doug Freed --- src/systemd/wg-quick at .service | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/systemd/wg-quick at .service b/src/systemd/wg-quick at .service index dbdab44..41e71b8 100644 --- a/src/systemd/wg-quick at .service +++ b/src/systemd/wg-quick at .service @@ -1,5 +1,6 @@ [Unit] Description=WireGuard via wg-quick(8) for %I +Before=wg-quick.target After=network-online.target nss-lookup.target Wants=network-online.target nss-lookup.target PartOf=wg-quick.target @@ -19,4 +20,4 @@ ExecReload=/bin/bash -c 'exec /usr/bin/wg syncconf %i <(exec /usr/bin/wg-quick s Environment=WG_ENDPOINT_RESOLUTION_RETRIES=infinity [Install] -WantedBy=multi-user.target +WantedBy=multi-user.target wg-quick.target -- 2.39.2 From caskd at redxen.eu Sun Apr 2 12:54:12 2023 From: caskd at redxen.eu (caskd) Date: Sun, 02 Apr 2023 12:54:12 +0000 Subject: Race condition/no locking on configuration load Message-ID: <3ADWX816HB4BO.3EX0UVUOJ70FG@unix.is.love.unix.is.life> Hello everyone, i've hit a weird edgecase where the wireguard config gets loaded and during the load the interface gets a address assigned which just disappears. Here's how i replicate it. ip link add $IFNAME type wireguard wg setconf $IFNAME $CONFIG #-- while this runs, run the command below in parallel ip -6 address add $ADDR dev $IFNAME Following this, the added interface address doesn't persist, yet no error is returned by either iproute2 or wireguard-tools. Using: iproute2 6.2.0 Linux 6.1.9 wireguard-tools 1.0.20210914 Is this a known problem? I assume it has to do with no locking being done or similar but i haven't looked deeper into it. -- Alex D. RedXen System & Infrastructure Administration https://redxen.eu/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 858 bytes Desc: not available URL: From regressions at leemhuis.info Sat Apr 8 12:01:30 2023 From: regressions at leemhuis.info (Linux regression tracking #update (Thorsten Leemhuis)) Date: Sat, 8 Apr 2023 14:01:30 +0200 Subject: Possible regression between 5.18.2 and 6.2.1 In-Reply-To: References: Message-ID: <1190d45f-28fd-271d-bfd7-e37c1e2acd7d@leemhuis.info> On 02.04.23 03:14, Dan Crawford wrote: > Thanks for the suggestions. I've done some bisecting and I've found > that the issue appears due to wg-quick, which means I can easily work > around it. First, apologies but there's a typo in my original > email, I upgraded from 5.12.8, not 5.18.2. > > On versions prior to 5.14.0, wg-quick correctly adds routes for the > appropriate addresses (line 341 and then line 177). However, on versions > after 5.14.0, the condition doesn't work quite right and the ip route > add command does not run (line 177). > > To investigate this I print ip -4 route show dev wg1 match 192.168.1.3, > on both 5.13.0 and 5.14.0, at line 177. > > On 5.13.0 I get no output, and the ip route add command runs. > However, on 5.14.0 the output is > > 192.168.1.0/24 proto kernel scope link src 192.168.1.0 Thx for your investigation. This per the Linux kernel policy might qualify as regression. But the thing is: the change was introduced quite a while ago already, hence fixing it now might itself lead to other regressions, as other scripts might have started to rely on the new behavior. If anyone wanted to discuss this upstream we'd also likely need a bisection to know which change caused the new behavior. Given all this and the relative simple... > and so the ip route add command does not run. > > Obviously I can easily work around the issue by patching the conditional > out of wg-quick. But I don't have any clue why the output of ip varies > between 5.13 and 5.14. I'm also surprised no-one has encountered > this issue either (unless I missed something while searching). > > Possibly one way to resolve the issue is to replace the conditional with > > [[ -n $(ip $proto route show dev "$INTERFACE" match "$1" proto boot 2>/dev/null) ]] ...workaround you apparently have found I'd say it's better to fix this in wg-quick. I'll thus for now will remove this from the list of tracked Linux kernel regressions: #regzbot inconclusive: small change broke script, workaround found; fixing this now might lead to other regressions #regzbot ignore-activity Ciao, Thorsten (wearing his 'the Linux kernel's regression tracker' hat) -- Everything you wanna know about Linux kernel regression tracking: https://linux-regtracking.leemhuis.info/about/#tldr That page also explains what to do if mails like this annoy you. > On Fri Mar 31, 2023 at 1:39 AM AEDT, Jason A. Donenfeld wrote: >> Hi Dan, >> >> Hard to imagine that this is a WireGuard bug, but more likely >> something having to do with SNAT or something. >> >> What is the unallowed src IP when you get that error? Can you debug >> further? Maybe bisect a bit? Otherwise, not much I can do. >> >> The diff between those versions you listed is pretty minimal, so I >> suspect your bug is elsewhere. >> >> Jason > > From Jason at zx2c4.com Tue Apr 11 10:27:21 2023 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Tue, 11 Apr 2023 12:27:21 +0200 Subject: Android Reproducible Builds & Signing Key Changes Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Hi folks, The WireGuard Android app can now be reproducibly built, so that its contents can be publicly verified. The F-Droid project now does this verification, by comparing their build of WireGuard to the build that the WireGuard project publishes. When they match, the new version becomes available. This is very positive news. As part of this development, we're taking the opportunity to unify the signing keys used for WireGuard builds by F-Droid, the Google Play Store, and elsewhere. Previously, F-Droid would release builds using their own signing key [1], and the Google Play Store would release builds using yet a different signing key [2]. Moving forward, both F-Droid and the Google Play Store will release builds using the same signing key that the WireGuard project uses [3]. (That signing key is held in an HSM, details for which I dumped here [4].) This means that it will be trivial to switch between F-Droid and the Google Play Store as a source for downloading WireGuard, as well as for receiving APKs directly from the WireGuard project, should we ever move to provide that. It will also let the app be bundled with ROMs more easily and still be updatable through any channel. And because the builds are reproducible, interested parties will be able to verify that they're receiving the same code from all places. However, since the signing key is changing from the respective app store keys to the WireGuard project key, a subset of users will need to remove and re-install the app using this basic procedure: 1. ? -> Export tunnels to zip file. 2. Uninstall the WireGuard app entirely. 3. Reinstall the WireGuard app from the Google Play Store or F-Droid. * Be sure to install version ? 1.0.20230405. 4. + -> Import from file or archive -> Downloads/wireguard-export.zip 5. File Manager -> delete Downloads/wireguard-export.zip But most users do not need to do this. Specifically: - Google Play Store users who do not care about interoperability with F-Droid or other app sources do *not* need carry out the above steps, as the Google Play Store will continue serving updates using the old key. - All F-Droid users (and users of alternative Google Play Store frontends, such as Aurora) with WireGuard below version 1.0.20230405 *must* carry out the above in order to continue receiving updates from anywhere. Hopefully this is relatively straight-forward and not too much of an inconvenience by those who care. I assume that F-Droid users are in general a more technical crowd, and should be able to manage. Please let me know if you have any questions or concerns. Regards, Jason [1] Old F-Droid signing key: d2ccbdf13c52e8905b02d9770dabae0b9d76ecdfe7533814134273ba959e2d3f [2] Old Play Store signing key: 79758d2ae9cd8b9107c0f6e67ff9ff02d255f9191c5e83202129ec081b4960fd [3] New WireGuard Project signing key: 84a13fa2c4e0064b0c11654b8a86574b7a9b9352a3834cee32455b061c3d4127 [4] YubiHSM APK signing details: https://github.com/Yubico/yubihsm-shell/issues/329 -----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEq5lC5tSkz8NBJiCnSfxwEqXeA64FAmQ0GNsACgkQSfxwEqXe A64uLhAAgNf96W4ogBcx31JJ+jtwrPB2J22hY+K4K5enBX2Jk0J9j9Kgq3SB74sl 3eg+X1OYypwkKhJMVhBh9LEdaqGCJHYUXc3B/tG0r9XXlYiMaOwry3GA72mPyOaQ vCgDA6t0a3WkUdib1sArL6Gn+T4w83I3GwbvvkQ1ooidHUtYJ8PsBw5619JSk/fC MfuPekg5+qfkTcd6dsWzK9O1GTEYO0c4NYubEva5d4VDU2V/cIbfWUCDi3+rMFgx F1dKMnZK0BWHc6AR7CcFFz1PHGUAPN8plZ2nObVsB9PW2wFq9hOXDJDI+5Sc8XjF FvG94yoiy7a/iWUfl7e7rllOanXPWdoiUKhX6j5Wsj6N+5+E039TpBN9LWtax7ES ms1NsbycV0bde+oh6rJud9RcrjXGbN8X/LdYYbZ/Z0F2B84fwzkSC+63EEHpeKOj uK6Ztc40yWLSJg6YnE4rn0hRfT+jsINXtCV/UcXk+4/asQC6O2EALMTQ83Wc6ONY MwAPIOFmtUKwgtOBcgsN6RCfyTYLUp+/fz17UtUShUnaK+Zl9NDuRuqLPdKn4mRc qLm/hBXA8FuqeVdMeQJfw/Xsffij3Yi+ILkBWfw8FqYJ6EUxOk49q0Sx0xF2GrzO sQfBLh75qJYlRaUhk/WtP3FSWbWbk90j5GcFU7OB4o2X8PKs91A= =huxB -----END PGP SIGNATURE----- From hiram at hiramchirino.com Fri Apr 7 20:26:38 2023 From: hiram at hiramchirino.com (Hiram Chirino) Date: Fri, 7 Apr 2023 16:26:38 -0400 Subject: [PATCH] conn: set the SO_REUSEADDR and SO_REUSEPORT socket options Message-ID: Setting the SO_REUSEADDR and SO_REUSEPORT socket options allows other applications to reuse the wg UDP port. This can be super handy to do Things like sending stun requests to stun servers from the wg port. This lets you discover the wg?s public IP:port mapping if you're behind a NAT router. Signed-off-by: Hiram Chirino --- conn/controlfns_reuseport_unix.go | 32 ++++++++++++++++++++++++++++ conn/controlfns_reuseport_windows.go | 24 +++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 conn/controlfns_reuseport_unix.go create mode 100644 conn/controlfns_reuseport_windows.go diff --git a/conn/controlfns_reuseport_unix.go b/conn/controlfns_reuseport_unix.go new file mode 100644 index 0000000..44d617b --- /dev/null +++ b/conn/controlfns_reuseport_unix.go @@ -0,0 +1,32 @@ +//go:build !plan9 && !windows && !wasm && !js + +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved. + */ + +package conn + +import ( + "golang.org/x/sys/unix" + "syscall" +) + +func init() { + + controlFns = append(controlFns, + func(network, address string, c syscall.RawConn) error { + return c.Control(func(fd uintptr) { + _ = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1) + }) + }, + ) + controlFns = append(controlFns, + func(network, address string, c syscall.RawConn) error { + return c.Control(func(fd uintptr) { + _ = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1) + }) + }, + ) + +} diff --git a/conn/controlfns_reuseport_windows.go b/conn/controlfns_reuseport_windows.go new file mode 100644 index 0000000..2f8a7bf --- /dev/null +++ b/conn/controlfns_reuseport_windows.go @@ -0,0 +1,24 @@ +//go:build windows + +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved. + */ + +package conn + +import ( + "syscall" + + "golang.org/x/sys/windows" +) + +func init() { + controlFns = append(controlFns, + func(network, address string, c syscall.RawConn) error { + return c.Control(func(fd uintptr) { + _ = windows.SetsockoptInt(windows.Handle(fd), windows.SOL_SOCKET, windows.SO_REUSEADDR, 1) + }) + }, + ) +} -- 2.37.1 (Apple Git-137.1) From jnashicq at googlemail.com Wed Apr 12 12:39:00 2023 From: jnashicq at googlemail.com (Anton) Date: Wed, 12 Apr 2023 16:39:00 +0400 Subject: Wireguard-go on Android 11+ Message-ID: Hi all, I'm porting a Golang-based program [1] to Android11+ (API level 30) and I've faced a problem,as the getifaddrs function is not available for apps and other restrictions. >From Android developer documentation [2]: > > In addition, non-privileged apps can't access the device's MAC address; only network interfaces with an IP address are visible. This impacts the getifaddrs() and NetworkInterface.getHardwareAddress() methods, as well as sending RTM_GETLINK Netlink messages. > The following is a list of the ways that apps are affected by this change: > NetworkInterface.getHardwareAddress() returns null for every interface. > Apps cannot use the bind() function on NETLINK_ROUTE sockets. > The ip command does not return information about interfaces. > Apps cannot send RTM_GETLINK messages. > I came up with a workaround [3], and now my app works OK. External references: https://github.com/mysteriumnetwork/node https://developer.android.com/training/articles/user-data-ids#mac-11-plus https://github.com/mysteriumnetwork/wireguard-go/pull/5/files -- best regards, Anton From mailman-wireguard.com at johnnyutahh.com Sun Apr 16 15:06:45 2023 From: mailman-wireguard.com at johnnyutahh.com (Johnny Utahh) Date: Sun, 16 Apr 2023 10:06:45 -0500 Subject: How to optimize AllowedIPs "overlapping" routes? Message-ID: 1. wg0.conf: AllowedIPs = 0.0.0.0/0, ::0/0 --> higher-latency network 2. wg1.conf: AllowedIPs = 192.168.7.0/24?? --> much-lower-latency network When enabling both of the devices/.conf's (listed as 1. and 2. above) concurrently, the #2 route travels over #1 (all starting up via 'wg-quick'). In this scenario I'd prefer #2 routing "bypasses" #1 and retain its (#2's) lower-latency path/network. Can this be done, somehow? I deduce the "route" for #2 changes when concurrently-enabling #1 because the #2-ping-latency immediately and dramatically increases to match #1-network's latency (and immediately reverts to #2's lower latency when #1 is disabled). This hurts my #2 network, badly. I'm running/testing the above on macOS v12.6.3 build 21G419, wireguard-go v0.0.20230223. If not on macOS, might this be feasible on Fedora or Ubuntu? I realize this might be a FAQ. I could not find any docs/resources to help after a brief search, so I'm posting here. [I'm not a networking expert, so I may be butchering various terminology, concepts. I apologize in advance for my ignorance.] ~J From mailman-wireguard.com at johnnyutahh.com Sun Apr 16 20:48:40 2023 From: mailman-wireguard.com at johnnyutahh.com (Johnny Utahh) Date: Sun, 16 Apr 2023 15:48:40 -0500 Subject: How to optimize AllowedIPs "overlapping" routes? In-Reply-To: References: Message-ID: More discussion here: https://www.reddit.com/r/WireGuard/comments/12oimvq/how_to_optimize_allowedips_overlapping_routes/ Clearly this is FAQ-ish kind of thing. It was a little hard for me to easily find a reference for this kind of stuff. I realize the WireGuard project may not consider it to be their responsibility to address such things. ~J On 2023-04-16 10:06 AM, Johnny Utahh wrote: > 1. wg0.conf: AllowedIPs = 0.0.0.0/0, ::0/0 --> higher-latency network > 2. wg1.conf: AllowedIPs = 192.168.7.0/24?? --> much-lower-latency network > > When enabling both of the devices/.conf's (listed as 1. and 2. above) > concurrently, the #2 route travels over #1 (all starting up via > 'wg-quick'). In this scenario I'd prefer #2 routing "bypasses" #1 and > retain its (#2's) lower-latency path/network. Can this be done, somehow? > > I deduce the "route" for #2 changes when concurrently-enabling #1 > because the #2-ping-latency immediately and dramatically increases to > match #1-network's latency (and immediately reverts to #2's lower > latency when #1 is disabled). This hurts my #2 network, badly. > > I'm running/testing the above on macOS v12.6.3 build 21G419, > wireguard-go v0.0.20230223. If not on macOS, might this be feasible on > Fedora or Ubuntu? > > I realize this might be a FAQ. I could not find any docs/resources to > help after a brief search, so I'm posting here. > > [I'm not a networking expert, so I may be butchering various > terminology, concepts. I apologize in advance for my ignorance.] > > ~J From omkhar at gmail.com Sat Apr 22 11:24:44 2023 From: omkhar at gmail.com (Omkhar Arasaratnam) Date: Sat, 22 Apr 2023 07:24:44 -0400 Subject: How to optimize AllowedIPs "overlapping" routes? In-Reply-To: References: Message-ID: Rather than using the route setup logic in wg-quick, you could manually set the default gateway for (1) and add a more specific route for (2) in your route table. iirc (in Linux anyway...) the more specific route would take higher precedence. --oa --oa On Sat, Apr 22, 2023 at 7:18?AM Johnny Utahh wrote: > > More discussion here: > > https://www.reddit.com/r/WireGuard/comments/12oimvq/how_to_optimize_allowedips_overlapping_routes/ > > Clearly this is FAQ-ish kind of thing. It was a little hard for me to > easily find a reference for this kind of stuff. I realize the WireGuard > project may not consider it to be their responsibility to address such > things. > > ~J > > On 2023-04-16 10:06 AM, Johnny Utahh wrote: > > 1. wg0.conf: AllowedIPs = 0.0.0.0/0, ::0/0 --> higher-latency network > > 2. wg1.conf: AllowedIPs = 192.168.7.0/24 --> much-lower-latency network > > > > When enabling both of the devices/.conf's (listed as 1. and 2. above) > > concurrently, the #2 route travels over #1 (all starting up via > > 'wg-quick'). In this scenario I'd prefer #2 routing "bypasses" #1 and > > retain its (#2's) lower-latency path/network. Can this be done, somehow? > > > > I deduce the "route" for #2 changes when concurrently-enabling #1 > > because the #2-ping-latency immediately and dramatically increases to > > match #1-network's latency (and immediately reverts to #2's lower > > latency when #1 is disabled). This hurts my #2 network, badly. > > > > I'm running/testing the above on macOS v12.6.3 build 21G419, > > wireguard-go v0.0.20230223. If not on macOS, might this be feasible on > > Fedora or Ubuntu? > > > > I realize this might be a FAQ. I could not find any docs/resources to > > help after a brief search, so I'm posting here. > > > > [I'm not a networking expert, so I may be butchering various > > terminology, concepts. I apologize in advance for my ignorance.] > > > > ~J From domi at tomcsanyi.net Sat Apr 22 11:43:28 2023 From: domi at tomcsanyi.net (Tomcsanyi, Domonkos) Date: Sat, 22 Apr 2023 13:43:28 +0200 Subject: How to optimize AllowedIPs "overlapping" routes? In-Reply-To: References: Message-ID: <52C0BA1D-015E-4A46-A32E-7359A3304996@tomcsanyi.net> The best way to deal with this IMHO in a multi platform way is adding weight or metric to the specific routes, allowing them to be manually prioritized. Cheers, Domi > 22.04.2023 d?tummal, 13:25 id?pontban Omkhar Arasaratnam ?rta: > > ?Rather than using the route setup logic in wg-quick, you could > manually set the default gateway for (1) and add a more specific route > for (2) in your route table. iirc (in Linux anyway...) the more > specific route would take higher precedence. > > --oa > > > --oa > > >> On Sat, Apr 22, 2023 at 7:18?AM Johnny Utahh >> wrote: >> >> More discussion here: >> >> https://www.reddit.com/r/WireGuard/comments/12oimvq/how_to_optimize_allowedips_overlapping_routes/ >> >> Clearly this is FAQ-ish kind of thing. It was a little hard for me to >> easily find a reference for this kind of stuff. I realize the WireGuard >> project may not consider it to be their responsibility to address such >> things. >> >> ~J >> >>> On 2023-04-16 10:06 AM, Johnny Utahh wrote: >>> 1. wg0.conf: AllowedIPs = 0.0.0.0/0, ::0/0 --> higher-latency network >>> 2. wg1.conf: AllowedIPs = 192.168.7.0/24 --> much-lower-latency network >>> >>> When enabling both of the devices/.conf's (listed as 1. and 2. above) >>> concurrently, the #2 route travels over #1 (all starting up via >>> 'wg-quick'). In this scenario I'd prefer #2 routing "bypasses" #1 and >>> retain its (#2's) lower-latency path/network. Can this be done, somehow? >>> >>> I deduce the "route" for #2 changes when concurrently-enabling #1 >>> because the #2-ping-latency immediately and dramatically increases to >>> match #1-network's latency (and immediately reverts to #2's lower >>> latency when #1 is disabled). This hurts my #2 network, badly. >>> >>> I'm running/testing the above on macOS v12.6.3 build 21G419, >>> wireguard-go v0.0.20230223. If not on macOS, might this be feasible on >>> Fedora or Ubuntu? >>> >>> I realize this might be a FAQ. I could not find any docs/resources to >>> help after a brief search, so I'm posting here. >>> >>> [I'm not a networking expert, so I may be butchering various >>> terminology, concepts. I apologize in advance for my ignorance.] >>> >>> ~J From leon at sidebranch.com Thu Apr 20 19:58:46 2023 From: leon at sidebranch.com (Leon Woestenberg) Date: Thu, 20 Apr 2023 21:58:46 +0200 Subject: Linux counter_validate() RFC6479 replay detection modifies bitmap before authentication? Message-ID: Hello all, I am trying to understand a few details in WireGuard protocol, looking at the Linux kernel WireGuard implementation if I am unsure about the description from the paper. One question I have: Does counter_validate() in the receive path update the bitmap from the Type 4 counter (their_counter) before the received Type 4 packet was authenticated? Regards, Leon. From Jason at zx2c4.com Sat Apr 22 12:03:42 2023 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Sat, 22 Apr 2023 14:03:42 +0200 Subject: Linux counter_validate() RFC6479 replay detection modifies bitmap before authentication? In-Reply-To: References: Message-ID: On 4/20/23, Leon Woestenberg wrote: > Hello all, > > I am trying to understand a few details in WireGuard protocol, looking > at the Linux kernel WireGuard implementation if I am unsure about the > description from the paper. One question I have: > > Does counter_validate() in the receive path update the bitmap from the > Type 4 counter (their_counter) before the received Type 4 packet was > authenticated? No, it happens after authentication. Otherwise that'd be a real DoS vector. From syzbot+c2775460db0e1c70018e at syzkaller.appspotmail.com Sun Apr 30 18:01:44 2023 From: syzbot+c2775460db0e1c70018e at syzkaller.appspotmail.com (syzbot) Date: Sun, 30 Apr 2023 11:01:44 -0700 Subject: [syzbot] [wireguard?] KASAN: slab-use-after-free Write in enqueue_timer Message-ID: <000000000000c0b11d05fa917fe3@google.com> Hello, syzbot found the following issue on: HEAD commit: 825a0714d2b3 Merge tag 'efi-next-for-v6.4' of git://git.ke.. git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=17f56dc8280000 kernel config: https://syzkaller.appspot.com/x/.config?x=7ecbb03c21601216 dashboard link: https://syzkaller.appspot.com/bug?extid=c2775460db0e1c70018e compiler: Debian clang version 15.0.7, GNU ld (GNU Binutils for Debian) 2.35.2 Unfortunately, I don't have any reproducer for this issue yet. Downloadable assets: disk image: https://storage.googleapis.com/syzbot-assets/93b1af100ee7/disk-825a0714.raw.xz vmlinux: https://storage.googleapis.com/syzbot-assets/3579f310db81/vmlinux-825a0714.xz kernel image: https://storage.googleapis.com/syzbot-assets/0bd9cec144b8/bzImage-825a0714.xz IMPORTANT: if you fix the issue, please add the following tag to the commit: Reported-by: syzbot+c2775460db0e1c70018e at syzkaller.appspotmail.com ================================================================== BUG: KASAN: slab-use-after-free in hlist_add_head include/linux/list.h:945 [inline] BUG: KASAN: slab-use-after-free in enqueue_timer+0xad/0x560 kernel/time/timer.c:605 Write of size 8 at addr ffff88801ecc1500 by task kworker/0:11/5405 CPU: 0 PID: 5405 Comm: kworker/0:11 Not tainted 6.3.0-syzkaller-11733-g825a0714d2b3 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/14/2023 Workqueue: wg-crypt-wg1 wg_packet_decrypt_worker Call Trace: __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:351 [inline] print_report+0x163/0x540 mm/kasan/report.c:462 kasan_report+0x176/0x1b0 mm/kasan/report.c:572 hlist_add_head include/linux/list.h:945 [inline] enqueue_timer+0xad/0x560 kernel/time/timer.c:605 internal_add_timer kernel/time/timer.c:634 [inline] __mod_timer+0xa76/0xf40 kernel/time/timer.c:1131 mod_peer_timer+0x158/0x220 drivers/net/wireguard/timers.c:37 wg_packet_consume_data_done drivers/net/wireguard/receive.c:354 [inline] wg_packet_rx_poll+0xd9e/0x2250 drivers/net/wireguard/receive.c:474 __napi_poll+0xc7/0x470 net/core/dev.c:6496 napi_poll net/core/dev.c:6563 [inline] net_rx_action+0x78b/0x1010 net/core/dev.c:6696 __do_softirq+0x2ab/0x908 kernel/softirq.c:571 do_softirq+0x166/0x250 kernel/softirq.c:472 __local_bh_enable_ip+0x1b5/0x1f0 kernel/softirq.c:396 spin_unlock_bh include/linux/spinlock.h:395 [inline] ptr_ring_consume_bh include/linux/ptr_ring.h:367 [inline] wg_packet_decrypt_worker+0xd40/0xde0 drivers/net/wireguard/receive.c:499 process_one_work+0x8a0/0x10e0 kernel/workqueue.c:2405 worker_thread+0xa63/0x1210 kernel/workqueue.c:2552 kthread+0x2b8/0x350 kernel/kthread.c:379 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:308 Allocated by task 16792: kasan_save_stack mm/kasan/common.c:45 [inline] kasan_set_track+0x4f/0x70 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:374 [inline] __kasan_kmalloc+0x98/0xb0 mm/kasan/common.c:383 kasan_kmalloc include/linux/kasan.h:196 [inline] __do_kmalloc_node mm/slab_common.c:966 [inline] __kmalloc_node+0xb8/0x230 mm/slab_common.c:973 kmalloc_node include/linux/slab.h:579 [inline] kvmalloc_node+0x72/0x180 mm/util.c:604 kvmalloc include/linux/slab.h:697 [inline] kvzalloc include/linux/slab.h:705 [inline] alloc_netdev_mqs+0x89/0xf30 net/core/dev.c:10626 rtnl_create_link+0x2f7/0xc00 net/core/rtnetlink.c:3315 rtnl_newlink_create net/core/rtnetlink.c:3433 [inline] __rtnl_newlink net/core/rtnetlink.c:3660 [inline] rtnl_newlink+0x1379/0x2010 net/core/rtnetlink.c:3673 rtnetlink_rcv_msg+0x825/0xf40 net/core/rtnetlink.c:6395 netlink_rcv_skb+0x1df/0x430 net/netlink/af_netlink.c:2546 netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] netlink_unicast+0x7c3/0x990 net/netlink/af_netlink.c:1365 netlink_sendmsg+0xa2a/0xd60 net/netlink/af_netlink.c:1913 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg net/socket.c:747 [inline] __sys_sendto+0x475/0x630 net/socket.c:2144 __do_sys_sendto net/socket.c:2156 [inline] __se_sys_sendto net/socket.c:2152 [inline] __x64_sys_sendto+0xde/0xf0 net/socket.c:2152 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd Freed by task 41: kasan_save_stack mm/kasan/common.c:45 [inline] kasan_set_track+0x4f/0x70 mm/kasan/common.c:52 kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:521 ____kasan_slab_free+0xd6/0x120 mm/kasan/common.c:236 kasan_slab_free include/linux/kasan.h:162 [inline] slab_free_hook mm/slub.c:1781 [inline] slab_free_freelist_hook mm/slub.c:1807 [inline] slab_free mm/slub.c:3786 [inline] __kmem_cache_free+0x264/0x3c0 mm/slub.c:3799 device_release+0x95/0x1c0 kobject_cleanup lib/kobject.c:683 [inline] kobject_release lib/kobject.c:714 [inline] kref_put include/linux/kref.h:65 [inline] kobject_put+0x228/0x470 lib/kobject.c:731 netdev_run_todo+0xe5a/0xf50 net/core/dev.c:10400 default_device_exit_batch+0x5c9/0x630 net/core/dev.c:11392 ops_exit_list net/core/net_namespace.c:175 [inline] cleanup_net+0x767/0xb80 net/core/net_namespace.c:614 process_one_work+0x8a0/0x10e0 kernel/workqueue.c:2405 worker_thread+0xa63/0x1210 kernel/workqueue.c:2552 kthread+0x2b8/0x350 kernel/kthread.c:379 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:308 Last potentially related work creation: kasan_save_stack+0x3f/0x60 mm/kasan/common.c:45 __kasan_record_aux_stack+0xb0/0xc0 mm/kasan/generic.c:491 insert_work+0x54/0x3d0 kernel/workqueue.c:1365 __queue_work+0xb37/0xf10 kernel/workqueue.c:1526 call_timer_fn+0x178/0x580 kernel/time/timer.c:1700 expire_timers kernel/time/timer.c:1746 [inline] __run_timers+0x67a/0x860 kernel/time/timer.c:2022 run_timer_softirq+0x67/0xf0 kernel/time/timer.c:2035 __do_softirq+0x2ab/0x908 kernel/softirq.c:571 Second to last potentially related work creation: kasan_save_stack+0x3f/0x60 mm/kasan/common.c:45 __kasan_record_aux_stack+0xb0/0xc0 mm/kasan/generic.c:491 insert_work+0x54/0x3d0 kernel/workqueue.c:1365 __queue_work+0xb37/0xf10 kernel/workqueue.c:1526 call_timer_fn+0x178/0x580 kernel/time/timer.c:1700 expire_timers kernel/time/timer.c:1746 [inline] __run_timers+0x67a/0x860 kernel/time/timer.c:2022 run_timer_softirq+0x67/0xf0 kernel/time/timer.c:2035 __do_softirq+0x2ab/0x908 kernel/softirq.c:571 The buggy address belongs to the object at ffff88801ecc0000 which belongs to the cache kmalloc-cg-8k of size 8192 The buggy address is located 5376 bytes inside of freed 8192-byte region [ffff88801ecc0000, ffff88801ecc2000) The buggy address belongs to the physical page: page:ffffea00007b3000 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1ecc0 head:ffffea00007b3000 order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0 memcg:ffff88807621e8c1 flags: 0xfff00000010200(slab|head|node=0|zone=1|lastcpupid=0x7ff) page_type: 0xffffffff() raw: 00fff00000010200 ffff88801244f640 dead000000000122 0000000000000000 raw: 0000000000000000 0000000000020002 00000001ffffffff ffff88807621e8c1 page dumped because: kasan: bad access detected page_owner tracks the page as allocated page last allocated via order 3, migratetype Unmovable, gfp_mask 0x1d60c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_RETRY_MAYFAIL|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC|__GFP_HARDWALL), pid 16792, tgid 16792 (syz-executor.2), ts 506275782663, free_ts 506274493341 set_page_owner include/linux/page_owner.h:31 [inline] post_alloc_hook+0x1e6/0x210 mm/page_alloc.c:1722 prep_new_page mm/page_alloc.c:1729 [inline] get_page_from_freelist+0x321c/0x33a0 mm/page_alloc.c:3493 __alloc_pages+0x255/0x670 mm/page_alloc.c:4759 alloc_slab_page+0x6a/0x160 mm/slub.c:1851 allocate_slab mm/slub.c:1998 [inline] new_slab+0x84/0x2f0 mm/slub.c:2051 ___slab_alloc+0xa85/0x10a0 mm/slub.c:3192 __slab_alloc mm/slub.c:3291 [inline] __slab_alloc_node mm/slub.c:3344 [inline] slab_alloc_node mm/slub.c:3441 [inline] __kmem_cache_alloc_node+0x1b8/0x290 mm/slub.c:3490 __do_kmalloc_node mm/slab_common.c:965 [inline] __kmalloc_node+0xa7/0x230 mm/slab_common.c:973 kmalloc_node include/linux/slab.h:579 [inline] kvmalloc_node+0x72/0x180 mm/util.c:604 kvmalloc include/linux/slab.h:697 [inline] kvzalloc include/linux/slab.h:705 [inline] alloc_netdev_mqs+0x89/0xf30 net/core/dev.c:10626 rtnl_create_link+0x2f7/0xc00 net/core/rtnetlink.c:3315 rtnl_newlink_create net/core/rtnetlink.c:3433 [inline] __rtnl_newlink net/core/rtnetlink.c:3660 [inline] rtnl_newlink+0x1379/0x2010 net/core/rtnetlink.c:3673 rtnetlink_rcv_msg+0x825/0xf40 net/core/rtnetlink.c:6395 netlink_rcv_skb+0x1df/0x430 net/netlink/af_netlink.c:2546 netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] netlink_unicast+0x7c3/0x990 net/netlink/af_netlink.c:1365 netlink_sendmsg+0xa2a/0xd60 net/netlink/af_netlink.c:1913 page last free stack trace: reset_page_owner include/linux/page_owner.h:24 [inline] free_pages_prepare mm/page_alloc.c:1302 [inline] free_unref_page_prepare+0x903/0xa30 mm/page_alloc.c:2555 free_unref_page+0x37/0x3f0 mm/page_alloc.c:2650 qlist_free_all+0x22/0x60 mm/kasan/quarantine.c:185 kasan_quarantine_reduce+0x14b/0x160 mm/kasan/quarantine.c:292 ____kasan_kmalloc mm/kasan/common.c:340 [inline] __kasan_kmalloc+0x23/0xb0 mm/kasan/common.c:383 kmalloc include/linux/slab.h:559 [inline] kzalloc include/linux/slab.h:680 [inline] ref_tracker_alloc+0x140/0x470 lib/ref_tracker.c:85 register_netdevice+0x110b/0x1790 net/core/dev.c:10105 ipcaif_newlink+0x1f0/0x4c0 net/caif/chnl_net.c:452 rtnl_newlink_create net/core/rtnetlink.c:3443 [inline] __rtnl_newlink net/core/rtnetlink.c:3660 [inline] rtnl_newlink+0x1468/0x2010 net/core/rtnetlink.c:3673 rtnetlink_rcv_msg+0x825/0xf40 net/core/rtnetlink.c:6395 netlink_rcv_skb+0x1df/0x430 net/netlink/af_netlink.c:2546 netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] netlink_unicast+0x7c3/0x990 net/netlink/af_netlink.c:1365 netlink_sendmsg+0xa2a/0xd60 net/netlink/af_netlink.c:1913 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg net/socket.c:747 [inline] __sys_sendto+0x475/0x630 net/socket.c:2144 __do_sys_sendto net/socket.c:2156 [inline] __se_sys_sendto net/socket.c:2152 [inline] __x64_sys_sendto+0xde/0xf0 net/socket.c:2152 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 Memory state around the buggy address: ffff88801ecc1400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff88801ecc1480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb >ffff88801ecc1500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff88801ecc1580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff88801ecc1600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ================================================================== --- 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 bug is already fixed, let syzbot know by replying with: #syz fix: exact-commit-title If you want to change bug's subsystems, reply with: #syz set subsystems: new-subsystem (See the list of subsystem names on the web dashboard) If the bug is a duplicate of another bug, reply with: #syz dup: exact-subject-of-another-report If you want to undo deduplication, reply with: #syz undup From benjcmin at gmail.com Tue Apr 18 15:10:05 2023 From: benjcmin at gmail.com (Benjcmin v. Bohr) Date: Tue, 18 Apr 2023 15:10:05 -0000 Subject: iOS App log disappering Message-ID: Hi, I'm using the wg iOS App and VPN functionality works fine. But checking the log doesn't work anymore. When I go to Settings, Log, show logs it shows log text for about 1sec and then they disappear. If saved to a text file everything seems to be there but beeing able to read them in the App is just way more comfortable. I hope I came to the right place to address this issue. Thx for the support. MfG Benjamin From ljbrits at tutamail.com Sat Apr 8 13:04:35 2023 From: ljbrits at tutamail.com (Leon J. Brits) Date: Sat, 08 Apr 2023 13:04:35 -0000 Subject: Multiple peers with one down Message-ID: Hi all,? I have a setup where a client connects to multiple peers. By accident one of the pees (a VM) was down and caused the client to connect to none of them, and showed the error: ? ? Device or resource busy: `:`. Trying again in seconds... for (about) 15 times with increased timeout between tries. Eventually it fails and deletes the whole wiregaurd interface with all successfull connections. I would like it to succeed and keep the successful connections and ignore the unsuccessful one. How do I do that? Thanks for your time Leon -- Sent with Tutanota, enjoy secure & ad-free emails. From alexandru.brinduse at pango.co Mon Apr 3 15:23:43 2023 From: alexandru.brinduse at pango.co (Alexandru Brinduse) Date: Mon, 03 Apr 2023 15:23:43 -0000 Subject: [PATCH] driver: indicate all available packets in the ring-buffer to NDIS in two NBL chains, one chain for IPv4 and one for IPv6. Message-ID: <20230403152307.171-1-alexandru.brinduse@pango.co> NdisMIndicateReceiveNetBufferLists() allows batch processing of chained NBLs. >From network performance measurements it can be seen that it brings a dramatic increase in download speed. No chain size limit was imposed due to the fact that the ring-buffer already has a limit. In worst case, not sure how it can be attained in real life, the NBL chain will have the same size as the ringbuffer. --- driver/wintun.c | 210 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 147 insertions(+), 63 deletions(-) diff --git a/driver/wintun.c b/driver/wintun.c index ad4b16b..64f8e1b 100644 --- a/driver/wintun.c +++ b/driver/wintun.c @@ -246,6 +246,35 @@ TunNblIsCompleted(_In_ NET_BUFFER_LIST *Nbl) return (ULONG_PTR)(NET_BUFFER_LIST_MINIPORT_RESERVED(Nbl)[0]) & 1; } +static VOID +TunFreeNblChain(_In_ NET_BUFFER_LIST* Nbl) +{ + while (Nbl) + { + NET_BUFFER_LIST* nextNbl = NET_BUFFER_LIST_NEXT_NBL(Nbl); + IoFreeMdl(NET_BUFFER_LIST_FIRST_NB(Nbl)->MdlChain); + NdisFreeNetBufferList(Nbl); + Nbl = nextNbl; + } +} + +static VOID +TunAddNewNblsToReceiveActiveNblsUnsafe( + _Inout_ TUN_CTX *Ctx, + _In_ NET_BUFFER_LIST* Head, + _In_ NET_BUFFER_LIST* Tail +) +{ + if (Ctx->Device.Receive.ActiveNbls.Head) + NET_BUFFER_LIST_NEXT_NBL_EX(Ctx->Device.Receive.ActiveNbls.Tail) = Head; + else + { + KeClearEvent(&Ctx->Device.Receive.ActiveNbls.Empty); + Ctx->Device.Receive.ActiveNbls.Head = Head; + } + Ctx->Device.Receive.ActiveNbls.Tail = Tail; +} + static MINIPORT_SEND_NET_BUFFER_LISTS TunSendNetBufferLists; _Use_decl_annotations_ static VOID @@ -491,89 +520,144 @@ TunProcessReceiveData(_Inout_ TUN_CTX *Ctx) KeClearEvent(Ctx->Device.Receive.TailMoved); } } + if (RingTail >= RingCapacity) break; - ULONG RingContent = TUN_RING_WRAP(RingTail - RingHead, RingCapacity); - if (RingContent < sizeof(TUN_PACKET)) + ULONG RingContentToConsume = TUN_RING_WRAP(RingTail - RingHead, RingCapacity); + if (RingContentToConsume < sizeof(TUN_PACKET)) break; + ULONG ConsumedRingContent = 0; - TUN_PACKET *Packet = (TUN_PACKET *)(Ring->Data + RingHead); - ULONG PacketSize = *(volatile ULONG *)&Packet->Size; - if (PacketSize > TUN_MAX_IP_PACKET_SIZE) - break; + NET_BUFFER_LIST* NblChainV4 = NULL, *NblChainV6 = NULL; + ULONG NumberOfNblsV4 = 0, NumberOfNblsV6 = 0; - ULONG AlignedPacketSize = TUN_ALIGN(sizeof(TUN_PACKET) + PacketSize); - if (AlignedPacketSize > RingContent) - break; + /* We'll build two NBL chains for IPv4 and IPv6 with all available packets + (they are sepparted so we can use NDIS_RECEIVE_FLAGS_SINGLE_ETHER_TYPE) + Network performance measurements indicate that the download speed is drastically increased + if multiple NBLs are indicated to NDIS in a single call */ + while (ConsumedRingContent < RingContentToConsume) + { + TUN_PACKET* Packet = (TUN_PACKET*)(Ring->Data + RingHead); + ULONG PacketSize = *(volatile ULONG*)&Packet->Size; + if (PacketSize > TUN_MAX_IP_PACKET_SIZE) + goto fatalError; - RingHead = TUN_RING_WRAP(RingHead + AlignedPacketSize, RingCapacity); + ULONG AlignedPacketSize = TUN_ALIGN(sizeof(TUN_PACKET) + PacketSize); + if (AlignedPacketSize > RingContentToConsume) + goto fatalError; - ULONG NblFlags; - USHORT NblProto; - if (PacketSize >= 20 && Packet->Data[0] >> 4 == 4) - { - NblFlags = NDIS_NBL_FLAGS_IS_IPV4; - NblProto = HTONS(NDIS_ETH_TYPE_IPV4); - } - else if (PacketSize >= 40 && Packet->Data[0] >> 4 == 6) - { - NblFlags = NDIS_NBL_FLAGS_IS_IPV6; - NblProto = HTONS(NDIS_ETH_TYPE_IPV6); - } - else - goto skipNbl; - - VOID *PacketAddr = - (UCHAR *)MmGetMdlVirtualAddress(Ctx->Device.Receive.Mdl) + (ULONG)(Packet->Data - (UCHAR *)Ring); - MDL *Mdl = IoAllocateMdl(PacketAddr, PacketSize, FALSE, FALSE, NULL); - if (!Mdl) - goto skipNbl; - IoBuildPartialMdl(Ctx->Device.Receive.Mdl, Mdl, PacketAddr, PacketSize); - NET_BUFFER_LIST *Nbl = NdisAllocateNetBufferAndNetBufferList(Ctx->NblPool, 0, 0, Mdl, 0, PacketSize); - if (!Nbl) - goto cleanupMdl; - Nbl->SourceHandle = Ctx->MiniportAdapterHandle; - NdisSetNblFlag(Nbl, NblFlags); - NET_BUFFER_LIST_INFO(Nbl, NetBufferListFrameType) = (PVOID)NblProto; - NET_BUFFER_LIST_STATUS(Nbl) = NDIS_STATUS_SUCCESS; - TunNblSetOffsetAndMarkActive(Nbl, RingHead); + RingHead = TUN_RING_WRAP(RingHead + AlignedPacketSize, RingCapacity); + + NET_BUFFER_LIST** TargetChain; + ULONG* NumberOfNblsInTargetChain; + ULONG NblFlags; + USHORT NblProto; + if (PacketSize >= 20 && Packet->Data[0] >> 4 == 4) + { + NblFlags = NDIS_NBL_FLAGS_IS_IPV4; + NblProto = HTONS(NDIS_ETH_TYPE_IPV4); + TargetChain = &NblChainV4; + NumberOfNblsInTargetChain = &NumberOfNblsV4; + } + else if (PacketSize >= 40 && Packet->Data[0] >> 4 == 6) + { + NblFlags = NDIS_NBL_FLAGS_IS_IPV6; + NblProto = HTONS(NDIS_ETH_TYPE_IPV6); + TargetChain = &NblChainV6; + NumberOfNblsInTargetChain = &NumberOfNblsV6; + } + else + break; + + VOID* PacketAddr = + (UCHAR*)MmGetMdlVirtualAddress(Ctx->Device.Receive.Mdl) + (ULONG)(Packet->Data - (UCHAR*)Ring); + MDL* Mdl = IoAllocateMdl(PacketAddr, PacketSize, FALSE, FALSE, NULL); + if (!Mdl) + break; + IoBuildPartialMdl(Ctx->Device.Receive.Mdl, Mdl, PacketAddr, PacketSize); + NET_BUFFER_LIST* Nbl = NdisAllocateNetBufferAndNetBufferList(Ctx->NblPool, 0, 0, Mdl, 0, PacketSize); + if (!Nbl) + goto skipPacket; + Nbl->SourceHandle = Ctx->MiniportAdapterHandle; + NdisSetNblFlag(Nbl, NblFlags); + NET_BUFFER_LIST_INFO(Nbl, NetBufferListFrameType) = (PVOID)NblProto; + NET_BUFFER_LIST_STATUS(Nbl) = NDIS_STATUS_SUCCESS; + TunNblSetOffsetAndMarkActive(Nbl, RingHead); + if (*TargetChain) + { + NET_BUFFER_LIST_NEXT_NBL((NET_BUFFER_LIST*)(*TargetChain)->Scratch) = Nbl; + NET_BUFFER_LIST_NEXT_NBL_EX((NET_BUFFER_LIST*)(*TargetChain)->Scratch) = Nbl; + } + else + { + *TargetChain = Nbl; + } + + (*TargetChain)->Scratch = Nbl; // Set LAST_NBL + ++(*NumberOfNblsInTargetChain); + ConsumedRingContent += AlignedPacketSize; + continue; + + skipPacket: + IoFreeMdl(Mdl); + break; + } + KIRQL Irql = ExAcquireSpinLockShared(&Ctx->TransitionLock); if (!ReadAcquire(&Ctx->Running)) - goto cleanupNbl; + { + ExReleaseSpinLockShared(&Ctx->TransitionLock, Irql); + goto notRunning; + } KLOCK_QUEUE_HANDLE LockHandle; KeAcquireInStackQueuedSpinLock(&Ctx->Device.Receive.Lock, &LockHandle); - if (Ctx->Device.Receive.ActiveNbls.Head) - NET_BUFFER_LIST_NEXT_NBL_EX(Ctx->Device.Receive.ActiveNbls.Tail) = Nbl; - else - { - KeClearEvent(&Ctx->Device.Receive.ActiveNbls.Empty); - Ctx->Device.Receive.ActiveNbls.Head = Nbl; - } - Ctx->Device.Receive.ActiveNbls.Tail = Nbl; + if(NblChainV4) + TunAddNewNblsToReceiveActiveNblsUnsafe(Ctx, NblChainV4, NblChainV4->Scratch); + if(NblChainV6) + TunAddNewNblsToReceiveActiveNblsUnsafe(Ctx, NblChainV6, NblChainV6->Scratch); KeReleaseInStackQueuedSpinLock(&LockHandle); - NdisMIndicateReceiveNetBufferLists( - Ctx->MiniportAdapterHandle, - Nbl, - NDIS_DEFAULT_PORT_NUMBER, - 1, - NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL | NDIS_RECEIVE_FLAGS_SINGLE_ETHER_TYPE); + if (NblChainV4) + { + NdisMIndicateReceiveNetBufferLists( + Ctx->MiniportAdapterHandle, + NblChainV4, + NDIS_DEFAULT_PORT_NUMBER, + NumberOfNblsV4, + NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL | NDIS_RECEIVE_FLAGS_SINGLE_ETHER_TYPE); + } + if (NblChainV6) + { + NdisMIndicateReceiveNetBufferLists( + Ctx->MiniportAdapterHandle, + NblChainV6, + NDIS_DEFAULT_PORT_NUMBER, + NumberOfNblsV6, + NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL | NDIS_RECEIVE_FLAGS_SINGLE_ETHER_TYPE); + } + ExReleaseSpinLockShared(&Ctx->TransitionLock, Irql); + + if (ConsumedRingContent < RingContentToConsume) + { + InterlockedIncrementNoFence64((LONG64*)&Ctx->Statistics.ifInDiscards); + KeWaitForSingleObject(&Ctx->Device.Receive.ActiveNbls.Empty, Executive, KernelMode, FALSE, NULL); + WriteULongRelease(&Ring->Head, RingHead); + } continue; - cleanupNbl: - ExReleaseSpinLockShared(&Ctx->TransitionLock, Irql); - NdisFreeNetBufferList(Nbl); - cleanupMdl: - IoFreeMdl(Mdl); - skipNbl: - InterlockedIncrementNoFence64((LONG64 *)&Ctx->Statistics.ifInDiscards); - KeWaitForSingleObject(&Ctx->Device.Receive.ActiveNbls.Empty, Executive, KernelMode, FALSE, NULL); - WriteULongRelease(&Ring->Head, RingHead); + fatalError: + InterlockedIncrementNoFence64((LONG64*)&Ctx->Statistics.ifInDiscards); + notRunning: + TunFreeNblChain(NblChainV4); + InterlockedAddNoFence64((LONG64*)&Ctx->Statistics.ifInDiscards, NumberOfNblsV4); + TunFreeNblChain(NblChainV6); + InterlockedAddNoFence64((LONG64*)&Ctx->Statistics.ifInDiscards, NumberOfNblsV6); + break; } /* Wait for all NBLs to return: 1. To prevent race between proceeding and invalidating ring head. 2. To have -- 2.36.0.windows.1