From nobody Mon Oct 23 15:10:34 2023 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 4SDdt26nsHz4y9MV; Mon, 23 Oct 2023 15:10: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 4SDdt25gRfz4JDd; Mon, 23 Oct 2023 15:10:34 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1698073834; 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=+OUWRbRge+LMIFOXlfkXbuHftg/uNRU6/KEujOeS4c0=; b=I+BYPoQuBICEvoP3Gaxu3UyHmX57Kwa92BqelaJI6Igqe80hPBu/nz3oRZTecy9jIBvXpl vgD83bN98eC2B3K2culVoWxoJMIUK4szJkcT9xxC3ehEMdFzwrxX9uGmzk+qVDt56vMPDn CzYDuM85g997w1AwagztmJlZHdGZCNEJdverR6twyniUQ2RYG0GEElSG0B7B41AXfjLoMd fbW5XbtCG/qWzhJm0jWsSu9a18CrLbEosDvScXGByPPNmJpV68CwFCEMshFQg9UF6ek9zA vg5wJN2DwbeCmPwDZB88eYhP5u544ifHwvH/ZgMeoZK1jYkMM8T7IpSg8CNj4g== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1698073834; a=rsa-sha256; cv=none; b=USDZ8SIEbESD9rt2wmupaS1kz/X/3zmQq+qLfCeVcWOElzJ+WWViOrdW5+RDR1p9mpU2tB COAncA9N9mJ3dD7CEZSjlIpY4gz7JAav9jD2iaLcAMKlH9l6rfSSMIT9bP6nsyaVWMLLa5 f4H0DHTR4cS5deb2VELOjUcGY8QjddsSZ6ur5rHcOltjilCbGXmb7G7v1jlQawv6Vg2YWz gqqMLoOmqIvWWyYEjXOU1OfDJNCQ3yelkhz7ff9T5jWI0il0ur7loQ/Pt53gteaHz8Xo7k +nu+iO/IxAXj6EcGwxrjtt1/UwZHByGsZJOrRAlmIkUt4ao+ha+9VvBhZe9lGQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1698073834; 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=+OUWRbRge+LMIFOXlfkXbuHftg/uNRU6/KEujOeS4c0=; b=WjGwrHYcYaAFScjhMCNAQnxHGF4+1GdMEdR55uLs+My7rwmqBq8Unsvs0VzcSPAJmWhS4E qkBSmghDAy5SYmLPafJlg7FGF7qUiPueoA9FdLWSc+bFPQHVLYfCWDSZqWKaKQmkeaywzM +MFjREVjKcbFVDDs/S6DmbRrXFQvOjbtzwcw6SNTxQBl9RtkFqjXEVL41/F2fM5qh10Sa9 O3KEEMQuBscdb7cmvDfUM+nvmzFv/ytXyX73r0PCUpn9jWw2sEkJ3HIQVsEZAh4JOpXI46 2/SctXtyz08ksECPktEV9qcnmdPCyMu7epJgEZE0dMRhfX2Wk/3q+rsiL09xFg== 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 4SDdt24jbnzl1j; Mon, 23 Oct 2023 15:10:34 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 39NFAYBF038527; Mon, 23 Oct 2023 15:10:34 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 39NFAYcE038524; Mon, 23 Oct 2023 15:10:34 GMT (envelope-from git) Date: Mon, 23 Oct 2023 15:10:34 GMT Message-Id: <202310231510.39NFAYcE038524@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: 044eef6ab9cf - main - pf: support basic filters for state listing 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: 044eef6ab9cf1730d21c5f5dffebb0cd35fb5bbf Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=044eef6ab9cf1730d21c5f5dffebb0cd35fb5bbf commit 044eef6ab9cf1730d21c5f5dffebb0cd35fb5bbf Author: Kristof Provost AuthorDate: 2023-10-16 14:47:22 +0000 Commit: Kristof Provost CommitDate: 2023-10-23 14:24:52 +0000 pf: support basic filters for state listing Allow users(pace) to specify a protocol, interface, address family and/ or address and mask, allowing the state listing to be pre-filtered in the kernel. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D42280 --- lib/libpfctl/libpfctl.c | 18 ++++++++++++++++-- lib/libpfctl/libpfctl.h | 9 +++++++++ sbin/pfctl/pfctl.c | 9 +++++---- sys/netpfil/pf/pf_nl.c | 43 ++++++++++++++++++++++++++++++++++++++----- sys/netpfil/pf/pf_nl.h | 2 ++ 5 files changed, 70 insertions(+), 11 deletions(-) diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index 3865dc85aea1..25bb77d9c021 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -1342,7 +1342,7 @@ static const struct snl_hdr_parser *all_parsers[] = { }; static int -pfctl_get_states_nl(struct snl_state *ss, pfctl_get_state_fn f, void *arg) +pfctl_get_states_nl(struct pfctl_state_filter *filter, struct snl_state *ss, pfctl_get_state_fn f, void *arg) { SNL_VERIFY_PARSERS(all_parsers); int family_id = snl_get_genl_family(ss, PFNL_FAMILY_NAME); @@ -1354,7 +1354,14 @@ pfctl_get_states_nl(struct snl_state *ss, pfctl_get_state_fn f, void *arg) snl_init_writer(ss, &nw); hdr = snl_create_genl_msg_request(&nw, family_id, PFNL_CMD_GETSTATES); hdr->nlmsg_flags |= NLM_F_DUMP; + snl_add_msg_attr_string(&nw, PF_ST_IFNAME, filter->ifname); + snl_add_msg_attr_u16(&nw, PF_ST_PROTO, filter->proto); + snl_add_msg_attr_u8(&nw, PF_ST_AF, filter->af); + snl_add_msg_attr_ip6(&nw, PF_ST_FILTER_ADDR, &filter->addr.v6); + snl_add_msg_attr_ip6(&nw, PF_ST_FILTER_MASK, &filter->mask.v6); + hdr = snl_finalize_msg(&nw); + uint32_t seq_id = hdr->nlmsg_seq; snl_send_message(ss, hdr); @@ -1379,12 +1386,19 @@ pfctl_get_states_nl(struct snl_state *ss, pfctl_get_state_fn f, void *arg) int pfctl_get_states_iter(pfctl_get_state_fn f, void *arg) +{ + struct pfctl_state_filter filter = {}; + return (pfctl_get_filtered_states_iter(&filter, f, arg)); +} + +int +pfctl_get_filtered_states_iter(struct pfctl_state_filter *filter, pfctl_get_state_fn f, void *arg) { struct snl_state ss = {}; int error; snl_init(&ss, NETLINK_GENERIC); - error = pfctl_get_states_nl(&ss, f, arg); + error = pfctl_get_states_nl(filter, &ss, f, arg); snl_free(&ss); return (error); diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index 06cd25e82c08..ad6fde89771c 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -415,8 +415,17 @@ int pfctl_add_rule(int dev, const struct pfctl_rule *r, uint32_t pool_ticket); int pfctl_set_keepcounters(int dev, bool keep); int pfctl_get_creatorids(uint32_t *creators, size_t *len); + +struct pfctl_state_filter { + char ifname[IFNAMSIZ]; + uint16_t proto; + sa_family_t af; + struct pf_addr addr; + struct pf_addr mask; +}; typedef int (*pfctl_get_state_fn)(struct pfctl_state *, void *); int pfctl_get_states_iter(pfctl_get_state_fn f, void *arg); +int pfctl_get_filtered_states_iter(struct pfctl_state_filter *filter, pfctl_get_state_fn f, void *arg); int pfctl_get_states(int dev, struct pfctl_states *states); void pfctl_free_states(struct pfctl_states *states); int pfctl_clear_states(int dev, const struct pfctl_kill *kill, diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index 56b1d28c6fd6..c3f3d82ff767 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -1529,9 +1529,6 @@ pfctl_show_state(struct pfctl_state *s, void *arg) { struct pfctl_show_state_arg *a = (struct pfctl_show_state_arg *)arg; - if (a->iface != NULL && strcmp(s->ifname, a->iface)) - return (0); - if (a->dotitle) { pfctl_print_title("STATES:"); a->dotitle = 0; @@ -1545,12 +1542,16 @@ int pfctl_show_states(int dev, const char *iface, int opts) { struct pfctl_show_state_arg arg; + struct pfctl_state_filter filter = {}; + + if (iface != NULL) + strncpy(filter.ifname, iface, IFNAMSIZ); arg.opts = opts; arg.dotitle = opts & PF_OPT_SHOWALL; arg.iface = iface; - if (pfctl_get_states_iter(pfctl_show_state, &arg)) + if (pfctl_get_filtered_states_iter(&filter, pfctl_show_state, &arg)) return (-1); return (0); diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c index d5d294134b1f..53ff5d031ed6 100644 --- a/sys/netpfil/pf/pf_nl.c +++ b/sys/netpfil/pf/pf_nl.c @@ -52,6 +52,11 @@ struct nl_parsed_state { uint8_t version; uint32_t id; uint32_t creatorid; + char ifname[IFNAMSIZ]; + uint16_t proto; + sa_family_t af; + struct pf_addr addr; + struct pf_addr mask; }; #define _IN(_field) offsetof(struct genlmsghdr, _field) @@ -59,6 +64,11 @@ struct nl_parsed_state { static const struct nlattr_parser nla_p_state[] = { { .type = PF_ST_ID, .off = _OUT(id), .cb = nlattr_get_uint32 }, { .type = PF_ST_CREATORID, .off = _OUT(creatorid), .cb = nlattr_get_uint32 }, + { .type = PF_ST_IFNAME, .arg = (const void *)IFNAMSIZ, .off = _OUT(ifname), .cb = nlattr_get_chara }, + { .type = PF_ST_AF, .off = _OUT(proto), .cb = nlattr_get_uint8 }, + { .type = PF_ST_PROTO, .off = _OUT(proto), .cb = nlattr_get_uint16 }, + { .type = PF_ST_FILTER_ADDR, .off = _OUT(addr), .cb = nlattr_get_in6_addr }, + { .type = PF_ST_FILTER_MASK, .off = _OUT(mask), .cb = nlattr_get_in6_addr }, }; static const struct nlfield_parser nlf_p_generic[] = { { .off_in = _IN(version), .off_out = _OUT(version), .cb = nlf_get_u8 }, @@ -217,11 +227,34 @@ handle_dumpstates(struct nlpcb *nlp, struct nl_parsed_state *attrs, PF_HASHROW_LOCK(ih); LIST_FOREACH(s, &ih->states, entry) { - if (s->timeout != PFTM_UNLINKED) { - error = dump_state(nlp, hdr, s, npt); - if (error != 0) - break; - } + sa_family_t af = s->key[PF_SK_WIRE]->af; + + if (s->timeout == PFTM_UNLINKED) + continue; + + /* Filter */ + if (attrs->creatorid != 0 && s->creatorid != attrs->creatorid) + continue; + if (attrs->ifname[0] != 0 && + strncmp(attrs->ifname, s->kif->pfik_name, IFNAMSIZ) != 0) + continue; + if (attrs->proto != 0 && s->key[PF_SK_WIRE]->proto != attrs->proto) + continue; + if (attrs->af != 0 && af != attrs->af) + continue; + if (pf_match_addr(1, &s->key[PF_SK_WIRE]->addr[0], + &attrs->mask, &attrs->addr, af) && + pf_match_addr(1, &s->key[PF_SK_WIRE]->addr[1], + &attrs->mask, &attrs->addr, af) && + pf_match_addr(1, &s->key[PF_SK_STACK]->addr[0], + &attrs->mask, &attrs->addr, af) && + pf_match_addr(1, &s->key[PF_SK_STACK]->addr[1], + &attrs->mask, &attrs->addr, af)) + continue; + + error = dump_state(nlp, hdr, s, npt); + if (error != 0) + break; } PF_HASHROW_UNLOCK(ih); } diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h index d936044c0d7d..8265ae1d1bfa 100644 --- a/sys/netpfil/pf/pf_nl.h +++ b/sys/netpfil/pf/pf_nl.h @@ -97,6 +97,8 @@ enum pfstate_type_t { PF_ST_SYNC_FLAGS = 26, /* u8 */ PF_ST_UPDATES = 27, /* u8 */ PF_ST_VERSION = 28, /* u64 */ + PF_ST_FILTER_ADDR = 29, /* in6_addr */ + PF_ST_FILTER_MASK = 30, /* in6_addr */ }; enum pf_addr_type_t {