From nobody Thu Dec 01 16:43:34 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4NNMMp67K6z4jfcv; Thu, 1 Dec 2022 16:43:34 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4NNMMp5Z0Yz4S9L; Thu, 1 Dec 2022 16:43:34 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1669913014; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+NFTFUsN4sSgsS/3JzQ6ODXjz8iAHiUbWCMyo3QCjMo=; b=vyXlnowu2g8dFsoOrhq+51evEO1OTc+8o4/GDaJuLojDpCMzblEKM6FrJwUUMP15Z+4Wqb hx6QkISWyrBexWc9l/JRPCrF92fVjqmjKah1IrVldtPzh8RB2WgTn5cg83nZ/XclbQYMhW jJXbQxDH7W9K4Aq90bIa7VKuMEzigAzQsEsnhACPP6H1oyrcRljDcLouNDkIZ4KvEPEzNa 6iDp2ABrWADoDfPqC7XN0n6GIjnZuCkHF53gqsljmjGPi3wyXxzd954eIam8mli346uWD4 1UAKQ+dcmB0tfu6s5DwDXSa5HE2SIlioNaNHc/8VRqoz8u8arfy7nqWBPJnShw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1669913014; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+NFTFUsN4sSgsS/3JzQ6ODXjz8iAHiUbWCMyo3QCjMo=; b=i24pRopeWLKjsEo7Q6KyIj3ovwl3S/9d4NNjBXdvLQz1igXQIX55r3ELxVSP0gAXEJFh1S RLLqeQeQGhrCfDqVtz8iFAaxepheVNX33VpuNMHrxjjsOMlCTrJOF+uqfr71r0TtP/e09O KyoBQSh2FIV7DeaHdfNaY1mp4PL7ZhQ+9qNhTUety6vdjTxaDpuo9GnFH4wDIR/A/Qrpof tkKUXbzkJSTQG27QdHQRwqR9CWJBXz4w1+QbonuhBZj4CXsEYXtX6KHq1XScMwA4GDJNBB VwvTBuDj2Wji4f1blf+UwAVtmxg2xh/Pu6H0kVY3k8MTmo0gZxB9oG7oDBQ+LQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1669913014; a=rsa-sha256; cv=none; b=Y8/HXexWXiNEcwHEUFxwmh7o+yL9spbg1lwLl1vIPUJrJB8KqKbJU4R4aOkldkyWxHquHt Eud00u2BdevA18Po4wcBAt+oUF7QCadnA7+iDEyflWGl8TmzyJj/m+RyptGqbi/zrRG3Ls +Vai4T/jkrIX2H4fxkkWOL4N8pHfYuy6aQPXcrFmKMvO11wILdsgaZL/F0G4cr34sMwa/+ Jvx52mKxhDsfJUdfFmmQcwuTk1idAQ0NMbC8kwNkUY/8dDqS708rN3687Q13M5XOrVGbXi ZlIp7enqXJ6npZuZ6AayWDyi9YxPh3ARQcof4gPMM15F28obH5JdECLEQqd3kg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4NNMMp4dSyzkRM; Thu, 1 Dec 2022 16:43:34 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 2B1GhYDs078317; Thu, 1 Dec 2022 16:43:34 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 2B1GhY5U078316; Thu, 1 Dec 2022 16:43:34 GMT (envelope-from git) Date: Thu, 1 Dec 2022 16:43:34 GMT Message-Id: <202212011643.2B1GhY5U078316@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: 97c802923e20 - main - if_ovpn: remove peer limit List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 97c802923e20e96302dbe63fb9ca07c059d781aa Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=97c802923e20e96302dbe63fb9ca07c059d781aa commit 97c802923e20e96302dbe63fb9ca07c059d781aa Author: Kristof Provost AuthorDate: 2022-11-28 09:16:24 +0000 Commit: Kristof Provost CommitDate: 2022-12-01 16:42:57 +0000 if_ovpn: remove peer limit Replace the fixed-sized array by an RB_TREE. This should both speed up lookups and remove the 128 peer limit. Reviewed by: zlei Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D37524 --- sys/net/if_ovpn.c | 136 +++++++++++++++++++----------------------------------- 1 file changed, 48 insertions(+), 88 deletions(-) diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c index 276927275a2b..b8322558e0f1 100644 --- a/sys/net/if_ovpn.c +++ b/sys/net/if_ovpn.c @@ -122,6 +122,7 @@ struct ovpn_notification { struct ovpn_softc; struct ovpn_kpeer { + RB_ENTRY(ovpn_kpeer) tree; int refcount; uint32_t peerid; @@ -141,8 +142,6 @@ struct ovpn_kpeer { struct callout ping_rcv; }; -#define OVPN_MAX_PEERS 128 - struct ovpn_counters { uint64_t lost_ctrl_pkts_in; uint64_t lost_ctrl_pkts_out; @@ -162,13 +161,15 @@ struct ovpn_counters { }; #define OVPN_COUNTER_SIZE (sizeof(struct ovpn_counters)/sizeof(uint64_t)) +RB_HEAD(ovpn_kpeers, ovpn_kpeer); + struct ovpn_softc { int refcount; struct rmlock lock; struct ifnet *ifp; struct socket *so; int peercount; - struct ovpn_kpeer *peers[OVPN_MAX_PEERS]; /* XXX Hard limit for now? */ + struct ovpn_kpeers peers; /* Pending notification */ struct buf_ring *notifring; @@ -187,6 +188,10 @@ static int ovpn_encap(struct ovpn_softc *, uint32_t, struct mbuf *); static int ovpn_get_af(struct mbuf *); static void ovpn_free_kkey_dir(struct ovpn_kkey_dir *); static bool ovpn_check_replay(struct ovpn_kkey_dir *, uint32_t); +static int ovpn_peer_compare(struct ovpn_kpeer *, struct ovpn_kpeer *); + +static RB_PROTOTYPE(ovpn_kpeers, ovpn_kpeer, tree, ovpn_peer_compare); +static RB_GENERATE(ovpn_kpeers, ovpn_kpeer, tree, ovpn_peer_compare); #define OVPN_MTU_MIN 576 #define OVPN_MTU_MAX (IP_MAXPACKET - sizeof(struct ip) - \ @@ -246,25 +251,22 @@ SYSCTL_INT(_net_link_openvpn, OID_AUTO, netisr_queue, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(async_netisr_queue), 0, "Use netisr_queue() rather than netisr_dispatch()."); +static int +ovpn_peer_compare(struct ovpn_kpeer *a, struct ovpn_kpeer *b) +{ + return (a->peerid - b->peerid); +} + static struct ovpn_kpeer * ovpn_find_peer(struct ovpn_softc *sc, uint32_t peerid) { - struct ovpn_kpeer *p = NULL; + struct ovpn_kpeer p; OVPN_ASSERT(sc); - for (int i = 0; i < OVPN_MAX_PEERS; i++) { - p = sc->peers[i]; - if (p == NULL) - continue; - - if (p->peerid == peerid) { - MPASS(p->sc == sc); - break; - } - } + p.peerid = peerid; - return (p); + return (RB_FIND(ovpn_kpeers, &sc->peers, &p)); } static struct ovpn_kpeer * @@ -272,15 +274,7 @@ ovpn_find_only_peer(struct ovpn_softc *sc) { OVPN_ASSERT(sc); - for (int i = 0; i < OVPN_MAX_PEERS; i++) { - if (sc->peers[i] == NULL) - continue; - return (sc->peers[i]); - } - - MPASS(false); - - return (NULL); + return (RB_ROOT(&sc->peers)); } static uint16_t @@ -466,7 +460,7 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl) struct socket *so = NULL; int fd; uint32_t peerid; - int ret = 0, i; + int ret = 0; if (nvl == NULL) return (EINVAL); @@ -586,20 +580,9 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl) sc->so = so; /* Insert the peer into the list. */ - for (i = 0; i < OVPN_MAX_PEERS; i++) { - if (sc->peers[i] != NULL) - continue; - - MPASS(sc->peers[i] == NULL); - sc->peers[i] = peer; - sc->peercount++; - soref(sc->so); - break; - } - if (i == OVPN_MAX_PEERS) { - ret = ENOSPC; - goto error_locked; - } + RB_INSERT(ovpn_kpeers, &sc->peers, peer); + sc->peercount++; + soref(sc->so); ret = udp_set_kernel_tunneling(sc->so, ovpn_udp_input, NULL, sc); if (ret == EBUSY) { @@ -607,7 +590,7 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl) ret = 0; } if (ret != 0) { - sc->peers[i] = NULL; + RB_REMOVE(ovpn_kpeers, &sc->peers, peer); sc->peercount--; goto error_locked; } @@ -633,24 +616,16 @@ static int _ovpn_del_peer(struct ovpn_softc *sc, uint32_t peerid) { struct ovpn_kpeer *peer; - int i; OVPN_WASSERT(sc); CURVNET_ASSERT_SET(); - for (i = 0; i < OVPN_MAX_PEERS; i++) { - if (sc->peers[i] == NULL) - continue; - if (sc->peers[i]->peerid != peerid) - continue; - - peer = sc->peers[i]; - break; - } - if (i == OVPN_MAX_PEERS) + peer = ovpn_find_peer(sc, peerid); + if (peer == NULL) return (ENOENT); + peer = RB_REMOVE(ovpn_kpeers, &sc->peers, peer); + MPASS(peer != NULL); - sc->peers[i] = NULL; sc->peercount--; ovpn_peer_release_ref(peer, true); @@ -1362,6 +1337,8 @@ ovpn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) struct ifdrv *ifd; int error; + CURVNET_ASSERT_SET(); + switch (cmd) { case SIOCSDRVSPEC: case SIOCGDRVSPEC: @@ -1622,13 +1599,10 @@ ovpn_find_peer_by_ip(struct ovpn_softc *sc, const struct in_addr addr) OVPN_ASSERT(sc); - for (int i = 0; i < OVPN_MAX_PEERS; i++) { - if (sc->peers[i] == NULL) - continue; - if (addr.s_addr == sc->peers[i]->vpn4.s_addr) { - peer = sc->peers[i]; - break; - } + /* TODO: Add a second RB so we can look up by IP. */ + RB_FOREACH(peer, ovpn_kpeers, &sc->peers) { + if (addr.s_addr == peer->vpn4.s_addr) + return (peer); } return (peer); @@ -1643,13 +1617,10 @@ ovpn_find_peer_by_ip6(struct ovpn_softc *sc, const struct in6_addr *addr) OVPN_ASSERT(sc); - for (int i = 0; i < OVPN_MAX_PEERS; i++) { - if (sc->peers[i] == NULL) - continue; - if (memcmp(addr, &sc->peers[i]->vpn6, sizeof(*addr)) == 0) { - peer = sc->peers[i]; - break; - } + /* TODO: Add a third RB so we can look up by IPv6 address. */ + RB_FOREACH(peer, ovpn_kpeers, &sc->peers) { + if (memcmp(addr, &peer->vpn6, sizeof(*addr)) == 0) + return (peer); } return (peer); @@ -2281,21 +2252,16 @@ ovpn_reassign(struct ifnet *ifp, struct vnet *new_vnet __unused, char *unused __unused) { struct ovpn_softc *sc = ifp->if_softc; - int i; + struct ovpn_kpeer *peer, *tmppeer; int ret __diagused; - i = 0; - OVPN_WLOCK(sc); /* Flush keys & configuration. */ - do { - if (sc->peers[i] != NULL) { - ret = _ovpn_del_peer(sc, sc->peers[i]->peerid); - MPASS(ret == 0); - } - i++; - } while (i < OVPN_MAX_PEERS); + RB_FOREACH_SAFE(peer, ovpn_kpeers, &sc->peers, tmppeer) { + ret = _ovpn_del_peer(sc, peer->peerid); + MPASS(ret == 0); + } ovpn_flush_rxring(sc); @@ -2393,9 +2359,7 @@ ovpn_clone_destroy_cb(struct epoch_context *ctx) sc = __containerof(ctx, struct ovpn_softc, epoch_ctx); MPASS(sc->peercount == 0); - for (int i = 0; i < OVPN_MAX_PEERS; i++) { - MPASS(sc->peers[i] == NULL); - } + MPASS(RB_EMPTY(&sc->peers)); COUNTER_ARRAY_FREE(sc->counters, OVPN_COUNTER_SIZE); @@ -2407,8 +2371,8 @@ static int ovpn_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags) { struct ovpn_softc *sc; + struct ovpn_kpeer *peer, *tmppeer; int unit; - int i; int ret __diagused; sc = ifp->if_softc; @@ -2421,14 +2385,10 @@ ovpn_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags) return (EBUSY); } - i = 0; - do { - if (sc->peers[i] != NULL) { - ret = _ovpn_del_peer(sc, sc->peers[i]->peerid); - MPASS(ret == 0); - } - i++; - } while (i < OVPN_MAX_PEERS); + RB_FOREACH_SAFE(peer, ovpn_kpeers, &sc->peers, tmppeer) { + ret = _ovpn_del_peer(sc, peer->peerid); + MPASS(ret == 0); + } ovpn_flush_rxring(sc); buf_ring_free(sc->notifring, M_OVPN);