git: 806adba81f3d - main - libpfctl: decode PFR_A_AF into a u8
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 29 Sep 2026 11:03:24 UTC
The branch main has been updated by rcm:
URL: https://cgit.FreeBSD.org/src/commit/?id=806adba81f3d808994b0cec955c38ef1a089e739
commit 806adba81f3d808994b0cec955c38ef1a089e739
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 11:00:50 +0000
libpfctl: decode PFR_A_AF into a u8
The kernel sends PFR_A_AF as a u32, although it is documented and
parsed as a u8, and libpfctl decoded it with snl_attr_get_uint32()
straight into the u8 pfra_af. That overwrote pfra_net, pfra_not and
pfra_fback, and left pfra_af zero on big-endian hosts.
Decode it via a temporary, and accept a u8 as well, so that the
kernel can be corrected later without breaking libpfctl.
Reviewed by: kp
Approved by: kp (mentor)
Fixes: f27e44e2e3b5 ("pf: convert DIOCRGETADDRS to netlink")
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60110
---
lib/libpfctl/libpfctl.c | 18 +++++++++++++++++-
sys/netpfil/pf/pf_nl.h | 2 +-
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index 26fcb6f50045..6578cff5e45a 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -2777,9 +2777,25 @@ struct nl_addrs {
size_t total_count;
};
+/* pfra_af is a u8, but the kernel sends PFR_A_AF as a u32. Accept both. */
+static bool
+snl_attr_get_pfra_af(struct snl_state *ss, struct nlattr *nla,
+ const void *arg __unused, void *target)
+{
+ uint32_t af;
+
+ if (snl_attr_get_uint8(ss, nla, NULL, target))
+ return (true);
+ if (! snl_attr_get_uint32(ss, nla, NULL, &af))
+ return (false);
+ *(uint8_t *)target = af;
+
+ return (true);
+}
+
#define _OUT(_field) offsetof(struct pfr_addr, _field)
static const struct snl_attr_parser ap_pfr_addr[] = {
- { .type = PFR_A_AF, .off = _OUT(pfra_af), .cb = snl_attr_get_uint32 },
+ { .type = PFR_A_AF, .off = _OUT(pfra_af), .cb = snl_attr_get_pfra_af },
{ .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 },
diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h
index 2b6785b6ffca..220ef8ea9cd8 100644
--- a/sys/netpfil/pf/pf_nl.h
+++ b/sys/netpfil/pf/pf_nl.h
@@ -494,7 +494,7 @@ enum pf_tstats_t {
enum pfr_addr_t {
PFR_A_UNSPEC,
- PFR_A_AF = 1, /* uint8_t */
+ PFR_A_AF = 1, /* uint8_t, uint32_t in replies */
PFR_A_NET = 2, /* uint8_t */
PFR_A_NOT = 3, /* bool */
PFR_A_ADDR = 4, /* in6_addr */