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);
 	}
 

Reply via email to