git: ebe11b46988e - main - pf: fix state export in the face of NAT64

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Tue, 17 Dec 2024 10:07:44 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=ebe11b46988eb27d287272b8c827eb80ebd900ba

commit ebe11b46988eb27d287272b8c827eb80ebd900ba
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2024-10-25 15:01:13 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2024-12-17 10:07:13 +0000

    pf: fix state export in the face of NAT64
    
    Now that we can NAT64 we can have states where the wire and stack address
    families (and protocol) are different.  Update the state export code to account
    for this.
    
    We keep exporting address family and protocol outside of the key, for backwards
    compatibility. This'll return misleading information to userspace in the NAT64
    case, but it's assumed that userspace will either understand NAT64 (and thus
    look for them in the correct place), or not configure it.
    
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D47787
---
 lib/libpfctl/libpfctl.c | 9 +++------
 sys/netpfil/pf/pf_nl.c  | 2 ++
 sys/netpfil/pf/pf_nl.h  | 2 ++
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index 21d0b24601a4..9fec8e77de26 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -1866,12 +1866,14 @@ static const struct snl_attr_parser nla_p_speer[] = {
 SNL_DECLARE_ATTR_PARSER(speer_parser, nla_p_speer);
 #undef _OUT
 
-#define	_OUT(_field)	offsetof(struct pf_state_key_export, _field)
+#define	_OUT(_field)	offsetof(struct pfctl_state_key, _field)
 static const struct snl_attr_parser nla_p_skey[] = {
 	{ .type = PF_STK_ADDR0, .off = _OUT(addr[0]), .cb = snl_attr_get_pfaddr },
 	{ .type = PF_STK_ADDR1, .off = _OUT(addr[1]), .cb = snl_attr_get_pfaddr },
 	{ .type = PF_STK_PORT0, .off = _OUT(port[0]), .cb = snl_attr_get_uint16 },
 	{ .type = PF_STK_PORT1, .off = _OUT(port[1]), .cb = snl_attr_get_uint16 },
+	{ .type = PF_STK_AF, .off = _OUT(af), .cb = snl_attr_get_uint8 },
+	{ .type = PF_STK_PROTO, .off = _OUT(proto), .cb = snl_attr_get_uint16 },
 };
 SNL_DECLARE_ATTR_PARSER(skey_parser, nla_p_skey);
 #undef _OUT
@@ -1897,8 +1899,6 @@ static struct snl_attr_parser ap_state[] = {
 	{ .type = PF_ST_PACKETS1, .off = _OUT(packets[1]), .cb = snl_attr_get_uint64 },
 	{ .type = PF_ST_BYTES0, .off = _OUT(bytes[0]), .cb = snl_attr_get_uint64 },
 	{ .type = PF_ST_BYTES1, .off = _OUT(bytes[1]), .cb = snl_attr_get_uint64 },
-	{ .type = PF_ST_AF, .off = _OUT(key[0].af), .cb = snl_attr_get_uint8 },
-	{ .type = PF_ST_PROTO, .off = _OUT(key[0].proto), .cb = snl_attr_get_uint8 },
 	{ .type = PF_ST_DIRECTION, .off = _OUT(direction), .cb = snl_attr_get_uint8 },
 	{ .type = PF_ST_LOG, .off = _OUT(log), .cb = snl_attr_get_uint8 },
 	{ .type = PF_ST_STATE_FLAGS, .off = _OUT(state_flags), .cb = snl_attr_get_uint16 },
@@ -1959,9 +1959,6 @@ pfctl_get_states_nl(struct pfctl_state_filter *filter, struct snl_state *ss, pfc
 		if (!snl_parse_nlmsg(ss, hdr, &state_parser, &s))
 			continue;
 
-		s.key[1].af = s.key[0].af;
-		s.key[1].proto = s.key[0].proto;
-
 		ret = f(&s, arg);
 		if (ret != 0)
 			return (ret);
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
index d2a050140dbc..3af27e11d27f 100644
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -133,6 +133,8 @@ dump_state_key(struct nl_writer *nw, int attr, const struct pf_state_key *key)
 	dump_addr(nw, PF_STK_ADDR1, &key->addr[1], key->af);
 	nlattr_add_u16(nw, PF_STK_PORT0, key->port[0]);
 	nlattr_add_u16(nw, PF_STK_PORT1, key->port[1]);
+	nlattr_add_u8(nw, PF_STK_AF, key->af);
+	nlattr_add_u16(nw, PF_STK_PROTO, key->proto);
 
 	nlattr_set_len(nw, off);
 
diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h
index 096b9913d4a6..3af931978860 100644
--- a/sys/netpfil/pf/pf_nl.h
+++ b/sys/netpfil/pf/pf_nl.h
@@ -71,6 +71,8 @@ enum pfstate_key_type_t {
 	PF_STK_ADDR1		= 2, /* ip */
 	PF_STK_PORT0		= 3, /* u16 */
 	PF_STK_PORT1		= 4, /* u16 */
+	PF_STK_AF		= 5, /* u8 */
+	PF_STK_PROTO		= 6, /* u16 */
 };
 
 enum pfstate_peer_type_t {