dragonfly.git
2 months agowg: Add and improve WG_PKT_* macros to help clean up the code
Aaron LI [Mon, 15 Jan 2024 14:34:32 +0000 (15 22:34 +0800)]
wg: Add and improve WG_PKT_* macros to help clean up the code

- Add WG_PKT_IS_INITIATION, WG_PKT_IS_RESPONSE, WG_PKT_IS_COOKIE,
  and WG_PKT_IS_DATA macros.
- Extend the original WG_PKT_DATA_MINLEN macro to be
  WG_PKT_ENCRYPTED_LEN(n).

2 months agowg: Clean up and improve wg_deliver_{in,out}() logic
Aaron LI [Mon, 15 Jan 2024 14:14:16 +0000 (15 22:14 +0800)]
wg: Clean up and improve wg_deliver_{in,out}() logic

- Refactor the code flow and avoid the 'goto' cases.
- Add 'oerrors' increment statement to wg_send(), pairing with the
  existing 'opackets' and 'obytes' increments; this make the code more
  clear.
- Assign 'mycpuid' to a local variable, avoiding repeated fetches within
  the loop.
- Add comment about why to always trigger the keepalive timers.

2 months agowg: Optimize wg_peer_{get,set}_endpoint()
Aaron LI [Mon, 15 Jan 2024 13:53:51 +0000 (15 21:53 +0800)]
wg: Optimize wg_peer_{get,set}_endpoint()

Similar to wg_peer_set_endpoint(), perform a comparion before really
coping the endpoint, saving unnecessary lockings.

In addition, add __predict_true() for the comparions.

2 months agowg: Fix panic of "user address access from kernel mode"
Aaron LI [Fri, 9 Feb 2024 13:14:25 +0000 (9 21:14 +0800)]
wg: Fix panic of "user address access from kernel mode"

Well, it never happened on my development VirtualBox VM, but always
happened on my desktop.  Fix it.  Actually, I made this mistake when
porting the code from OpenBSD.

2 months agoBump copyright year
Aaron LI [Fri, 9 Feb 2024 09:39:30 +0000 (9 17:39 +0800)]
Bump copyright year

2 months agoifconfig(8): Minor code and style cleanups
Aaron LI [Fri, 9 Feb 2024 09:36:29 +0000 (9 17:36 +0800)]
ifconfig(8): Minor code and style cleanups

No functional changes.

2 months agoifconfig(8): Change some 'int' variables to 'bool' whenever possible
Aaron LI [Fri, 9 Feb 2024 09:35:45 +0000 (9 17:35 +0800)]
ifconfig(8): Change some 'int' variables to 'bool' whenever possible

I'd like to change 'doalias' as well, but it seems to require 3 states,
so leave it alone this moment.

2 months agoifconfig(8): Fix bug in interface address configuration
Aaron LI [Fri, 9 Feb 2024 09:02:50 +0000 (9 17:02 +0800)]
ifconfig(8): Fix bug in interface address configuration

When the interface name had a length of >= 8, the address configuration
would fail with the ENXIO error, i.e., "no such interface".

This bug was made by me in commit c29ec76.  It was caused by the
interface was truncated because the destination buffer size was wrongly
determined, as I was using sizeof() on a 'void *' pointer instead of the
actual interface name buffer.

Fix it by directly using IFNAMSIZ instead of sizeof().

2 months agowg: Flush v4 routes for v6 randomized test to reduce the test time
Aaron LI [Sat, 3 Feb 2024 05:04:11 +0000 (3 13:04 +0800)]
wg: Flush v4 routes for v6 randomized test to reduce the test time

The validation method uses a simple list to store all the routes in a
sorted way so that it can be looked up and verify the lookup results
of the radix tree.  The list method can be really slow when there are
many routes, so the randomized test can take ~80 minutes on my test box.
Separate the v4 and v6 tests to significantly reduce the test time (e.g.,
from ~80 minutes to ~15 minutes).

2 months agowg: Update makefile with (commented) selftest defines
Aaron LI [Sat, 27 Jan 2024 15:03:20 +0000 (27 23:03 +0800)]
wg: Update makefile with (commented) selftest defines

2 months agowg: Refactor selftest allowedips.c
Aaron LI [Sat, 27 Jan 2024 14:59:31 +0000 (27 22:59 +0800)]
wg: Refactor selftest allowedips.c

- Refactor multiple functions and macros to make the implementation read
  better.
- Fix some memory free issues upon errors; e.g., kfree() panics if the
  given pointer is NULL.
- Add progress reports for the randomized test as it can take really
  long time (e.g., ~80 minutes on my test box).
- Various improvements and style cleanups.

2 months agowg: Port selftest allowedips.c
Aaron LI [Fri, 26 Jan 2024 09:05:58 +0000 (26 17:05 +0800)]
wg: Port selftest allowedips.c

2 months agowg: Style cleanups and minor updates to selftest cookie.c and counter.c
Aaron LI [Thu, 25 Jan 2024 01:30:15 +0000 (25 09:30 +0800)]
wg: Style cleanups and minor updates to selftest cookie.c and counter.c

- Style cleanups to make them consistent.
- Add '#undef' to cleanup defines.
- Add MIT license contents to file headers.
- Tweak 'for' loops in noise_counter_selftest() to make them more clear.
- Rename 'rl' to be 'rl_test'; rename 'MESSAGE_LEN' to be
  'T_MESSAGE_LEN'.
