Page MenuHomeFreeBSD

D46670.diff
No OneTemporary

D46670.diff

diff --git a/sys/dev/wg/if_wg.c b/sys/dev/wg/if_wg.c
--- a/sys/dev/wg/if_wg.c
+++ b/sys/dev/wg/if_wg.c
@@ -317,7 +317,7 @@
static void wg_aip_remove_all(struct wg_softc *, struct wg_peer *);
static struct wg_peer *wg_peer_alloc(struct wg_softc *, const uint8_t [WG_KEY_SIZE]);
static void wg_peer_free_deferred(struct noise_remote *);
-static void wg_peer_destroy(struct wg_peer *);
+static void wg_peer_destroy(struct wg_peer *, bool);
static void wg_peer_destroy_all(struct wg_softc *);
static void wg_peer_send_buf(struct wg_peer *, uint8_t *, size_t);
static void wg_send_initiation(struct wg_peer *);
@@ -451,7 +451,7 @@
}
static void
-wg_peer_destroy(struct wg_peer *peer)
+wg_peer_destroy(struct wg_peer *peer, bool linked)
{
struct wg_softc *sc = peer->p_sc;
sx_assert(&sc->sc_lock, SX_XLOCKED);
@@ -468,8 +468,11 @@
/* Remove peer from the interface, then free. Some references may still
* exist to p_remote, so noise_remote_free will wait until they're all
* put to call wg_peer_free_deferred. */
- sc->sc_peers_num--;
- TAILQ_REMOVE(&sc->sc_peers, peer, p_entry);
+ if (linked) {
+ sc->sc_peers_num--;
+ TAILQ_REMOVE(&sc->sc_peers, peer, p_entry);
+ }
+
DPRINTF(sc, "Peer %" PRIu64 " destroyed\n", peer->p_id);
noise_remote_free(peer->p_remote, wg_peer_free_deferred);
}
@@ -479,7 +482,7 @@
{
struct wg_peer *peer, *tpeer;
TAILQ_FOREACH_SAFE(peer, &sc->sc_peers, p_entry, tpeer)
- wg_peer_destroy(peer);
+ wg_peer_destroy(peer, true);
}
static void
@@ -2398,7 +2401,7 @@
if (nvlist_exists_bool(nvl, "remove") &&
nvlist_get_bool(nvl, "remove")) {
if (remote != NULL) {
- wg_peer_destroy(peer);
+ wg_peer_destroy(peer, true);
noise_remote_put(remote);
}
return (0);
@@ -2481,8 +2484,14 @@
noise_remote_put(remote);
return (0);
out:
- if (need_insert) /* If we fail, only destroy if it was new. */
- wg_peer_destroy(peer);
+ /*
+ * If we fail, only destroy if it was new. Linking the peer into the
+ * device's peer tailq and accounting for it in sc_peers_num only
+ * happens after every other plausible failure path, so if we got here
+ * then we should avoid those parts of wg_peer_destroy().
+ */
+ if (need_insert)
+ wg_peer_destroy(peer, false);
if (remote != NULL)
noise_remote_put(remote);
return (err);
@@ -2552,7 +2561,7 @@
if ((remote = noise_remote_lookup(sc->sc_local,
public)) != NULL) {
peer = noise_remote_arg(remote);
- wg_peer_destroy(peer);
+ wg_peer_destroy(peer, true);
noise_remote_put(remote);
}
}

File Metadata

Mime Type
text/plain
Expires
Thu, Nov 14, 10:20 PM (8 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
11722301
Default Alt Text
D46670.diff (2 KB)

Event Timeline