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 <[email protected]>
@@ -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);
}