- Remove unnecessary '[0 ... INITIATIONS_BURSTABLE - 1]' initialization
  designator, and thus save one GNU extension.

2 months agowg: Port selftest cookie.c and counter.c
Aaron LI [Wed, 24 Jan 2024 13:30:59 +0000 (24 21:30 +0800)]
wg: Port selftest cookie.c and counter.c

Note that 'int sleep_time' would overflow in calculating the tsleep()
timeout ticks, so change it to 'uint64_t' type.

2 months agowg: Import selftest code from wireguard-freebsd
Aaron LI [Tue, 23 Jan 2024 15:55:34 +0000 (23 23:55 +0800)]
wg: Import selftest code from wireguard-freebsd

URL: https://git.zx2c4.com/wireguard-freebsd/
Files:
- src/selftest/allowedips.c
- src/selftest/cookie.c
- src/selftest/counter.c

2 months agokernel: Add the 'wg' option and list it in LINT64
Aaron LI [Tue, 16 Jan 2024 07:28:55 +0000 (16 15:28 +0800)]
kernel: Add the 'wg' option and list it in LINT64

2 months agowg: Hook to the build system
Aaron LI [Tue, 16 Jan 2024 07:27:53 +0000 (16 15:27 +0800)]
wg: Hook to the build system

2 months agowg: Adapt the man page to match our version
Aaron LI [Thu, 18 Jan 2024 01:20:48 +0000 (18 09:20 +0800)]
wg: Adapt the man page to match our version

2 months agowg: Rewrite the module Makefile
Aaron LI [Tue, 16 Jan 2024 02:00:15 +0000 (16 10:00 +0800)]
wg: Rewrite the module Makefile

2 months agowg: Prevent wg_{cookie,noise}.h from including by userland
Aaron LI [Thu, 8 Feb 2024 06:06:19 +0000 (8 14:06 +0800)]
wg: Prevent wg_{cookie,noise}.h from including by userland

Since our build system currently would install all headers (i.e., '*.h')
in 'sys/net/wg' directory, but actually only the 'if_wg.h' is required
by userland, i.e., ifconfig(8).  So add the '_KERNEL' guard to prevent
the other two headers from including by userland.

Nonetheless, the build system should be improved in the future.

2 months agowg: Reset the obsolete version number to 1
Aaron LI [Wed, 7 Feb 2024 14:14:04 +0000 (7 22:14 +0800)]
wg: Reset the obsolete version number to 1

The version number meant the snapshot date of the wireguard-freebsd [0],
but it's obsolete now, because there is no more active development
there.  In addition, this port has been diverged a lot from the FreeBSD
version.  So just reset the version number to 1 for simplicity.

[0] wireguard-freebsd: https://git.zx2c4.com/wireguard-freebsd

2 months agowg: Fix noise_remote_alloc() to acquire 'l_identity_lock' lock
Aaron LI [Tue, 16 Jan 2024 12:27:35 +0000 (16 20:27 +0800)]
wg: Fix noise_remote_alloc() to acquire 'l_identity_lock' lock

The 'l_identity_lock' lock must be acquired to access 'l_has_identity'
and 'l_private' members; i.e., noise_precompute_ss() must be called with
the 'l_identity_lock' locked.  So fix noise_remote_alloc() to acquire
the lock before calling noise_precompute_ss().  Meanwhile, add an
assertion to the latter to assert the required lock is held.

2 months agowg: Fix bug in calculate_padding()
Aaron LI [Mon, 15 Jan 2024 13:48:18 +0000 (15 21:48 +0800)]
wg: Fix bug in calculate_padding()

The calculation for 'pkt->p_mtu == 0' case was wrong, but it didn't
cause actual harm because currently only keepalive packets have
'p_mtu = 0' but also have a zero length.

Fix the calculation and add a comment about the keepalive packets.

2 months agowg: Fix build without INET6 option
Aaron LI [Mon, 15 Jan 2024 00:54:20 +0000 (15 08:54 +0800)]
wg: Fix build without INET6 option

2 months agowg: Remove INET option and the 'opt_inet.h' header
Aaron LI [Mon, 15 Jan 2024 00:51:10 +0000 (15 08:51 +0800)]
wg: Remove INET option and the 'opt_inet.h' header

DragonFly generally assumes INET always available, and doesn't actually
support an IPv6-only setup.  So remove the INET option to clean up the
code a bit.

2 months agowg: Remove unsupported endpoint.e_local and clean up related code
Aaron LI [Sun, 14 Jan 2024 14:50:53 +0000 (14 22:50 +0800)]
wg: Remove unsupported endpoint.e_local and clean up related code

On DragonFly, the socket upcall and so_pru_soreceive() cannot provide
the local (i.e., destination) address of a received packet.  Even if
there is the 'IP_RECVDSTADDR' control option to obtain the dst address,
but it's unsafe to use it with the socket, because the packet is queued
by the socket layer and the original packet may have been freed then.

As a result, just remove the unsupported 'e_local' part from
wg_endpoint.  Meanwhile, clean up the code related to the 'e_local'
endpoint.

Moreover, DragonFly by default sends UDP packets asynchronously, so
so_pru_sosend() may just return 0 even if the packet fails to send.
Therefore, there is no much point to check its return code and retry
the sending.  Remove the retry code from wg_send_buf() and the
'EADDRNOTAVAIL' check code from wg_deliver_out().

