diff options
-rw-r--r-- | sbin/pfctl/pfctl.c | 15 | ||||
-rw-r--r-- | sbin/pfctl/pfctl.h | 6 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.h | 6 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_radix.c | 11 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_table.c | 4 | ||||
-rw-r--r-- | sys/net/pf_ioctl.c | 12 | ||||
-rw-r--r-- | sys/net/pf_table.c | 44 | ||||
-rw-r--r-- | sys/net/pfvar.h | 12 |
8 files changed, 68 insertions, 42 deletions
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index c9e35ec956a..15eb3840683 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.c,v 1.182 2003/07/18 06:30:07 cedric Exp $ */ +/* $OpenBSD: pfctl.c,v 1.183 2003/07/31 22:25:54 cedric Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -921,15 +921,22 @@ pfctl_rules(int dev, char *filename, int opts, char *anchorname, struct pfioc_rule pr[PF_RULESET_MAX]; struct pfioc_altq pa; struct pfctl pf; + struct pfr_table trs; int i; memset(&pa, 0, sizeof(pa)); memset(&pf, 0, sizeof(pf)); + memset(&trs, 0, sizeof(trs)); for (i = 0; i < PF_RULESET_MAX; i++) { memset(&pr[i], 0, sizeof(pr[i])); memcpy(pr[i].anchor, anchorname, sizeof(pr[i].anchor)); memcpy(pr[i].ruleset, rulesetname, sizeof(pr[i].ruleset)); } + if (strlcpy(trs.pfrt_anchor, anchorname, + sizeof(trs.pfrt_anchor)) >= sizeof(trs.pfrt_anchor) || + strlcpy(trs.pfrt_ruleset, rulesetname, + sizeof(trs.pfrt_ruleset)) >= sizeof(trs.pfrt_ruleset)) + ERRX("pfctl_rules: strlcpy"); if (strcmp(filename, "-") == 0) { fin = stdin; infile = "stdin"; @@ -965,7 +972,7 @@ pfctl_rules(int dev, char *filename, int opts, char *anchorname, ERR("DIOCBEGINRULES"); } if (loadopt & PFCTL_FLAG_TABLE) { - if (pfr_ina_begin(&pf.tticket, NULL, 0) != 0) + if (pfr_ina_begin(&trs, &pf.tticket, NULL, 0) != 0) ERR("begin table"); } } @@ -1014,7 +1021,7 @@ pfctl_rules(int dev, char *filename, int opts, char *anchorname, ERR("DIOCCOMMITRULES FILTER"); } if (loadopt & PFCTL_FLAG_TABLE) { - if (pfr_ina_commit(pf.tticket, NULL, NULL, 0)) + if (pfr_ina_commit(&trs, pf.tticket, NULL, NULL, 0)) ERR("commit table"); pf.tdirty = 0; } @@ -1031,7 +1038,7 @@ pfctl_rules(int dev, char *filename, int opts, char *anchorname, _error: if (pf.tdirty) /* cleanup kernel leftover */ - pfr_ina_begin(NULL, NULL, 0); + pfr_ina_begin(&trs, NULL, NULL, 0); exit(1); #undef ERR diff --git a/sbin/pfctl/pfctl.h b/sbin/pfctl/pfctl.h index ad6e0b85aec..750f80167c8 100644 --- a/sbin/pfctl/pfctl.h +++ b/sbin/pfctl/pfctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.h,v 1.23 2003/07/04 11:05:44 henning Exp $ */ +/* $OpenBSD: pfctl.h,v 1.24 2003/07/31 22:25:54 cedric Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -63,8 +63,8 @@ int pfr_get_astats(struct pfr_table *, struct pfr_astats *, int *, int); int pfr_clr_astats(struct pfr_table *, struct pfr_addr *, int, int *, int); int pfr_tst_addrs(struct pfr_table *, struct pfr_addr *, int, int *, int); int pfr_set_tflags(struct pfr_table *, int, int, int, int *, int *, int); -int pfr_ina_begin(int *, int *, int); -int pfr_ina_commit(int, int *, int *, int); +int pfr_ina_begin(struct pfr_table *, int *, int *, int); +int pfr_ina_commit(struct pfr_table *, int, int *, int *, int); int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *, int *, int, int); void pfr_buf_clear(struct pfr_buffer *); diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h index 1079d5925c4..b8331a5b725 100644 --- a/sbin/pfctl/pfctl_parser.h +++ b/sbin/pfctl/pfctl_parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.h,v 1.65 2003/07/18 06:30:07 cedric Exp $ */ +/* $OpenBSD: pfctl_parser.h,v 1.66 2003/07/31 22:25:54 cedric Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -60,7 +60,7 @@ struct pfctl { int dev; int opts; int loadopt; - int tticket; /* table ticket */ + u_int32_t tticket; /* table ticket */ int tdirty; /* kernel dirty */ u_int32_t rule_nr; struct pfioc_pooladdr paddr; @@ -166,7 +166,7 @@ void print_queue(const struct pf_altq *, unsigned, struct node_queue_bw *, int, struct node_queue_opt *); int pfctl_define_table(char *, int, int, const char *, const char *, - struct pfr_buffer *, int); + struct pfr_buffer *, u_int32_t); struct icmptypeent { const char *name; diff --git a/sbin/pfctl/pfctl_radix.c b/sbin/pfctl/pfctl_radix.c index 1ff36e3e643..a07285f49fd 100644 --- a/sbin/pfctl/pfctl_radix.c +++ b/sbin/pfctl/pfctl_radix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_radix.c,v 1.18 2003/07/04 11:05:44 henning Exp $ */ +/* $OpenBSD: pfctl_radix.c,v 1.19 2003/07/31 22:25:54 cedric Exp $ */ /* * Copyright (c) 2002 Cedric Berger @@ -391,11 +391,13 @@ pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, } int -pfr_ina_begin(int *ticket, int *ndel, int flags) +pfr_ina_begin(struct pfr_table *trs, int *ticket, int *ndel, int flags) { struct pfioc_table io; bzero(&io, sizeof io); + if (trs != NULL) + io.pfrio_table = *trs; io.pfrio_flags = flags; if (ioctl(dev, DIOCRINABEGIN, &io)) return (-1); @@ -407,11 +409,14 @@ pfr_ina_begin(int *ticket, int *ndel, int flags) } int -pfr_ina_commit(int ticket, int *nadd, int *nchange, int flags) +pfr_ina_commit(struct pfr_table *trs, int ticket, int *nadd, int *nchange, + int flags) { struct pfioc_table io; bzero(&io, sizeof io); + if (trs != NULL) + io.pfrio_table = *trs; io.pfrio_flags = flags; io.pfrio_ticket = ticket; if (ioctl(dev, DIOCRINACOMMIT, &io)) diff --git a/sbin/pfctl/pfctl_table.c b/sbin/pfctl/pfctl_table.c index c0500379872..01af4423eef 100644 --- a/sbin/pfctl/pfctl_table.c +++ b/sbin/pfctl/pfctl_table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_table.c,v 1.48 2003/07/11 08:29:34 cedric Exp $ */ +/* $OpenBSD: pfctl_table.c,v 1.49 2003/07/31 22:25:54 cedric Exp $ */ /* * Copyright (c) 2002 Cedric Berger @@ -443,7 +443,7 @@ radix_perror(void) int pfctl_define_table(char *name, int flags, int addrs, const char *anchor, - const char *ruleset, struct pfr_buffer *ab, int ticket) + const char *ruleset, struct pfr_buffer *ab, u_int32_t ticket) { struct pfr_table tbl; diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c index 2b38f3152b2..83d32550c16 100644 --- a/sys/net/pf_ioctl.c +++ b/sys/net/pf_ioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_ioctl.c,v 1.76 2003/07/19 13:08:58 cedric Exp $ */ +/* $OpenBSD: pf_ioctl.c,v 1.77 2003/07/31 22:25:54 cedric Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -348,7 +348,7 @@ pf_remove_if_empty_ruleset(struct pf_ruleset *ruleset) struct pf_anchor *anchor; int i; - if (ruleset == NULL || ruleset->anchor == NULL || ruleset->tables > 0) + 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) || @@ -2077,8 +2077,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = ENODEV; break; } - error = pfr_ina_begin(&io->pfrio_ticket, &io->pfrio_ndel, - io->pfrio_flags); + error = pfr_ina_begin(&io->pfrio_table, &io->pfrio_ticket, + &io->pfrio_ndel, io->pfrio_flags); break; } @@ -2089,8 +2089,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = ENODEV; break; } - error = pfr_ina_commit(io->pfrio_ticket, &io->pfrio_nadd, - &io->pfrio_nchange, io->pfrio_flags); + error = pfr_ina_commit(&io->pfrio_table, io->pfrio_ticket, + &io->pfrio_nadd, &io->pfrio_nchange, io->pfrio_flags); break; } diff --git a/sys/net/pf_table.c b/sys/net/pf_table.c index 2d58ad836c7..3844d701413 100644 --- a/sys/net/pf_table.c +++ b/sys/net/pf_table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_table.c,v 1.38 2003/06/24 13:52:50 henning Exp $ */ +/* $OpenBSD: pf_table.c,v 1.39 2003/07/31 22:25:55 cedric Exp $ */ /* * Copyright (c) 2002 Cedric Berger @@ -158,7 +158,6 @@ RB_GENERATE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare); struct pfr_ktablehead pfr_ktables; struct pfr_table pfr_nulltable; int pfr_ktable_cnt; -int pfr_ticket; void pfr_initialize(void) @@ -172,8 +171,6 @@ pfr_initialize(void) pfr_sin.sin_family = AF_INET; pfr_sin6.sin6_len = sizeof(pfr_sin6); pfr_sin6.sin6_family = AF_INET6; - - pfr_ticket = 100; } int @@ -1310,48 +1307,58 @@ _skip: } int -pfr_ina_begin(int *ticket, int *ndel, int flags) +pfr_ina_begin(struct pfr_table *trs, u_int32_t *ticket, int *ndel, int flags) { struct pfr_ktableworkq workq; struct pfr_ktable *p; + struct pf_ruleset *rs; int xdel = 0; ACCEPT_FLAGS(PFR_FLAG_DUMMY); + rs = pf_find_or_create_ruleset(trs->pfrt_anchor, trs->pfrt_ruleset); + if (rs == NULL) + return (ENOMEM); SLIST_INIT(&workq); RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) { - if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE)) + if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) || + pfr_skip_table(trs, p, 0)) continue; p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_INACTIVE; SLIST_INSERT_HEAD(&workq, p, pfrkt_workq); xdel++; } - if (!(flags & PFR_FLAG_DUMMY)) + if (!(flags & PFR_FLAG_DUMMY)) { pfr_setflags_ktables(&workq); + if (ticket != NULL) + *ticket = ++rs->tticket; + rs->topen = 1; + } else + pf_remove_if_empty_ruleset(rs); if (ndel != NULL) *ndel = xdel; - if (ticket != NULL && !(flags & PFR_FLAG_DUMMY)) - *ticket = ++pfr_ticket; return (0); } int pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size, - int *nadd, int *naddr, int ticket, int flags) + int *nadd, int *naddr, u_int32_t ticket, int flags) { struct pfr_ktableworkq tableq; struct pfr_kentryworkq addrq; struct pfr_ktable *kt, *rt, *shadow, key; struct pfr_kentry *p; struct pfr_addr ad; + struct pf_ruleset *rs; int i, rv, xadd = 0, xaddr = 0; ACCEPT_FLAGS(PFR_FLAG_DUMMY|PFR_FLAG_ADDRSTOO); - if (ticket != pfr_ticket) - return (EBUSY); if (size && !(flags & PFR_FLAG_ADDRSTOO)) return (EINVAL); if (pfr_validate_table(tbl, PFR_TFLAG_USRMASK)) return (EINVAL); + rs = pf_find_ruleset(tbl->pfrt_anchor, tbl->pfrt_ruleset); + if (rs == NULL || !rs->topen || ticket != rs->tticket) + return (EBUSY); tbl->pfrt_flags |= PFR_TFLAG_INACTIVE; SLIST_INIT(&tableq); kt = RB_FIND(pfr_ktablehead, &pfr_ktables, (struct pfr_ktable *)tbl); @@ -1432,21 +1439,24 @@ _bad: } int -pfr_ina_commit(int ticket, int *nadd, int *nchange, int flags) +pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd, + int *nchange, int flags) { struct pfr_ktable *p; struct pfr_ktableworkq workq; + struct pf_ruleset *rs; int s, xadd = 0, xchange = 0; long tzero = time.tv_sec; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY); - if (ticket != pfr_ticket) + rs = pf_find_ruleset(trs->pfrt_anchor, trs->pfrt_ruleset); + if (rs == NULL || !rs->topen || ticket != rs->tticket) return (EBUSY); - pfr_ticket++; SLIST_INIT(&workq); RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) { - if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE)) + if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) || + pfr_skip_table(trs, p, 0)) continue; SLIST_INSERT_HEAD(&workq, p, pfrkt_workq); if (p->pfrkt_flags & PFR_TFLAG_ACTIVE) @@ -1462,6 +1472,8 @@ pfr_ina_commit(int ticket, int *nadd, int *nchange, int flags) pfr_commit_ktable(p, tzero); if (flags & PFR_FLAG_ATOMIC) splx(s); + rs->topen = 0; + pf_remove_if_empty_ruleset(rs); } if (nadd != NULL) *nadd = xadd; diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 4c247953a71..0e15f54f07c 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.163 2003/07/19 13:08:58 cedric Exp $ */ +/* $OpenBSD: pfvar.h,v 1.164 2003/07/31 22:25:55 cedric Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -495,7 +495,9 @@ struct pf_ruleset { } active, inactive; } rules[PF_RULESET_MAX]; struct pf_anchor *anchor; + u_int32_t tticket; int tables; + int topen; }; TAILQ_HEAD(pf_rulesetqueue, pf_ruleset); @@ -915,7 +917,7 @@ struct pfioc_table { int pfrio_ndel; int pfrio_nchange; int pfrio_flags; - int pfrio_ticket; + u_int32_t pfrio_ticket; }; #define pfrio_exists pfrio_nadd #define pfrio_nzero pfrio_nadd @@ -1107,10 +1109,10 @@ int pfr_clr_astats(struct pfr_table *, struct pfr_addr *, int, int *, int); int pfr_tst_addrs(struct pfr_table *, struct pfr_addr *, int, int *, int); -int pfr_ina_begin(int *, int *, int); -int pfr_ina_commit(int, int *, int *, int); +int pfr_ina_begin(struct pfr_table *, u_int32_t *, int *, int); +int pfr_ina_commit(struct pfr_table *, u_int32_t, int *, int *, int); int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *, - int *, int, int); + int *, u_int32_t, int); u_int16_t pf_tagname2tag(char *); void pf_tag2tagname(u_int16_t, char *); |