dragonfly.git
6 months agoAdded support for Realtek E2600 (Killer Ethernet Adapter E2600).
Shingy Shabooya [Wed, 21 Feb 2024 14:52:41 +0000 (21 21:52 +0700)]
Added support for Realtek E2600 (Killer Ethernet Adapter E2600).

6 months agorc.d/wg: Simplify the quote() in the awk script
Aaron LI [Wed, 21 Feb 2024 05:16:17 +0000 (21 13:16 +0800)]
rc.d/wg: Simplify the quote() in the awk script

6 months agorc.d/wg: Fix issue in parsing a config file of no peers
Aaron LI [Wed, 21 Feb 2024 05:10:22 +0000 (21 13:10 +0800)]
rc.d/wg: Fix issue in parsing a config file of no peers

A config file may have only the [interface] section but no [peer]
sections.

6 months agorc.d/wg: Fix the mistake of the 'wg_config_dir' variable
Aaron LI [Tue, 20 Feb 2024 15:56:59 +0000 (20 23:56 +0800)]
rc.d/wg: Fix the mistake of the 'wg_config_dir' variable

Remove the local 'WG_CONFIG_DIR' variable that was used during the
development.  Use the 'wg_config_dir' variable loaded from 'rc.conf'
instead.

6 months agocrypto: Move blake2s_hmac() to its only user wg_noise.c
Aaron LI [Tue, 20 Feb 2024 13:51:24 +0000 (20 21:51 +0800)]
crypto: Move blake2s_hmac() to its only user wg_noise.c

The blake2s_hmac() is simply an ad-hoc HMAC implementation using the
BLAKE2s hash algorithm.  It's not generic; a proper solution is to
implement the HMAC construction that supports any hash algorithms.
Therefore, it's better to move blake2s_hmac() to wg_noise.c as
noise_hmac().

See also: https://git.zx2c4.com/wireguard-freebsd/commit/?id=5c5832279855722b939a381b9a291dc5ca2ee52e

6 months agoifconfig(8): Minor cleanups to ifwg.c
Aaron LI [Tue, 20 Feb 2024 13:41:10 +0000 (20 21:41 +0800)]
ifconfig(8): Minor cleanups to ifwg.c

Meanwhile, fix a minor typo in the error message of '-wgpka' command.

6 months agowg: Write rc(8) script to easily manage wg(4) interfaces
Aaron LI [Wed, 14 Feb 2024 15:17:04 +0000 (14 23:17 +0800)]
wg: Write rc(8) script to easily manage wg(4) interfaces

This "wg" rc(8) script is somewhat similar to the "wg-quick" tool on
Linux/FreeBSD.  It can be used to quickly start/stop the wg(4)
interfaces according to the wg.conf(5) configuration files in the
"/etc/wireguard" directory.

The syntax of wg.conf(5) configuration file is very similar to that
of "wg-quick" but with necessary changes and minor additions.  See
wg.conf(5) for details.

On the one hand, the new "wg_enable" and "wg_interfaces" variables in
"/etc/rc.conf" can be used to auto-configure the wg(4) interfaces during
the system startup.  See rc.conf(5) for more details.

On the other hand, this "wg" script can be manually called from the
command-line to start/stop the wg(4) interfaces.

Thanks to swildner for reviewing the man page.

6 months agorc.conf.5: Reorder "rc_conf_files" to group "rc_*" variables
Aaron LI [Wed, 14 Feb 2024 15:20:23 +0000 (14 23:20 +0800)]
rc.conf.5: Reorder "rc_conf_files" to group "rc_*" variables

7 months agowg: Change cpu_sfence() to release store + acquire load pair
Aaron LI [Thu, 8 Feb 2024 16:45:09 +0000 (9 00:45 +0800)]
wg: Change cpu_sfence() to release store + acquire load pair

Although DragonFly is currently x86-only and this is actually
unnecessary, update to use the store+load pairs for better
portability.

7 months agowg: Convert BPF_MTAP_AF() macro to inline function wg_bpf_ptap()
Aaron LI [Thu, 8 Feb 2024 16:25:25 +0000 (9 00:25 +0800)]
wg: Convert BPF_MTAP_AF() macro to inline function wg_bpf_ptap()

