From nobody Mon Jul 21 02:13:58 2025 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 4blkTz3HSmz61xx7; Mon, 21 Jul 2025 02:13:59 +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 "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4blkTz0CH2z3NlB; Mon, 21 Jul 2025 02:13:59 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1753064039; 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=OkRGLPxyZAHnKc5jlkwmF94G2Va+V3tLeiAA9qrg6nY=; b=HgQAIZWEjhPHNO5S3jagzAjG9NFOJ0xcpXvuvw12GSVCMKz/2QIBRoNUAiixRTYjMjW3ZJ cWViD2P0Zx8CYFlMfw0K2FrgtkF2bnAVntuk0xsq0NhQO//Ft9clPrLvjdU+t7PV8OPVlb jZxyds35Ik9YY3JxHjVjg8lcOOy+CvDoHXZy48trdu3aQxoowq2zwDknSJcvDuWwoD7V9/ ChI4d4wKUs5SIwKG0mZ3k8ImS4vm5YVZ7UBjZ53f/0MTFOFWExEzOe1GM/YwKikQ8D+/TR rQP4fpyN2SD0TaQsrK9Mila6GjOlC2D+aUQSl3nqi3BR0zJ9/VA5IBSGohZh5g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1753064039; 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=OkRGLPxyZAHnKc5jlkwmF94G2Va+V3tLeiAA9qrg6nY=; b=TWg/aOa51FnxMh03TZxbMwUT5LrgyzfqUMHGnVQ36/JRNekuvYnq7o7EHnILb+lHUqGY+G W2LiuDjaNT2NRWF6cRgR2OL7Sqq/wu/awgpLyVloX1Gw7eGCaHZ5ly+MxUF8VyN4Uq7afl iV4thPqF7yUwS8dHejVEFcLiyc0BCK5X0evlhyHRT8+uPdXNInjsjIaq21dJaDHqMDlEfr MmMPitIW0yEw9bMaXGFwtXnAsWlMZqWHrX6yWbKR1bM2KKQLRsLDh13Epd14MfqCpapXi6 TF1PmrH/nrNs3IGpTVfcvzKH2TPBSQLHi+TcP/RL2kGjw7j+7t+9yOVBj0Xb8g== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1753064039; a=rsa-sha256; cv=none; b=BQYvmAQOc7HpTom/XN5M7IG8lnbWLZc84Oj2VxoFoiLWoXpqUbTSpb3tzY4cuir61g6xDC yLqjVPoAceD8NnpEBP5jkzThAMXiE9bRmLYZFTTA1+nQtTTzhGqJdoIdE8NlgeX5oBBv/N Y3t9DCt6M0NSgdGJBRN9NXLyFp7kZVzDUpPlys/GLw3Ev/neQfOn1PURyAFpn/k+C4DFne PjPbnmxpJdbElxK5GskCh5vRrTV+z4Lwc+Q+W/ZEpgF6HWW5+dB22z7LmjfFrnWMxMHoSH 1DlpnqDJAAMxyhKPm1jv+kkolTvtRPAJJb5lvUsQ2AGcTUBBy7eFI26eHRzfGg== 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 4blkTy6QBvzfgd; Mon, 21 Jul 2025 02:13:58 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 56L2Dw5j013947; Mon, 21 Jul 2025 02:13:58 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 56L2Dw1F013944; Mon, 21 Jul 2025 02:13:58 GMT (envelope-from git) Date: Mon, 21 Jul 2025 02:13:58 GMT Message-Id: <202507210213.56L2Dw1F013944@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kyle Evans Subject: git: 684dd4e8c008 - stable/14 - kern: wg: add support for removing Allowed-IPs 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: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kevans X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 684dd4e8c0085f4e64016a44d4cd699b2fc29681 Auto-Submitted: auto-generated The branch stable/14 has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=684dd4e8c0085f4e64016a44d4cd699b2fc29681 commit 684dd4e8c0085f4e64016a44d4cd699b2fc29681 Author: Kyle Evans AuthorDate: 2025-06-26 02:57:02 +0000 Commit: Kyle Evans CommitDate: 2025-07-21 02:12:59 +0000 kern: wg: add support for removing Allowed-IPs This was recently added to Linux to improve incremental update support, as you could previously add Allowed-IPs but not remove without replacing the whole set (and thus, potentially disrupting existing traffic). Removal is incredibly straightforward; we'll find it in p_aips first to ensure that it's actually valid for this peer, then we'll delete it from the radix tree before we remove the corresponding p_aips entry. Reviewed by: Jason A. Donenfeld, jhb (cherry picked from commit d15d610fac97df4fefed3f14b31dcfbdcec65bf9) (cherry picked from commit d1ac3e245f084ee0637bde9a446687621358c418) --- sys/dev/wg/if_wg.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++- sys/dev/wg/if_wg.h | 6 +++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/sys/dev/wg/if_wg.c b/sys/dev/wg/if_wg.c index 380e579eed07..75af5e279669 100644 --- a/sys/dev/wg/if_wg.c +++ b/sys/dev/wg/if_wg.c @@ -314,6 +314,8 @@ static void wg_timers_run_zero_key_material(void *); static void wg_timers_run_persistent_keepalive(void *); static int wg_aip_add(struct wg_softc *, struct wg_peer *, sa_family_t, const void *, uint8_t); +static int wg_aip_del(struct wg_softc *, struct wg_peer *, sa_family_t, + const void *, uint8_t); static struct wg_peer *wg_aip_lookup(struct wg_softc *, sa_family_t, void *); static void wg_aip_remove_all(struct wg_softc *, struct wg_peer *); static struct wg_peer *wg_peer_create(struct wg_softc *, @@ -530,10 +532,12 @@ wg_peer_get_endpoint(struct wg_peer *peer, struct wg_endpoint *e) static int wg_aip_addrinfo(struct wg_aip *aip, const void *baddr, uint8_t cidr) { +#if defined(INET) || defined(INET6) struct aip_addr *addr, *mask; addr = &aip->a_addr; mask = &aip->a_mask; +#endif switch (aip->a_af) { #ifdef INET case AF_INET: @@ -608,6 +612,58 @@ wg_aip_add(struct wg_softc *sc, struct wg_peer *peer, sa_family_t af, return (ret); } +static int +wg_aip_del(struct wg_softc *sc, struct wg_peer *peer, sa_family_t af, + const void *baddr, uint8_t cidr) +{ + struct radix_node_head *root = NULL; + struct radix_node *dnode __diagused, *node; + struct wg_aip *aip, addr; + int ret = 0; + + /* + * We need to be sure that all padding is cleared, as it is above when + * new AllowedIPs are added, since we want to do a direct comparison. + */ + memset(&addr, 0, sizeof(addr)); + addr.a_af = af; + + ret = wg_aip_addrinfo(&addr, baddr, cidr); + if (ret != 0) + return (ret); + + root = af == AF_INET ? sc->sc_aip4 : sc->sc_aip6; + + MPASS(root != NULL); + RADIX_NODE_HEAD_LOCK(root); + + node = root->rnh_lookup(&addr.a_addr, &addr.a_mask, &root->rh); + if (node == NULL) { + RADIX_NODE_HEAD_UNLOCK(root); + return (0); + } + + aip = (struct wg_aip *)node; + if (aip->a_peer != peer) { + /* + * They could have specified an allowed-ip that belonged to a + * different peer, in which case our job is done because the + * AllowedIP has been removed. + */ + RADIX_NODE_HEAD_UNLOCK(root); + return (0); + } + + dnode = root->rnh_deladdr(&aip->a_addr, &aip->a_mask, &root->rh); + MPASS(dnode == node); + RADIX_NODE_HEAD_UNLOCK(root); + + LIST_REMOVE(aip, a_entry); + peer->p_aips_num--; + free(aip, M_WG); + return (0); +} + static struct wg_peer * wg_aip_lookup(struct wg_softc *sc, sa_family_t af, void *a) { @@ -2477,11 +2533,19 @@ wg_peer_add(struct wg_softc *sc, const nvlist_t *nvl) aipl = nvlist_get_nvlist_array(nvl, "allowed-ips", &allowedip_count); for (size_t idx = 0; idx < allowedip_count; idx++) { sa_family_t ipaf; + int ipflags; if (!nvlist_exists_number(aipl[idx], "cidr")) continue; ipaf = AF_UNSPEC; + ipflags = 0; + if (nvlist_exists_number(aipl[idx], "flags")) + ipflags = nvlist_get_number(aipl[idx], "flags"); + if ((ipflags & ~WGALLOWEDIP_VALID_FLAGS) != 0) { + err = EOPNOTSUPP; + goto out; + } cidr = nvlist_get_number(aipl[idx], "cidr"); if (nvlist_exists_binary(aipl[idx], "ipv4")) { addr = nvlist_get_binary(aipl[idx], "ipv4", &size); @@ -2504,7 +2568,13 @@ wg_peer_add(struct wg_softc *sc, const nvlist_t *nvl) } MPASS(ipaf != AF_UNSPEC); - if ((err = wg_aip_add(sc, peer, ipaf, addr, cidr)) != 0) + if ((ipflags & WGALLOWEDIP_REMOVE_ME) != 0) { + err = wg_aip_del(sc, peer, ipaf, addr, cidr); + } else { + err = wg_aip_add(sc, peer, ipaf, addr, cidr); + } + + if (err != 0) goto out; } } diff --git a/sys/dev/wg/if_wg.h b/sys/dev/wg/if_wg.h index f00b7f676319..801eaf38141d 100644 --- a/sys/dev/wg/if_wg.h +++ b/sys/dev/wg/if_wg.h @@ -32,4 +32,10 @@ struct wg_data_io { #define SIOCSWG _IOWR('i', 210, struct wg_data_io) #define SIOCGWG _IOWR('i', 211, struct wg_data_io) + +/* Keep these in sync with wireguard-tools:containers.h */ +#define WGALLOWEDIP_REMOVE_ME 0x0001 + +#define WGALLOWEDIP_VALID_FLAGS WGALLOWEDIP_REMOVE_ME + #endif /* __IF_WG_H__ */