aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* if_wg: remove M_WAITOK, check return codes on initMatt Dunwoodie2021-04-232-68/+90
| | | | | | | | | | | | | | | Here we remove all M_WAITOK checks, because we don't want to hang while trying to allocate memory. It is better to return an error so the user can try again later. We also make sure to check all the return codes in peer and interface allocation. The structure of those functions is: 1) Allocate all memory 2) Initialise fields in order of the struct 3) Cleanup gotos Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* if_wg: check wg_module_init succeededMatt Dunwoodie2021-04-231-9/+15
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* if_wg: set snd_tag to NULL after releasingJason A. Donenfeld2021-04-221-1/+3
| | | | | | The rest of the stack does this. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: destroy interfaces on module unloadJason A. Donenfeld2021-04-221-10/+4
| | | | | | This is already done anyway by if_clone_detach, so let that happen. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* wg_cookie: import optional inet6 headersJason A. Donenfeld2021-04-221-0/+2
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* wg_cookie: hash vnet into ratelimiter entryJason A. Donenfeld2021-04-225-62/+46
| | | | | | IPs mean different things per-vnet. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: properly use rn_inithead and rn_detachheadJason A. Donenfeld2021-04-224-35/+59
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* wg_cookie: allocate ratelimit table staticallyMatt Dunwoodie2021-04-232-34/+26
| | | | | | | | | | | | | | | We can simplify the ratelimit init/deinit calls by allocating the table statically, that is by not using hashinit_flags. That function ended up doing some unnecessary calculation and meant that the mask couldn't be constant. By increasing the size of struct ratelimit, this also caught a nasty (but benign) bug, where ratelimit_pool was initialised to allocate sizeof(struct ratelimit) and not sizeof(struct ratelimit_entry). It has been this way since FreeBSD tree and I didn't pick up on it while moving the uma_zcreate call to wg_cookie. Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* wg_cookie: cleanup internal codeMatt Dunwoodie2021-04-232-70/+68
| | | | | | | | | | | | | | The two main changes here are: * Remove cookie_ prefix from static functions. This is a leftover from OpenBSD where they don't want static functions. * Rename cm to macs, and cp to cm. Not sure where this came from but it didn't really make much sense to leave it as is. The reset are whitespace changes. Overall there is no modification to functionality here, just appearances. Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* wg_cookie: add cookie_valid boolMatt Dunwoodie2021-04-233-20/+22
| | | | | | | | | | | | | | | | | | | | | | | | Primarily this commit adds a cookie_valid state, to prevent a recently booted machine from sending a mac2. We also do a little bit of reworking on locking and a fixup for int to bool. There is one slight difference to cookie_valid (latest_cookie.is_valid) on Linux and that is to set cookie_valid to false when the cookie_birthdate has expired. The purpose of this is to prevent the expensive timer check after it has expired. For the locking, we want to hold a write lock in cookie_maker_mac because we write to mac1_last, mac1_valid and cookie_valid. This wouldn't cause too much contention as this is a per peer lock and we only do so when sending handshake packets. This is different from Linux as Linux writes all it's variables at the start, then downgrades to a read lock. We also match cookie_maker_consume_payload locking to Linux, that is to read lock while checking mac1_valid and decrypting the cookie then take a write lock to set the cookie. Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* wg_cookie: make ratelimiter globalMatt Dunwoodie2021-04-235-115/+113
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* TODO: more nitsJason A. Donenfeld2021-04-221-2/+12
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: add more usual string concat spacingJason A. Donenfeld2021-04-221-14/+14
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: correct logic in tag clearingJason A. Donenfeld2021-04-221-1/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* global: add missing bracketsJason A. Donenfeld2021-04-222-2/+4
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: more thorough wg_mbuf_resetMatt Dunwoodie2021-04-221-6/+36
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* if_wg: better loop detectionMatt Dunwoodie2021-04-221-3/+4
| | | | | | | | | | | | | While it was nice to have per peer loop detection, it was not meant to be. The loop tag has a tag type == 0, which conflicts with other tags. Therefore we want to at least be a little bit more sure that the tag cookie is unique to the loop tag. I guess the peer address was also quite hacky so on the other side, I'm glad to be rid of that. Now we have a loop of 8 (to any peer) which should be good enough for an edge case operation. Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* selftests: fixup headersJason A. Donenfeld2021-04-224-12/+14
| | | | | | Also remove the stale entry from the TODO list. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* wg_noise: add selftestMatt Dunwoodie2021-04-224-0/+100
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* wg_cookie: add selftestMatt Dunwoodie2021-04-224-0/+303
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* if_wg: port allowedips selftest from Linux code and fix bugsJason A. Donenfeld2021-04-223-66/+674
| | | | | | | And then fix broken allowedips implementation for the static unit tests to pass. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* wg_cookie: ensure gc is called regularlyMatt Dunwoodie2021-04-212-29/+44
| | | | | | | | | | | | | | | | | Previously we relied on gc being called when adding a new entry, which could leave us in a gc "blind spot". With this change, we schedule a callout to run gc whenever we have entries in the table. The callout will continue to run every ELEMENT_TIMEOUT seconds until the table is empty. Access to rl_gc is locked by rl_lock, so we will never have any threads racing to callout_{pending,stop,reset}. The alternative (which Linux does currently) is just to run the callout every ELEMENT_TIMEOUT (1) second even when no entries are in the table. However, the callout solution proposed here seems simple enough. Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* global: update timer-type commentsJason A. Donenfeld2021-04-202-5/+5
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* global: cleanup openbsd lock definesJason A. Donenfeld2021-04-204-60/+26
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* global: use ck for loads/stores, rather than macro mazeJason A. Donenfeld2021-04-204-86/+70
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* global: move siphash helper out of supportJason A. Donenfeld2021-04-204-32/+24
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* TODO: add a few thingsJason A. Donenfeld2021-04-201-0/+4
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* global: use sbintime_t consistentlyJason A. Donenfeld2021-04-204-48/+45
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* wg_noise: inline noise_timer_expired to make expensive multiplication go awayJason A. Donenfeld2021-04-201-1/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: minor code cleanup, improve readabilityMatt Dunwoodie2021-04-211-69/+75
| | | | | | | | | | | Nothing serious here, just use a goto in wg_deliver_{in,out} rather than another if/else indentation. The code should have no functional change, just improve readability. Additionally, use a local `sc` variable rather than `peer->p_sc` in spots. Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* wg_noise: unify two state bools to an enumMatt Dunwoodie2021-04-211-14/+16
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* global: use proper boolean typesJason A. Donenfeld2021-04-204-46/+49
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* wg_noise: ensure we check peer count on hashtable insertMatt Dunwoodie2021-04-213-11/+19
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* wg_noise: avoid handshake/keypair type confusionMatt Dunwoodie2021-04-203-7/+16
| | | | | | | | | | | | | | | | | | | | So the last change broke consuming responses, as it may return an invalid remote pointer. Thanks for the catch zx2c4. We just pass a flag "lookup_keypair" which will lookup the keypair when we want (for cookie) and will not when we don't (for consuming responses). It would be possible to merge both noise_remote_index_lookup and noise_keypair_lookup, but the result would probably need to return a void * (for both keypair and remote) or a noise_index * which would need to be cast to the relevant type somewhere. The trickiest thing here would be for if_wg to "put" the result of the function, as it may be a remote or a keypair (which store their refcount in different locations). Perhaps it would return a noise_index * which could contain the refcount for both keypair and remote. It all seems easier to leave them separate. The only argument for combining them would be to reduce duplication of (similar) functions. Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* wg_noise: insert/remove peer independent of alloc/destroyMatt Dunwoodie2021-04-203-34/+49
| | | | | | | | | This is needed, to remove the peer from the public key hashtable before calling noise_remote_destroy. This will prevent any incoming handshakes from starting in that time. It also cleans up the insert path to make it more like it was before the wg_noise EPOCH changes. Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* wg_noise: assign index without lock then checkMatt Dunwoodie2021-04-201-1/+11
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* wg_noise: remove duplicate peer checkMatt Dunwoodie2021-04-201-5/+1
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* if_wg: remove unused loadMatt Dunwoodie2021-04-201-1/+0
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* wg_noise: check keypair recvwith after nonceMatt Dunwoodie2021-04-203-38/+31
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* wg_noise: use sbintime_t instead of timespecMatt Dunwoodie2021-04-201-23/+19
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* wg_noise: no need to enter epoch hereMatt Dunwoodie2021-04-201-6/+1
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* wg_noise: whitespace cleanupMatt Dunwoodie2021-04-201-5/+0
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* wg_noise: lookup both keypair and handshake index at onceMatt Dunwoodie2021-04-202-9/+10
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* if_wg: add missing return parens to follow style(9)Jason A. Donenfeld2021-04-191-25/+25
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* if_wg: allow v4 xor v6 socket binding to fail with EADDRNOTAVAILJason A. Donenfeld2021-04-191-21/+40
| | | | | | | | | | | This happens if a jail does not have an interface with a configured v4 or v6 address. In that case, we just fall back to only having one socket for the address family that does exist. In the case that neither socket can be created, fail as before. Closes: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=254212 Reported-by: Mark Johnston <markj@FreeBSD.org> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* crypto: chacha and poly in same loopMatt Dunwoodie2021-04-191-92/+58
| | | | | | | | | | This is a fixup of f685f466, where previously we chacha'd in a different loop to poly'ing. Now we do in the same loop to keep the cache hot. In practice this didn't result in an (easily) observable change, which could be due to only having 1-2 mbufs in a chain. However this is still the preferred way to do it. Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* if_wg: fixup wg_mbuf_resetMatt Dunwoodie2021-04-191-2/+0
| | | | | | | Zeroing these values broke TCP recv, so not great, just remove them and hope they don't store anything secret. Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* if_wg: replace %lu with PRIu64Matt Dunwoodie2021-04-191-14/+15
| | | | | | | | While on __LP64__ uint64_t is unsigned long, that is not the case for !__LP64__, which is commonly unsigned long long. Here we use the PRIu64 macro as defined in machine/_inttypes.h. Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* if_wg: fix up bodged wg_mbuf_resetMatt Dunwoodie2021-04-191-3/+3
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
* if_wg: add wg_mbuf_reset to clear metadataMatt Dunwoodie2021-04-191-2/+14
| | | | Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>