7 months agowg: Add RXCSUM support to avoid unnecessary checksum validation
Aaron LI [Thu, 8 Feb 2024 09:41:16 +0000 (8 17:41 +0800)]
wg: Add RXCSUM support to avoid unnecessary checksum validation

The packet that is about to be delivered in is authentic as ensured by
the AEAD tag, so we can tell the networking stack that this packet has
valid checksums and thus is unnecessary to check again.

Therefore, implement RXCSUM support for the wg interface, and update the
ioctl() to support to enable/disable this feature.

Meanwhile, move the mbuf flags clearance code just before the delivery,
i.e., netisr_queue() and wg_send().

7 months agowg: Track noise_{local,remote,keypair} allocations to detect leaks
Aaron LI [Thu, 8 Feb 2024 03:19:03 +0000 (8 11:19 +0800)]
wg: Track noise_{local,remote,keypair} allocations to detect leaks

Use lists to track the allocations of noise_{local,remote,keypair}
structs, and then assert that all of them have been freed upon the
module deinitialization.

Enclose the code within 'INVARIANTS' macro, so that it can be just
ignored when performance is important.

7 months agowg: Some code cleanups, minor improvements and comment updates
Aaron LI [Wed, 7 Feb 2024 14:25:49 +0000 (7 22:25 +0800)]
wg: Some code cleanups, minor improvements and comment updates

- Clean up some code logics to make the conditional flow and error
  handling more smooth.
- Add and update various comments to make the code more understandable.
  A large fraction of the comments are derived from the WireGuard code
  in Linux/OpenBSD, and from commit messages.

7 months agowg: Minor improvements to wg_ioctl_set()
Aaron LI [Wed, 7 Feb 2024 14:02:40 +0000 (7 22:02 +0800)]
wg: Minor improvements to wg_ioctl_set()

- Skip allowed IPs removal for a new peer.
- Try and send staged packets if the interface is UP.

Referred to the Linux version of WireGuard.

7 months agowg: Improve noise_keypair_received_with()
Aaron LI [Wed, 7 Feb 2024 13:56:46 +0000 (7 21:56 +0800)]
wg: Improve noise_keypair_received_with()

- Optimize the check flow by directly returning if the keypair is of an
  initiator.
- Add a brief function description and another comment.

7 months agowg: Refactor noise_keep_key_fresh_{send,recv}() functions
Aaron LI [Wed, 7 Feb 2024 13:06:45 +0000 (7 21:06 +0800)]
wg: Refactor noise_keep_key_fresh_{send,recv}() functions

These two functions were derived from the Linux version where called
keep_key_fresh() in {send,receive}.c.  However, they behaved differently
from their Linux version; i.e., they only checked whether the keypair
needed a refresh but didn't actually perform the refreshing.  So their
name was actually misleading.

Refactor these two functions and combine them into a single function
called noise_keypair_should_refresh(), with an extra parameter to
distinguish between the sending and receiving cases.

7 months agowg: Refactor cookie functions to make cookie_{checker,maker} opaque
Aaron LI [Mon, 5 Feb 2024 16:13:15 +0000 (6 00:13 +0800)]
wg: Refactor cookie functions to make cookie_{checker,maker} opaque

- Rename cookie_{checker,maker}_init() to cookie_{checker,maker}_alloc(),
  in symmetry with cookie_{checker,maker}_free().
- Make cookie_{checker,maker} structs opaque, and move them from
  wg_cookie.h to wg_cookie.c.
- Update if_wg.c and selftest code accordingly.

7 months agowg: Refactor and improve determine_af_and_pullup() and xmit_err()
Aaron LI [Sat, 3 Feb 2024 14:33:08 +0000 (3 22:33 +0800)]
wg: Refactor and improve determine_af_and_pullup() and xmit_err()

Meanwhile, clean up and improve wg_output(); simplifying the error
handling a lot.

7 months agowg: Cleanup static function prototypes in if_wg.c
Aaron LI [Sat, 3 Feb 2024 11:21:32 +0000 (3 19:21 +0800)]
wg: Cleanup static function prototypes in if_wg.c

- Group the static function prototypes.
- Remove unnecessary prototypes.
- Style cleanups.

