aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/pf/net/pf_ioctl.c
diff options
context:
space:
mode:
authorMax Laier <mlaier@FreeBSD.org>2005-05-03 16:43:32 +0000
committerMax Laier <mlaier@FreeBSD.org>2005-05-03 16:43:32 +0000
commitb01933e6bf90b35ba467ac88917f46cc3676b371 (patch)
treec89a2417dc919aa1ce54db59627c344530c85d79 /sys/contrib/pf/net/pf_ioctl.c
parent532c491b2bbc9e47b6655cadfff6cd556cd62fb9 (diff)
downloadsrc-b01933e6bf90b35ba467ac88917f46cc3676b371.tar.gz
src-b01933e6bf90b35ba467ac88917f46cc3676b371.zip
Resolve conflicts created during the import of pf 3.7 Some features are
missing and will be implemented in a second step. This is functional as is. Tested by: freebsd-pf, pfsense.org Obtained from: OpenBSD X-MFC after: never (breaks API/ABI)
Notes
Notes: svn path=/head/; revision=145836
Diffstat (limited to 'sys/contrib/pf/net/pf_ioctl.c')
-rw-r--r--sys/contrib/pf/net/pf_ioctl.c955
1 files changed, 540 insertions, 415 deletions
diff --git a/sys/contrib/pf/net/pf_ioctl.c b/sys/contrib/pf/net/pf_ioctl.c
index ad1d552cd708..2c8989e66c86 100644
--- a/sys/contrib/pf/net/pf_ioctl.c
+++ b/sys/contrib/pf/net/pf_ioctl.c
@@ -1,6 +1,5 @@
/* $FreeBSD$ */
-/* $OpenBSD: pf_ioctl.c,v 1.112.2.2 2004/07/24 18:28:12 brad Exp $ */
-/* add $OpenBSD: pf_ioctl.c,v 1.118 2004/05/03 07:51:59 kjc Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.139 2005/03/03 07:13:39 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -115,13 +114,19 @@ void cleanup_pf_zone(void);
int pfattach(void);
#else
void pfattach(int);
-int pfopen(struct cdev *, int, int, struct proc *);
-int pfclose(struct cdev *, int, int, struct proc *);
+int pfopen(dev_t, int, int, struct proc *);
+int pfclose(dev_t, int, int, struct proc *);
#endif
-struct pf_pool *pf_get_pool(char *, char *, u_int32_t,
- u_int8_t, u_int32_t, u_int8_t, u_int8_t, u_int8_t);
+struct pf_pool *pf_get_pool(char *, u_int32_t, u_int8_t, u_int32_t,
+ u_int8_t, u_int8_t, u_int8_t);
int pf_get_ruleset_number(u_int8_t);
void pf_init_ruleset(struct pf_ruleset *);
+int pf_anchor_setup(struct pf_rule *,
+ const struct pf_ruleset *, const char *);
+int pf_anchor_copyout(const struct pf_ruleset *,
+ const struct pf_rule *, struct pfioc_rule *);
+void pf_anchor_remove(struct pf_rule *);
+
void pf_mv_pool(struct pf_palist *, struct pf_palist *);
void pf_empty_pool(struct pf_palist *);
#ifdef __FreeBSD__
@@ -136,9 +141,9 @@ int pf_commit_altq(u_int32_t);
int pf_enable_altq(struct pf_altq *);
int pf_disable_altq(struct pf_altq *);
#endif /* ALTQ */
-int pf_begin_rules(u_int32_t *, int, char *, char *);
-int pf_rollback_rules(u_int32_t, int, char *, char *);
-int pf_commit_rules(u_int32_t, int, char *, char *);
+int pf_begin_rules(u_int32_t *, int, const char *);
+int pf_rollback_rules(u_int32_t, int, char *);
+int pf_commit_rules(u_int32_t, int, char *);
#ifdef __FreeBSD__
extern struct callout pf_expire_to;
@@ -161,6 +166,9 @@ TAILQ_HEAD(pf_tags, pf_tagname) pf_tags = TAILQ_HEAD_INITIALIZER(pf_tags),
static u_int16_t tagname2tag(struct pf_tags *, char *);
static void tag2tagname(struct pf_tags *, u_int16_t, char *);
static void tag_unref(struct pf_tags *, u_int16_t);
+int pf_rtlabel_add(struct pf_addr_wrap *);
+void pf_rtlabel_remove(struct pf_addr_wrap *);
+void pf_rtlabel_copyout(struct pf_addr_wrap *);
#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
@@ -261,6 +269,7 @@ pfattach(void)
UMA_CREATE(pf_pooladdr_pl, struct pf_pooladdr, "pfpooladdrpl");
UMA_CREATE(pfr_ktable_pl, struct pfr_ktable, "pfrktable");
UMA_CREATE(pfr_kentry_pl, struct pfr_kentry, "pfrkentry");
+ UMA_CREATE(pfr_kentry_pl2, struct pfr_kentry, "pfrkentry2");
UMA_CREATE(pf_frent_pl, struct pf_frent, "pffrent");
UMA_CREATE(pf_frag_pl, struct pf_fragment, "pffrag");
UMA_CREATE(pf_cache_pl, struct pf_fragment, "pffrcache");
@@ -284,13 +293,15 @@ pfattach(void)
pf_pool_limits[PF_LIMIT_STATES].pp = pf_state_pl;
pf_pool_limits[PF_LIMIT_STATES].limit = PFSTATE_HIWAT;
+ pf_pool_limits[PF_LIMIT_SRC_NODES].pp = pf_src_tree_pl;
+ pf_pool_limits[PF_LIMIT_SRC_NODES].limit = PFSNODE_HIWAT;
pf_pool_limits[PF_LIMIT_FRAGS].pp = pf_frent_pl;
pf_pool_limits[PF_LIMIT_FRAGS].limit = PFFRAG_FRENT_HIWAT;
uma_zone_set_max(pf_pool_limits[PF_LIMIT_STATES].pp,
pf_pool_limits[PF_LIMIT_STATES].limit);
RB_INIT(&tree_src_tracking);
- TAILQ_INIT(&pf_anchors);
+ RB_INIT(&pf_anchors);
pf_init_ruleset(&pf_main_ruleset);
TAILQ_INIT(&pf_altqs[0]);
TAILQ_INIT(&pf_altqs[1]);
@@ -305,22 +316,24 @@ pfattach(void)
pf_default_rule.nr = -1;
/* initialize default timeouts */
- my_timeout[PFTM_TCP_FIRST_PACKET] = 120; /* First TCP packet */
- my_timeout[PFTM_TCP_OPENING] = 30; /* No response yet */
- my_timeout[PFTM_TCP_ESTABLISHED] = 24*60*60; /* Established */
- my_timeout[PFTM_TCP_CLOSING] = 15 * 60; /* Half closed */
- my_timeout[PFTM_TCP_FIN_WAIT] = 45; /* Got both FINs */
- my_timeout[PFTM_TCP_CLOSED] = 90; /* Got a RST */
- my_timeout[PFTM_UDP_FIRST_PACKET] = 60; /* First UDP packet */
- my_timeout[PFTM_UDP_SINGLE] = 30; /* Unidirectional */
- my_timeout[PFTM_UDP_MULTIPLE] = 60; /* Bidirectional */
- my_timeout[PFTM_ICMP_FIRST_PACKET] = 20; /* First ICMP packet */
- my_timeout[PFTM_ICMP_ERROR_REPLY] = 10; /* Got error response */
- my_timeout[PFTM_OTHER_FIRST_PACKET] = 60; /* First packet */
- my_timeout[PFTM_OTHER_SINGLE] = 30; /* Unidirectional */
- my_timeout[PFTM_OTHER_MULTIPLE] = 60; /* Bidirectional */
- my_timeout[PFTM_FRAG] = 30; /* Fragment expire */
- my_timeout[PFTM_INTERVAL] = 10; /* Expire interval */
+ my_timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
+ my_timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
+ my_timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
+ my_timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL;
+ my_timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL;
+ my_timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL;
+ my_timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL;
+ my_timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL;
+ my_timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL;
+ my_timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL;
+ my_timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL;
+ my_timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL;
+ my_timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL;
+ my_timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL;
+ my_timeout[PFTM_FRAG] = PFTM_FRAG_VAL;
+ my_timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL;
+ my_timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL;
+ my_timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL;
/*
* XXX
@@ -332,7 +345,7 @@ pfattach(void)
pf_purge_timeout, &pf_expire_to);
pf_normalize_init();
- pf_status.debug = PF_DEBUG_URGENT;
+ bzero(&pf_status, sizeof(pf_status));
pf_pfil_hooked = 0;
/* XXX do our best to avoid a conflict */
@@ -353,9 +366,9 @@ pfattach(int num)
pool_init(&pf_state_pl, sizeof(struct pf_state), 0, 0, 0, "pfstatepl",
NULL);
pool_init(&pf_altq_pl, sizeof(struct pf_altq), 0, 0, 0, "pfaltqpl",
- NULL);
+ &pool_allocator_nointr);
pool_init(&pf_pooladdr_pl, sizeof(struct pf_pooladdr), 0, 0, 0,
- "pfpooladdrpl", NULL);
+ "pfpooladdrpl", &pool_allocator_nointr);
pfr_initialize();
pfi_initialize();
pf_osfp_initialize();
@@ -364,7 +377,7 @@ pfattach(int num)
pf_pool_limits[PF_LIMIT_STATES].limit, NULL, 0);
RB_INIT(&tree_src_tracking);
- TAILQ_INIT(&pf_anchors);
+ RB_INIT(&pf_anchors);
pf_init_ruleset(&pf_main_ruleset);
TAILQ_INIT(&pf_altqs[0]);
TAILQ_INIT(&pf_altqs[1]);
@@ -379,23 +392,24 @@ pfattach(int num)
pf_default_rule.nr = -1;
/* initialize default timeouts */
- timeout[PFTM_TCP_FIRST_PACKET] = 120; /* First TCP packet */
- timeout[PFTM_TCP_OPENING] = 30; /* No response yet */
- timeout[PFTM_TCP_ESTABLISHED] = 24*60*60; /* Established */
- timeout[PFTM_TCP_CLOSING] = 15 * 60; /* Half closed */
- timeout[PFTM_TCP_FIN_WAIT] = 45; /* Got both FINs */
- timeout[PFTM_TCP_CLOSED] = 90; /* Got a RST */
- timeout[PFTM_UDP_FIRST_PACKET] = 60; /* First UDP packet */
- timeout[PFTM_UDP_SINGLE] = 30; /* Unidirectional */
- timeout[PFTM_UDP_MULTIPLE] = 60; /* Bidirectional */
- timeout[PFTM_ICMP_FIRST_PACKET] = 20; /* First ICMP packet */
- timeout[PFTM_ICMP_ERROR_REPLY] = 10; /* Got error response */
- timeout[PFTM_OTHER_FIRST_PACKET] = 60; /* First packet */
- timeout[PFTM_OTHER_SINGLE] = 30; /* Unidirectional */
- timeout[PFTM_OTHER_MULTIPLE] = 60; /* Bidirectional */
- timeout[PFTM_FRAG] = 30; /* Fragment expire */
- timeout[PFTM_INTERVAL] = 10; /* Expire interval */
- timeout[PFTM_SRC_NODE] = 0; /* Source tracking */
+ timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
+ timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
+ timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
+ timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL;
+ timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL;
+ timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL;
+ timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL;
+ timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL;
+ timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL;
+ timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL;
+ timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL;
+ timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL;
+ timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL;
+ timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL;
+ timeout[PFTM_FRAG] = PFTM_FRAG_VAL;
+ timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL;
+ timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL;
+ timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL;
timeout_set(&pf_expire_to, pf_purge_timeout, &pf_expire_to);
timeout_add(&pf_expire_to, timeout[PFTM_INTERVAL] * hz);
@@ -426,15 +440,15 @@ pfclose(struct cdev *dev, int flags, int fmt, struct proc *p)
#endif /* __FreeBSD__ */
struct pf_pool *
-pf_get_pool(char *anchorname, char *rulesetname, u_int32_t ticket,
- u_int8_t rule_action, u_int32_t rule_number, u_int8_t r_last,
- u_int8_t active, u_int8_t check_ticket)
+pf_get_pool(char *anchor, u_int32_t ticket, u_int8_t rule_action,
+ u_int32_t rule_number, u_int8_t r_last, u_int8_t active,
+ u_int8_t check_ticket)
{
struct pf_ruleset *ruleset;
struct pf_rule *rule;
int rs_num;
- ruleset = pf_find_ruleset(anchorname, rulesetname);
+ ruleset = pf_find_ruleset(anchor);
if (ruleset == NULL)
return (NULL);
rs_num = pf_get_ruleset_number(rule_action);
@@ -474,6 +488,7 @@ pf_get_ruleset_number(u_int8_t action)
{
switch (action) {
case PF_SCRUB:
+ case PF_NOSCRUB:
return (PF_RULESET_SCRUB);
break;
case PF_PASS:
@@ -513,118 +528,265 @@ pf_init_ruleset(struct pf_ruleset *ruleset)
}
struct pf_anchor *
-pf_find_anchor(const char *anchorname)
+pf_find_anchor(const char *path)
{
- struct pf_anchor *anchor;
- int n = -1;
+ static struct pf_anchor key;
- anchor = TAILQ_FIRST(&pf_anchors);
- while (anchor != NULL && (n = strcmp(anchor->name, anchorname)) < 0)
- anchor = TAILQ_NEXT(anchor, entries);
- if (n == 0)
- return (anchor);
- else
- return (NULL);
+ memset(&key, 0, sizeof(key));
+ strlcpy(key.path, path, sizeof(key.path));
+ return (RB_FIND(pf_anchor_global, &pf_anchors, &key));
}
struct pf_ruleset *
-pf_find_ruleset(char *anchorname, char *rulesetname)
+pf_find_ruleset(const char *path)
{
struct pf_anchor *anchor;
- struct pf_ruleset *ruleset;
- if (!anchorname[0] && !rulesetname[0])
+ while (*path == '/')
+ path++;
+ if (!*path)
return (&pf_main_ruleset);
- if (!anchorname[0] || !rulesetname[0])
- return (NULL);
- anchorname[PF_ANCHOR_NAME_SIZE-1] = 0;
- rulesetname[PF_RULESET_NAME_SIZE-1] = 0;
- anchor = pf_find_anchor(anchorname);
+ anchor = pf_find_anchor(path);
if (anchor == NULL)
return (NULL);
- ruleset = TAILQ_FIRST(&anchor->rulesets);
- while (ruleset != NULL && strcmp(ruleset->name, rulesetname) < 0)
- ruleset = TAILQ_NEXT(ruleset, entries);
- if (ruleset != NULL && !strcmp(ruleset->name, rulesetname))
- return (ruleset);
else
- return (NULL);
+ return (&anchor->ruleset);
}
struct pf_ruleset *
-pf_find_or_create_ruleset(char anchorname[PF_ANCHOR_NAME_SIZE],
- char rulesetname[PF_RULESET_NAME_SIZE])
+pf_find_or_create_ruleset(const char *path)
{
- struct pf_anchor *anchor, *a;
- struct pf_ruleset *ruleset, *r;
+ static char p[MAXPATHLEN];
+ char *q = NULL, *r; /* make the compiler happy */
+ struct pf_ruleset *ruleset;
+ struct pf_anchor *anchor = NULL, *dup, *parent = NULL;
- if (!anchorname[0] && !rulesetname[0])
- return (&pf_main_ruleset);
- if (!anchorname[0] || !rulesetname[0])
+ while (*path == '/')
+ path++;
+ ruleset = pf_find_ruleset(path);
+ if (ruleset != NULL)
+ return (ruleset);
+ strlcpy(p, path, sizeof(p));
+#ifdef __FreeBSD__
+ while (parent == NULL && (q = rindex(p, '/')) != NULL) {
+#else
+ while (parent == NULL && (q = strrchr(p, '/')) != NULL) {
+#endif
+ *q = 0;
+ if ((ruleset = pf_find_ruleset(p)) != NULL) {
+ parent = ruleset->anchor;
+ break;
+ }
+ }
+ if (q == NULL)
+ q = p;
+ else
+ q++;
+ strlcpy(p, path, sizeof(p));
+ if (!*q)
return (NULL);
- anchorname[PF_ANCHOR_NAME_SIZE-1] = 0;
- rulesetname[PF_RULESET_NAME_SIZE-1] = 0;
- a = TAILQ_FIRST(&pf_anchors);
- while (a != NULL && strcmp(a->name, anchorname) < 0)
- a = TAILQ_NEXT(a, entries);
- if (a != NULL && !strcmp(a->name, anchorname))
- anchor = a;
- else {
- anchor = (struct pf_anchor *)malloc(sizeof(struct pf_anchor),
- M_TEMP, M_NOWAIT);
+#ifdef __FreeBSD__
+ while ((r = index(q, '/')) != NULL || *q) {
+#else
+ while ((r = strchr(q, '/')) != NULL || *q) {
+#endif
+ if (r != NULL)
+ *r = 0;
+ if (!*q || strlen(q) >= PF_ANCHOR_NAME_SIZE ||
+ (parent != NULL && strlen(parent->path) >=
+ MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 1))
+ return (NULL);
+ anchor = (struct pf_anchor *)malloc(sizeof(*anchor), M_TEMP,
+ M_NOWAIT);
if (anchor == NULL)
return (NULL);
- memset(anchor, 0, sizeof(struct pf_anchor));
- bcopy(anchorname, anchor->name, sizeof(anchor->name));
- TAILQ_INIT(&anchor->rulesets);
- if (a != NULL)
- TAILQ_INSERT_BEFORE(a, anchor, entries);
- else
- TAILQ_INSERT_TAIL(&pf_anchors, anchor, entries);
- }
- r = TAILQ_FIRST(&anchor->rulesets);
- while (r != NULL && strcmp(r->name, rulesetname) < 0)
- r = TAILQ_NEXT(r, entries);
- if (r != NULL && !strcmp(r->name, rulesetname))
- return (r);
- ruleset = (struct pf_ruleset *)malloc(sizeof(struct pf_ruleset),
- M_TEMP, M_NOWAIT);
- if (ruleset != NULL) {
- pf_init_ruleset(ruleset);
- bcopy(rulesetname, ruleset->name, sizeof(ruleset->name));
- ruleset->anchor = anchor;
+ memset(anchor, 0, sizeof(*anchor));
+ 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, &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);
+ free(anchor, M_TEMP);
+ 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, &pf_anchors,
+ anchor);
+ free(anchor, M_TEMP);
+ return (NULL);
+ }
+ }
+ pf_init_ruleset(&anchor->ruleset);
+ anchor->ruleset.anchor = anchor;
+ parent = anchor;
if (r != NULL)
- TAILQ_INSERT_BEFORE(r, ruleset, entries);
+ q = r + 1;
else
- TAILQ_INSERT_TAIL(&anchor->rulesets, ruleset, entries);
+ *q = 0;
}
- return (ruleset);
+ return (&anchor->ruleset);
}
void
pf_remove_if_empty_ruleset(struct pf_ruleset *ruleset)
{
- struct pf_anchor *anchor;
+ struct pf_anchor *parent;
int i;
- if (ruleset == NULL || ruleset->anchor == NULL || 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)
+ 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, &pf_anchors, ruleset->anchor);
+ if ((parent = ruleset->anchor->parent) != NULL)
+ RB_REMOVE(pf_anchor_node, &parent->children,
+ ruleset->anchor);
+ free(ruleset->anchor, M_TEMP);
+ if (parent == NULL)
return;
+ ruleset = &parent->ruleset;
+ }
+}
- anchor = ruleset->anchor;
- TAILQ_REMOVE(&anchor->rulesets, ruleset, entries);
- free(ruleset, M_TEMP);
+int
+pf_anchor_setup(struct pf_rule *r, const struct pf_ruleset *s,
+ const char *name)
+{
+ static char *p, path[MAXPATHLEN];
+ struct pf_ruleset *ruleset;
- if (TAILQ_EMPTY(&anchor->rulesets)) {
- TAILQ_REMOVE(&pf_anchors, anchor, entries);
- free(anchor, M_TEMP);
- pf_update_anchor_rules();
+ r->anchor = NULL;
+ r->anchor_relative = 0;
+ r->anchor_wildcard = 0;
+ if (!name[0])
+ return (0);
+ if (name[0] == '/')
+ strlcpy(path, name + 1, sizeof(path));
+ else {
+ /* relative path */
+ r->anchor_relative = 1;
+ if (s->anchor == NULL || !s->anchor->path[0])
+ path[0] = 0;
+ else
+ strlcpy(path, s->anchor->path, sizeof(path));
+ while (name[0] == '.' && name[1] == '.' && name[2] == '/') {
+ if (!path[0]) {
+ printf("pf_anchor_setup: .. beyond root\n");
+ return (1);
+ }
+#ifdef __FreeBSD__
+ if ((p = rindex(path, '/')) != NULL)
+#else
+ if ((p = strrchr(path, '/')) != NULL)
+#endif
+ *p = 0;
+ else
+ path[0] = 0;
+ r->anchor_relative++;
+ name += 3;
+ }
+ if (path[0])
+ strlcat(path, "/", sizeof(path));
+ strlcat(path, name, sizeof(path));
+ }
+#ifdef __FreeBSD__
+ if ((p = rindex(path, '/')) != NULL && !strcmp(p, "/*")) {
+#else
+ if ((p = strrchr(path, '/')) != NULL && !strcmp(p, "/*")) {
+#endif
+ r->anchor_wildcard = 1;
+ *p = 0;
}
+ ruleset = pf_find_or_create_ruleset(path);
+ if (ruleset == NULL || ruleset->anchor == NULL) {
+ printf("pf_anchor_setup: ruleset\n");
+ return (1);
+ }
+ r->anchor = ruleset->anchor;
+ r->anchor->refcnt++;
+ return (0);
+}
+
+int
+pf_anchor_copyout(const struct pf_ruleset *rs, const struct pf_rule *r,
+ struct pfioc_rule *pr)
+{
+ pr->anchor_call[0] = 0;
+ if (r->anchor == NULL)
+ return (0);
+ if (!r->anchor_relative) {
+ strlcpy(pr->anchor_call, "/", sizeof(pr->anchor_call));
+ strlcat(pr->anchor_call, r->anchor->path,
+ sizeof(pr->anchor_call));
+ } else {
+ char a[MAXPATHLEN], b[MAXPATHLEN], *p;
+ int i;
+
+ if (rs->anchor == NULL)
+ a[0] = 0;
+ else
+ strlcpy(a, rs->anchor->path, sizeof(a));
+ strlcpy(b, r->anchor->path, sizeof(b));
+ for (i = 1; i < r->anchor_relative; ++i) {
+#ifdef __FreeBSD__
+ if ((p = rindex(a, '/')) == NULL)
+#else
+ if ((p = strrchr(a, '/')) == NULL)
+#endif
+ p = a;
+ *p = 0;
+ strlcat(pr->anchor_call, "../",
+ sizeof(pr->anchor_call));
+ }
+ if (strncmp(a, b, strlen(a))) {
+ printf("pf_anchor_copyout: '%s' '%s'\n", a, b);
+ return (1);
+ }
+ if (strlen(b) > strlen(a))
+ strlcat(pr->anchor_call, b + (a[0] ? strlen(a) + 1 : 0),
+ sizeof(pr->anchor_call));
+ }
+ if (r->anchor_wildcard)
+ strlcat(pr->anchor_call, pr->anchor_call[0] ? "/*" : "*",
+ sizeof(pr->anchor_call));
+ return (0);
+}
+
+void
+pf_anchor_remove(struct pf_rule *r)
+{
+ if (r->anchor == NULL)
+ return;
+ if (r->anchor->refcnt <= 0) {
+ printf("pf_anchor_remove: broken refcount");
+ r->anchor = NULL;
+ return;
+ }
+ if (!--r->anchor->refcnt)
+ pf_remove_if_empty_ruleset(&r->anchor->ruleset);
+ r->anchor = NULL;
}
void
@@ -664,6 +826,8 @@ pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule)
*/
pf_tbladdr_remove(&rule->src.addr);
pf_tbladdr_remove(&rule->dst.addr);
+ if (rule->overload_tbl)
+ pfr_detach_table(rule->overload_tbl);
}
TAILQ_REMOVE(rulequeue, rule, entries);
rule->entries.tqe_prev = NULL;
@@ -680,13 +844,18 @@ pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule)
pf_qid_unref(rule->pqid);
pf_qid_unref(rule->qid);
#endif
+ pf_rtlabel_remove(&rule->src.addr);
+ pf_rtlabel_remove(&rule->dst.addr);
pfi_dynaddr_remove(&rule->src.addr);
pfi_dynaddr_remove(&rule->dst.addr);
if (rulequeue == NULL) {
pf_tbladdr_remove(&rule->src.addr);
pf_tbladdr_remove(&rule->dst.addr);
+ if (rule->overload_tbl)
+ pfr_detach_table(rule->overload_tbl);
}
pfi_detach_rule(rule->kif);
+ pf_anchor_remove(rule);
pf_empty_pool(&rule->rpool.list);
pool_put(&pf_rule_pl, rule);
}
@@ -781,11 +950,69 @@ pf_tag2tagname(u_int16_t tagid, char *p)
}
void
+pf_tag_ref(u_int16_t tag)
+{
+ struct pf_tagname *t;
+
+ TAILQ_FOREACH(t, &pf_tags, entries)
+ if (t->tag == tag)
+ break;
+ if (t != NULL)
+ t->ref++;
+}
+
+void
pf_tag_unref(u_int16_t tag)
{
return (tag_unref(&pf_tags, tag));
}
+int
+pf_rtlabel_add(struct pf_addr_wrap *a)
+{
+#ifdef __FreeBSD__
+ /* XXX_IMPORT: later */
+ return (0);
+#else
+ if (a->type == PF_ADDR_RTLABEL &&
+ (a->v.rtlabel = rtlabel_name2id(a->v.rtlabelname)) == 0)
+ return (-1);
+ return (0);
+#endif
+}
+
+void
+pf_rtlabel_remove(struct pf_addr_wrap *a)
+{
+#ifdef __FreeBSD__
+ /* XXX_IMPORT: later */
+#else
+ if (a->type == PF_ADDR_RTLABEL)
+ rtlabel_unref(a->v.rtlabel);
+#endif
+}
+
+void
+pf_rtlabel_copyout(struct pf_addr_wrap *a)
+{
+#ifdef __FreeBSD__
+ /* XXX_IMPORT: later */
+ if (a->type == PF_ADDR_RTLABEL && a->v.rtlabel)
+ strlcpy(a->v.rtlabelname, "?", sizeof(a->v.rtlabelname));
+#else
+ const char *name;
+
+ if (a->type == PF_ADDR_RTLABEL && a->v.rtlabel) {
+ if ((name = rtlabel_id2name(a->v.rtlabel)) == NULL)
+ strlcpy(a->v.rtlabelname, "?",
+ sizeof(a->v.rtlabelname));
+ else
+ strlcpy(a->v.rtlabelname, name,
+ sizeof(a->v.rtlabelname));
+ }
+#endif
+}
+
#ifdef ALTQ
u_int32_t
pf_qname2qid(char *qname)
@@ -928,7 +1155,7 @@ pf_enable_altq(struct pf_altq *altq)
error = tbr_set(&ifp->if_snd, &tb);
#ifdef __FreeBSD__
PF_LOCK();
-#endif
+#endif
splx(s);
}
@@ -973,14 +1200,14 @@ pf_disable_altq(struct pf_altq *altq)
#endif /* ALTQ */
int
-pf_begin_rules(u_int32_t *ticket, int rs_num, char *anchor, char *ruleset)
+pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor)
{
struct pf_ruleset *rs;
struct pf_rule *rule;
if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
return (EINVAL);
- rs = pf_find_or_create_ruleset(anchor, ruleset);
+ rs = pf_find_or_create_ruleset(anchor);
if (rs == NULL)
return (EINVAL);
while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL)
@@ -991,14 +1218,14 @@ pf_begin_rules(u_int32_t *ticket, int rs_num, char *anchor, char *ruleset)
}
int
-pf_rollback_rules(u_int32_t ticket, int rs_num, char *anchor, char *ruleset)
+pf_rollback_rules(u_int32_t ticket, int rs_num, char *anchor)
{
struct pf_ruleset *rs;
struct pf_rule *rule;
if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
return (EINVAL);
- rs = pf_find_ruleset(anchor, ruleset);
+ rs = pf_find_ruleset(anchor);
if (rs == NULL || !rs->rules[rs_num].inactive.open ||
rs->rules[rs_num].inactive.ticket != ticket)
return (0);
@@ -1009,7 +1236,7 @@ pf_rollback_rules(u_int32_t ticket, int rs_num, char *anchor, char *ruleset)
}
int
-pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor, char *ruleset)
+pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
{
struct pf_ruleset *rs;
struct pf_rule *rule;
@@ -1018,7 +1245,7 @@ pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor, char *ruleset)
if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
return (EINVAL);
- rs = pf_find_ruleset(anchor, ruleset);
+ rs = pf_find_ruleset(anchor);
if (rs == NULL || !rs->rules[rs_num].inactive.open ||
ticket != rs->rules[rs_num].inactive.ticket)
return (EBUSY);
@@ -1038,7 +1265,6 @@ pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor, char *ruleset)
pf_rm_rule(old_rules, rule);
rs->rules[rs_num].inactive.open = 0;
pf_remove_if_empty_ruleset(rs);
- pf_update_anchor_rules();
splx(s);
return (0);
}
@@ -1053,7 +1279,9 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
{
struct pf_pooladdr *pa = NULL;
struct pf_pool *pool = NULL;
+#ifndef __FreeBSD__
int s;
+#endif
int error = 0;
/* XXX keep in sync with switch() below */
@@ -1080,8 +1308,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCGETALTQS:
case DIOCGETALTQ:
case DIOCGETQSTATS:
- case DIOCGETANCHORS:
- case DIOCGETANCHOR:
case DIOCGETRULESETS:
case DIOCGETRULESET:
case DIOCRGETTABLES:
@@ -1103,6 +1329,8 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
#ifdef __FreeBSD__
case DIOCGIFSPEED:
#endif
+ case DIOCSETIFFLAG:
+ case DIOCCLRIFFLAG:
break;
case DIOCRCLRTABLES:
case DIOCRADDTABLES:
@@ -1130,8 +1358,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCGETALTQS:
case DIOCGETALTQ:
case DIOCGETQSTATS:
- case DIOCGETANCHORS:
- case DIOCGETANCHOR:
case DIOCGETRULESETS:
case DIOCGETRULESET:
case DIOCRGETTABLES:
@@ -1165,8 +1391,9 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
#ifdef __FreeBSD__
PF_LOCK();
+#else
+ s = splsoftnet();
#endif
-
switch (cmd) {
case DIOCSTART:
@@ -1184,17 +1411,9 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
#endif
pf_status.running = 1;
-#ifdef __FreeBSD__
pf_status.since = time_second;
-#else
- pf_status.since = time.tv_sec;
-#endif
if (pf_status.stateid == 0) {
-#ifdef __FreeBSD__
pf_status.stateid = time_second;
-#else
- pf_status.stateid = time.tv_sec;
-#endif
pf_status.stateid = pf_status.stateid << 32;
}
DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n"));
@@ -1215,22 +1434,12 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
DPFPRINTF(PF_DEBUG_MISC,
("pf: pfil unregisteration failed\n"));
}
- pf_status.since = time_second;
-#else
- pf_status.since = time.tv_sec;
#endif
+ pf_status.since = time_second;
DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n"));
}
break;
- case DIOCBEGINRULES: {
- struct pfioc_rule *pr = (struct pfioc_rule *)addr;
-
- error = pf_begin_rules(&pr->ticket, pf_get_ruleset_number(
- pr->rule.action), pr->anchor, pr->ruleset);
- break;
- }
-
case DIOCADDRULE: {
struct pfioc_rule *pr = (struct pfioc_rule *)addr;
struct pf_ruleset *ruleset;
@@ -1238,7 +1447,8 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pf_pooladdr *pa;
int rs_num;
- ruleset = pf_find_ruleset(pr->anchor, pr->ruleset);
+ pr->anchor[sizeof(pr->anchor) - 1] = 0;
+ ruleset = pf_find_ruleset(pr->anchor);
if (ruleset == NULL) {
error = EINVAL;
break;
@@ -1248,19 +1458,19 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = EINVAL;
break;
}
- if (pr->rule.anchorname[0] && ruleset != &pf_main_ruleset) {
- error = EINVAL;
- break;
- }
if (pr->rule.return_icmp >> 8 > ICMP_MAXTYPE) {
error = EINVAL;
break;
}
if (pr->ticket != ruleset->rules[rs_num].inactive.ticket) {
+ printf("ticket: %d != [%d]%d\n", pr->ticket,
+ rs_num, ruleset->rules[rs_num].inactive.ticket);
error = EBUSY;
break;
}
if (pr->pool_ticket != ticket_pabuf) {
+ printf("pool_ticket: %d != %d\n", pr->pool_ticket,
+ ticket_pabuf);
error = EBUSY;
break;
}
@@ -1328,6 +1538,9 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = EBUSY;
if (rule->rt && !rule->direction)
error = EINVAL;
+ if (pf_rtlabel_add(&rule->src.addr) ||
+ pf_rtlabel_add(&rule->dst.addr))
+ error = EBUSY;
if (pfi_dynaddr_setup(&rule->src.addr, rule->af))
error = EINVAL;
if (pfi_dynaddr_setup(&rule->dst.addr, rule->af))
@@ -1336,13 +1549,24 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = EINVAL;
if (pf_tbladdr_setup(ruleset, &rule->dst.addr))
error = EINVAL;
+ if (pf_anchor_setup(rule, ruleset, pr->anchor_call))
+ error = EINVAL;
TAILQ_FOREACH(pa, &pf_pabuf, entries)
if (pf_tbladdr_setup(ruleset, &pa->addr))
error = EINVAL;
+ if (rule->overload_tblname[0]) {
+ if ((rule->overload_tbl = pfr_attach_table(ruleset,
+ rule->overload_tblname)) == NULL)
+ error = EINVAL;
+ else
+ rule->overload_tbl->pfrkt_flags |=
+ PFR_TFLAG_ACTIVE;
+ }
+
pf_mv_pool(&pf_pabuf, &rule->rpool.list);
if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) ||
- (rule->action == PF_BINAT)) && !rule->anchorname[0]) ||
+ (rule->action == PF_BINAT)) && rule->anchor == NULL) ||
(rule->rt > PF_FASTROUTE)) &&
(TAILQ_FIRST(&rule->rpool.list) == NULL))
error = EINVAL;
@@ -1358,21 +1582,14 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
- case DIOCCOMMITRULES: {
- struct pfioc_rule *pr = (struct pfioc_rule *)addr;
-
- error = pf_commit_rules(pr->ticket, pf_get_ruleset_number(
- pr->rule.action), pr->anchor, pr->ruleset);
- break;
- }
-
case DIOCGETRULES: {
struct pfioc_rule *pr = (struct pfioc_rule *)addr;
struct pf_ruleset *ruleset;
struct pf_rule *tail;
int rs_num;
- ruleset = pf_find_ruleset(pr->anchor, pr->ruleset);
+ pr->anchor[sizeof(pr->anchor) - 1] = 0;
+ ruleset = pf_find_ruleset(pr->anchor);
if (ruleset == NULL) {
error = EINVAL;
break;
@@ -1382,7 +1599,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = EINVAL;
break;
}
- s = splsoftnet();
tail = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
pf_rulequeue);
if (tail)
@@ -1390,7 +1606,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
else
pr->nr = 0;
pr->ticket = ruleset->rules[rs_num].active.ticket;
- splx(s);
break;
}
@@ -1400,7 +1615,8 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pf_rule *rule;
int rs_num, i;
- ruleset = pf_find_ruleset(pr->anchor, pr->ruleset);
+ pr->anchor[sizeof(pr->anchor) - 1] = 0;
+ ruleset = pf_find_ruleset(pr->anchor);
if (ruleset == NULL) {
error = EINVAL;
break;
@@ -1414,27 +1630,30 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = EBUSY;
break;
}
- s = splsoftnet();
rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
while ((rule != NULL) && (rule->nr != pr->nr))
rule = TAILQ_NEXT(rule, entries);
if (rule == NULL) {
error = EBUSY;
- splx(s);
break;
}
bcopy(rule, &pr->rule, sizeof(struct pf_rule));
+ if (pf_anchor_copyout(ruleset, rule, pr)) {
+ error = EBUSY;
+ break;
+ }
pfi_dynaddr_copyout(&pr->rule.src.addr);
pfi_dynaddr_copyout(&pr->rule.dst.addr);
pf_tbladdr_copyout(&pr->rule.src.addr);
pf_tbladdr_copyout(&pr->rule.dst.addr);
+ pf_rtlabel_copyout(&pr->rule.src.addr);
+ pf_rtlabel_copyout(&pr->rule.dst.addr);
for (i = 0; i < PF_SKIP_COUNT; ++i)
if (rule->skip[i].ptr == NULL)
pr->rule.skip[i].nr = -1;
else
pr->rule.skip[i].nr =
rule->skip[i].ptr->nr;
- splx(s);
break;
}
@@ -1457,7 +1676,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = EINVAL;
break;
}
- ruleset = pf_find_ruleset(pcr->anchor, pcr->ruleset);
+ ruleset = pf_find_ruleset(pcr->anchor);
if (ruleset == NULL) {
error = EINVAL;
break;
@@ -1531,7 +1750,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
} else
newrule->pqid = newrule->qid;
}
-#endif
+#endif /* ALTQ */
if (newrule->tagname[0])
if ((newrule->tag =
pf_tagname2tag(newrule->tagname)) == 0)
@@ -1540,9 +1759,11 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
if ((newrule->match_tag = pf_tagname2tag(
newrule->match_tagname)) == 0)
error = EBUSY;
-
if (newrule->rt && !newrule->direction)
error = EINVAL;
+ if (pf_rtlabel_add(&newrule->src.addr) ||
+ pf_rtlabel_add(&newrule->dst.addr))
+ error = EBUSY;
if (pfi_dynaddr_setup(&newrule->src.addr, newrule->af))
error = EINVAL;
if (pfi_dynaddr_setup(&newrule->dst.addr, newrule->af))
@@ -1551,13 +1772,25 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = EINVAL;
if (pf_tbladdr_setup(ruleset, &newrule->dst.addr))
error = EINVAL;
+ if (pf_anchor_setup(newrule, ruleset, pcr->anchor_call))
+ error = EINVAL;
+
+ if (newrule->overload_tblname[0]) {
+ if ((newrule->overload_tbl = pfr_attach_table(
+ ruleset, newrule->overload_tblname)) ==
+ NULL)
+ error = EINVAL;
+ else
+ newrule->overload_tbl->pfrkt_flags |=
+ PFR_TFLAG_ACTIVE;
+ }
pf_mv_pool(&pf_pabuf, &newrule->rpool.list);
if (((((newrule->action == PF_NAT) ||
(newrule->action == PF_RDR) ||
(newrule->action == PF_BINAT) ||
(newrule->rt > PF_FASTROUTE)) &&
- !newrule->anchorname[0])) &&
+ !pcr->anchor[0])) &&
(TAILQ_FIRST(&newrule->rpool.list) == NULL))
error = EINVAL;
@@ -1571,8 +1804,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
pf_empty_pool(&pf_pabuf);
- s = splsoftnet();
-
if (pcr->action == PF_CHANGE_ADD_HEAD)
oldrule = TAILQ_FIRST(
ruleset->rules[rs_num].active.ptr);
@@ -1588,7 +1819,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
if (newrule != NULL)
pf_rm_rule(NULL, newrule);
error = EINVAL;
- splx(s);
break;
}
}
@@ -1614,12 +1844,11 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
ruleset->rules[rs_num].active.ptr, entries)
oldrule->nr = nr++;
+ ruleset->rules[rs_num].active.ticket++;
+
pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr);
pf_remove_if_empty_ruleset(ruleset);
- pf_update_anchor_rules();
- ruleset->rules[rs_num].active.ticket++;
- splx(s);
break;
}
@@ -1628,7 +1857,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
int killed = 0;
- s = splsoftnet();
RB_FOREACH(state, pf_state_tree_id, &tree_id) {
if (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname,
state->u.s.kif->pfik_name)) {
@@ -1646,7 +1874,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
#if NPFSYNC
pfsync_clear_states(pf_status.hostid, psk->psk_ifname);
#endif
- splx(s);
break;
}
@@ -1655,16 +1882,15 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
int killed = 0;
- s = splsoftnet();
RB_FOREACH(state, pf_state_tree_id, &tree_id) {
if ((!psk->psk_af || state->af == psk->psk_af)
&& (!psk->psk_proto || psk->psk_proto ==
state->proto) &&
- PF_MATCHA(psk->psk_src.not,
+ PF_MATCHA(psk->psk_src.neg,
&psk->psk_src.addr.v.a.addr,
&psk->psk_src.addr.v.a.mask,
&state->lan.addr, state->af) &&
- PF_MATCHA(psk->psk_dst.not,
+ PF_MATCHA(psk->psk_dst.neg,
&psk->psk_dst.addr.v.a.addr,
&psk->psk_dst.addr.v.a.mask,
&state->ext.addr, state->af) &&
@@ -1683,7 +1909,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
}
pf_purge_expired_states();
- splx(s);
psk->psk_af = killed;
break;
}
@@ -1703,12 +1928,10 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = ENOMEM;
break;
}
- s = splsoftnet();
kif = pfi_lookup_create(ps->state.u.ifname);
if (kif == NULL) {
pool_put(&pf_state_pl, state);
error = ENOENT;
- splx(s);
break;
}
bcopy(&ps->state, state, sizeof(struct pf_state));
@@ -1717,11 +1940,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
state->nat_rule.ptr = NULL;
state->anchor.ptr = NULL;
state->rt_kif = NULL;
-#ifdef __FreeBSD__
state->creation = time_second;
-#else
- state->creation = time.tv_sec;
-#endif
state->pfsync_time = 0;
state->packets[0] = state->packets[1] = 0;
state->bytes[0] = state->bytes[1] = 0;
@@ -1731,7 +1950,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
pool_put(&pf_state_pl, state);
error = ENOMEM;
}
- splx(s);
break;
}
@@ -1741,7 +1959,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
u_int32_t nr;
nr = 0;
- s = splsoftnet();
RB_FOREACH(state, pf_state_tree_id, &tree_id) {
if (nr >= ps->nr)
break;
@@ -1749,7 +1966,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
if (state == NULL) {
error = EBUSY;
- splx(s);
break;
}
bcopy(state, &ps->state, sizeof(struct pf_state));
@@ -1758,15 +1974,9 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
-1 : state->nat_rule.ptr->nr;
ps->state.anchor.nr = (state->anchor.ptr == NULL) ?
-1 : state->anchor.ptr->nr;
- splx(s);
ps->state.expire = pf_state_expires(state);
-#ifdef __FreeBSD__
if (ps->state.expire > time_second)
ps->state.expire -= time_second;
-#else
- if (ps->state.expire > time.tv_sec)
- ps->state.expire -= time.tv_sec;
-#endif
else
ps->state.expire = 0;
break;
@@ -1781,27 +1991,17 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
int space = ps->ps_len;
if (space == 0) {
- s = splsoftnet();
TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states)
nr += kif->pfik_states;
- splx(s);
ps->ps_len = sizeof(struct pf_state) * nr;
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- return (0);
+ break;
}
- s = splsoftnet();
p = ps->ps_states;
TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states)
RB_FOREACH(state, pf_state_tree_ext_gwy,
&kif->pfik_ext_gwy) {
-#ifdef __FreeBSD__
int secs = time_second;
-#else
- int secs = time.tv_sec;
-#endif
if ((nr+1) * sizeof(*p) > (unsigned)ps->ps_len)
break;
@@ -1825,15 +2025,12 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
#else
error = copyout(&pstore, p, sizeof(*p));
#endif
- if (error) {
- splx(s);
+ if (error)
goto fail;
- }
p++;
nr++;
}
ps->ps_len = sizeof(struct pf_state) * nr;
- splx(s);
break;
}
@@ -1884,8 +2081,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
!pnl->dport || !pnl->sport)
error = EINVAL;
else {
- s = splsoftnet();
-
/*
* userland gives us source and dest of connection,
* reverse the lookup so we ask for what happens with
@@ -1925,7 +2120,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
} else
error = ENOENT;
- splx(s);
}
break;
}
@@ -2002,12 +2196,10 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pf_ruleset *ruleset = &pf_main_ruleset;
struct pf_rule *rule;
- s = splsoftnet();
TAILQ_FOREACH(rule,
ruleset->rules[PF_RULESET_FILTER].active.ptr, entries)
rule->evaluations = rule->packets =
rule->bytes = 0;
- splx(s);
break;
}
@@ -2036,7 +2228,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pf_altq *altq;
/* enable all altq interfaces on active list */
- s = splsoftnet();
TAILQ_FOREACH(altq, pf_altqs_active, entries) {
if (altq->qname[0] == 0) {
error = pf_enable_altq(altq);
@@ -2046,7 +2237,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
if (error == 0)
pf_altq_running = 1;
- splx(s);
DPFPRINTF(PF_DEBUG_MISC, ("altq: started\n"));
break;
}
@@ -2055,7 +2245,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pf_altq *altq;
/* disable all altq interfaces on active list */
- s = splsoftnet();
TAILQ_FOREACH(altq, pf_altqs_active, entries) {
if (altq->qname[0] == 0) {
error = pf_disable_altq(altq);
@@ -2065,18 +2254,10 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
if (error == 0)
pf_altq_running = 0;
- splx(s);
DPFPRINTF(PF_DEBUG_MISC, ("altq: stopped\n"));
break;
}
- case DIOCBEGINALTQS: {
- u_int32_t *ticket = (u_int32_t *)addr;
-
- error = pf_begin_altq(ticket);
- break;
- }
-
case DIOCADDALTQ: {
struct pfioc_altq *pa = (struct pfioc_altq *)addr;
struct pf_altq *altq, *a;
@@ -2128,23 +2309,14 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
- case DIOCCOMMITALTQS: {
- u_int32_t ticket = *(u_int32_t *)addr;
-
- error = pf_commit_altq(ticket);
- break;
- }
-
case DIOCGETALTQS: {
struct pfioc_altq *pa = (struct pfioc_altq *)addr;
struct pf_altq *altq;
pa->nr = 0;
- s = splsoftnet();
TAILQ_FOREACH(altq, pf_altqs_active, entries)
pa->nr++;
pa->ticket = ticket_altqs_active;
- splx(s);
break;
}
@@ -2158,7 +2330,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
nr = 0;
- s = splsoftnet();
altq = TAILQ_FIRST(pf_altqs_active);
while ((altq != NULL) && (nr < pa->nr)) {
altq = TAILQ_NEXT(altq, entries);
@@ -2166,11 +2337,9 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
if (altq == NULL) {
error = EBUSY;
- splx(s);
break;
}
bcopy(altq, &pa->altq, sizeof(struct pf_altq));
- splx(s);
break;
}
@@ -2191,7 +2360,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
nbytes = pq->nbytes;
nr = 0;
- s = splsoftnet();
altq = TAILQ_FIRST(pf_altqs_active);
while ((altq != NULL) && (nr < pq->nr)) {
altq = TAILQ_NEXT(altq, entries);
@@ -2199,7 +2367,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
if (altq == NULL) {
error = EBUSY;
- splx(s);
break;
}
#ifdef __FreeBSD__
@@ -2209,7 +2376,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
#ifdef __FreeBSD__
PF_LOCK();
#endif
- splx(s);
if (error == 0) {
pq->scheduler = altq->scheduler;
pq->nbytes = nbytes;
@@ -2276,17 +2442,14 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
pp->nr = 0;
- s = splsoftnet();
- pool = pf_get_pool(pp->anchor, pp->ruleset, pp->ticket,
- pp->r_action, pp->r_num, 0, 1, 0);
+ pool = pf_get_pool(pp->anchor, pp->ticket, pp->r_action,
+ pp->r_num, 0, 1, 0);
if (pool == NULL) {
error = EBUSY;
- splx(s);
break;
}
TAILQ_FOREACH(pa, &pool->list, entries)
pp->nr++;
- splx(s);
break;
}
@@ -2294,12 +2457,10 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
u_int32_t nr = 0;
- s = splsoftnet();
- pool = pf_get_pool(pp->anchor, pp->ruleset, pp->ticket,
- pp->r_action, pp->r_num, 0, 1, 1);
+ pool = pf_get_pool(pp->anchor, pp->ticket, pp->r_action,
+ pp->r_num, 0, 1, 1);
if (pool == NULL) {
error = EBUSY;
- splx(s);
break;
}
pa = TAILQ_FIRST(&pool->list);
@@ -2309,13 +2470,12 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
if (pa == NULL) {
error = EBUSY;
- splx(s);
break;
}
bcopy(pa, &pp->addr, sizeof(struct pf_pooladdr));
pfi_dynaddr_copyout(&pp->addr.addr);
pf_tbladdr_copyout(&pp->addr.addr);
- splx(s);
+ pf_rtlabel_copyout(&pp->addr.addr);
break;
}
@@ -2336,13 +2496,13 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
- ruleset = pf_find_ruleset(pca->anchor, pca->ruleset);
+ ruleset = pf_find_ruleset(pca->anchor);
if (ruleset == NULL) {
error = EBUSY;
break;
}
- pool = pf_get_pool(pca->anchor, pca->ruleset, pca->ticket,
- pca->r_action, pca->r_num, pca->r_last, 1, 1);
+ pool = pf_get_pool(pca->anchor, pca->ticket, pca->r_action,
+ pca->r_num, pca->r_last, 1, 1);
if (pool == NULL) {
error = EBUSY;
break;
@@ -2387,8 +2547,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
}
- s = splsoftnet();
-
if (pca->action == PF_CHANGE_ADD_HEAD)
oldpa = TAILQ_FIRST(&pool->list);
else if (pca->action == PF_CHANGE_ADD_TAIL)
@@ -2403,7 +2561,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
if (oldpa == NULL) {
error = EINVAL;
- splx(s);
break;
}
}
@@ -2428,72 +2585,64 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
pool->cur = TAILQ_FIRST(&pool->list);
PF_ACPY(&pool->counter, &pool->cur->addr.v.a.addr,
pca->af);
- splx(s);
- break;
- }
-
- case DIOCGETANCHORS: {
- struct pfioc_anchor *pa = (struct pfioc_anchor *)addr;
- struct pf_anchor *anchor;
-
- pa->nr = 0;
- TAILQ_FOREACH(anchor, &pf_anchors, entries)
- pa->nr++;
- break;
- }
-
- case DIOCGETANCHOR: {
- struct pfioc_anchor *pa = (struct pfioc_anchor *)addr;
- struct pf_anchor *anchor;
- u_int32_t nr = 0;
-
- anchor = TAILQ_FIRST(&pf_anchors);
- while (anchor != NULL && nr < pa->nr) {
- anchor = TAILQ_NEXT(anchor, entries);
- nr++;
- }
- if (anchor == NULL)
- error = EBUSY;
- else
- bcopy(anchor->name, pa->name, sizeof(pa->name));
break;
}
case DIOCGETRULESETS: {
struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
- struct pf_anchor *anchor;
struct pf_ruleset *ruleset;
+ struct pf_anchor *anchor;
- pr->anchor[PF_ANCHOR_NAME_SIZE-1] = 0;
- if ((anchor = pf_find_anchor(pr->anchor)) == NULL) {
+ pr->path[sizeof(pr->path) - 1] = 0;
+ if ((ruleset = pf_find_ruleset(pr->path)) == NULL) {
error = EINVAL;
break;
}
pr->nr = 0;
- TAILQ_FOREACH(ruleset, &anchor->rulesets, entries)
- pr->nr++;
+ if (ruleset->anchor == NULL) {
+ /* XXX kludge for pf_main_ruleset */
+ RB_FOREACH(anchor, pf_anchor_global, &pf_anchors)
+ if (anchor->parent == NULL)
+ pr->nr++;
+ } else {
+ RB_FOREACH(anchor, pf_anchor_node,
+ &ruleset->anchor->children)
+ pr->nr++;
+ }
break;
}
case DIOCGETRULESET: {
struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
- struct pf_anchor *anchor;
struct pf_ruleset *ruleset;
+ struct pf_anchor *anchor;
u_int32_t nr = 0;
- if ((anchor = pf_find_anchor(pr->anchor)) == NULL) {
+ pr->path[sizeof(pr->path) - 1] = 0;
+ if ((ruleset = pf_find_ruleset(pr->path)) == NULL) {
error = EINVAL;
break;
}
- ruleset = TAILQ_FIRST(&anchor->rulesets);
- while (ruleset != NULL && nr < pr->nr) {
- ruleset = TAILQ_NEXT(ruleset, entries);
- nr++;
+ pr->name[0] = 0;
+ if (ruleset->anchor == NULL) {
+ /* XXX kludge for pf_main_ruleset */
+ RB_FOREACH(anchor, pf_anchor_global, &pf_anchors)
+ if (anchor->parent == NULL && nr++ == pr->nr) {
+ strlcpy(pr->name, anchor->name,
+ sizeof(pr->name));
+ break;
+ }
+ } else {
+ RB_FOREACH(anchor, pf_anchor_node,
+ &ruleset->anchor->children)
+ if (nr++ == pr->nr) {
+ strlcpy(pr->name, anchor->name,
+ sizeof(pr->name));
+ break;
+ }
}
- if (ruleset == NULL)
+ if (!pr->name[0])
error = EBUSY;
- else
- bcopy(ruleset->name, pr->name, sizeof(pr->name));
break;
}
@@ -2684,31 +2833,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
- case DIOCRINABEGIN: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != 0) {
- error = ENODEV;
- break;
- }
- error = pfr_ina_begin(&io->pfrio_table, &io->pfrio_ticket,
- &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
- break;
- }
-
- case DIOCRINACOMMIT: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != 0) {
- error = ENODEV;
- break;
- }
- error = pfr_ina_commit(&io->pfrio_table, io->pfrio_ticket,
- &io->pfrio_nadd, &io->pfrio_nchange, io->pfrio_flags |
- PFR_FLAG_USERIOCTL);
- break;
- }
-
case DIOCRINADEFINE: {
struct pfioc_table *io = (struct pfioc_table *)addr;
@@ -2724,25 +2848,22 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCOSFPADD: {
struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
- s = splsoftnet();
error = pf_osfp_add(io);
- splx(s);
break;
}
case DIOCOSFPGET: {
struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
- s = splsoftnet();
error = pf_osfp_get(io);
- splx(s);
break;
}
case DIOCXBEGIN: {
- struct pfioc_trans *io = (struct pfioc_trans *)addr;
- struct pfioc_trans_e ioe;
- struct pfr_table table;
- int i;
+ struct pfioc_trans *io = (struct pfioc_trans *)
+ addr;
+ static struct pfioc_trans_e ioe;
+ static struct pfr_table table;
+ int i;
if (io->esize != sizeof(ioe)) {
error = ENODEV;
@@ -2761,7 +2882,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
switch (ioe.rs_num) {
#ifdef ALTQ
case PF_RULESET_ALTQ:
- if (ioe.anchor[0] || ioe.ruleset[0]) {
+ if (ioe.anchor[0]) {
error = EINVAL;
goto fail;
}
@@ -2773,15 +2894,13 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
bzero(&table, sizeof(table));
strlcpy(table.pfrt_anchor, ioe.anchor,
sizeof(table.pfrt_anchor));
- strlcpy(table.pfrt_ruleset, ioe.ruleset,
- sizeof(table.pfrt_ruleset));
if ((error = pfr_ina_begin(&table,
&ioe.ticket, NULL, 0)))
goto fail;
break;
default:
if ((error = pf_begin_rules(&ioe.ticket,
- ioe.rs_num, ioe.anchor, ioe.ruleset)))
+ ioe.rs_num, ioe.anchor)))
goto fail;
break;
}
@@ -2800,10 +2919,11 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
case DIOCXROLLBACK: {
- struct pfioc_trans *io = (struct pfioc_trans *)addr;
- struct pfioc_trans_e ioe;
- struct pfr_table table;
- int i;
+ struct pfioc_trans *io = (struct pfioc_trans *)
+ addr;
+ static struct pfioc_trans_e ioe;
+ static struct pfr_table table;
+ int i;
if (io->esize != sizeof(ioe)) {
error = ENODEV;
@@ -2822,7 +2942,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
switch (ioe.rs_num) {
#ifdef ALTQ
case PF_RULESET_ALTQ:
- if (ioe.anchor[0] || ioe.ruleset[0]) {
+ if (ioe.anchor[0]) {
error = EINVAL;
goto fail;
}
@@ -2834,15 +2954,13 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
bzero(&table, sizeof(table));
strlcpy(table.pfrt_anchor, ioe.anchor,
sizeof(table.pfrt_anchor));
- strlcpy(table.pfrt_ruleset, ioe.ruleset,
- sizeof(table.pfrt_ruleset));
if ((error = pfr_ina_rollback(&table,
ioe.ticket, NULL, 0)))
goto fail; /* really bad */
break;
default:
if ((error = pf_rollback_rules(ioe.ticket,
- ioe.rs_num, ioe.anchor, ioe.ruleset)))
+ ioe.rs_num, ioe.anchor)))
goto fail; /* really bad */
break;
}
@@ -2851,11 +2969,12 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
case DIOCXCOMMIT: {
- struct pfioc_trans *io = (struct pfioc_trans *)addr;
- struct pfioc_trans_e ioe;
- struct pfr_table table;
- struct pf_ruleset *rs;
- int i;
+ struct pfioc_trans *io = (struct pfioc_trans *)
+ addr;
+ static struct pfioc_trans_e ioe;
+ static struct pfr_table table;
+ struct pf_ruleset *rs;
+ int i;
if (io->esize != sizeof(ioe)) {
error = ENODEV;
@@ -2875,7 +2994,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
switch (ioe.rs_num) {
#ifdef ALTQ
case PF_RULESET_ALTQ:
- if (ioe.anchor[0] || ioe.ruleset[0]) {
+ if (ioe.anchor[0]) {
error = EINVAL;
goto fail;
}
@@ -2887,7 +3006,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
#endif /* ALTQ */
case PF_RULESET_TABLE:
- rs = pf_find_ruleset(ioe.anchor, ioe.ruleset);
+ rs = pf_find_ruleset(ioe.anchor);
if (rs == NULL || !rs->topen || ioe.ticket !=
rs->tticket) {
error = EBUSY;
@@ -2900,7 +3019,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = EINVAL;
goto fail;
}
- rs = pf_find_ruleset(ioe.anchor, ioe.ruleset);
+ rs = pf_find_ruleset(ioe.anchor);
if (rs == NULL ||
!rs->rules[ioe.rs_num].inactive.open ||
rs->rules[ioe.rs_num].inactive.ticket !=
@@ -2933,15 +3052,13 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
bzero(&table, sizeof(table));
strlcpy(table.pfrt_anchor, ioe.anchor,
sizeof(table.pfrt_anchor));
- strlcpy(table.pfrt_ruleset, ioe.ruleset,
- sizeof(table.pfrt_ruleset));
if ((error = pfr_ina_commit(&table, ioe.ticket,
NULL, NULL, 0)))
goto fail; /* really bad */
break;
default:
if ((error = pf_commit_rules(ioe.ticket,
- ioe.rs_num, ioe.anchor, ioe.ruleset)))
+ ioe.rs_num, ioe.anchor)))
goto fail; /* really bad */
break;
}
@@ -2957,25 +3074,15 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
int space = psn->psn_len;
if (space == 0) {
- s = splsoftnet();
RB_FOREACH(n, pf_src_tree, &tree_src_tracking)
nr++;
- splx(s);
psn->psn_len = sizeof(struct pf_src_node) * nr;
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- return (0);
+ break;
}
- s = splsoftnet();
p = psn->psn_src_nodes;
RB_FOREACH(n, pf_src_tree, &tree_src_tracking) {
-#ifdef __FreeBSD__
- int secs = time_second;
-#else
- int secs = time.tv_sec;
-#endif
+ int secs = time_second, diff;
if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len)
break;
@@ -2988,20 +3095,27 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
pstore.expire -= secs;
else
pstore.expire = 0;
+
+ /* adjust the connection rate estimate */
+ diff = secs - n->conn_rate.last;
+ if (diff >= n->conn_rate.seconds)
+ pstore.conn_rate.count = 0;
+ else
+ pstore.conn_rate.count -=
+ n->conn_rate.count * diff /
+ n->conn_rate.seconds;
+
#ifdef __FreeBSD__
PF_COPYOUT(&pstore, p, sizeof(*p), error);
#else
error = copyout(&pstore, p, sizeof(*p));
#endif
- if (error) {
- splx(s);
+ if (error)
goto fail;
- }
p++;
nr++;
}
psn->psn_len = sizeof(struct pf_src_node) * nr;
- splx(s);
break;
}
@@ -3009,7 +3123,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pf_src_node *n;
struct pf_state *state;
- s = splsoftnet();
RB_FOREACH(state, pf_state_tree_id, &tree_id) {
state->src_node = NULL;
state->nat_src_node = NULL;
@@ -3020,25 +3133,21 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
pf_purge_expired_src_nodes();
pf_status.src_nodes = 0;
- splx(s);
break;
}
case DIOCSETHOSTID: {
u_int32_t *hostid = (u_int32_t *)addr;
- if (*hostid == 0) {
- error = EINVAL;
- goto fail;
- }
- pf_status.hostid = *hostid;
+ if (*hostid == 0)
+ pf_status.hostid = arc4random();
+ else
+ pf_status.hostid = *hostid;
break;
}
case DIOCOSFPFLUSH:
- s = splsoftnet();
pf_osfp_flush();
- splx(s);
break;
case DIOCIGETIFACES: {
@@ -3061,6 +3170,20 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
+ case DIOCSETIFFLAG: {
+ struct pfioc_iface *io = (struct pfioc_iface *)addr;
+
+ error = pfi_set_flags(io->pfiio_name, io->pfiio_flags);
+ break;
+ }
+
+ case DIOCCLRIFFLAG: {
+ struct pfioc_iface *io = (struct pfioc_iface *)addr;
+
+ error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags);
+ break;
+ }
+
default:
error = ENODEV;
break;
@@ -3068,6 +3191,8 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
fail:
#ifdef __FreeBSD__
PF_UNLOCK();
+#else
+ splx(s);
#endif
return (error);
}
@@ -3147,38 +3272,38 @@ shutdown_pf(void)
pf_status.running = 0;
do {
- if ((error = pf_begin_rules(&t[0], PF_RULESET_SCRUB, &nn,
- &nn)) != 0) {
+ if ((error = pf_begin_rules(&t[0], PF_RULESET_SCRUB, &nn))
+ != 0) {
DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: SCRUB\n"));
break;
}
- if ((error = pf_begin_rules(&t[1], PF_RULESET_FILTER, &nn,
- &nn)) != 0) {
+ if ((error = pf_begin_rules(&t[1], PF_RULESET_FILTER, &nn))
+ != 0) {
DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: FILTER\n"));
break; /* XXX: rollback? */
}
- if ((error = pf_begin_rules(&t[2], PF_RULESET_NAT, &nn, &nn))
+ if ((error = pf_begin_rules(&t[2], PF_RULESET_NAT, &nn))
!= 0) {
DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: NAT\n"));
break; /* XXX: rollback? */
}
- if ((error = pf_begin_rules(&t[3], PF_RULESET_BINAT, &nn, &nn))
+ if ((error = pf_begin_rules(&t[3], PF_RULESET_BINAT, &nn))
!= 0) {
DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: BINAT\n"));
break; /* XXX: rollback? */
}
- if ((error = pf_begin_rules(&t[4], PF_RULESET_RDR, &nn, &nn))
+ if ((error = pf_begin_rules(&t[4], PF_RULESET_RDR, &nn))
!= 0) {
DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: RDR\n"));
break; /* XXX: rollback? */
}
/* XXX: these should always succeed here */
- pf_commit_rules(t[0], PF_RULESET_SCRUB, &nn, &nn);
- pf_commit_rules(t[1], PF_RULESET_FILTER, &nn, &nn);
- pf_commit_rules(t[2], PF_RULESET_NAT, &nn, &nn);
- pf_commit_rules(t[3], PF_RULESET_BINAT, &nn, &nn);
- pf_commit_rules(t[4], PF_RULESET_RDR, &nn, &nn);
+ pf_commit_rules(t[0], PF_RULESET_SCRUB, &nn);
+ pf_commit_rules(t[1], PF_RULESET_FILTER, &nn);
+ pf_commit_rules(t[2], PF_RULESET_NAT, &nn);
+ pf_commit_rules(t[3], PF_RULESET_BINAT, &nn);
+ pf_commit_rules(t[4], PF_RULESET_RDR, &nn);
if ((error = pf_clear_tables()) != 0)
break;
@@ -3223,7 +3348,7 @@ pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
HTONS(h->ip_len);
HTONS(h->ip_off);
}
- chk = pf_test(PF_IN, ifp, m, inp);
+ chk = pf_test(PF_IN, ifp, m, NULL, inp);
if (chk && *m) {
m_freem(*m);
*m = NULL;
@@ -3263,7 +3388,7 @@ pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
HTONS(h->ip_len);
HTONS(h->ip_off);
}
- chk = pf_test(PF_OUT, ifp, m, inp);
+ chk = pf_test(PF_OUT, ifp, m, NULL, inp);
if (chk && *m) {
m_freem(*m);
*m = NULL;
@@ -3287,7 +3412,7 @@ pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
*/
int chk;
- chk = pf_test6(PF_IN, ifp, m, inp);
+ chk = pf_test6(PF_IN, ifp, m, NULL, inp);
if (chk && *m) {
m_freem(*m);
*m = NULL;
@@ -3309,7 +3434,7 @@ pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
in_delayed_cksum(*m);
(*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
}
- chk = pf_test6(PF_OUT, ifp, m, inp);
+ chk = pf_test6(PF_OUT, ifp, m, NULL, inp);
if (chk && *m) {
m_freem(*m);
*m = NULL;