2 months agowg: Port #37: reimplement wg_mbuf_reset()
Aaron LI [Tue, 9 Jan 2024 01:57:23 +0000 (9 09:57 +0800)]
wg: Port #37: reimplement wg_mbuf_reset()

We define the 'MBUF_CLEARFLAGS' based on 'M_COPYFLAGS' for the mbuf
flags to be cleared.  Since we don't make use of mbuf tag for loop
detection, the wg_mbuf_reset() function becomes really simple, so I just
do mbuf resetting in wg_encrypt()/wg_decrypt() and remove this function.

Referred-to: OpenBSD

2 months agowg: Port #36: reimplement loop detection feature
Aaron LI [Sat, 13 Jan 2024 13:27:37 +0000 (13 21:27 +0800)]
wg: Port #36: reimplement loop detection feature

The mbuf m_pkthdr has been extended to provide the 'loop_cnt' member to
help detect loops.  Adapt the code to make use of it.

Referred-to: OpenBSD

2 months agowg: Assert 'sc_lock' acquired before LK_EXCLUSIVE 'so_lock'
Aaron LI [Sat, 13 Jan 2024 08:49:41 +0000 (13 16:49 +0800)]
wg: Assert 'sc_lock' acquired before LK_EXCLUSIVE 'so_lock'

So it's not needed to acquire the 'so_lock' in order to access the
'sc_socket' members.  Comment this in wg_ioctl_get().

2 months agowg: Add wg_timers_get_persistent_keepalive() to get PKA
Aaron LI [Sat, 13 Jan 2024 08:25:49 +0000 (13 16:25 +0800)]
wg: Add wg_timers_get_persistent_keepalive() to get PKA

In sync with wg_timers_set_persistent_keepalive(), the atomic ops is
used to get the pka value.

Referred-to: OpenBSD

2 months agowg: Implement wg_peer_{set,get}_endpoint() to set the remote endpoint
Aaron LI [Sat, 13 Jan 2024 08:19:38 +0000 (13 16:19 +0800)]
wg: Implement wg_peer_{set,get}_endpoint() to set the remote endpoint

Moving the setting and getting the peer remote endpoint to their own
separate functions.  This cleans up the already lengthy
wg_ioctl_{set,get}() functions.

In addition, these two functions fix the following two issues:
- The 'p_endpoint_lock' wasn't acquired before setting/getting the
  endpoint address.
- The local address 'e_local' wasn't cleared when setting the remote
  endpoint address.

Referred-to: OpenBSD

2 months agowg: Clean up wg_input() a bit and make return type 'void'
Aaron LI [Sat, 13 Jan 2024 06:50:05 +0000 (13 14:50 +0800)]
wg: Clean up wg_input() a bit and make return type 'void'

2 months agowg: Fix saving of local endpoint in wg_input()
Aaron LI [Fri, 12 Jan 2024 13:55:20 +0000 (12 21:55 +0800)]
wg: Fix saving of local endpoint in wg_input()

The so_pru_soreceive() can only obtain the remote address and port, so
there is no local address to save in wg_input().  Remove the wrong code
of saving the local endpoint from wg_input().

In addition, rename 'sa' to 'from' in wg_upcall() to make this more
clear.

2 months agowg: Treat zero birthdate as expired in noise's timer_expired()
Aaron LI [Fri, 12 Jan 2024 01:09:22 +0000 (12 09:09 +0800)]
wg: Treat zero birthdate as expired in noise's timer_expired()

2 months agowg: Change several noise functions to return boolean for clarity
Aaron LI [Fri, 12 Jan 2024 01:04:13 +0000 (12 09:04 +0800)]
wg: Change several noise functions to return boolean for clarity

2 months agowg: Remove unnecessary wg_init()
Aaron LI [Thu, 11 Jan 2024 14:48:30 +0000 (11 22:48 +0800)]
wg: Remove unnecessary wg_init()

The ifp->if_init() routine is required only for Ethernet drivers, so
it's unnecessary and actually unused here.  Just remove it to avoid any
confusion.

2 months agowg: Allow to set persistent-keepalive regardless of peer status
Aaron LI [Tue, 9 Jan 2024 05:32:36 +0000 (9 13:32 +0800)]
wg: Allow to set persistent-keepalive regardless of peer status

It was unable to set persistent-keepalive when the peer was disabled,
which was inconvenient and unnecessary.  For example, one can configure
the interface and peers before finally making the interface UP.

2 months agowg: Improve the return types of noise handshake functions
Aaron LI [Sat, 6 Jan 2024 15:41:56 +0000 (6 23:41 +0800)]
wg: Improve the return types of noise handshake functions

- Change noise_create_initiation() and noise_create_response() to return
  a boolean.
- Change noise_consume_initiation() and noise_consume_response() to
  return the corresponding remote, with another reference acquired.
  As a result, the 'struct noise_remote **' parameter is obsolete and
  removed.
- Update the callers in if_wg.c accordingly.

Referred to Linux's version.

2 months agowg: Improve noise_begin_session()
Aaron LI [Sat, 6 Jan 2024 15:29:06 +0000 (6 23:29 +0800)]
wg: Improve noise_begin_session()

- Merge noise_add_new_keypair() into noise_begin_session(), as it's only
  used there.
- Add extra comments to explain the operations to the keypairs,
  especially the index replacement in the hashtable.  This helps a lot
  in understanding the code.
