git: e0a1a2e47fbf - stable/14 - if_ovpn: improve reconnect handling

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Mon, 30 Dec 2024 20:45:04 UTC
The branch stable/14 has been updated by kp:

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

commit e0a1a2e47fbf1df75e054acced189819eaf7c4e7
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2024-12-18 16:10:29 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2024-12-30 20:42:57 +0000

    if_ovpn: improve reconnect handling
    
    When a DCO client reconnects (e.g. on server restart) OpenVPN may create a new
    socket rather than reusing the existing one. This used to be rejected because we
    expect all peers to use the same socket. However, if there are no peers it's
    safe to release the previous socket and install the tunnel function on the new
    one.
    
    See also:       https://redmine.pfsense.org/issues/15928
    MFC after:      2 weeks
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    
    (cherry picked from commit 3624de5394991c0cacd42d5a3b33e35c1a002e09)
---
 sys/net/if_ovpn.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c
index be75eff74d34..de7920981027 100644
--- a/sys/net/if_ovpn.c
+++ b/sys/net/if_ovpn.c
@@ -628,8 +628,20 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl)
 	}
 
 	/* Must be the same socket as for other peers on this interface. */
-	if (sc->so != NULL && so != sc->so)
-		goto error_locked;
+	if (sc->so != NULL && so != sc->so) {
+		if (! RB_EMPTY(&sc->peers)) {
+			ret = EBUSY;
+			goto error_locked;
+		}
+
+		/*
+		 * If we have no peers we can safely release the socket and accept
+		 * a new one.
+		 */
+		ret = udp_set_kernel_tunneling(sc->so, NULL, NULL, NULL);
+		sorele(sc->so);
+		sc->so = NULL;
+	}
 
 	if (sc->so == NULL)
 		sc->so = so;