Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 Jan 2021 14:45:04 GMT
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 34b94d9ebb2d - stable/12 - pfctl: Stop sharing pf_ruleset.c with the kernel
Message-ID:  <202101201445.10KEj48R019518@gitrepo.freebsd.org>

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

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

commit 34b94d9ebb2d6cb9e97eade82ea5b8ace28a937d
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2020-12-24 15:02:04 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2021-01-20 14:16:05 +0000

    pfctl: Stop sharing pf_ruleset.c with the kernel
    
    Now that we've split up the datastructures used by the kernel and
    userspace there's essentually no more overlap between the pf_ruleset.c
    code used by userspace and kernelspace.
    
    Copy the userspace bits to the pfctl directory and stop using the kernel
    file.
    
    Reviewed by:    philip
    MFC after:      2 weeks
    Sponsored by:   Orange Business Services
    Differential Revision:  https://reviews.freebsd.org/D27764
    
    (cherry picked from commit fda7daf06301beef1bdad39891232a12c6925b22)
---
 sbin/pfctl/Makefile         |   3 -
 sbin/pfctl/pf_ruleset.c     | 343 ++++++++++++++++++++++++++++++++++++++++++++
 sys/netpfil/pf/pf_ruleset.c | 285 +-----------------------------------
 3 files changed, 348 insertions(+), 283 deletions(-)

diff --git a/sbin/pfctl/Makefile b/sbin/pfctl/Makefile
index 8ca3b5d86285..14dc83eb97b0 100644
--- a/sbin/pfctl/Makefile
+++ b/sbin/pfctl/Makefile
@@ -2,9 +2,6 @@
 
 .include <src.opts.mk>
 
-# pf_ruleset.c is shared between kernel and pfctl
-.PATH: ${SRCTOP}/sys/netpfil/pf
-
 PACKAGE=pf
 CONFS=	pf.os
 PROG=	pfctl