- Change the function to return a boolean, making the callers easier to
  use it.

2 months agowg: Update noise_remote_index_insert() to return the new index
Aaron LI [Sat, 6 Jan 2024 14:02:36 +0000 (6 22:02 +0800)]
wg: Update noise_remote_index_insert() to return the new index

This index is required by the caller, i.e., noise_create_initiation().
So make this change to help simplify the code a bit.

2 months agowg: Rename keypair fields in 'noise_remote' struct for clarity
Aaron LI [Sat, 6 Jan 2024 14:00:21 +0000 (6 22:00 +0800)]
wg: Rename keypair fields in 'noise_remote' struct for clarity

Rename keypair fields 'r_next', 'r_current' and 'r_previous' to
'r_keypair_next', 'r_keypair_current' and 'r_keypair_previous'.

2 months agowg: Rename 'wg_lock' to 'wg_mtx' since shared lock is unused
Aaron LI [Thu, 8 Feb 2024 03:21:04 +0000 (8 11:21 +0800)]
wg: Rename 'wg_lock' to 'wg_mtx' since shared lock is unused

2 months agowg: Don't acquire 'wg_lock' in wg_ioctl()
Aaron LI [Sat, 6 Jan 2024 13:56:48 +0000 (6 21:56 +0800)]
wg: Don't acquire 'wg_lock' in wg_ioctl()

The ioctl() operation is already locked by the caller (interface layer),
and the 'wg_lock' is only used to protect the 'wg_list' structure, so
don't acquire this lock in wg_ioctl().

2 months agowg: Add 'const' qualifier to several functions in if_wg.c
Aaron LI [Sat, 3 Feb 2024 04:36:36 +0000 (3 12:36 +0800)]
wg: Add 'const' qualifier to several functions in if_wg.c

2 months agowg: More style cleanups and minor updates to if_wg.c
Aaron LI [Fri, 29 Dec 2023 14:42:49 +0000 (29 22:42 +0800)]
wg: More style cleanups and minor updates to if_wg.c

- Clean up header inclusions.
- Add 'WG_PKT_WITH_PADDING()' and 'WG_PKT_DATA_MINLEN' macros to help
  simplify some code.
- Remove unnecessary assignments that are already ensured by
  kmalloc(M_ZERO).
- Rename some variables for consistency.
- Use 'int' instead of 'u_int' for cpu, in consistent with 'ncpus'.
- Use 'memcmp()' instead of 'bmcp()' for consistent with other parts.
- Remove the KKASSERT() of lock assertion from 'wg_aip_remove()', as
  it's quite obvious and thus unnecessary.
- Various style adjustments and cleanups.

2 months agowg: Style cleanups and minor updates to wg_noise.[ch]
Aaron LI [Fri, 29 Dec 2023 16:14:43 +0000 (30 00:14 +0800)]
wg: Style cleanups and minor updates to wg_noise.[ch]

- Remove unnecessary assignments that are already ensured by
  kmalloc(M_ZERO).
- Use sizeof() in bzero()/explicit_bzero() to simplify the code.
- Improve noise_kdf() by adding KKASSERT() to check the arguments,
  by adding comments to blake2s_hmac() arguments.
- Swap the 'arg' and 'public' parameters to look more sensible.
- Move inline functions to the file top.
- Rename noise_timer_expired() to timer_expired(), similar to the same
  function in 'wg_cookie.c'.
- Change 'ENOSPC' to 'ENOMEM' for consistency.
- Add 'static' qualifier to the MALLOC_DEFINE().
- Fix and adjust the comments a bit.
- Adjust code style to align with ours.

2 months agowg: Change some functions to return boolean for clarity
Aaron LI [Fri, 5 Jan 2024 15:07:52 +0000 (5 23:07 +0800)]
wg: Change some functions to return boolean for clarity

These functions are used in 'if' conditional, so only a boolean return
value if necessary.  Change them to return a boolean to make the code
read more clearly.

2 months agowg: Simplify various COUNTER_* macros in wg_noise.c
Aaron LI [Fri, 5 Jan 2024 14:13:47 +0000 (5 22:13 +0800)]
wg: Simplify various COUNTER_* macros in wg_noise.c

2 months agowg: Improve noise_remote_keys() to copy PSK only if set
Aaron LI [Thu, 4 Jan 2024 02:07:21 +0000 (4 10:07 +0800)]
wg: Improve noise_remote_keys() to copy PSK only if set

2 months agowg: Port #35: refactor noise keypair functions to avoid epoch
Aaron LI [Fri, 5 Jan 2024 13:09:33 +0000 (5 21:09 +0800)]
wg: Port #35: refactor noise keypair functions to avoid epoch

- Refactor the functions to avoid using epoch or deferred operations.
  So noise_keypair_put() is simplified and remove the obsolete
  noise_keypair_smr_free() function.
- Remove 'refcount_acquire_if_not_zero()' and use plain refcount instead,
  since there's no more deferred frees.
- Use shared locks instead of epoch sections; meanwhile, rename
  'r_keypair_mtx' to 'r_keypair_lock' because it now supports both
  shared and exclusive locks.

2 months agowg: Port #34: adapt if_wg.c to not use epoch
Aaron LI [Sun, 31 Dec 2023 15:03:26 +0000 (31 23:03 +0800)]
wg: Port #34: adapt if_wg.c to not use epoch

