git: 727e413ff3f1 - main - libpfctl: add pfctl_open_from_nl_fd() and pfctl_nl_fd()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 30 Oct 2026 14:08:07 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=727e413ff3f18af8788ea78043b506e0111bfadc
commit 727e413ff3f18af8788ea78043b506e0111bfadc
Author: Avinash Duduskar <avinash.duduskar@gmail.com>
AuthorDate: 2026-10-26 14:38:10 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2026-10-30 14:06:58 +0000
libpfctl: add pfctl_open_from_nl_fd() and pfctl_nl_fd()
pfctl_open_from_nl_fd() opens the pf device as pfctl_open() does but,
when given a descriptor, adopts it as the Netlink socket instead of
creating one. The handle's sequence numbers start at a random value:
replies are matched by sequence number, so a random start makes it
improbable that a reply an earlier owner of the socket left unread is
taken for the answer to one of ours, or one of ours for theirs, however
many times the socket has been handed on. pfctl_open() becomes a
wrapper that passes -1.
pfctl_nl_fd() returns the handle's Netlink descriptor, as pfctl_fd()
does for the device, so a caller can hand it to a child process.
PR: 291981
Signed-off-by: Avinash Duduskar <avinash.duduskar@gmail.com>
Reviewed by: kp
Pull Request: https://github.com/freebsd/freebsd-src/pull/2508
---
lib/libpfctl/libpfctl.c | 28 +++++++++++++++++++++++++---
lib/libpfctl/libpfctl.h | 3 +++
2 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index 1522fd1554ab..22ad7888bace 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -73,7 +73,7 @@ static int _pfctl_clear_states(int , const struct pfctl_kill *,
static void _pfctl_verify_parsers(void);
struct pfctl_handle *
-pfctl_open(const char *pf_device)
+pfctl_open_from_nl_fd(const char *pf_device, int nl_fd)
{
struct pfctl_handle *h;
@@ -85,8 +85,18 @@ pfctl_open(const char *pf_device)
if (h->fd < 0)
goto error;
- if (!snl_init(&h->ss, NETLINK_GENERIC))
- goto error;
+ if (nl_fd >= 0) {
+ if (!snl_init_fd(&h->ss, nl_fd))
+ goto error;
+ /*
+ * Replies are matched by sequence number; a random start makes
+ * a collision with an earlier owner's counter improbable.
+ */
+ h->ss.seq = arc4random();
+ } else {
+ if (!snl_init(&h->ss, NETLINK_GENERIC))
+ goto error;
+ }
h->family_id = snl_get_genl_family(&h->ss, PFNL_FAMILY_NAME);
if (h->family_id == 0)
@@ -102,6 +112,12 @@ error:
return (NULL);
}
+struct pfctl_handle *
+pfctl_open(const char *pf_device)
+{
+ return (pfctl_open_from_nl_fd(pf_device, -1));
+}
+
void
pfctl_close(struct pfctl_handle *h)
{
@@ -116,6 +132,12 @@ pfctl_fd(struct pfctl_handle *h)
return (h->fd);
}
+int
+pfctl_nl_fd(struct pfctl_handle *h)
+{
+ return (h->ss.fd);
+}
+
static int
pfctl_do_netlink_cmd(struct pfctl_handle *h, uint cmd)
{
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
index 0e56d081e9d7..41be320329d1 100644
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -444,8 +444,11 @@ struct pfctl_src_node {
struct pfctl_handle;
struct pfctl_handle *pfctl_open(const char *pf_device);
+struct pfctl_handle *pfctl_open_from_nl_fd(const char *pf_device,
+ int nl_fd);
void pfctl_close(struct pfctl_handle *);
int pfctl_fd(struct pfctl_handle *);
+int pfctl_nl_fd(struct pfctl_handle *);
int pfctl_startstop(struct pfctl_handle *h, int start);
struct pfctl_status* pfctl_get_status_h(struct pfctl_handle *h);