git: ba2a92078626 - main - pf: convert DIOCBEGINADDRS to netlink
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 08 Jun 2024 02:47:22 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=ba2a920786265f364973562abe9262829cf1901b
commit ba2a920786265f364973562abe9262829cf1901b
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2024-06-07 20:44:40 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2024-06-08 02:46:43 +0000
pf: convert DIOCBEGINADDRS to netlink
---
contrib/pf/ftp-proxy/filter.c | 2 +-
contrib/pf/tftp-proxy/filter.c | 2 +-
lib/libpfctl/libpfctl.c | 49 ++++++++++++++++++++++++++++++++++++++++++
lib/libpfctl/libpfctl.h | 1 +
sbin/pfctl/pfctl.c | 2 +-
sys/net/pfvar.h | 1 +
sys/netpfil/pf/pf_ioctl.c | 16 ++++++++++----
sys/netpfil/pf/pf_nl.c | 37 +++++++++++++++++++++++++++++++
sys/netpfil/pf/pf_nl.h | 6 ++++++
9 files changed, 109 insertions(+), 7 deletions(-)
diff --git a/contrib/pf/ftp-proxy/filter.c b/contrib/pf/ftp-proxy/filter.c
index e3276f88489e..7d6d3f1fa348 100644
--- a/contrib/pf/ftp-proxy/filter.c
+++ b/contrib/pf/ftp-proxy/filter.c
@@ -263,7 +263,7 @@ prepare_rule(u_int32_t id, int rs_num, struct sockaddr *src,
errno = EINVAL;
return (-1);
}
- if (ioctl(pfctl_fd(pfh), DIOCBEGINADDRS, &pfp) == -1)
+ if (pfctl_begin_addrs(pfh, &pfp.ticket))
return (-1);
pfpool_ticket = pfp.ticket;
diff --git a/contrib/pf/tftp-proxy/filter.c b/contrib/pf/tftp-proxy/filter.c
index 3cf2e1fcf3ab..8d5dcc21badc 100644
--- a/contrib/pf/tftp-proxy/filter.c
+++ b/contrib/pf/tftp-proxy/filter.c
@@ -272,7 +272,7 @@ prepare_rule(u_int32_t id, int rs_num, struct sockaddr *src,
errno = EINVAL;
return (-1);
}
- if (ioctl(pfctl_fd(pfh), DIOCBEGINADDRS, &pfp) == -1)
+ if (pfctl_begin_addrs(pfh, &pfp.ticket))
return (-1);
pfpool_ticket = pfp.ticket;
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index ebe52e7a415f..b9fba232b8ca 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -2688,3 +2688,52 @@ pfctl_get_limit(struct pfctl_handle *h, const int index, uint *limit)
return (e.error);
}
+
+struct pfctl_nl_begin_addrs {
+ uint32_t ticket;
+};
+#define _OUT(_field) offsetof(struct pfctl_nl_begin_addrs, _field)
+static struct snl_attr_parser ap_begin_addrs[] = {
+ { .type = PF_BA_TICKET, .off = _OUT(ticket), .cb = snl_attr_get_uint32 },
+};
+static struct snl_field_parser fp_begin_addrs[] = {};
+#undef _OUT
+SNL_DECLARE_PARSER(begin_addrs_parser, struct genlmsghdr, fp_begin_addrs, ap_begin_addrs);
+
+int
+pfctl_begin_addrs(struct pfctl_handle *h, uint32_t *ticket)
+{
+ struct snl_writer nw;
+ struct pfctl_nl_begin_addrs attrs = {};
+ struct snl_errmsg_data e = {};
+ struct nlmsghdr *hdr;
+ uint32_t seq_id;
+ int family_id;
+
+ family_id = snl_get_genl_family(&h->ss, PFNL_FAMILY_NAME);
+ if (family_id == 0)
+ return (ENOTSUP);
+
+ snl_init_writer(&h->ss, &nw);
+ hdr = snl_create_genl_msg_request(&nw, family_id, PFNL_CMD_BEGIN_ADDRS);
+ hdr->nlmsg_flags |= NLM_F_DUMP;
+
+ if ((hdr = snl_finalize_msg(&nw)) == NULL)
+ return (ENXIO);
+
+ seq_id = hdr->nlmsg_seq;
+
+ if (! snl_send_message(&h->ss, hdr))
+ return (ENXIO);
+
+ while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) {
+ if (! snl_parse_nlmsg(&h->ss, hdr, &begin_addrs_parser, &attrs))
+ continue;
+ }
+
+ if (ticket != NULL)
+ *ticket = attrs.ticket;
+
+ return (e.error);
+}
+
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
index 44c7fa47e88d..eebc97c52565 100644
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -497,5 +497,6 @@ int pfctl_set_timeout(struct pfctl_handle *h, uint32_t timeout, uint32_t seconds
int pfctl_get_timeout(struct pfctl_handle *h, uint32_t timeout, uint32_t *seconds);
int pfctl_set_limit(struct pfctl_handle *h, const int index, const uint limit);
int pfctl_get_limit(struct pfctl_handle *h, const int index, uint *limit);
+int pfctl_begin_addrs(struct pfctl_handle *h, uint32_t *ticket);
#endif
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index ec718f6b0a99..450c64785b9c 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1719,7 +1719,7 @@ pfctl_add_pool(struct pfctl *pf, struct pfctl_pool *p, sa_family_t af)
struct pf_pooladdr *pa;
if ((pf->opts & PF_OPT_NOACTION) == 0) {
- if (ioctl(pf->dev, DIOCBEGINADDRS, &pf->paddr))
+ if (pfctl_begin_addrs(pf->h, &pf->paddr.ticket))
err(1, "DIOCBEGINADDRS");
}
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index eb36c0aee4d1..d6d01c9b5970 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2507,6 +2507,7 @@ int pf_ioctl_get_timeout(int, int *);
int pf_ioctl_set_timeout(int, int, int *);
int pf_ioctl_get_limit(int, unsigned int *);
int pf_ioctl_set_limit(int, unsigned int, unsigned int *);
+int pf_ioctl_begin_addrs(uint32_t *);
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 af3f914982ec..f801afd9da80 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -2517,6 +2517,17 @@ pf_ioctl_get_limit(int index, unsigned int *limit)
return (0);
}
+int
+pf_ioctl_begin_addrs(uint32_t *ticket)
+{
+ PF_RULES_WLOCK();
+ pf_empty_kpool(&V_pf_pabuf);
+ *ticket = ++V_ticket_pabuf;
+ PF_RULES_WUNLOCK();
+
+ return (0);
+}
+
static int
pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
{
@@ -4182,10 +4193,7 @@ DIOCGETSTATESV2_full:
case DIOCBEGINADDRS: {
struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
- PF_RULES_WLOCK();
- pf_empty_kpool(&V_pf_pabuf);
- pp->ticket = ++V_ticket_pabuf;
- PF_RULES_WUNLOCK();
+ error = pf_ioctl_begin_addrs(&pp->ticket);
break;
}
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
index 57b1a4a6b5b3..615a9229b3f3 100644
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -1471,6 +1471,36 @@ pf_handle_get_limit(struct nlmsghdr *hdr, struct nl_pstate *npt)
return (0);
}
+static int
+pf_handle_begin_addrs(struct nlmsghdr *hdr, struct nl_pstate *npt)
+{
+ struct nl_writer *nw = npt->nw;
+ struct genlmsghdr *ghdr_new;
+ uint32_t ticket;
+ int error;
+
+ error = pf_ioctl_begin_addrs(&ticket);
+ if (error != 0)
+ return (error);
+
+ if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr)))
+ return (ENOMEM);
+
+ ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
+ ghdr_new->cmd = PFNL_CMD_BEGIN_ADDRS;
+ ghdr_new->version = 0;
+ ghdr_new->reserved = 0;
+
+ nlattr_add_u32(nw, PF_BA_TICKET, ticket);
+
+ if (!nlmsg_end(nw)) {
+ nlmsg_abort(nw);
+ return (ENOMEM);
+ }
+
+ return (0);
+}
+
static const struct nlhdr_parser *all_parsers[] = {
&state_parser,
&addrule_parser,
@@ -1612,6 +1642,13 @@ static const struct genl_cmd pf_cmds[] = {
.cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
.cmd_priv = PRIV_NETINET_PF,
},
+ {
+ .cmd_num = PFNL_CMD_BEGIN_ADDRS,
+ .cmd_name = "BEGIN_ADDRS",
+ .cmd_cb = pf_handle_begin_addrs,
+ .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
+ .cmd_priv = PRIV_NETINET_PF,
+ },
};
void
diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h
index 437cc6482dbb..d50b5a1e9d43 100644
--- a/sys/netpfil/pf/pf_nl.h
+++ b/sys/netpfil/pf/pf_nl.h
@@ -54,6 +54,7 @@ enum {
PFNL_CMD_GET_TIMEOUT = 16,
PFNL_CMD_SET_LIMIT = 17,
PFNL_CMD_GET_LIMIT = 18,
+ PFNL_CMD_BEGIN_ADDRS = 19,
__PFNL_CMD_MAX,
};
#define PFNL_CMD_MAX (__PFNL_CMD_MAX -1)
@@ -350,6 +351,11 @@ enum pf_limit_types_t {
PF_LI_LIMIT = 2, /* u32 */
};
+enum pf_begin_addrs_types_t {
+ PF_BA_UNSPEC,
+ PF_BA_TICKET = 1, /* u32 */
+};
+
#ifdef _KERNEL
void pf_nl_register(void);