The relevant code is already using atomic operations.  I don't think the
epoch, especially the NET global epoch, is actually required here.  So I
decided to remove the epoch operations; however, wg_timers_disable() has
been changed to use callout_drain() instead of callout_stop() to wait
the callout cancellation to complete.

Meanwhile, simplify wg_timers_set_persistent_keepalive() by referring to
OpenBSD's code.

2 months agowg: Port #33: refactor noise remote functions to avoid epoch
Aaron LI [Fri, 29 Dec 2023 15:59:56 +0000 (29 23:59 +0800)]
wg: Port #33: refactor noise remote functions to avoid epoch

- Refactor the functions to avoid using epoch or deferred operations.
  So noise_remote_free() is simplified and no longer requires an async
  cleanup function.
- Remove 'refcount_acquire_if_not_zero()' and use plain refcount instead,
  since there's no more deferred frees.
- Use shared locks instead of epoch sections; meanwhile, rename
  'l_remote_mtx'/'l_index_mtx' to 'l_remote_lock'/'l_index_lock' because
  they now supports both shared and exclusive locks.
- Simplify noise_remote_index_insert() and remove the unnecessary
  pre-trial.
- Merge wg_peer_free_deferred() into wg_peer_destroy() and remove it.

2 months agowg: Port #32: refactor interface code and avoid deferred free
Aaron LI [Fri, 29 Dec 2023 06:27:59 +0000 (29 14:27 +0800)]
wg: Port #32: refactor interface code and avoid deferred free

- Refactor wg_clone_destroy() to not use async/deferred free, and thus
  avoid the async call of wg_clone_deferred_free() via noise_local_free().
  As a consequence, remove the 'l_arg' and 'l_cleanup' members from
  'noise_local' struct; also remove the noise_local_arg() API.

- Fix wg_clone_destroy() to not clear 'if_softc' at the beginning of the
  destruction, which fixes a panic of NULL dereference in wg_output()
  via the if_purgeaddrs_nolink() call.

- Remove the 'WGF_DYING' flag and the associated obsolete code.

- Remove the 'clone_count' global as it's no longer required.

2 months agowg: Rename enum 'wg_ring_state' to 'wg_packet_state' for consistency
Aaron LI [Sun, 24 Dec 2023 13:39:57 +0000 (24 21:39 +0800)]
wg: Rename enum 'wg_ring_state' to 'wg_packet_state' for consistency

2 months agowg: Make noise_local_{ref,put}() static
Aaron LI [Sat, 9 Dec 2023 04:27:04 +0000 (9 12:27 +0800)]
wg: Make noise_local_{ref,put}() static

They're not used by external code.

2 months agowg: Remove unused noise_remote_local() function
Aaron LI [Fri, 8 Dec 2023 05:46:38 +0000 (8 13:46 +0800)]
wg: Remove unused noise_remote_local() function

2 months agowg: Replace strlen() with 'sizeof' in wg_{cookie,noise}.c
Aaron LI [Thu, 7 Dec 2023 02:24:09 +0000 (7 10:24 +0800)]
wg: Replace strlen() with 'sizeof' in wg_{cookie,noise}.c

Get rid of unnecessary strlen() calls.

2 months agowg: Export the internal peer ID to userland for diagnostics
Aaron LI [Thu, 7 Dec 2023 01:07:51 +0000 (7 09:07 +0800)]
wg: Export the internal peer ID to userland for diagnostics

The auto-generated internal peer ID is used in various debug messages,
so exporting it to the userland (i.e., ifconfig(8)) can help with the
diagnostics.

Update ifconfig(8) to print the added peer ID.

2 months agowg: Rename noise_local_private() and make it return the key status
Aaron LI [Tue, 28 Nov 2023 05:26:47 +0000 (28 13:26 +0800)]
wg: Rename noise_local_private() and make it return the key status

- Rename noise_local_private() to noise_local_set_private() to make it
  clearer.
- Update it to return the key/identity status, so the caller don't need
  to make another call of noise_local_keys().
- Simplify the caller code accordingly, and update the comments.

Referred to OpenBSD.

2 months agowg: Refactor socket create/bind/close operations
Aaron LI [Tue, 28 Nov 2023 02:28:59 +0000 (28 10:28 +0800)]
wg: Refactor socket create/bind/close operations

- Add the wg_socket_open() function to do socket creation and binding
  for one AF, and then use it to simplify the wg_socket_init() function.
  Meanwhil, wg_socket_bind() thus becomes obsolete and is removed.
- Clean up wg_socket_uninit(), wg_socket_set_cookie() and
  wg_socket_set_sockopt().
- Add the 'so_lock' lock to protect the 'struct wg_socket' fields.
  Update wg_send() accordingly.
- Add a comment about EADDRNOTAVAIL and single-stack support.

Referred to OpenBSD.

2 months agowg: Change 'p_id' to use type 'unsigned long'
Aaron LI [Tue, 28 Nov 2023 01:53:26 +0000 (28 09:53 +0800)]
wg: Change 'p_id' to use type 'unsigned long'

The 'peer_counter' that is used to generate the 'p_id' is also defined
as type 'unsigned long', so it's natural to use 'unsigned long' for
'p_id'.  It also simplifies the printing by using '%ld' instead of
'% PRIu64'.

