The branch main has been updated by kp:

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

commit e5a99196e269bd397a0c533dea792eaceb80a2a4
Author:     Kristof Provost <k...@freebsd.org>
AuthorDate: 2025-07-03 15:16:21 +0000
Commit:     Kristof Provost <k...@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);

Reply via email to