Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Jul 2025 08:59:06 GMT
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: e5a99196e269 - main - pf: deduplicate the ioctl and netlink NATLOOK handling
Message-ID:  <202507090859.5698x6Iv044955@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kp:

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

commit e5a99196e269bd397a0c533dea792eaceb80a2a4
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-07-03 15:16:21 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-07-09 08:57:49 +0000

    pf: deduplicate the ioctl and netlink NATLOOK handling
    
    Factor out handling of NATLOOK to a separate function so we can use it for both
    the ioctl and netlink implementation.
    
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sys/net/pfvar.h           |  1 +
 sys/netpfil/pf/pf_ioctl.c | 97 +++++++++++++++++++++++++----------------------
 sys/netpfil/pf/pf_nl.c    | 68 +++++++--------------------------
 3 files changed, 66 insertions(+), 100 deletions(-)

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 1416f0c2cdbe..0970f041cb1b 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2670,6 +2670,7 @@ int			 pf_ioctl_get_addrs(struct pf_nl_pooladdr *);
 int			 pf_ioctl_get_addr(struct pf_nl_pooladdr *);
 int			 pf_ioctl_get_rulesets(struct pfioc_ruleset *);
 int			 pf_ioctl_get_ruleset(struct pfioc_ruleset *);
+int			 pf_ioctl_natlook(struct pfioc_natlook *);
 
 void			 pf_krule_free(struct pf_krule *);
 void			 pf_krule_clear_counters(struct pf_krule *);
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index 9cd7cea340a6..8a3f311d7d30 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -2796,6 +2796,56 @@ pf_ioctl_get_ruleset(struct pfioc_ruleset *pr)
 	return (error);
 }
 
+int
+pf_ioctl_natlook(struct pfioc_natlook *pnl)
+{
+	struct pf_state_key	*sk;
+	struct pf_kstate	*state;
+	struct pf_state_key_cmp	 key;
+	int			 m = 0, direction = pnl->direction;
+	int			 sidx, didx;
+
+	/* NATLOOK src and dst are reversed, so reverse sidx/didx */
+	sidx = (direction == PF_IN) ? 1 : 0;
+	didx = (direction == PF_IN) ? 0 : 1;
+
+	if (!pnl->proto ||
+	    PF_AZERO(&pnl->saddr, pnl->af) ||
+	    PF_AZERO(&pnl->daddr, pnl->af) ||
+	    ((pnl->proto == IPPROTO_TCP ||
+	    pnl->proto == IPPROTO_UDP) &&
+	    (!pnl->dport || !pnl->sport)))
+		return (EINVAL);
+
+	bzero(&key, sizeof(key));
+	key.af = pnl->af;
+	key.proto = pnl->proto;
+	pf_addrcpy(&key.addr[sidx], &pnl->saddr, pnl->af);
+	key.port[sidx] = pnl->sport;
+	pf_addrcpy(&key.addr[didx], &pnl->daddr, pnl->af);
+	key.port[didx] = pnl->dport;
+
+	state = pf_find_state_all(&key, direction, &m);
+	if (state == NULL)
+		return (ENOENT);
+
+	if (m > 1) {
+		PF_STATE_UNLOCK(state);
+		return (E2BIG);	/* more than one state */
+	}
+
+	sk = state->key[sidx];
+	pf_addrcpy(&pnl->rsaddr,
+	    &sk->addr[sidx], sk->af);
+	pnl->rsport = sk->port[sidx];
+	pf_addrcpy(&pnl->rdaddr,
+	    &sk->addr[didx], sk->af);
+	pnl->rdport = sk->port[didx];
+	PF_STATE_UNLOCK(state);
+
+	return (0);
+}
+
 static int
 pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
 {
@@ -4133,51 +4183,8 @@ DIOCGETSTATESV2_full:
 
 	case DIOCNATLOOK: {
 		struct pfioc_natlook	*pnl = (struct pfioc_natlook *)addr;
-		struct pf_state_key	*sk;
-		struct pf_kstate	*state;
-		struct pf_state_key_cmp	 key;
-		int			 m = 0, direction = pnl->direction;
-		int			 sidx, didx;
-
-		/* NATLOOK src and dst are reversed, so reverse sidx/didx */
-		sidx = (direction == PF_IN) ? 1 : 0;
-		didx = (direction == PF_IN) ? 0 : 1;
-
-		if (!pnl->proto ||
-		    PF_AZERO(&pnl->saddr, pnl->af) ||
-		    PF_AZERO(&pnl->daddr, pnl->af) ||
-		    ((pnl->proto == IPPROTO_TCP ||
-		    pnl->proto == IPPROTO_UDP) &&
-		    (!pnl->dport || !pnl->sport)))
-			error = EINVAL;
-		else {
-			bzero(&key, sizeof(key));
-			key.af = pnl->af;
-			key.proto = pnl->proto;
-			pf_addrcpy(&key.addr[sidx], &pnl->saddr, pnl->af);
-			key.port[sidx] = pnl->sport;
-			pf_addrcpy(&key.addr[didx], &pnl->daddr, pnl->af);
-			key.port[didx] = pnl->dport;
-
-			state = pf_find_state_all(&key, direction, &m);
-			if (state == NULL) {
-				error = ENOENT;
-			} else {
-				if (m > 1) {
-					PF_STATE_UNLOCK(state);
-					error = E2BIG;	/* more than one state */
-				} else {
-					sk = state->key[sidx];
-					pf_addrcpy(&pnl->rsaddr,
-					    &sk->addr[sidx], sk->af);
-					pnl->rsport = sk->port[sidx];
-					pf_addrcpy(&pnl->rdaddr,
-					    &sk->addr[didx], sk->af);
-					pnl->rdport = sk->port[didx];
-					PF_STATE_UNLOCK(state);
-				}
-			}
-		}
+
+		error = pf_ioctl_natlook(pnl);
 		break;
 	}
 
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
index d5d6dc70255e..73933c022ca2 100644
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -1256,23 +1256,13 @@ pf_handle_clear_status(struct nlmsghdr *hdr, struct nl_pstate *npt)
 	return (0);
 }
 