diff --git a/sbin/pfctl/pf_ruleset.c b/sbin/pfctl/pf_ruleset.c
new file mode 100644
index 000000000000..7c337d7a2da7
--- /dev/null
+++ b/sbin/pfctl/pf_ruleset.c
@@ -0,0 +1,343 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2001 Daniel Hartmeier
+ * Copyright (c) 2002,2003 Henning Brauer
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    - Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    - Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Effort sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
+ *
+ *	$OpenBSD: pf_ruleset.c,v 1.2 2008/12/18 15:31:37 dhill Exp $
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/mbuf.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+#include <net/if.h>
+#include <net/vnet.h>
+#include <net/pfvar.h>
+
+#ifdef INET6
+#include <netinet/ip6.h>
+#endif /* INET6 */
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define rs_malloc(x)		 calloc(1, x)
+#define rs_free(x)		 free(x)
+
+#ifdef PFDEBUG
+#include <sys/stdarg.h>
+#define DPFPRINTF(format, x...)	fprintf(stderr, format , ##x)
+#else
+#define DPFPRINTF(format, x...)	((void)0)
+#endif /* PFDEBUG */
+
+struct pf_anchor_global	 pf_anchors;
+struct pf_anchor	 pf_main_anchor;
+#undef V_pf_anchors
+#define V_pf_anchors		 pf_anchors
+#undef pf_main_ruleset
+#define pf_main_ruleset		 pf_main_anchor.ruleset
+
+static __inline int		pf_anchor_compare(struct pf_anchor *,
+				    struct pf_anchor *);
+static struct pf_anchor		*pf_find_anchor(const char *);
+
+RB_GENERATE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare);
+RB_GENERATE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare);
+
+static __inline int
+pf_anchor_compare(struct pf_anchor *a, struct pf_anchor *b)
+{
+	int c = strcmp(a->path, b->path);
+
+	return (c ? (c < 0 ? -1 : 1) : 0);
+}
+
+int
+pf_get_ruleset_number(u_int8_t action)
+{
+	switch (action) {
+	case PF_SCRUB:
+	case PF_NOSCRUB:
+		return (PF_RULESET_SCRUB);
+		break;
+	case PF_PASS:
+	case PF_DROP:
+		return (PF_RULESET_FILTER);
+		break;
+	case PF_NAT:
+	case PF_NONAT:
+		return (PF_RULESET_NAT);
+		break;
+	case PF_BINAT:
+	case PF_NOBINAT:
+		return (PF_RULESET_BINAT);
+		break;
+	case PF_RDR:
+	case PF_NORDR:
+		return (PF_RULESET_RDR);
+		break;
+	default:
+		return (PF_RULESET_MAX);
+		break;
+	}
+}
+
+void
+pf_init_ruleset(struct pf_ruleset *ruleset)
+{
+	int	i;
+
+	memset(ruleset, 0, sizeof(struct pf_ruleset));
+	for (i = 0; i < PF_RULESET_MAX; i++) {
+		TAILQ_INIT(&ruleset->rules[i].queues[0]);
+		TAILQ_INIT(&ruleset->rules[i].queues[1]);
+		ruleset->rules[i].active.ptr = &ruleset->rules[i].queues[0];
+		ruleset->rules[i].inactive.ptr = &ruleset->rules[i].queues[1];
+	}
+}
+
+static struct pf_anchor *
+pf_find_anchor(const char *path)
+{
+	struct pf_anchor	*key, *found;
+
+	key = (struct pf_anchor *)rs_malloc(sizeof(*key));
+	if (key == NULL)
+		return (NULL);
+	strlcpy(key->path, path, sizeof(key->path));
+	found = RB_FIND(pf_anchor_global, &V_pf_anchors, key);
+	rs_free(key);
+	return (found);
+}
+
+struct pf_ruleset *
+pf_find_ruleset(const char *path)
+{
+	struct pf_anchor	*anchor;
+
+	while (*path == '/')
+		path++;
+	if (!*path)
+		return (&pf_main_ruleset);
+	anchor = pf_find_anchor(path);
+	if (anchor == NULL)
+		return (NULL);
+	else
+		return (&anchor->ruleset);
+}
+
+struct pf_ruleset *
+pf_find_or_create_ruleset(const char *path)
+{
+	char			*p, *q, *r;
+	struct pf_ruleset	*ruleset;
+	struct pf_anchor	*anchor = NULL, *dup, *parent = NULL;
+
+	if (path[0] == 0)
+		return (&pf_main_ruleset);
+	while (*path == '/')
+		path++;
+	ruleset = pf_find_ruleset(path);
+	if (ruleset != NULL)
+		return (ruleset);
+	p = (char *)rs_malloc(MAXPATHLEN);
+	if (p == NULL)
+		return (NULL);
+	strlcpy(p, path, MAXPATHLEN);
+	while (parent == NULL && (q = strrchr(p, '/')) != NULL) {
+		*q = 0;
+		if ((ruleset = pf_find_ruleset(p)) != NULL) {
+			parent = ruleset->anchor;
+			break;
+		}
+	}
+	if (q == NULL)
+		q = p;
+	else
+		q++;
+	strlcpy(p, path, MAXPATHLEN);
+	if (!*q) {
+		rs_free(p);
+		return (NULL);
+	}
+	while ((r = strchr(q, '/')) != NULL || *q) {
+		if (r != NULL)
+			*r = 0;
+		if (!*q || strlen(q) >= PF_ANCHOR_NAME_SIZE ||
+		    (parent != NULL && strlen(parent->path) >=
+		    MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 1)) {
+			rs_free(p);
+			return (NULL);
+		}
+		anchor = (struct pf_anchor *)rs_malloc(sizeof(*anchor));
+		if (anchor == NULL) {
+			rs_free(p);
+			return (NULL);
+		}
+		RB_INIT(&anchor->children);
+		strlcpy(anchor->name, q, sizeof(anchor->name));
+		if (parent != NULL) {
+			strlcpy(anchor->path, parent->path,
+			    sizeof(anchor->path));
+			strlcat(anchor->path, "/", sizeof(anchor->path));
+		}
+		strlcat(anchor->path, anchor->name, sizeof(anchor->path));
+		if ((dup = RB_INSERT(pf_anchor_global, &V_pf_anchors, anchor)) !=
+		    NULL) {
+			printf("pf_find_or_create_ruleset: RB_INSERT1 "
+			    "'%s' '%s' collides with '%s' '%s'\n",
+			    anchor->path, anchor->name, dup->path, dup->name);
+			rs_free(anchor);
+			rs_free(p);
+			return (NULL);
+		}
+		if (parent != NULL) {
+			anchor->parent = parent;
+			if ((dup = RB_INSERT(pf_anchor_node, &parent->children,
+			    anchor)) != NULL) {
+				printf("pf_find_or_create_ruleset: "
+				    "RB_INSERT2 '%s' '%s' collides with "
+				    "'%s' '%s'\n", anchor->path, anchor->name,
+				    dup->path, dup->name);
+				RB_REMOVE(pf_anchor_global, &V_pf_anchors,
+				    anchor);
+				rs_free(anchor);
+				rs_free(p);
+				return (NULL);
+			}
+		}
+		pf_init_ruleset(&anchor->ruleset);
+		anchor->ruleset.anchor = anchor;
+		parent = anchor;
+		if (r != NULL)
+			q = r + 1;
+		else
+			*q = 0;
+	}
+	rs_free(p);
+	return (&anchor->ruleset);
+}
+
+void
+pf_remove_if_empty_ruleset(struct pf_ruleset *ruleset)
+{
+	struct pf_anchor	*parent;
+	int			 i;
+
+	while (ruleset != NULL) {
+		if (ruleset == &pf_main_ruleset || ruleset->anchor == NULL ||
+		    !RB_EMPTY(&ruleset->anchor->children) ||
+		    ruleset->anchor->refcnt > 0 || ruleset->tables > 0 ||
+		    ruleset->topen)
+			return;
+		for (i = 0; i < PF_RULESET_MAX; ++i)
+			if (!TAILQ_EMPTY(ruleset->rules[i].active.ptr) ||
+			    !TAILQ_EMPTY(ruleset->rules[i].inactive.ptr) ||
+			    ruleset->rules[i].inactive.open)
+				return;
+		RB_REMOVE(pf_anchor_global, &V_pf_anchors, ruleset->anchor);
+		if ((parent = ruleset->anchor->parent) != NULL)
+			RB_REMOVE(pf_anchor_node, &parent->children,
+			    ruleset->anchor);
+		rs_free(ruleset->anchor);
+		if (parent == NULL)
+			return;
+		ruleset = &parent->ruleset;
+	}
+}
+int
+pf_anchor_setup(struct pf_rule *r, const struct pf_ruleset *s,
+    const char *name)
+{
+	char			*p, *path;
+	struct pf_ruleset	*ruleset;
+
+	r->anchor = NULL;
+	r->anchor_relative = 0;
+	r->anchor_wildcard = 0;
+	if (!name[0])
+		return (0);
+	path = (char *)rs_malloc(MAXPATHLEN);
+	if (path == NULL)
+		return (1);
+	if (name[0] == '/')
+		strlcpy(path, name + 1, MAXPATHLEN);
+	else {
+		/* relative path */
+		r->anchor_relative = 1;
+		if (s->anchor == NULL || !s->anchor->path[0])
+			path[0] = 0;
+		else
+			strlcpy(path, s->anchor->path, MAXPATHLEN);
+		while (name[0] == '.' && name[1] == '.' && name[2] == '/') {
+			if (!path[0]) {
+				printf("pf_anchor_setup: .. beyond root\n");
+				rs_free(path);
+				return (1);
+			}
+			if ((p = strrchr(path, '/')) != NULL)
+				*p = 0;
+			else
+				path[0] = 0;
+			r->anchor_relative++;
+			name += 3;
+		}
+		if (path[0])
+			strlcat(path, "/", MAXPATHLEN);
+		strlcat(path, name, MAXPATHLEN);
+	}
+	if ((p = strrchr(path, '/')) != NULL && !strcmp(p, "/*")) {
+		r->anchor_wildcard = 1;
+		*p = 0;
+	}
+	ruleset = pf_find_or_create_ruleset(path);
+	rs_free(path);
+	if (ruleset == NULL || ruleset->anchor == NULL) {
+		printf("pf_anchor_setup: ruleset\n");
+		return (1);
+	}
+	r->anchor = ruleset->anchor;
+	r->anchor->refcnt++;
+	return (0);
+}
diff --git a/sys/netpfil/pf/pf_ruleset.c b/sys/netpfil/pf/pf_ruleset.c
index 9c697034649f..31a4ed879937 100644
--- a/sys/netpfil/pf/pf_ruleset.c
+++ b/sys/netpfil/pf/pf_ruleset.c
@@ -41,10 +41,8 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/socket.h>
-#ifdef _KERNEL
-# include <sys/systm.h>
-# include <sys/refcount.h>
-#endif /* _KERNEL */
+#include <sys/systm.h>
+#include <sys/refcount.h>
 #include <sys/mbuf.h>
 
 #include <netinet/in.h>
