Thu Aug 27 02:55:05 2020 UTC ()
wg: Drop invalid message types on the floor faster.

Don't even let them reach the thread -- drop them in softint.


(riastradh)
diff -r1.27 -r1.28 src/sys/net/if_wg.c

cvs diff -r1.27 -r1.28 src/sys/net/if_wg.c (switch to unified diff)

--- src/sys/net/if_wg.c 2020/08/27 02:54:31 1.27
+++ src/sys/net/if_wg.c 2020/08/27 02:55:04 1.28
@@ -1,1043 +1,1043 @@ @@ -1,1043 +1,1043 @@
1/* $NetBSD: if_wg.c,v 1.27 2020/08/27 02:54:31 riastradh Exp $ */ 1/* $NetBSD: if_wg.c,v 1.28 2020/08/27 02:55:04 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (C) Ryota Ozaki <ozaki.ryota@gmail.com> 4 * Copyright (C) Ryota Ozaki <ozaki.ryota@gmail.com>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors 15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software 16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission. 17 * without specific prior written permission.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * This network interface aims to implement the WireGuard protocol. 33 * This network interface aims to implement the WireGuard protocol.
34 * The implementation is based on the paper of WireGuard as of 34 * The implementation is based on the paper of WireGuard as of
35 * 2018-06-30 [1]. The paper is referred in the source code with label 35 * 2018-06-30 [1]. The paper is referred in the source code with label
36 * [W]. Also the specification of the Noise protocol framework as of 36 * [W]. Also the specification of the Noise protocol framework as of
37 * 2018-07-11 [2] is referred with label [N]. 37 * 2018-07-11 [2] is referred with label [N].
38 * 38 *
39 * [1] https://www.wireguard.com/papers/wireguard.pdf 39 * [1] https://www.wireguard.com/papers/wireguard.pdf
40 * [2] http://noiseprotocol.org/noise.pdf 40 * [2] http://noiseprotocol.org/noise.pdf
41 */ 41 */
42 42
43#include <sys/cdefs.h> 43#include <sys/cdefs.h>
44__KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.27 2020/08/27 02:54:31 riastradh Exp $"); 44__KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.28 2020/08/27 02:55:04 riastradh Exp $");
45 45
46#ifdef _KERNEL_OPT 46#ifdef _KERNEL_OPT
47#include "opt_inet.h" 47#include "opt_inet.h"
48#endif 48#endif
49 49
50#include <sys/param.h> 50#include <sys/param.h>
51#include <sys/systm.h> 51#include <sys/systm.h>
52#include <sys/kernel.h> 52#include <sys/kernel.h>
53#include <sys/mbuf.h> 53#include <sys/mbuf.h>
54#include <sys/socket.h> 54#include <sys/socket.h>
55#include <sys/sockio.h> 55#include <sys/sockio.h>
56#include <sys/errno.h> 56#include <sys/errno.h>
57#include <sys/ioctl.h> 57#include <sys/ioctl.h>
58#include <sys/time.h> 58#include <sys/time.h>
59#include <sys/timespec.h> 59#include <sys/timespec.h>
60#include <sys/socketvar.h> 60#include <sys/socketvar.h>
61#include <sys/syslog.h> 61#include <sys/syslog.h>
62#include <sys/cpu.h> 62#include <sys/cpu.h>
63#include <sys/intr.h> 63#include <sys/intr.h>
64#include <sys/kmem.h> 64#include <sys/kmem.h>
65#include <sys/device.h> 65#include <sys/device.h>
66#include <sys/module.h> 66#include <sys/module.h>
67#include <sys/mutex.h> 67#include <sys/mutex.h>
68#include <sys/rwlock.h> 68#include <sys/rwlock.h>
69#include <sys/pserialize.h> 69#include <sys/pserialize.h>
70#include <sys/psref.h> 70#include <sys/psref.h>
71#include <sys/kthread.h> 71#include <sys/kthread.h>
72#include <sys/cprng.h> 72#include <sys/cprng.h>
73#include <sys/atomic.h> 73#include <sys/atomic.h>
74#include <sys/sysctl.h> 74#include <sys/sysctl.h>
75#include <sys/domain.h> 75#include <sys/domain.h>
76#include <sys/pcq.h> 76#include <sys/pcq.h>
77#include <sys/queue.h> 77#include <sys/queue.h>
78#include <sys/percpu.h> 78#include <sys/percpu.h>
79#include <sys/callout.h> 79#include <sys/callout.h>
80 80
81#include <net/bpf.h> 81#include <net/bpf.h>
82#include <net/if.h> 82#include <net/if.h>
83#include <net/if_types.h> 83#include <net/if_types.h>
84#include <net/route.h> 84#include <net/route.h>
85 85
86#include <netinet/in.h> 86#include <netinet/in.h>
87#include <netinet/ip.h> 87#include <netinet/ip.h>
88#include <netinet/ip_var.h> 88#include <netinet/ip_var.h>
89#include <netinet/udp.h> 89#include <netinet/udp.h>
90#include <netinet/udp_var.h> 90#include <netinet/udp_var.h>
91#include <netinet/in_var.h> 91#include <netinet/in_var.h>
92#include <netinet/in_pcb.h> 92#include <netinet/in_pcb.h>
93 93
94#ifdef INET6 94#ifdef INET6
95#include <netinet6/in6_var.h> 95#include <netinet6/in6_var.h>
96#include <netinet/ip6.h> 96#include <netinet/ip6.h>
97#include <netinet6/ip6_var.h> 97#include <netinet6/ip6_var.h>
98#include <netinet6/in6_pcb.h> 98#include <netinet6/in6_pcb.h>
99#include <netinet6/udp6_var.h> 99#include <netinet6/udp6_var.h>
100#endif /* INET6 */ 100#endif /* INET6 */
101 101
102#include <net/if_wg.h> 102#include <net/if_wg.h>
103 103
104#include <prop/proplib.h> 104#include <prop/proplib.h>
105 105
106#include <crypto/blake2/blake2s.h> 106#include <crypto/blake2/blake2s.h>
107#include <crypto/sodium/crypto_scalarmult.h> 107#include <crypto/sodium/crypto_scalarmult.h>
108#include <crypto/sodium/crypto_aead_chacha20poly1305.h> 108#include <crypto/sodium/crypto_aead_chacha20poly1305.h>
109#include <crypto/sodium/crypto_aead_xchacha20poly1305.h> 109#include <crypto/sodium/crypto_aead_xchacha20poly1305.h>
110 110
111#include "ioconf.h" 111#include "ioconf.h"
112 112
113#ifdef WG_RUMPKERNEL 113#ifdef WG_RUMPKERNEL
114#include "wg_user.h" 114#include "wg_user.h"
115#endif 115#endif
116 116
117/* 117/*
118 * Data structures 118 * Data structures
119 * - struct wg_softc is an instance of wg interfaces 119 * - struct wg_softc is an instance of wg interfaces
120 * - It has a list of peers (struct wg_peer) 120 * - It has a list of peers (struct wg_peer)
121 * - It has a kthread that sends/receives handshake messages and 121 * - It has a kthread that sends/receives handshake messages and
122 * runs event handlers 122 * runs event handlers
123 * - It has its own two routing tables: one is for IPv4 and the other IPv6 123 * - It has its own two routing tables: one is for IPv4 and the other IPv6
124 * - struct wg_peer is a representative of a peer 124 * - struct wg_peer is a representative of a peer
125 * - It has a softint that is used to send packets over an wg interface 125 * - It has a softint that is used to send packets over an wg interface
126 * to a peer 126 * to a peer
127 * - It has a pair of session instances (struct wg_session) 127 * - It has a pair of session instances (struct wg_session)
128 * - It has a pair of endpoint instances (struct wg_sockaddr) 128 * - It has a pair of endpoint instances (struct wg_sockaddr)
129 * - Normally one endpoint is used and the second one is used only on 129 * - Normally one endpoint is used and the second one is used only on
130 * a peer migration (a change of peer's IP address) 130 * a peer migration (a change of peer's IP address)
131 * - It has a list of IP addresses and sub networks called allowedips 131 * - It has a list of IP addresses and sub networks called allowedips
132 * (struct wg_allowedip) 132 * (struct wg_allowedip)
133 * - A packets sent over a session is allowed if its destination matches 133 * - A packets sent over a session is allowed if its destination matches
134 * any IP addresses or sub networks of the list 134 * any IP addresses or sub networks of the list
135 * - struct wg_session represents a session of a secure tunnel with a peer 135 * - struct wg_session represents a session of a secure tunnel with a peer
136 * - Two instances of sessions belong to a peer; a stable session and a 136 * - Two instances of sessions belong to a peer; a stable session and a
137 * unstable session 137 * unstable session
138 * - A handshake process of a session always starts with a unstable instace 138 * - A handshake process of a session always starts with a unstable instace
139 * - Once a session is established, its instance becomes stable and the 139 * - Once a session is established, its instance becomes stable and the
140 * other becomes unstable instead 140 * other becomes unstable instead
141 * - Data messages are always sent via a stable session 141 * - Data messages are always sent via a stable session
142 * 142 *
143 * Locking notes: 143 * Locking notes:
144 * - wg interfaces (struct wg_softc, wg) is listed in wg_softcs.list and 144 * - wg interfaces (struct wg_softc, wg) is listed in wg_softcs.list and
145 * protected by wg_softcs.lock 145 * protected by wg_softcs.lock
146 * - Each wg has a mutex(9) and a rwlock(9) 146 * - Each wg has a mutex(9) and a rwlock(9)
147 * - The mutex (wg_lock) protects its peer list (wg_peers) 147 * - The mutex (wg_lock) protects its peer list (wg_peers)
148 * - A peer on the list is also protected by pserialize(9) or psref(9) 148 * - A peer on the list is also protected by pserialize(9) or psref(9)
149 * - The rwlock (wg_rwlock) protects the routing tables (wg_rtable_ipv[46]) 149 * - The rwlock (wg_rwlock) protects the routing tables (wg_rtable_ipv[46])
150 * - Each peer (struct wg_peer, wgp) has a mutex 150 * - Each peer (struct wg_peer, wgp) has a mutex
151 * - The mutex (wgp_lock) protects wgp_session_unstable and wgp_state 151 * - The mutex (wgp_lock) protects wgp_session_unstable and wgp_state
152 * - Each session (struct wg_session, wgs) has a mutex 152 * - Each session (struct wg_session, wgs) has a mutex
153 * - The mutex (wgs_lock) protects its state (wgs_state) and its handshake 153 * - The mutex (wgs_lock) protects its state (wgs_state) and its handshake
154 * states 154 * states
155 * - wgs_state of a unstable session can be changed while it never be 155 * - wgs_state of a unstable session can be changed while it never be
156 * changed on a stable session, so once get a session instace via 156 * changed on a stable session, so once get a session instace via
157 * wgp_session_stable we can safely access wgs_state without 157 * wgp_session_stable we can safely access wgs_state without
158 * holding wgs_lock 158 * holding wgs_lock
159 * - A session is protected by pserialize or psref like wgp 159 * - A session is protected by pserialize or psref like wgp
160 * - On a session swap, we must wait for all readers to release a 160 * - On a session swap, we must wait for all readers to release a
161 * reference to a stable session before changing wgs_state and 161 * reference to a stable session before changing wgs_state and
162 * session states 162 * session states
163 */ 163 */
164 164
165 165
166#define WGLOG(level, fmt, args...) \ 166#define WGLOG(level, fmt, args...) \
167 log(level, "%s: " fmt, __func__, ##args) 167 log(level, "%s: " fmt, __func__, ##args)
168 168
169/* Debug options */ 169/* Debug options */
170#ifdef WG_DEBUG 170#ifdef WG_DEBUG
171/* Output debug logs */ 171/* Output debug logs */
172#ifndef WG_DEBUG_LOG 172#ifndef WG_DEBUG_LOG
173#define WG_DEBUG_LOG 173#define WG_DEBUG_LOG
174#endif 174#endif
175/* Output trace logs */ 175/* Output trace logs */
176#ifndef WG_DEBUG_TRACE 176#ifndef WG_DEBUG_TRACE
177#define WG_DEBUG_TRACE 177#define WG_DEBUG_TRACE
178#endif 178#endif
179/* Output hash values, etc. */ 179/* Output hash values, etc. */
180#ifndef WG_DEBUG_DUMP 180#ifndef WG_DEBUG_DUMP
181#define WG_DEBUG_DUMP 181#define WG_DEBUG_DUMP
182#endif 182#endif
183/* Make some internal parameters configurable for testing and debugging */ 183/* Make some internal parameters configurable for testing and debugging */
184#ifndef WG_DEBUG_PARAMS 184#ifndef WG_DEBUG_PARAMS
185#define WG_DEBUG_PARAMS 185#define WG_DEBUG_PARAMS
186#endif 186#endif
187#endif 187#endif
188 188
189#ifdef WG_DEBUG_TRACE 189#ifdef WG_DEBUG_TRACE
190#define WG_TRACE(msg) \ 190#define WG_TRACE(msg) \
191 log(LOG_DEBUG, "%s:%d: %s\n", __func__, __LINE__, (msg)) 191 log(LOG_DEBUG, "%s:%d: %s\n", __func__, __LINE__, (msg))
192#else 192#else
193#define WG_TRACE(msg) __nothing 193#define WG_TRACE(msg) __nothing
194#endif 194#endif
195 195
196#ifdef WG_DEBUG_LOG 196#ifdef WG_DEBUG_LOG
197#define WG_DLOG(fmt, args...) log(LOG_DEBUG, "%s: " fmt, __func__, ##args) 197#define WG_DLOG(fmt, args...) log(LOG_DEBUG, "%s: " fmt, __func__, ##args)
198#else 198#else
199#define WG_DLOG(fmt, args...) __nothing 199#define WG_DLOG(fmt, args...) __nothing
200#endif 200#endif
201 201
202#define WG_LOG_RATECHECK(wgprc, level, fmt, args...) do { \ 202#define WG_LOG_RATECHECK(wgprc, level, fmt, args...) do { \
203 if (ppsratecheck(&(wgprc)->wgprc_lasttime, \ 203 if (ppsratecheck(&(wgprc)->wgprc_lasttime, \
204 &(wgprc)->wgprc_curpps, 1)) { \ 204 &(wgprc)->wgprc_curpps, 1)) { \
205 log(level, fmt, ##args); \ 205 log(level, fmt, ##args); \
206 } \ 206 } \
207} while (0) 207} while (0)
208 208
209#ifdef WG_DEBUG_PARAMS 209#ifdef WG_DEBUG_PARAMS
210static bool wg_force_underload = false; 210static bool wg_force_underload = false;
211#endif 211#endif
212 212
213#ifdef WG_DEBUG_DUMP 213#ifdef WG_DEBUG_DUMP
214 214
215#ifdef WG_RUMPKERNEL 215#ifdef WG_RUMPKERNEL
216static void 216static void
217wg_dump_buf(const char *func, const char *buf, const size_t size) 217wg_dump_buf(const char *func, const char *buf, const size_t size)
218{ 218{
219 219
220 log(LOG_DEBUG, "%s: ", func); 220 log(LOG_DEBUG, "%s: ", func);
221 for (int i = 0; i < size; i++) 221 for (int i = 0; i < size; i++)
222 log(LOG_DEBUG, "%02x ", (int)(0xff & buf[i])); 222 log(LOG_DEBUG, "%02x ", (int)(0xff & buf[i]));
223 log(LOG_DEBUG, "\n"); 223 log(LOG_DEBUG, "\n");
224} 224}
225#endif 225#endif
226 226
227static void 227static void
228wg_dump_hash(const uint8_t *func, const uint8_t *name, const uint8_t *hash, 228wg_dump_hash(const uint8_t *func, const uint8_t *name, const uint8_t *hash,
229 const size_t size) 229 const size_t size)
230{ 230{
231 231
232 log(LOG_DEBUG, "%s: %s: ", func, name); 232 log(LOG_DEBUG, "%s: %s: ", func, name);
233 for (int i = 0; i < size; i++) 233 for (int i = 0; i < size; i++)
234 log(LOG_DEBUG, "%02x ", (int)(0xff & hash[i])); 234 log(LOG_DEBUG, "%02x ", (int)(0xff & hash[i]));
235 log(LOG_DEBUG, "\n"); 235 log(LOG_DEBUG, "\n");
236} 236}
237 237
238#define WG_DUMP_HASH(name, hash) \ 238#define WG_DUMP_HASH(name, hash) \
239 wg_dump_hash(__func__, name, hash, WG_HASH_LEN) 239 wg_dump_hash(__func__, name, hash, WG_HASH_LEN)
240#define WG_DUMP_HASH48(name, hash) \ 240#define WG_DUMP_HASH48(name, hash) \
241 wg_dump_hash(__func__, name, hash, 48) 241 wg_dump_hash(__func__, name, hash, 48)
242#define WG_DUMP_BUF(buf, size) \ 242#define WG_DUMP_BUF(buf, size) \
243 wg_dump_buf(__func__, buf, size) 243 wg_dump_buf(__func__, buf, size)
244#else 244#else
245#define WG_DUMP_HASH(name, hash) __nothing 245#define WG_DUMP_HASH(name, hash) __nothing
246#define WG_DUMP_HASH48(name, hash) __nothing 246#define WG_DUMP_HASH48(name, hash) __nothing
247#define WG_DUMP_BUF(buf, size) __nothing 247#define WG_DUMP_BUF(buf, size) __nothing
248#endif /* WG_DEBUG_DUMP */ 248#endif /* WG_DEBUG_DUMP */
249 249
250#define WG_MTU 1420 250#define WG_MTU 1420
251#define WG_ALLOWEDIPS 16 251#define WG_ALLOWEDIPS 16
252 252
253#define CURVE25519_KEY_LEN 32 253#define CURVE25519_KEY_LEN 32
254#define TAI64N_LEN sizeof(uint32_t) * 3 254#define TAI64N_LEN sizeof(uint32_t) * 3
255#define POLY1305_AUTHTAG_LEN 16 255#define POLY1305_AUTHTAG_LEN 16
256#define HMAC_BLOCK_LEN 64 256#define HMAC_BLOCK_LEN 64
257 257
258/* [N] 4.1: "DHLEN must be 32 or greater." WireGuard chooses 32. */ 258/* [N] 4.1: "DHLEN must be 32 or greater." WireGuard chooses 32. */
259/* [N] 4.3: Hash functions */ 259/* [N] 4.3: Hash functions */
260#define NOISE_DHLEN 32 260#define NOISE_DHLEN 32
261/* [N] 4.3: "Must be 32 or 64." WireGuard chooses 32. */ 261/* [N] 4.3: "Must be 32 or 64." WireGuard chooses 32. */
262#define NOISE_HASHLEN 32 262#define NOISE_HASHLEN 32
263#define NOISE_BLOCKLEN 64 263#define NOISE_BLOCKLEN 64
264#define NOISE_HKDF_OUTPUT_LEN NOISE_HASHLEN 264#define NOISE_HKDF_OUTPUT_LEN NOISE_HASHLEN
265/* [N] 5.1: "k" */ 265/* [N] 5.1: "k" */
266#define NOISE_CIPHER_KEY_LEN 32 266#define NOISE_CIPHER_KEY_LEN 32
267/* 267/*
268 * [N] 9.2: "psk" 268 * [N] 9.2: "psk"
269 * "... psk is a 32-byte secret value provided by the application." 269 * "... psk is a 32-byte secret value provided by the application."
270 */ 270 */
271#define NOISE_PRESHARED_KEY_LEN 32 271#define NOISE_PRESHARED_KEY_LEN 32
272 272
273#define WG_STATIC_KEY_LEN CURVE25519_KEY_LEN 273#define WG_STATIC_KEY_LEN CURVE25519_KEY_LEN
274#define WG_TIMESTAMP_LEN TAI64N_LEN 274#define WG_TIMESTAMP_LEN TAI64N_LEN
275 275
276#define WG_PRESHARED_KEY_LEN NOISE_PRESHARED_KEY_LEN 276#define WG_PRESHARED_KEY_LEN NOISE_PRESHARED_KEY_LEN
277 277
278#define WG_COOKIE_LEN 16 278#define WG_COOKIE_LEN 16
279#define WG_MAC_LEN 16 279#define WG_MAC_LEN 16
280#define WG_RANDVAL_LEN 24 280#define WG_RANDVAL_LEN 24
281 281
282#define WG_EPHEMERAL_KEY_LEN CURVE25519_KEY_LEN 282#define WG_EPHEMERAL_KEY_LEN CURVE25519_KEY_LEN
283/* [N] 5.2: "ck: A chaining key of HASHLEN bytes" */ 283/* [N] 5.2: "ck: A chaining key of HASHLEN bytes" */
284#define WG_CHAINING_KEY_LEN NOISE_HASHLEN 284#define WG_CHAINING_KEY_LEN NOISE_HASHLEN
285/* [N] 5.2: "h: A hash output of HASHLEN bytes" */ 285/* [N] 5.2: "h: A hash output of HASHLEN bytes" */
286#define WG_HASH_LEN NOISE_HASHLEN 286#define WG_HASH_LEN NOISE_HASHLEN
287#define WG_CIPHER_KEY_LEN NOISE_CIPHER_KEY_LEN 287#define WG_CIPHER_KEY_LEN NOISE_CIPHER_KEY_LEN
288#define WG_DH_OUTPUT_LEN NOISE_DHLEN 288#define WG_DH_OUTPUT_LEN NOISE_DHLEN
289#define WG_KDF_OUTPUT_LEN NOISE_HKDF_OUTPUT_LEN 289#define WG_KDF_OUTPUT_LEN NOISE_HKDF_OUTPUT_LEN
290#define WG_AUTHTAG_LEN POLY1305_AUTHTAG_LEN 290#define WG_AUTHTAG_LEN POLY1305_AUTHTAG_LEN
291#define WG_DATA_KEY_LEN 32 291#define WG_DATA_KEY_LEN 32
292#define WG_SALT_LEN 24 292#define WG_SALT_LEN 24
293 293
294/* 294/*
295 * The protocol messages 295 * The protocol messages
296 */ 296 */
297struct wg_msg { 297struct wg_msg {
298 uint32_t wgm_type; 298 uint32_t wgm_type;
299} __packed; 299} __packed;
300 300
301/* [W] 5.4.2 First Message: Initiator to Responder */ 301/* [W] 5.4.2 First Message: Initiator to Responder */
302struct wg_msg_init { 302struct wg_msg_init {
303 uint32_t wgmi_type; 303 uint32_t wgmi_type;
304 uint32_t wgmi_sender; 304 uint32_t wgmi_sender;
305 uint8_t wgmi_ephemeral[WG_EPHEMERAL_KEY_LEN]; 305 uint8_t wgmi_ephemeral[WG_EPHEMERAL_KEY_LEN];
306 uint8_t wgmi_static[WG_STATIC_KEY_LEN + WG_AUTHTAG_LEN]; 306 uint8_t wgmi_static[WG_STATIC_KEY_LEN + WG_AUTHTAG_LEN];
307 uint8_t wgmi_timestamp[WG_TIMESTAMP_LEN + WG_AUTHTAG_LEN]; 307 uint8_t wgmi_timestamp[WG_TIMESTAMP_LEN + WG_AUTHTAG_LEN];
308 uint8_t wgmi_mac1[WG_MAC_LEN]; 308 uint8_t wgmi_mac1[WG_MAC_LEN];
309 uint8_t wgmi_mac2[WG_MAC_LEN]; 309 uint8_t wgmi_mac2[WG_MAC_LEN];
310} __packed; 310} __packed;
311 311
312/* [W] 5.4.3 Second Message: Responder to Initiator */ 312/* [W] 5.4.3 Second Message: Responder to Initiator */
313struct wg_msg_resp { 313struct wg_msg_resp {
314 uint32_t wgmr_type; 314 uint32_t wgmr_type;
315 uint32_t wgmr_sender; 315 uint32_t wgmr_sender;
316 uint32_t wgmr_receiver; 316 uint32_t wgmr_receiver;
317 uint8_t wgmr_ephemeral[WG_EPHEMERAL_KEY_LEN]; 317 uint8_t wgmr_ephemeral[WG_EPHEMERAL_KEY_LEN];
318 uint8_t wgmr_empty[0 + WG_AUTHTAG_LEN]; 318 uint8_t wgmr_empty[0 + WG_AUTHTAG_LEN];
319 uint8_t wgmr_mac1[WG_MAC_LEN]; 319 uint8_t wgmr_mac1[WG_MAC_LEN];
320 uint8_t wgmr_mac2[WG_MAC_LEN]; 320 uint8_t wgmr_mac2[WG_MAC_LEN];
321} __packed; 321} __packed;
322 322
323/* [W] 5.4.6 Subsequent Messages: Transport Data Messages */ 323/* [W] 5.4.6 Subsequent Messages: Transport Data Messages */
324struct wg_msg_data { 324struct wg_msg_data {
325 uint32_t wgmd_type; 325 uint32_t wgmd_type;
326 uint32_t wgmd_receiver; 326 uint32_t wgmd_receiver;
327 uint64_t wgmd_counter; 327 uint64_t wgmd_counter;
328 uint32_t wgmd_packet[0]; 328 uint32_t wgmd_packet[0];
329} __packed; 329} __packed;
330 330
331/* [W] 5.4.7 Under Load: Cookie Reply Message */ 331/* [W] 5.4.7 Under Load: Cookie Reply Message */
332struct wg_msg_cookie { 332struct wg_msg_cookie {
333 uint32_t wgmc_type; 333 uint32_t wgmc_type;
334 uint32_t wgmc_receiver; 334 uint32_t wgmc_receiver;
335 uint8_t wgmc_salt[WG_SALT_LEN]; 335 uint8_t wgmc_salt[WG_SALT_LEN];
336 uint8_t wgmc_cookie[WG_COOKIE_LEN + WG_AUTHTAG_LEN]; 336 uint8_t wgmc_cookie[WG_COOKIE_LEN + WG_AUTHTAG_LEN];
337} __packed; 337} __packed;
338 338
339#define WG_MSG_TYPE_INIT 1 339#define WG_MSG_TYPE_INIT 1
340#define WG_MSG_TYPE_RESP 2 340#define WG_MSG_TYPE_RESP 2
341#define WG_MSG_TYPE_COOKIE 3 341#define WG_MSG_TYPE_COOKIE 3
342#define WG_MSG_TYPE_DATA 4 342#define WG_MSG_TYPE_DATA 4
343#define WG_MSG_TYPE_MAX WG_MSG_TYPE_DATA 343#define WG_MSG_TYPE_MAX WG_MSG_TYPE_DATA
344 344
345/* Sliding windows */ 345/* Sliding windows */
346 346
347#define SLIWIN_BITS 2048u 347#define SLIWIN_BITS 2048u
348#define SLIWIN_TYPE uint32_t 348#define SLIWIN_TYPE uint32_t
349#define SLIWIN_BPW NBBY*sizeof(SLIWIN_TYPE) 349#define SLIWIN_BPW NBBY*sizeof(SLIWIN_TYPE)
350#define SLIWIN_WORDS howmany(SLIWIN_BITS, SLIWIN_BPW) 350#define SLIWIN_WORDS howmany(SLIWIN_BITS, SLIWIN_BPW)
351#define SLIWIN_NPKT (SLIWIN_BITS - NBBY*sizeof(SLIWIN_TYPE)) 351#define SLIWIN_NPKT (SLIWIN_BITS - NBBY*sizeof(SLIWIN_TYPE))
352 352
353struct sliwin { 353struct sliwin {
354 SLIWIN_TYPE B[SLIWIN_WORDS]; 354 SLIWIN_TYPE B[SLIWIN_WORDS];
355 uint64_t T; 355 uint64_t T;
356}; 356};
357 357
358static void 358static void
359sliwin_reset(struct sliwin *W) 359sliwin_reset(struct sliwin *W)
360{ 360{
361 361
362 memset(W, 0, sizeof(*W)); 362 memset(W, 0, sizeof(*W));
363} 363}
364 364
365static int 365static int
366sliwin_check_fast(const volatile struct sliwin *W, uint64_t S) 366sliwin_check_fast(const volatile struct sliwin *W, uint64_t S)
367{ 367{
368 368
369 /* 369 /*
370 * If it's more than one window older than the highest sequence 370 * If it's more than one window older than the highest sequence
371 * number we've seen, reject. 371 * number we've seen, reject.
372 */ 372 */
373#ifdef __HAVE_ATOMIC64_LOADSTORE 373#ifdef __HAVE_ATOMIC64_LOADSTORE
374 if (S + SLIWIN_NPKT < atomic_load_relaxed(&W->T)) 374 if (S + SLIWIN_NPKT < atomic_load_relaxed(&W->T))
375 return EAUTH; 375 return EAUTH;
376#endif 376#endif
377 377
378 /* 378 /*
379 * Otherwise, we need to take the lock to decide, so don't 379 * Otherwise, we need to take the lock to decide, so don't
380 * reject just yet. Caller must serialize a call to 380 * reject just yet. Caller must serialize a call to
381 * sliwin_update in this case. 381 * sliwin_update in this case.
382 */ 382 */
383 return 0; 383 return 0;
384} 384}
385 385
386static int 386static int
387sliwin_update(struct sliwin *W, uint64_t S) 387sliwin_update(struct sliwin *W, uint64_t S)
388{ 388{
389 unsigned word, bit; 389 unsigned word, bit;
390 390
391 /* 391 /*
392 * If it's more than one window older than the highest sequence 392 * If it's more than one window older than the highest sequence
393 * number we've seen, reject. 393 * number we've seen, reject.
394 */ 394 */
395 if (S + SLIWIN_NPKT < W->T) 395 if (S + SLIWIN_NPKT < W->T)
396 return EAUTH; 396 return EAUTH;
397 397
398 /* 398 /*
399 * If it's higher than the highest sequence number we've seen, 399 * If it's higher than the highest sequence number we've seen,
400 * advance the window. 400 * advance the window.
401 */ 401 */
402 if (S > W->T) { 402 if (S > W->T) {
403 uint64_t i = W->T / SLIWIN_BPW; 403 uint64_t i = W->T / SLIWIN_BPW;
404 uint64_t j = S / SLIWIN_BPW; 404 uint64_t j = S / SLIWIN_BPW;
405 unsigned k; 405 unsigned k;
406 406
407 for (k = 0; k < MIN(j - i, SLIWIN_WORDS); k++) 407 for (k = 0; k < MIN(j - i, SLIWIN_WORDS); k++)
408 W->B[(i + k + 1) % SLIWIN_WORDS] = 0; 408 W->B[(i + k + 1) % SLIWIN_WORDS] = 0;
409#ifdef __HAVE_ATOMIC64_LOADSTORE 409#ifdef __HAVE_ATOMIC64_LOADSTORE
410 atomic_store_relaxed(&W->T, S); 410 atomic_store_relaxed(&W->T, S);
411#else 411#else
412 W->T = S; 412 W->T = S;
413#endif 413#endif
414 } 414 }
415 415
416 /* Test and set the bit -- if already set, reject. */ 416 /* Test and set the bit -- if already set, reject. */
417 word = (S / SLIWIN_BPW) % SLIWIN_WORDS; 417 word = (S / SLIWIN_BPW) % SLIWIN_WORDS;
418 bit = S % SLIWIN_BPW; 418 bit = S % SLIWIN_BPW;
419 if (W->B[word] & (1UL << bit)) 419 if (W->B[word] & (1UL << bit))
420 return EAUTH; 420 return EAUTH;
421 W->B[word] |= 1UL << bit; 421 W->B[word] |= 1UL << bit;
422 422
423 /* Accept! */ 423 /* Accept! */
424 return 0; 424 return 0;
425} 425}
426 426
427struct wg_worker { 427struct wg_worker {
428 kmutex_t wgw_lock; 428 kmutex_t wgw_lock;
429 kcondvar_t wgw_cv; 429 kcondvar_t wgw_cv;
430 bool wgw_todie; 430 bool wgw_todie;
431 struct socket *wgw_so4; 431 struct socket *wgw_so4;
432 struct socket *wgw_so6; 432 struct socket *wgw_so6;
433 int wgw_wakeup_reasons; 433 int wgw_wakeup_reasons;
434#define WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4 __BIT(0) 434#define WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4 __BIT(0)
435#define WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6 __BIT(1) 435#define WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6 __BIT(1)
436#define WG_WAKEUP_REASON_PEER __BIT(2) 436#define WG_WAKEUP_REASON_PEER __BIT(2)
437}; 437};
438 438
439struct wg_session { 439struct wg_session {
440 struct wg_peer *wgs_peer; 440 struct wg_peer *wgs_peer;
441 struct psref_target 441 struct psref_target
442 wgs_psref; 442 wgs_psref;
443 kmutex_t *wgs_lock; 443 kmutex_t *wgs_lock;
444 444
445 int wgs_state; 445 int wgs_state;
446#define WGS_STATE_UNKNOWN 0 446#define WGS_STATE_UNKNOWN 0
447#define WGS_STATE_INIT_ACTIVE 1 447#define WGS_STATE_INIT_ACTIVE 1
448#define WGS_STATE_INIT_PASSIVE 2 448#define WGS_STATE_INIT_PASSIVE 2
449#define WGS_STATE_ESTABLISHED 3 449#define WGS_STATE_ESTABLISHED 3
450#define WGS_STATE_DESTROYING 4 450#define WGS_STATE_DESTROYING 4
451 451
452 time_t wgs_time_established; 452 time_t wgs_time_established;
453 time_t wgs_time_last_data_sent; 453 time_t wgs_time_last_data_sent;
454 bool wgs_is_initiator; 454 bool wgs_is_initiator;
455 455
456 uint32_t wgs_sender_index; 456 uint32_t wgs_sender_index;
457 uint32_t wgs_receiver_index; 457 uint32_t wgs_receiver_index;
458#ifdef __HAVE_ATOMIC64_LOADSTORE 458#ifdef __HAVE_ATOMIC64_LOADSTORE
459 volatile uint64_t 459 volatile uint64_t
460 wgs_send_counter; 460 wgs_send_counter;
461#else 461#else
462 kmutex_t wgs_send_counter_lock; 462 kmutex_t wgs_send_counter_lock;
463 uint64_t wgs_send_counter; 463 uint64_t wgs_send_counter;
464#endif 464#endif
465 465
466 struct { 466 struct {
467 kmutex_t lock; 467 kmutex_t lock;
468 struct sliwin window; 468 struct sliwin window;
469 } *wgs_recvwin; 469 } *wgs_recvwin;
470 470
471 uint8_t wgs_handshake_hash[WG_HASH_LEN]; 471 uint8_t wgs_handshake_hash[WG_HASH_LEN];
472 uint8_t wgs_chaining_key[WG_CHAINING_KEY_LEN]; 472 uint8_t wgs_chaining_key[WG_CHAINING_KEY_LEN];
473 uint8_t wgs_ephemeral_key_pub[WG_EPHEMERAL_KEY_LEN]; 473 uint8_t wgs_ephemeral_key_pub[WG_EPHEMERAL_KEY_LEN];
474 uint8_t wgs_ephemeral_key_priv[WG_EPHEMERAL_KEY_LEN]; 474 uint8_t wgs_ephemeral_key_priv[WG_EPHEMERAL_KEY_LEN];
475 uint8_t wgs_ephemeral_key_peer[WG_EPHEMERAL_KEY_LEN]; 475 uint8_t wgs_ephemeral_key_peer[WG_EPHEMERAL_KEY_LEN];
476 uint8_t wgs_tkey_send[WG_DATA_KEY_LEN]; 476 uint8_t wgs_tkey_send[WG_DATA_KEY_LEN];
477 uint8_t wgs_tkey_recv[WG_DATA_KEY_LEN]; 477 uint8_t wgs_tkey_recv[WG_DATA_KEY_LEN];
478}; 478};
479 479
480struct wg_sockaddr { 480struct wg_sockaddr {
481 union { 481 union {
482 struct sockaddr_storage _ss; 482 struct sockaddr_storage _ss;
483 struct sockaddr _sa; 483 struct sockaddr _sa;
484 struct sockaddr_in _sin; 484 struct sockaddr_in _sin;
485 struct sockaddr_in6 _sin6; 485 struct sockaddr_in6 _sin6;
486 }; 486 };
487 struct psref_target wgsa_psref; 487 struct psref_target wgsa_psref;
488}; 488};
489 489
490#define wgsatosa(wgsa) (&(wgsa)->_sa) 490#define wgsatosa(wgsa) (&(wgsa)->_sa)
491#define wgsatosin(wgsa) (&(wgsa)->_sin) 491#define wgsatosin(wgsa) (&(wgsa)->_sin)
492#define wgsatosin6(wgsa) (&(wgsa)->_sin6) 492#define wgsatosin6(wgsa) (&(wgsa)->_sin6)
493 493
494struct wg_peer; 494struct wg_peer;
495struct wg_allowedip { 495struct wg_allowedip {
496 struct radix_node wga_nodes[2]; 496 struct radix_node wga_nodes[2];
497 struct wg_sockaddr _wga_sa_addr; 497 struct wg_sockaddr _wga_sa_addr;
498 struct wg_sockaddr _wga_sa_mask; 498 struct wg_sockaddr _wga_sa_mask;
499#define wga_sa_addr _wga_sa_addr._sa 499#define wga_sa_addr _wga_sa_addr._sa
500#define wga_sa_mask _wga_sa_mask._sa 500#define wga_sa_mask _wga_sa_mask._sa
501 501
502 int wga_family; 502 int wga_family;
503 uint8_t wga_cidr; 503 uint8_t wga_cidr;
504 union { 504 union {
505 struct in_addr _ip4; 505 struct in_addr _ip4;
506 struct in6_addr _ip6; 506 struct in6_addr _ip6;
507 } wga_addr; 507 } wga_addr;
508#define wga_addr4 wga_addr._ip4 508#define wga_addr4 wga_addr._ip4
509#define wga_addr6 wga_addr._ip6 509#define wga_addr6 wga_addr._ip6
510 510
511 struct wg_peer *wga_peer; 511 struct wg_peer *wga_peer;
512}; 512};
513 513
514typedef uint8_t wg_timestamp_t[WG_TIMESTAMP_LEN]; 514typedef uint8_t wg_timestamp_t[WG_TIMESTAMP_LEN];
515 515
516struct wg_ppsratecheck { 516struct wg_ppsratecheck {
517 struct timeval wgprc_lasttime; 517 struct timeval wgprc_lasttime;
518 int wgprc_curpps; 518 int wgprc_curpps;
519}; 519};
520 520
521struct wg_softc; 521struct wg_softc;
522struct wg_peer { 522struct wg_peer {
523 struct wg_softc *wgp_sc; 523 struct wg_softc *wgp_sc;
524 char wgp_name[WG_PEER_NAME_MAXLEN + 1]; 524 char wgp_name[WG_PEER_NAME_MAXLEN + 1];
525 struct pslist_entry wgp_peerlist_entry; 525 struct pslist_entry wgp_peerlist_entry;
526 pserialize_t wgp_psz; 526 pserialize_t wgp_psz;
527 struct psref_target wgp_psref; 527 struct psref_target wgp_psref;
528 kmutex_t *wgp_lock; 528 kmutex_t *wgp_lock;
529 529
530 uint8_t wgp_pubkey[WG_STATIC_KEY_LEN]; 530 uint8_t wgp_pubkey[WG_STATIC_KEY_LEN];
531 struct wg_sockaddr *wgp_endpoint; 531 struct wg_sockaddr *wgp_endpoint;
532#define wgp_ss wgp_endpoint->_ss 532#define wgp_ss wgp_endpoint->_ss
533#define wgp_sa wgp_endpoint->_sa 533#define wgp_sa wgp_endpoint->_sa
534#define wgp_sin wgp_endpoint->_sin 534#define wgp_sin wgp_endpoint->_sin
535#define wgp_sin6 wgp_endpoint->_sin6 535#define wgp_sin6 wgp_endpoint->_sin6
536 struct wg_sockaddr *wgp_endpoint0; 536 struct wg_sockaddr *wgp_endpoint0;
537 bool wgp_endpoint_changing; 537 bool wgp_endpoint_changing;
538 bool wgp_endpoint_available; 538 bool wgp_endpoint_available;
539 539
540 /* The preshared key (optional) */ 540 /* The preshared key (optional) */
541 uint8_t wgp_psk[WG_PRESHARED_KEY_LEN]; 541 uint8_t wgp_psk[WG_PRESHARED_KEY_LEN];
542 542
543 int wgp_state; 543 int wgp_state;
544#define WGP_STATE_INIT 0 544#define WGP_STATE_INIT 0
545#define WGP_STATE_ESTABLISHED 1 545#define WGP_STATE_ESTABLISHED 1
546#define WGP_STATE_GIVEUP 2 546#define WGP_STATE_GIVEUP 2
547#define WGP_STATE_DESTROYING 3 547#define WGP_STATE_DESTROYING 3
548 548
549 void *wgp_si; 549 void *wgp_si;
550 pcq_t *wgp_q; 550 pcq_t *wgp_q;
551 551
552 struct wg_session *wgp_session_stable; 552 struct wg_session *wgp_session_stable;
553 struct wg_session *wgp_session_unstable; 553 struct wg_session *wgp_session_unstable;
554 554
555 /* timestamp in big-endian */ 555 /* timestamp in big-endian */
556 wg_timestamp_t wgp_timestamp_latest_init; 556 wg_timestamp_t wgp_timestamp_latest_init;
557 557
558 struct timespec wgp_last_handshake_time; 558 struct timespec wgp_last_handshake_time;
559 559
560 callout_t wgp_rekey_timer; 560 callout_t wgp_rekey_timer;
561 callout_t wgp_handshake_timeout_timer; 561 callout_t wgp_handshake_timeout_timer;
562 callout_t wgp_session_dtor_timer; 562 callout_t wgp_session_dtor_timer;
563 563
564 time_t wgp_handshake_start_time; 564 time_t wgp_handshake_start_time;
565 565
566 int wgp_n_allowedips; 566 int wgp_n_allowedips;
567 struct wg_allowedip wgp_allowedips[WG_ALLOWEDIPS]; 567 struct wg_allowedip wgp_allowedips[WG_ALLOWEDIPS];
568 568
569 time_t wgp_latest_cookie_time; 569 time_t wgp_latest_cookie_time;
570 uint8_t wgp_latest_cookie[WG_COOKIE_LEN]; 570 uint8_t wgp_latest_cookie[WG_COOKIE_LEN];
571 uint8_t wgp_last_sent_mac1[WG_MAC_LEN]; 571 uint8_t wgp_last_sent_mac1[WG_MAC_LEN];
572 bool wgp_last_sent_mac1_valid; 572 bool wgp_last_sent_mac1_valid;
573 uint8_t wgp_last_sent_cookie[WG_COOKIE_LEN]; 573 uint8_t wgp_last_sent_cookie[WG_COOKIE_LEN];
574 bool wgp_last_sent_cookie_valid; 574 bool wgp_last_sent_cookie_valid;
575 575
576 time_t wgp_last_msg_received_time[WG_MSG_TYPE_MAX]; 576 time_t wgp_last_msg_received_time[WG_MSG_TYPE_MAX];
577 577
578 time_t wgp_last_genrandval_time; 578 time_t wgp_last_genrandval_time;
579 uint32_t wgp_randval; 579 uint32_t wgp_randval;
580 580
581 struct wg_ppsratecheck wgp_ppsratecheck; 581 struct wg_ppsratecheck wgp_ppsratecheck;
582 582
583 volatile unsigned int wgp_tasks; 583 volatile unsigned int wgp_tasks;
584#define WGP_TASK_SEND_INIT_MESSAGE __BIT(0) 584#define WGP_TASK_SEND_INIT_MESSAGE __BIT(0)
585#define WGP_TASK_ENDPOINT_CHANGED __BIT(1) 585#define WGP_TASK_ENDPOINT_CHANGED __BIT(1)
586#define WGP_TASK_SEND_KEEPALIVE_MESSAGE __BIT(2) 586#define WGP_TASK_SEND_KEEPALIVE_MESSAGE __BIT(2)
587#define WGP_TASK_DESTROY_PREV_SESSION __BIT(3) 587#define WGP_TASK_DESTROY_PREV_SESSION __BIT(3)
588}; 588};
589 589
590struct wg_ops; 590struct wg_ops;
591 591
592struct wg_softc { 592struct wg_softc {
593 struct ifnet wg_if; 593 struct ifnet wg_if;
594 LIST_ENTRY(wg_softc) wg_list; 594 LIST_ENTRY(wg_softc) wg_list;
595 kmutex_t *wg_lock; 595 kmutex_t *wg_lock;
596 krwlock_t *wg_rwlock; 596 krwlock_t *wg_rwlock;
597 597
598 uint8_t wg_privkey[WG_STATIC_KEY_LEN]; 598 uint8_t wg_privkey[WG_STATIC_KEY_LEN];
599 uint8_t wg_pubkey[WG_STATIC_KEY_LEN]; 599 uint8_t wg_pubkey[WG_STATIC_KEY_LEN];
600 600
601 int wg_npeers; 601 int wg_npeers;
602 struct pslist_head wg_peers; 602 struct pslist_head wg_peers;
603 uint16_t wg_listen_port; 603 uint16_t wg_listen_port;
604 604
605 struct wg_worker *wg_worker; 605 struct wg_worker *wg_worker;
606 lwp_t *wg_worker_lwp; 606 lwp_t *wg_worker_lwp;
607 607
608 struct radix_node_head *wg_rtable_ipv4; 608 struct radix_node_head *wg_rtable_ipv4;
609 struct radix_node_head *wg_rtable_ipv6; 609 struct radix_node_head *wg_rtable_ipv6;
610 610
611 struct wg_ppsratecheck wg_ppsratecheck; 611 struct wg_ppsratecheck wg_ppsratecheck;
612 612
613 struct wg_ops *wg_ops; 613 struct wg_ops *wg_ops;
614 614
615#ifdef WG_RUMPKERNEL 615#ifdef WG_RUMPKERNEL
616 struct wg_user *wg_user; 616 struct wg_user *wg_user;
617#endif 617#endif
618}; 618};
619 619
620/* [W] 6.1 Preliminaries */ 620/* [W] 6.1 Preliminaries */
621#define WG_REKEY_AFTER_MESSAGES (1ULL << 60) 621#define WG_REKEY_AFTER_MESSAGES (1ULL << 60)
622#define WG_REJECT_AFTER_MESSAGES (UINT64_MAX - (1 << 13)) 622#define WG_REJECT_AFTER_MESSAGES (UINT64_MAX - (1 << 13))
623#define WG_REKEY_AFTER_TIME 120 623#define WG_REKEY_AFTER_TIME 120
624#define WG_REJECT_AFTER_TIME 180 624#define WG_REJECT_AFTER_TIME 180
625#define WG_REKEY_ATTEMPT_TIME 90 625#define WG_REKEY_ATTEMPT_TIME 90
626#define WG_REKEY_TIMEOUT 5 626#define WG_REKEY_TIMEOUT 5
627#define WG_KEEPALIVE_TIMEOUT 10 627#define WG_KEEPALIVE_TIMEOUT 10
628 628
629#define WG_COOKIE_TIME 120 629#define WG_COOKIE_TIME 120
630#define WG_RANDVAL_TIME (2 * 60) 630#define WG_RANDVAL_TIME (2 * 60)
631 631
632static uint64_t wg_rekey_after_messages = WG_REKEY_AFTER_MESSAGES; 632static uint64_t wg_rekey_after_messages = WG_REKEY_AFTER_MESSAGES;
633static uint64_t wg_reject_after_messages = WG_REJECT_AFTER_MESSAGES; 633static uint64_t wg_reject_after_messages = WG_REJECT_AFTER_MESSAGES;
634static unsigned wg_rekey_after_time = WG_REKEY_AFTER_TIME; 634static unsigned wg_rekey_after_time = WG_REKEY_AFTER_TIME;
635static unsigned wg_reject_after_time = WG_REJECT_AFTER_TIME; 635static unsigned wg_reject_after_time = WG_REJECT_AFTER_TIME;
636static unsigned wg_rekey_attempt_time = WG_REKEY_ATTEMPT_TIME; 636static unsigned wg_rekey_attempt_time = WG_REKEY_ATTEMPT_TIME;
637static unsigned wg_rekey_timeout = WG_REKEY_TIMEOUT; 637static unsigned wg_rekey_timeout = WG_REKEY_TIMEOUT;
638static unsigned wg_keepalive_timeout = WG_KEEPALIVE_TIMEOUT; 638static unsigned wg_keepalive_timeout = WG_KEEPALIVE_TIMEOUT;
639 639
640static struct mbuf * 640static struct mbuf *
641 wg_get_mbuf(size_t, size_t); 641 wg_get_mbuf(size_t, size_t);
642 642
643static void wg_wakeup_worker(struct wg_worker *, int); 643static void wg_wakeup_worker(struct wg_worker *, int);
644 644
645static int wg_send_data_msg(struct wg_peer *, struct wg_session *, 645static int wg_send_data_msg(struct wg_peer *, struct wg_session *,
646 struct mbuf *); 646 struct mbuf *);
647static int wg_send_cookie_msg(struct wg_softc *, struct wg_peer *, 647static int wg_send_cookie_msg(struct wg_softc *, struct wg_peer *,
648 const uint32_t, const uint8_t [], const struct sockaddr *); 648 const uint32_t, const uint8_t [], const struct sockaddr *);
649static int wg_send_handshake_msg_resp(struct wg_softc *, 649static int wg_send_handshake_msg_resp(struct wg_softc *,
650 struct wg_peer *, const struct wg_msg_init *); 650 struct wg_peer *, const struct wg_msg_init *);
651static void wg_send_keepalive_msg(struct wg_peer *, struct wg_session *); 651static void wg_send_keepalive_msg(struct wg_peer *, struct wg_session *);
652 652
653static struct wg_peer * 653static struct wg_peer *
654 wg_pick_peer_by_sa(struct wg_softc *, const struct sockaddr *, 654 wg_pick_peer_by_sa(struct wg_softc *, const struct sockaddr *,
655 struct psref *); 655 struct psref *);
656static struct wg_peer * 656static struct wg_peer *
657 wg_lookup_peer_by_pubkey(struct wg_softc *, 657 wg_lookup_peer_by_pubkey(struct wg_softc *,
658 const uint8_t [], struct psref *); 658 const uint8_t [], struct psref *);
659 659
660static struct wg_session * 660static struct wg_session *
661 wg_lookup_session_by_index(struct wg_softc *, 661 wg_lookup_session_by_index(struct wg_softc *,
662 const uint32_t, struct psref *); 662 const uint32_t, struct psref *);
663 663
664static void wg_update_endpoint_if_necessary(struct wg_peer *, 664static void wg_update_endpoint_if_necessary(struct wg_peer *,
665 const struct sockaddr *); 665 const struct sockaddr *);
666 666
667static void wg_schedule_rekey_timer(struct wg_peer *); 667static void wg_schedule_rekey_timer(struct wg_peer *);
668static void wg_schedule_session_dtor_timer(struct wg_peer *); 668static void wg_schedule_session_dtor_timer(struct wg_peer *);
669static void wg_stop_session_dtor_timer(struct wg_peer *); 669static void wg_stop_session_dtor_timer(struct wg_peer *);
670 670
671static bool wg_is_underload(struct wg_softc *, struct wg_peer *, int); 671static bool wg_is_underload(struct wg_softc *, struct wg_peer *, int);
672static void wg_calculate_keys(struct wg_session *, const bool); 672static void wg_calculate_keys(struct wg_session *, const bool);
673 673
674static void wg_clear_states(struct wg_session *); 674static void wg_clear_states(struct wg_session *);
675 675
676static void wg_get_peer(struct wg_peer *, struct psref *); 676static void wg_get_peer(struct wg_peer *, struct psref *);
677static void wg_put_peer(struct wg_peer *, struct psref *); 677static void wg_put_peer(struct wg_peer *, struct psref *);
678 678
679static int wg_send_so(struct wg_peer *, struct mbuf *); 679static int wg_send_so(struct wg_peer *, struct mbuf *);
680static int wg_send_udp(struct wg_peer *, struct mbuf *); 680static int wg_send_udp(struct wg_peer *, struct mbuf *);
681static int wg_output(struct ifnet *, struct mbuf *, 681static int wg_output(struct ifnet *, struct mbuf *,
682 const struct sockaddr *, const struct rtentry *); 682 const struct sockaddr *, const struct rtentry *);
683static void wg_input(struct ifnet *, struct mbuf *, const int); 683static void wg_input(struct ifnet *, struct mbuf *, const int);
684static int wg_ioctl(struct ifnet *, u_long, void *); 684static int wg_ioctl(struct ifnet *, u_long, void *);
685static int wg_bind_port(struct wg_softc *, const uint16_t); 685static int wg_bind_port(struct wg_softc *, const uint16_t);
686static int wg_init(struct ifnet *); 686static int wg_init(struct ifnet *);
687static void wg_stop(struct ifnet *, int); 687static void wg_stop(struct ifnet *, int);
688 688
689static int wg_clone_create(struct if_clone *, int); 689static int wg_clone_create(struct if_clone *, int);
690static int wg_clone_destroy(struct ifnet *); 690static int wg_clone_destroy(struct ifnet *);
691 691
692struct wg_ops { 692struct wg_ops {
693 int (*send_hs_msg)(struct wg_peer *, struct mbuf *); 693 int (*send_hs_msg)(struct wg_peer *, struct mbuf *);
694 int (*send_data_msg)(struct wg_peer *, struct mbuf *); 694 int (*send_data_msg)(struct wg_peer *, struct mbuf *);
695 void (*input)(struct ifnet *, struct mbuf *, const int); 695 void (*input)(struct ifnet *, struct mbuf *, const int);
696 int (*bind_port)(struct wg_softc *, const uint16_t); 696 int (*bind_port)(struct wg_softc *, const uint16_t);
697}; 697};
698 698
699struct wg_ops wg_ops_rumpkernel = { 699struct wg_ops wg_ops_rumpkernel = {
700 .send_hs_msg = wg_send_so, 700 .send_hs_msg = wg_send_so,
701 .send_data_msg = wg_send_udp, 701 .send_data_msg = wg_send_udp,
702 .input = wg_input, 702 .input = wg_input,
703 .bind_port = wg_bind_port, 703 .bind_port = wg_bind_port,
704}; 704};
705 705
706#ifdef WG_RUMPKERNEL 706#ifdef WG_RUMPKERNEL
707static bool wg_user_mode(struct wg_softc *); 707static bool wg_user_mode(struct wg_softc *);
708static int wg_ioctl_linkstr(struct wg_softc *, struct ifdrv *); 708static int wg_ioctl_linkstr(struct wg_softc *, struct ifdrv *);
709 709
710static int wg_send_user(struct wg_peer *, struct mbuf *); 710static int wg_send_user(struct wg_peer *, struct mbuf *);
711static void wg_input_user(struct ifnet *, struct mbuf *, const int); 711static void wg_input_user(struct ifnet *, struct mbuf *, const int);
712static int wg_bind_port_user(struct wg_softc *, const uint16_t); 712static int wg_bind_port_user(struct wg_softc *, const uint16_t);
713 713
714struct wg_ops wg_ops_rumpuser = { 714struct wg_ops wg_ops_rumpuser = {
715 .send_hs_msg = wg_send_user, 715 .send_hs_msg = wg_send_user,
716 .send_data_msg = wg_send_user, 716 .send_data_msg = wg_send_user,
717 .input = wg_input_user, 717 .input = wg_input_user,
718 .bind_port = wg_bind_port_user, 718 .bind_port = wg_bind_port_user,
719}; 719};
720#endif 720#endif
721 721
722#define WG_PEER_READER_FOREACH(wgp, wg) \ 722#define WG_PEER_READER_FOREACH(wgp, wg) \
723 PSLIST_READER_FOREACH((wgp), &(wg)->wg_peers, struct wg_peer, \ 723 PSLIST_READER_FOREACH((wgp), &(wg)->wg_peers, struct wg_peer, \
724 wgp_peerlist_entry) 724 wgp_peerlist_entry)
725#define WG_PEER_WRITER_FOREACH(wgp, wg) \ 725#define WG_PEER_WRITER_FOREACH(wgp, wg) \
726 PSLIST_WRITER_FOREACH((wgp), &(wg)->wg_peers, struct wg_peer, \ 726 PSLIST_WRITER_FOREACH((wgp), &(wg)->wg_peers, struct wg_peer, \
727 wgp_peerlist_entry) 727 wgp_peerlist_entry)
728#define WG_PEER_WRITER_INSERT_HEAD(wgp, wg) \ 728#define WG_PEER_WRITER_INSERT_HEAD(wgp, wg) \
729 PSLIST_WRITER_INSERT_HEAD(&(wg)->wg_peers, (wgp), wgp_peerlist_entry) 729 PSLIST_WRITER_INSERT_HEAD(&(wg)->wg_peers, (wgp), wgp_peerlist_entry)
730#define WG_PEER_WRITER_REMOVE(wgp) \ 730#define WG_PEER_WRITER_REMOVE(wgp) \
731 PSLIST_WRITER_REMOVE((wgp), wgp_peerlist_entry) 731 PSLIST_WRITER_REMOVE((wgp), wgp_peerlist_entry)
732 732
733struct wg_route { 733struct wg_route {
734 struct radix_node wgr_nodes[2]; 734 struct radix_node wgr_nodes[2];
735 struct wg_peer *wgr_peer; 735 struct wg_peer *wgr_peer;
736}; 736};
737 737
738static struct radix_node_head * 738static struct radix_node_head *
739wg_rnh(struct wg_softc *wg, const int family) 739wg_rnh(struct wg_softc *wg, const int family)
740{ 740{
741 741
742 switch (family) { 742 switch (family) {
743 case AF_INET: 743 case AF_INET:
744 return wg->wg_rtable_ipv4; 744 return wg->wg_rtable_ipv4;
745#ifdef INET6 745#ifdef INET6
746 case AF_INET6: 746 case AF_INET6:
747 return wg->wg_rtable_ipv6; 747 return wg->wg_rtable_ipv6;
748#endif 748#endif
749 default: 749 default:
750 return NULL; 750 return NULL;
751 } 751 }
752} 752}
753 753
754 754
755/* 755/*
756 * Global variables 756 * Global variables
757 */ 757 */
758LIST_HEAD(wg_sclist, wg_softc); 758LIST_HEAD(wg_sclist, wg_softc);
759static struct { 759static struct {
760 struct wg_sclist list; 760 struct wg_sclist list;
761 kmutex_t lock; 761 kmutex_t lock;
762} wg_softcs __cacheline_aligned; 762} wg_softcs __cacheline_aligned;
763 763
764struct psref_class *wg_psref_class __read_mostly; 764struct psref_class *wg_psref_class __read_mostly;
765 765
766static struct if_clone wg_cloner = 766static struct if_clone wg_cloner =
767 IF_CLONE_INITIALIZER("wg", wg_clone_create, wg_clone_destroy); 767 IF_CLONE_INITIALIZER("wg", wg_clone_create, wg_clone_destroy);
768 768
769 769
770void wgattach(int); 770void wgattach(int);
771/* ARGSUSED */ 771/* ARGSUSED */
772void 772void
773wgattach(int count) 773wgattach(int count)
774{ 774{
775 /* 775 /*
776 * Nothing to do here, initialization is handled by the 776 * Nothing to do here, initialization is handled by the
777 * module initialization code in wginit() below). 777 * module initialization code in wginit() below).
778 */ 778 */
779} 779}
780 780
781static void 781static void
782wginit(void) 782wginit(void)
783{ 783{
784 784
785 wg_psref_class = psref_class_create("wg", IPL_SOFTNET); 785 wg_psref_class = psref_class_create("wg", IPL_SOFTNET);
786 786
787 mutex_init(&wg_softcs.lock, MUTEX_DEFAULT, IPL_NONE); 787 mutex_init(&wg_softcs.lock, MUTEX_DEFAULT, IPL_NONE);
788 LIST_INIT(&wg_softcs.list); 788 LIST_INIT(&wg_softcs.list);
789 if_clone_attach(&wg_cloner); 789 if_clone_attach(&wg_cloner);
790} 790}
791 791
792static int 792static int
793wgdetach(void) 793wgdetach(void)
794{ 794{
795 int error = 0; 795 int error = 0;
796 796
797 mutex_enter(&wg_softcs.lock); 797 mutex_enter(&wg_softcs.lock);
798 if (!LIST_EMPTY(&wg_softcs.list)) { 798 if (!LIST_EMPTY(&wg_softcs.list)) {
799 mutex_exit(&wg_softcs.lock); 799 mutex_exit(&wg_softcs.lock);
800 error = EBUSY; 800 error = EBUSY;
801 } 801 }
802 802
803 if (error == 0) { 803 if (error == 0) {
804 psref_class_destroy(wg_psref_class); 804 psref_class_destroy(wg_psref_class);
805 805
806 if_clone_detach(&wg_cloner); 806 if_clone_detach(&wg_cloner);
807 } 807 }
808 808
809 return error; 809 return error;
810} 810}
811 811
812static void 812static void
813wg_init_key_and_hash(uint8_t ckey[WG_CHAINING_KEY_LEN], 813wg_init_key_and_hash(uint8_t ckey[WG_CHAINING_KEY_LEN],
814 uint8_t hash[WG_HASH_LEN]) 814 uint8_t hash[WG_HASH_LEN])
815{ 815{
816 /* [W] 5.4: CONSTRUCTION */ 816 /* [W] 5.4: CONSTRUCTION */
817 const char *signature = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"; 817 const char *signature = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s";
818 /* [W] 5.4: IDENTIFIER */ 818 /* [W] 5.4: IDENTIFIER */
819 const char *id = "WireGuard v1 zx2c4 Jason@zx2c4.com"; 819 const char *id = "WireGuard v1 zx2c4 Jason@zx2c4.com";
820 struct blake2s state; 820 struct blake2s state;
821 821
822 blake2s(ckey, WG_CHAINING_KEY_LEN, NULL, 0, 822 blake2s(ckey, WG_CHAINING_KEY_LEN, NULL, 0,
823 signature, strlen(signature)); 823 signature, strlen(signature));
824 824
825 CTASSERT(WG_HASH_LEN == WG_CHAINING_KEY_LEN); 825 CTASSERT(WG_HASH_LEN == WG_CHAINING_KEY_LEN);
826 memcpy(hash, ckey, WG_CHAINING_KEY_LEN); 826 memcpy(hash, ckey, WG_CHAINING_KEY_LEN);
827 827
828 blake2s_init(&state, WG_HASH_LEN, NULL, 0); 828 blake2s_init(&state, WG_HASH_LEN, NULL, 0);
829 blake2s_update(&state, ckey, WG_CHAINING_KEY_LEN); 829 blake2s_update(&state, ckey, WG_CHAINING_KEY_LEN);
830 blake2s_update(&state, id, strlen(id)); 830 blake2s_update(&state, id, strlen(id));
831 blake2s_final(&state, hash); 831 blake2s_final(&state, hash);
832 832
833 WG_DUMP_HASH("ckey", ckey); 833 WG_DUMP_HASH("ckey", ckey);
834 WG_DUMP_HASH("hash", hash); 834 WG_DUMP_HASH("hash", hash);
835} 835}
836 836
837static void 837static void
838wg_algo_hash(uint8_t hash[WG_HASH_LEN], const uint8_t input[], 838wg_algo_hash(uint8_t hash[WG_HASH_LEN], const uint8_t input[],
839 const size_t inputsize) 839 const size_t inputsize)
840{ 840{
841 struct blake2s state; 841 struct blake2s state;
842 842
843 blake2s_init(&state, WG_HASH_LEN, NULL, 0); 843 blake2s_init(&state, WG_HASH_LEN, NULL, 0);
844 blake2s_update(&state, hash, WG_HASH_LEN); 844 blake2s_update(&state, hash, WG_HASH_LEN);
845 blake2s_update(&state, input, inputsize); 845 blake2s_update(&state, input, inputsize);
846 blake2s_final(&state, hash); 846 blake2s_final(&state, hash);
847} 847}
848 848
849static void 849static void
850wg_algo_mac(uint8_t out[], const size_t outsize, 850wg_algo_mac(uint8_t out[], const size_t outsize,
851 const uint8_t key[], const size_t keylen, 851 const uint8_t key[], const size_t keylen,
852 const uint8_t input1[], const size_t input1len, 852 const uint8_t input1[], const size_t input1len,
853 const uint8_t input2[], const size_t input2len) 853 const uint8_t input2[], const size_t input2len)
854{ 854{
855 struct blake2s state; 855 struct blake2s state;
856 856
857 blake2s_init(&state, outsize, key, keylen); 857 blake2s_init(&state, outsize, key, keylen);
858 858
859 blake2s_update(&state, input1, input1len); 859 blake2s_update(&state, input1, input1len);
860 if (input2 != NULL) 860 if (input2 != NULL)
861 blake2s_update(&state, input2, input2len); 861 blake2s_update(&state, input2, input2len);
862 blake2s_final(&state, out); 862 blake2s_final(&state, out);
863} 863}
864 864
865static void 865static void
866wg_algo_mac_mac1(uint8_t out[], const size_t outsize, 866wg_algo_mac_mac1(uint8_t out[], const size_t outsize,
867 const uint8_t input1[], const size_t input1len, 867 const uint8_t input1[], const size_t input1len,
868 const uint8_t input2[], const size_t input2len) 868 const uint8_t input2[], const size_t input2len)
869{ 869{
870 struct blake2s state; 870 struct blake2s state;
871 /* [W] 5.4: LABEL-MAC1 */ 871 /* [W] 5.4: LABEL-MAC1 */
872 const char *label = "mac1----"; 872 const char *label = "mac1----";
873 uint8_t key[WG_HASH_LEN]; 873 uint8_t key[WG_HASH_LEN];
874 874
875 blake2s_init(&state, sizeof(key), NULL, 0); 875 blake2s_init(&state, sizeof(key), NULL, 0);
876 blake2s_update(&state, label, strlen(label)); 876 blake2s_update(&state, label, strlen(label));
877 blake2s_update(&state, input1, input1len); 877 blake2s_update(&state, input1, input1len);
878 blake2s_final(&state, key); 878 blake2s_final(&state, key);
879 879
880 blake2s_init(&state, outsize, key, sizeof(key)); 880 blake2s_init(&state, outsize, key, sizeof(key));
881 if (input2 != NULL) 881 if (input2 != NULL)
882 blake2s_update(&state, input2, input2len); 882 blake2s_update(&state, input2, input2len);
883 blake2s_final(&state, out); 883 blake2s_final(&state, out);
884} 884}
885 885
886static void 886static void
887wg_algo_mac_cookie(uint8_t out[], const size_t outsize, 887wg_algo_mac_cookie(uint8_t out[], const size_t outsize,
888 const uint8_t input1[], const size_t input1len) 888 const uint8_t input1[], const size_t input1len)
889{ 889{
890 struct blake2s state; 890 struct blake2s state;
891 /* [W] 5.4: LABEL-COOKIE */ 891 /* [W] 5.4: LABEL-COOKIE */
892 const char *label = "cookie--"; 892 const char *label = "cookie--";
893 893
894 blake2s_init(&state, outsize, NULL, 0); 894 blake2s_init(&state, outsize, NULL, 0);
895 blake2s_update(&state, label, strlen(label)); 895 blake2s_update(&state, label, strlen(label));
896 blake2s_update(&state, input1, input1len); 896 blake2s_update(&state, input1, input1len);
897 blake2s_final(&state, out); 897 blake2s_final(&state, out);
898} 898}
899 899
900static void 900static void
901wg_algo_generate_keypair(uint8_t pubkey[WG_EPHEMERAL_KEY_LEN], 901wg_algo_generate_keypair(uint8_t pubkey[WG_EPHEMERAL_KEY_LEN],
902 uint8_t privkey[WG_EPHEMERAL_KEY_LEN]) 902 uint8_t privkey[WG_EPHEMERAL_KEY_LEN])
903{ 903{
904 904
905 CTASSERT(WG_EPHEMERAL_KEY_LEN == crypto_scalarmult_curve25519_BYTES); 905 CTASSERT(WG_EPHEMERAL_KEY_LEN == crypto_scalarmult_curve25519_BYTES);
906 906
907 cprng_strong(kern_cprng, privkey, WG_EPHEMERAL_KEY_LEN, 0); 907 cprng_strong(kern_cprng, privkey, WG_EPHEMERAL_KEY_LEN, 0);
908 crypto_scalarmult_base(pubkey, privkey); 908 crypto_scalarmult_base(pubkey, privkey);
909} 909}
910 910
911static void 911static void
912wg_algo_dh(uint8_t out[WG_DH_OUTPUT_LEN], 912wg_algo_dh(uint8_t out[WG_DH_OUTPUT_LEN],
913 const uint8_t privkey[WG_STATIC_KEY_LEN], 913 const uint8_t privkey[WG_STATIC_KEY_LEN],
914 const uint8_t pubkey[WG_STATIC_KEY_LEN]) 914 const uint8_t pubkey[WG_STATIC_KEY_LEN])
915{ 915{
916 916
917 CTASSERT(WG_STATIC_KEY_LEN == crypto_scalarmult_curve25519_BYTES); 917 CTASSERT(WG_STATIC_KEY_LEN == crypto_scalarmult_curve25519_BYTES);
918 918
919 int ret __diagused = crypto_scalarmult(out, privkey, pubkey); 919 int ret __diagused = crypto_scalarmult(out, privkey, pubkey);
920 KASSERT(ret == 0); 920 KASSERT(ret == 0);
921} 921}
922 922
923static void 923static void
924wg_algo_hmac(uint8_t out[], const size_t outlen, 924wg_algo_hmac(uint8_t out[], const size_t outlen,
925 const uint8_t key[], const size_t keylen, 925 const uint8_t key[], const size_t keylen,
926 const uint8_t in[], const size_t inlen) 926 const uint8_t in[], const size_t inlen)
927{ 927{
928#define IPAD 0x36 928#define IPAD 0x36
929#define OPAD 0x5c 929#define OPAD 0x5c
930 uint8_t hmackey[HMAC_BLOCK_LEN] = {0}; 930 uint8_t hmackey[HMAC_BLOCK_LEN] = {0};
931 uint8_t ipad[HMAC_BLOCK_LEN]; 931 uint8_t ipad[HMAC_BLOCK_LEN];
932 uint8_t opad[HMAC_BLOCK_LEN]; 932 uint8_t opad[HMAC_BLOCK_LEN];
933 int i; 933 int i;
934 struct blake2s state; 934 struct blake2s state;
935 935
936 KASSERT(outlen == WG_HASH_LEN); 936 KASSERT(outlen == WG_HASH_LEN);
937 KASSERT(keylen <= HMAC_BLOCK_LEN); 937 KASSERT(keylen <= HMAC_BLOCK_LEN);
938 938
939 memcpy(hmackey, key, keylen); 939 memcpy(hmackey, key, keylen);
940 940
941 for (i = 0; i < sizeof(hmackey); i++) { 941 for (i = 0; i < sizeof(hmackey); i++) {
942 ipad[i] = hmackey[i] ^ IPAD; 942 ipad[i] = hmackey[i] ^ IPAD;
943 opad[i] = hmackey[i] ^ OPAD; 943 opad[i] = hmackey[i] ^ OPAD;
944 } 944 }
945 945
946 blake2s_init(&state, WG_HASH_LEN, NULL, 0); 946 blake2s_init(&state, WG_HASH_LEN, NULL, 0);
947 blake2s_update(&state, ipad, sizeof(ipad)); 947 blake2s_update(&state, ipad, sizeof(ipad));
948 blake2s_update(&state, in, inlen); 948 blake2s_update(&state, in, inlen);
949 blake2s_final(&state, out); 949 blake2s_final(&state, out);
950 950
951 blake2s_init(&state, WG_HASH_LEN, NULL, 0); 951 blake2s_init(&state, WG_HASH_LEN, NULL, 0);
952 blake2s_update(&state, opad, sizeof(opad)); 952 blake2s_update(&state, opad, sizeof(opad));
953 blake2s_update(&state, out, WG_HASH_LEN); 953 blake2s_update(&state, out, WG_HASH_LEN);
954 blake2s_final(&state, out); 954 blake2s_final(&state, out);
955#undef IPAD 955#undef IPAD
956#undef OPAD 956#undef OPAD
957} 957}
958 958
959static void 959static void
960wg_algo_kdf(uint8_t out1[WG_KDF_OUTPUT_LEN], uint8_t out2[WG_KDF_OUTPUT_LEN], 960wg_algo_kdf(uint8_t out1[WG_KDF_OUTPUT_LEN], uint8_t out2[WG_KDF_OUTPUT_LEN],
961 uint8_t out3[WG_KDF_OUTPUT_LEN], const uint8_t ckey[WG_CHAINING_KEY_LEN], 961 uint8_t out3[WG_KDF_OUTPUT_LEN], const uint8_t ckey[WG_CHAINING_KEY_LEN],
962 const uint8_t input[], const size_t inputlen) 962 const uint8_t input[], const size_t inputlen)
963{ 963{
964 uint8_t tmp1[WG_KDF_OUTPUT_LEN], tmp2[WG_KDF_OUTPUT_LEN + 1]; 964 uint8_t tmp1[WG_KDF_OUTPUT_LEN], tmp2[WG_KDF_OUTPUT_LEN + 1];
965 uint8_t one[1]; 965 uint8_t one[1];
966 966
967 /* 967 /*
968 * [N] 4.3: "an input_key_material byte sequence with length 968 * [N] 4.3: "an input_key_material byte sequence with length
969 * either zero bytes, 32 bytes, or DHLEN bytes." 969 * either zero bytes, 32 bytes, or DHLEN bytes."
970 */ 970 */
971 KASSERT(inputlen == 0 || inputlen == 32 || inputlen == NOISE_DHLEN); 971 KASSERT(inputlen == 0 || inputlen == 32 || inputlen == NOISE_DHLEN);
972 972
973 WG_DUMP_HASH("ckey", ckey); 973 WG_DUMP_HASH("ckey", ckey);
974 if (input != NULL) 974 if (input != NULL)
975 WG_DUMP_HASH("input", input); 975 WG_DUMP_HASH("input", input);
976 wg_algo_hmac(tmp1, sizeof(tmp1), ckey, WG_CHAINING_KEY_LEN, 976 wg_algo_hmac(tmp1, sizeof(tmp1), ckey, WG_CHAINING_KEY_LEN,
977 input, inputlen); 977 input, inputlen);
978 WG_DUMP_HASH("tmp1", tmp1); 978 WG_DUMP_HASH("tmp1", tmp1);
979 one[0] = 1; 979 one[0] = 1;
980 wg_algo_hmac(out1, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1), 980 wg_algo_hmac(out1, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1),
981 one, sizeof(one)); 981 one, sizeof(one));
982 WG_DUMP_HASH("out1", out1); 982 WG_DUMP_HASH("out1", out1);
983 if (out2 == NULL) 983 if (out2 == NULL)
984 return; 984 return;
985 memcpy(tmp2, out1, WG_KDF_OUTPUT_LEN); 985 memcpy(tmp2, out1, WG_KDF_OUTPUT_LEN);
986 tmp2[WG_KDF_OUTPUT_LEN] = 2; 986 tmp2[WG_KDF_OUTPUT_LEN] = 2;
987 wg_algo_hmac(out2, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1), 987 wg_algo_hmac(out2, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1),
988 tmp2, sizeof(tmp2)); 988 tmp2, sizeof(tmp2));
989 WG_DUMP_HASH("out2", out2); 989 WG_DUMP_HASH("out2", out2);
990 if (out3 == NULL) 990 if (out3 == NULL)
991 return; 991 return;
992 memcpy(tmp2, out2, WG_KDF_OUTPUT_LEN); 992 memcpy(tmp2, out2, WG_KDF_OUTPUT_LEN);
993 tmp2[WG_KDF_OUTPUT_LEN] = 3; 993 tmp2[WG_KDF_OUTPUT_LEN] = 3;
994 wg_algo_hmac(out3, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1), 994 wg_algo_hmac(out3, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1),
995 tmp2, sizeof(tmp2)); 995 tmp2, sizeof(tmp2));
996 WG_DUMP_HASH("out3", out3); 996 WG_DUMP_HASH("out3", out3);
997} 997}
998 998
999static void 999static void
1000wg_algo_dh_kdf(uint8_t ckey[WG_CHAINING_KEY_LEN], 1000wg_algo_dh_kdf(uint8_t ckey[WG_CHAINING_KEY_LEN],
1001 uint8_t cipher_key[WG_CIPHER_KEY_LEN], 1001 uint8_t cipher_key[WG_CIPHER_KEY_LEN],
1002 const uint8_t local_key[WG_STATIC_KEY_LEN], 1002 const uint8_t local_key[WG_STATIC_KEY_LEN],
1003 const uint8_t remote_key[WG_STATIC_KEY_LEN]) 1003 const uint8_t remote_key[WG_STATIC_KEY_LEN])
1004{ 1004{
1005 uint8_t dhout[WG_DH_OUTPUT_LEN]; 1005 uint8_t dhout[WG_DH_OUTPUT_LEN];
1006 1006
1007 wg_algo_dh(dhout, local_key, remote_key); 1007 wg_algo_dh(dhout, local_key, remote_key);
1008 wg_algo_kdf(ckey, cipher_key, NULL, ckey, dhout, sizeof(dhout)); 1008 wg_algo_kdf(ckey, cipher_key, NULL, ckey, dhout, sizeof(dhout));
1009 1009
1010 WG_DUMP_HASH("dhout", dhout); 1010 WG_DUMP_HASH("dhout", dhout);
1011 WG_DUMP_HASH("ckey", ckey); 1011 WG_DUMP_HASH("ckey", ckey);
1012 if (cipher_key != NULL) 1012 if (cipher_key != NULL)
1013 WG_DUMP_HASH("cipher_key", cipher_key); 1013 WG_DUMP_HASH("cipher_key", cipher_key);
1014} 1014}
1015 1015
1016static void 1016static void
1017wg_algo_aead_enc(uint8_t out[], size_t expected_outsize, const uint8_t key[], 1017wg_algo_aead_enc(uint8_t out[], size_t expected_outsize, const uint8_t key[],
1018 const uint64_t counter, const uint8_t plain[], const size_t plainsize, 1018 const uint64_t counter, const uint8_t plain[], const size_t plainsize,
1019 const uint8_t auth[], size_t authlen) 1019 const uint8_t auth[], size_t authlen)
1020{ 1020{
1021 uint8_t nonce[(32 + 64) / 8] = {0}; 1021 uint8_t nonce[(32 + 64) / 8] = {0};
1022 long long unsigned int outsize; 1022 long long unsigned int outsize;
1023 int error __diagused; 1023 int error __diagused;
1024 1024
1025 memcpy(&nonce[4], &counter, sizeof(counter)); 1025 memcpy(&nonce[4], &counter, sizeof(counter));
1026 1026
1027 error = crypto_aead_chacha20poly1305_ietf_encrypt(out, &outsize, plain, 1027 error = crypto_aead_chacha20poly1305_ietf_encrypt(out, &outsize, plain,
1028 plainsize, auth, authlen, NULL, nonce, key); 1028 plainsize, auth, authlen, NULL, nonce, key);
1029 KASSERT(error == 0); 1029 KASSERT(error == 0);
1030 KASSERT(outsize == expected_outsize); 1030 KASSERT(outsize == expected_outsize);
1031} 1031}
1032 1032
1033static int 1033static int
1034wg_algo_aead_dec(uint8_t out[], size_t expected_outsize, const uint8_t key[], 1034wg_algo_aead_dec(uint8_t out[], size_t expected_outsize, const uint8_t key[],
1035 const uint64_t counter, const uint8_t encrypted[], 1035 const uint64_t counter, const uint8_t encrypted[],
1036 const size_t encryptedsize, const uint8_t auth[], size_t authlen) 1036 const size_t encryptedsize, const uint8_t auth[], size_t authlen)
1037{ 1037{
1038 uint8_t nonce[(32 + 64) / 8] = {0}; 1038 uint8_t nonce[(32 + 64) / 8] = {0};
1039 long long unsigned int outsize; 1039 long long unsigned int outsize;
1040 int error; 1040 int error;
1041 1041
1042 memcpy(&nonce[4], &counter, sizeof(counter)); 1042 memcpy(&nonce[4], &counter, sizeof(counter));
1043 1043
@@ -1938,2025 +1938,2032 @@ wg_fill_msg_cookie(struct wg_softc *wg,  @@ -1938,2025 +1938,2032 @@ wg_fill_msg_cookie(struct wg_softc *wg,
1938 * random value" 1938 * random value"
1939 */ 1939 */
1940 if ((time_uptime - wgp->wgp_last_genrandval_time) > WG_RANDVAL_TIME) { 1940 if ((time_uptime - wgp->wgp_last_genrandval_time) > WG_RANDVAL_TIME) {
1941 wgp->wgp_randval = cprng_strong32(); 1941 wgp->wgp_randval = cprng_strong32();
1942 wgp->wgp_last_genrandval_time = time_uptime; 1942 wgp->wgp_last_genrandval_time = time_uptime;
1943 } 1943 }
1944 1944
1945 switch (src->sa_family) { 1945 switch (src->sa_family) {
1946 case AF_INET: { 1946 case AF_INET: {
1947 const struct sockaddr_in *sin = satocsin(src); 1947 const struct sockaddr_in *sin = satocsin(src);
1948 addrlen = sizeof(sin->sin_addr); 1948 addrlen = sizeof(sin->sin_addr);
1949 memcpy(addr, &sin->sin_addr, addrlen); 1949 memcpy(addr, &sin->sin_addr, addrlen);
1950 uh_sport = sin->sin_port; 1950 uh_sport = sin->sin_port;
1951 break; 1951 break;
1952 } 1952 }
1953#ifdef INET6 1953#ifdef INET6
1954 case AF_INET6: { 1954 case AF_INET6: {
1955 const struct sockaddr_in6 *sin6 = satocsin6(src); 1955 const struct sockaddr_in6 *sin6 = satocsin6(src);
1956 addrlen = sizeof(sin6->sin6_addr); 1956 addrlen = sizeof(sin6->sin6_addr);
1957 memcpy(addr, &sin6->sin6_addr, addrlen); 1957 memcpy(addr, &sin6->sin6_addr, addrlen);
1958 uh_sport = sin6->sin6_port; 1958 uh_sport = sin6->sin6_port;
1959 break; 1959 break;
1960 } 1960 }
1961#endif 1961#endif
1962 default: 1962 default:
1963 panic("invalid af=%d", wgp->wgp_sa.sa_family); 1963 panic("invalid af=%d", wgp->wgp_sa.sa_family);
1964 } 1964 }
1965 1965
1966 wg_algo_mac(cookie, sizeof(cookie), 1966 wg_algo_mac(cookie, sizeof(cookie),
1967 (const uint8_t *)&wgp->wgp_randval, sizeof(wgp->wgp_randval), 1967 (const uint8_t *)&wgp->wgp_randval, sizeof(wgp->wgp_randval),
1968 addr, addrlen, (const uint8_t *)&uh_sport, sizeof(uh_sport)); 1968 addr, addrlen, (const uint8_t *)&uh_sport, sizeof(uh_sport));
1969 wg_algo_mac_cookie(key, sizeof(key), wg->wg_pubkey, 1969 wg_algo_mac_cookie(key, sizeof(key), wg->wg_pubkey,
1970 sizeof(wg->wg_pubkey)); 1970 sizeof(wg->wg_pubkey));
1971 wg_algo_xaead_enc(wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie), key, 1971 wg_algo_xaead_enc(wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie), key,
1972 cookie, sizeof(cookie), mac1, WG_MAC_LEN, wgmc->wgmc_salt); 1972 cookie, sizeof(cookie), mac1, WG_MAC_LEN, wgmc->wgmc_salt);
1973 1973
1974 /* Need to store to calculate mac2 */ 1974 /* Need to store to calculate mac2 */
1975 memcpy(wgp->wgp_last_sent_cookie, cookie, sizeof(cookie)); 1975 memcpy(wgp->wgp_last_sent_cookie, cookie, sizeof(cookie));
1976 wgp->wgp_last_sent_cookie_valid = true; 1976 wgp->wgp_last_sent_cookie_valid = true;
1977} 1977}
1978 1978
1979static int 1979static int
1980wg_send_cookie_msg(struct wg_softc *wg, struct wg_peer *wgp, 1980wg_send_cookie_msg(struct wg_softc *wg, struct wg_peer *wgp,
1981 const uint32_t sender, const uint8_t mac1[WG_MAC_LEN], 1981 const uint32_t sender, const uint8_t mac1[WG_MAC_LEN],
1982 const struct sockaddr *src) 1982 const struct sockaddr *src)
1983{ 1983{
1984 int error; 1984 int error;
1985 struct mbuf *m; 1985 struct mbuf *m;
1986 struct wg_msg_cookie *wgmc; 1986 struct wg_msg_cookie *wgmc;
1987 1987
1988 m = m_gethdr(M_WAIT, MT_DATA); 1988 m = m_gethdr(M_WAIT, MT_DATA);
1989 m->m_pkthdr.len = m->m_len = sizeof(*wgmc); 1989 m->m_pkthdr.len = m->m_len = sizeof(*wgmc);
1990 wgmc = mtod(m, struct wg_msg_cookie *); 1990 wgmc = mtod(m, struct wg_msg_cookie *);
1991 wg_fill_msg_cookie(wg, wgp, wgmc, sender, mac1, src); 1991 wg_fill_msg_cookie(wg, wgp, wgmc, sender, mac1, src);
1992 1992
1993 error = wg->wg_ops->send_hs_msg(wgp, m); 1993 error = wg->wg_ops->send_hs_msg(wgp, m);
1994 if (error == 0) 1994 if (error == 0)
1995 WG_TRACE("cookie msg sent"); 1995 WG_TRACE("cookie msg sent");
1996 return error; 1996 return error;
1997} 1997}
1998 1998
1999static bool 1999static bool
2000wg_is_underload(struct wg_softc *wg, struct wg_peer *wgp, int msgtype) 2000wg_is_underload(struct wg_softc *wg, struct wg_peer *wgp, int msgtype)
2001{ 2001{
2002#ifdef WG_DEBUG_PARAMS 2002#ifdef WG_DEBUG_PARAMS
2003 if (wg_force_underload) 2003 if (wg_force_underload)
2004 return true; 2004 return true;
2005#endif 2005#endif
2006 2006
2007 /* 2007 /*
2008 * XXX we don't have a means of a load estimation. The purpose of 2008 * XXX we don't have a means of a load estimation. The purpose of
2009 * the mechanism is a DoS mitigation, so we consider frequent handshake 2009 * the mechanism is a DoS mitigation, so we consider frequent handshake
2010 * messages as (a kind of) load; if a message of the same type comes 2010 * messages as (a kind of) load; if a message of the same type comes
2011 * to a peer within 1 second, we consider we are under load. 2011 * to a peer within 1 second, we consider we are under load.
2012 */ 2012 */
2013 time_t last = wgp->wgp_last_msg_received_time[msgtype]; 2013 time_t last = wgp->wgp_last_msg_received_time[msgtype];
2014 wgp->wgp_last_msg_received_time[msgtype] = time_uptime; 2014 wgp->wgp_last_msg_received_time[msgtype] = time_uptime;
2015 return (time_uptime - last) == 0; 2015 return (time_uptime - last) == 0;
2016} 2016}
2017 2017
2018static void 2018static void
2019wg_calculate_keys(struct wg_session *wgs, const bool initiator) 2019wg_calculate_keys(struct wg_session *wgs, const bool initiator)
2020{ 2020{
2021 2021
2022 /* 2022 /*
2023 * [W] 5.4.5: Ti^send = Tr^recv, Ti^recv = Tr^send := KDF2(Ci = Cr, e) 2023 * [W] 5.4.5: Ti^send = Tr^recv, Ti^recv = Tr^send := KDF2(Ci = Cr, e)
2024 */ 2024 */
2025 if (initiator) { 2025 if (initiator) {
2026 wg_algo_kdf(wgs->wgs_tkey_send, wgs->wgs_tkey_recv, NULL, 2026 wg_algo_kdf(wgs->wgs_tkey_send, wgs->wgs_tkey_recv, NULL,
2027 wgs->wgs_chaining_key, NULL, 0); 2027 wgs->wgs_chaining_key, NULL, 0);
2028 } else { 2028 } else {
2029 wg_algo_kdf(wgs->wgs_tkey_recv, wgs->wgs_tkey_send, NULL, 2029 wg_algo_kdf(wgs->wgs_tkey_recv, wgs->wgs_tkey_send, NULL,
2030 wgs->wgs_chaining_key, NULL, 0); 2030 wgs->wgs_chaining_key, NULL, 0);
2031 } 2031 }
2032 WG_DUMP_HASH("wgs_tkey_send", wgs->wgs_tkey_send); 2032 WG_DUMP_HASH("wgs_tkey_send", wgs->wgs_tkey_send);
2033 WG_DUMP_HASH("wgs_tkey_recv", wgs->wgs_tkey_recv); 2033 WG_DUMP_HASH("wgs_tkey_recv", wgs->wgs_tkey_recv);
2034} 2034}
2035 2035
2036static uint64_t 2036static uint64_t
2037wg_session_get_send_counter(struct wg_session *wgs) 2037wg_session_get_send_counter(struct wg_session *wgs)
2038{ 2038{
2039#ifdef __HAVE_ATOMIC64_LOADSTORE 2039#ifdef __HAVE_ATOMIC64_LOADSTORE
2040 return atomic_load_relaxed(&wgs->wgs_send_counter); 2040 return atomic_load_relaxed(&wgs->wgs_send_counter);
2041#else 2041#else
2042 uint64_t send_counter; 2042 uint64_t send_counter;
2043 2043
2044 mutex_enter(&wgs->wgs_send_counter_lock); 2044 mutex_enter(&wgs->wgs_send_counter_lock);
2045 send_counter = wgs->wgs_send_counter; 2045 send_counter = wgs->wgs_send_counter;
2046 mutex_exit(&wgs->wgs_send_counter_lock); 2046 mutex_exit(&wgs->wgs_send_counter_lock);
2047 2047
2048 return send_counter; 2048 return send_counter;
2049#endif 2049#endif
2050} 2050}
2051 2051
2052static uint64_t 2052static uint64_t
2053wg_session_inc_send_counter(struct wg_session *wgs) 2053wg_session_inc_send_counter(struct wg_session *wgs)
2054{ 2054{
2055#ifdef __HAVE_ATOMIC64_LOADSTORE 2055#ifdef __HAVE_ATOMIC64_LOADSTORE
2056 return atomic_inc_64_nv(&wgs->wgs_send_counter) - 1; 2056 return atomic_inc_64_nv(&wgs->wgs_send_counter) - 1;
2057#else 2057#else
2058 uint64_t send_counter; 2058 uint64_t send_counter;
2059 2059
2060 mutex_enter(&wgs->wgs_send_counter_lock); 2060 mutex_enter(&wgs->wgs_send_counter_lock);
2061 send_counter = wgs->wgs_send_counter++; 2061 send_counter = wgs->wgs_send_counter++;
2062 mutex_exit(&wgs->wgs_send_counter_lock); 2062 mutex_exit(&wgs->wgs_send_counter_lock);
2063 2063
2064 return send_counter; 2064 return send_counter;
2065#endif 2065#endif
2066} 2066}
2067 2067
2068static void 2068static void
2069wg_clear_states(struct wg_session *wgs) 2069wg_clear_states(struct wg_session *wgs)
2070{ 2070{
2071 2071
2072 wgs->wgs_send_counter = 0; 2072 wgs->wgs_send_counter = 0;
2073 sliwin_reset(&wgs->wgs_recvwin->window); 2073 sliwin_reset(&wgs->wgs_recvwin->window);
2074 2074
2075#define wgs_clear(v) explicit_memset(wgs->wgs_##v, 0, sizeof(wgs->wgs_##v)) 2075#define wgs_clear(v) explicit_memset(wgs->wgs_##v, 0, sizeof(wgs->wgs_##v))
2076 wgs_clear(handshake_hash); 2076 wgs_clear(handshake_hash);
2077 wgs_clear(chaining_key); 2077 wgs_clear(chaining_key);
2078 wgs_clear(ephemeral_key_pub); 2078 wgs_clear(ephemeral_key_pub);
2079 wgs_clear(ephemeral_key_priv); 2079 wgs_clear(ephemeral_key_priv);
2080 wgs_clear(ephemeral_key_peer); 2080 wgs_clear(ephemeral_key_peer);
2081#undef wgs_clear 2081#undef wgs_clear
2082} 2082}
2083 2083
2084static struct wg_session * 2084static struct wg_session *
2085wg_lookup_session_by_index(struct wg_softc *wg, const uint32_t index, 2085wg_lookup_session_by_index(struct wg_softc *wg, const uint32_t index,
2086 struct psref *psref) 2086 struct psref *psref)
2087{ 2087{
2088 struct wg_peer *wgp; 2088 struct wg_peer *wgp;
2089 struct wg_session *wgs; 2089 struct wg_session *wgs;
2090 2090
2091 int s = pserialize_read_enter(); 2091 int s = pserialize_read_enter();
2092 /* XXX O(n) */ 2092 /* XXX O(n) */
2093 WG_PEER_READER_FOREACH(wgp, wg) { 2093 WG_PEER_READER_FOREACH(wgp, wg) {
2094 wgs = wgp->wgp_session_stable; 2094 wgs = wgp->wgp_session_stable;
2095 WG_DLOG("index=%x wgs_sender_index=%x\n", 2095 WG_DLOG("index=%x wgs_sender_index=%x\n",
2096 index, wgs->wgs_sender_index); 2096 index, wgs->wgs_sender_index);
2097 if (wgs->wgs_sender_index == index) 2097 if (wgs->wgs_sender_index == index)
2098 break; 2098 break;
2099 wgs = wgp->wgp_session_unstable; 2099 wgs = wgp->wgp_session_unstable;
2100 WG_DLOG("index=%x wgs_sender_index=%x\n", 2100 WG_DLOG("index=%x wgs_sender_index=%x\n",
2101 index, wgs->wgs_sender_index); 2101 index, wgs->wgs_sender_index);
2102 if (wgs->wgs_sender_index == index) 2102 if (wgs->wgs_sender_index == index)
2103 break; 2103 break;
2104 wgs = NULL; 2104 wgs = NULL;
2105 } 2105 }
2106 if (wgs != NULL) 2106 if (wgs != NULL)
2107 psref_acquire(psref, &wgs->wgs_psref, wg_psref_class); 2107 psref_acquire(psref, &wgs->wgs_psref, wg_psref_class);
2108 pserialize_read_exit(s); 2108 pserialize_read_exit(s);
2109 2109
2110 return wgs; 2110 return wgs;
2111} 2111}
2112 2112
2113static void 2113static void
2114wg_schedule_rekey_timer(struct wg_peer *wgp) 2114wg_schedule_rekey_timer(struct wg_peer *wgp)
2115{ 2115{
2116 int timeout = MIN(wg_rekey_after_time, INT_MAX/hz); 2116 int timeout = MIN(wg_rekey_after_time, INT_MAX/hz);
2117 2117
2118 callout_schedule(&wgp->wgp_rekey_timer, timeout * hz); 2118 callout_schedule(&wgp->wgp_rekey_timer, timeout * hz);
2119} 2119}
2120 2120
2121static void 2121static void
2122wg_send_keepalive_msg(struct wg_peer *wgp, struct wg_session *wgs) 2122wg_send_keepalive_msg(struct wg_peer *wgp, struct wg_session *wgs)
2123{ 2123{
2124 struct mbuf *m; 2124 struct mbuf *m;
2125 2125
2126 /* 2126 /*
2127 * [W] 6.5 Passive Keepalive 2127 * [W] 6.5 Passive Keepalive
2128 * "A keepalive message is simply a transport data message with 2128 * "A keepalive message is simply a transport data message with
2129 * a zero-length encapsulated encrypted inner-packet." 2129 * a zero-length encapsulated encrypted inner-packet."
2130 */ 2130 */
2131 m = m_gethdr(M_WAIT, MT_DATA); 2131 m = m_gethdr(M_WAIT, MT_DATA);
2132 wg_send_data_msg(wgp, wgs, m); 2132 wg_send_data_msg(wgp, wgs, m);
2133} 2133}
2134 2134
2135static bool 2135static bool
2136wg_need_to_send_init_message(struct wg_session *wgs) 2136wg_need_to_send_init_message(struct wg_session *wgs)
2137{ 2137{
2138 /* 2138 /*
2139 * [W] 6.2 Transport Message Limits 2139 * [W] 6.2 Transport Message Limits
2140 * "if a peer is the initiator of a current secure session, 2140 * "if a peer is the initiator of a current secure session,
2141 * WireGuard will send a handshake initiation message to begin 2141 * WireGuard will send a handshake initiation message to begin
2142 * a new secure session ... if after receiving a transport data 2142 * a new secure session ... if after receiving a transport data
2143 * message, the current secure session is (REJECT-AFTER-TIME − 2143 * message, the current secure session is (REJECT-AFTER-TIME −
2144 * KEEPALIVE-TIMEOUT − REKEY-TIMEOUT) seconds old and it has 2144 * KEEPALIVE-TIMEOUT − REKEY-TIMEOUT) seconds old and it has
2145 * not yet acted upon this event." 2145 * not yet acted upon this event."
2146 */ 2146 */
2147 return wgs->wgs_is_initiator && wgs->wgs_time_last_data_sent == 0 && 2147 return wgs->wgs_is_initiator && wgs->wgs_time_last_data_sent == 0 &&
2148 (time_uptime - wgs->wgs_time_established) >= 2148 (time_uptime - wgs->wgs_time_established) >=
2149 (wg_reject_after_time - wg_keepalive_timeout - wg_rekey_timeout); 2149 (wg_reject_after_time - wg_keepalive_timeout - wg_rekey_timeout);
2150} 2150}
2151 2151
2152static void 2152static void
2153wg_schedule_peer_task(struct wg_peer *wgp, int task) 2153wg_schedule_peer_task(struct wg_peer *wgp, int task)
2154{ 2154{
2155 2155
2156 atomic_or_uint(&wgp->wgp_tasks, task); 2156 atomic_or_uint(&wgp->wgp_tasks, task);
2157 WG_DLOG("tasks=%d, task=%d\n", wgp->wgp_tasks, task); 2157 WG_DLOG("tasks=%d, task=%d\n", wgp->wgp_tasks, task);
2158 wg_wakeup_worker(wgp->wgp_sc->wg_worker, WG_WAKEUP_REASON_PEER); 2158 wg_wakeup_worker(wgp->wgp_sc->wg_worker, WG_WAKEUP_REASON_PEER);
2159} 2159}
2160 2160
2161static void 2161static void
2162wg_change_endpoint(struct wg_peer *wgp, const struct sockaddr *new) 2162wg_change_endpoint(struct wg_peer *wgp, const struct sockaddr *new)
2163{ 2163{
2164 2164
2165 KASSERT(mutex_owned(wgp->wgp_lock)); 2165 KASSERT(mutex_owned(wgp->wgp_lock));
2166 2166
2167 WG_TRACE("Changing endpoint"); 2167 WG_TRACE("Changing endpoint");
2168 2168
2169 memcpy(wgp->wgp_endpoint0, new, new->sa_len); 2169 memcpy(wgp->wgp_endpoint0, new, new->sa_len);
2170 wgp->wgp_endpoint0 = atomic_swap_ptr(&wgp->wgp_endpoint, 2170 wgp->wgp_endpoint0 = atomic_swap_ptr(&wgp->wgp_endpoint,
2171 wgp->wgp_endpoint0); 2171 wgp->wgp_endpoint0);
2172 if (!wgp->wgp_endpoint_available) 2172 if (!wgp->wgp_endpoint_available)
2173 wgp->wgp_endpoint_available = true; 2173 wgp->wgp_endpoint_available = true;
2174 wgp->wgp_endpoint_changing = true; 2174 wgp->wgp_endpoint_changing = true;
2175 wg_schedule_peer_task(wgp, WGP_TASK_ENDPOINT_CHANGED); 2175 wg_schedule_peer_task(wgp, WGP_TASK_ENDPOINT_CHANGED);
2176} 2176}
2177 2177
2178static bool 2178static bool
2179wg_validate_inner_packet(const char *packet, size_t decrypted_len, int *af) 2179wg_validate_inner_packet(const char *packet, size_t decrypted_len, int *af)
2180{ 2180{
2181 uint16_t packet_len; 2181 uint16_t packet_len;
2182 const struct ip *ip; 2182 const struct ip *ip;
2183 2183
2184 if (__predict_false(decrypted_len < sizeof(struct ip))) 2184 if (__predict_false(decrypted_len < sizeof(struct ip)))
2185 return false; 2185 return false;
2186 2186
2187 ip = (const struct ip *)packet; 2187 ip = (const struct ip *)packet;
2188 if (ip->ip_v == 4) 2188 if (ip->ip_v == 4)
2189 *af = AF_INET; 2189 *af = AF_INET;
2190 else if (ip->ip_v == 6) 2190 else if (ip->ip_v == 6)
2191 *af = AF_INET6; 2191 *af = AF_INET6;
2192 else 2192 else
2193 return false; 2193 return false;
2194 2194
2195 WG_DLOG("af=%d\n", *af); 2195 WG_DLOG("af=%d\n", *af);
2196 2196
2197 if (*af == AF_INET) { 2197 if (*af == AF_INET) {
2198 packet_len = ntohs(ip->ip_len); 2198 packet_len = ntohs(ip->ip_len);
2199 } else { 2199 } else {
2200 const struct ip6_hdr *ip6; 2200 const struct ip6_hdr *ip6;
2201 2201
2202 if (__predict_false(decrypted_len < sizeof(struct ip6_hdr))) 2202 if (__predict_false(decrypted_len < sizeof(struct ip6_hdr)))
2203 return false; 2203 return false;
2204 2204
2205 ip6 = (const struct ip6_hdr *)packet; 2205 ip6 = (const struct ip6_hdr *)packet;
2206 packet_len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen); 2206 packet_len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen);
2207 } 2207 }
2208 2208
2209 WG_DLOG("packet_len=%u\n", packet_len); 2209 WG_DLOG("packet_len=%u\n", packet_len);
2210 if (packet_len > decrypted_len) 2210 if (packet_len > decrypted_len)
2211 return false; 2211 return false;
2212 2212
2213 return true; 2213 return true;
2214} 2214}
2215 2215
2216static bool 2216static bool
2217wg_validate_route(struct wg_softc *wg, struct wg_peer *wgp_expected, 2217wg_validate_route(struct wg_softc *wg, struct wg_peer *wgp_expected,
2218 int af, char *packet) 2218 int af, char *packet)
2219{ 2219{
2220 struct sockaddr_storage ss; 2220 struct sockaddr_storage ss;
2221 struct sockaddr *sa; 2221 struct sockaddr *sa;
2222 struct psref psref; 2222 struct psref psref;
2223 struct wg_peer *wgp; 2223 struct wg_peer *wgp;
2224 bool ok; 2224 bool ok;
2225 2225
2226 /* 2226 /*
2227 * II CRYPTOKEY ROUTING 2227 * II CRYPTOKEY ROUTING
2228 * "it will only accept it if its source IP resolves in the 2228 * "it will only accept it if its source IP resolves in the
2229 * table to the public key used in the secure session for 2229 * table to the public key used in the secure session for
2230 * decrypting it." 2230 * decrypting it."
2231 */ 2231 */
2232 2232
2233 if (af == AF_INET) { 2233 if (af == AF_INET) {
2234 const struct ip *ip = (const struct ip *)packet; 2234 const struct ip *ip = (const struct ip *)packet;
2235 struct sockaddr_in *sin = (struct sockaddr_in *)&ss; 2235 struct sockaddr_in *sin = (struct sockaddr_in *)&ss;
2236 sockaddr_in_init(sin, &ip->ip_src, 0); 2236 sockaddr_in_init(sin, &ip->ip_src, 0);
2237 sa = sintosa(sin); 2237 sa = sintosa(sin);
2238#ifdef INET6 2238#ifdef INET6
2239 } else { 2239 } else {
2240 const struct ip6_hdr *ip6 = (const struct ip6_hdr *)packet; 2240 const struct ip6_hdr *ip6 = (const struct ip6_hdr *)packet;
2241 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss; 2241 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss;
2242 sockaddr_in6_init(sin6, &ip6->ip6_src, 0, 0, 0); 2242 sockaddr_in6_init(sin6, &ip6->ip6_src, 0, 0, 0);
2243 sa = sin6tosa(sin6); 2243 sa = sin6tosa(sin6);
2244#endif 2244#endif
2245 } 2245 }
2246 2246
2247 wgp = wg_pick_peer_by_sa(wg, sa, &psref); 2247 wgp = wg_pick_peer_by_sa(wg, sa, &psref);
2248 ok = (wgp == wgp_expected); 2248 ok = (wgp == wgp_expected);
2249 if (wgp != NULL) 2249 if (wgp != NULL)
2250 wg_put_peer(wgp, &psref); 2250 wg_put_peer(wgp, &psref);
2251 2251
2252 return ok; 2252 return ok;
2253} 2253}
2254 2254
2255static void 2255static void
2256wg_session_dtor_timer(void *arg) 2256wg_session_dtor_timer(void *arg)
2257{ 2257{
2258 struct wg_peer *wgp = arg; 2258 struct wg_peer *wgp = arg;
2259 2259
2260 WG_TRACE("enter"); 2260 WG_TRACE("enter");
2261 2261
2262 mutex_enter(wgp->wgp_lock); 2262 mutex_enter(wgp->wgp_lock);
2263 if (__predict_false(wgp->wgp_state == WGP_STATE_DESTROYING)) { 2263 if (__predict_false(wgp->wgp_state == WGP_STATE_DESTROYING)) {
2264 mutex_exit(wgp->wgp_lock); 2264 mutex_exit(wgp->wgp_lock);
2265 return; 2265 return;
2266 } 2266 }
2267 mutex_exit(wgp->wgp_lock); 2267 mutex_exit(wgp->wgp_lock);
2268 2268
2269 wg_schedule_peer_task(wgp, WGP_TASK_DESTROY_PREV_SESSION); 2269 wg_schedule_peer_task(wgp, WGP_TASK_DESTROY_PREV_SESSION);
2270} 2270}
2271 2271
2272static void 2272static void
2273wg_schedule_session_dtor_timer(struct wg_peer *wgp) 2273wg_schedule_session_dtor_timer(struct wg_peer *wgp)
2274{ 2274{
2275 2275
2276 /* 1 second grace period */ 2276 /* 1 second grace period */
2277 callout_schedule(&wgp->wgp_session_dtor_timer, hz); 2277 callout_schedule(&wgp->wgp_session_dtor_timer, hz);
2278} 2278}
2279 2279
2280static void 2280static void
2281wg_stop_session_dtor_timer(struct wg_peer *wgp) 2281wg_stop_session_dtor_timer(struct wg_peer *wgp)
2282{ 2282{
2283 2283
2284 callout_halt(&wgp->wgp_session_dtor_timer, NULL); 2284 callout_halt(&wgp->wgp_session_dtor_timer, NULL);
2285} 2285}
2286 2286
2287static bool 2287static bool
2288sockaddr_port_match(const struct sockaddr *sa1, const struct sockaddr *sa2) 2288sockaddr_port_match(const struct sockaddr *sa1, const struct sockaddr *sa2)
2289{ 2289{
2290 if (sa1->sa_family != sa2->sa_family) 2290 if (sa1->sa_family != sa2->sa_family)
2291 return false; 2291 return false;
2292 2292
2293 switch (sa1->sa_family) { 2293 switch (sa1->sa_family) {
2294 case AF_INET: 2294 case AF_INET:
2295 return satocsin(sa1)->sin_port == satocsin(sa2)->sin_port; 2295 return satocsin(sa1)->sin_port == satocsin(sa2)->sin_port;
2296 case AF_INET6: 2296 case AF_INET6:
2297 return satocsin6(sa1)->sin6_port == satocsin6(sa2)->sin6_port; 2297 return satocsin6(sa1)->sin6_port == satocsin6(sa2)->sin6_port;
2298 default: 2298 default:
2299 return true; 2299 return true;
2300 } 2300 }
2301} 2301}
2302 2302
2303static void 2303static void
2304wg_update_endpoint_if_necessary(struct wg_peer *wgp, 2304wg_update_endpoint_if_necessary(struct wg_peer *wgp,
2305 const struct sockaddr *src) 2305 const struct sockaddr *src)
2306{ 2306{
2307 2307
2308#ifdef WG_DEBUG_LOG 2308#ifdef WG_DEBUG_LOG
2309 char oldaddr[128], newaddr[128]; 2309 char oldaddr[128], newaddr[128];
2310 sockaddr_format(&wgp->wgp_sa, oldaddr, sizeof(oldaddr)); 2310 sockaddr_format(&wgp->wgp_sa, oldaddr, sizeof(oldaddr));
2311 sockaddr_format(src, newaddr, sizeof(newaddr)); 2311 sockaddr_format(src, newaddr, sizeof(newaddr));
2312 WG_DLOG("old=%s, new=%s\n", oldaddr, newaddr); 2312 WG_DLOG("old=%s, new=%s\n", oldaddr, newaddr);
2313#endif 2313#endif
2314 2314
2315 /* 2315 /*
2316 * III: "Since the packet has authenticated correctly, the source IP of 2316 * III: "Since the packet has authenticated correctly, the source IP of
2317 * the outer UDP/IP packet is used to update the endpoint for peer..." 2317 * the outer UDP/IP packet is used to update the endpoint for peer..."
2318 */ 2318 */
2319 if (__predict_false(sockaddr_cmp(src, &wgp->wgp_sa) != 0 || 2319 if (__predict_false(sockaddr_cmp(src, &wgp->wgp_sa) != 0 ||
2320 !sockaddr_port_match(src, &wgp->wgp_sa))) { 2320 !sockaddr_port_match(src, &wgp->wgp_sa))) {
2321 mutex_enter(wgp->wgp_lock); 2321 mutex_enter(wgp->wgp_lock);
2322 /* XXX We can't change the endpoint twice in a short period */ 2322 /* XXX We can't change the endpoint twice in a short period */
2323 if (!wgp->wgp_endpoint_changing) { 2323 if (!wgp->wgp_endpoint_changing) {
2324 wg_change_endpoint(wgp, src); 2324 wg_change_endpoint(wgp, src);
2325 } 2325 }
2326 mutex_exit(wgp->wgp_lock); 2326 mutex_exit(wgp->wgp_lock);
2327 } 2327 }
2328} 2328}
2329 2329
2330static void 2330static void
2331wg_handle_msg_data(struct wg_softc *wg, struct mbuf *m, 2331wg_handle_msg_data(struct wg_softc *wg, struct mbuf *m,
2332 const struct sockaddr *src) 2332 const struct sockaddr *src)
2333{ 2333{
2334 struct wg_msg_data *wgmd; 2334 struct wg_msg_data *wgmd;
2335 char *encrypted_buf = NULL, *decrypted_buf; 2335 char *encrypted_buf = NULL, *decrypted_buf;
2336 size_t encrypted_len, decrypted_len; 2336 size_t encrypted_len, decrypted_len;
2337 struct wg_session *wgs; 2337 struct wg_session *wgs;
2338 struct wg_peer *wgp; 2338 struct wg_peer *wgp;
2339 size_t mlen; 2339 size_t mlen;
2340 struct psref psref; 2340 struct psref psref;
2341 int error, af; 2341 int error, af;
2342 bool success, free_encrypted_buf = false, ok; 2342 bool success, free_encrypted_buf = false, ok;
2343 struct mbuf *n; 2343 struct mbuf *n;
2344 2344
2345 KASSERT(m->m_len >= sizeof(struct wg_msg_data)); 2345 KASSERT(m->m_len >= sizeof(struct wg_msg_data));
2346 wgmd = mtod(m, struct wg_msg_data *); 2346 wgmd = mtod(m, struct wg_msg_data *);
2347 2347
2348 KASSERT(wgmd->wgmd_type == WG_MSG_TYPE_DATA); 2348 KASSERT(wgmd->wgmd_type == WG_MSG_TYPE_DATA);
2349 WG_TRACE("data"); 2349 WG_TRACE("data");
2350 2350
2351 wgs = wg_lookup_session_by_index(wg, wgmd->wgmd_receiver, &psref); 2351 wgs = wg_lookup_session_by_index(wg, wgmd->wgmd_receiver, &psref);
2352 if (wgs == NULL) { 2352 if (wgs == NULL) {
2353 WG_TRACE("No session found"); 2353 WG_TRACE("No session found");
2354 m_freem(m); 2354 m_freem(m);
2355 return; 2355 return;
2356 } 2356 }
2357 wgp = wgs->wgs_peer; 2357 wgp = wgs->wgs_peer;
2358 2358
2359 error = sliwin_check_fast(&wgs->wgs_recvwin->window, 2359 error = sliwin_check_fast(&wgs->wgs_recvwin->window,
2360 wgmd->wgmd_counter); 2360 wgmd->wgmd_counter);
2361 if (error) { 2361 if (error) {
2362 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2362 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2363 "out-of-window packet: %"PRIu64"\n", 2363 "out-of-window packet: %"PRIu64"\n",
2364 wgmd->wgmd_counter); 2364 wgmd->wgmd_counter);
2365 goto out; 2365 goto out;
2366 } 2366 }
2367 2367
2368 mlen = m_length(m); 2368 mlen = m_length(m);
2369 encrypted_len = mlen - sizeof(*wgmd); 2369 encrypted_len = mlen - sizeof(*wgmd);
2370 2370
2371 if (encrypted_len < WG_AUTHTAG_LEN) { 2371 if (encrypted_len < WG_AUTHTAG_LEN) {
2372 WG_DLOG("Short encrypted_len: %lu\n", encrypted_len); 2372 WG_DLOG("Short encrypted_len: %lu\n", encrypted_len);
2373 goto out; 2373 goto out;
2374 } 2374 }
2375 2375
2376 success = m_ensure_contig(&m, sizeof(*wgmd) + encrypted_len); 2376 success = m_ensure_contig(&m, sizeof(*wgmd) + encrypted_len);
2377 if (success) { 2377 if (success) {
2378 encrypted_buf = mtod(m, char *) + sizeof(*wgmd); 2378 encrypted_buf = mtod(m, char *) + sizeof(*wgmd);
2379 } else { 2379 } else {
2380 encrypted_buf = kmem_intr_alloc(encrypted_len, KM_NOSLEEP); 2380 encrypted_buf = kmem_intr_alloc(encrypted_len, KM_NOSLEEP);
2381 if (encrypted_buf == NULL) { 2381 if (encrypted_buf == NULL) {
2382 WG_DLOG("failed to allocate encrypted_buf\n"); 2382 WG_DLOG("failed to allocate encrypted_buf\n");
2383 goto out; 2383 goto out;
2384 } 2384 }
2385 m_copydata(m, sizeof(*wgmd), encrypted_len, encrypted_buf); 2385 m_copydata(m, sizeof(*wgmd), encrypted_len, encrypted_buf);
2386 free_encrypted_buf = true; 2386 free_encrypted_buf = true;
2387 } 2387 }
2388 /* m_ensure_contig may change m regardless of its result */ 2388 /* m_ensure_contig may change m regardless of its result */
2389 KASSERT(m->m_len >= sizeof(*wgmd)); 2389 KASSERT(m->m_len >= sizeof(*wgmd));
2390 wgmd = mtod(m, struct wg_msg_data *); 2390 wgmd = mtod(m, struct wg_msg_data *);
2391 2391
2392 decrypted_len = encrypted_len - WG_AUTHTAG_LEN; 2392 decrypted_len = encrypted_len - WG_AUTHTAG_LEN;
2393 if (decrypted_len > MCLBYTES) { 2393 if (decrypted_len > MCLBYTES) {
2394 /* FIXME handle larger data than MCLBYTES */ 2394 /* FIXME handle larger data than MCLBYTES */
2395 WG_DLOG("couldn't handle larger data than MCLBYTES\n"); 2395 WG_DLOG("couldn't handle larger data than MCLBYTES\n");
2396 goto out; 2396 goto out;
2397 } 2397 }
2398 2398
2399 /* To avoid zero length */ 2399 /* To avoid zero length */
2400 n = wg_get_mbuf(0, decrypted_len + WG_AUTHTAG_LEN); 2400 n = wg_get_mbuf(0, decrypted_len + WG_AUTHTAG_LEN);
2401 if (n == NULL) { 2401 if (n == NULL) {
2402 WG_DLOG("wg_get_mbuf failed\n"); 2402 WG_DLOG("wg_get_mbuf failed\n");
2403 goto out; 2403 goto out;
2404 } 2404 }
2405 decrypted_buf = mtod(n, char *); 2405 decrypted_buf = mtod(n, char *);
2406 2406
2407 WG_DLOG("mlen=%lu, encrypted_len=%lu\n", mlen, encrypted_len); 2407 WG_DLOG("mlen=%lu, encrypted_len=%lu\n", mlen, encrypted_len);
2408 error = wg_algo_aead_dec(decrypted_buf, 2408 error = wg_algo_aead_dec(decrypted_buf,
2409 encrypted_len - WG_AUTHTAG_LEN /* can be 0 */, 2409 encrypted_len - WG_AUTHTAG_LEN /* can be 0 */,
2410 wgs->wgs_tkey_recv, wgmd->wgmd_counter, encrypted_buf, 2410 wgs->wgs_tkey_recv, wgmd->wgmd_counter, encrypted_buf,
2411 encrypted_len, NULL, 0); 2411 encrypted_len, NULL, 0);
2412 if (error != 0) { 2412 if (error != 0) {
2413 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2413 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2414 "failed to wg_algo_aead_dec\n"); 2414 "failed to wg_algo_aead_dec\n");
2415 m_freem(n); 2415 m_freem(n);
2416 goto out; 2416 goto out;
2417 } 2417 }
2418 WG_DLOG("outsize=%u\n", (u_int)decrypted_len); 2418 WG_DLOG("outsize=%u\n", (u_int)decrypted_len);
2419 2419
2420 mutex_enter(&wgs->wgs_recvwin->lock); 2420 mutex_enter(&wgs->wgs_recvwin->lock);
2421 error = sliwin_update(&wgs->wgs_recvwin->window, 2421 error = sliwin_update(&wgs->wgs_recvwin->window,
2422 wgmd->wgmd_counter); 2422 wgmd->wgmd_counter);
2423 mutex_exit(&wgs->wgs_recvwin->lock); 2423 mutex_exit(&wgs->wgs_recvwin->lock);
2424 if (error) { 2424 if (error) {
2425 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2425 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2426 "replay or out-of-window packet: %"PRIu64"\n", 2426 "replay or out-of-window packet: %"PRIu64"\n",
2427 wgmd->wgmd_counter); 2427 wgmd->wgmd_counter);
2428 m_freem(n); 2428 m_freem(n);
2429 goto out; 2429 goto out;
2430 } 2430 }
2431 2431
2432 m_freem(m); 2432 m_freem(m);
2433 m = NULL; 2433 m = NULL;
2434 wgmd = NULL; 2434 wgmd = NULL;
2435 2435
2436 ok = wg_validate_inner_packet(decrypted_buf, decrypted_len, &af); 2436 ok = wg_validate_inner_packet(decrypted_buf, decrypted_len, &af);
2437 if (!ok) { 2437 if (!ok) {
2438 /* something wrong... */ 2438 /* something wrong... */
2439 m_freem(n); 2439 m_freem(n);
2440 goto out; 2440 goto out;
2441 } 2441 }
2442 2442
2443 wg_update_endpoint_if_necessary(wgp, src); 2443 wg_update_endpoint_if_necessary(wgp, src);
2444 2444
2445 ok = wg_validate_route(wg, wgp, af, decrypted_buf); 2445 ok = wg_validate_route(wg, wgp, af, decrypted_buf);
2446 if (ok) { 2446 if (ok) {
2447 wg->wg_ops->input(&wg->wg_if, n, af); 2447 wg->wg_ops->input(&wg->wg_if, n, af);
2448 } else { 2448 } else {
2449 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2449 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2450 "invalid source address\n"); 2450 "invalid source address\n");
2451 m_freem(n); 2451 m_freem(n);
2452 /* 2452 /*
2453 * The inner address is invalid however the session is valid 2453 * The inner address is invalid however the session is valid
2454 * so continue the session processing below. 2454 * so continue the session processing below.
2455 */ 2455 */
2456 } 2456 }
2457 n = NULL; 2457 n = NULL;
2458 2458
2459 if (wgs->wgs_state == WGS_STATE_INIT_PASSIVE) { 2459 if (wgs->wgs_state == WGS_STATE_INIT_PASSIVE) {
2460 struct wg_session *wgs_prev; 2460 struct wg_session *wgs_prev;
2461 2461
2462 KASSERT(wgs == wgp->wgp_session_unstable); 2462 KASSERT(wgs == wgp->wgp_session_unstable);
2463 wgs->wgs_state = WGS_STATE_ESTABLISHED; 2463 wgs->wgs_state = WGS_STATE_ESTABLISHED;
2464 wgs->wgs_time_established = time_uptime; 2464 wgs->wgs_time_established = time_uptime;
2465 wgs->wgs_time_last_data_sent = 0; 2465 wgs->wgs_time_last_data_sent = 0;
2466 wgs->wgs_is_initiator = false; 2466 wgs->wgs_is_initiator = false;
2467 WG_TRACE("WGS_STATE_ESTABLISHED"); 2467 WG_TRACE("WGS_STATE_ESTABLISHED");
2468 2468
2469 mutex_enter(wgp->wgp_lock); 2469 mutex_enter(wgp->wgp_lock);
2470 wg_swap_sessions(wgp); 2470 wg_swap_sessions(wgp);
2471 wgs_prev = wgp->wgp_session_unstable; 2471 wgs_prev = wgp->wgp_session_unstable;
2472 mutex_enter(wgs_prev->wgs_lock); 2472 mutex_enter(wgs_prev->wgs_lock);
2473 getnanotime(&wgp->wgp_last_handshake_time); 2473 getnanotime(&wgp->wgp_last_handshake_time);
2474 wgp->wgp_handshake_start_time = 0; 2474 wgp->wgp_handshake_start_time = 0;
2475 wgp->wgp_last_sent_mac1_valid = false; 2475 wgp->wgp_last_sent_mac1_valid = false;
2476 wgp->wgp_last_sent_cookie_valid = false; 2476 wgp->wgp_last_sent_cookie_valid = false;
2477 mutex_exit(wgp->wgp_lock); 2477 mutex_exit(wgp->wgp_lock);
2478 2478
2479 if (wgs_prev->wgs_state == WGS_STATE_ESTABLISHED) { 2479 if (wgs_prev->wgs_state == WGS_STATE_ESTABLISHED) {
2480 wgs_prev->wgs_state = WGS_STATE_DESTROYING; 2480 wgs_prev->wgs_state = WGS_STATE_DESTROYING;
2481 /* We can't destroy the old session immediately */ 2481 /* We can't destroy the old session immediately */
2482 wg_schedule_session_dtor_timer(wgp); 2482 wg_schedule_session_dtor_timer(wgp);
2483 } else { 2483 } else {
2484 wg_clear_states(wgs_prev); 2484 wg_clear_states(wgs_prev);
2485 wgs_prev->wgs_state = WGS_STATE_UNKNOWN; 2485 wgs_prev->wgs_state = WGS_STATE_UNKNOWN;
2486 } 2486 }
2487 mutex_exit(wgs_prev->wgs_lock); 2487 mutex_exit(wgs_prev->wgs_lock);
2488 2488
2489 /* Anyway run a softint to flush pending packets */ 2489 /* Anyway run a softint to flush pending packets */
2490 kpreempt_disable(); 2490 kpreempt_disable();
2491 softint_schedule(wgp->wgp_si); 2491 softint_schedule(wgp->wgp_si);
2492 kpreempt_enable(); 2492 kpreempt_enable();
2493 } else { 2493 } else {
2494 if (__predict_false(wg_need_to_send_init_message(wgs))) { 2494 if (__predict_false(wg_need_to_send_init_message(wgs))) {
2495 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 2495 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
2496 } 2496 }
2497 /* 2497 /*
2498 * [W] 6.5 Passive Keepalive 2498 * [W] 6.5 Passive Keepalive
2499 * "If a peer has received a validly-authenticated transport 2499 * "If a peer has received a validly-authenticated transport
2500 * data message (section 5.4.6), but does not have any packets 2500 * data message (section 5.4.6), but does not have any packets
2501 * itself to send back for KEEPALIVE-TIMEOUT seconds, it sends 2501 * itself to send back for KEEPALIVE-TIMEOUT seconds, it sends
2502 * a keepalive message." 2502 * a keepalive message."
2503 */ 2503 */
2504 WG_DLOG("time_uptime=%lu wgs_time_last_data_sent=%lu\n", 2504 WG_DLOG("time_uptime=%lu wgs_time_last_data_sent=%lu\n",
2505 time_uptime, wgs->wgs_time_last_data_sent); 2505 time_uptime, wgs->wgs_time_last_data_sent);
2506 if ((time_uptime - wgs->wgs_time_last_data_sent) >= 2506 if ((time_uptime - wgs->wgs_time_last_data_sent) >=
2507 wg_keepalive_timeout) { 2507 wg_keepalive_timeout) {
2508 WG_TRACE("Schedule sending keepalive message"); 2508 WG_TRACE("Schedule sending keepalive message");
2509 /* 2509 /*
2510 * We can't send a keepalive message here to avoid 2510 * We can't send a keepalive message here to avoid
2511 * a deadlock; we already hold the solock of a socket 2511 * a deadlock; we already hold the solock of a socket
2512 * that is used to send the message. 2512 * that is used to send the message.
2513 */ 2513 */
2514 wg_schedule_peer_task(wgp, 2514 wg_schedule_peer_task(wgp,
2515 WGP_TASK_SEND_KEEPALIVE_MESSAGE); 2515 WGP_TASK_SEND_KEEPALIVE_MESSAGE);
2516 } 2516 }
2517 } 2517 }
2518out: 2518out:
2519 wg_put_session(wgs, &psref); 2519 wg_put_session(wgs, &psref);
2520 if (m != NULL) 2520 if (m != NULL)
2521 m_freem(m); 2521 m_freem(m);
2522 if (free_encrypted_buf) 2522 if (free_encrypted_buf)
2523 kmem_intr_free(encrypted_buf, encrypted_len); 2523 kmem_intr_free(encrypted_buf, encrypted_len);
2524} 2524}
2525 2525
2526static void 2526static void
2527wg_handle_msg_cookie(struct wg_softc *wg, const struct wg_msg_cookie *wgmc) 2527wg_handle_msg_cookie(struct wg_softc *wg, const struct wg_msg_cookie *wgmc)
2528{ 2528{
2529 struct wg_session *wgs; 2529 struct wg_session *wgs;
2530 struct wg_peer *wgp; 2530 struct wg_peer *wgp;
2531 struct psref psref; 2531 struct psref psref;
2532 int error; 2532 int error;
2533 uint8_t key[WG_HASH_LEN]; 2533 uint8_t key[WG_HASH_LEN];
2534 uint8_t cookie[WG_COOKIE_LEN]; 2534 uint8_t cookie[WG_COOKIE_LEN];
2535 2535
2536 WG_TRACE("cookie msg received"); 2536 WG_TRACE("cookie msg received");
2537 wgs = wg_lookup_session_by_index(wg, wgmc->wgmc_receiver, &psref); 2537 wgs = wg_lookup_session_by_index(wg, wgmc->wgmc_receiver, &psref);
2538 if (wgs == NULL) { 2538 if (wgs == NULL) {
2539 WG_TRACE("No session found"); 2539 WG_TRACE("No session found");
2540 return; 2540 return;
2541 } 2541 }
2542 wgp = wgs->wgs_peer; 2542 wgp = wgs->wgs_peer;
2543 2543
2544 if (!wgp->wgp_last_sent_mac1_valid) { 2544 if (!wgp->wgp_last_sent_mac1_valid) {
2545 WG_TRACE("No valid mac1 sent (or expired)"); 2545 WG_TRACE("No valid mac1 sent (or expired)");
2546 goto out; 2546 goto out;
2547 } 2547 }
2548 2548
2549 wg_algo_mac_cookie(key, sizeof(key), wgp->wgp_pubkey, 2549 wg_algo_mac_cookie(key, sizeof(key), wgp->wgp_pubkey,
2550 sizeof(wgp->wgp_pubkey)); 2550 sizeof(wgp->wgp_pubkey));
2551 error = wg_algo_xaead_dec(cookie, sizeof(cookie), key, 0, 2551 error = wg_algo_xaead_dec(cookie, sizeof(cookie), key, 0,
2552 wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie), 2552 wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie),
2553 wgp->wgp_last_sent_mac1, sizeof(wgp->wgp_last_sent_mac1), 2553 wgp->wgp_last_sent_mac1, sizeof(wgp->wgp_last_sent_mac1),
2554 wgmc->wgmc_salt); 2554 wgmc->wgmc_salt);
2555 if (error != 0) { 2555 if (error != 0) {
2556 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2556 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2557 "wg_algo_aead_dec for cookie failed: error=%d\n", error); 2557 "wg_algo_aead_dec for cookie failed: error=%d\n", error);
2558 goto out; 2558 goto out;
2559 } 2559 }
2560 /* 2560 /*
2561 * [W] 6.6: Interaction with Cookie Reply System 2561 * [W] 6.6: Interaction with Cookie Reply System
2562 * "it should simply store the decrypted cookie value from the cookie 2562 * "it should simply store the decrypted cookie value from the cookie
2563 * reply message, and wait for the expiration of the REKEY-TIMEOUT 2563 * reply message, and wait for the expiration of the REKEY-TIMEOUT
2564 * timer for retrying a handshake initiation message." 2564 * timer for retrying a handshake initiation message."
2565 */ 2565 */
2566 wgp->wgp_latest_cookie_time = time_uptime; 2566 wgp->wgp_latest_cookie_time = time_uptime;
2567 memcpy(wgp->wgp_latest_cookie, cookie, sizeof(wgp->wgp_latest_cookie)); 2567 memcpy(wgp->wgp_latest_cookie, cookie, sizeof(wgp->wgp_latest_cookie));
2568out: 2568out:
2569 wg_put_session(wgs, &psref); 2569 wg_put_session(wgs, &psref);
2570} 2570}
2571 2571
2572static struct mbuf * 2572static struct mbuf *
2573wg_validate_msg_header(struct wg_softc *wg, struct mbuf *m) 2573wg_validate_msg_header(struct wg_softc *wg, struct mbuf *m)
2574{ 2574{
2575 struct wg_msg wgm; 2575 struct wg_msg wgm;
2576 size_t mbuflen; 2576 size_t mbuflen;
2577 size_t msglen; 2577 size_t msglen;
2578 2578
2579 /* 2579 /*
2580 * Get the mbuf chain length. It is already guaranteed, by 2580 * Get the mbuf chain length. It is already guaranteed, by
2581 * wg_overudp_cb, to be large enough for a struct wg_msg. 2581 * wg_overudp_cb, to be large enough for a struct wg_msg.
2582 */ 2582 */
2583 mbuflen = m_length(m); 2583 mbuflen = m_length(m);
2584 KASSERT(mbuflen >= sizeof(struct wg_msg)); 2584 KASSERT(mbuflen >= sizeof(struct wg_msg));
2585 2585
2586 /* 2586 /*
2587 * Copy the message header (32-bit message type) out -- we'll 2587 * Copy the message header (32-bit message type) out -- we'll
2588 * worry about contiguity and alignment later. 2588 * worry about contiguity and alignment later.
2589 */ 2589 */
2590 m_copydata(m, 0, sizeof(wgm), &wgm); 2590 m_copydata(m, 0, sizeof(wgm), &wgm);
2591 switch (wgm.wgm_type) { 2591 switch (wgm.wgm_type) {
2592 case WG_MSG_TYPE_INIT: 2592 case WG_MSG_TYPE_INIT:
2593 msglen = sizeof(struct wg_msg_init); 2593 msglen = sizeof(struct wg_msg_init);
2594 break; 2594 break;
2595 case WG_MSG_TYPE_RESP: 2595 case WG_MSG_TYPE_RESP:
2596 msglen = sizeof(struct wg_msg_resp); 2596 msglen = sizeof(struct wg_msg_resp);
2597 break; 2597 break;
2598 case WG_MSG_TYPE_COOKIE: 2598 case WG_MSG_TYPE_COOKIE:
2599 msglen = sizeof(struct wg_msg_cookie); 2599 msglen = sizeof(struct wg_msg_cookie);
2600 break; 2600 break;
2601 case WG_MSG_TYPE_DATA: 2601 case WG_MSG_TYPE_DATA:
2602 msglen = sizeof(struct wg_msg_data); 2602 msglen = sizeof(struct wg_msg_data);
2603 break; 2603 break;
2604 default: 2604 default:
2605 WG_LOG_RATECHECK(&wg->wg_ppsratecheck, LOG_DEBUG, 2605 WG_LOG_RATECHECK(&wg->wg_ppsratecheck, LOG_DEBUG,
2606 "Unexpected msg type: %u\n", wgm.wgm_type); 2606 "Unexpected msg type: %u\n", wgm.wgm_type);
2607 goto error; 2607 goto error;
2608 } 2608 }
2609 2609
2610 /* Verify the mbuf chain is long enough for this type of message. */ 2610 /* Verify the mbuf chain is long enough for this type of message. */
2611 if (__predict_false(mbuflen < msglen)) { 2611 if (__predict_false(mbuflen < msglen)) {
2612 WG_DLOG("Invalid msg size: mbuflen=%lu type=%u\n", mbuflen, 2612 WG_DLOG("Invalid msg size: mbuflen=%lu type=%u\n", mbuflen,
2613 wgm.wgm_type); 2613 wgm.wgm_type);
2614 goto error; 2614 goto error;
2615 } 2615 }
2616 2616
2617 /* Make the message header contiguous if necessary. */ 2617 /* Make the message header contiguous if necessary. */
2618 if (__predict_false(m->m_len < msglen)) { 2618 if (__predict_false(m->m_len < msglen)) {
2619 m = m_pullup(m, msglen); 2619 m = m_pullup(m, msglen);
2620 if (m == NULL) 2620 if (m == NULL)
2621 return NULL; 2621 return NULL;
2622 } 2622 }
2623 2623
2624 return m; 2624 return m;
2625 2625
2626error: 2626error:
2627 m_freem(m); 2627 m_freem(m);
2628 return NULL; 2628 return NULL;
2629} 2629}
2630 2630
2631static void 2631static void
2632wg_handle_packet(struct wg_softc *wg, struct mbuf *m, 2632wg_handle_packet(struct wg_softc *wg, struct mbuf *m,
2633 const struct sockaddr *src) 2633 const struct sockaddr *src)
2634{ 2634{
2635 struct wg_msg *wgm; 2635 struct wg_msg *wgm;
2636 2636
2637 m = wg_validate_msg_header(wg, m); 2637 m = wg_validate_msg_header(wg, m);
2638 if (__predict_false(m == NULL)) 2638 if (__predict_false(m == NULL))
2639 return; 2639 return;
2640 2640
2641 KASSERT(m->m_len >= sizeof(struct wg_msg)); 2641 KASSERT(m->m_len >= sizeof(struct wg_msg));
2642 wgm = mtod(m, struct wg_msg *); 2642 wgm = mtod(m, struct wg_msg *);
2643 switch (wgm->wgm_type) { 2643 switch (wgm->wgm_type) {
2644 case WG_MSG_TYPE_INIT: 2644 case WG_MSG_TYPE_INIT:
2645 wg_handle_msg_init(wg, (struct wg_msg_init *)wgm, src); 2645 wg_handle_msg_init(wg, (struct wg_msg_init *)wgm, src);
2646 break; 2646 break;
2647 case WG_MSG_TYPE_RESP: 2647 case WG_MSG_TYPE_RESP:
2648 wg_handle_msg_resp(wg, (struct wg_msg_resp *)wgm, src); 2648 wg_handle_msg_resp(wg, (struct wg_msg_resp *)wgm, src);
2649 break; 2649 break;
2650 case WG_MSG_TYPE_COOKIE: 2650 case WG_MSG_TYPE_COOKIE:
2651 wg_handle_msg_cookie(wg, (struct wg_msg_cookie *)wgm); 2651 wg_handle_msg_cookie(wg, (struct wg_msg_cookie *)wgm);
2652 break; 2652 break;
2653 case WG_MSG_TYPE_DATA: 2653 case WG_MSG_TYPE_DATA:
2654 wg_handle_msg_data(wg, m, src); 2654 wg_handle_msg_data(wg, m, src);
2655 break; 2655 break;
2656 default: 2656 default:
2657 /* wg_validate_msg_header should already reject this case */ 2657 /* wg_validate_msg_header should already reject this case */
2658 break; 2658 break;
2659 } 2659 }
2660} 2660}
2661 2661
2662static void 2662static void
2663wg_receive_packets(struct wg_softc *wg, const int af) 2663wg_receive_packets(struct wg_softc *wg, const int af)
2664{ 2664{
2665 2665
2666 for (;;) { 2666 for (;;) {
2667 int error, flags; 2667 int error, flags;
2668 struct socket *so; 2668 struct socket *so;
2669 struct mbuf *m = NULL; 2669 struct mbuf *m = NULL;
2670 struct uio dummy_uio; 2670 struct uio dummy_uio;
2671 struct mbuf *paddr = NULL; 2671 struct mbuf *paddr = NULL;
2672 struct sockaddr *src; 2672 struct sockaddr *src;
2673 2673
2674 so = wg_get_so_by_af(wg->wg_worker, af); 2674 so = wg_get_so_by_af(wg->wg_worker, af);
2675 flags = MSG_DONTWAIT; 2675 flags = MSG_DONTWAIT;
2676 dummy_uio.uio_resid = 1000000000; 2676 dummy_uio.uio_resid = 1000000000;
2677 2677
2678 error = so->so_receive(so, &paddr, &dummy_uio, &m, NULL, 2678 error = so->so_receive(so, &paddr, &dummy_uio, &m, NULL,
2679 &flags); 2679 &flags);
2680 if (error || m == NULL) { 2680 if (error || m == NULL) {
2681 //if (error == EWOULDBLOCK) 2681 //if (error == EWOULDBLOCK)
2682 return; 2682 return;
2683 } 2683 }
2684 2684
2685 KASSERT(paddr != NULL); 2685 KASSERT(paddr != NULL);
2686 KASSERT(paddr->m_len >= sizeof(struct sockaddr)); 2686 KASSERT(paddr->m_len >= sizeof(struct sockaddr));
2687 src = mtod(paddr, struct sockaddr *); 2687 src = mtod(paddr, struct sockaddr *);
2688 2688
2689 wg_handle_packet(wg, m, src); 2689 wg_handle_packet(wg, m, src);
2690 } 2690 }
2691} 2691}
2692 2692
2693static void 2693static void
2694wg_get_peer(struct wg_peer *wgp, struct psref *psref) 2694wg_get_peer(struct wg_peer *wgp, struct psref *psref)
2695{ 2695{
2696 2696
2697 psref_acquire(psref, &wgp->wgp_psref, wg_psref_class); 2697 psref_acquire(psref, &wgp->wgp_psref, wg_psref_class);
2698} 2698}
2699 2699
2700static void 2700static void
2701wg_put_peer(struct wg_peer *wgp, struct psref *psref) 2701wg_put_peer(struct wg_peer *wgp, struct psref *psref)
2702{ 2702{
2703 2703
2704 psref_release(psref, &wgp->wgp_psref, wg_psref_class); 2704 psref_release(psref, &wgp->wgp_psref, wg_psref_class);
2705} 2705}
2706 2706
2707static void 2707static void
2708wg_task_send_init_message(struct wg_softc *wg, struct wg_peer *wgp) 2708wg_task_send_init_message(struct wg_softc *wg, struct wg_peer *wgp)
2709{ 2709{
2710 struct psref psref; 2710 struct psref psref;
2711 struct wg_session *wgs; 2711 struct wg_session *wgs;
2712 2712
2713 WG_TRACE("WGP_TASK_SEND_INIT_MESSAGE"); 2713 WG_TRACE("WGP_TASK_SEND_INIT_MESSAGE");
2714 2714
2715 if (!wgp->wgp_endpoint_available) { 2715 if (!wgp->wgp_endpoint_available) {
2716 WGLOG(LOG_DEBUG, "No endpoint available\n"); 2716 WGLOG(LOG_DEBUG, "No endpoint available\n");
2717 /* XXX should do something? */ 2717 /* XXX should do something? */
2718 return; 2718 return;
2719 } 2719 }
2720 2720
2721 wgs = wg_get_stable_session(wgp, &psref); 2721 wgs = wg_get_stable_session(wgp, &psref);
2722 if (wgs->wgs_state == WGS_STATE_UNKNOWN) { 2722 if (wgs->wgs_state == WGS_STATE_UNKNOWN) {
2723 wg_put_session(wgs, &psref); 2723 wg_put_session(wgs, &psref);
2724 wg_send_handshake_msg_init(wg, wgp); 2724 wg_send_handshake_msg_init(wg, wgp);
2725 } else { 2725 } else {
2726 wg_put_session(wgs, &psref); 2726 wg_put_session(wgs, &psref);
2727 /* rekey */ 2727 /* rekey */
2728 wgs = wg_get_unstable_session(wgp, &psref); 2728 wgs = wg_get_unstable_session(wgp, &psref);
2729 if (wgs->wgs_state != WGS_STATE_INIT_ACTIVE) 2729 if (wgs->wgs_state != WGS_STATE_INIT_ACTIVE)
2730 wg_send_handshake_msg_init(wg, wgp); 2730 wg_send_handshake_msg_init(wg, wgp);
2731 wg_put_session(wgs, &psref); 2731 wg_put_session(wgs, &psref);
2732 } 2732 }
2733} 2733}
2734 2734
2735static void 2735static void
2736wg_task_endpoint_changed(struct wg_softc *wg, struct wg_peer *wgp) 2736wg_task_endpoint_changed(struct wg_softc *wg, struct wg_peer *wgp)
2737{ 2737{
2738 2738
2739 WG_TRACE("WGP_TASK_ENDPOINT_CHANGED"); 2739 WG_TRACE("WGP_TASK_ENDPOINT_CHANGED");
2740 2740
2741 mutex_enter(wgp->wgp_lock); 2741 mutex_enter(wgp->wgp_lock);
2742 if (wgp->wgp_endpoint_changing) { 2742 if (wgp->wgp_endpoint_changing) {
2743 pserialize_perform(wgp->wgp_psz); 2743 pserialize_perform(wgp->wgp_psz);
2744 psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref, 2744 psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref,
2745 wg_psref_class); 2745 wg_psref_class);
2746 psref_target_init(&wgp->wgp_endpoint0->wgsa_psref, 2746 psref_target_init(&wgp->wgp_endpoint0->wgsa_psref,
2747 wg_psref_class); 2747 wg_psref_class);
2748 wgp->wgp_endpoint_changing = false; 2748 wgp->wgp_endpoint_changing = false;
2749 } 2749 }
2750 mutex_exit(wgp->wgp_lock); 2750 mutex_exit(wgp->wgp_lock);
2751} 2751}
2752 2752
2753static void 2753static void
2754wg_task_send_keepalive_message(struct wg_softc *wg, struct wg_peer *wgp) 2754wg_task_send_keepalive_message(struct wg_softc *wg, struct wg_peer *wgp)
2755{ 2755{
2756 struct psref psref; 2756 struct psref psref;
2757 struct wg_session *wgs; 2757 struct wg_session *wgs;
2758 2758
2759 WG_TRACE("WGP_TASK_SEND_KEEPALIVE_MESSAGE"); 2759 WG_TRACE("WGP_TASK_SEND_KEEPALIVE_MESSAGE");
2760 2760
2761 wgs = wg_get_stable_session(wgp, &psref); 2761 wgs = wg_get_stable_session(wgp, &psref);
2762 wg_send_keepalive_msg(wgp, wgs); 2762 wg_send_keepalive_msg(wgp, wgs);
2763 wg_put_session(wgs, &psref); 2763 wg_put_session(wgs, &psref);
2764} 2764}
2765 2765
2766static void 2766static void
2767wg_task_destroy_prev_session(struct wg_softc *wg, struct wg_peer *wgp) 2767wg_task_destroy_prev_session(struct wg_softc *wg, struct wg_peer *wgp)
2768{ 2768{
2769 struct wg_session *wgs; 2769 struct wg_session *wgs;
2770 2770
2771 WG_TRACE("WGP_TASK_DESTROY_PREV_SESSION"); 2771 WG_TRACE("WGP_TASK_DESTROY_PREV_SESSION");
2772 2772
2773 mutex_enter(wgp->wgp_lock); 2773 mutex_enter(wgp->wgp_lock);
2774 wgs = wgp->wgp_session_unstable; 2774 wgs = wgp->wgp_session_unstable;
2775 mutex_enter(wgs->wgs_lock); 2775 mutex_enter(wgs->wgs_lock);
2776 if (wgs->wgs_state == WGS_STATE_DESTROYING) { 2776 if (wgs->wgs_state == WGS_STATE_DESTROYING) {
2777 pserialize_perform(wgp->wgp_psz); 2777 pserialize_perform(wgp->wgp_psz);
2778 psref_target_destroy(&wgs->wgs_psref, wg_psref_class); 2778 psref_target_destroy(&wgs->wgs_psref, wg_psref_class);
2779 psref_target_init(&wgs->wgs_psref, wg_psref_class); 2779 psref_target_init(&wgs->wgs_psref, wg_psref_class);
2780 wg_clear_states(wgs); 2780 wg_clear_states(wgs);
2781 wgs->wgs_state = WGS_STATE_UNKNOWN; 2781 wgs->wgs_state = WGS_STATE_UNKNOWN;
2782 } 2782 }
2783 mutex_exit(wgs->wgs_lock); 2783 mutex_exit(wgs->wgs_lock);
2784 mutex_exit(wgp->wgp_lock); 2784 mutex_exit(wgp->wgp_lock);
2785} 2785}
2786 2786
2787static void 2787static void
2788wg_process_peer_tasks(struct wg_softc *wg) 2788wg_process_peer_tasks(struct wg_softc *wg)
2789{ 2789{
2790 struct wg_peer *wgp; 2790 struct wg_peer *wgp;
2791 int s; 2791 int s;
2792 2792
2793 /* XXX should avoid checking all peers */ 2793 /* XXX should avoid checking all peers */
2794 s = pserialize_read_enter(); 2794 s = pserialize_read_enter();
2795 WG_PEER_READER_FOREACH(wgp, wg) { 2795 WG_PEER_READER_FOREACH(wgp, wg) {
2796 struct psref psref; 2796 struct psref psref;
2797 unsigned int tasks; 2797 unsigned int tasks;
2798 2798
2799 if (wgp->wgp_tasks == 0) 2799 if (wgp->wgp_tasks == 0)
2800 continue; 2800 continue;
2801 2801
2802 wg_get_peer(wgp, &psref); 2802 wg_get_peer(wgp, &psref);
2803 pserialize_read_exit(s); 2803 pserialize_read_exit(s);
2804 2804
2805 restart: 2805 restart:
2806 tasks = atomic_swap_uint(&wgp->wgp_tasks, 0); 2806 tasks = atomic_swap_uint(&wgp->wgp_tasks, 0);
2807 KASSERT(tasks != 0); 2807 KASSERT(tasks != 0);
2808 2808
2809 WG_DLOG("tasks=%x\n", tasks); 2809 WG_DLOG("tasks=%x\n", tasks);
2810 2810
2811 if (ISSET(tasks, WGP_TASK_SEND_INIT_MESSAGE)) 2811 if (ISSET(tasks, WGP_TASK_SEND_INIT_MESSAGE))
2812 wg_task_send_init_message(wg, wgp); 2812 wg_task_send_init_message(wg, wgp);
2813 if (ISSET(tasks, WGP_TASK_ENDPOINT_CHANGED)) 2813 if (ISSET(tasks, WGP_TASK_ENDPOINT_CHANGED))
2814 wg_task_endpoint_changed(wg, wgp); 2814 wg_task_endpoint_changed(wg, wgp);
2815 if (ISSET(tasks, WGP_TASK_SEND_KEEPALIVE_MESSAGE)) 2815 if (ISSET(tasks, WGP_TASK_SEND_KEEPALIVE_MESSAGE))
2816 wg_task_send_keepalive_message(wg, wgp); 2816 wg_task_send_keepalive_message(wg, wgp);
2817 if (ISSET(tasks, WGP_TASK_DESTROY_PREV_SESSION)) 2817 if (ISSET(tasks, WGP_TASK_DESTROY_PREV_SESSION))
2818 wg_task_destroy_prev_session(wg, wgp); 2818 wg_task_destroy_prev_session(wg, wgp);
2819 2819
2820 /* New tasks may be scheduled during processing tasks */ 2820 /* New tasks may be scheduled during processing tasks */
2821 WG_DLOG("wgp_tasks=%d\n", wgp->wgp_tasks); 2821 WG_DLOG("wgp_tasks=%d\n", wgp->wgp_tasks);
2822 if (wgp->wgp_tasks != 0) 2822 if (wgp->wgp_tasks != 0)
2823 goto restart; 2823 goto restart;
2824 2824
2825 s = pserialize_read_enter(); 2825 s = pserialize_read_enter();
2826 wg_put_peer(wgp, &psref); 2826 wg_put_peer(wgp, &psref);
2827 } 2827 }
2828 pserialize_read_exit(s); 2828 pserialize_read_exit(s);
2829} 2829}
2830 2830
2831static void 2831static void
2832wg_worker(void *arg) 2832wg_worker(void *arg)
2833{ 2833{
2834 struct wg_softc *wg = arg; 2834 struct wg_softc *wg = arg;
2835 struct wg_worker *wgw = wg->wg_worker; 2835 struct wg_worker *wgw = wg->wg_worker;
2836 bool todie = false; 2836 bool todie = false;
2837 2837
2838 KASSERT(wg != NULL); 2838 KASSERT(wg != NULL);
2839 KASSERT(wgw != NULL); 2839 KASSERT(wgw != NULL);
2840 2840
2841 while (!todie) { 2841 while (!todie) {
2842 int reasons; 2842 int reasons;
2843 int bound; 2843 int bound;
2844 2844
2845 mutex_enter(&wgw->wgw_lock); 2845 mutex_enter(&wgw->wgw_lock);
2846 /* New tasks may come during task handling */ 2846 /* New tasks may come during task handling */
2847 while ((reasons = wgw->wgw_wakeup_reasons) == 0 && 2847 while ((reasons = wgw->wgw_wakeup_reasons) == 0 &&
2848 !(todie = wgw->wgw_todie)) 2848 !(todie = wgw->wgw_todie))
2849 cv_wait(&wgw->wgw_cv, &wgw->wgw_lock); 2849 cv_wait(&wgw->wgw_cv, &wgw->wgw_lock);
2850 wgw->wgw_wakeup_reasons = 0; 2850 wgw->wgw_wakeup_reasons = 0;
2851 mutex_exit(&wgw->wgw_lock); 2851 mutex_exit(&wgw->wgw_lock);
2852 2852
2853 bound = curlwp_bind(); 2853 bound = curlwp_bind();
2854 if (ISSET(reasons, WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4)) 2854 if (ISSET(reasons, WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4))
2855 wg_receive_packets(wg, AF_INET); 2855 wg_receive_packets(wg, AF_INET);
2856 if (ISSET(reasons, WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6)) 2856 if (ISSET(reasons, WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6))
2857 wg_receive_packets(wg, AF_INET6); 2857 wg_receive_packets(wg, AF_INET6);
2858 if (ISSET(reasons, WG_WAKEUP_REASON_PEER)) 2858 if (ISSET(reasons, WG_WAKEUP_REASON_PEER))
2859 wg_process_peer_tasks(wg); 2859 wg_process_peer_tasks(wg);
2860 curlwp_bindx(bound); 2860 curlwp_bindx(bound);
2861 } 2861 }
2862 kthread_exit(0); 2862 kthread_exit(0);
2863} 2863}
2864 2864
2865static void 2865static void
2866wg_wakeup_worker(struct wg_worker *wgw, const int reason) 2866wg_wakeup_worker(struct wg_worker *wgw, const int reason)
2867{ 2867{
2868 2868
2869 mutex_enter(&wgw->wgw_lock); 2869 mutex_enter(&wgw->wgw_lock);
2870 wgw->wgw_wakeup_reasons |= reason; 2870 wgw->wgw_wakeup_reasons |= reason;
2871 cv_broadcast(&wgw->wgw_cv); 2871 cv_broadcast(&wgw->wgw_cv);
2872 mutex_exit(&wgw->wgw_lock); 2872 mutex_exit(&wgw->wgw_lock);
2873} 2873}
2874 2874
2875static int 2875static int
2876wg_bind_port(struct wg_softc *wg, const uint16_t port) 2876wg_bind_port(struct wg_softc *wg, const uint16_t port)
2877{ 2877{
2878 int error; 2878 int error;
2879 struct wg_worker *wgw = wg->wg_worker; 2879 struct wg_worker *wgw = wg->wg_worker;
2880 uint16_t old_port = wg->wg_listen_port; 2880 uint16_t old_port = wg->wg_listen_port;
2881 2881
2882 if (port != 0 && old_port == port) 2882 if (port != 0 && old_port == port)
2883 return 0; 2883 return 0;
2884 2884
2885 struct sockaddr_in _sin, *sin = &_sin; 2885 struct sockaddr_in _sin, *sin = &_sin;
2886 sin->sin_len = sizeof(*sin); 2886 sin->sin_len = sizeof(*sin);
2887 sin->sin_family = AF_INET; 2887 sin->sin_family = AF_INET;
2888 sin->sin_addr.s_addr = INADDR_ANY; 2888 sin->sin_addr.s_addr = INADDR_ANY;
2889 sin->sin_port = htons(port); 2889 sin->sin_port = htons(port);
2890 2890
2891 error = sobind(wgw->wgw_so4, sintosa(sin), curlwp); 2891 error = sobind(wgw->wgw_so4, sintosa(sin), curlwp);
2892 if (error != 0) 2892 if (error != 0)
2893 return error; 2893 return error;
2894 2894
2895#ifdef INET6 2895#ifdef INET6
2896 struct sockaddr_in6 _sin6, *sin6 = &_sin6; 2896 struct sockaddr_in6 _sin6, *sin6 = &_sin6;
2897 sin6->sin6_len = sizeof(*sin6); 2897 sin6->sin6_len = sizeof(*sin6);
2898 sin6->sin6_family = AF_INET6; 2898 sin6->sin6_family = AF_INET6;
2899 sin6->sin6_addr = in6addr_any; 2899 sin6->sin6_addr = in6addr_any;
2900 sin6->sin6_port = htons(port); 2900 sin6->sin6_port = htons(port);
2901 2901
2902 error = sobind(wgw->wgw_so6, sin6tosa(sin6), curlwp); 2902 error = sobind(wgw->wgw_so6, sin6tosa(sin6), curlwp);
2903 if (error != 0) 2903 if (error != 0)
2904 return error; 2904 return error;
2905#endif 2905#endif
2906 2906
2907 wg->wg_listen_port = port; 2907 wg->wg_listen_port = port;
2908 2908
2909 return 0; 2909 return 0;
2910} 2910}
2911 2911
2912static void 2912static void
2913wg_so_upcall(struct socket *so, void *arg, int events, int waitflag) 2913wg_so_upcall(struct socket *so, void *arg, int events, int waitflag)
2914{ 2914{
2915 struct wg_worker *wgw = arg; 2915 struct wg_worker *wgw = arg;
2916 int reason; 2916 int reason;
2917 2917
2918 reason = (so->so_proto->pr_domain->dom_family == AF_INET) ? 2918 reason = (so->so_proto->pr_domain->dom_family == AF_INET) ?
2919 WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4 : 2919 WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4 :
2920 WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6; 2920 WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6;
2921 wg_wakeup_worker(wgw, reason); 2921 wg_wakeup_worker(wgw, reason);
2922} 2922}
2923 2923
2924static int 2924static int
2925wg_overudp_cb(struct mbuf **mp, int offset, struct socket *so, 2925wg_overudp_cb(struct mbuf **mp, int offset, struct socket *so,
2926 struct sockaddr *src, void *arg) 2926 struct sockaddr *src, void *arg)
2927{ 2927{
2928 struct wg_softc *wg = arg; 2928 struct wg_softc *wg = arg;
2929 struct wg_msg wgm; 2929 struct wg_msg wgm;
2930 struct mbuf *m = *mp; 2930 struct mbuf *m = *mp;
2931 2931
2932 WG_TRACE("enter"); 2932 WG_TRACE("enter");
2933 2933
2934 /* Verify the mbuf chain is long enough to have a wg msg header. */ 2934 /* Verify the mbuf chain is long enough to have a wg msg header. */
2935 KASSERT(offset <= m_length(m)); 2935 KASSERT(offset <= m_length(m));
2936 if (__predict_false(m_length(m) - offset < sizeof(struct wg_msg))) { 2936 if (__predict_false(m_length(m) - offset < sizeof(struct wg_msg))) {
 2937 /* drop on the floor */
2937 m_freem(m); 2938 m_freem(m);
2938 return -1; 2939 return -1;
2939 } 2940 }
2940 2941
2941 /* 2942 /*
2942 * Copy the message header (32-bit message type) out -- we'll 2943 * Copy the message header (32-bit message type) out -- we'll
2943 * worry about contiguity and alignment later. 2944 * worry about contiguity and alignment later.
2944 */ 2945 */
2945 m_copydata(m, offset, sizeof(struct wg_msg), &wgm); 2946 m_copydata(m, offset, sizeof(struct wg_msg), &wgm);
2946 WG_DLOG("type=%d\n", wgm.wgm_type); 2947 WG_DLOG("type=%d\n", wgm.wgm_type);
2947 2948
2948 /* 2949 /*
2949 * Handle DATA packets promptly as they arrive. Other packets 2950 * Handle DATA packets promptly as they arrive. Other packets
2950 * may require expensive public-key crypto and are not as 2951 * may require expensive public-key crypto and are not as
2951 * sensitive to latency, so defer them to the worker thread. 2952 * sensitive to latency, so defer them to the worker thread.
2952 */ 2953 */
2953 switch (wgm.wgm_type) { 2954 switch (wgm.wgm_type) {
2954 case WG_MSG_TYPE_DATA: 2955 case WG_MSG_TYPE_DATA:
 2956 /* handle immediately */
2955 m_adj(m, offset); 2957 m_adj(m, offset);
2956 wg_handle_msg_data(wg, m, src); 2958 wg_handle_msg_data(wg, m, src);
2957 *mp = NULL; 2959 *mp = NULL;
2958 return 1; 2960 return 1;
 2961 case WG_MSG_TYPE_INIT:
 2962 case WG_MSG_TYPE_RESP:
 2963 case WG_MSG_TYPE_COOKIE:
 2964 /* pass through to so_receive in wg_receive_packets */
 2965 return 0;
2959 default: 2966 default:
2960 break; 2967 /* drop on the floor */
 2968 m_freem(m);
 2969 return -1;
2961 } 2970 }
2962 
2963 return 0; 
2964} 2971}
2965 2972
2966static int 2973static int
2967wg_worker_socreate(struct wg_softc *wg, struct wg_worker *wgw, const int af, 2974wg_worker_socreate(struct wg_softc *wg, struct wg_worker *wgw, const int af,
2968 struct socket **sop) 2975 struct socket **sop)
2969{ 2976{
2970 int error; 2977 int error;
2971 struct socket *so; 2978 struct socket *so;
2972 2979
2973 error = socreate(af, &so, SOCK_DGRAM, 0, curlwp, NULL); 2980 error = socreate(af, &so, SOCK_DGRAM, 0, curlwp, NULL);
2974 if (error != 0) 2981 if (error != 0)
2975 return error; 2982 return error;
2976 2983
2977 solock(so); 2984 solock(so);
2978 so->so_upcallarg = wgw; 2985 so->so_upcallarg = wgw;
2979 so->so_upcall = wg_so_upcall; 2986 so->so_upcall = wg_so_upcall;
2980 so->so_rcv.sb_flags |= SB_UPCALL; 2987 so->so_rcv.sb_flags |= SB_UPCALL;
2981 if (af == AF_INET) 2988 if (af == AF_INET)
2982 in_pcb_register_overudp_cb(sotoinpcb(so), wg_overudp_cb, wg); 2989 in_pcb_register_overudp_cb(sotoinpcb(so), wg_overudp_cb, wg);
2983#if INET6 2990#if INET6
2984 else 2991 else
2985 in6_pcb_register_overudp_cb(sotoin6pcb(so), wg_overudp_cb, wg); 2992 in6_pcb_register_overudp_cb(sotoin6pcb(so), wg_overudp_cb, wg);
2986#endif 2993#endif
2987 sounlock(so); 2994 sounlock(so);
2988 2995
2989 *sop = so; 2996 *sop = so;
2990 2997
2991 return 0; 2998 return 0;
2992} 2999}
2993 3000
2994static int 3001static int
2995wg_worker_init(struct wg_softc *wg) 3002wg_worker_init(struct wg_softc *wg)
2996{ 3003{
2997 int error; 3004 int error;
2998 struct wg_worker *wgw; 3005 struct wg_worker *wgw;
2999 const char *ifname = wg->wg_if.if_xname; 3006 const char *ifname = wg->wg_if.if_xname;
3000 struct socket *so; 3007 struct socket *so;
3001 3008
3002 wgw = kmem_zalloc(sizeof(struct wg_worker), KM_SLEEP); 3009 wgw = kmem_zalloc(sizeof(struct wg_worker), KM_SLEEP);
3003 3010
3004 mutex_init(&wgw->wgw_lock, MUTEX_DEFAULT, IPL_NONE); 3011 mutex_init(&wgw->wgw_lock, MUTEX_DEFAULT, IPL_NONE);
3005 cv_init(&wgw->wgw_cv, ifname); 3012 cv_init(&wgw->wgw_cv, ifname);
3006 wgw->wgw_todie = false; 3013 wgw->wgw_todie = false;
3007 wgw->wgw_wakeup_reasons = 0; 3014 wgw->wgw_wakeup_reasons = 0;
3008 3015
3009 error = wg_worker_socreate(wg, wgw, AF_INET, &so); 3016 error = wg_worker_socreate(wg, wgw, AF_INET, &so);
3010 if (error != 0) 3017 if (error != 0)
3011 goto error; 3018 goto error;
3012 wgw->wgw_so4 = so; 3019 wgw->wgw_so4 = so;
3013#ifdef INET6 3020#ifdef INET6
3014 error = wg_worker_socreate(wg, wgw, AF_INET6, &so); 3021 error = wg_worker_socreate(wg, wgw, AF_INET6, &so);
3015 if (error != 0) 3022 if (error != 0)
3016 goto error; 3023 goto error;
3017 wgw->wgw_so6 = so; 3024 wgw->wgw_so6 = so;
3018#endif 3025#endif
3019 3026
3020 wg->wg_worker = wgw; 3027 wg->wg_worker = wgw;
3021 3028
3022 error = kthread_create(PRI_NONE, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, 3029 error = kthread_create(PRI_NONE, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN,
3023 NULL, wg_worker, wg, &wg->wg_worker_lwp, "%s", ifname); 3030 NULL, wg_worker, wg, &wg->wg_worker_lwp, "%s", ifname);
3024 if (error != 0) 3031 if (error != 0)
3025 goto error; 3032 goto error;
3026 3033
3027 return 0; 3034 return 0;
3028 3035
3029error: 3036error:
3030#ifdef INET6 3037#ifdef INET6
3031 if (wgw->wgw_so6 != NULL) 3038 if (wgw->wgw_so6 != NULL)
3032 soclose(wgw->wgw_so6); 3039 soclose(wgw->wgw_so6);
3033#endif 3040#endif
3034 if (wgw->wgw_so4 != NULL) 3041 if (wgw->wgw_so4 != NULL)
3035 soclose(wgw->wgw_so4); 3042 soclose(wgw->wgw_so4);
3036 cv_destroy(&wgw->wgw_cv); 3043 cv_destroy(&wgw->wgw_cv);
3037 mutex_destroy(&wgw->wgw_lock); 3044 mutex_destroy(&wgw->wgw_lock);
3038 3045
3039 return error; 3046 return error;
3040} 3047}
3041 3048
3042static void 3049static void
3043wg_worker_destroy(struct wg_softc *wg) 3050wg_worker_destroy(struct wg_softc *wg)
3044{ 3051{
3045 struct wg_worker *wgw = wg->wg_worker; 3052 struct wg_worker *wgw = wg->wg_worker;
3046 3053
3047 mutex_enter(&wgw->wgw_lock); 3054 mutex_enter(&wgw->wgw_lock);
3048 wgw->wgw_todie = true; 3055 wgw->wgw_todie = true;
3049 wgw->wgw_wakeup_reasons = 0; 3056 wgw->wgw_wakeup_reasons = 0;
3050 cv_broadcast(&wgw->wgw_cv); 3057 cv_broadcast(&wgw->wgw_cv);
3051 mutex_exit(&wgw->wgw_lock); 3058 mutex_exit(&wgw->wgw_lock);
3052 3059
3053 kthread_join(wg->wg_worker_lwp); 3060 kthread_join(wg->wg_worker_lwp);
3054 3061
3055#ifdef INET6 3062#ifdef INET6
3056 soclose(wgw->wgw_so6); 3063 soclose(wgw->wgw_so6);
3057#endif 3064#endif
3058 soclose(wgw->wgw_so4); 3065 soclose(wgw->wgw_so4);
3059 cv_destroy(&wgw->wgw_cv); 3066 cv_destroy(&wgw->wgw_cv);
3060 mutex_destroy(&wgw->wgw_lock); 3067 mutex_destroy(&wgw->wgw_lock);
3061 kmem_free(wg->wg_worker, sizeof(struct wg_worker)); 3068 kmem_free(wg->wg_worker, sizeof(struct wg_worker));
3062 wg->wg_worker = NULL; 3069 wg->wg_worker = NULL;
3063} 3070}
3064 3071
3065static bool 3072static bool
3066wg_session_hit_limits(struct wg_session *wgs) 3073wg_session_hit_limits(struct wg_session *wgs)
3067{ 3074{
3068 3075
3069 /* 3076 /*
3070 * [W] 6.2: Transport Message Limits 3077 * [W] 6.2: Transport Message Limits
3071 * "After REJECT-AFTER-MESSAGES transport data messages or after the 3078 * "After REJECT-AFTER-MESSAGES transport data messages or after the
3072 * current secure session is REJECT-AFTER-TIME seconds old, whichever 3079 * current secure session is REJECT-AFTER-TIME seconds old, whichever
3073 * comes first, WireGuard will refuse to send any more transport data 3080 * comes first, WireGuard will refuse to send any more transport data
3074 * messages using the current secure session, ..." 3081 * messages using the current secure session, ..."
3075 */ 3082 */
3076 KASSERT(wgs->wgs_time_established != 0); 3083 KASSERT(wgs->wgs_time_established != 0);
3077 if ((time_uptime - wgs->wgs_time_established) > wg_reject_after_time) { 3084 if ((time_uptime - wgs->wgs_time_established) > wg_reject_after_time) {
3078 WG_DLOG("The session hits REJECT_AFTER_TIME\n"); 3085 WG_DLOG("The session hits REJECT_AFTER_TIME\n");
3079 return true; 3086 return true;
3080 } else if (wg_session_get_send_counter(wgs) > 3087 } else if (wg_session_get_send_counter(wgs) >
3081 wg_reject_after_messages) { 3088 wg_reject_after_messages) {
3082 WG_DLOG("The session hits REJECT_AFTER_MESSAGES\n"); 3089 WG_DLOG("The session hits REJECT_AFTER_MESSAGES\n");
3083 return true; 3090 return true;
3084 } 3091 }
3085 3092
3086 return false; 3093 return false;
3087} 3094}
3088 3095
3089static void 3096static void
3090wg_peer_softint(void *arg) 3097wg_peer_softint(void *arg)
3091{ 3098{
3092 struct wg_peer *wgp = arg; 3099 struct wg_peer *wgp = arg;
3093 struct wg_session *wgs; 3100 struct wg_session *wgs;
3094 struct mbuf *m; 3101 struct mbuf *m;
3095 struct psref psref; 3102 struct psref psref;
3096 3103
3097 wgs = wg_get_stable_session(wgp, &psref); 3104 wgs = wg_get_stable_session(wgp, &psref);
3098 if (wgs->wgs_state != WGS_STATE_ESTABLISHED) { 3105 if (wgs->wgs_state != WGS_STATE_ESTABLISHED) {
3099 /* XXX how to treat? */ 3106 /* XXX how to treat? */
3100 WG_TRACE("skipped"); 3107 WG_TRACE("skipped");
3101 goto out; 3108 goto out;
3102 } 3109 }
3103 if (wg_session_hit_limits(wgs)) { 3110 if (wg_session_hit_limits(wgs)) {
3104 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 3111 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3105 goto out; 3112 goto out;
3106 } 3113 }
3107 WG_TRACE("running"); 3114 WG_TRACE("running");
3108 3115
3109 while ((m = pcq_get(wgp->wgp_q)) != NULL) { 3116 while ((m = pcq_get(wgp->wgp_q)) != NULL) {
3110 wg_send_data_msg(wgp, wgs, m); 3117 wg_send_data_msg(wgp, wgs, m);
3111 } 3118 }
3112out: 3119out:
3113 wg_put_session(wgs, &psref); 3120 wg_put_session(wgs, &psref);
3114} 3121}
3115 3122
3116static void 3123static void
3117wg_rekey_timer(void *arg) 3124wg_rekey_timer(void *arg)
3118{ 3125{
3119 struct wg_peer *wgp = arg; 3126 struct wg_peer *wgp = arg;
3120 3127
3121 mutex_enter(wgp->wgp_lock); 3128 mutex_enter(wgp->wgp_lock);
3122 if (__predict_true(wgp->wgp_state != WGP_STATE_DESTROYING)) { 3129 if (__predict_true(wgp->wgp_state != WGP_STATE_DESTROYING)) {
3123 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 3130 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3124 } 3131 }
3125 mutex_exit(wgp->wgp_lock); 3132 mutex_exit(wgp->wgp_lock);
3126} 3133}
3127 3134
3128static void 3135static void
3129wg_purge_pending_packets(struct wg_peer *wgp) 3136wg_purge_pending_packets(struct wg_peer *wgp)
3130{ 3137{
3131 struct mbuf *m; 3138 struct mbuf *m;
3132 3139
3133 while ((m = pcq_get(wgp->wgp_q)) != NULL) { 3140 while ((m = pcq_get(wgp->wgp_q)) != NULL) {
3134 m_freem(m); 3141 m_freem(m);
3135 } 3142 }
3136} 3143}
3137 3144
3138static void 3145static void
3139wg_handshake_timeout_timer(void *arg) 3146wg_handshake_timeout_timer(void *arg)
3140{ 3147{
3141 struct wg_peer *wgp = arg; 3148 struct wg_peer *wgp = arg;
3142 struct wg_session *wgs; 3149 struct wg_session *wgs;
3143 struct psref psref; 3150 struct psref psref;
3144 3151
3145 WG_TRACE("enter"); 3152 WG_TRACE("enter");
3146 3153
3147 mutex_enter(wgp->wgp_lock); 3154 mutex_enter(wgp->wgp_lock);
3148 if (__predict_false(wgp->wgp_state == WGP_STATE_DESTROYING)) { 3155 if (__predict_false(wgp->wgp_state == WGP_STATE_DESTROYING)) {
3149 mutex_exit(wgp->wgp_lock); 3156 mutex_exit(wgp->wgp_lock);
3150 return; 3157 return;
3151 } 3158 }
3152 mutex_exit(wgp->wgp_lock); 3159 mutex_exit(wgp->wgp_lock);
3153 3160
3154 KASSERT(wgp->wgp_handshake_start_time != 0); 3161 KASSERT(wgp->wgp_handshake_start_time != 0);
3155 wgs = wg_get_unstable_session(wgp, &psref); 3162 wgs = wg_get_unstable_session(wgp, &psref);
3156 KASSERT(wgs->wgs_state == WGS_STATE_INIT_ACTIVE); 3163 KASSERT(wgs->wgs_state == WGS_STATE_INIT_ACTIVE);
3157 3164
3158 /* [W] 6.4 Handshake Initiation Retransmission */ 3165 /* [W] 6.4 Handshake Initiation Retransmission */
3159 if ((time_uptime - wgp->wgp_handshake_start_time) > 3166 if ((time_uptime - wgp->wgp_handshake_start_time) >
3160 wg_rekey_attempt_time) { 3167 wg_rekey_attempt_time) {
3161 /* Give up handshaking */ 3168 /* Give up handshaking */
3162 wgs->wgs_state = WGS_STATE_UNKNOWN; 3169 wgs->wgs_state = WGS_STATE_UNKNOWN;
3163 wg_clear_states(wgs); 3170 wg_clear_states(wgs);
3164 wgp->wgp_state = WGP_STATE_GIVEUP; 3171 wgp->wgp_state = WGP_STATE_GIVEUP;
3165 wgp->wgp_handshake_start_time = 0; 3172 wgp->wgp_handshake_start_time = 0;
3166 wg_put_session(wgs, &psref); 3173 wg_put_session(wgs, &psref);
3167 WG_TRACE("give up"); 3174 WG_TRACE("give up");
3168 /* 3175 /*
3169 * If a new data packet comes, handshaking will be retried 3176 * If a new data packet comes, handshaking will be retried
3170 * and a new session would be established at that time, 3177 * and a new session would be established at that time,
3171 * however we don't want to send pending packets then. 3178 * however we don't want to send pending packets then.
3172 */ 3179 */
3173 wg_purge_pending_packets(wgp); 3180 wg_purge_pending_packets(wgp);
3174 return; 3181 return;
3175 } 3182 }
3176 3183
3177 /* No response for an initiation message sent, retry handshaking */ 3184 /* No response for an initiation message sent, retry handshaking */
3178 wgs->wgs_state = WGS_STATE_UNKNOWN; 3185 wgs->wgs_state = WGS_STATE_UNKNOWN;
3179 wg_clear_states(wgs); 3186 wg_clear_states(wgs);
3180 wg_put_session(wgs, &psref); 3187 wg_put_session(wgs, &psref);
3181 3188
3182 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 3189 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3183} 3190}
3184 3191
3185static struct wg_peer * 3192static struct wg_peer *
3186wg_alloc_peer(struct wg_softc *wg) 3193wg_alloc_peer(struct wg_softc *wg)
3187{ 3194{
3188 struct wg_peer *wgp; 3195 struct wg_peer *wgp;
3189 3196
3190 wgp = kmem_zalloc(sizeof(*wgp), KM_SLEEP); 3197 wgp = kmem_zalloc(sizeof(*wgp), KM_SLEEP);
3191 3198
3192 wgp->wgp_sc = wg; 3199 wgp->wgp_sc = wg;
3193 wgp->wgp_state = WGP_STATE_INIT; 3200 wgp->wgp_state = WGP_STATE_INIT;
3194 wgp->wgp_q = pcq_create(1024, KM_SLEEP); 3201 wgp->wgp_q = pcq_create(1024, KM_SLEEP);
3195 wgp->wgp_si = softint_establish(SOFTINT_NET, wg_peer_softint, wgp); 3202 wgp->wgp_si = softint_establish(SOFTINT_NET, wg_peer_softint, wgp);
3196 callout_init(&wgp->wgp_rekey_timer, CALLOUT_MPSAFE); 3203 callout_init(&wgp->wgp_rekey_timer, CALLOUT_MPSAFE);
3197 callout_setfunc(&wgp->wgp_rekey_timer, wg_rekey_timer, wgp); 3204 callout_setfunc(&wgp->wgp_rekey_timer, wg_rekey_timer, wgp);
3198 callout_init(&wgp->wgp_handshake_timeout_timer, CALLOUT_MPSAFE); 3205 callout_init(&wgp->wgp_handshake_timeout_timer, CALLOUT_MPSAFE);
3199 callout_setfunc(&wgp->wgp_handshake_timeout_timer, 3206 callout_setfunc(&wgp->wgp_handshake_timeout_timer,
3200 wg_handshake_timeout_timer, wgp); 3207 wg_handshake_timeout_timer, wgp);
3201 callout_init(&wgp->wgp_session_dtor_timer, CALLOUT_MPSAFE); 3208 callout_init(&wgp->wgp_session_dtor_timer, CALLOUT_MPSAFE);
3202 callout_setfunc(&wgp->wgp_session_dtor_timer, 3209 callout_setfunc(&wgp->wgp_session_dtor_timer,
3203 wg_session_dtor_timer, wgp); 3210 wg_session_dtor_timer, wgp);
3204 PSLIST_ENTRY_INIT(wgp, wgp_peerlist_entry); 3211 PSLIST_ENTRY_INIT(wgp, wgp_peerlist_entry);
3205 wgp->wgp_endpoint_changing = false; 3212 wgp->wgp_endpoint_changing = false;
3206 wgp->wgp_endpoint_available = false; 3213 wgp->wgp_endpoint_available = false;
3207 wgp->wgp_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 3214 wgp->wgp_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3208 wgp->wgp_psz = pserialize_create(); 3215 wgp->wgp_psz = pserialize_create();
3209 psref_target_init(&wgp->wgp_psref, wg_psref_class); 3216 psref_target_init(&wgp->wgp_psref, wg_psref_class);
3210 3217
3211 wgp->wgp_endpoint = kmem_zalloc(sizeof(*wgp->wgp_endpoint), KM_SLEEP); 3218 wgp->wgp_endpoint = kmem_zalloc(sizeof(*wgp->wgp_endpoint), KM_SLEEP);
3212 wgp->wgp_endpoint0 = kmem_zalloc(sizeof(*wgp->wgp_endpoint0), KM_SLEEP); 3219 wgp->wgp_endpoint0 = kmem_zalloc(sizeof(*wgp->wgp_endpoint0), KM_SLEEP);
3213 psref_target_init(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class); 3220 psref_target_init(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class);
3214 psref_target_init(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class); 3221 psref_target_init(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class);
3215 3222
3216 struct wg_session *wgs; 3223 struct wg_session *wgs;
3217 wgp->wgp_session_stable = 3224 wgp->wgp_session_stable =
3218 kmem_zalloc(sizeof(*wgp->wgp_session_stable), KM_SLEEP); 3225 kmem_zalloc(sizeof(*wgp->wgp_session_stable), KM_SLEEP);
3219 wgp->wgp_session_unstable = 3226 wgp->wgp_session_unstable =
3220 kmem_zalloc(sizeof(*wgp->wgp_session_unstable), KM_SLEEP); 3227 kmem_zalloc(sizeof(*wgp->wgp_session_unstable), KM_SLEEP);
3221 wgs = wgp->wgp_session_stable; 3228 wgs = wgp->wgp_session_stable;
3222 wgs->wgs_peer = wgp; 3229 wgs->wgs_peer = wgp;
3223 wgs->wgs_state = WGS_STATE_UNKNOWN; 3230 wgs->wgs_state = WGS_STATE_UNKNOWN;
3224 psref_target_init(&wgs->wgs_psref, wg_psref_class); 3231 psref_target_init(&wgs->wgs_psref, wg_psref_class);
3225 wgs->wgs_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 3232 wgs->wgs_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3226#ifndef __HAVE_ATOMIC64_LOADSTORE 3233#ifndef __HAVE_ATOMIC64_LOADSTORE
3227 mutex_init(&wgs->wgs_send_counter_lock, MUTEX_DEFAULT, IPL_SOFTNET); 3234 mutex_init(&wgs->wgs_send_counter_lock, MUTEX_DEFAULT, IPL_SOFTNET);
3228#endif 3235#endif
3229 wgs->wgs_recvwin = kmem_zalloc(sizeof(*wgs->wgs_recvwin), KM_SLEEP); 3236 wgs->wgs_recvwin = kmem_zalloc(sizeof(*wgs->wgs_recvwin), KM_SLEEP);
3230 mutex_init(&wgs->wgs_recvwin->lock, MUTEX_DEFAULT, IPL_NONE); 3237 mutex_init(&wgs->wgs_recvwin->lock, MUTEX_DEFAULT, IPL_NONE);
3231 3238
3232 wgs = wgp->wgp_session_unstable; 3239 wgs = wgp->wgp_session_unstable;
3233 wgs->wgs_peer = wgp; 3240 wgs->wgs_peer = wgp;
3234 wgs->wgs_state = WGS_STATE_UNKNOWN; 3241 wgs->wgs_state = WGS_STATE_UNKNOWN;
3235 psref_target_init(&wgs->wgs_psref, wg_psref_class); 3242 psref_target_init(&wgs->wgs_psref, wg_psref_class);
3236 wgs->wgs_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 3243 wgs->wgs_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3237#ifndef __HAVE_ATOMIC64_LOADSTORE 3244#ifndef __HAVE_ATOMIC64_LOADSTORE
3238 mutex_init(&wgs->wgs_send_counter_lock, MUTEX_DEFAULT, IPL_SOFTNET); 3245 mutex_init(&wgs->wgs_send_counter_lock, MUTEX_DEFAULT, IPL_SOFTNET);
3239#endif 3246#endif
3240 wgs->wgs_recvwin = kmem_zalloc(sizeof(*wgs->wgs_recvwin), KM_SLEEP); 3247 wgs->wgs_recvwin = kmem_zalloc(sizeof(*wgs->wgs_recvwin), KM_SLEEP);
3241 mutex_init(&wgs->wgs_recvwin->lock, MUTEX_DEFAULT, IPL_NONE); 3248 mutex_init(&wgs->wgs_recvwin->lock, MUTEX_DEFAULT, IPL_NONE);
3242 3249
3243 return wgp; 3250 return wgp;
3244} 3251}
3245 3252
3246static void 3253static void
3247wg_destroy_peer(struct wg_peer *wgp) 3254wg_destroy_peer(struct wg_peer *wgp)
3248{ 3255{
3249 struct wg_session *wgs; 3256 struct wg_session *wgs;
3250 struct wg_softc *wg = wgp->wgp_sc; 3257 struct wg_softc *wg = wgp->wgp_sc;
3251 3258
3252 rw_enter(wg->wg_rwlock, RW_WRITER); 3259 rw_enter(wg->wg_rwlock, RW_WRITER);
3253 for (int i = 0; i < wgp->wgp_n_allowedips; i++) { 3260 for (int i = 0; i < wgp->wgp_n_allowedips; i++) {
3254 struct wg_allowedip *wga = &wgp->wgp_allowedips[i]; 3261 struct wg_allowedip *wga = &wgp->wgp_allowedips[i];
3255 struct radix_node_head *rnh = wg_rnh(wg, wga->wga_family); 3262 struct radix_node_head *rnh = wg_rnh(wg, wga->wga_family);
3256 struct radix_node *rn; 3263 struct radix_node *rn;
3257 3264
3258 KASSERT(rnh != NULL); 3265 KASSERT(rnh != NULL);
3259 rn = rnh->rnh_deladdr(&wga->wga_sa_addr, 3266 rn = rnh->rnh_deladdr(&wga->wga_sa_addr,
3260 &wga->wga_sa_mask, rnh); 3267 &wga->wga_sa_mask, rnh);
3261 if (rn == NULL) { 3268 if (rn == NULL) {
3262 char addrstr[128]; 3269 char addrstr[128];
3263 sockaddr_format(&wga->wga_sa_addr, addrstr, 3270 sockaddr_format(&wga->wga_sa_addr, addrstr,
3264 sizeof(addrstr)); 3271 sizeof(addrstr));
3265 WGLOG(LOG_WARNING, "Couldn't delete %s", addrstr); 3272 WGLOG(LOG_WARNING, "Couldn't delete %s", addrstr);
3266 } 3273 }
3267 } 3274 }
3268 rw_exit(wg->wg_rwlock); 3275 rw_exit(wg->wg_rwlock);
3269 3276
3270 softint_disestablish(wgp->wgp_si); 3277 softint_disestablish(wgp->wgp_si);
3271 callout_halt(&wgp->wgp_rekey_timer, NULL); 3278 callout_halt(&wgp->wgp_rekey_timer, NULL);
3272 callout_halt(&wgp->wgp_handshake_timeout_timer, NULL); 3279 callout_halt(&wgp->wgp_handshake_timeout_timer, NULL);
3273 callout_halt(&wgp->wgp_session_dtor_timer, NULL); 3280 callout_halt(&wgp->wgp_session_dtor_timer, NULL);
3274 3281
3275 wgs = wgp->wgp_session_unstable; 3282 wgs = wgp->wgp_session_unstable;
3276 psref_target_destroy(&wgs->wgs_psref, wg_psref_class); 3283 psref_target_destroy(&wgs->wgs_psref, wg_psref_class);
3277 mutex_obj_free(wgs->wgs_lock); 3284 mutex_obj_free(wgs->wgs_lock);
3278 mutex_destroy(&wgs->wgs_recvwin->lock); 3285 mutex_destroy(&wgs->wgs_recvwin->lock);
3279 kmem_free(wgs->wgs_recvwin, sizeof(*wgs->wgs_recvwin)); 3286 kmem_free(wgs->wgs_recvwin, sizeof(*wgs->wgs_recvwin));
3280#ifndef __HAVE_ATOMIC64_LOADSTORE 3287#ifndef __HAVE_ATOMIC64_LOADSTORE
3281 mutex_destroy(&wgs->wgs_send_counter_lock); 3288 mutex_destroy(&wgs->wgs_send_counter_lock);
3282#endif 3289#endif
3283 kmem_free(wgs, sizeof(*wgs)); 3290 kmem_free(wgs, sizeof(*wgs));
3284 wgs = wgp->wgp_session_stable; 3291 wgs = wgp->wgp_session_stable;
3285 psref_target_destroy(&wgs->wgs_psref, wg_psref_class); 3292 psref_target_destroy(&wgs->wgs_psref, wg_psref_class);
3286 mutex_obj_free(wgs->wgs_lock); 3293 mutex_obj_free(wgs->wgs_lock);
3287 mutex_destroy(&wgs->wgs_recvwin->lock); 3294 mutex_destroy(&wgs->wgs_recvwin->lock);
3288 kmem_free(wgs->wgs_recvwin, sizeof(*wgs->wgs_recvwin)); 3295 kmem_free(wgs->wgs_recvwin, sizeof(*wgs->wgs_recvwin));
3289#ifndef __HAVE_ATOMIC64_LOADSTORE 3296#ifndef __HAVE_ATOMIC64_LOADSTORE
3290 mutex_destroy(&wgs->wgs_send_counter_lock); 3297 mutex_destroy(&wgs->wgs_send_counter_lock);
3291#endif 3298#endif
3292 kmem_free(wgs, sizeof(*wgs)); 3299 kmem_free(wgs, sizeof(*wgs));
3293 3300
3294 psref_target_destroy(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class); 3301 psref_target_destroy(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class);
3295 psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class); 3302 psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class);
3296 kmem_free(wgp->wgp_endpoint, sizeof(*wgp->wgp_endpoint)); 3303 kmem_free(wgp->wgp_endpoint, sizeof(*wgp->wgp_endpoint));
3297 kmem_free(wgp->wgp_endpoint0, sizeof(*wgp->wgp_endpoint0)); 3304 kmem_free(wgp->wgp_endpoint0, sizeof(*wgp->wgp_endpoint0));
3298 3305
3299 pserialize_destroy(wgp->wgp_psz); 3306 pserialize_destroy(wgp->wgp_psz);
3300 pcq_destroy(wgp->wgp_q); 3307 pcq_destroy(wgp->wgp_q);
3301 mutex_obj_free(wgp->wgp_lock); 3308 mutex_obj_free(wgp->wgp_lock);
3302 3309
3303 kmem_free(wgp, sizeof(*wgp)); 3310 kmem_free(wgp, sizeof(*wgp));
3304} 3311}
3305 3312
3306static void 3313static void
3307wg_destroy_all_peers(struct wg_softc *wg) 3314wg_destroy_all_peers(struct wg_softc *wg)
3308{ 3315{
3309 struct wg_peer *wgp; 3316 struct wg_peer *wgp;
3310 3317
3311restart: 3318restart:
3312 mutex_enter(wg->wg_lock); 3319 mutex_enter(wg->wg_lock);
3313 WG_PEER_WRITER_FOREACH(wgp, wg) { 3320 WG_PEER_WRITER_FOREACH(wgp, wg) {
3314 WG_PEER_WRITER_REMOVE(wgp); 3321 WG_PEER_WRITER_REMOVE(wgp);
3315 mutex_enter(wgp->wgp_lock); 3322 mutex_enter(wgp->wgp_lock);
3316 wgp->wgp_state = WGP_STATE_DESTROYING; 3323 wgp->wgp_state = WGP_STATE_DESTROYING;
3317 pserialize_perform(wgp->wgp_psz); 3324 pserialize_perform(wgp->wgp_psz);
3318 mutex_exit(wgp->wgp_lock); 3325 mutex_exit(wgp->wgp_lock);
3319 PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry); 3326 PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry);
3320 break; 3327 break;
3321 } 3328 }
3322 mutex_exit(wg->wg_lock); 3329 mutex_exit(wg->wg_lock);
3323 3330
3324 if (wgp == NULL) 3331 if (wgp == NULL)
3325 return; 3332 return;
3326 3333
3327 psref_target_destroy(&wgp->wgp_psref, wg_psref_class); 3334 psref_target_destroy(&wgp->wgp_psref, wg_psref_class);
3328 3335
3329 wg_destroy_peer(wgp); 3336 wg_destroy_peer(wgp);
3330 3337
3331 goto restart; 3338 goto restart;
3332} 3339}
3333 3340
3334static int 3341static int
3335wg_destroy_peer_name(struct wg_softc *wg, const char *name) 3342wg_destroy_peer_name(struct wg_softc *wg, const char *name)
3336{ 3343{
3337 struct wg_peer *wgp; 3344 struct wg_peer *wgp;
3338 3345
3339 mutex_enter(wg->wg_lock); 3346 mutex_enter(wg->wg_lock);
3340 WG_PEER_WRITER_FOREACH(wgp, wg) { 3347 WG_PEER_WRITER_FOREACH(wgp, wg) {
3341 if (strcmp(wgp->wgp_name, name) == 0) 3348 if (strcmp(wgp->wgp_name, name) == 0)
3342 break; 3349 break;
3343 } 3350 }
3344 if (wgp != NULL) { 3351 if (wgp != NULL) {
3345 WG_PEER_WRITER_REMOVE(wgp); 3352 WG_PEER_WRITER_REMOVE(wgp);
3346 wg->wg_npeers--; 3353 wg->wg_npeers--;
3347 mutex_enter(wgp->wgp_lock); 3354 mutex_enter(wgp->wgp_lock);
3348 wgp->wgp_state = WGP_STATE_DESTROYING; 3355 wgp->wgp_state = WGP_STATE_DESTROYING;
3349 pserialize_perform(wgp->wgp_psz); 3356 pserialize_perform(wgp->wgp_psz);
3350 mutex_exit(wgp->wgp_lock); 3357 mutex_exit(wgp->wgp_lock);
3351 PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry); 3358 PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry);
3352 } 3359 }
3353 mutex_exit(wg->wg_lock); 3360 mutex_exit(wg->wg_lock);
3354 3361
3355 if (wgp == NULL) 3362 if (wgp == NULL)
3356 return ENOENT; 3363 return ENOENT;
3357 3364
3358 psref_target_destroy(&wgp->wgp_psref, wg_psref_class); 3365 psref_target_destroy(&wgp->wgp_psref, wg_psref_class);
3359 3366
3360 wg_destroy_peer(wgp); 3367 wg_destroy_peer(wgp);
3361 3368
3362 return 0; 3369 return 0;
3363} 3370}
3364 3371
3365static int 3372static int
3366wg_if_attach(struct wg_softc *wg) 3373wg_if_attach(struct wg_softc *wg)
3367{ 3374{
3368 int error; 3375 int error;
3369 3376
3370 wg->wg_if.if_addrlen = 0; 3377 wg->wg_if.if_addrlen = 0;
3371 wg->wg_if.if_mtu = WG_MTU; 3378 wg->wg_if.if_mtu = WG_MTU;
3372 wg->wg_if.if_flags = IFF_POINTOPOINT; 3379 wg->wg_if.if_flags = IFF_POINTOPOINT;
3373 wg->wg_if.if_extflags = IFEF_NO_LINK_STATE_CHANGE; 3380 wg->wg_if.if_extflags = IFEF_NO_LINK_STATE_CHANGE;
3374 wg->wg_if.if_extflags |= IFEF_MPSAFE; 3381 wg->wg_if.if_extflags |= IFEF_MPSAFE;
3375 wg->wg_if.if_ioctl = wg_ioctl; 3382 wg->wg_if.if_ioctl = wg_ioctl;
3376 wg->wg_if.if_output = wg_output; 3383 wg->wg_if.if_output = wg_output;
3377 wg->wg_if.if_init = wg_init; 3384 wg->wg_if.if_init = wg_init;
3378 wg->wg_if.if_stop = wg_stop; 3385 wg->wg_if.if_stop = wg_stop;
3379 wg->wg_if.if_type = IFT_OTHER; 3386 wg->wg_if.if_type = IFT_OTHER;
3380 wg->wg_if.if_dlt = DLT_NULL; 3387 wg->wg_if.if_dlt = DLT_NULL;
3381 wg->wg_if.if_softc = wg; 3388 wg->wg_if.if_softc = wg;
3382 IFQ_SET_READY(&wg->wg_if.if_snd); 3389 IFQ_SET_READY(&wg->wg_if.if_snd);
3383 3390
3384 error = if_initialize(&wg->wg_if); 3391 error = if_initialize(&wg->wg_if);
3385 if (error != 0) 3392 if (error != 0)
3386 return error; 3393 return error;
3387 3394
3388 if_alloc_sadl(&wg->wg_if); 3395 if_alloc_sadl(&wg->wg_if);
3389 if_register(&wg->wg_if); 3396 if_register(&wg->wg_if);
3390 3397
3391 bpf_attach(&wg->wg_if, DLT_NULL, sizeof(uint32_t)); 3398 bpf_attach(&wg->wg_if, DLT_NULL, sizeof(uint32_t));
3392 3399
3393 return 0; 3400 return 0;
3394} 3401}
3395 3402
3396static int 3403static int
3397wg_clone_create(struct if_clone *ifc, int unit) 3404wg_clone_create(struct if_clone *ifc, int unit)
3398{ 3405{
3399 struct wg_softc *wg; 3406 struct wg_softc *wg;
3400 int error; 3407 int error;
3401 3408
3402 wg = kmem_zalloc(sizeof(struct wg_softc), KM_SLEEP); 3409 wg = kmem_zalloc(sizeof(struct wg_softc), KM_SLEEP);
3403 3410
3404 if_initname(&wg->wg_if, ifc->ifc_name, unit); 3411 if_initname(&wg->wg_if, ifc->ifc_name, unit);
3405 3412
3406 error = wg_worker_init(wg); 3413 error = wg_worker_init(wg);
3407 if (error != 0) { 3414 if (error != 0) {
3408 kmem_free(wg, sizeof(struct wg_softc)); 3415 kmem_free(wg, sizeof(struct wg_softc));
3409 return error; 3416 return error;
3410 } 3417 }
3411 3418
3412 rn_inithead((void **)&wg->wg_rtable_ipv4, 3419 rn_inithead((void **)&wg->wg_rtable_ipv4,
3413 offsetof(struct sockaddr_in, sin_addr) * NBBY); 3420 offsetof(struct sockaddr_in, sin_addr) * NBBY);
3414#ifdef INET6 3421#ifdef INET6
3415 rn_inithead((void **)&wg->wg_rtable_ipv6, 3422 rn_inithead((void **)&wg->wg_rtable_ipv6,
3416 offsetof(struct sockaddr_in6, sin6_addr) * NBBY); 3423 offsetof(struct sockaddr_in6, sin6_addr) * NBBY);
3417#endif 3424#endif
3418 3425
3419 PSLIST_INIT(&wg->wg_peers); 3426 PSLIST_INIT(&wg->wg_peers);
3420 wg->wg_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 3427 wg->wg_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3421 wg->wg_rwlock = rw_obj_alloc(); 3428 wg->wg_rwlock = rw_obj_alloc();
3422 wg->wg_ops = &wg_ops_rumpkernel; 3429 wg->wg_ops = &wg_ops_rumpkernel;
3423 3430
3424 error = wg_if_attach(wg); 3431 error = wg_if_attach(wg);
3425 if (error != 0) { 3432 if (error != 0) {
3426 wg_worker_destroy(wg); 3433 wg_worker_destroy(wg);
3427 if (wg->wg_rtable_ipv4 != NULL) 3434 if (wg->wg_rtable_ipv4 != NULL)
3428 free(wg->wg_rtable_ipv4, M_RTABLE); 3435 free(wg->wg_rtable_ipv4, M_RTABLE);
3429 if (wg->wg_rtable_ipv6 != NULL) 3436 if (wg->wg_rtable_ipv6 != NULL)
3430 free(wg->wg_rtable_ipv6, M_RTABLE); 3437 free(wg->wg_rtable_ipv6, M_RTABLE);
3431 PSLIST_DESTROY(&wg->wg_peers); 3438 PSLIST_DESTROY(&wg->wg_peers);
3432 mutex_obj_free(wg->wg_lock); 3439 mutex_obj_free(wg->wg_lock);
3433 kmem_free(wg, sizeof(struct wg_softc)); 3440 kmem_free(wg, sizeof(struct wg_softc));
3434 return error; 3441 return error;
3435 } 3442 }
3436 3443
3437 mutex_enter(&wg_softcs.lock); 3444 mutex_enter(&wg_softcs.lock);
3438 LIST_INSERT_HEAD(&wg_softcs.list, wg, wg_list); 3445 LIST_INSERT_HEAD(&wg_softcs.list, wg, wg_list);
3439 mutex_exit(&wg_softcs.lock); 3446 mutex_exit(&wg_softcs.lock);
3440 3447
3441 return 0; 3448 return 0;
3442} 3449}
3443 3450
3444static int 3451static int
3445wg_clone_destroy(struct ifnet *ifp) 3452wg_clone_destroy(struct ifnet *ifp)
3446{ 3453{
3447 struct wg_softc *wg = container_of(ifp, struct wg_softc, wg_if); 3454 struct wg_softc *wg = container_of(ifp, struct wg_softc, wg_if);
3448 3455
3449 mutex_enter(&wg_softcs.lock); 3456 mutex_enter(&wg_softcs.lock);
3450 LIST_REMOVE(wg, wg_list); 3457 LIST_REMOVE(wg, wg_list);
3451 mutex_exit(&wg_softcs.lock); 3458 mutex_exit(&wg_softcs.lock);
3452 3459
3453#ifdef WG_RUMPKERNEL 3460#ifdef WG_RUMPKERNEL
3454 if (wg_user_mode(wg)) { 3461 if (wg_user_mode(wg)) {
3455 rumpuser_wg_destroy(wg->wg_user); 3462 rumpuser_wg_destroy(wg->wg_user);
3456 wg->wg_user = NULL; 3463 wg->wg_user = NULL;
3457 } 3464 }
3458#endif 3465#endif
3459 3466
3460 bpf_detach(ifp); 3467 bpf_detach(ifp);
3461 if_detach(ifp); 3468 if_detach(ifp);
3462 wg_worker_destroy(wg); 3469 wg_worker_destroy(wg);
3463 wg_destroy_all_peers(wg); 3470 wg_destroy_all_peers(wg);
3464 if (wg->wg_rtable_ipv4 != NULL) 3471 if (wg->wg_rtable_ipv4 != NULL)
3465 free(wg->wg_rtable_ipv4, M_RTABLE); 3472 free(wg->wg_rtable_ipv4, M_RTABLE);
3466 if (wg->wg_rtable_ipv6 != NULL) 3473 if (wg->wg_rtable_ipv6 != NULL)
3467 free(wg->wg_rtable_ipv6, M_RTABLE); 3474 free(wg->wg_rtable_ipv6, M_RTABLE);
3468 3475
3469 PSLIST_DESTROY(&wg->wg_peers); 3476 PSLIST_DESTROY(&wg->wg_peers);
3470 mutex_obj_free(wg->wg_lock); 3477 mutex_obj_free(wg->wg_lock);
3471 rw_obj_free(wg->wg_rwlock); 3478 rw_obj_free(wg->wg_rwlock);
3472 3479
3473 kmem_free(wg, sizeof(struct wg_softc)); 3480 kmem_free(wg, sizeof(struct wg_softc));
3474 3481
3475 return 0; 3482 return 0;
3476} 3483}
3477 3484
3478static struct wg_peer * 3485static struct wg_peer *
3479wg_pick_peer_by_sa(struct wg_softc *wg, const struct sockaddr *sa, 3486wg_pick_peer_by_sa(struct wg_softc *wg, const struct sockaddr *sa,
3480 struct psref *psref) 3487 struct psref *psref)
3481{ 3488{
3482 struct radix_node_head *rnh; 3489 struct radix_node_head *rnh;
3483 struct radix_node *rn; 3490 struct radix_node *rn;
3484 struct wg_peer *wgp = NULL; 3491 struct wg_peer *wgp = NULL;
3485 struct wg_allowedip *wga; 3492 struct wg_allowedip *wga;
3486 3493
3487#ifdef WG_DEBUG_LOG 3494#ifdef WG_DEBUG_LOG
3488 char addrstr[128]; 3495 char addrstr[128];
3489 sockaddr_format(sa, addrstr, sizeof(addrstr)); 3496 sockaddr_format(sa, addrstr, sizeof(addrstr));
3490 WG_DLOG("sa=%s\n", addrstr); 3497 WG_DLOG("sa=%s\n", addrstr);
3491#endif 3498#endif
3492 3499
3493 rw_enter(wg->wg_rwlock, RW_READER); 3500 rw_enter(wg->wg_rwlock, RW_READER);
3494 3501
3495 rnh = wg_rnh(wg, sa->sa_family); 3502 rnh = wg_rnh(wg, sa->sa_family);
3496 if (rnh == NULL) 3503 if (rnh == NULL)
3497 goto out; 3504 goto out;
3498 3505
3499 rn = rnh->rnh_matchaddr(sa, rnh); 3506 rn = rnh->rnh_matchaddr(sa, rnh);
3500 if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0) 3507 if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0)
3501 goto out; 3508 goto out;
3502 3509
3503 WG_TRACE("success"); 3510 WG_TRACE("success");
3504 3511
3505 wga = container_of(rn, struct wg_allowedip, wga_nodes[0]); 3512 wga = container_of(rn, struct wg_allowedip, wga_nodes[0]);
3506 wgp = wga->wga_peer; 3513 wgp = wga->wga_peer;
3507 wg_get_peer(wgp, psref); 3514 wg_get_peer(wgp, psref);
3508 3515
3509out: 3516out:
3510 rw_exit(wg->wg_rwlock); 3517 rw_exit(wg->wg_rwlock);
3511 return wgp; 3518 return wgp;
3512} 3519}
3513 3520
3514static void 3521static void
3515wg_fill_msg_data(struct wg_softc *wg, struct wg_peer *wgp, 3522wg_fill_msg_data(struct wg_softc *wg, struct wg_peer *wgp,
3516 struct wg_session *wgs, struct wg_msg_data *wgmd) 3523 struct wg_session *wgs, struct wg_msg_data *wgmd)
3517{ 3524{
3518 3525
3519 memset(wgmd, 0, sizeof(*wgmd)); 3526 memset(wgmd, 0, sizeof(*wgmd));
3520 wgmd->wgmd_type = WG_MSG_TYPE_DATA; 3527 wgmd->wgmd_type = WG_MSG_TYPE_DATA;
3521 wgmd->wgmd_receiver = wgs->wgs_receiver_index; 3528 wgmd->wgmd_receiver = wgs->wgs_receiver_index;
3522 /* [W] 5.4.6: msg.counter := Nm^send */ 3529 /* [W] 5.4.6: msg.counter := Nm^send */
3523 /* [W] 5.4.6: Nm^send := Nm^send + 1 */ 3530 /* [W] 5.4.6: Nm^send := Nm^send + 1 */
3524 wgmd->wgmd_counter = wg_session_inc_send_counter(wgs); 3531 wgmd->wgmd_counter = wg_session_inc_send_counter(wgs);
3525 WG_DLOG("counter=%"PRIu64"\n", wgmd->wgmd_counter); 3532 WG_DLOG("counter=%"PRIu64"\n", wgmd->wgmd_counter);
3526} 3533}
3527 3534
3528static int 3535static int
3529wg_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 3536wg_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
3530 const struct rtentry *rt) 3537 const struct rtentry *rt)
3531{ 3538{
3532 struct wg_softc *wg = ifp->if_softc; 3539 struct wg_softc *wg = ifp->if_softc;
3533 int error = 0; 3540 int error = 0;
3534 int bound; 3541 int bound;
3535 struct psref psref; 3542 struct psref psref;
3536 3543
3537 /* TODO make the nest limit configurable via sysctl */ 3544 /* TODO make the nest limit configurable via sysctl */
3538 error = if_tunnel_check_nesting(ifp, m, 1); 3545 error = if_tunnel_check_nesting(ifp, m, 1);
3539 if (error != 0) { 3546 if (error != 0) {
3540 m_freem(m); 3547 m_freem(m);
3541 WGLOG(LOG_ERR, "tunneling loop detected and packet dropped\n"); 3548 WGLOG(LOG_ERR, "tunneling loop detected and packet dropped\n");
3542 return error; 3549 return error;
3543 } 3550 }
3544 3551
3545 bound = curlwp_bind(); 3552 bound = curlwp_bind();
3546 3553
3547 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family); 3554 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family);
3548 3555
3549 bpf_mtap_af(ifp, dst->sa_family, m, BPF_D_OUT); 3556 bpf_mtap_af(ifp, dst->sa_family, m, BPF_D_OUT);
3550 3557
3551 m->m_flags &= ~(M_BCAST|M_MCAST); 3558 m->m_flags &= ~(M_BCAST|M_MCAST);
3552 3559
3553 struct wg_peer *wgp = wg_pick_peer_by_sa(wg, dst, &psref); 3560 struct wg_peer *wgp = wg_pick_peer_by_sa(wg, dst, &psref);
3554 if (wgp == NULL) { 3561 if (wgp == NULL) {
3555 WG_TRACE("peer not found"); 3562 WG_TRACE("peer not found");
3556 error = EHOSTUNREACH; 3563 error = EHOSTUNREACH;
3557 goto error; 3564 goto error;
3558 } 3565 }
3559 3566
3560 /* Clear checksum-offload flags. */ 3567 /* Clear checksum-offload flags. */
3561 m->m_pkthdr.csum_flags = 0; 3568 m->m_pkthdr.csum_flags = 0;
3562 m->m_pkthdr.csum_data = 0; 3569 m->m_pkthdr.csum_data = 0;
3563 3570
3564 if (!pcq_put(wgp->wgp_q, m)) { 3571 if (!pcq_put(wgp->wgp_q, m)) {
3565 error = ENOBUFS; 3572 error = ENOBUFS;
3566 goto error; 3573 goto error;
3567 } 3574 }
3568 3575
3569 struct psref psref_wgs; 3576 struct psref psref_wgs;
3570 struct wg_session *wgs; 3577 struct wg_session *wgs;
3571 wgs = wg_get_stable_session(wgp, &psref_wgs); 3578 wgs = wg_get_stable_session(wgp, &psref_wgs);
3572 if (wgs->wgs_state == WGS_STATE_ESTABLISHED && 3579 if (wgs->wgs_state == WGS_STATE_ESTABLISHED &&
3573 !wg_session_hit_limits(wgs)) { 3580 !wg_session_hit_limits(wgs)) {
3574 kpreempt_disable(); 3581 kpreempt_disable();
3575 softint_schedule(wgp->wgp_si); 3582 softint_schedule(wgp->wgp_si);
3576 kpreempt_enable(); 3583 kpreempt_enable();
3577 WG_TRACE("softint scheduled"); 3584 WG_TRACE("softint scheduled");
3578 } else { 3585 } else {
3579 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 3586 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3580 WG_TRACE("softint NOT scheduled"); 3587 WG_TRACE("softint NOT scheduled");
3581 } 3588 }
3582 wg_put_session(wgs, &psref_wgs); 3589 wg_put_session(wgs, &psref_wgs);
3583 wg_put_peer(wgp, &psref); 3590 wg_put_peer(wgp, &psref);
3584 3591
3585 return 0; 3592 return 0;
3586 3593
3587error: 3594error:
3588 if (wgp != NULL) 3595 if (wgp != NULL)
3589 wg_put_peer(wgp, &psref); 3596 wg_put_peer(wgp, &psref);
3590 if (m != NULL) 3597 if (m != NULL)
3591 m_freem(m); 3598 m_freem(m);
3592 curlwp_bindx(bound); 3599 curlwp_bindx(bound);
3593 return error; 3600 return error;
3594} 3601}
3595 3602
3596static int 3603static int
3597wg_send_udp(struct wg_peer *wgp, struct mbuf *m) 3604wg_send_udp(struct wg_peer *wgp, struct mbuf *m)
3598{ 3605{
3599 struct psref psref; 3606 struct psref psref;
3600 struct wg_sockaddr *wgsa; 3607 struct wg_sockaddr *wgsa;
3601 int error; 3608 int error;
3602 struct socket *so = wg_get_so_by_peer(wgp); 3609 struct socket *so = wg_get_so_by_peer(wgp);
3603 3610
3604 solock(so); 3611 solock(so);
3605 wgsa = wg_get_endpoint_sa(wgp, &psref); 3612 wgsa = wg_get_endpoint_sa(wgp, &psref);
3606 if (wgsatosa(wgsa)->sa_family == AF_INET) { 3613 if (wgsatosa(wgsa)->sa_family == AF_INET) {
3607 error = udp_send(so, m, wgsatosa(wgsa), NULL, curlwp); 3614 error = udp_send(so, m, wgsatosa(wgsa), NULL, curlwp);
3608 } else { 3615 } else {
3609#ifdef INET6 3616#ifdef INET6
3610 error = udp6_output(sotoin6pcb(so), m, wgsatosin6(wgsa), 3617 error = udp6_output(sotoin6pcb(so), m, wgsatosin6(wgsa),
3611 NULL, curlwp); 3618 NULL, curlwp);
3612#else 3619#else
3613 error = EPROTONOSUPPORT; 3620 error = EPROTONOSUPPORT;
3614#endif 3621#endif
3615 } 3622 }
3616 wg_put_sa(wgp, wgsa, &psref); 3623 wg_put_sa(wgp, wgsa, &psref);
3617 sounlock(so); 3624 sounlock(so);
3618 3625
3619 return error; 3626 return error;
3620} 3627}
3621 3628
3622/* Inspired by pppoe_get_mbuf */ 3629/* Inspired by pppoe_get_mbuf */
3623static struct mbuf * 3630static struct mbuf *
3624wg_get_mbuf(size_t leading_len, size_t len) 3631wg_get_mbuf(size_t leading_len, size_t len)
3625{ 3632{
3626 struct mbuf *m; 3633 struct mbuf *m;
3627 3634
3628 m = m_gethdr(M_DONTWAIT, MT_DATA); 3635 m = m_gethdr(M_DONTWAIT, MT_DATA);
3629 if (m == NULL) 3636 if (m == NULL)
3630 return NULL; 3637 return NULL;
3631 if (len + leading_len > MHLEN) { 3638 if (len + leading_len > MHLEN) {
3632 m_clget(m, M_DONTWAIT); 3639 m_clget(m, M_DONTWAIT);
3633 if ((m->m_flags & M_EXT) == 0) { 3640 if ((m->m_flags & M_EXT) == 0) {
3634 m_free(m); 3641 m_free(m);
3635 return NULL; 3642 return NULL;
3636 } 3643 }
3637 } 3644 }
3638 m->m_data += leading_len; 3645 m->m_data += leading_len;
3639 m->m_pkthdr.len = m->m_len = len; 3646 m->m_pkthdr.len = m->m_len = len;
3640 3647
3641 return m; 3648 return m;
3642} 3649}
3643 3650
3644static int 3651static int
3645wg_send_data_msg(struct wg_peer *wgp, struct wg_session *wgs, 3652wg_send_data_msg(struct wg_peer *wgp, struct wg_session *wgs,
3646 struct mbuf *m) 3653 struct mbuf *m)
3647{ 3654{
3648 struct wg_softc *wg = wgp->wgp_sc; 3655 struct wg_softc *wg = wgp->wgp_sc;
3649 int error; 3656 int error;
3650 size_t inner_len, padded_len, encrypted_len; 3657 size_t inner_len, padded_len, encrypted_len;
3651 char *padded_buf = NULL; 3658 char *padded_buf = NULL;
3652 size_t mlen; 3659 size_t mlen;
3653 struct wg_msg_data *wgmd; 3660 struct wg_msg_data *wgmd;
3654 bool free_padded_buf = false; 3661 bool free_padded_buf = false;
3655 struct mbuf *n; 3662 struct mbuf *n;
3656 size_t leading_len = max_linkhdr + sizeof(struct ip6_hdr) + 3663 size_t leading_len = max_linkhdr + sizeof(struct ip6_hdr) +
3657 sizeof(struct udphdr); 3664 sizeof(struct udphdr);
3658 3665
3659 mlen = m_length(m); 3666 mlen = m_length(m);
3660 inner_len = mlen; 3667 inner_len = mlen;
3661 padded_len = roundup(mlen, 16); 3668 padded_len = roundup(mlen, 16);
3662 encrypted_len = padded_len + WG_AUTHTAG_LEN; 3669 encrypted_len = padded_len + WG_AUTHTAG_LEN;
3663 WG_DLOG("inner=%lu, padded=%lu, encrypted_len=%lu\n", 3670 WG_DLOG("inner=%lu, padded=%lu, encrypted_len=%lu\n",
3664 inner_len, padded_len, encrypted_len); 3671 inner_len, padded_len, encrypted_len);
3665 if (mlen != 0) { 3672 if (mlen != 0) {
3666 bool success; 3673 bool success;
3667 success = m_ensure_contig(&m, padded_len); 3674 success = m_ensure_contig(&m, padded_len);
3668 if (success) { 3675 if (success) {
3669 padded_buf = mtod(m, char *); 3676 padded_buf = mtod(m, char *);
3670 } else { 3677 } else {
3671 padded_buf = kmem_intr_alloc(padded_len, KM_NOSLEEP); 3678 padded_buf = kmem_intr_alloc(padded_len, KM_NOSLEEP);
3672 if (padded_buf == NULL) { 3679 if (padded_buf == NULL) {
3673 error = ENOBUFS; 3680 error = ENOBUFS;
3674 goto end; 3681 goto end;
3675 } 3682 }
3676 free_padded_buf = true; 3683 free_padded_buf = true;
3677 m_copydata(m, 0, mlen, padded_buf); 3684 m_copydata(m, 0, mlen, padded_buf);
3678 } 3685 }
3679 memset(padded_buf + mlen, 0, padded_len - inner_len); 3686 memset(padded_buf + mlen, 0, padded_len - inner_len);
3680 } 3687 }
3681 3688
3682 n = wg_get_mbuf(leading_len, sizeof(*wgmd) + encrypted_len); 3689 n = wg_get_mbuf(leading_len, sizeof(*wgmd) + encrypted_len);
3683 if (n == NULL) { 3690 if (n == NULL) {
3684 error = ENOBUFS; 3691 error = ENOBUFS;
3685 goto end; 3692 goto end;
3686 } 3693 }
3687 KASSERT(n->m_len >= sizeof(*wgmd)); 3694 KASSERT(n->m_len >= sizeof(*wgmd));
3688 wgmd = mtod(n, struct wg_msg_data *); 3695 wgmd = mtod(n, struct wg_msg_data *);
3689 wg_fill_msg_data(wg, wgp, wgs, wgmd); 3696 wg_fill_msg_data(wg, wgp, wgs, wgmd);
3690 /* [W] 5.4.6: AEAD(Tm^send, Nm^send, P, e) */ 3697 /* [W] 5.4.6: AEAD(Tm^send, Nm^send, P, e) */
3691 wg_algo_aead_enc((char *)wgmd + sizeof(*wgmd), encrypted_len, 3698 wg_algo_aead_enc((char *)wgmd + sizeof(*wgmd), encrypted_len,
3692 wgs->wgs_tkey_send, wgmd->wgmd_counter, padded_buf, padded_len, 3699 wgs->wgs_tkey_send, wgmd->wgmd_counter, padded_buf, padded_len,
3693 NULL, 0); 3700 NULL, 0);
3694 3701
3695 error = wg->wg_ops->send_data_msg(wgp, n); 3702 error = wg->wg_ops->send_data_msg(wgp, n);
3696 if (error == 0) { 3703 if (error == 0) {
3697 struct ifnet *ifp = &wg->wg_if; 3704 struct ifnet *ifp = &wg->wg_if;
3698 if_statadd(ifp, if_obytes, mlen); 3705 if_statadd(ifp, if_obytes, mlen);
3699 if_statinc(ifp, if_opackets); 3706 if_statinc(ifp, if_opackets);
3700 if (wgs->wgs_is_initiator && 3707 if (wgs->wgs_is_initiator &&
3701 wgs->wgs_time_last_data_sent == 0) { 3708 wgs->wgs_time_last_data_sent == 0) {
3702 /* 3709 /*
3703 * [W] 6.2 Transport Message Limits 3710 * [W] 6.2 Transport Message Limits
3704 * "if a peer is the initiator of a current secure 3711 * "if a peer is the initiator of a current secure
3705 * session, WireGuard will send a handshake initiation 3712 * session, WireGuard will send a handshake initiation
3706 * message to begin a new secure session if, after 3713 * message to begin a new secure session if, after
3707 * transmitting a transport data message, the current 3714 * transmitting a transport data message, the current
3708 * secure session is REKEY-AFTER-TIME seconds old," 3715 * secure session is REKEY-AFTER-TIME seconds old,"
3709 */ 3716 */
3710 wg_schedule_rekey_timer(wgp); 3717 wg_schedule_rekey_timer(wgp);
3711 } 3718 }
3712 wgs->wgs_time_last_data_sent = time_uptime; 3719 wgs->wgs_time_last_data_sent = time_uptime;
3713 if (wg_session_get_send_counter(wgs) >= 3720 if (wg_session_get_send_counter(wgs) >=
3714 wg_rekey_after_messages) { 3721 wg_rekey_after_messages) {
3715 /* 3722 /*
3716 * [W] 6.2 Transport Message Limits 3723 * [W] 6.2 Transport Message Limits
3717 * "WireGuard will try to create a new session, by 3724 * "WireGuard will try to create a new session, by
3718 * sending a handshake initiation message (section 3725 * sending a handshake initiation message (section
3719 * 5.4.2), after it has sent REKEY-AFTER-MESSAGES 3726 * 5.4.2), after it has sent REKEY-AFTER-MESSAGES
3720 * transport data messages..." 3727 * transport data messages..."
3721 */ 3728 */
3722 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 3729 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3723 } 3730 }
3724 } 3731 }
3725end: 3732end:
3726 m_freem(m); 3733 m_freem(m);
3727 if (free_padded_buf) 3734 if (free_padded_buf)
3728 kmem_intr_free(padded_buf, padded_len); 3735 kmem_intr_free(padded_buf, padded_len);
3729 return error; 3736 return error;
3730} 3737}
3731 3738
3732static void 3739static void
3733wg_input(struct ifnet *ifp, struct mbuf *m, const int af) 3740wg_input(struct ifnet *ifp, struct mbuf *m, const int af)
3734{ 3741{
3735 pktqueue_t *pktq; 3742 pktqueue_t *pktq;
3736 size_t pktlen; 3743 size_t pktlen;
3737 3744
3738 KASSERT(af == AF_INET || af == AF_INET6); 3745 KASSERT(af == AF_INET || af == AF_INET6);
3739 3746
3740 WG_TRACE(""); 3747 WG_TRACE("");
3741 3748
3742 m_set_rcvif(m, ifp); 3749 m_set_rcvif(m, ifp);
3743 pktlen = m->m_pkthdr.len; 3750 pktlen = m->m_pkthdr.len;
3744 3751
3745 bpf_mtap_af(ifp, af, m, BPF_D_IN); 3752 bpf_mtap_af(ifp, af, m, BPF_D_IN);
3746 3753
3747 switch (af) { 3754 switch (af) {
3748 case AF_INET: 3755 case AF_INET:
3749 pktq = ip_pktq; 3756 pktq = ip_pktq;
3750 break; 3757 break;
3751#ifdef INET6 3758#ifdef INET6
3752 case AF_INET6: 3759 case AF_INET6:
3753 pktq = ip6_pktq; 3760 pktq = ip6_pktq;
3754 break; 3761 break;
3755#endif 3762#endif
3756 default: 3763 default:
3757 panic("invalid af=%d", af); 3764 panic("invalid af=%d", af);
3758 } 3765 }
3759 3766
3760 const u_int h = curcpu()->ci_index; 3767 const u_int h = curcpu()->ci_index;
3761 if (__predict_true(pktq_enqueue(pktq, m, h))) { 3768 if (__predict_true(pktq_enqueue(pktq, m, h))) {
3762 if_statadd(ifp, if_ibytes, pktlen); 3769 if_statadd(ifp, if_ibytes, pktlen);
3763 if_statinc(ifp, if_ipackets); 3770 if_statinc(ifp, if_ipackets);
3764 } else { 3771 } else {
3765 m_freem(m); 3772 m_freem(m);
3766 } 3773 }
3767} 3774}
3768 3775
3769static void 3776static void
3770wg_calc_pubkey(uint8_t pubkey[WG_STATIC_KEY_LEN], 3777wg_calc_pubkey(uint8_t pubkey[WG_STATIC_KEY_LEN],
3771 const uint8_t privkey[WG_STATIC_KEY_LEN]) 3778 const uint8_t privkey[WG_STATIC_KEY_LEN])
3772{ 3779{
3773 3780
3774 crypto_scalarmult_base(pubkey, privkey); 3781 crypto_scalarmult_base(pubkey, privkey);
3775} 3782}
3776 3783
3777static int 3784static int
3778wg_rtable_add_route(struct wg_softc *wg, struct wg_allowedip *wga) 3785wg_rtable_add_route(struct wg_softc *wg, struct wg_allowedip *wga)
3779{ 3786{
3780 struct radix_node_head *rnh; 3787 struct radix_node_head *rnh;
3781 struct radix_node *rn; 3788 struct radix_node *rn;
3782 int error = 0; 3789 int error = 0;
3783 3790
3784 rw_enter(wg->wg_rwlock, RW_WRITER); 3791 rw_enter(wg->wg_rwlock, RW_WRITER);
3785 rnh = wg_rnh(wg, wga->wga_family); 3792 rnh = wg_rnh(wg, wga->wga_family);
3786 KASSERT(rnh != NULL); 3793 KASSERT(rnh != NULL);
3787 rn = rnh->rnh_addaddr(&wga->wga_sa_addr, &wga->wga_sa_mask, rnh, 3794 rn = rnh->rnh_addaddr(&wga->wga_sa_addr, &wga->wga_sa_mask, rnh,
3788 wga->wga_nodes); 3795 wga->wga_nodes);
3789 rw_exit(wg->wg_rwlock); 3796 rw_exit(wg->wg_rwlock);
3790 3797
3791 if (rn == NULL) 3798 if (rn == NULL)
3792 error = EEXIST; 3799 error = EEXIST;
3793 3800
3794 return error; 3801 return error;
3795} 3802}
3796 3803
3797static int 3804static int
3798wg_handle_prop_peer(struct wg_softc *wg, prop_dictionary_t peer, 3805wg_handle_prop_peer(struct wg_softc *wg, prop_dictionary_t peer,
3799 struct wg_peer **wgpp) 3806 struct wg_peer **wgpp)
3800{ 3807{
3801 int error = 0; 3808 int error = 0;
3802 const void *pubkey; 3809 const void *pubkey;
3803 size_t pubkey_len; 3810 size_t pubkey_len;
3804 const void *psk; 3811 const void *psk;
3805 size_t psk_len; 3812 size_t psk_len;
3806 const char *name = NULL; 3813 const char *name = NULL;
3807 3814
3808 if (prop_dictionary_get_string(peer, "name", &name)) { 3815 if (prop_dictionary_get_string(peer, "name", &name)) {
3809 if (strlen(name) > WG_PEER_NAME_MAXLEN) { 3816 if (strlen(name) > WG_PEER_NAME_MAXLEN) {
3810 error = EINVAL; 3817 error = EINVAL;
3811 goto out; 3818 goto out;
3812 } 3819 }
3813 } 3820 }
3814 3821
3815 if (!prop_dictionary_get_data(peer, "public_key", 3822 if (!prop_dictionary_get_data(peer, "public_key",
3816 &pubkey, &pubkey_len)) { 3823 &pubkey, &pubkey_len)) {
3817 error = EINVAL; 3824 error = EINVAL;
3818 goto out; 3825 goto out;
3819 } 3826 }
3820#ifdef WG_DEBUG_DUMP 3827#ifdef WG_DEBUG_DUMP
3821 log(LOG_DEBUG, "pubkey=%p, pubkey_len=%lu\n", pubkey, pubkey_len); 3828 log(LOG_DEBUG, "pubkey=%p, pubkey_len=%lu\n", pubkey, pubkey_len);
3822 for (int _i = 0; _i < pubkey_len; _i++) 3829 for (int _i = 0; _i < pubkey_len; _i++)
3823 log(LOG_DEBUG, "%c", ((const char *)pubkey)[_i]); 3830 log(LOG_DEBUG, "%c", ((const char *)pubkey)[_i]);
3824 log(LOG_DEBUG, "\n"); 3831 log(LOG_DEBUG, "\n");
3825#endif 3832#endif
3826 3833
3827 struct wg_peer *wgp = wg_alloc_peer(wg); 3834 struct wg_peer *wgp = wg_alloc_peer(wg);
3828 memcpy(wgp->wgp_pubkey, pubkey, sizeof(wgp->wgp_pubkey)); 3835 memcpy(wgp->wgp_pubkey, pubkey, sizeof(wgp->wgp_pubkey));
3829 if (name != NULL) 3836 if (name != NULL)
3830 strncpy(wgp->wgp_name, name, sizeof(wgp->wgp_name)); 3837 strncpy(wgp->wgp_name, name, sizeof(wgp->wgp_name));
3831 3838
3832 if (prop_dictionary_get_data(peer, "preshared_key", &psk, &psk_len)) { 3839 if (prop_dictionary_get_data(peer, "preshared_key", &psk, &psk_len)) {
3833 if (psk_len != sizeof(wgp->wgp_psk)) { 3840 if (psk_len != sizeof(wgp->wgp_psk)) {
3834 error = EINVAL; 3841 error = EINVAL;
3835 goto out; 3842 goto out;
3836 } 3843 }
3837 memcpy(wgp->wgp_psk, psk, sizeof(wgp->wgp_psk)); 3844 memcpy(wgp->wgp_psk, psk, sizeof(wgp->wgp_psk));
3838 } 3845 }
3839 3846
3840 struct sockaddr_storage sockaddr; 3847 struct sockaddr_storage sockaddr;
3841 const void *addr; 3848 const void *addr;
3842 size_t addr_len; 3849 size_t addr_len;
3843 3850
3844 if (!prop_dictionary_get_data(peer, "endpoint", &addr, &addr_len)) 3851 if (!prop_dictionary_get_data(peer, "endpoint", &addr, &addr_len))
3845 goto skip_endpoint; 3852 goto skip_endpoint;
3846 memcpy(&sockaddr, addr, addr_len); 3853 memcpy(&sockaddr, addr, addr_len);
3847 switch (sockaddr.ss_family) { 3854 switch (sockaddr.ss_family) {
3848 case AF_INET: { 3855 case AF_INET: {
3849 struct sockaddr_in sin; 3856 struct sockaddr_in sin;
3850 sockaddr_copy(sintosa(&sin), sizeof(sin), 3857 sockaddr_copy(sintosa(&sin), sizeof(sin),
3851 (const struct sockaddr *)&sockaddr); 3858 (const struct sockaddr *)&sockaddr);
3852 sockaddr_copy(sintosa(&wgp->wgp_sin), 3859 sockaddr_copy(sintosa(&wgp->wgp_sin),
3853 sizeof(wgp->wgp_sin), (const struct sockaddr *)&sockaddr); 3860 sizeof(wgp->wgp_sin), (const struct sockaddr *)&sockaddr);
3854 char addrstr[128]; 3861 char addrstr[128];
3855 sockaddr_format(sintosa(&sin), addrstr, sizeof(addrstr)); 3862 sockaddr_format(sintosa(&sin), addrstr, sizeof(addrstr));
3856 WG_DLOG("addr=%s\n", addrstr); 3863 WG_DLOG("addr=%s\n", addrstr);
3857 break; 3864 break;
3858 } 3865 }
3859#ifdef INET6 3866#ifdef INET6
3860 case AF_INET6: { 3867 case AF_INET6: {
3861 struct sockaddr_in6 sin6; 3868 struct sockaddr_in6 sin6;
3862 char addrstr[128]; 3869 char addrstr[128];
3863 sockaddr_copy(sintosa(&sin6), sizeof(sin6), 3870 sockaddr_copy(sintosa(&sin6), sizeof(sin6),
3864 (const struct sockaddr *)&sockaddr); 3871 (const struct sockaddr *)&sockaddr);
3865 sockaddr_format(sintosa(&sin6), addrstr, sizeof(addrstr)); 3872 sockaddr_format(sintosa(&sin6), addrstr, sizeof(addrstr));
3866 WG_DLOG("addr=%s\n", addrstr); 3873 WG_DLOG("addr=%s\n", addrstr);
3867 sockaddr_copy(sin6tosa(&wgp->wgp_sin6), 3874 sockaddr_copy(sin6tosa(&wgp->wgp_sin6),
3868 sizeof(wgp->wgp_sin6), (const struct sockaddr *)&sockaddr); 3875 sizeof(wgp->wgp_sin6), (const struct sockaddr *)&sockaddr);
3869 break; 3876 break;
3870 } 3877 }
3871#endif 3878#endif
3872 default: 3879 default:
3873 break; 3880 break;
3874 } 3881 }
3875 wgp->wgp_endpoint_available = true; 3882 wgp->wgp_endpoint_available = true;
3876 3883
3877 prop_array_t allowedips; 3884 prop_array_t allowedips;
3878skip_endpoint: 3885skip_endpoint:
3879 allowedips = prop_dictionary_get(peer, "allowedips"); 3886 allowedips = prop_dictionary_get(peer, "allowedips");
3880 if (allowedips == NULL) 3887 if (allowedips == NULL)
3881 goto skip; 3888 goto skip;
3882 3889
3883 prop_object_iterator_t _it = prop_array_iterator(allowedips); 3890 prop_object_iterator_t _it = prop_array_iterator(allowedips);
3884 prop_dictionary_t prop_allowedip; 3891 prop_dictionary_t prop_allowedip;
3885 int j = 0; 3892 int j = 0;
3886 while ((prop_allowedip = prop_object_iterator_next(_it)) != NULL) { 3893 while ((prop_allowedip = prop_object_iterator_next(_it)) != NULL) {
3887 struct wg_allowedip *wga = &wgp->wgp_allowedips[j]; 3894 struct wg_allowedip *wga = &wgp->wgp_allowedips[j];
3888 3895
3889 if (!prop_dictionary_get_int(prop_allowedip, "family", 3896 if (!prop_dictionary_get_int(prop_allowedip, "family",
3890 &wga->wga_family)) 3897 &wga->wga_family))
3891 continue; 3898 continue;
3892 if (!prop_dictionary_get_data(prop_allowedip, "ip", 3899 if (!prop_dictionary_get_data(prop_allowedip, "ip",
3893 &addr, &addr_len)) 3900 &addr, &addr_len))
3894 continue; 3901 continue;
3895 if (!prop_dictionary_get_uint8(prop_allowedip, "cidr", 3902 if (!prop_dictionary_get_uint8(prop_allowedip, "cidr",
3896 &wga->wga_cidr)) 3903 &wga->wga_cidr))
3897 continue; 3904 continue;
3898 3905
3899 switch (wga->wga_family) { 3906 switch (wga->wga_family) {
3900 case AF_INET: { 3907 case AF_INET: {
3901 struct sockaddr_in sin; 3908 struct sockaddr_in sin;
3902 char addrstr[128]; 3909 char addrstr[128];
3903 struct in_addr mask; 3910 struct in_addr mask;
3904 struct sockaddr_in sin_mask; 3911 struct sockaddr_in sin_mask;
3905 3912
3906 if (addr_len != sizeof(struct in_addr)) 3913 if (addr_len != sizeof(struct in_addr))
3907 return EINVAL; 3914 return EINVAL;
3908 memcpy(&wga->wga_addr4, addr, addr_len); 3915 memcpy(&wga->wga_addr4, addr, addr_len);
3909 3916
3910 sockaddr_in_init(&sin, (const struct in_addr *)addr, 3917 sockaddr_in_init(&sin, (const struct in_addr *)addr,
3911 0); 3918 0);
3912 sockaddr_copy(&wga->wga_sa_addr, 3919 sockaddr_copy(&wga->wga_sa_addr,
3913 sizeof(sin), sintosa(&sin)); 3920 sizeof(sin), sintosa(&sin));
3914 3921
3915 sockaddr_format(sintosa(&sin), 3922 sockaddr_format(sintosa(&sin),
3916 addrstr, sizeof(addrstr)); 3923 addrstr, sizeof(addrstr));
3917 WG_DLOG("addr=%s/%d\n", addrstr, wga->wga_cidr); 3924 WG_DLOG("addr=%s/%d\n", addrstr, wga->wga_cidr);
3918 3925
3919 in_len2mask(&mask, wga->wga_cidr); 3926 in_len2mask(&mask, wga->wga_cidr);
3920 sockaddr_in_init(&sin_mask, &mask, 0); 3927 sockaddr_in_init(&sin_mask, &mask, 0);
3921 sockaddr_copy(&wga->wga_sa_mask, 3928 sockaddr_copy(&wga->wga_sa_mask,
3922 sizeof(sin_mask), sintosa(&sin_mask)); 3929 sizeof(sin_mask), sintosa(&sin_mask));
3923 3930
3924 break; 3931 break;
3925 } 3932 }
3926#ifdef INET6 3933#ifdef INET6
3927 case AF_INET6: { 3934 case AF_INET6: {
3928 struct sockaddr_in6 sin6; 3935 struct sockaddr_in6 sin6;
3929 char addrstr[128]; 3936 char addrstr[128];
3930 struct in6_addr mask; 3937 struct in6_addr mask;
3931 struct sockaddr_in6 sin6_mask; 3938 struct sockaddr_in6 sin6_mask;
3932 3939
3933 if (addr_len != sizeof(struct in6_addr)) 3940 if (addr_len != sizeof(struct in6_addr))
3934 return EINVAL; 3941 return EINVAL;
3935 memcpy(&wga->wga_addr6, addr, addr_len); 3942 memcpy(&wga->wga_addr6, addr, addr_len);
3936 3943
3937 sockaddr_in6_init(&sin6, (const struct in6_addr *)addr, 3944 sockaddr_in6_init(&sin6, (const struct in6_addr *)addr,
3938 0, 0, 0); 3945 0, 0, 0);
3939 sockaddr_copy(&wga->wga_sa_addr, 3946 sockaddr_copy(&wga->wga_sa_addr,
3940 sizeof(sin6), sin6tosa(&sin6)); 3947 sizeof(sin6), sin6tosa(&sin6));
3941 3948
3942 sockaddr_format(sin6tosa(&sin6), 3949 sockaddr_format(sin6tosa(&sin6),
3943 addrstr, sizeof(addrstr)); 3950 addrstr, sizeof(addrstr));
3944 WG_DLOG("addr=%s/%d\n", addrstr, wga->wga_cidr); 3951 WG_DLOG("addr=%s/%d\n", addrstr, wga->wga_cidr);
3945 3952
3946 in6_prefixlen2mask(&mask, wga->wga_cidr); 3953 in6_prefixlen2mask(&mask, wga->wga_cidr);
3947 sockaddr_in6_init(&sin6_mask, &mask, 0, 0, 0); 3954 sockaddr_in6_init(&sin6_mask, &mask, 0, 0, 0);
3948 sockaddr_copy(&wga->wga_sa_mask, 3955 sockaddr_copy(&wga->wga_sa_mask,
3949 sizeof(sin6_mask), sin6tosa(&sin6_mask)); 3956 sizeof(sin6_mask), sin6tosa(&sin6_mask));
3950 3957
3951 break; 3958 break;
3952 } 3959 }
3953#endif 3960#endif
3954 default: 3961 default:
3955 error = EINVAL; 3962 error = EINVAL;
3956 goto out; 3963 goto out;
3957 } 3964 }
3958 wga->wga_peer = wgp; 3965 wga->wga_peer = wgp;
3959 3966
3960 error = wg_rtable_add_route(wg, wga); 3967 error = wg_rtable_add_route(wg, wga);
3961 if (error != 0) 3968 if (error != 0)
3962 goto out; 3969 goto out;