2 months agowg: Remove the unused 'sc_ucred' field and related code
Aaron LI [Tue, 28 Nov 2023 01:16:51 +0000 (28 09:16 +0800)]
wg: Remove the unused 'sc_ucred' field and related code

This was used in FreeBSD to control the permissions of an WG interface
in an VNET, in order to achieve something similar to Linux's network
namespace.

However, DragonFly doesn't yet support this feature, so the 'sc_ucred'
field becomes unused and thus can be removed.  It's easy to get it back
when we're ready to implement this feature in the future.

2 months agowg: Use 'void *buf' instead of 'uint8_t *buf' to save some casting
Aaron LI [Sun, 26 Nov 2023 13:54:32 +0000 (26 21:54 +0800)]
wg: Use 'void *buf' instead of 'uint8_t *buf' to save some casting

2 months agowg: Port #31: adapt socket functions
Aaron LI [Sun, 26 Nov 2023 06:30:59 +0000 (26 14:30 +0800)]
wg: Port #31: adapt socket functions

- Use so_pru_sockaddr() function to obtain the bound address/port.
- Add flags=0 as the required second argument to soclose().
- Our sbcreatecontrol() function doesn't accept the 'how' mflags, so
  remove the 'M_NOWAIT' argument.

2 months agowg: Style cleanups and minor updates to if_wg.c
Aaron LI [Sun, 26 Nov 2023 03:22:53 +0000 (26 11:22 +0800)]
wg: Style cleanups and minor updates to if_wg.c

- Add 'static' qualifier to MALLOC_DEFINE().
- Remove obsolete 'TODO' markers.
- Add '__func__' to several panic() messages.
- Compare the return value of noise_keypair_received_with() to 0 instead
  of ECONNRESET, making it read clearer.
- Various style adjustments and cleanups.

2 months agowg: Further improve wg_send_buf()
Aaron LI [Thu, 19 Oct 2023 08:15:44 +0000 (19 16:15 +0800)]
wg: Further improve wg_send_buf()

- This function is only used to send handshake packets, which are of
  known length and shorter than MHLEN, so we can just allocate an mbuf
  of packet header type and use plain memcpy() to copy the data.

- Set 'M_PRIO' mbuf flag to give handshake packets high priority.
  (referred to OpenBSD)

- Adjust the code a bit and remove the unnecessary 'retried' variable.

2 months agowg: Port #30: replace m_get2() with m_getl()
Aaron LI [Sun, 26 Nov 2023 02:52:25 +0000 (26 10:52 +0800)]
wg: Port #30: replace m_get2() with m_getl()

Our m_getl() has the similar semantics to FreeBSD's m_get2(): it will
allocate an mbuf cluster if the requested size is big enough.  However,
m_getl() wouldn't return NULL simply because the requested size exceeds
the cluster size (MCLBYTES), but FreeBSD's m_get2() would just return
NULL, which is OK because the wg_send_buf() only sends handshake packets
of known and limited lengths.

2 months agowg: Use karc4random() to generate jitter
Aaron LI [Sun, 26 Nov 2023 02:41:28 +0000 (26 10:41 +0800)]
wg: Use karc4random() to generate jitter

karc4random() should be enough; no need to use the more complex
karc4random_uniform().

2 months agowg: Port #29: change 'ENOTCAPABLE' to 'ENOENT' for 'ENOKEY'
Aaron LI [Sat, 25 Nov 2023 14:10:04 +0000 (25 22:10 +0800)]
wg: Port #29: change 'ENOTCAPABLE' to 'ENOENT' for 'ENOKEY'

The 'ENOTCAPABLE' is FreeBSD-specific and means 'capabilities
insufficient'.  We don't have that errno, so use ENOENT instead,
which I think is also reasonable.

2 months agowg: Integrate version.h into if_wg.c
Aaron LI [Sat, 25 Nov 2023 11:59:41 +0000 (25 19:59 +0800)]
wg: Integrate version.h into if_wg.c

I think it's unnecessary to use the separate 'version.h' file to hold
the single 'WIREGUARD_VERSION' macro.

2 months agowg: Update copyright headers and inclusion guards
Aaron LI [Sat, 25 Nov 2023 11:57:39 +0000 (25 19:57 +0800)]
wg: Update copyright headers and inclusion guards

- Add the content of the ISC License to the copyright headers.
- Add a copyright of me to 'if_wg.c' and 'wg_noise.c', which have been
  significantly updated by me.
- Rename the inclusion guards to match the style of our existing
  headers.

2 months agowg: Rename macro 'SELFTESTS' to 'WG_SELFTESTS'
Aaron LI [Sat, 25 Nov 2023 11:43:23 +0000 (25 19:43 +0800)]
wg: Rename macro 'SELFTESTS' to 'WG_SELFTESTS'

To make it more clear and avoid possible conflicts with others.

2 months agowg: Fix and clean up header inclusions
Aaron LI [Sat, 25 Nov 2023 11:40:52 +0000 (25 19:40 +0800)]
wg: Fix and clean up header inclusions

2 months agowg: Style cleanups and minor updates to wg_cookie.[ch]
Aaron LI [Sat, 25 Nov 2023 11:38:23 +0000 (25 19:38 +0800)]
wg: Style cleanups and minor updates to wg_cookie.[ch]

- Adjust code style to align with ours.
- Move inline functions to the file top.
- Add the 'const' qualifier to function parameters as much as possible.
- Move 'cookie_checker_validate_macs()' function to group the functions
  better.
