From nobody Thu Oct 01 10:39:53 2026 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 4hwT214T0fz6vSTx for ; Thu, 01 Oct 2026 10:39:53 +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 "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hwT211c81z4w6n for ; Thu, 01 Oct 2026 10:39:53 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1790851193; 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=RTA5VJAqGe0Mvid/Cjl3kL/aB7QVJCdJ8UILZyqzUzo=; b=t7YuIf12j1DJw7P3hbVGkrDsiZ7APp5Vo3FxJtCQSaBu26siz6pfaDydRmyEb+CSaj7fGf RS9n2/wCw6hR948K0AcJd01AsaaSnghyWgPcIabjReea669mo83Iwa1sdshw3TnepGUBGC UP0ujEnDRw2gmfYDQ7i21zud4FqcXaeqmBgvGGMxqGu7BN4Y/vooMdaDE1HS3wEuoLNI41 szl1oplVJB6ogU0bIieiKDDJhI5bhpfoccbszMvMhGlHQGNEITY0Wt60F5ScxM7zhcWx5f QR06hOPko9QYMWxbqarCDOLcRPOXNzrNpXemI08ZaK6gIhAWtxcYAAUZsRaDkw== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1790851193; b=T5PUFiFqDV2Yso/OaoZE2GRUrVaGRBoysWGUvrtF2QB+Y+tdj8ImJSu/+NHkQdHDv1MS4I FDY6hIL+ExqaAGPZhhI3ZEBit3VUFzKry/H0TWD3PXQ3LFOn7iM7ayqdASRzs+r+8g1om7 f1C0X2x7kHe8XGGoiKuaL57UY6NzYGqAtZ4KHcjYC0YyYM1/fjUqC6366phCsH3ziMRtzz Gp6pkX+Cx6luAQ2Xe6Obo3zIwFDGubVL6vLSm/D43HQQ+gecQrDTuYTnx1F7nmmYBcGPhT A1T7xKr6ZvazZviE7aKgsEV7vAK2TiOxqzb+uUyMtoQSPNnDX8fnlmJLEHLfXA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1790851193; 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=RTA5VJAqGe0Mvid/Cjl3kL/aB7QVJCdJ8UILZyqzUzo=; b=FNVsTzyncRGmzXvV3jehEhi7PXh1xHMLBVinJhneova9RAw6Os/hHExzz+gfSUkvH9he/P HCYx68HEGs42tDbpcsFuWELHJqoNujqvvggu9naMxioVuIsdSIuvf5/7PLVwWpP1YM7ssw GLknvVhgviTUpwMLFyAy9JBfxFLX45modSTAbnub6XmnfWwi3z32Kyitlsd/VYRw4DFo5K s31/ywHhAiM1vpeqoJPdZ6N6vYVkJQ+T6B0kr69fMT8IEHKUHJ+Lai1+TsDWdkL8zov4/L ndv/zJP6lfh7sk7DC8SRxCUS925uVlxihbmsEXCg3VLOS5hOogjKdt6hvUfEZA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hwT210h15zRy8 for ; Thu, 01 Oct 2026 10:39:53 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3c604 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 01 Oct 2026 10:39:53 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: R. Christian McDonald Subject: git: f05af59fba69 - main - pf: return per-address feedback from netlink table test 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: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rcm X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: f05af59fba6912bdde8c911b0820871224ed16db Auto-Submitted: auto-generated Date: Thu, 01 Oct 2026 10:39:53 +0000 Message-Id: <6abe3879.3c604.1329732a@gitrepo.freebsd.org> The branch main has been updated by rcm: URL: https://cgit.FreeBSD.org/src/commit/?id=f05af59fba6912bdde8c911b0820871224ed16db commit f05af59fba6912bdde8c911b0820871224ed16db Author: R. Christian McDonald AuthorDate: 2026-10-01 10:39:01 +0000 Commit: R. Christian McDonald CommitDate: 2026-10-01 10:39:01 +0000 pf: return per-address feedback from netlink table test The PFNL_CMD_TABLE_TEST_ADDRS reply carries only the match count, so the per-address feedback from pfr_tst_addrs() is lost: "pfctl -v -T test" lists nothing and "pfctl -vv -T test" reports every address as "nomatch". Return each address, as updated by pfr_tst_addrs(), in a nested PF_TAS_ADDR attribute, and decode them into the caller's array in libpfctl. PF_TA_ADDR is not reused: it shares its value with PF_TAS_ASTATS, which older libpfctl would decode into an uninitialised target. That target was also read when no reply was parsed, so the match count could be garbage; initialise it. Add a regression test. Reviewed by: kp Approved by: kp (mentor) Fixes: 281282e9357b ("pf: convert DIOCRTSTADDRS to netlink") See also: https://redmine.pfsense.org/issues/17135 Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D60146 --- lib/libpfctl/libpfctl.c | 12 ++++++++-- sys/netpfil/pf/pf_nl.c | 4 ++++ sys/netpfil/pf/pf_nl.h | 1 + tests/sys/netpfil/pf/table.sh | 55 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index aa3f4ec30f74..65c1a77b4d87 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -3896,6 +3896,14 @@ static struct snl_attr_parser ap_table_get_astats[] = { #undef _OUT SNL_DECLARE_PARSER(table_astats_parser, struct genlmsghdr, snl_f_p_empty, ap_table_get_astats); +#define _OUT(_field) offsetof(struct nl_addrs, _field) +static struct snl_attr_parser ap_table_test_addrs[] = { + { .type = PF_TAS_ASTATS_COUNT, .off = _OUT(total_count), .cb = snl_attr_get_uint32 }, + { .type = PF_TAS_ADDR, .off = 0, .cb = snl_attr_get_pfr_addrs }, +}; +#undef _OUT +SNL_DECLARE_PARSER(table_test_addrs_parser, struct genlmsghdr, snl_f_p_empty, ap_table_test_addrs); + int pfctl_get_astats(struct pfctl_handle *h, const struct pfr_table *tbl, struct pfr_astats *as, int *size, int flags) @@ -4022,7 +4030,7 @@ _pfctl_test_addrs(struct pfctl_handle *h, const struct pfr_table *tbl, struct snl_errmsg_data e = {}; struct nlmsghdr *hdr; uint32_t seq_id; - struct nl_astats attrs; + struct nl_addrs attrs = { .addrs = addrs, .max = size }; snl_init_writer(&h->ss, &nw); hdr = snl_create_genl_msg_request(&nw, h->family_id, @@ -4046,7 +4054,7 @@ _pfctl_test_addrs(struct pfctl_handle *h, const struct pfr_table *tbl, } while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) { - if (! snl_parse_nlmsg(&h->ss, hdr, &table_astats_parser, &attrs)) + if (! snl_parse_nlmsg(&h->ss, hdr, &table_test_addrs_parser, &attrs)) continue; } diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c index ad060ea3230a..80d12c3abae3 100644 --- a/sys/netpfil/pf/pf_nl.c +++ b/sys/netpfil/pf/pf_nl.c @@ -2553,6 +2553,10 @@ pf_handle_table_test_addrs(struct nlmsghdr *hdr, struct nl_pstate *npt) ghdr_new->cmd = PFNL_CMD_TABLE_TEST_ADDRS; nlattr_add_u32(nw, PF_TAS_ASTATS_COUNT, attrs.nchange); + if (error == 0) { + for (size_t i = 0; i < attrs.addr_count; i++) + nlattr_add_pfr_addr(nw, PF_TAS_ADDR, &attrs.addrs[i]); + } if (!nlmsg_end(nw)) return (ENOMEM); diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h index d795d33c085a..c3c8da3571d3 100644 --- a/sys/netpfil/pf/pf_nl.h +++ b/sys/netpfil/pf/pf_nl.h @@ -527,6 +527,7 @@ enum pf_table_astats_t { PF_TAS_FLAGS = 3, /* u32 */ PF_TAS_ASTATS_COUNT = 4, /* u32 */ PF_TAS_ASTATS_ZEROED = 5, /* u32 */ + PF_TAS_ADDR = 6, /* nested, pfr_addr_t */ }; enum pf_limit_rate_t { diff --git a/tests/sys/netpfil/pf/table.sh b/tests/sys/netpfil/pf/table.sh index 9c93df781852..e21d998b4ece 100644 --- a/tests/sys/netpfil/pf/table.sh +++ b/tests/sys/netpfil/pf/table.sh @@ -986,6 +986,60 @@ test_cleanup() pft_cleanup } +atf_test_case "test_verbose" "cleanup" +test_verbose_head() +{ + atf_set descr 'Test pfctl -v -T test per-address feedback' + atf_set require.user root +} + +test_verbose_body() +{ + pft_init + + vnet_mkjail alcatraz + jexec alcatraz pfctl -e + + pft_set_rules alcatraz \ + "table persist { 192.0.2.1 198.51.100.0/24 !198.51.100.7 }" \ + "pass all" + + # -v lists only the matching addresses. + atf_check -s exit:2 -e match:"2/4 addresses match." \ + -o match:"^M 192\.0\.2\.1$" \ + -o match:"^M 198\.51\.100\.5$" \ + -o not-match:"198\.51\.100\.7" \ + -o not-match:"1\.2\.3\.4" \ + jexec alcatraz pfctl -t foo -v -T test \ + 192.0.2.1 198.51.100.5 198.51.100.7 1.2.3.4 + + # -vv lists every address and the table entry it matched. + atf_check -s exit:2 -e match:"2/4 addresses match." \ + -o match:"^M 192\.0\.2\.1 192\.0\.2\.1$" \ + -o match:"^M 198\.51\.100\.5 198\.51\.100\.0/24$" \ + -o match:"^ 198\.51\.100\.7 !198\.51\.100\.7$" \ + -o match:"^ 1\.2\.3\.4 nomatch$" \ + jexec alcatraz pfctl -t foo -vv -T test \ + 192.0.2.1 198.51.100.5 198.51.100.7 1.2.3.4 + + # libpfctl tests 256 addresses per request, check across requests. + for i in `seq 1 255`; do + echo "203.0.113.${i}" + done > addrs + echo "1.2.3.4" >> addrs + echo "198.51.100.5" >> addrs + atf_check -s exit:2 -e match:"1/257 addresses match." \ + -o match:"^ 203\.0\.113\.255 nomatch$" \ + -o match:"^ 1\.2\.3\.4 nomatch$" \ + -o match:"^M 198\.51\.100\.5 198\.51\.100\.0/24$" \ + jexec alcatraz pfctl -t foo -vv -T test -f $(pwd)/addrs +} + +test_verbose_cleanup() +{ + pft_cleanup +} + atf_test_case "show_no_counters" "cleanup" show_no_counters_head() { @@ -1042,5 +1096,6 @@ atf_init_test_cases() atf_add_test_case "replace_create" atf_add_test_case "load" atf_add_test_case "test" + atf_add_test_case "test_verbose" atf_add_test_case "show_no_counters" }