Module Name: src Committed By: riastradh Date: Mon Jul 29 02:28:58 UTC 2024
Modified Files: src/sys/net: if_wg.c Log Message: wg(4): Put force_rekey state in the session, not the peer. That way, there is a time when one thread has exclusive access to the state, in wg_destroy_session under the peer lock, when we can clear the state without racing against the data tx path. This will work more reliably than the atomic_swap_uint I used before. Noted by kre@. PR kern/55729: net/if_wg/t_misc:wg_rekey test case fails PR kern/56252: wg(4) state machine has race conditions PR kern/58463: if_wg does not work when idle. To generate a diff of this commit: cvs rdiff -u -r1.112 -r1.113 src/sys/net/if_wg.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/if_wg.c diff -u src/sys/net/if_wg.c:1.112 src/sys/net/if_wg.c:1.113 --- src/sys/net/if_wg.c:1.112 Sun Jul 28 14:55:30 2024 +++ src/sys/net/if_wg.c Mon Jul 29 02:28:58 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wg.c,v 1.112 2024/07/28 14:55:30 riastradh Exp $ */ +/* $NetBSD: if_wg.c,v 1.113 2024/07/29 02:28:58 riastradh Exp $ */ /* * Copyright (C) Ryota Ozaki <ozaki.ry...@gmail.com> @@ -41,7 +41,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.112 2024/07/28 14:55:30 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.113 2024/07/29 02:28:58 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_altq_enabled.h" @@ -522,6 +522,7 @@ struct wg_session { wgs_time_established; volatile uint32_t wgs_time_last_data_sent; + volatile bool wgs_force_rekey; bool wgs_is_initiator; uint32_t wgs_local_index; @@ -627,8 +628,6 @@ struct wg_peer { time_t wgp_handshake_start_time; - volatile unsigned wgp_force_rekey; - int wgp_n_allowedips; struct wg_allowedip wgp_allowedips[WG_ALLOWEDIPS]; @@ -1306,6 +1305,7 @@ wg_destroy_session(struct wg_softc *wg, wgs->wgs_remote_index = 0; wg_clear_states(wgs); wgs->wgs_state = WGS_STATE_UNKNOWN; + wgs->wgs_force_rekey = false; } /* @@ -3209,7 +3209,7 @@ wg_task_send_init_message(struct wg_soft */ wgs = wgp->wgp_session_stable; if (wgs->wgs_state == WGS_STATE_ESTABLISHED && - !atomic_swap_uint(&wgp->wgp_force_rekey, 0)) + !atomic_load_relaxed(&wgs->wgs_force_rekey)) return; /* @@ -4410,7 +4410,7 @@ wg_send_data_msg(struct wg_peer *wgp, st * secure session is REKEY-AFTER-TIME seconds old," */ WG_TRACE("rekey after time"); - atomic_store_relaxed(&wgp->wgp_force_rekey, 1); + atomic_store_relaxed(&wgs->wgs_force_rekey, true); wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); } @@ -4426,7 +4426,7 @@ wg_send_data_msg(struct wg_peer *wgp, st * transport data messages..." */ WG_TRACE("rekey after messages"); - atomic_store_relaxed(&wgp->wgp_force_rekey, 1); + atomic_store_relaxed(&wgs->wgs_force_rekey, true); wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); }