git: 1fc0dac54cb4 - main - pf: Convert struct pf_addr_wrap before sending it over netlink

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Thu, 15 Aug 2024 11:06:31 UTC
The branch main has been updated by kp:

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

commit 1fc0dac54cb444d6c22102d7bbc23545de459e0f
Author:     Kajetan Staszkiewicz <vegeta@tuxpowered.net>
AuthorDate: 2024-08-15 09:07:27 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2024-08-15 09:11:59 +0000

    pf: Convert struct pf_addr_wrap before sending it over netlink
    
    The struct pf_addr_wrap when used inside of kernel operates on pointers to
    tables or interfaces. When reading a ruleset the struct must contain
    counters calculated from the aforementioned tables and interfaces. Both the
    pointers and the resulting counters are stored in an union and thus can't be
    present in the struct at the same time.
    
    The original ioctl code handles this by making a copy of struct pf_addr_wrap
    for pool addresses, accessing the table or interface structures by their
    pointers, calculating the counter values and storing them in place of those
    pointers in the copy. Then this copy is sent over ioctl.
    
    Use this mechanism for netlink too. Create a copy of src/dst addresses. Use
    the existing function pf_addr_copyout() to convert pointers to counters both
    for src/dst and pool addresses.
    
    Reviewed by:    kp
    Differential Revision:  https://reviews.freebsd.org/D46291
---
 sys/net/pfvar.h           |  1 +
 sys/netpfil/pf/pf_ioctl.c |  3 +--
 sys/netpfil/pf/pf_nl.c    | 23 +++++++----------------
 3 files changed, 9 insertions(+), 18 deletions(-)

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index eeded1e900a6..863883c2d61e 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2533,6 +2533,7 @@ int			 pf_ioctl_get_addr(struct pfioc_pooladdr *);
 
 void			 pf_krule_free(struct pf_krule *);
 void			 pf_krule_clear_counters(struct pf_krule *);
+void			 pf_addr_copyout(struct pf_addr_wrap *);
 #endif
 
 /* The fingerprint functions can be linked into userland programs (tcpdump) */
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index 959ebdf94cd4..5467ebbed2eb 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -129,7 +129,6 @@ static void		 pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *);
 static int		 pf_commit_rules(u_int32_t, int, char *);
 static int		 pf_addr_setup(struct pf_kruleset *,
 			    struct pf_addr_wrap *, sa_family_t);
-static void		 pf_addr_copyout(struct pf_addr_wrap *);
 static void		 pf_src_node_copy(const struct pf_ksrc_node *,
 			    struct pf_src_node *);
 #ifdef ALTQ
@@ -1525,7 +1524,7 @@ pf_addr_setup(struct pf_kruleset *ruleset, struct pf_addr_wrap *addr,
 	return (error);
 }
 
-static void
+void
 pf_addr_copyout(struct pf_addr_wrap *addr)
 {
 
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
index 060cd5e39852..6e752159b4bd 100644
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -416,7 +416,6 @@ static bool
 nlattr_add_addr_wrap(struct nl_writer *nw, int attrtype, struct pf_addr_wrap *a)
 {
 	int off = nlattr_add_nested(nw, attrtype);
-	int num;
 
 	nlattr_add_in6_addr(nw, PF_AT_ADDR, &a->v.a.addr.v6);
 	nlattr_add_in6_addr(nw, PF_AT_MASK, &a->v.a.mask.v6);
@@ -425,22 +424,10 @@ nlattr_add_addr_wrap(struct nl_writer *nw, int attrtype, struct pf_addr_wrap *a)
 
 	if (a->type == PF_ADDR_DYNIFTL) {
 		nlattr_add_string(nw, PF_AT_IFNAME, a->v.ifname);
-		num = 0;
-		if (a->p.dyn != NULL)
-			num = a->p.dyn->pfid_acnt4 + a->p.dyn->pfid_acnt6;
-		nlattr_add_u32(nw, PF_AT_DYNCNT, num);
+		nlattr_add_u32(nw, PF_AT_DYNCNT, a->p.dyncnt);
 	} else if (a->type == PF_ADDR_TABLE) {
-		struct pfr_ktable *kt;
-
 		nlattr_add_string(nw, PF_AT_TABLENAME, a->v.tblname);
-		num = -1;
-		kt = a->p.tbl;
-		if ((kt->pfrkt_flags & PFR_TFLAG_ACTIVE) &&
-		    kt->pfrkt_root != NULL)
-			kt = kt->pfrkt_root;
-		if (kt->pfrkt_flags & PFR_TFLAG_ACTIVE)
-			num = kt->pfrkt_cnt;
-		nlattr_add_u32(nw, PF_AT_TBLCNT, num);
+		nlattr_add_u32(nw, PF_AT_TBLCNT, a->p.tblcnt);
 	}
 
 	nlattr_set_len(nw, off);
@@ -462,9 +449,13 @@ NL_DECLARE_ATTR_PARSER(rule_addr_parser, nla_p_ruleaddr);
 static bool
 nlattr_add_rule_addr(struct nl_writer *nw, int attrtype, struct pf_rule_addr *r)
 {
+	struct pf_addr_wrap aw = {0};
 	int off = nlattr_add_nested(nw, attrtype);
 
-	nlattr_add_addr_wrap(nw, PF_RAT_ADDR, &r->addr);
+	bcopy(&(r->addr), &aw, sizeof(struct pf_addr_wrap));
+	pf_addr_copyout(&aw);
+
+	nlattr_add_addr_wrap(nw, PF_RAT_ADDR, &aw);
 	nlattr_add_u16(nw, PF_RAT_SRC_PORT, r->port[0]);
 	nlattr_add_u16(nw, PF_RAT_DST_PORT, r->port[1]);
 	nlattr_add_u8(nw, PF_RAT_NEG, r->neg);