@@ -60,72 +58,26 @@ __FBSDID("$FreeBSD$");
 #include <netinet/ip6.h>
 #endif /* INET6 */
 
+#ifndef _KERNEL
+#error "Kernel only file. Please use sbin/pfctl/pf_ruleset.c instead."
+#endif
 
-#ifdef _KERNEL
 #define DPFPRINTF(format, x...)				\
 	if (V_pf_status.debug >= PF_DEBUG_NOISY)	\
 		printf(format , ##x)
 #define rs_malloc(x)		malloc(x, M_TEMP, M_NOWAIT|M_ZERO)
 #define rs_free(x)		free(x, M_TEMP)
 
-#else
-/* Userland equivalents so we can lend code to pfctl et al. */
-
-#include <arpa/inet.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#define rs_malloc(x)		 calloc(1, x)
-#define rs_free(x)		 free(x)
-
-#ifdef PFDEBUG
-#include <sys/stdarg.h>
-#define DPFPRINTF(format, x...)	fprintf(stderr, format , ##x)
-#else
-#define DPFPRINTF(format, x...)	((void)0)
-#endif /* PFDEBUG */
-#endif /* _KERNEL */
-
-#ifdef _KERNEL
 VNET_DEFINE(struct pf_kanchor_global,	pf_anchors);
 VNET_DEFINE(struct pf_kanchor,		pf_main_anchor);
-#else /* ! _KERNEL */
-struct pf_anchor_global	 pf_anchors;
-struct pf_anchor	 pf_main_anchor;
-#undef V_pf_anchors
-#define V_pf_anchors		 pf_anchors
-#undef pf_main_ruleset
-#define pf_main_ruleset		 pf_main_anchor.ruleset
-#endif /* _KERNEL */
-
 
-#ifdef _KERNEL
 static __inline int		pf_kanchor_compare(struct pf_kanchor *,
 				    struct pf_kanchor *);
 static struct pf_kanchor	*pf_find_kanchor(const char *);
 
 RB_GENERATE(pf_kanchor_global, pf_kanchor, entry_global, pf_kanchor_compare);
 RB_GENERATE(pf_kanchor_node, pf_kanchor, entry_node, pf_kanchor_compare);
-#else
-static __inline int		pf_anchor_compare(struct pf_anchor *,
-				    struct pf_anchor *);
-static struct pf_anchor		*pf_find_anchor(const char *);
-
-RB_GENERATE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare);
-RB_GENERATE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare);
-#endif
-
 