- Zero the input ratelimit struct in ratelimit_init().
- Fix and adjust the comments a bit.

2 months agoifconfig.8: Add description for wg(4)
Aaron LI [Fri, 15 Dec 2023 15:24:21 +0000 (15 23:24 +0800)]
ifconfig.8: Add description for wg(4)

Note that the 'wgcookie' and '-wgcookie' parameters are commented out
for the moment, because they're ineffective yet.

2 months agoifconfig(8): Show wg(4) private key and PSK if '-k' specified
Aaron LI [Wed, 29 Nov 2023 01:19:21 +0000 (29 09:19 +0800)]
ifconfig(8): Show wg(4) private key and PSK if '-k' specified

2 months agoifconfig(8): Add WireGuard wg(4) support
Aaron LI [Sat, 25 Nov 2023 05:05:55 +0000 (25 13:05 +0800)]
ifconfig(8): Add WireGuard wg(4) support

Obtained from OpenBSD with significant modifications.

2 months agowg: Port #28: adapt crypto code (chacha20poly1305)
Aaron LI [Wed, 22 Nov 2023 07:45:33 +0000 (22 15:45 +0800)]
wg: Port #28: adapt crypto code (chacha20poly1305)

Update to use the chacha20poly1305 implemention from
'crypto/chachapoly.[ch]'.  Remove the obsolete code 'wg_crypto.c'.

Meanwhile, rename the original 'uint64_t nonce' to 'counter' to avoid
confusing with the 96-bit nonce (byte string) of ChaCha20-Poly1305.

2 months agowg: Port #27: adapt crypto code (curve25519, blake2s, siphash)
Aaron LI [Sat, 18 Nov 2023 10:01:55 +0000 (18 18:01 +0800)]
wg: Port #27: adapt crypto code (curve25519, blake2s, siphash)

I've imported OpenBSD's blake2s implementation to 'crypto/blake2s', so
don't need the 'COMPAT_NEED_BLAKE2S' code in 'wg_crypto.c'.

2 months agowg: Port #26: adapt the radix code for peer allowed IPs
Aaron LI [Wed, 15 Nov 2023 01:51:44 +0000 (15 09:51 +0800)]
wg: Port #26: adapt the radix code for peer allowed IPs

- Create a global mask tree and share it with all peers' AIP trees.
- Add the 'sc_aip_lock' lock to protect both the IPv4 and IPv6 trees.
- Refactor the handling of various cases in wg_aip_add() to make the
  logic more clear.
- Refactor wg_aip_remove_all() to simplify the code.

2 months agowg: Port #25: replace wmb() with cpu_sfence()
Aaron LI [Thu, 9 Nov 2023 07:21:49 +0000 (9 15:21 +0800)]
wg: Port #25: replace wmb() with cpu_sfence()

Meanwhile, comment briefly about the memory fence usage.

2 months agowg: Port #24: replace netisr_dispatch() with netisr_queue()
Aaron LI [Thu, 9 Nov 2023 07:18:48 +0000 (9 15:18 +0800)]
wg: Port #24: replace netisr_dispatch() with netisr_queue()

While there, tweak a bit the assertion and conditional on 'pkt->p_af'.

2 months agowg: Port #23: replace gtaskqueue with taskqueue(9) API
Aaron LI [Fri, 27 Oct 2023 10:51:14 +0000 (27 18:51 +0800)]
wg: Port #23: replace gtaskqueue with taskqueue(9) API

While DragonFly has already imported FreeBSD gtaskqueue API, I
personally think its implementation is unnecessarily complex, so I
decided to replace it with the simpler taskqueue(9) API.

I emulate the gtaskqueue_drain() API by randomly choosing one taskqueue
among all CPUs for the task to distribute the work load.  The randomly
chosen taskqueues are kept in the struct along with the task, so new
struct fields are added accordingly.

2 months agowg: Port #22: replace udp_set_kernel_tunneling() with socket upcall
Aaron LI [Wed, 25 Oct 2023 01:27:37 +0000 (25 09:27 +0800)]
wg: Port #22: replace udp_set_kernel_tunneling() with socket upcall

Implement the wg_upcall() function as the socket's so_upcall() method to
receive data from the kernel socket.  Adjust the original wg_input()
function to process the received data from wg_upcall().  Since we
already read the UDP data from the socket, so there is no more UDP
header in the given mbuf packet.

Adjust the socreate() invocation; however, we still need to perform
extra ucred check to achieve the wanted permission controls.

Also replace sosend() with so_pru_sosend(), as suggested by its
description in <sys/socketops.h>.

2 months agowg: Port #21: replace sbintime_t with timespec/getnanouptime()
Aaron LI [Mon, 23 Oct 2023 03:42:21 +0000 (23 11:42 +0800)]
wg: Port #21: replace sbintime_t with timespec/getnanouptime()

Partially based on OpenBSD's wg code.

2 months agowg: Improve wg_peer_alloc() to simplify the calling
Aaron LI [Sat, 21 Oct 2023 16:19:46 +0000 (22 00:19 +0800)]
wg: Improve wg_peer_alloc() to simplify the calling

Move the necessary extra logics (i.e., noise_remote_enable() and
TAILQ_INSERT_TAIL()) from wg_ioctl_set() to wg_peer_alloc(), and thus
make it easier to be called.  Actually, the updated version is more
asymmetric to wg_peer_destroy() and thus less likely to be misused.
Meanwhile, rename it to wg_peer_create() to look more consistent with
wg_peer_destroy().

