git: 1fc0dac54cb4 - main - pf: Convert struct pf_addr_wrap before sending it over netlink
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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);