-#ifndef _KERNEL
-static __inline int
-pf_anchor_compare(struct pf_anchor *a, struct pf_anchor *b)
-{
-	int c = strcmp(a->path, b->path);
-
-	return (c ? (c < 0 ? -1 : 1) : 0);
-}
-#else
 static __inline int
 pf_kanchor_compare(struct pf_kanchor *a, struct pf_kanchor *b)
 {
@@ -133,7 +85,6 @@ pf_kanchor_compare(struct pf_kanchor *a, struct pf_kanchor *b)
 
 	return (c ? (c < 0 ? -1 : 1) : 0);
 }
-#endif
 
 int
 pf_get_ruleset_number(u_int8_t action)
@@ -165,35 +116,6 @@ pf_get_ruleset_number(u_int8_t action)
 	}
 }
 
-#ifndef _KERNEL
-void
-pf_init_ruleset(struct pf_ruleset *ruleset)
-{
-	int	i;
-
-	memset(ruleset, 0, sizeof(struct pf_ruleset));
-	for (i = 0; i < PF_RULESET_MAX; i++) {
-		TAILQ_INIT(&ruleset->rules[i].queues[0]);
-		TAILQ_INIT(&ruleset->rules[i].queues[1]);
-		ruleset->rules[i].active.ptr = &ruleset->rules[i].queues[0];
-		ruleset->rules[i].inactive.ptr = &ruleset->rules[i].queues[1];
-	}
-}
-
-static struct pf_anchor *
-pf_find_anchor(const char *path)
-{
-	struct pf_anchor	*key, *found;
-
-	key = (struct pf_anchor *)rs_malloc(sizeof(*key));
-	if (key == NULL)
-		return (NULL);
-	strlcpy(key->path, path, sizeof(key->path));
-	found = RB_FIND(pf_anchor_global, &V_pf_anchors, key);
-	rs_free(key);
-	return (found);
-}
-#else
 static struct pf_kanchor *
 pf_find_kanchor(const char *path)
 {
@@ -221,10 +143,7 @@ pf_init_kruleset(struct pf_kruleset *ruleset)
 		ruleset->rules[i].inactive.ptr = &ruleset->rules[i].queues[1];
 	}
 }
