git: da69782bf066 - main - if_ovpn: extend notifications with a reason

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Mon, 05 Dec 2022 10:29:50 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=da69782bf06645f38852a8b23afc965fc30d0e08

commit da69782bf06645f38852a8b23afc965fc30d0e08
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2022-12-01 15:20:24 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2022-12-05 10:09:34 +0000

    if_ovpn: extend notifications with a reason
    
    Extend peer deleted notifications (which are the only type right now) to
    include the reason the peer was deleted. This can be either because
    userspace requested it, or because the peer timed out.
    
    Reviewed by:    zlei
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D37583
---
 sys/net/if_ovpn.c | 35 ++++++++++++++++++++++++-----------
 sys/net/if_ovpn.h |  5 +++++
 2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c
index b8322558e0f1..0f326512b236 100644
--- a/sys/net/if_ovpn.c
+++ b/sys/net/if_ovpn.c
@@ -116,6 +116,7 @@ struct ovpn_wire_header {
 
 struct ovpn_notification {
 	enum ovpn_notif_type	type;
+	enum ovpn_del_reason	del_reason;
 	uint32_t		peerid;
 };
 
@@ -136,6 +137,7 @@ struct ovpn_kpeer {
 	struct ovpn_kkey	 keys[2];
 	uint32_t		 tx_seq;
 
+	enum ovpn_del_reason	 del_reason;
 	struct ovpn_keepalive	 keepalive;
 	uint32_t		*last_active;
 	struct callout		 ping_send;
@@ -388,6 +390,7 @@ ovpn_notify_del_peer(struct ovpn_softc *sc, struct ovpn_kpeer *peer)
 
 	n->peerid = peer->peerid;
 	n->type = OVPN_NOTIF_DEL_PEER;
+	n->del_reason = peer->del_reason;
 	if (buf_ring_enqueue(sc->notifring, n) != 0) {
 		free(n, M_OVPN);
 	} else if (sc->so != NULL) {
@@ -613,18 +616,17 @@ done:
 }
 
 static int
-_ovpn_del_peer(struct ovpn_softc *sc, uint32_t peerid)
+_ovpn_del_peer(struct ovpn_softc *sc, struct ovpn_kpeer *peer)
 {
-	struct ovpn_kpeer *peer;
+	struct ovpn_kpeer *tmp __diagused;
 
 	OVPN_WASSERT(sc);
 	CURVNET_ASSERT_SET();
 
-	peer = ovpn_find_peer(sc, peerid);
-	if (peer == NULL)
-		return (ENOENT);
-	peer = RB_REMOVE(ovpn_kpeers, &sc->peers, peer);
-	MPASS(peer != NULL);
+	MPASS(RB_FIND(ovpn_kpeers, &sc->peers, peer) == peer);
+
+	tmp = RB_REMOVE(ovpn_kpeers, &sc->peers, peer);
+	MPASS(tmp != NULL);
 
 	sc->peercount--;
 
@@ -637,6 +639,7 @@ static int
 ovpn_del_peer(struct ifnet *ifp, nvlist_t *nvl)
 {
 	struct ovpn_softc *sc = ifp->if_softc;
+	struct ovpn_kpeer *peer;
 	uint32_t peerid;
 	int ret;
 
@@ -650,7 +653,12 @@ ovpn_del_peer(struct ifnet *ifp, nvlist_t *nvl)
 
 	peerid = nvlist_get_number(nvl, "peerid");
 
-	ret = _ovpn_del_peer(sc, peerid);
+	peer = ovpn_find_peer(sc, peerid);
+	if (peer == NULL)
+		return (ENOENT);
+
+	peer->del_reason = OVPN_DEL_REASON_REQUESTED;
+	ret = _ovpn_del_peer(sc, peer);
 
 	return (ret);
 }
@@ -1032,7 +1040,8 @@ ovpn_timeout(void *arg)
 	}
 
 	CURVNET_SET(sc->ifp->if_vnet);
-	ret = _ovpn_del_peer(sc, peer->peerid);
+	peer->del_reason = OVPN_DEL_REASON_TIMEOUT;
+	ret = _ovpn_del_peer(sc, peer);
 	MPASS(ret == 0);
 	CURVNET_RESTORE();
 }
@@ -1274,6 +1283,8 @@ opvn_get_pkt(struct ovpn_softc *sc, nvlist_t **onvl)
 	}
 	nvlist_add_number(nvl, "peerid", n->peerid);
 	nvlist_add_number(nvl, "notification", n->type);
+	if (n->type == OVPN_NOTIF_DEL_PEER)
+		nvlist_add_number(nvl, "del_reason", n->del_reason);
 	free(n, M_OVPN);
 
 	*onvl = nvl;
@@ -2259,7 +2270,8 @@ ovpn_reassign(struct ifnet *ifp, struct vnet *new_vnet __unused,
 
 	/* Flush keys & configuration. */
 	RB_FOREACH_SAFE(peer, ovpn_kpeers, &sc->peers, tmppeer) {
-		ret = _ovpn_del_peer(sc, peer->peerid);
+		peer->del_reason = OVPN_DEL_REASON_REQUESTED;
+		ret = _ovpn_del_peer(sc, peer);
 		MPASS(ret == 0);
 	}
 
@@ -2386,7 +2398,8 @@ ovpn_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
 	}
 
 	RB_FOREACH_SAFE(peer, ovpn_kpeers, &sc->peers, tmppeer) {
-		ret = _ovpn_del_peer(sc, peer->peerid);
+		peer->del_reason = OVPN_DEL_REASON_REQUESTED;
+		ret = _ovpn_del_peer(sc, peer);
 		MPASS(ret == 0);
 	}
 
diff --git a/sys/net/if_ovpn.h b/sys/net/if_ovpn.h
index fd1c21e70435..3db36f5b0539 100644
--- a/sys/net/if_ovpn.h
+++ b/sys/net/if_ovpn.h
@@ -38,6 +38,11 @@ enum ovpn_notif_type {
 	OVPN_NOTIF_DEL_PEER,
 };
 
+enum ovpn_del_reason {
+	OVPN_DEL_REASON_REQUESTED	= 0,
+	OVPN_DEL_REASON_TIMEOUT		= 1
+};
+
 enum ovpn_key_slot {
 	OVPN_KEY_SLOT_PRIMARY	= 0,
 	OVPN_KEY_SLOT_SECONDARY	= 1