summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric Berger <cedric@cvs.openbsd.org>2003-04-30 12:30:28 +0000
committerCedric Berger <cedric@cvs.openbsd.org>2003-04-30 12:30:28 +0000
commitba4eec495765b9095d5d66d12e933cae99fbfba5 (patch)
tree8242fa1f0a74e8277324734a9b5d014dbf6d7771
parentd08d75cff317e4ebbe3d8d3f9ebdd6daee64a27f (diff)
Allow tables to be loaded into anchors.
Most pfctl table commands (excluding 'show' and 'flush') support the "-a" modifier. ok dhartmei@
-rw-r--r--sbin/pfctl/parse.y5
-rw-r--r--sbin/pfctl/pfctl.c40
-rw-r--r--sbin/pfctl/pfctl.h9
-rw-r--r--sbin/pfctl/pfctl_parser.h6
-rw-r--r--sbin/pfctl/pfctl_table.c49
-rw-r--r--sys/net/pf.c8
-rw-r--r--sys/net/pf_ioctl.c10
-rw-r--r--sys/net/pf_table.c110
-rw-r--r--sys/net/pfvar.h10
-rw-r--r--usr.sbin/authpf/authpf.c5
10 files changed, 188 insertions, 64 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 76bf7b7c24e..f3b7041d5b7 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.368 2003/04/25 17:36:33 dhartmei Exp $ */
+/* $OpenBSD: parse.y,v 1.369 2003/04/30 12:30:27 cedric Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -756,7 +756,8 @@ tabledef : TABLE '<' STRING '>' table_opts {
}
pfctl_define_table($3, $5.flags, $5.init_addr,
(pf->opts & PF_OPT_NOACTION) || !(pf->loadopt &
- (PFCTL_FLAG_TABLE | PFCTL_FLAG_ALL)));
+ (PFCTL_FLAG_TABLE | PFCTL_FLAG_ALL)),
+ pf->anchor, pf->ruleset);
}
;
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 702108565cd..c8725390062 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.c,v 1.167 2003/04/03 15:52:24 cedric Exp $ */
+/* $OpenBSD: pfctl.c,v 1.168 2003/04/30 12:30:27 cedric Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -988,6 +988,8 @@ pfctl_rules(int dev, char *filename, int opts)
pf.prule[i] = &pr[i];
}
pf.rule_nr = 0;
+ pf.anchor = anchorname;
+ pf.ruleset = rulesetname;
if (parse_rules(fin, &pf) < 0)
errx(1, "Syntax error in config file: pf rules not loaded");
if ((altqsupport && (loadopt & (PFCTL_FLAG_ALTQ | PFCTL_FLAG_ALL)) != 0))
@@ -996,14 +998,17 @@ pfctl_rules(int dev, char *filename, int opts)
if ((opts & PF_OPT_NOACTION) == 0) {
if ((loadopt & (PFCTL_FLAG_NAT | PFCTL_FLAG_ALL)) != 0) {
pr[PF_RULESET_NAT].rule.action = PF_NAT;
- if (ioctl(dev, DIOCCOMMITRULES, &pr[PF_RULESET_NAT]))
- err(1, "DIOCCOMMITRULES");
+ if (ioctl(dev, DIOCCOMMITRULES, &pr[PF_RULESET_NAT]) &&
+ (errno != EINVAL || pf.rule_nr))
+ err(1, "DIOCCOMMITRULES NAT");
pr[PF_RULESET_RDR].rule.action = PF_RDR;
- if (ioctl(dev, DIOCCOMMITRULES, &pr[PF_RULESET_RDR]))
- err(1, "DIOCCOMMITRULES");
+ if (ioctl(dev, DIOCCOMMITRULES, &pr[PF_RULESET_RDR]) &&
+ (errno != EINVAL || pf.rule_nr))
+ err(1, "DIOCCOMMITRULES RDR");
pr[PF_RULESET_BINAT].rule.action = PF_BINAT;
- if (ioctl(dev, DIOCCOMMITRULES, &pr[PF_RULESET_BINAT]))
- err(1, "DIOCCOMMITRULES");
+ if (ioctl(dev, DIOCCOMMITRULES, &pr[PF_RULESET_BINAT]) &&
+ (errno != EINVAL || pf.rule_nr))
+ err(1, "DIOCCOMMITRULES BINAT");
}
if (((altqsupport && (loadopt &
(PFCTL_FLAG_ALTQ | PFCTL_FLAG_ALL)) != 0)) &&
@@ -1011,11 +1016,13 @@ pfctl_rules(int dev, char *filename, int opts)
err(1, "DIOCCOMMITALTQS");
if ((loadopt & (PFCTL_FLAG_FILTER | PFCTL_FLAG_ALL)) != 0) {
pr[PF_RULESET_SCRUB].rule.action = PF_SCRUB;
- if (ioctl(dev, DIOCCOMMITRULES, &pr[PF_RULESET_SCRUB]))
- err(1, "DIOCCOMMITRULES");
+ if (ioctl(dev, DIOCCOMMITRULES, &pr[PF_RULESET_SCRUB]) &&
+ (errno != EINVAL || pf.rule_nr))
+ err(1, "DIOCCOMMITRULES SCRUB");
pr[PF_RULESET_FILTER].rule.action = PF_PASS;
- if (ioctl(dev, DIOCCOMMITRULES, &pr[PF_RULESET_FILTER]))
- err(1, "DIOCCOMMITRULES");
+ if (ioctl(dev, DIOCCOMMITRULES, &pr[PF_RULESET_FILTER]) &&
+ (errno != EINVAL || pf.rule_nr))
+ err(1, "DIOCCOMMITRULES FILTER");
}
if (loadopt & (PFCTL_FLAG_TABLE | PFCTL_FLAG_ALL))
pfctl_commit_table();
@@ -1438,6 +1445,7 @@ main(int argc, char *argv[])
loadopt &= ~PFCTL_FLAG_ALL;
loadopt |= PFCTL_FLAG_FILTER;
loadopt |= PFCTL_FLAG_NAT;
+ loadopt |= PFCTL_FLAG_TABLE;
}
}
@@ -1480,10 +1488,10 @@ main(int argc, char *argv[])
pfctl_clear_altq(dev, opts);
pfctl_clear_states(dev, opts);
pfctl_clear_stats(dev, opts);
- pfctl_clear_tables(opts);
+ pfctl_clear_tables(anchorname, rulesetname, opts);
break;
case 'T':
- pfctl_clear_tables(opts);
+ pfctl_clear_tables(anchorname, rulesetname, opts);
break;
default:
assert(0);
@@ -1494,7 +1502,7 @@ main(int argc, char *argv[])
if (tblcmdopt != NULL) {
error = pfctl_command_tables(argc, argv, tableopt,
- tblcmdopt, rulesopt, opts);
+ tblcmdopt, rulesopt, anchorname, rulesetname, opts);
rulesopt = NULL;
}
@@ -1540,10 +1548,10 @@ main(int argc, char *argv[])
pfctl_show_rules(dev, opts, 1);
pfctl_show_timeouts(dev);
pfctl_show_limits(dev);
- pfctl_show_tables(opts);
+ pfctl_show_tables(anchorname, rulesetname, opts);
break;
case 'T':
- pfctl_show_tables(opts);
+ pfctl_show_tables(anchorname, rulesetname, opts);
break;
default:
assert(0);
diff --git a/sbin/pfctl/pfctl.h b/sbin/pfctl/pfctl.h
index 873aee6a4c9..5ca83fa05a3 100644
--- a/sbin/pfctl/pfctl.h
+++ b/sbin/pfctl/pfctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.h,v 1.17 2003/04/14 14:50:46 henning Exp $ */
+/* $OpenBSD: pfctl.h,v 1.18 2003/04/30 12:30:27 cedric Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -55,9 +55,10 @@ int pfr_ina_begin(int *, int *, int);
int pfr_ina_commit(int, int *, int *, int);
int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *,
int *, int, int);
-int pfctl_clear_tables(int);
-int pfctl_show_tables(int);
-int pfctl_command_tables(int, char *[], char *, const char *, char *, int);
+int pfctl_clear_tables(const char *, const char *, int);
+int pfctl_show_tables(const char *, const char *, int);
+int pfctl_command_tables(int, char *[], char *, const char *, char *,
+ const char *, const char *, int);
int pfctl_show_altq(int, int, int);
#ifndef DEFAULT_PRIORITY
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index b890117af9a..48e8ef74f19 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.h,v 1.58 2003/04/15 11:29:24 henning Exp $ */
+/* $OpenBSD: pfctl_parser.h,v 1.59 2003/04/30 12:30:27 cedric Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -65,6 +65,8 @@ struct pfctl {
struct pfioc_rule *prule[PF_RULESET_MAX];
struct pfioc_altq *paltq;
struct pfioc_queue *pqueue;
+ const char *anchor;
+ const char *ruleset;
};
enum pfctl_iflookup_mode {
@@ -151,7 +153,7 @@ void print_queue(const struct pf_altq *, unsigned, struct node_queue_bw *,
void pfctl_begin_table(void);
void pfctl_append_addr(char *, int, int);
void pfctl_append_file(char *);
-void pfctl_define_table(char *, int, int, int);
+void pfctl_define_table(char *, int, int, int, const char *, const char *);
void pfctl_commit_table(void);
struct icmptypeent {
diff --git a/sbin/pfctl/pfctl_table.c b/sbin/pfctl/pfctl_table.c
index 44abcf6a6e3..f3776f79c52 100644
--- a/sbin/pfctl/pfctl_table.c
+++ b/sbin/pfctl/pfctl_table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_table.c,v 1.40 2003/04/27 16:02:08 cedric Exp $ */
+/* $OpenBSD: pfctl_table.c,v 1.41 2003/04/30 12:30:27 cedric Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@@ -55,7 +55,8 @@
#define BUF_SIZE 256
extern void usage(void);
-static int pfctl_table(int, char *[], char *, const char *, char *, int);
+static int pfctl_table(int, char *[], char *, const char *, char *,
+ const char *, const char *, int);
static void grow_buffer(size_t, int);
static void print_table(struct pfr_table *, int, int);
static void print_tstats(struct pfr_tstats *, int);
@@ -105,29 +106,31 @@ static const char *stats_text[PFR_DIR_MAX][PFR_OP_TABLE_MAX] = {
} while(0)
int
-pfctl_clear_tables(int opts)
+pfctl_clear_tables(const char *anchor, const char *ruleset, int opts)
{
- return pfctl_table(0, NULL, NULL, "-F", NULL, opts);
+ return pfctl_table(0, NULL, NULL, "-F", NULL, anchor, ruleset, opts);
}
int
-pfctl_show_tables(int opts)
+pfctl_show_tables(const char *anchor, const char *ruleset, int opts)
{
- return pfctl_table(0, NULL, NULL, "-s", NULL, opts);
+ return pfctl_table(0, NULL, NULL, "-s", NULL, anchor, ruleset, opts);
}
int
pfctl_command_tables(int argc, char *argv[], char *tname,
- const char *command, char *file, int opts)
+ const char *command, char *file, const char *anchor, const char *ruleset,
+ int opts)
{
if (tname == NULL || command == NULL)
usage();
- return pfctl_table(argc, argv, tname, command, file, opts);
+ return pfctl_table(argc, argv, tname, command, file, anchor, ruleset,
+ opts);
}
int
pfctl_table(int argc, char *argv[], char *tname, const char *command,
- char *file, int opts)
+ char *file, const char *anchor, const char *ruleset, int opts)
{
struct pfr_table table;
int nadd = 0, ndel = 0, nchange = 0, nzero = 0;
@@ -145,6 +148,11 @@ pfctl_table(int argc, char *argv[], char *tname, const char *command,
sizeof(table.pfrt_name)) >= sizeof(table.pfrt_name))
errx(1, "pfctl_table: strlcpy");
}
+ if (strlcpy(table.pfrt_anchor, anchor,
+ sizeof(table.pfrt_anchor)) >= sizeof(table.pfrt_anchor) ||
+ strlcpy(table.pfrt_ruleset, ruleset,
+ sizeof(table.pfrt_ruleset)) >= sizeof(table.pfrt_ruleset))
+ errx(1, "pfctl_table: strlcpy");
if (!strcmp(command, "-F")) {
if (argc || file != NULL)
usage();
@@ -336,13 +344,19 @@ print_table(struct pfr_table *ta, int verbose, int debug)
if (!debug && !(ta->pfrt_flags & PFR_TFLAG_ACTIVE))
return;
if (verbose) {
- printf("%c%c%c%c%c\t%s\n",
+ printf("%c%c%c%c%c%c\t%s",
(ta->pfrt_flags & PFR_TFLAG_CONST) ? 'c' : '-',
(ta->pfrt_flags & PFR_TFLAG_PERSIST) ? 'p' : '-',
(ta->pfrt_flags & PFR_TFLAG_ACTIVE) ? 'a' : '-',
(ta->pfrt_flags & PFR_TFLAG_INACTIVE) ? 'i' : '-',
(ta->pfrt_flags & PFR_TFLAG_REFERENCED) ? 'r' : '-',
+ (ta->pfrt_flags & PFR_TFLAG_REFDANCHOR) ? 'h' : '-',
ta->pfrt_name);
+ if (ta->pfrt_anchor[0])
+ printf("\t%s", ta->pfrt_anchor);
+ if (ta->pfrt_ruleset[0])
+ printf(":%s", ta->pfrt_ruleset);
+ puts("");
} else
puts(ta->pfrt_name);
}
@@ -357,8 +371,10 @@ print_tstats(struct pfr_tstats *ts, int debug)
return;
print_table(&ts->pfrts_t, 1, debug);
printf("\tAddresses: %d\n", ts->pfrts_cnt);
- printf("\tReferences: %d\n", ts->pfrts_refcnt[PFR_REFCNT_RULE]);
printf("\tCleared: %s", ctime(&time));
+ printf("\tReferences: [ Anchors: %-18d Rules: %-18d ]\n",
+ ts->pfrts_refcnt[PFR_REFCNT_ANCHOR],
+ ts->pfrts_refcnt[PFR_REFCNT_RULE]);
printf("\tEvaluations: [ NoMatch: %-18llu Match: %-18llu ]\n",
ts->pfrts_nomatch, ts->pfrts_match);
for (dir = 0; dir < PFR_DIR_MAX; dir++)
@@ -598,14 +614,19 @@ pfctl_append_file(char *file)
}
void
-pfctl_define_table(char *name, int flags, int addrs, int noaction)
+pfctl_define_table(char *name, int flags, int addrs, int noaction,
+ const char *anchor, const char *ruleset)
{
struct pfr_table tbl;
if (!noaction) {
bzero(&tbl, sizeof(tbl));
- if (strlcpy(tbl.pfrt_name, name, sizeof(tbl.pfrt_name)) >=
- sizeof(tbl.pfrt_name))
+ if (strlcpy(tbl.pfrt_name, name,
+ sizeof(tbl.pfrt_name)) >= sizeof(tbl.pfrt_name) ||
+ strlcpy(tbl.pfrt_anchor, anchor,
+ sizeof(tbl.pfrt_anchor)) >= sizeof(tbl.pfrt_anchor) ||
+ strlcpy(tbl.pfrt_ruleset, ruleset,
+ sizeof(tbl.pfrt_ruleset)) >= sizeof(tbl.pfrt_ruleset))
errx(1, "pfctl_define_table: strlcpy");
tbl.pfrt_flags = flags;
diff --git a/sys/net/pf.c b/sys/net/pf.c
index a21a7383277..8a2cdefa588 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.338 2003/04/25 17:41:25 dhartmei Exp $ */
+/* $OpenBSD: pf.c,v 1.339 2003/04/30 12:30:27 cedric Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -117,8 +117,6 @@ struct pf_state *pf_find_state(struct pf_state_tree *,
struct pf_tree_node *);
void pf_purge_expired_states(void);
void pf_purge_timeout(void *);
-int pf_tbladdr_setup(struct pf_addr_wrap *);
-void pf_tbladdr_remove(struct pf_addr_wrap *);
void pf_dynaddr_update(void *);
void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t);
void pf_print_state(struct pf_state *);
@@ -492,11 +490,11 @@ pf_purge_expired_states(void)
}
int
-pf_tbladdr_setup(struct pf_addr_wrap *aw)
+pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw)
{
if (aw->type != PF_ADDR_TABLE)
return (0);
- if ((aw->p.tbl = pfr_attach_table(aw->v.tblname)) == NULL)
+ if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL)
return (1);
return (0);
}
diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
index 1d7f7a3045b..7499129897d 100644
--- a/sys/net/pf_ioctl.c
+++ b/sys/net/pf_ioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_ioctl.c,v 1.59 2003/04/27 16:02:07 cedric Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.60 2003/04/30 12:30:27 cedric Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -609,9 +609,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = EINVAL;
if (pf_dynaddr_setup(&rule->dst.addr, rule->af))
error = EINVAL;
- if (pf_tbladdr_setup(&rule->src.addr))
+ if (pf_tbladdr_setup(ruleset, &rule->src.addr))
error = EINVAL;
- if (pf_tbladdr_setup(&rule->dst.addr))
+ if (pf_tbladdr_setup(ruleset, &rule->dst.addr))
error = EINVAL;
pf_mv_pool(&pf_pabuf, &rule->rpool.list);
@@ -848,9 +848,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = EINVAL;
if (pf_dynaddr_setup(&newrule->dst.addr, newrule->af))
error = EINVAL;
- if (pf_tbladdr_setup(&newrule->src.addr))
+ if (pf_tbladdr_setup(ruleset, &newrule->src.addr))
error = EINVAL;
- if (pf_tbladdr_setup(&newrule->dst.addr))
+ if (pf_tbladdr_setup(ruleset, &newrule->dst.addr))
error = EINVAL;
pf_mv_pool(&pf_pabuf, &newrule->rpool.list);
diff --git a/sys/net/pf_table.c b/sys/net/pf_table.c
index db2b8750da4..251dfec885d 100644
--- a/sys/net/pf_table.c
+++ b/sys/net/pf_table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_table.c,v 1.33 2003/04/27 16:02:08 cedric Exp $ */
+/* $OpenBSD: pf_table.c,v 1.34 2003/04/30 12:30:27 cedric Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@@ -1021,7 +1021,7 @@ int
pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
{
struct pfr_ktableworkq addq, changeq;
- struct pfr_ktable *p, *q, key;
+ struct pfr_ktable *p, *q, *r, key;
int i, rv, s, xadd = 0;
long tzero = time.tv_sec;
@@ -1040,14 +1040,37 @@ pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
if (p == NULL)
senderr(ENOMEM);
SLIST_FOREACH(q, &addq, pfrkt_workq) {
- if (!strcmp(p->pfrkt_name, q->pfrkt_name))
+ if (!pfr_ktable_compare(p, q))
goto _skip;
}
SLIST_INSERT_HEAD(&addq, p, pfrkt_workq);
xadd++;
+ if (!key.pfrkt_anchor[0])
+ goto _skip;
+
+ /* find or create root table */
+ bzero(key.pfrkt_anchor, sizeof(key.pfrkt_anchor));
+ bzero(key.pfrkt_ruleset, sizeof(key.pfrkt_ruleset));
+ r = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
+ if (r != NULL) {
+ p->pfrkt_root = r;
+ goto _skip;
+ }
+ SLIST_FOREACH(q, &addq, pfrkt_workq) {
+ if (!pfr_ktable_compare(&key, q)) {
+ p->pfrkt_root = q;
+ goto _skip;
+ }
+ }
+ key.pfrkt_flags = 0;
+ r = pfr_create_ktable(&key.pfrkt_t, 0);
+ if (r == NULL)
+ senderr(ENOMEM);
+ SLIST_INSERT_HEAD(&addq, r, pfrkt_workq);
+ p->pfrkt_root = r;
} else if (!(p->pfrkt_flags & PFR_TFLAG_ACTIVE)) {
SLIST_FOREACH(q, &changeq, pfrkt_workq)
- if (!strcmp(key.pfrkt_name, q->pfrkt_name))
+ if (!pfr_ktable_compare(&key, q))
goto _skip;
p->pfrkt_nflags = (p->pfrkt_flags &
~PFR_TFLAG_USRMASK) | key.pfrkt_flags;
@@ -1091,7 +1114,7 @@ pfr_del_tables(struct pfr_table *tbl, int size, int *ndel, int flags)
p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
if (p != NULL && (p->pfrkt_flags & PFR_TFLAG_ACTIVE)) {
SLIST_FOREACH(q, &workq, pfrkt_workq)
- if (!strcmp(p->pfrkt_name, q->pfrkt_name))
+ if (!pfr_ktable_compare(p, q))
goto _skip;
p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_ACTIVE;
SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
@@ -1239,7 +1262,7 @@ pfr_set_tflags(struct pfr_table *tbl, int size, int setflag, int clrflag,
if (p->pfrkt_nflags == p->pfrkt_flags)
goto _skip;
SLIST_FOREACH(q, &workq, pfrkt_workq)
- if (!strcmp(p->pfrkt_name, q->pfrkt_name))
+ if (!pfr_ktable_compare(p, q))
goto _skip;
SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
if ((p->pfrkt_flags & PFR_TFLAG_PERSIST) &&
@@ -1297,7 +1320,7 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
{
struct pfr_ktableworkq tableq;
struct pfr_kentryworkq addrq;
- struct pfr_ktable *kt, *shadow;
+ struct pfr_ktable *kt, *rt, *shadow, key;
struct pfr_kentry *p;
struct pfr_addr ad;
int i, rv, xadd = 0, xaddr = 0;
@@ -1318,8 +1341,27 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
return (ENOMEM);
SLIST_INSERT_HEAD(&tableq, kt, pfrkt_workq);
xadd++;
+ if (!tbl->pfrt_anchor[0])
+ goto _skip;
+
+ /* find or create root table */
+ bzero(&key, sizeof(key));
+ strlcpy(key.pfrkt_name, tbl->pfrt_name, sizeof(key.pfrkt_name));
+ rt = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
+ if (rt != NULL) {
+ kt->pfrkt_root = rt;
+ goto _skip;
+ }
+ rt = pfr_create_ktable(&key.pfrkt_t, 0);
+ if (rt == NULL) {
+ pfr_destroy_ktables(&tableq, 0);
+ return (ENOMEM);
+ }
+ SLIST_INSERT_HEAD(&tableq, rt, pfrkt_workq);
+ kt->pfrkt_root = rt;
} else if (!(kt->pfrkt_flags & PFR_TFLAG_INACTIVE))
xadd++;
+_skip:
shadow = pfr_create_ktable(tbl, 0);
if (shadow == NULL) {
pfr_destroy_ktables(&tableq, 0);
@@ -1499,6 +1541,10 @@ pfr_insert_ktable(struct pfr_ktable *kt)
{
RB_INSERT(pfr_ktablehead, &pfr_ktables, kt);
pfr_ktable_cnt++;
+ if (kt->pfrkt_root != NULL)
+ if (!kt->pfrkt_root->pfrkt_refcnt[PFR_REFCNT_ANCHOR]++)
+ pfr_setflags_ktable(kt->pfrkt_root,
+ kt->pfrkt_root->pfrkt_flags|PFR_TFLAG_REFDANCHOR);
}
void
@@ -1522,6 +1568,11 @@ pfr_setflags_ktable(struct pfr_ktable *kt, int newf)
newf &= ~PFR_TFLAG_USRMASK;
if (!(newf & PFR_TFLAG_SETMASK)) {
RB_REMOVE(pfr_ktablehead, &pfr_ktables, kt);
+ if (kt->pfrkt_root != NULL)
+ if (!--kt->pfrkt_root->pfrkt_refcnt[PFR_REFCNT_ANCHOR])
+ pfr_setflags_ktable(kt->pfrkt_root,
+ kt->pfrkt_root->pfrkt_flags &
+ ~PFR_TFLAG_REFDANCHOR);
pfr_destroy_ktable(kt, 1);
pfr_ktable_cnt--;
return;
@@ -1620,7 +1671,15 @@ pfr_destroy_ktable(struct pfr_ktable *kt, int flushaddr)
int
pfr_ktable_compare(struct pfr_ktable *p, struct pfr_ktable *q)
{
- return (strncmp(p->pfrkt_name, q->pfrkt_name, PF_TABLE_NAME_SIZE));
+ int d;
+
+ if ((d = strncmp(p->pfrkt_name, q->pfrkt_name, PF_TABLE_NAME_SIZE)))
+ return (d);
+ if ((d = strncmp(p->pfrkt_anchor, q->pfrkt_anchor,
+ PF_ANCHOR_NAME_SIZE)))
+ return (d);
+ return strncmp(p->pfrkt_ruleset, q->pfrkt_ruleset,
+ PF_RULESET_NAME_SIZE);
}
struct pfr_ktable *
@@ -1636,6 +1695,11 @@ pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
struct pfr_kentry *ke = NULL;
int match;
+ if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
+ kt = kt->pfrkt_root;
+ if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ return 0;
+
switch (af) {
case AF_INET:
pfr_sin.sin_addr.s_addr = a->addr32[0];
@@ -1664,6 +1728,11 @@ pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
{
struct pfr_kentry *ke = NULL;
+ if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
+ kt = kt->pfrkt_root;
+ if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ return;
+
switch (af) {
case AF_INET:
pfr_sin.sin_addr.s_addr = a->addr32[0];
@@ -1692,18 +1761,37 @@ pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
}
struct pfr_ktable *
-pfr_attach_table(char *name)
+pfr_attach_table(struct pf_ruleset *rs, char *name)
{
- struct pfr_ktable *kt;
+ struct pfr_ktable *kt, *rt;
struct pfr_table tbl;
+ struct pf_anchor *ac = rs->anchor;
bzero(&tbl, sizeof(tbl));
strlcpy(tbl.pfrt_name, name, sizeof(tbl.pfrt_name));
+ if (ac != NULL) {
+ strlcpy(tbl.pfrt_anchor, ac->name, sizeof(tbl.pfrt_anchor));
+ strlcpy(tbl.pfrt_ruleset, rs->name, sizeof(tbl.pfrt_ruleset));
+ }
kt = pfr_lookup_table(&tbl);
if (kt == NULL) {
kt = pfr_create_ktable(&tbl, time.tv_sec);
if (kt == NULL)
- return NULL;
+ return (NULL);
+ if (ac != NULL) {
+ bzero(tbl.pfrt_anchor, sizeof(tbl.pfrt_anchor));
+ bzero(tbl.pfrt_ruleset, sizeof(tbl.pfrt_ruleset));
+ rt = pfr_lookup_table(&tbl);
+ if (rt == NULL) {
+ rt = pfr_create_ktable(&tbl, 0);
+ if (rt == NULL) {
+ pfr_destroy_ktable(kt, 0);
+ return (NULL);
+ }
+ pfr_insert_ktable(rt);
+ }
+ kt->pfrkt_root = rt;
+ }
pfr_insert_ktable(kt);
}
if (!kt->pfrkt_refcnt[PFR_REFCNT_RULE]++)
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 3b537fbfee1..8bbb3ca529f 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.141 2003/04/27 16:02:08 cedric Exp $ */
+/* $OpenBSD: pfvar.h,v 1.142 2003/04/30 12:30:27 cedric Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -558,10 +558,13 @@ struct pfr_ktable {
struct radix_node_head *pfrkt_ip4;
struct radix_node_head *pfrkt_ip6;
struct pfr_ktable *pfrkt_shadow;
+ struct pfr_ktable *pfrkt_root;
int pfrkt_nflags;
};
#define pfrkt_t pfrkt_ts.pfrts_t
#define pfrkt_name pfrkt_t.pfrt_name
+#define pfrkt_anchor pfrkt_t.pfrt_anchor
+#define pfrkt_ruleset pfrkt_t.pfrt_ruleset
#define pfrkt_flags pfrkt_t.pfrt_flags
#define pfrkt_cnt pfrkt_ts.pfrts_cnt
#define pfrkt_refcnt pfrkt_ts.pfrts_refcnt
@@ -960,7 +963,8 @@ extern struct pf_altqqueue *pf_altqs_active;
extern struct pf_altqqueue *pf_altqs_inactive;
extern struct pf_poolqueue *pf_pools_active;
extern struct pf_poolqueue *pf_pools_inactive;
-extern int pf_tbladdr_setup(struct pf_addr_wrap *);
+extern int pf_tbladdr_setup(struct pf_ruleset *,
+ struct pf_addr_wrap *);
extern void pf_tbladdr_remove(struct pf_addr_wrap *);
extern void pf_tbladdr_copyout(struct pf_addr_wrap *);
extern int pf_dynaddr_setup(struct pf_addr_wrap *,
@@ -1012,7 +1016,7 @@ int pfr_match_addr(struct pfr_ktable *, struct pf_addr *, sa_family_t);
void pfr_update_stats(struct pfr_ktable *, struct pf_addr *, sa_family_t,
u_int64_t, int, int, int);
struct pfr_ktable *
- pfr_attach_table(char *);
+ pfr_attach_table(struct pf_ruleset *, char *);
void pfr_detach_table(struct pfr_ktable *);
int pfr_clr_tables(int *, int);
int pfr_add_tables(struct pfr_table *, int, int *, int);
diff --git a/usr.sbin/authpf/authpf.c b/usr.sbin/authpf/authpf.c
index 2f97980d009..056bf327b61 100644
--- a/usr.sbin/authpf/authpf.c
+++ b/usr.sbin/authpf/authpf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authpf.c,v 1.54 2003/04/20 02:37:00 beck Exp $ */
+/* $OpenBSD: authpf.c,v 1.55 2003/04/30 12:30:27 cedric Exp $ */
/*
* Copyright (C) 1998 - 2002 Bob Beck (beck@openbsd.org).
@@ -859,7 +859,8 @@ pfctl_append_file(char *file)
}
void
-pfctl_define_table(char *name, int flags, int addrs, int noaction)
+pfctl_define_table(char *name, int flags, int addrs, int noaction,
+ const char *anchor, const char *ruleset)
{
fprintf(stderr, "table definitions not yet supported in authpf\n");
}