Referred-to: OpenBSD

2 months agowg: Port #20: rewrite ioctl API based on OpenBSD's version
Aaron LI [Sat, 21 Oct 2023 09:17:59 +0000 (21 17:17 +0800)]
wg: Port #20: rewrite ioctl API based on OpenBSD's version

DragonFly doesn't support the nv(9) API and I don't want to port it from
FreeBSD.  So rewrite the ioctl API based on OpenBSD's version, which
uses the wg_interface_io/wg_peer_io/wg_aip_io structs and is more
straightforward.

- Replace if_wg.h with OpenBSD's version, with minor style adjustments.
- Replace 'WG_INTERFACE_HAS_RTABLE' with 'WG_INTERFACE_HAS_COOKIE', as
  the FreeBSD WG supports the latter.
- Add compile-time assertions to make sure WG_KEY_SIZE is big enough.
- Replace 'wg_timespec64' struct with the standard 'timespec' struct
  since the former is no longer needed.
- Bring in custom peer description support from OpenBSD.

I'll later port the WG support to ifconfig(8) from OpenBSD as well.

2 months agowg: Port #19: adjust callout(9) API and replace MSEC_2_TICKS() macro
Aaron LI [Sat, 21 Oct 2023 02:00:42 +0000 (21 10:00 +0800)]
wg: Port #19: adjust callout(9) API and replace MSEC_2_TICKS() macro

2 months agowg: Port #18: adjust arc4random* functions
Aaron LI [Thu, 19 Oct 2023 08:42:16 +0000 (19 16:42 +0800)]
wg: Port #18: adjust arc4random* functions

2 months agowg: Port #17: adapt ifp->if_output() routine
Aaron LI [Thu, 19 Oct 2023 08:03:38 +0000 (19 16:03 +0800)]
wg: Port #17: adapt ifp->if_output() routine

Remove the original unsupported/unnecessary wg_transmit() routine, and
combine the wg_xmit() routine into wg_output() routine, and then adapt
it to our if_output() API.

WireGuard already implements the wg_queue API to queue the output
packets for encryption before sending, so we don't have to use any
if_snd/ifq/ifaltq_subque, thus ifp->if_start() can also be ignored.
However, we still need to call ifq_set_maxlen() and ifq_set_ready()
to suppress the warning "driver didn't set altq_maxlen".

2 months agowg: Port #16: remove unsupported IFCAP_LINKSTATE
Aaron LI [Thu, 19 Oct 2023 07:52:31 +0000 (19 15:52 +0800)]
wg: Port #16: remove unsupported IFCAP_LINKSTATE

2 months agowg: Port #15: adapt 'struct ifnet' related code and routines
Aaron LI [Wed, 18 Oct 2023 02:59:05 +0000 (18 10:59 +0800)]
wg: Port #15: adapt 'struct ifnet' related code and routines

Remove unsupported routines, like wg_qflush() and wg_reassign().
Also remove the unsupported 'IFF_DYING' workaround for IPv6.  If we also
have such an issue, should fix the IPv6 code.

TODO: rework the if_output() and if_start() routines.

2 months agowg: Port #14: replace MPASS() macro with KKASSERT()
Aaron LI [Wed, 18 Oct 2023 00:44:48 +0000 (18 08:44 +0800)]
wg: Port #14: replace MPASS() macro with KKASSERT()

2 months agowg: Add a missing bpfdetach() in wg_clone_destroy()
Aaron LI [Tue, 17 Oct 2023 01:16:15 +0000 (17 09:16 +0800)]
wg: Add a missing bpfdetach() in wg_clone_destroy()

2 months agowg: Port #13: adjust the BPF tap macro
Aaron LI [Tue, 17 Oct 2023 01:10:56 +0000 (17 09:10 +0800)]
wg: Port #13: adjust the BPF tap macro

2 months agowg: Port #12: remove unsupported vnet code and use if_clone only
Aaron LI [Wed, 11 Oct 2023 01:13:31 +0000 (11 09:13 +0800)]
wg: Port #12: remove unsupported vnet code and use if_clone only

In addition, change the module unloading logic a bit: prevent from
unloading and return the EBUSY error if the module is still in use.

2 months agowg: Port #11: remove unsupported FIB code
Aaron LI [Tue, 26 Sep 2023 06:02:54 +0000 (26 14:02 +0800)]
wg: Port #11: remove unsupported FIB code

We don't support multiple FIBs (forwarding information base), i.e.,
routing tables.

2 months agowg: Port #10: replace if_inc_counter() with IFNET_STAT_INC()
Aaron LI [Mon, 25 Sep 2023 09:02:46 +0000 (25 17:02 +0800)]
wg: Port #10: replace if_inc_counter() with IFNET_STAT_INC()

2 months agowg: Port #9: replace 'mp_ncpus' with 'ncpus'
Aaron LI [Mon, 25 Sep 2023 09:01:17 +0000 (25 17:01 +0800)]
wg: Port #9: replace 'mp_ncpus' with 'ncpus'

2 months agowg: Port #8: remove unsupported jail code
Aaron LI [Mon, 25 Sep 2023 08:59:32 +0000 (25 16:59 +0800)]
wg: Port #8: remove unsupported jail code