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:			f27e44e2e3 ("pf: convert DIOCRGETADDRS to netlink")
Sponsored by:		Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D60110
This commit is contained in:
R. Christian McDonald committed 2026-09-29 07:00:50 -04:00
1 parent 0dac2c5327
commit 806adba81f
2 files changed
+18 -2

No files matched your search

+17 -1
View File
@@ -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 },
+1 -1
View File
@@ -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 */