7 months agowg: Improve wg_clone_destroy() and wg_down()
Aaron LI [Sat, 3 Feb 2024 06:49:35 +0000 (3 14:49 +0800)]
wg: Improve wg_clone_destroy() and wg_down()

- Move the cancellation of tasks from wg_clone_destroy() to wg_down(),
  which is actually more appropriate.
- Just call wg_down() in wg_clone_destroy() to reduce duplicate code.
- No need to call if_purgeaddrs_nolink(), as it will be called by
  if_detach().
- Detach and free the interface before destroying the aip radix trees,
  in order to avoid possible panics.

7 months agowg: Simplify socket so_lock scope and init/uninit
Aaron LI [Sat, 3 Feb 2024 05:28:53 +0000 (3 13:28 +0800)]
wg: Simplify socket so_lock scope and init/uninit

Move the init/uninit of the so_lock to wg_socket_init() and
wg_socket_uninit() respectively, making its scope more clear.

7 months agowg: Clean up noise_keypair_counter_check() a bit
Aaron LI [Tue, 30 Jan 2024 15:49:50 +0000 (30 23:49 +0800)]
wg: Clean up noise_keypair_counter_check() a bit

Remove '++recv' together with the '+ 1' calculation, so the code nows
becomes more understandable, and the conditional of
'kp->kp_counter_recv >= REJECT_AFTER_MESSAGES' also becomes the same as
the one in noise_keypair_decrypt(); so it reduces the confusion between
them.  The selftest is also passed.  (Referred to OpenBSD)

In addition, add brief comments to describe the 'kp_counter_send' and
'kp_counter_recv'.

7 months agowg: Improve noise_keypair_counter_check() to return different errnos
Aaron LI [Tue, 30 Jan 2024 15:12:58 +0000 (30 23:12 +0800)]
wg: Improve noise_keypair_counter_check() to return different errnos

Use different errnos (i.e., EINVAL, ESTALE, EEXIST) for different
failure cases in noise_keypair_counter_check().  Meanwhile, update the
selftest code to test this function more vigorously.

In addition, add function description and comments to help understand
it.

7 months agowg: Reorganize wg_packet and wg_queue functions
Aaron LI [Tue, 23 Jan 2024 15:50:18 +0000 (23 23:50 +0800)]
wg: Reorganize wg_packet and wg_queue functions

- Move the wg_packet and wg_queue functions to the beginning part, which
  seems more appropriate.
- Remove the unnecessary function prototypes.
- Add a brief description about the various queues, especially about the
  parallel and serial queues.
- Add several more comments to help understand the code.

No functional changes.

7 months agowg: Make peer ID start from 1 (instead of 0)
Aaron LI [Tue, 23 Jan 2024 15:45:55 +0000 (23 23:45 +0800)]
wg: Make peer ID start from 1 (instead of 0)

Use '++peer_counter' instead of 'peer_counter++' to generate the peer
ID, so make it start from 1.

Since 'peer_counter' is only used in wg_peer_create(), so move it into
this function.  In addition, drop the unnecessary 'volatile' qualifier,
because it's accessed with the 'sc_lock' exclusively hold.

7 months agowg: Rename wg_softc_*() functions to wg_*_worker()
Aaron LI [Mon, 15 Jan 2024 14:44:22 +0000 (15 22:44 +0800)]
wg: Rename wg_softc_*() functions to wg_*_worker()

This makes the code more understandable.

Referred-to: OpenBSD

7 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).

7 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.

7 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.

7 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.

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

7 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.

7 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.

7 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().

7 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).

7 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

7 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.

7 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

7 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.

7 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.

7 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

7 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

7 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

7 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

7 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

7 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.

7 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

7 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.

7 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.

7 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

7 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.

7 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().

7 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

7 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

7 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().

7 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

7 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

7 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'

7 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.

7 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()

7 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

7 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.

7 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.

7 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.

7 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.

7 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.

7 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'.

7 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

7 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().

7 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

7 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.

7 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.

7 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.

7 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

7 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

7 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.

7 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.

7 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.

7 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.

7 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

7 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.

7 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

7 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.

7 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.

7 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.

7 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.

7 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'.

7 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.

7 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

7 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.

7 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.

7 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.

7 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.

7 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().

7 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.

7 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.

7 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.

7 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.

7 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

7 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.