From nobody Wed Dec 14 05:49:45 2022 X-Original-To: dev-commits-src-main@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 4NX4FP4HzHz4kvny; Wed, 14 Dec 2022 05:49:45 +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 4NX4FP2dxWz3PSM; Wed, 14 Dec 2022 05:49:45 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1670996985; 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=tFHb7rBSyej4Wm27FKzlsWJWFogOGrhiZYN/ii1MaPg=; b=MUNuD2MBjizduThcTAPi3fLUMcIf2yGZB0XYWWVdYly7AdsT+9W5OS1lJUtl4jXUhC1tA9 BYY3QTNawyA/B0FbVdYlS/klwQ0bpvDZnNpoLzScHCMsYVuuKooMO8M+cq9XxlWUlJaQNB yLCNAGc4H0T+xjQ6jac5t6ZPOTMsXRXs59bluI0qI9kRD1vofrL6XqBPZq8HXDy+xX8ZOw uRlUUEKvjkor+iuIoxWBGO0A26Qu1pbv9T/WkbPBqw9r5diFHBueldHYb6/xbB3w7HMphg nHBs/PchCZa7QnOjm/AKt0GRi4DKuwrsNLFXnUr7Ch4UXwvCm7rabY7PlXtHPA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1670996985; 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=tFHb7rBSyej4Wm27FKzlsWJWFogOGrhiZYN/ii1MaPg=; b=KeRE153UTfrRxwrwlxF0Azuva/dEIyjKXvIl7/wLPLLUPSA4kAurxzTptwsiPGnordqPLM GcLD+ZsNkVa7oH0MXLEDI2NdvEY2GWAIghHnCO7EHFgL+YbznEMdEKh1l15Eh3bhjS4zlj ljEpSnBeFl54il0mWXCAo6sA4g2oO+rZRdeojXl23NZV5VdW+6G/UYesjhKESBOHCGEdnd vktoIYaDwPAXbCN9enZgsrDCqKCrYv2QS2isRhbH1WxZ6h1SmVwfzwGttI6gZMru5EfYIe dF0N6x1UiC+BNtL1wG6ZWJ6yHV9eIF22uZ15Cky+zM11jOTd8eKFl3ljAwuh6w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1670996985; a=rsa-sha256; cv=none; b=pFmTZIpiKMNrMX4xvuhjzXxbwjIl7rWWkEeOt7kgjTA9rekWP3ew+tkG2agsgOhldeMy0d 55AZoIC/bmgHqldwZIvTwfSQJ7WRwQ3BhRZjPxYITGCXKVV6Sfvwghdx25qN8NIK5cWnrE +IXYTvtCtI6jaXmS8f4trbeq99l8Y+ZYgL5yzugqje3cCIuQDk6yBiNgwq+aP2iohjfYPW NX1ThV39VlXmXOoCfnycODGJ6T2sQfcpRCGoEotcCHSRdRSlAmvajoVP9v1oc981opWO1/ o97Finh4i0DYeoufcNfONsJeQPGBLLPuCh+aJqK8VK2exOCjaAxtJ8pNJp6GQw== 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 4NX4FP1kRszjd4; Wed, 14 Dec 2022 05:49:45 +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 2BE5njc5034661; Wed, 14 Dec 2022 05:49:45 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 2BE5njUg034660; Wed, 14 Dec 2022 05:49:45 GMT (envelope-from git) Date: Wed, 14 Dec 2022 05:49:45 GMT Message-Id: <202212140549.2BE5njUg034660@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: 92f0cf77db18 - main - if_ovpn: allow peer lookup by vpn4/vpn6 address List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@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: 92f0cf77db18502cac9a731cd2f6e8f3cc8a9369 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=92f0cf77db18502cac9a731cd2f6e8f3cc8a9369 commit 92f0cf77db18502cac9a731cd2f6e8f3cc8a9369 Author: Kristof Provost AuthorDate: 2022-11-29 11:06:32 +0000 Commit: Kristof Provost CommitDate: 2022-12-14 05:48:59 +0000 if_ovpn: allow peer lookup by vpn4/vpn6 address Introduce two more RB_TREEs so that we can look up peers by their peer id (already present) or vpn4 or vpn6 address. This removes the last linear scan of the peer list. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D37605 --- sys/net/if_ovpn.c | 81 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 18 deletions(-) diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c index 2cfe55568348..cf5f2cc6fcf6 100644 --- a/sys/net/if_ovpn.c +++ b/sys/net/if_ovpn.c @@ -174,6 +174,8 @@ struct ovpn_counters { #define OVPN_COUNTER_SIZE (sizeof(struct ovpn_counters)/sizeof(uint64_t)) RB_HEAD(ovpn_kpeers, ovpn_kpeer); +RB_HEAD(ovpn_kpeers_by_ip, ovpn_kpeer); +RB_HEAD(ovpn_kpeers_by_ip6, ovpn_kpeer); struct ovpn_softc { int refcount; @@ -182,6 +184,8 @@ struct ovpn_softc { struct socket *so; int peercount; struct ovpn_kpeers peers; + struct ovpn_kpeers_by_ip peers_by_ip; + struct ovpn_kpeers_by_ip6 peers_by_ip6; /* Pending notification */ struct buf_ring *notifring; @@ -192,6 +196,10 @@ struct ovpn_softc { }; static struct ovpn_kpeer *ovpn_find_peer(struct ovpn_softc *, uint32_t); +static struct ovpn_kpeer *ovpn_find_peer_by_ip(struct ovpn_softc *, + const struct in_addr); +static struct ovpn_kpeer *ovpn_find_peer_by_ip6(struct ovpn_softc *, + const struct in6_addr *); static bool ovpn_udp_input(struct mbuf *, int, struct inpcb *, const struct sockaddr *, void *); static int ovpn_transmit_to_peer(struct ifnet *, struct mbuf *, @@ -200,10 +208,23 @@ 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 int ovpn_peer_compare(const struct ovpn_kpeer *, + const struct ovpn_kpeer *); +static int ovpn_peer_compare_by_ip(const struct ovpn_kpeer *, + const struct ovpn_kpeer *); +static int ovpn_peer_compare_by_ip6(const struct ovpn_kpeer *, + const 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); +static RB_PROTOTYPE(ovpn_kpeers_by_ip, ovpn_kpeer, tree, + ovpn_peer_compare_by_ip); +static RB_GENERATE(ovpn_kpeers_by_ip, ovpn_kpeer, tree, + ovpn_peer_compare_by_ip); +static RB_PROTOTYPE(ovpn_kpeers_by_ip6, ovpn_kpeer, tree, + ovpn_peer_compare_by_ip6); +static RB_GENERATE(ovpn_kpeers_by_ip6, ovpn_kpeer, tree, + ovpn_peer_compare_by_ip6); #define OVPN_MTU_MIN 576 #define OVPN_MTU_MAX (IP_MAXPACKET - sizeof(struct ip) - \ @@ -267,11 +288,24 @@ SYSCTL_INT(_net_link_openvpn, OID_AUTO, netisr_queue, "Use netisr_queue() rather than netisr_dispatch()."); static int -ovpn_peer_compare(struct ovpn_kpeer *a, struct ovpn_kpeer *b) +ovpn_peer_compare(const struct ovpn_kpeer *a, const struct ovpn_kpeer *b) { return (a->peerid - b->peerid); } +static int +ovpn_peer_compare_by_ip(const struct ovpn_kpeer *a, const struct ovpn_kpeer *b) +{ + return (memcmp(&a->vpn4, &b->vpn4, sizeof(a->vpn4))); +} + +static int +ovpn_peer_compare_by_ip6(const struct ovpn_kpeer *a, + const struct ovpn_kpeer *b) +{ + return (memcmp(&a->vpn6, &b->vpn6, sizeof(a->vpn6))); +} + static struct ovpn_kpeer * ovpn_find_peer(struct ovpn_softc *sc, uint32_t peerid) { @@ -596,8 +630,14 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl) if (sc->so == NULL) sc->so = so; - /* Insert the peer into the list. */ + /* Insert the peer into the lists. */ RB_INSERT(ovpn_kpeers, &sc->peers, peer); + if (nvlist_exists_binary(nvl, "vpn_ipv4")) { + RB_INSERT(ovpn_kpeers_by_ip, &sc->peers_by_ip, peer); + } + if (nvlist_exists_binary(nvl, "vpn_ipv6")) { + RB_INSERT(ovpn_kpeers_by_ip6, &sc->peers_by_ip6, peer); + } sc->peercount++; soref(sc->so); @@ -608,6 +648,12 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl) } if (ret != 0) { RB_REMOVE(ovpn_kpeers, &sc->peers, peer); + if (nvlist_exists_binary(nvl, "vpn_ipv4")) { + RB_REMOVE(ovpn_kpeers_by_ip, &sc->peers_by_ip, peer); + } + if (nvlist_exists_binary(nvl, "vpn_ipv6")) { + RB_REMOVE(ovpn_kpeers_by_ip6, &sc->peers_by_ip6, peer); + } sc->peercount--; goto error_locked; } @@ -633,7 +679,7 @@ done: static int _ovpn_del_peer(struct ovpn_softc *sc, struct ovpn_kpeer *peer) { - struct ovpn_kpeer *tmp __diagused; + struct ovpn_kpeer *tmp; OVPN_WASSERT(sc); CURVNET_ASSERT_SET(); @@ -643,6 +689,13 @@ _ovpn_del_peer(struct ovpn_softc *sc, struct ovpn_kpeer *peer) tmp = RB_REMOVE(ovpn_kpeers, &sc->peers, peer); MPASS(tmp != NULL); + tmp = ovpn_find_peer_by_ip(sc, peer->vpn4); + if (tmp) + RB_REMOVE(ovpn_kpeers_by_ip, &sc->peers_by_ip, tmp); + tmp = ovpn_find_peer_by_ip6(sc, &peer->vpn6); + if (tmp) + RB_REMOVE(ovpn_kpeers_by_ip6, &sc->peers_by_ip6, tmp); + sc->peercount--; ovpn_peer_release_ref(peer, true); @@ -1628,17 +1681,13 @@ ovpn_get_af(struct mbuf *m) static struct ovpn_kpeer * ovpn_find_peer_by_ip(struct ovpn_softc *sc, const struct in_addr addr) { - struct ovpn_kpeer *peer = NULL; + struct ovpn_kpeer peer; OVPN_ASSERT(sc); - /* 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); - } + peer.vpn4 = addr; - return (peer); + return (RB_FIND(ovpn_kpeers_by_ip, &sc->peers_by_ip, &peer)); } #endif @@ -1646,17 +1695,13 @@ ovpn_find_peer_by_ip(struct ovpn_softc *sc, const struct in_addr addr) static struct ovpn_kpeer * ovpn_find_peer_by_ip6(struct ovpn_softc *sc, const struct in6_addr *addr) { - struct ovpn_kpeer *peer = NULL; + struct ovpn_kpeer peer; OVPN_ASSERT(sc); - /* 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); - } + peer.vpn6 = *addr; - return (peer); + return (RB_FIND(ovpn_kpeers_by_ip6, &sc->peers_by_ip6, &peer)); } #endif