-#endif
-
 
-#ifdef _KERNEL
 struct pf_kruleset *
 pf_find_kruleset(const char *path)
 {
@@ -477,197 +396,3 @@ pf_kanchor_remove(struct pf_krule *r)
 		pf_remove_if_empty_kruleset(&r->anchor->ruleset);
 	r->anchor = NULL;
 }
-
-#else
-
-struct pf_ruleset *
-pf_find_ruleset(const char *path)
-{
-	struct pf_anchor	*anchor;
-
-	while (*path == '/')
-		path++;
-	if (!*path)
-		return (&pf_main_ruleset);
-	anchor = pf_find_anchor(path);
-	if (anchor == NULL)
-		return (NULL);
-	else
-		return (&anchor->ruleset);
-}
-
-struct pf_ruleset *
-pf_find_or_create_ruleset(const char *path)
-{
-	char			*p, *q, *r;
-	struct pf_ruleset	*ruleset;
-	struct pf_anchor	*anchor = NULL, *dup, *parent = NULL;
-
-	if (path[0] == 0)
-		return (&pf_main_ruleset);
-	while (*path == '/')
-		path++;
-	ruleset = pf_find_ruleset(path);
-	if (ruleset != NULL)
-		return (ruleset);
-	p = (char *)rs_malloc(MAXPATHLEN);
-	if (p == NULL)
-		return (NULL);
-	strlcpy(p, path, MAXPATHLEN);
-	while (parent == NULL && (q = strrchr(p, '/')) != NULL) {
-		*q = 0;
-		if ((ruleset = pf_find_ruleset(p)) != NULL) {
-			parent = ruleset->anchor;
-			break;
-		}
-	}
-	if (q == NULL)
-		q = p;
-	else
-		q++;
-	strlcpy(p, path, MAXPATHLEN);
-	if (!*q) {
-		rs_free(p);
-		return (NULL);
-	}
-	while ((r = strchr(q, '/')) != NULL || *q) {
-		if (r != NULL)
-			*r = 0;
-		if (!*q || strlen(q) >= PF_ANCHOR_NAME_SIZE ||
-		    (parent != NULL && strlen(parent->path) >=
-		    MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 1)) {
-			rs_free(p);
-			return (NULL);
-		}
-		anchor = (struct pf_anchor *)rs_malloc(sizeof(*anchor));
-		if (anchor == NULL) {
-			rs_free(p);
-			return (NULL);
-		}
-		RB_INIT(&anchor->children);
-		strlcpy(anchor->name, q, sizeof(anchor->name));
-		if (parent != NULL) {
-			strlcpy(anchor->path, parent->path,
-			    sizeof(anchor->path));
-			strlcat(anchor->path, "/", sizeof(anchor->path));
-		}
-		strlcat(anchor->path, anchor->name, sizeof(anchor->path));
-		if ((dup = RB_INSERT(pf_anchor_global, &V_pf_anchors, anchor)) !=
-		    NULL) {
-			printf("pf_find_or_create_ruleset: RB_INSERT1 "
-			    "'%s' '%s' collides with '%s' '%s'\n",
-			    anchor->path, anchor->name, dup->path, dup->name);
-			rs_free(anchor);
-			rs_free(p);
-			return (NULL);
-		}
-		if (parent != NULL) {
-			anchor->parent = parent;
-			if ((dup = RB_INSERT(pf_anchor_node, &parent->children,
-			    anchor)) != NULL) {
-				printf("pf_find_or_create_ruleset: "
-				    "RB_INSERT2 '%s' '%s' collides with "
-				    "'%s' '%s'\n", anchor->path, anchor->name,
-				    dup->path, dup->name);
-				RB_REMOVE(pf_anchor_global, &V_pf_anchors,
-				    anchor);
-				rs_free(anchor);
-				rs_free(p);
-				return (NULL);
-			}
-		}
-		pf_init_ruleset(&anchor->ruleset);
-		anchor->ruleset.anchor = anchor;
-		parent = anchor;
-		if (r != NULL)
-			q = r + 1;
-		else
-			*q = 0;
-	}
-	rs_free(p);
-	return (&anchor->ruleset);
-}
-
-void
-pf_remove_if_empty_ruleset(struct pf_ruleset *ruleset)
-{
-	struct pf_anchor	*parent;
-	int			 i;
-
-	while (ruleset != NULL) {
-		if (ruleset == &pf_main_ruleset || ruleset->anchor == NULL ||
-		    !RB_EMPTY(&ruleset->anchor->children) ||
-		    ruleset->anchor->refcnt > 0 || ruleset->tables > 0 ||
-		    ruleset->topen)
-			return;
-		for (i = 0; i < PF_RULESET_MAX; ++i)
-			if (!TAILQ_EMPTY(ruleset->rules[i].active.ptr) ||
-			    !TAILQ_EMPTY(ruleset->rules[i].inactive.ptr) ||
-			    ruleset->rules[i].inactive.open)
-				return;
-		RB_REMOVE(pf_anchor_global, &V_pf_anchors, ruleset->anchor);
-		if ((parent = ruleset->anchor->parent) != NULL)
-			RB_REMOVE(pf_anchor_node, &parent->children,
-			    ruleset->anchor);
-		rs_free(ruleset->anchor);
-		if (parent == NULL)
-			return;
-		ruleset = &parent->ruleset;
-	}
-}
-int
-pf_anchor_setup(struct pf_rule *r, const struct pf_ruleset *s,
-    const char *name)
-{
-	char			*p, *path;
-	struct pf_ruleset	*ruleset;
-
-	r->anchor = NULL;
-	r->anchor_relative = 0;
-	r->anchor_wildcard = 0;
-	if (!name[0])
-		return (0);
-	path = (char *)rs_malloc(MAXPATHLEN);
-	if (path == NULL)
-		return (1);
-	if (name[0] == '/')
-		strlcpy(path, name + 1, MAXPATHLEN);
-	else {
-		/* relative path */
-		r->anchor_relative = 1;
-		if (s->anchor == NULL || !s->anchor->path[0])
-			path[0] = 0;
-		else
-			strlcpy(path, s->anchor->path, MAXPATHLEN);
-		while (name[0] == '.' && name[1] == '.' && name[2] == '/') {
-			if (!path[0]) {
-				printf("pf_anchor_setup: .. beyond root\n");
-				rs_free(path);
-				return (1);
-			}
-			if ((p = strrchr(path, '/')) != NULL)
-				*p = 0;
-			else
-				path[0] = 0;
-			r->anchor_relative++;
-			name += 3;
-		}
-		if (path[0])
-			strlcat(path, "/", MAXPATHLEN);
-		strlcat(path, name, MAXPATHLEN);
-	}
-	if ((p = strrchr(path, '/')) != NULL && !strcmp(p, "/*")) {
-		r->anchor_wildcard = 1;
-		*p = 0;
-	}
-	ruleset = pf_find_or_create_ruleset(path);
-	rs_free(path);
-	if (ruleset == NULL || ruleset->anchor == NULL) {
-		printf("pf_anchor_setup: ruleset\n");
-		return (1);
-	}
-	r->anchor = ruleset->anchor;
-	r->anchor->refcnt++;
-	return (0);
-}
-#endif



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