-struct pf_nl_natlook {
-	sa_family_t af;
-	uint8_t direction;
-	uint8_t proto;
-	struct pf_addr src;
-	struct pf_addr dst;
-	uint16_t sport;
-	uint16_t dport;
-};
-
-#define	_OUT(_field)	offsetof(struct pf_nl_natlook, _field)
+#define	_OUT(_field)	offsetof(struct pfioc_natlook, _field)
 static const struct nlattr_parser nla_p_natlook[] = {
 	{ .type = PF_NL_AF, .off = _OUT(af), .cb = nlattr_get_uint8 },
 	{ .type = PF_NL_DIRECTION, .off = _OUT(direction), .cb = nlattr_get_uint8 },
 	{ .type = PF_NL_PROTO, .off = _OUT(proto), .cb = nlattr_get_uint8 },
-	{ .type = PF_NL_SRC_ADDR, .off = _OUT(src), .cb = nlattr_get_in6_addr },
-	{ .type = PF_NL_DST_ADDR, .off = _OUT(dst), .cb = nlattr_get_in6_addr },
+	{ .type = PF_NL_SRC_ADDR, .off = _OUT(saddr), .cb = nlattr_get_in6_addr },
+	{ .type = PF_NL_DST_ADDR, .off = _OUT(daddr), .cb = nlattr_get_in6_addr },
 	{ .type = PF_NL_SRC_PORT, .off = _OUT(sport), .cb = nlattr_get_uint16 },
 	{ .type = PF_NL_DST_PORT, .off = _OUT(dport), .cb = nlattr_get_uint16 },
 };
@@ -1282,63 +1272,31 @@ NL_DECLARE_PARSER(natlook_parser, struct genlmsghdr, nlf_p_empty, nla_p_natlook)
 static int
 pf_handle_natlook(struct nlmsghdr *hdr, struct nl_pstate *npt)
 {
-	struct pf_nl_natlook	 attrs = {};
-	struct pf_state_key_cmp	 key = {};
+	struct pfioc_natlook attrs = {};
 	struct nl_writer	*nw = npt->nw;
-	struct pf_state_key	*sk;
-	struct pf_kstate	*state;
 	struct genlmsghdr	*ghdr_new;
-	int			 error, m = 0;
-	int			 sidx, didx;
+	int			 error;
 
 	error = nl_parse_nlmsg(hdr, &natlook_parser, npt, &attrs);
 	if (error != 0)
 		return (error);
 
-	if (attrs.proto == 0 ||
-	    PF_AZERO(&attrs.src, attrs.af) ||
-	    PF_AZERO(&attrs.dst, attrs.af) ||
-	    ((attrs.proto == IPPROTO_TCP || attrs.proto == IPPROTO_UDP) &&
-	     (attrs.sport == 0 || attrs.dport == 0)))
-		return (EINVAL);
-
-	/* NATLOOK src and dst are reversed, so reverse sidx/didx */
-	sidx = (attrs.direction == PF_IN) ? 1 : 0;
-	didx = (attrs.direction == PF_IN) ? 0 : 1;
-
-	key.af = attrs.af;
-	key.proto = attrs.proto;
-	pf_addrcpy(&key.addr[sidx], &attrs.src, attrs.af);
-	key.port[sidx] = attrs.sport;
-	pf_addrcpy(&key.addr[didx], &attrs.dst, attrs.af);
-	key.port[didx] = attrs.dport;
-
-	state = pf_find_state_all(&key, attrs.direction, &m);
-	if (state == NULL)
-		return (ENOENT);
-	if (m > 1) {
-		PF_STATE_UNLOCK(state);
-		return (E2BIG);
-	}
+	error = pf_ioctl_natlook(&attrs);
+	if (error != 0)
+		return (error);
 
-	if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) {
-		PF_STATE_UNLOCK(state);
+	if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr)))
 		return (ENOMEM);
-	}
 
 	ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
 	ghdr_new->cmd = PFNL_CMD_NATLOOK;
 	ghdr_new->version = 0;
 	ghdr_new->reserved = 0;
 
-	sk = state->key[sidx];
-
-	nlattr_add_in6_addr(nw, PF_NL_SRC_ADDR, &sk->addr[sidx].v6);
-	nlattr_add_in6_addr(nw, PF_NL_DST_ADDR, &sk->addr[didx].v6);
-	nlattr_add_u16(nw, PF_NL_SRC_PORT, sk->port[sidx]);
-	nlattr_add_u16(nw, PF_NL_DST_PORT, sk->port[didx]);
-
-	PF_STATE_UNLOCK(state);
+	nlattr_add_in6_addr(nw, PF_NL_SRC_ADDR, &attrs.rsaddr.v6);
+	nlattr_add_in6_addr(nw, PF_NL_DST_ADDR, &attrs.rdaddr.v6);
+	nlattr_add_u16(nw, PF_NL_SRC_PORT, attrs.rsport);
+	nlattr_add_u16(nw, PF_NL_DST_PORT, attrs.rdport);
 
 	if (!nlmsg_end(nw)) {
 		nlmsg_abort(nw);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202507090859.5698x6Iv044955>