Commit Graph

178 Commits

Author SHA1 Message Date
Jason A. Donenfeld 20584d1c32 support: account for protosw change
e7d02be19 ("protosw: refactor protosw and domain static declaration and
load") changed the way this function should be invoked.

Link: e7d02be19d
Reported-by: Michael Pro <michael.adm@gmail.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-09-04 19:19:55 +02:00
Jason A. Donenfeld 3cc22b29d6 version: bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-06-15 16:11:06 +02:00
Joseph Mingrone 11468c59f8 compat: update version to handle sbcreatecontrol() changes
The sockbuf changes to merge two versions of sbcreatecontrol() into one
occurred in b46667c63eb7 in the FreeBSD src repository.  The value of
__FreeBSD_version at the time of that commit was 1400059, so check
for systems with a version stamp less than 1400059.

Ideally __FreeBSD_version would have been bumped in b46667c63eb7,
however it was set to 1400059 53 commits prior in 3a9a9c0ca44e and not
bumped to 1400060 until 374 commits later in 85d7875d4291.  Thus, this
is not a perfect solution because CURRENT systems built from 53 possible
commits that require the adjustment will still fail to build the
wireguard kernel module.  This is better than checking for systems with
__FreeBSD_version < 1400057.  In that case, there are 767 different
commits a CURRENT system may be built from where the module will fail to
build.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-06-14 21:58:03 +02:00
Jason A. Donenfeld 5ba28362fe crypto: inline blake2s convenience function
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-06-14 11:35:01 +02:00
Jason A. Donenfeld 5c58322798 wg_noise: import hmac from crypto
This is weird and no library should implement it. Bring it into wg_noise
instead.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-06-14 11:33:26 +02:00
Ed Maste 7e3b50994e ci: add FreeBSD 12.3 and 13.1
Signed-off-by: Ed Maste <emaste@FreeBSD.org>
2022-06-14 11:26:59 +02:00
Jason A. Donenfeld a7d386f91e version: bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-06-14 11:19:42 +02:00
Jason A. Donenfeld e519e8e44d compat: fix version stamp
Reported-by: Michael Butler <imb@protected-networks.net>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-06-14 01:26:13 +02:00
Jason A. Donenfeld 416c5dcf27 crypto: harmonize with compat and clean up
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-06-14 01:24:38 +02:00
John Baldwin 613c964ee9 crypto: use curve25519 API from the kernel when available
Signed-off-by: John Baldwin <jhb@FreeBSD.org>
2022-06-14 00:55:29 +02:00
John Baldwin f59e60e369 crypto: use <crypto/chacha20_poly1305.h> when present
Signed-off-by: John Baldwin <jhb@FreeBSD.org>
2022-06-14 00:55:15 +02:00
John Baldwin a6354a1436 crypto: use OCF to encrypt/decrypt packets when supported
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>
2022-06-14 00:54:55 +02:00
John Baldwin b7441e3154 if_wg: wg_peer_alloc and wg_aip_add: Use M_WAITOK with malloc
Signed-off-by: John Baldwin <jhb@FreeBSD.org>
2022-06-14 00:54:37 +02:00
Jason A. Donenfeld ccf37db6e6 build: include compat.h for all files
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>
2022-06-10 23:37:49 +02:00
Jason A. Donenfeld d0c75d8e7d version: bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-06-10 19:21:17 +02:00
Jason A. Donenfeld c66627f1ea if_wg: account for added argument to sbcreatecontrol
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-06-10 19:16:09 +02:00
John Baldwin 352883bb38 crypto: return an error code from mbuf crypt routines
This permits returning different error codes for different conditions.

Signed-off-by: John Baldwin <jhb@FreeBSD.org>
2022-06-10 19:04:15 +02:00
John Baldwin 7658a19cb6 if_wg: wg_module_init: clean up more if the self tests fail
Signed-off-by: John Baldwin <jhb@FreeBSD.org>
2022-06-10 18:58:50 +02:00
John Baldwin ddc22dade9 if_wg: avoid scheduling excessive tasks for encryption/decryption
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>
2022-06-10 18:58:50 +02:00
John Baldwin dad3e685f5 if_wg: wg_mbuf_reset: don't free send tags
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>
2022-06-10 18:57:51 +02:00
John Baldwin 60ac45234c wg_cookie: ratelimit_init: use callout_init_mtx
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>
2022-06-10 18:57:33 +02:00
John Baldwin 7196782c5d if_wg: wg_clone_create: Use M_WAITOK with malloc
Signed-off-by: John Baldwin <jhb@FreeBSD.org>
2022-06-10 18:57:22 +02:00
John Baldwin 8c2797b04a if_wg: wgc_get/set: use M_WAITOK with malloc()
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>
2022-06-10 18:57:16 +02:00
John Baldwin 1d5dd08074 if_wg: wg_queue_delist_staged: use more standard STAILQ_CONCAT
No functional change.

Signed-off-by: John Baldwin <jhb@FreeBSD.org>
2022-06-10 18:57:08 +02:00
John Baldwin a31339b25e if_wg: wg_queue_len: remove locking
Locking a mutex just to read a single word doesn't close any races.

Signed-off-by: John Baldwin <jhb@FreeBSD.org>
2022-06-10 18:57:00 +02:00
John Baldwin 54b2075e29 build: only include compat.h for if_wg.c and fix build with an obj directory
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>
2022-06-10 18:56:32 +02:00
Jason A. Donenfeld b5cb87eebb if_wg: account for input function returning a boolean
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>
2022-06-10 18:41:27 +02:00
Jason A. Donenfeld 5043212a73 if_wg: do not use continue statement on \!VIMAGE
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-06-10 17:42:51 +02:00
Jason A. Donenfeld 8ed513557b version: bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-11-05 15:40:17 +01:00
Jason A. Donenfeld 0c4dfbf209 if_wg: protect in6_mask2len with INET6
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>
2021-10-29 16:20:16 +02:00
Jason A. Donenfeld 93bd2b17d6 if_wg: bump keepalive timers unconditionally on send
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>
2021-10-26 11:22:32 +02:00
Jason A. Donenfeld 64a507ad6b compat: taskqueue draining was backported to stable/13
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>
2021-06-07 11:51:17 +02:00
Jason A. Donenfeld bf27d10262 version: bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-06-06 15:35:25 +02:00
Jason A. Donenfeld 7855bfe930 if_wg: do not crash if deiniting before vnet is up
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-06-06 15:33:17 +02:00
Jason A. Donenfeld 0955fa72f5 global: replace rwlock with mtx if never rlocked
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>
2021-06-05 23:29:57 +02:00
Jason A. Donenfeld 5158e2c0f4 global: destroy rwlocks and mtxs
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>
2021-06-05 23:29:34 +02:00
Jason A. Donenfeld 0de29313dd ci: test on 12.1 and 12.2
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-06-01 15:27:11 +02:00
Jason A. Donenfeld b4a0f872e6 compat: account for lack of CSUM_SND_TAG on ≤12.2
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>
2021-06-01 15:27:11 +02:00
Jason A. Donenfeld 2265d72ca1 if_wg: add braces for 12.1 compiler warning
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-06-01 15:27:11 +02:00
Jason A. Donenfeld 395d925470 netns: use massive datagrams
This tests the mbuf fragment code more heavily.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-06-01 15:27:11 +02:00
Jason A. Donenfeld 1fb21d1665 netns: account for FreeBSD 12 quirks
In ping6, -W -> -x, and DAD affects bind(), so disable it.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-06-01 15:27:11 +02:00
Jason A. Donenfeld 3be23818a1 netns: trim test to working parts and rework jail logic
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>
2021-06-01 15:12:30 +02:00
Jason A. Donenfeld a554cedba4 if_wg: pass back result of selftests and enable in CI
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>
2021-05-19 01:23:09 +02:00
Ed Maste 74b1ad5ffd ci: add a Cirrus-CI config file to build + smoke test
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>
2021-05-19 00:49:21 +02:00
Ed Maste f324db0677 netns: use `exit 0` for early exit
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>
2021-05-19 00:29:27 +02:00
Jason A. Donenfeld 0f6950b07f version: bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-05-06 11:19:05 +02:00
Jason A. Donenfeld 47f0fccb86 if_wg: destroy interfaces before uma zone
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>
2021-05-03 19:55:50 +02:00
Jason A. Donenfeld 31d3186a6d TODO: add note about excessive rw locks
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-05-03 19:55:50 +02:00
Jason A. Donenfeld 561f3a8f93 wg_noise: set handshake to dead before removing keypair
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>
2021-05-03 19:54:39 +02:00
Jason A. Donenfeld 280bee380d if_wg: put event notifiers in main loop
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-05-03 16:03:02 +02:00