git: eaba5142bdef - main - pf: carry pfra_fback in the netlink pfr_addr encoding
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 29 Sep 2026 20:01:26 UTC
The branch main has been updated by rcm:
URL: https://cgit.FreeBSD.org/src/commit/?id=eaba5142bdefd6b5b249793f6f8ec3528afb12e3
commit eaba5142bdefd6b5b249793f6f8ec3528afb12e3
Author: R. Christian McDonald <rcm@FreeBSD.org>
AuthorDate: 2026-09-29 01:21:56 +0000
Commit: R. Christian McDonald <rcm@FreeBSD.org>
CommitDate: 2026-09-29 19:57:47 +0000
pf: carry pfra_fback in the netlink pfr_addr encoding
The netlink encoding of struct pfr_addr omits pfra_fback, so no
per-address feedback reaches userspace. In particular,
pfr_get_astats() marks entries of tables without counters with
PFR_FB_NOCOUNT, which pfctl uses to skip their counters, so
"pfctl -v -T show" prints zero counters for such tables.
Add PFR_A_FBACK, emit it from the kernel and decode it in libpfctl.
Add a regression test.
Reviewed by: kp
Approved by: kp (mentor)
Fixes: 08f54dfca197 ("pf: convert DIOCRGETASTATS to netlink")
Sponsored by: Rubicon Communications, LLC ("Netgate")
---
lib/libpfctl/libpfctl.c | 1 +
sys/netpfil/pf/pf_nl.c | 1 +
sys/netpfil/pf/pf_nl.h | 1 +
tests/sys/netpfil/pf/table.sh | 33 +++++++++++++++++++++++++++++++++
4 files changed, 36 insertions(+)
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index 6578cff5e45a..a7dbc0a412aa 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -2799,6 +2799,7 @@ static const struct snl_attr_parser ap_pfr_addr[] = {
{ .type = PFR_A_NET, .off = _OUT(pfra_net), .cb = snl_attr_get_uint8 },
{ .type = PFR_A_NOT, .off = _OUT(pfra_not), .cb = snl_attr_get_bool },
{ .type = PFR_A_ADDR, .off = _OUT(pfra_ip6addr), .cb = snl_attr_get_in6_addr },
+ { .type = PFR_A_FBACK, .off = _OUT(pfra_fback), .cb = snl_attr_get_uint8 },
};
#undef _OUT
SNL_DECLARE_ATTR_PARSER(pfr_addr_parser, ap_pfr_addr);
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
index 8a04c330f4eb..6281b2d0ad19 100644
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -2315,6 +2315,7 @@ nlattr_add_pfr_addr(struct nl_writer *nw, int attr, const struct pfr_addr *a)
nlattr_add_u8(nw, PFR_A_NET, a->pfra_net);
nlattr_add_bool(nw, PFR_A_NOT, a->pfra_not);
nlattr_add_in6_addr(nw, PFR_A_ADDR, &a->pfra_u._pfra_ip6addr);
+ nlattr_add_u8(nw, PFR_A_FBACK, a->pfra_fback);
nlattr_set_len(nw, off);
diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h
index 220ef8ea9cd8..d795d33c085a 100644
--- a/sys/netpfil/pf/pf_nl.h
+++ b/sys/netpfil/pf/pf_nl.h
@@ -498,6 +498,7 @@ enum pfr_addr_t {
PFR_A_NET = 2, /* uint8_t */
PFR_A_NOT = 3, /* bool */
PFR_A_ADDR = 4, /* in6_addr */
+ PFR_A_FBACK = 5, /* uint8_t */
};
enum pf_table_addrs_t {
diff --git a/tests/sys/netpfil/pf/table.sh b/tests/sys/netpfil/pf/table.sh
index 7c8cb084b48a..24201588ddbf 100644
--- a/tests/sys/netpfil/pf/table.sh
+++ b/tests/sys/netpfil/pf/table.sh
@@ -949,6 +949,38 @@ test_cleanup()
pft_cleanup
}
+atf_test_case "show_no_counters" "cleanup"
+show_no_counters_head()
+{
+ atf_set descr 'Test pfctl -v -T show on a table without counters'
+ atf_set require.user root
+}
+
+show_no_counters_body()
+{
+ pft_init
+
+ vnet_mkjail alcatraz
+ jexec alcatraz pfctl -e
+
+ pft_set_rules alcatraz \
+ "table <foo> persist { 192.0.2.1 }" \
+ "table <bar> persist counters { 192.0.2.1 }" \
+ "pass all"
+
+ atf_check -s exit:0 -e ignore \
+ -o match:"Cleared:" -o not-match:"In/Block:" \
+ jexec alcatraz pfctl -t foo -v -T show
+ atf_check -s exit:0 -e ignore \
+ -o match:"Cleared:" -o match:"In/Block:" \
+ jexec alcatraz pfctl -t bar -v -T show
+}
+
+show_no_counters_cleanup()
+{
+ pft_cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case "v4_counters"
@@ -972,4 +1004,5 @@ atf_init_test_cases()
atf_add_test_case "replace_verbose"
atf_add_test_case "load"
atf_add_test_case "test"
+ atf_add_test_case "show_no_counters"
}