diff options
author | Cedric Berger <cedric@cvs.openbsd.org> | 2003-04-30 12:30:28 +0000 |
---|---|---|
committer | Cedric Berger <cedric@cvs.openbsd.org> | 2003-04-30 12:30:28 +0000 |
commit | ba4eec495765b9095d5d66d12e933cae99fbfba5 (patch) | |
tree | 8242fa1f0a74e8277324734a9b5d014dbf6d7771 | |
parent | d08d75cff317e4ebbe3d8d3f9ebdd6daee64a27f (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.y | 5 | ||||
-rw-r--r-- | sbin/pfctl/pfctl.c | 40 | ||||
-rw-r--r-- | sbin/pfctl/pfctl.h | 9 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.h | 6 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_table.c | 49 | ||||
-rw-r--r-- | sys/net/pf.c | 8 | ||||
-rw-r--r-- | sys/net/pf_ioctl.c | 10 | ||||
-rw-r--r-- | sys/net/pf_table.c | 110 | ||||
-rw-r--r-- | sys/net/pfvar.h | 10 | ||||
-rw-r--r-- | usr.sbin/authpf/authpf.c | 5 |
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"); } |