aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* version: bumpv0.0.20220614Jason A. Donenfeld2022-06-141-1/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* compat: fix version stampJason A. Donenfeld2022-06-141-1/+1
| | | | | Reported-by: Michael Butler <imb@protected-networks.net> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* crypto: harmonize with compat and clean upJason A. Donenfeld2022-06-143-181/+170
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* crypto: use curve25519 API from the kernel when availableJohn Baldwin2022-06-142-0/+13
| | | | Signed-off-by: John Baldwin <jhb@FreeBSD.org>
* crypto: use <crypto/chacha20_poly1305.h> when presentJohn Baldwin2022-06-142-8/+74
| | | | Signed-off-by: John Baldwin <jhb@FreeBSD.org>
* crypto: use OCF to encrypt/decrypt packets when supportedJohn Baldwin2022-06-143-2/+109
| | | | | | | | This requires the the recent changes in FreeBSD to support the Chacha20-Poly1305 AEAD cipher with support for an 8 byte nonce (vs the 12 byte nonce used by TLS and IPsec). Signed-off-by: John Baldwin <jhb@FreeBSD.org>
* if_wg: wg_peer_alloc and wg_aip_add: Use M_WAITOK with mallocJohn Baldwin2022-06-142-28/+7
| | | | Signed-off-by: John Baldwin <jhb@FreeBSD.org>
* build: include compat.h for all filesJason A. Donenfeld2022-06-102-3/+3
| | | | | | | | 54b2075 ("build: only include compat.h for if_wg.c and fix build with an obj directory") scoped compat.h to if_wg.c, which broke building on 12.3. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* version: bumpv0.0.20220610Jason A. Donenfeld2022-06-101-1/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: account for added argument to sbcreatecontrolJason A. Donenfeld2022-06-102-2/+7
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* crypto: return an error code from mbuf crypt routinesJohn Baldwin2022-06-103-13/+18
| | | | | | This permits returning different error codes for different conditions. Signed-off-by: John Baldwin <jhb@FreeBSD.org>
* if_wg: wg_module_init: clean up more if the self tests failJohn Baldwin2022-06-101-1/+4
| | | | Signed-off-by: John Baldwin <jhb@FreeBSD.org>
* if_wg: avoid scheduling excessive tasks for encryption/decryptionJohn Baldwin2022-06-101-10/+13
| | | | | | | | | | | | | | | | Previously the wg_encrypt/decrypt_dispatch routines would wakeup all of the non-scheduled tasks. This resulted in waking up several tasks which did no useful work but did add overhead in terms of extra context switches, etc. In a single-threaded iperf3 TCP test on an 8-CPU system, only ~13% of the scheduled tasks did any work. Instead, adopt a similar scheme to that used in the Linux wireguard driver in which each call only wakes up a single task and uses per-queue CPU iterators to round-robin among CPUs when choosing a task to schedule. This improved throughput in the iperf3 TCP test by more than double and ~65% of scheduled tasks did useful work. Signed-off-by: John Baldwin <jhb@FreeBSD.org>
* if_wg: wg_mbuf_reset: don't free send tagsJohn Baldwin2022-06-102-14/+2
| | | | | | | | Send tags are only added on mbufs sent to an interface which supports if_snd_tag_alloc. Just assert that they are never present instead. Signed-off-by: John Baldwin <jhb@FreeBSD.org>
* wg_cookie: ratelimit_init: use callout_init_mtxJohn Baldwin2022-06-101-1/+1
| | | | | | | | callout_init_rw() happens to compile ok because both are macros that dereference the passed in lock's "lock_object" member to pass to the real function. Signed-off-by: John Baldwin <jhb@FreeBSD.org>
* if_wg: wg_clone_create: Use M_WAITOK with mallocJohn Baldwin2022-06-102-15/+5
| | | | Signed-off-by: John Baldwin <jhb@FreeBSD.org>
* if_wg: wgc_get/set: use M_WAITOK with malloc()John Baldwin2022-06-101-24/+16
| | | | | | | | | | | This reduces the edge cases which need handling, and M_WAITOK is safe to use in this context. While here, narrow the scope of the sc_lock to the code that interacts with the softc, but not copyin/copyout, malloc, and nvlist_pack calls before and after interacting with the softc. Signed-off-by: John Baldwin <jhb@FreeBSD.org>
* if_wg: wg_queue_delist_staged: use more standard STAILQ_CONCATJohn Baldwin2022-06-101-2/+2
| | | | | | No functional change. Signed-off-by: John Baldwin <jhb@FreeBSD.org>
* if_wg: wg_queue_len: remove lockingJohn Baldwin2022-06-101-5/+1
| | | | | | Locking a mutex just to read a single word doesn't close any races. Signed-off-by: John Baldwin <jhb@FreeBSD.org>
* build: only include compat.h for if_wg.c and fix build with an obj directoryJohn Baldwin2022-06-101-1/+1
| | | | | | | In particular, this permits building the module as part of a kernel build via the LOCAL_MODULES facility. Signed-off-by: John Baldwin <jhb@FreeBSD.org>
* if_wg: account for input function returning a booleanJason A. Donenfeld2022-06-101-9/+9
| | | | | | | | | Since 742e7210 ("udp: allow udp_tun_func_t() to indicate it did not eat the packet"), wg_input must return a boolean. We force a cast for old kernels. It'd be nicer to work around this in compat.h, but we can't because FreeBSD's headers have dependencies we can't resolve from there. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: do not use continue statement on \!VIMAGEJason A. Donenfeld2022-06-101-4/+4
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* version: bumpv0.0.20211105Jason A. Donenfeld2021-11-051-1/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: protect in6_mask2len with INET6Jason A. Donenfeld2021-10-291-1/+6
| | | | | | | In the process, just don't do v6 allowedips if there's no INET6 support. Reported-by: Yi <yu@boenyc.us> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: bump keepalive timers unconditionally on sendJason A. Donenfeld2021-10-261-2/+2
| | | | | | | | | | | | | | | | | | The keepalive timers -- both persistent and mandatory -- are part of the internal state machine, which needs to be cranked whether or not the packet was actually sent. A packet might be dropped by the network. Or the packet might be dropped by the local network stack. The latter case gives a hint -- which is useful for the data_sent event -- but is harmful to consider for the keepalive state machine. So, crank those timers before even calling wg_send. Incidentally, doing it this way matches exactly what Linux's send.c's wg_packet_create_data_done and Go's send.go's RoutineSequentialSender do too. Suggested-by: Kyle Evans <kevans@freebsd.org> Reported-by: Ryan Roosa <ryanroosa@gmail.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* compat: taskqueue draining was backported to stable/13Jason A. Donenfeld2021-06-071-1/+1
| | | | | | | | | Since 407b687dfef ("Make sure all tasklets are drained before unloading the LinuxKPI. Else use-after-free may happen."), stable/13 now has the taskqueue API that we need. Reported-by: Herbert J. Skuhra <herbert@gojira.at> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* version: bumpv0.0.20210606Jason A. Donenfeld2021-06-061-1/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: do not crash if deiniting before vnet is upJason A. Donenfeld2021-06-062-2/+5
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* global: replace rwlock with mtx if never rlockedJason A. Donenfeld2021-06-054-45/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There were multiple places where a rwlock was used despite never rlocking, so just change these into mtxs. This was done with the aid of Coccinelle's spatch, using this input: #spatch -j 4 --recursive-includes --include-headers-for-types --include-headers --in-place --macro-file <seebelow.h> virtual after_start @initialize:ocaml@ @@ let has_write_table = Hashtbl.create 101 let has_read_table = Hashtbl.create 101 let ok i m = let entry = (i,m) in Hashtbl.mem has_write_table entry && not(Hashtbl.mem has_read_table entry) @hasw depends on !after_start@ identifier i,m; struct i x; @@ ( rw_wlock(&x.m) | rw_wunlock(&x.m) ) @script:ocaml@ i << hasw.i; m << hasw.m; @@ Hashtbl.replace has_write_table (i,m) () @hasr depends on !after_start@ identifier i,m; struct i x; @@ ( rw_rlock(&x.m) | rw_runlock(&x.m) ) @script:ocaml@ i << hasr.i; m << hasr.m; @@ Hashtbl.replace has_read_table (i,m) () @finalize:ocaml depends on !after_start@ wt << merge.has_write_table; rt << merge.has_read_table; @@ let redo ts dst = List.iter (Hashtbl.iter (fun k _ -> Hashtbl.add dst k ())) ts in redo wt has_write_table; redo rt has_read_table; let it = new iteration() in it#add_virtual_rule After_start; it#register() (* ----------------------------------------------------------- *) @depends on after_start@ identifier i; identifier m : script:ocaml(i) { ok i m }; @@ struct i { ... - struct rwlock m; + struct mtx m; ... } @depends on after_start disable fld_to_ptr@ identifier m; identifier i : script:ocaml(m) { ok i m }; struct i x; @@ - rw_wlock + mtx_lock (&x.m) @depends on after_start disable fld_to_ptr@ identifier m; identifier i : script:ocaml(m) { ok i m }; struct i x; @@ - rw_wunlock + mtx_unlock (&x.m) @depends on after_start disable fld_to_ptr@ identifier m; expression e; identifier i : script:ocaml(m) { ok i m }; struct i x; @@ - rw_init(&x.m, e); + mtx_init(&x.m, e, NULL, MTX_DEF); @depends on after_start disable fld_to_ptr@ identifier m; identifier i : script:ocaml(m) { ok i m }; struct i x; @@ - rw_destroy + mtx_destroy (&x.m) @depends on after_start disable fld_to_ptr, ptr_to_array@ identifier m; identifier i : script:ocaml(m) { ok i m }; struct i *x; @@ - rw_wlock + mtx_lock (&x->m) @depends on after_start disable fld_to_ptr, ptr_to_array@ identifier m; identifier i : script:ocaml(m) { ok i m }; struct i *x; @@ - rw_wunlock + mtx_unlock (&x->m) @depends on after_start disable fld_to_ptr, ptr_to_array@ identifier m; expression e; identifier i : script:ocaml(m) { ok i m }; struct i *x; @@ - rw_init(&x->m, e); + mtx_init(&x->m, e, NULL, MTX_DEF); @depends on after_start disable fld_to_ptr, ptr_to_array@ identifier m; identifier i : script:ocaml(m) { ok i m }; struct i *x; @@ - rw_destroy + mtx_destroy (&x->m) A few macros needed to be provided manually for the parser to work: #define LIST_HEAD(x,y) int #define TAILQ_HEAD(x,y) int #define STAILQ_HEAD(x,y) int #define CK_LIST_HEAD(x,y) int #define CK_LIST_ENTRY(x) int #define LIST_ENTRY(x) int #define TAILQ_ENTRY(x) int #define STAILQ_ENTRY(x) int Co-authored-by: Julia Lawall <julia.lawall@inria.fr> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* global: destroy rwlocks and mtxsJason A. Donenfeld2021-06-055-1/+31
| | | | | | | Before, most uses of rwlock and mtx never called the destroy method, which might cause problems for witness. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* ci: test on 12.1 and 12.2Jason A. Donenfeld2021-06-012-15/+16
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* compat: account for lack of CSUM_SND_TAG on ≤12.2Jason A. Donenfeld2021-06-011-0/+5
| | | | | | | | This was added to 12.1 in a security fix, but wasn't really wired up properly, so this effectively disables it from packet resetting, which is a bummer, but it's more preferable than hacking this in bad ways. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: add braces for 12.1 compiler warningJason A. Donenfeld2021-06-011-2/+2
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* netns: use massive datagramsJason A. Donenfeld2021-06-011-1/+4
| | | | | | This tests the mbuf fragment code more heavily. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* netns: account for FreeBSD 12 quirksJason A. Donenfeld2021-06-011-2/+7
| | | | | | In ping6, -W -> -x, and DAD affects bind(), so disable it. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* netns: trim test to working parts and rework jail logicJason A. Donenfeld2021-06-012-707/+43
| | | | | | | | | | Rather than agonizing on and on about finishing this, just get what actually works in a tidy place. We also make everything happen in a dedicated child jail, and work with JIDs instead of labels. This should improve isolation and reliability. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: pass back result of selftests and enable in CIJason A. Donenfeld2021-05-196-22/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Hopefully bad tests will cause the module to not insert, so the CI picks this up. It looks like a failure to insert the module at the moment actually causes another crash, though: Kernel page fault with the following non-sleepable locks held: exclusive sleep mutex if_cloners lock (if_cloners lock) r = 0 (0xffffffff81d9a9b8) locked @ /usr/src/sys/net/if_clone.c:447 stack backtrace: #0 0xffffffff80c66181 at witness_debugger+0x71 #1 0xffffffff80c6729d at witness_warn+0x40d #2 0xffffffff8109499e at trap_pfault+0x7e #3 0xffffffff81093fab at trap+0x2ab #4 0xffffffff810687f8 at calltrap+0x8 #5 0xffffffff82925610 at wg_module_event_handler+0x120 #6 0xffffffff80bd53c3 at module_register_init+0xd3 #7 0xffffffff80bc5c61 at linker_load_module+0xc01 #8 0xffffffff80bc73b9 at kern_kldload+0xe9 #9 0xffffffff80bc74db at sys_kldload+0x5b #10 0xffffffff810952f7 at amd64_syscall+0x147 #11 0xffffffff8106911e at fast_syscall_common+0xf8 Fatal trap 12: page fault while in kernel mode cpuid = 9; apic id = 09 fault virtual address = 0x70 fault code = supervisor read data, page not present instruction pointer = 0x20:0xffffffff80d18e37 stack pointer = 0x28:0xfffffe0115fb35a0 frame pointer = 0x28:0xfffffe0115fb35c0 code segment = base 0x0, limit 0xfffff, type 0x1b = DPL 0, pres 1, long 1, def32 0, gran 1 processor eflags = interrupt enabled, resume, IOPL = 0 current process = 1587 (kldload) trap number = 12 panic: page fault cpuid = 9 time = 1621380034 KDB: stack backtrace: #0 0xffffffff80c44695 at kdb_backtrace+0x65 #1 0xffffffff80bf9d01 at vpanic+0x181 #2 0xffffffff80bf9ad3 at panic+0x43 #3 0xffffffff81094917 at trap_fatal+0x387 #4 0xffffffff810949b7 at trap_pfault+0x97 #5 0xffffffff81093fab at trap+0x2ab #6 0xffffffff810687f8 at calltrap+0x8 #7 0xffffffff82925610 at wg_module_event_handler+0x120 #8 0xffffffff80bd53c3 at module_register_init+0xd3 #9 0xffffffff80bc5c61 at linker_load_module+0xc01 #10 0xffffffff80bc73b9 at kern_kldload+0xe9 #11 0xffffffff80bc74db at sys_kldload+0x5b #12 0xffffffff810952f7 at amd64_syscall+0x147 #13 0xffffffff8106911e at fast_syscall_common+0xf8 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* ci: add a Cirrus-CI config file to build + smoke testEd Maste2021-05-191-0/+25
| | | | | | | Fetch src tarball corresponding to the release (TODO: support snapshots too), build and load WireGuard module, and run netns test script. Signed-off-by: Ed Maste <emaste@FreeBSD.org>
* netns: use `exit 0` for early exitEd Maste2021-05-191-1/+1
| | | | | | | | It appears that much of netns is not yet ported/usable on FreeBSD, and we previously used `exit 1` to exit early and skip the remainder. Exit without error instead, for CI purposes. Signed-off-by: Ed Maste <emaste@FreeBSD.org>
* version: bumpv0.0.20210503Jason A. Donenfeld2021-05-061-1/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: destroy interfaces before uma zoneJason A. Donenfeld2021-05-031-4/+13
| | | | | | | | | | | | | | | | Fixes: #12 0xffffffff80f20105 in uma_zalloc_arg (zone=<optimized out>, udata=<optimized out>, udata@entry=0x0, flags=flags@entry=257) at /usr/src/sys/vm/uma_core.c:3420 #13 0xffffffff82922844 in uma_zalloc (zone=<unavailable>, flags=257) at /usr/src/sys/vm/uma.h:358 #14 wg_packet_alloc (m=0xfffff801154bfa00) at if_wg.c:1769 #15 wg_send_keepalive (peer=0xfffff800075dd000, peer@entry=<error reading variable: value is not available>) at if_wg.c:1291 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* TODO: add note about excessive rw locksJason A. Donenfeld2021-05-031-0/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* wg_noise: set handshake to dead before removing keypairJason A. Donenfeld2021-05-031-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Otherwise CK_LIST_REMOVE might be called twice on the same element. Running the following trigger will reproduce the bug that Manojav reported: #!/usr/local/bin/bash NUM_PEER=50 peer_args=( ) for ((i=0; i<NUM_PEER; i++)); do port="$RANDOM" private="$(wg genkey)" ifconfig "wg$i" create wg set "wg$i" listen-port "$port" private-key <(echo "$private") peer_args+=( peer "$(wg pubkey <<<"$private")" endpoint "127.0.0.1:$port" persistent-keepalive 1 ) done for ((i=0; i<NUM_PEER; i++)); do wg set "wg$i" "${peer_args[@]}" ifconfig "wg$i" up done wg while true; do for ((i=0; i<NUM_PEER; i++)); do ifconfig "wg$i" down ifconfig "wg$i" up done done Reported-by: Manojav Sridhar <manojav@manojav.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: put event notifiers in main loopJason A. Donenfeld2021-05-032-15/+9
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* version: bumpv0.0.20210502Jason A. Donenfeld2021-05-031-1/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* wg_noise: cleanup counter algorithmJason A. Donenfeld2021-05-032-30/+33
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* wg_cookie: zero before init in selftest for witnessJason A. Donenfeld2021-05-021-0/+3
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: don't double increment error counterJason A. Donenfeld2021-05-021-3/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: ensure packet is not shared before writingJason A. Donenfeld2021-05-021-1/+16
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: don't memcpy data for no reasonJason A. Donenfeld2021-05-021-4/+2
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>