diff options
-rw-r--r-- | sbin/pfctl/parse.y | 22 | ||||
-rw-r--r-- | sbin/pfctl/pf_print_state.c | 13 | ||||
-rw-r--r-- | sbin/pfctl/pfctl.h | 4 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_radix.c | 45 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_table.c | 26 | ||||
-rw-r--r-- | sys/net/pf.c | 142 | ||||
-rw-r--r-- | sys/net/pf_ioctl.c | 43 | ||||
-rw-r--r-- | sys/net/pf_norm.c | 30 | ||||
-rw-r--r-- | sys/net/pf_table.c | 223 | ||||
-rw-r--r-- | sys/net/pfvar.h | 59 |
10 files changed, 229 insertions, 378 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index c3b55028a77..1c2edb43550 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.279 2003/01/06 11:30:10 mcbride Exp $ */ +/* $OpenBSD: parse.y,v 1.280 2003/01/07 00:21:07 dhartmei Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -1479,23 +1479,19 @@ xhost : '!' host { host : address | STRING '/' number { $$ = host($1, $3); } | PORTUNARY STRING PORTUNARY { - struct pfr_table tbl; - int exists = 0; - if ($1 != PF_OP_LT || $3 != PF_OP_GT) YYERROR; + if (strlen($2) >= PF_TABLE_NAME_SIZE) { + yyerror("table name '%s' too long"); + YYERROR; + } $$ = calloc(1, sizeof(struct node_host)); if ($$ == NULL) err(1, "host: calloc"); - $$->af = 0; - bzero(&tbl, sizeof(tbl)); - strlcpy(tbl.pfrt_name, $2, sizeof(tbl.pfrt_name)); - if (pfr_wrap_table(&tbl, &$$->addr, &exists, 0)) - err(1, "pfr_wrap_table"); - if (!exists) - fprintf(stderr, "warning: %s " - "table is not currently defined\n", - tbl.pfrt_name); + $$->addr.type = PF_ADDR_TABLE; + strlcpy($$->addr.v.tblname, $2, PF_TABLE_NAME_SIZE); + $$->next = NULL; + $$->tail = $$; } ; diff --git a/sbin/pfctl/pf_print_state.c b/sbin/pfctl/pf_print_state.c index bafcc1166b5..27fb9b19cb2 100644 --- a/sbin/pfctl/pf_print_state.c +++ b/sbin/pfctl/pf_print_state.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_print_state.c,v 1.17 2003/01/05 22:14:23 dhartmei Exp $ */ +/* $OpenBSD: pf_print_state.c,v 1.18 2003/01/07 00:21:08 dhartmei Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -62,17 +62,10 @@ print_addr(struct pf_addr_wrap *addr, sa_family_t af) { char buf[48]; - if (addr->v.a.mask.addr32[0] == PF_TABLE_MASK) { - struct pfr_table tbl = { "?" }; - - if (pfr_unwrap_table(&tbl, addr, 0)) - printf("<0x%08X>", addr->v.a.addr.addr32[0]); - else - printf("<%s>", tbl.pfrt_name); - return; - } if (addr->type == PF_ADDR_DYNIFTL) printf("(%s)", addr->v.ifname); + else if (addr->type == PF_ADDR_TABLE) + printf("<%s>", addr->v.tblname); else { if (inet_ntop(af, &addr->v.a.addr, buf, sizeof(buf)) == NULL) printf("?"); diff --git a/sbin/pfctl/pfctl.h b/sbin/pfctl/pfctl.h index 5346ab1a949..8111f407405 100644 --- a/sbin/pfctl/pfctl.h +++ b/sbin/pfctl/pfctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.h,v 1.2 2003/01/04 22:42:14 henning Exp $ */ +/* $OpenBSD: pfctl.h,v 1.3 2003/01/07 00:21:08 dhartmei Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -50,8 +50,6 @@ int pfr_get_addrs(struct pfr_table *, struct pfr_addr *, int *, int); 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_wrap_table(struct pfr_table *, struct pf_addr_wrap *, int *, int); -int pfr_unwrap_table(struct pfr_table *, struct pf_addr_wrap *, int); int pfctl_clear_tables(int); int pfctl_show_tables(int); int pfctl_command_tables(int, char *[], char *, char *, char *, int); diff --git a/sbin/pfctl/pfctl_radix.c b/sbin/pfctl/pfctl_radix.c index 08de265eb5d..d5fdb825dac 100644 --- a/sbin/pfctl/pfctl_radix.c +++ b/sbin/pfctl/pfctl_radix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_radix.c,v 1.6 2003/01/04 00:01:34 deraadt Exp $ */ +/* $OpenBSD: pfctl_radix.c,v 1.7 2003/01/07 00:21:08 dhartmei Exp $ */ /* * Copyright (c) 2002 Cedric Berger @@ -337,46 +337,3 @@ pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, *nmatch = io.pfrio_nmatch; return (0); } - -int -pfr_wrap_table(struct pfr_table *tbl, struct pf_addr_wrap *wrap, - int *exists, int flags) -{ - struct pfioc_table io; - - if (tbl == NULL) { - errno = EINVAL; - return -1; - } - bzero(&io, sizeof io); - io.pfrio_flags = flags; - io.pfrio_table = *tbl; - io.pfrio_buffer = wrap; - io.pfrio_size = wrap ? 1 : 0; - io.pfrio_exists = exists ? 1 : 0; - if (ioctl(dev, DIOCRWRAPTABLE, &io)) - return (-1); - if (exists) - *exists = io.pfrio_exists; - return (0); -} - -int -pfr_unwrap_table(struct pfr_table *tbl, struct pf_addr_wrap *wrap, int flags) -{ - struct pfioc_table io; - - if (wrap == NULL) { - errno = EINVAL; - return -1; - } - bzero(&io, sizeof io); - io.pfrio_flags = flags; - io.pfrio_buffer = wrap; - io.pfrio_size = 1; - if (ioctl(dev, DIOCRUNWRTABLE, &io)) - return (-1); - if (tbl != NULL) - *tbl = io.pfrio_table; - return (0); -} diff --git a/sbin/pfctl/pfctl_table.c b/sbin/pfctl/pfctl_table.c index 7db623f3771..9957718b181 100644 --- a/sbin/pfctl/pfctl_table.c +++ b/sbin/pfctl/pfctl_table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_table.c,v 1.11 2003/01/04 00:01:34 deraadt Exp $ */ +/* $OpenBSD: pfctl_table.c,v 1.12 2003/01/07 00:21:08 dhartmei Exp $ */ /* * Copyright (c) 2002 Cedric Berger @@ -60,8 +60,8 @@ extern void usage(void); static int pfctl_table(int, char *[], char *, char *, char *, int); static void grow_buffer(int, int); -static void print_table(struct pfr_table *); -static void print_tstats(struct pfr_tstats *); +static void print_table(struct pfr_table *, int); +static void print_tstats(struct pfr_tstats *, int); static void load_addr(int, char *[], char *, int); static int next_token(char [], FILE *); static void append_addr(char *, int); @@ -181,9 +181,11 @@ pfctl_table(int argc, char *argv[], char *tname, char *command, } for (i = 0; i < size; i++) if (opts & PF_OPT_VERBOSE) - print_tstats(buffer.tstats+i); + print_tstats(buffer.tstats+i, + opts & PF_OPT_VERBOSE2); else - print_table(buffer.tables+i); + print_table(buffer.tables+i, + opts & PF_OPT_VERBOSE2); } else if (!strcmp(*p, "create")) { if (argc || file != NULL) usage(); @@ -358,19 +360,25 @@ grow_buffer(int bs, int minsize) } void -print_table(struct pfr_table *ta) +print_table(struct pfr_table *ta, int all) { - printf("%s\n", ta->pfrt_name); + if (!all && !(ta->pfrt_flags & PFR_TFLAG_ACTIVE)) + return; + printf(" %c%s\n", (ta->pfrt_flags & PFR_TFLAG_PERSIST)?'+':' ', + ta->pfrt_name); } void -print_tstats(struct pfr_tstats *ts) +print_tstats(struct pfr_tstats *ts, int all) { time_t time = ts->pfrts_tzero; int dir, op; - printf("%s\n", ts->pfrts_name); + if (!all && !(ts->pfrts_flags & PFR_TFLAG_ACTIVE)) + return; + print_table(&ts->pfrts_t, all); printf("\tAddresses: %d\n", ts->pfrts_cnt); + printf("\tReferences: %d\n", ts->pfrts_refcnt); printf("\tCleared: %s", ctime(&time)); printf("\tEvaluations: [ NoMatch: %-18llu Match: %-18llu ]\n", ts->pfrts_nomatch, ts->pfrts_match); diff --git a/sys/net/pf.c b/sys/net/pf.c index fa9eeaf1a71..7bdc9617f99 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.299 2003/01/06 10:08:36 deraadt Exp $ */ +/* $OpenBSD: pf.c,v 1.300 2003/01/07 00:21:07 dhartmei Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -150,6 +150,8 @@ 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 *); @@ -508,6 +510,25 @@ pf_purge_expired_states(void) } int +pf_tbladdr_setup(struct pf_addr_wrap *aw) +{ + if (aw->type != PF_ADDR_TABLE) + return (0); + if ((aw->p.tbl = pfr_attach_table(aw->v.tblname)) == NULL) + return (1); + return (0); +} + +void +pf_tbladdr_remove(struct pf_addr_wrap *aw) +{ + if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL) + return; + pfr_detach_table(aw->p.tbl); + aw->p.tbl = NULL; +} + +int pf_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af) { if (aw->type != PF_ADDR_DYNIFTL) @@ -751,6 +772,8 @@ pf_calc_skip_steps(struct pf_rulequeue *rules) PF_SET_SKIP_STEPS(PF_SKIP_PROTO); if (cur->src.addr.type == PF_ADDR_DYNIFTL || prev->src.addr.type == PF_ADDR_DYNIFTL || + cur->src.addr.type == PF_ADDR_TABLE || + prev->src.addr.type == PF_ADDR_TABLE || cur->src.not != prev->src.not || (cur->src.addr.type == PF_ADDR_NOROUTE) != (prev->src.addr.type == PF_ADDR_NOROUTE) || @@ -763,6 +786,8 @@ pf_calc_skip_steps(struct pf_rulequeue *rules) PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT); if (cur->dst.addr.type == PF_ADDR_DYNIFTL || prev->dst.addr.type == PF_ADDR_DYNIFTL || + cur->dst.addr.type == PF_ADDR_TABLE || + prev->dst.addr.type == PF_ADDR_TABLE || cur->dst.not != prev->dst.not || (cur->dst.addr.type == PF_ADDR_NOROUTE) != (prev->dst.addr.type == PF_ADDR_NOROUTE) || @@ -1168,9 +1193,6 @@ pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m, { int match = 0; - if (m->addr32[0] == PF_TABLE_MASK) - return (pfr_match_addr(a, m, b, af) != n); - switch (af) { #ifdef INET case AF_INET: @@ -1411,6 +1433,9 @@ pf_map_addr(u_int8_t af, struct pf_pool *rpool, struct pf_addr *saddr, struct pf_addr *raddr = &rpool->cur->addr.addr.v.a.addr; struct pf_addr *rmask = &rpool->cur->addr.addr.v.a.mask; + if (cur->addr.addr.type == PF_ADDR_NOROUTE || + cur->addr.addr.type == PF_ADDR_TABLE) + return (1); if (cur->addr.addr.type == PF_ADDR_DYNIFTL && cur->addr.addr.p.dyn->undefined) return (1); @@ -1607,17 +1632,14 @@ pf_match_translation(int direction, struct ifnet *ifp, u_int8_t proto, r = r->skip[PF_SKIP_AF].ptr; else if (r->proto && r->proto != proto) r = r->skip[PF_SKIP_PROTO].ptr; - else if (src != NULL && !PF_AZERO(&src->addr.v.a.mask, af) && - !PF_MATCHA(src->not, - &src->addr.v.a.addr, &src->addr.v.a.mask, saddr, af)) + else if (src != NULL && + PF_MISMATCHAW(&src->addr, saddr, af, src->not)) r = r->skip[PF_SKIP_SRC_ADDR].ptr; else if (src != NULL && src->port_op && !pf_match_port(src->port_op, src->port[0], src->port[1], sport)) r = r->skip[PF_SKIP_SRC_PORT].ptr; - else if (!PF_AZERO(&r->dst.addr.v.a.mask, af) && - !PF_MATCHA(r->dst.not, - &r->dst.addr.v.a.addr, &r->dst.addr.v.a.mask, daddr, af)) + else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not)) r = r->skip[PF_SKIP_DST_ADDR].ptr; else if (r->dst.port_op && !pf_match_port(r->dst.port_op, r->dst.port[0], r->dst.port[1], dport)) @@ -1836,24 +1858,12 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp, r = r->skip[PF_SKIP_AF].ptr; else if (r->proto && r->proto != IPPROTO_TCP) r = r->skip[PF_SKIP_PROTO].ptr; - else if (r->src.addr.type == PF_ADDR_NOROUTE && - pf_routable(saddr, af)) - r = TAILQ_NEXT(r, entries); - else if (r->src.addr.type != PF_ADDR_NOROUTE && - !PF_AZERO(&r->src.addr.v.a.mask, af) && - !PF_MATCHA(r->src.not, &r->src.addr.v.a.addr, - &r->src.addr.v.a.mask, saddr, af)) + else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not)) r = r->skip[PF_SKIP_SRC_ADDR].ptr; else if (r->src.port_op && !pf_match_port(r->src.port_op, r->src.port[0], r->src.port[1], th->th_sport)) r = r->skip[PF_SKIP_SRC_PORT].ptr; - else if (r->dst.addr.type == PF_ADDR_NOROUTE && - pf_routable(daddr, af)) - r = TAILQ_NEXT(r, entries); - else if (r->dst.addr.type != PF_ADDR_NOROUTE && - !PF_AZERO(&r->dst.addr.v.a.mask, af) && - !PF_MATCHA(r->dst.not, &r->dst.addr.v.a.addr, - &r->dst.addr.v.a.mask, daddr, af)) + else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not)) r = r->skip[PF_SKIP_DST_ADDR].ptr; else if (r->dst.port_op && !pf_match_port(r->dst.port_op, r->dst.port[0], r->dst.port[1], th->th_dport)) @@ -2093,24 +2103,12 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp, r = r->skip[PF_SKIP_AF].ptr; else if (r->proto && r->proto != IPPROTO_UDP) r = r->skip[PF_SKIP_PROTO].ptr; - else if (r->src.addr.type == PF_ADDR_NOROUTE && - pf_routable(saddr, af)) - r = TAILQ_NEXT(r, entries); - else if (r->src.addr.type != PF_ADDR_NOROUTE && - !PF_AZERO(&r->src.addr.v.a.mask, af) && - !PF_MATCHA(r->src.not, &r->src.addr.v.a.addr, - &r->src.addr.v.a.mask, saddr, af)) + else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not)) r = r->skip[PF_SKIP_SRC_ADDR].ptr; else if (r->src.port_op && !pf_match_port(r->src.port_op, r->src.port[0], r->src.port[1], uh->uh_sport)) r = r->skip[PF_SKIP_SRC_PORT].ptr; - else if (r->dst.addr.type == PF_ADDR_NOROUTE && - pf_routable(daddr, af)) - r = TAILQ_NEXT(r, entries); - else if (r->dst.addr.type != PF_ADDR_NOROUTE && - !PF_AZERO(&r->dst.addr.v.a.mask, af) && - !PF_MATCHA(r->dst.not, &r->dst.addr.v.a.addr, - &r->dst.addr.v.a.mask, daddr, af)) + else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not)) r = r->skip[PF_SKIP_DST_ADDR].ptr; else if (r->dst.port_op && !pf_match_port(r->dst.port_op, r->dst.port[0], r->dst.port[1], uh->uh_dport)) @@ -2374,21 +2372,9 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp, r = r->skip[PF_SKIP_AF].ptr; else if (r->proto && r->proto != pd->proto) r = r->skip[PF_SKIP_PROTO].ptr; - else if (r->src.addr.type == PF_ADDR_NOROUTE && - pf_routable(saddr, af)) - r = TAILQ_NEXT(r, entries); - else if (r->src.addr.type != PF_ADDR_NOROUTE && - !PF_AZERO(&r->src.addr.v.a.mask, af) && - !PF_MATCHA(r->src.not, &r->src.addr.v.a.addr, - &r->src.addr.v.a.mask, saddr, af)) + else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not)) r = r->skip[PF_SKIP_SRC_ADDR].ptr; - else if (r->dst.addr.type == PF_ADDR_NOROUTE && - pf_routable(daddr, af)) - r = TAILQ_NEXT(r, entries); - else if (r->dst.addr.type != PF_ADDR_NOROUTE && - !PF_AZERO(&r->dst.addr.v.a.mask, af) && - !PF_MATCHA(r->dst.not, &r->dst.addr.v.a.addr, - &r->dst.addr.v.a.mask, daddr, af)) + else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not)) r = r->skip[PF_SKIP_DST_ADDR].ptr; else if (r->type && r->type != icmptype + 1) r = TAILQ_NEXT(r, entries); @@ -2581,21 +2567,9 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp, r = r->skip[PF_SKIP_AF].ptr; else if (r->proto && r->proto != pd->proto) r = r->skip[PF_SKIP_PROTO].ptr; - else if (r->src.addr.type == PF_ADDR_NOROUTE && - pf_routable(pd->src, af)) - r = TAILQ_NEXT(r, entries); - else if (r->src.addr.type != PF_ADDR_NOROUTE && - !PF_AZERO(&r->src.addr.v.a.mask, af) && - !PF_MATCHA(r->src.not, &r->src.addr.v.a.addr, - &r->src.addr.v.a.mask, pd->src, af)) + else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not)) r = r->skip[PF_SKIP_SRC_ADDR].ptr; - else if (r->dst.addr.type == PF_ADDR_NOROUTE && - pf_routable(pd->dst, af)) - r = TAILQ_NEXT(r, entries); - else if (r->src.addr.type != PF_ADDR_NOROUTE && - !PF_AZERO(&r->dst.addr.v.a.mask, af) && - !PF_MATCHA(r->dst.not, &r->dst.addr.v.a.addr, - &r->dst.addr.v.a.mask, pd->dst, af)) + else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not)) r = r->skip[PF_SKIP_DST_ADDR].ptr; else if (r->tos && !(r->tos & pd->tos)) r = TAILQ_NEXT(r, entries); @@ -2730,21 +2704,9 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct ifnet *ifp, r = r->skip[PF_SKIP_AF].ptr; else if (r->proto && r->proto != pd->proto) r = r->skip[PF_SKIP_PROTO].ptr; - else if (r->src.addr.type == PF_ADDR_NOROUTE && - pf_routable(pd->src, af)) - r = TAILQ_NEXT(r, entries); - else if (r->src.addr.type != PF_ADDR_NOROUTE && - !PF_AZERO(&r->src.addr.v.a.mask, af) && - !PF_MATCHA(r->src.not, &r->src.addr.v.a.addr, - &r->src.addr.v.a.mask, pd->src, af)) + else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not)) r = r->skip[PF_SKIP_SRC_ADDR].ptr; - else if (r->dst.addr.type == PF_ADDR_NOROUTE && - pf_routable(pd->dst, af)) - r = TAILQ_NEXT(r, entries); - else if (r->src.addr.type != PF_ADDR_NOROUTE && - !PF_AZERO(&r->dst.addr.v.a.mask, af) && - !PF_MATCHA(r->dst.not, &r->dst.addr.v.a.addr, - &r->dst.addr.v.a.mask, pd->dst, af)) + else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not)) r = r->skip[PF_SKIP_DST_ADDR].ptr; else if (r->tos && !(r->tos & pd->tos)) r = TAILQ_NEXT(r, entries); @@ -4176,16 +4138,16 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0) } done: - if (r != NULL && r->src.addr.v.a.mask.addr32[0] == PF_TABLE_MASK) - pfr_update_stats(&r->src.addr.v.a.addr, &r->src.addr.v.a.mask, - (r->direction == dir) ? pd.src : pd.dst, - pd.af, pd.tot_len, dir == PF_OUT, - r->action == PF_PASS, r->src.not); - if (r != NULL && r->dst.addr.v.a.mask.addr32[0] == PF_TABLE_MASK) - pfr_update_stats(&r->dst.addr.v.a.addr, &r->dst.addr.v.a.mask, - (r->direction == dir) ? pd.dst : pd.src, - pd.af, pd.tot_len, dir == PF_OUT, - r->action == PF_PASS, r->dst.not); + if (r != NULL && r->src.addr.type == PF_ADDR_TABLE) + pfr_update_stats(r->src.addr.p.tbl, + (r->direction == dir) ? pd.src : pd.dst, pd.af, + pd.tot_len, dir == PF_OUT, r->action == PF_PASS, + r->src.not); + if (r != NULL && r->dst.addr.type == PF_ADDR_TABLE) + pfr_update_stats(r->dst.addr.p.tbl, + (r->direction == dir) ? pd.dst : pd.src, pd.af, + pd.tot_len, dir == PF_OUT, r->action == PF_PASS, + r->dst.not); if (action != PF_DROP && h->ip_hl > 5 && !((s && s->allow_opts) || (r && r->allow_opts))) { diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c index 719f82ccc9b..6f75f10f72c 100644 --- a/sys/net/pf_ioctl.c +++ b/sys/net/pf_ioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_ioctl.c,v 1.44 2003/01/06 14:19:40 cedric Exp $ */ +/* $OpenBSD: pf_ioctl.c,v 1.45 2003/01/07 00:21:07 dhartmei Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -364,6 +364,8 @@ pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule) { pf_dynaddr_remove(&rule->src.addr); pf_dynaddr_remove(&rule->dst.addr); + pf_tbladdr_remove(&rule->src.addr); + pf_tbladdr_remove(&rule->dst.addr); pf_empty_pool(&rule->rpool.list); if (rulequeue != NULL) TAILQ_REMOVE(rulequeue, rule, entries); @@ -413,8 +415,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) case DIOCRGETASTATS: case DIOCRCLRASTATS: case DIOCRTSTADDRS: - case DIOCRWRAPTABLE: - case DIOCRUNWRTABLE: break; default: return (EPERM); @@ -443,8 +443,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) case DIOCRGETADDRS: case DIOCRGETASTATS: case DIOCRTSTADDRS: - case DIOCRWRAPTABLE: - case DIOCRUNWRTABLE: break; default: return (EACCES); @@ -572,6 +570,10 @@ 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)) + error = EINVAL; + if (pf_tbladdr_setup(&rule->dst.addr)) + error = EINVAL; pf_mv_pool(&pf_pabuf, &rule->rpool.list); if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) || @@ -793,6 +795,10 @@ 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)) + error = EINVAL; + if (pf_tbladdr_setup(&newrule->dst.addr)) + error = EINVAL; pf_mv_pool(&pf_pabuf, &newrule->rpool.list); if (((((newrule->action == PF_NAT) || @@ -1461,6 +1467,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } #endif /* INET6 */ + if (pp->addr.addr.addr.type != PF_ADDR_ADDRMASK && + pp->addr.addr.addr.type != PF_ADDR_DYNIFTL) { + error = EINVAL; + break; + } pa = pool_get(&pf_pooladdr_pl, PR_NOWAIT); if (pa == NULL) { error = ENOMEM; @@ -1540,6 +1551,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = EINVAL; break; } + if (pca->addr.addr.addr.type != PF_ADDR_ADDRMASK && + pca->addr.addr.addr.type != PF_ADDR_DYNIFTL) { + error = EINVAL; + break; + } pool = pf_get_pool(pca->anchor, pca->ruleset, 0, pca->r_action, pca->r_num, pca->r_last, 1, 1); @@ -1804,23 +1820,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } - case DIOCRWRAPTABLE: { - struct pfioc_table *io = (struct pfioc_table *)addr; - - error = pfr_wrap_table(&io->pfrio_table, io->pfrio_buffer, - io->pfrio_exists ? &io->pfrio_exists : NULL, - io->pfrio_flags); - break; - } - - case DIOCRUNWRTABLE: { - struct pfioc_table *io = (struct pfioc_table *)addr; - - error = pfr_unwrap_table(&io->pfrio_table, io->pfrio_buffer, - io->pfrio_flags); - break; - } - default: error = ENODEV; break; diff --git a/sys/net/pf_norm.c b/sys/net/pf_norm.c index e24b4bf680a..70c9cb0e627 100644 --- a/sys/net/pf_norm.c +++ b/sys/net/pf_norm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_norm.c,v 1.49 2003/01/05 22:14:23 dhartmei Exp $ */ +/* $OpenBSD: pf_norm.c,v 1.50 2003/01/07 00:21:07 dhartmei Exp $ */ /* * Copyright 2001 Niels Provos <provos@citi.umich.edu> @@ -811,15 +811,11 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason) r = r->skip[PF_SKIP_AF].ptr; else if (r->proto && r->proto != h->ip_p) r = r->skip[PF_SKIP_PROTO].ptr; - else if (!PF_AZERO(&r->src.addr.v.a.mask, AF_INET) && - !PF_MATCHA(r->src.not, &r->src.addr.v.a.addr, - &r->src.addr.v.a.mask, (struct pf_addr *)&h->ip_src.s_addr, - AF_INET)) + else if (PF_MISMATCHAW(&r->src.addr, + (struct pf_addr *)&h->ip_src.s_addr, AF_INET, r->src.not)) r = r->skip[PF_SKIP_SRC_ADDR].ptr; - else if (!PF_AZERO(&r->dst.addr.v.a.mask, AF_INET) && - !PF_MATCHA(r->dst.not, &r->dst.addr.v.a.addr, - &r->dst.addr.v.a.mask, (struct pf_addr *)&h->ip_dst.s_addr, - AF_INET)) + else if (PF_MISMATCHAW(&r->dst.addr, + (struct pf_addr *)&h->ip_dst.s_addr, AF_INET, r->dst.not)) r = r->skip[PF_SKIP_DST_ADDR].ptr; else break; @@ -1016,24 +1012,12 @@ pf_normalize_tcp(int dir, struct ifnet *ifp, struct mbuf *m, int ipoff, r = r->skip[PF_SKIP_AF].ptr; else if (r->proto && r->proto != pd->proto) r = r->skip[PF_SKIP_PROTO].ptr; - else if (r->src.addr.type == PF_ADDR_NOROUTE && - pf_routable(pd->src, af)) - r = TAILQ_NEXT(r, entries); - else if (r->src.addr.type != PF_ADDR_NOROUTE && - !PF_AZERO(&r->src.addr.v.a.mask, af) && - !PF_MATCHA(r->src.not, &r->src.addr.v.a.addr, - &r->src.addr.v.a.mask, pd->src, af)) + else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not)) r = r->skip[PF_SKIP_SRC_ADDR].ptr; else if (r->src.port_op && !pf_match_port(r->src.port_op, r->src.port[0], r->src.port[1], th->th_sport)) r = r->skip[PF_SKIP_SRC_PORT].ptr; - else if (r->dst.addr.type == PF_ADDR_NOROUTE && - pf_routable(pd->dst, af)) - r = TAILQ_NEXT(r, entries); - else if (!r->dst.addr.type != PF_ADDR_NOROUTE && - !PF_AZERO(&r->dst.addr.v.a.mask, af) && - !PF_MATCHA(r->dst.not, &r->dst.addr.v.a.addr, - &r->dst.addr.v.a.mask, pd->dst, af)) + else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not)) r = r->skip[PF_SKIP_DST_ADDR].ptr; else if (r->dst.port_op && !pf_match_port(r->dst.port_op, r->dst.port[0], r->dst.port[1], th->th_dport)) diff --git a/sys/net/pf_table.c b/sys/net/pf_table.c index 0775961c572..b363bebeaca 100644 --- a/sys/net/pf_table.c +++ b/sys/net/pf_table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_table.c,v 1.14 2003/01/06 14:19:40 cedric Exp $ */ +/* $OpenBSD: pf_table.c,v 1.15 2003/01/07 00:21:07 dhartmei Exp $ */ /* * Copyright (c) 2002 Cedric Berger @@ -42,8 +42,6 @@ #include <netinet/ip_ipsp.h> #include <net/pfvar.h> -#include <crypto/sha1.h> - #define ACCEPT_FLAGS(oklist) \ do { \ if ((flags & ~(oklist)) & \ @@ -89,9 +87,6 @@ struct pfr_walktree { #define pfrw_workq pfrw_1.pfrw1_workq #define pfrw_cnt pfrw_free -#define PFR_HASH_BUCKETS 1024 -#define PFR_HASH_BUCKET(hash) ((hash).pfrh_int32[1] & (PFR_HASH_BUCKETS-1)) - #define senderr(e) do { rv = (e); goto _bad; } while (0) struct pool pfr_ktable_pl; @@ -130,18 +125,11 @@ void pfr_destroy_ktable(struct pfr_ktable *); void pfr_destroy_ktables(struct pfr_ktableworkq *); int pfr_ktable_compare(struct pfr_ktable *, struct pfr_ktable *); -struct pfr_ktable *pfr_lookup_hash(union pfr_hash *); struct pfr_ktable *pfr_lookup_table(struct pfr_table *); -int pfr_match_addr(struct pf_addr *, struct pf_addr *, - struct pf_addr *, sa_family_t); -void pfr_update_stats(struct pf_addr *, struct pf_addr *, - struct pf_addr *, sa_family_t, u_int64_t, int, int, - int); RB_PROTOTYPE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare); RB_GENERATE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare); -struct pfr_ktablehashq pfr_ktablehash[PFR_HASH_BUCKETS]; struct pfr_ktablehead pfr_ktables; struct pfr_table pfr_nulltable; int pfr_ktable_cnt; @@ -169,7 +157,7 @@ pfr_clr_addrs(struct pfr_table *tbl, int *ndel, int flags) ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY); kt = pfr_lookup_table(tbl); - if (kt == NULL) + if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE)) return (ESRCH); rv = pfr_enqueue_addrs(kt, &workq, ndel); if (rv) @@ -202,7 +190,7 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK); kt = pfr_lookup_table(tbl); - if (kt == NULL) + if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE)) return (ESRCH); tmpkt = pfr_create_ktable(&pfr_nulltable, 0); if (tmpkt == NULL) @@ -265,7 +253,7 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK); kt = pfr_lookup_table(tbl); - if (kt == NULL) + if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE)) return (ESRCH); bzero(&w, sizeof(w)); @@ -328,7 +316,7 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK); kt = pfr_lookup_table(tbl); - if (kt == NULL) + if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE)) return (ESRCH); tmpkt = pfr_create_ktable(&pfr_nulltable, 0); if (tmpkt == NULL) @@ -444,7 +432,7 @@ pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, ACCEPT_FLAGS(PFR_FLAG_REPLACE); kt = pfr_lookup_table(tbl); - if (kt == NULL) + if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE)) return (ESRCH); for (i = 0; i < size; i++) { @@ -479,7 +467,7 @@ pfr_get_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int *size, ACCEPT_FLAGS(0); kt = pfr_lookup_table(tbl); - if (kt == NULL) + if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE)) return (ESRCH); if (kt->pfrkt_cnt > *size) { *size = kt->pfrkt_cnt; @@ -516,7 +504,7 @@ pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size, ACCEPT_FLAGS(PFR_FLAG_ATOMIC); /* XXX PFR_FLAG_CLSTATS disabled */ kt = pfr_lookup_table(tbl); - if (kt == NULL) + if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE)) return (ESRCH); if (kt->pfrkt_cnt > *size) { *size = kt->pfrkt_cnt; @@ -563,7 +551,7 @@ pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size, ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK); kt = pfr_lookup_table(tbl); - if (kt == NULL) + if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE)) return (ESRCH); SLIST_INIT(&workq); for (i = 0; i < size; i++) { @@ -949,18 +937,20 @@ pfr_clr_tables(int *ndel, int flags) int pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags) { - struct pfr_ktableworkq workq; + struct pfr_ktableworkq workq, changeq; struct pfr_ktable *p, *q, key; int i, rv, s, xadd = 0; long tzero = time.tv_sec; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY); SLIST_INIT(&workq); + SLIST_INIT(&changeq); for (i = 0; i < size; i++) { if (copyin(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t))) senderr(EFAULT); if (key.pfrkt_name[PF_TABLE_NAME_SIZE-1]) senderr(EINVAL); + key.pfrkt_flags = PFR_TFLAG_ACTIVE+PFR_TFLAG_PERSIST; p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key); if (p == NULL) { p = pfr_create_ktable(&key.pfrkt_t, tzero); @@ -969,19 +959,11 @@ pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags) SLIST_FOREACH(q, &workq, pfrkt_workq) { if (!strcmp(p->pfrkt_name, q->pfrkt_name)) goto _skip; - if (!memcmp(&p->pfrkt_hash, &q->pfrkt_hash, - sizeof(p->pfrkt_hash))) { - printf("pfr_add_tables: " - "sha collision\n"); - senderr(EEXIST); - } } SLIST_INSERT_HEAD(&workq, p, pfrkt_workq); - if (pfr_lookup_hash(&p->pfrkt_hash)) { - printf("pfr_add_tables: sha collision\n"); - senderr(EEXIST); - } xadd++; + } else if (!(p->pfrkt_flags & PFR_TFLAG_PERSIST)) { + SLIST_INSERT_HEAD(&changeq, p, pfrkt_workq); } _skip: } @@ -989,6 +971,8 @@ _skip: if (flags & PFR_FLAG_ATOMIC) s = splsoftnet(); pfr_insert_ktables(&workq); + SLIST_FOREACH(p, &changeq, pfrkt_workq) + p->pfrkt_flags |= PFR_TFLAG_PERSIST; if (flags & PFR_FLAG_ATOMIC) splx(s); } else @@ -1004,22 +988,27 @@ _bad: int pfr_del_tables(struct pfr_table *tbl, int size, int *ndel, int flags) { - struct pfr_ktableworkq workq; + struct pfr_ktableworkq workq, changeq; struct pfr_ktable *p, *q, key; int i, s, xdel = 0; ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY); SLIST_INIT(&workq); + SLIST_INIT(&changeq); for (i = 0; i < size; i++) { if (copyin(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t))) return (EFAULT); p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key); if (p != NULL) { - SLIST_FOREACH(q, &workq, pfrkt_workq) + struct pfr_ktableworkq *queue; + + queue = (p->pfrkt_refcnt > 0) ? &changeq : &workq; + SLIST_FOREACH(q, queue, pfrkt_workq) if (!strcmp(p->pfrkt_name, q->pfrkt_name)) goto _skip; - SLIST_INSERT_HEAD(&workq, p, pfrkt_workq); - xdel++; + SLIST_INSERT_HEAD(queue, p, pfrkt_workq); + if (queue == &workq) + xdel++; } _skip: } @@ -1028,6 +1017,8 @@ _skip: if (flags & PFR_FLAG_ATOMIC) s = splsoftnet(); pfr_remove_ktables(&workq); + SLIST_FOREACH(p, &changeq, pfrkt_workq) + p->pfrkt_flags &= ~PFR_TFLAG_PERSIST; if (flags & PFR_FLAG_ATOMIC) splx(s); } @@ -1135,62 +1126,11 @@ pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags) return (0); } -int -pfr_wrap_table(struct pfr_table *tbl, struct pf_addr_wrap *wrap, - int *exists, int flags) -{ - union pfr_hash hash; - struct pf_addr_wrap w; - SHA1_CTX sha1; - - ACCEPT_FLAGS(0); - if (!*tbl->pfrt_name || tbl->pfrt_name[PF_TABLE_NAME_SIZE-1]) - return (EINVAL); - SHA1Init(&sha1); - SHA1Update(&sha1, tbl->pfrt_name, strlen(tbl->pfrt_name)); - SHA1Final(hash.pfrh_sha1, &sha1); - - bzero(&w, sizeof(w)); - bcopy(&hash, &w.v.a.addr, sizeof(w.v.a.addr)); - w.v.a.mask.addr32[0] = PF_TABLE_MASK; - w.v.a.mask.addr32[1] = hash.pfrh_int32[4]; - if (copyout(&w, wrap, sizeof(*wrap))) - return (EFAULT); - - if (exists != NULL) - *exists = pfr_lookup_table(tbl) != NULL; - return (0); -} - -int -pfr_unwrap_table(struct pfr_table *tbl, struct pf_addr_wrap *wrap, int flags) -{ - union pfr_hash hash; - struct pf_addr_wrap w; - struct pfr_ktable *kt; - - ACCEPT_FLAGS(0); - if (copyin(wrap, &w, sizeof(w))) - return (EFAULT); - - if (w.v.a.mask.addr32[0] != PF_TABLE_MASK || w.v.a.mask.addr32[2] || - w.v.a.mask.addr32[3]) - return (EINVAL); - - bcopy(&w.v.a.addr, &hash, 16); - hash.pfrh_int32[4] = w.v.a.mask.addr32[1]; - kt = pfr_lookup_hash(&hash); - if (kt == NULL) - return (ENOENT); - *tbl = kt->pfrkt_t; - return (0); -} - void pfr_insert_ktables(struct pfr_ktableworkq *workq) { struct pfr_ktable *p; - int s, n = 0; + int n = 0; /* insert into tree */ SLIST_FOREACH(p, workq, pfrkt_workq) { @@ -1198,14 +1138,6 @@ pfr_insert_ktables(struct pfr_ktableworkq *workq) n++; } pfr_ktable_cnt += n; - - SLIST_FOREACH(p, workq, pfrkt_workq) { - s = splsoftnet(); - SLIST_INSERT_HEAD(pfr_ktablehash + - PFR_HASH_BUCKET(p->pfrkt_hash), - p, pfrkt_hashq); - splx(s); - } } void @@ -1213,14 +1145,7 @@ pfr_remove_ktables(struct pfr_ktableworkq *workq) { struct pfr_kentryworkq addrq; struct pfr_ktable *p; - int s, n = 0; - - SLIST_FOREACH(p, workq, pfrkt_workq) { - s = splsoftnet(); - SLIST_REMOVE(pfr_ktablehash + PFR_HASH_BUCKET(p->pfrkt_hash), - p, pfr_ktable, pfrkt_hashq); - splx(s); - } + int n = 0; SLIST_FOREACH(p, workq, pfrkt_workq) { RB_REMOVE(pfr_ktablehead, &pfr_ktables, p); @@ -1259,7 +1184,6 @@ struct pfr_ktable * pfr_create_ktable(struct pfr_table *tbl, long tzero) { struct pfr_ktable *kt; - SHA1_CTX sha1; kt = pool_get(&pfr_ktable_pl, PR_NOWAIT); if (kt == NULL) @@ -1267,11 +1191,6 @@ pfr_create_ktable(struct pfr_table *tbl, long tzero) bzero(kt, sizeof(*kt)); kt->pfrkt_t = *tbl; - /* compute secure hash */ - SHA1Init(&sha1); - SHA1Update(&sha1, kt->pfrkt_name, strlen(kt->pfrkt_name)); - SHA1Final(kt->pfrkt_hash.pfrh_sha1, &sha1); - if (!rn_inithead((void **)&kt->pfrkt_ip4, offsetof(struct sockaddr_in, sin_addr) * 8) || !rn_inithead((void **)&kt->pfrkt_ip6, @@ -1314,17 +1233,6 @@ pfr_ktable_compare(struct pfr_ktable *p, struct pfr_ktable *q) } struct pfr_ktable * -pfr_lookup_hash(union pfr_hash *hash) -{ - struct pfr_ktable *p; - - SLIST_FOREACH(p, pfr_ktablehash+PFR_HASH_BUCKET(*hash), pfrkt_hashq) - if (!memcmp(p->pfrkt_hash.pfrh_sha1, hash->pfrh_sha1, 20)) - return (p); - return (NULL); -} - -struct pfr_ktable * pfr_lookup_table(struct pfr_table *tbl) { /* struct pfr_ktable start like a struct pfr_table */ @@ -1338,26 +1246,18 @@ pfr_lookup_table(struct pfr_table *tbl) * are different. */ int -pfr_match_addr(struct pf_addr *a, struct pf_addr *m, - struct pf_addr *b, sa_family_t af) +pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af) { - union pfr_hash hash; - struct pfr_ktable *kt; struct pfr_kentry *ke = NULL; int match; - bcopy(a, &hash, 16); - hash.pfrh_int32[4] = m->addr32[1]; - kt = pfr_lookup_hash(&hash); - if (kt == NULL) - return (0); switch (af) { case AF_INET: - pfr_sin.sin_addr.s_addr = b->addr32[0]; + pfr_sin.sin_addr.s_addr = a->addr32[0]; ke = (struct pfr_kentry *)rn_match(&pfr_sin, kt->pfrkt_ip4); break; case AF_INET6: - bcopy(&b, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr)); + bcopy(&a, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr)); ke = (struct pfr_kentry *)rn_match(&pfr_sin6, kt->pfrkt_ip6); break; } @@ -1370,27 +1270,18 @@ pfr_match_addr(struct pf_addr *a, struct pf_addr *m, } void -pfr_update_stats(struct pf_addr *a, struct pf_addr *m, - struct pf_addr *b, sa_family_t af, u_int64_t len, - int dir_out, int op_pass, int notrule) +pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af, + u_int64_t len, int dir_out, int op_pass, int notrule) { - union pfr_hash hash; - struct pfr_ktable *kt; struct pfr_kentry *ke = NULL; - bcopy(a, &hash, 16); - hash.pfrh_int32[4] = m->addr32[1]; - kt = pfr_lookup_hash(&hash); - if (kt == NULL) - return; - switch (af) { case AF_INET: - pfr_sin.sin_addr.s_addr = b->addr32[0]; + pfr_sin.sin_addr.s_addr = a->addr32[0]; ke = (struct pfr_kentry *)rn_match(&pfr_sin, kt->pfrkt_ip4); break; case AF_INET6: - bcopy(&b, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr)); + bcopy(&a, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr)); ke = (struct pfr_kentry *)rn_match(&pfr_sin6, kt->pfrkt_ip6); break; } @@ -1406,3 +1297,45 @@ pfr_update_stats(struct pf_addr *a, struct pf_addr *m, ke->pfrke_bytes[dir_out][op_pass] += len; } } + +struct pfr_ktable * +pfr_attach_table(char *name) +{ + struct pfr_ktable *p, key; + struct pfr_ktableworkq workq; + + bzero(&key, sizeof(key)); + strlcpy(key.pfrkt_name, name, sizeof(key.pfrkt_name)); + key.pfrkt_flags = PFR_TFLAG_ACTIVE; + p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key); + if (p == NULL) { + p = pfr_create_ktable(&key.pfrkt_t, time.tv_sec); + if (p == NULL) + return NULL; + SLIST_INIT(&workq); + SLIST_INSERT_HEAD(&workq, p, pfrkt_workq); + pfr_insert_ktables(&workq); + } + p->pfrkt_refcnt++; + return p; +} + +void +pfr_detach_table(struct pfr_ktable *kt) +{ + struct pfr_ktableworkq workq; + + if (kt->pfrkt_refcnt <= 0) + printf("pfr_detach_table, refcount = %d\n", + kt->pfrkt_refcnt); + else { + kt->pfrkt_refcnt--; + if (kt->pfrkt_refcnt == 0 && + !(kt->pfrkt_flags & PFR_TFLAG_PERSIST)) { + kt->pfrkt_flags &= ~PFR_TFLAG_ACTIVE; + SLIST_INIT(&workq); + SLIST_INSERT_HEAD(&workq, kt, pfrkt_workq); + pfr_remove_ktables(&workq); + } + } +} diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 29910674357..2ce24b2abba 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.128 2003/01/06 14:19:40 cedric Exp $ */ +/* $OpenBSD: pfvar.h,v 1.129 2003/01/07 00:21:07 dhartmei Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -244,6 +244,24 @@ struct pf_addr_dyn { #endif /* PF_INET6_ONLY */ #endif /* PF_INET_INET6 */ +#define PF_MISMATCHAW(aw, x, af, not) \ + ( \ + (((aw)->type == PF_ADDR_NOROUTE && \ + pf_routable((x), (af))) || \ + ((aw)->type == PF_ADDR_TABLE && \ + !pfr_match_addr((aw)->p.tbl, (x), (af))) || \ + ((aw)->type == PF_ADDR_DYNIFTL && \ + ((aw)->p.dyn->undefined || \ + (!PF_AZERO(&(aw)->v.a.mask, (af)) && \ + !PF_MATCHA(0, &(aw)->v.a.addr, \ + &(aw)->v.a.mask, (x), (af))))) || \ + ((aw)->type == PF_ADDR_ADDRMASK && \ + !PF_AZERO(&(aw)->v.a.mask, (af)) && \ + !PF_MATCHA(0, &(aw)->v.a.addr, \ + &(aw)->v.a.mask, (x), (af)))) != \ + (not) \ + ) + struct pf_rule_uid { uid_t uid[2]; u_int8_t op; @@ -452,10 +470,15 @@ struct pf_anchor { TAILQ_HEAD(pf_anchorqueue, pf_anchor); -#define PF_TABLE_MASK 0xCAFEBABE +#define PFR_TFLAG_PERSIST 0x00000001 +#define PFR_TFLAG_CONST 0x00000002 +#define PFR_TFLAG_ACTIVE 0x00000004 +#define PFR_TFLAG_INACTIVE 0x00000008 +#define PFR_TFLAG_ALLMASK 0x0000000F struct pfr_table { char pfrt_name[PF_TABLE_NAME_SIZE]; + u_int32_t pfrt_flags; }; enum { PFR_FB_NONE, PFR_FB_MATCH, PFR_FB_ADDED, PFR_FB_DELETED, @@ -494,13 +517,10 @@ struct pfr_tstats { u_int64_t pfrts_nomatch; long pfrts_tzero; int pfrts_cnt; + int pfrts_refcnt; }; #define pfrts_name pfrts_t.pfrt_name - -union pfr_hash { - char pfrh_sha1[20]; - u_int32_t pfrh_int32[5]; -}; +#define pfrts_flags pfrts_t.pfrt_flags SLIST_HEAD(pfr_kentryworkq, pfr_kentry); struct pfr_kentry { @@ -516,21 +536,20 @@ struct pfr_kentry { u_int8_t pfrke_mark; }; -SLIST_HEAD(pfr_ktablehashq, pfr_ktable); SLIST_HEAD(pfr_ktableworkq, pfr_ktable); RB_HEAD(pfr_ktablehead, pfr_ktable); struct pfr_ktable { struct pfr_tstats pfrkt_ts; - union pfr_hash pfrkt_hash; RB_ENTRY(pfr_ktable) pfrkt_tree; - SLIST_ENTRY(pfr_ktable) pfrkt_hashq; SLIST_ENTRY(pfr_ktable) pfrkt_workq; struct radix_node_head *pfrkt_ip4; struct radix_node_head *pfrkt_ip6; }; #define pfrkt_t pfrkt_ts.pfrts_t #define pfrkt_name pfrkt_t.pfrt_name +#define pfrkt_flags pfrkt_t.pfrt_flags #define pfrkt_cnt pfrkt_ts.pfrts_cnt +#define pfrkt_refcnt pfrkt_ts.pfrts_refcnt #define pfrkt_packets pfrkt_ts.pfrts_packets #define pfrkt_bytes pfrkt_ts.pfrts_bytes #define pfrkt_match pfrkt_ts.pfrts_match @@ -896,8 +915,6 @@ struct pfioc_table { #define DIOCRGETASTATS _IOWR('D', 71, struct pfioc_table) #define DIOCRCLRASTATS _IOWR('D', 72, struct pfioc_table) #define DIOCRTSTADDRS _IOWR('D', 73, struct pfioc_table) -#define DIOCRWRAPTABLE _IOWR('D', 74, struct pfioc_table) -#define DIOCRUNWRTABLE _IOWR('D', 75, struct pfioc_table) #ifdef _KERNEL @@ -921,12 +938,14 @@ 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 void pf_dynaddr_remove(struct pf_addr_wrap *); +extern int pf_tbladdr_setup(struct pf_addr_wrap *); +extern void pf_tbladdr_remove(struct pf_addr_wrap *); extern int pf_dynaddr_setup(struct pf_addr_wrap *, - u_int8_t); + sa_family_t); +extern void pf_dynaddr_copyout(struct pf_addr_wrap *); +extern void pf_dynaddr_remove(struct pf_addr_wrap *); extern void pf_calc_skip_steps(struct pf_rulequeue *); extern void pf_update_anchor_rules(void); -extern void pf_dynaddr_copyout(struct pf_addr_wrap *); extern struct pool pf_tree_pl, pf_rule_pl, pf_addr_pl; extern struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl; extern void pf_purge_timeout(void *); @@ -963,10 +982,12 @@ int pf_normalize_ip(struct mbuf **, int, struct ifnet *, u_short *); void pf_purge_expired_fragments(void); int pf_routable(struct pf_addr *addr, sa_family_t af); void pfr_initialize(void); -int pfr_match_addr(struct pf_addr *, struct pf_addr *, - struct pf_addr *, sa_family_t); -void pfr_update_stats(struct pf_addr *, struct pf_addr *, - struct pf_addr *, sa_family_t, u_int64_t, int, int, int); +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 *); +void pfr_detach_table(struct pfr_ktable *); int pfr_clr_tables(int *, int); int pfr_add_tables(struct pfr_table *, int, int *, int); int pfr_del_tables(struct pfr_table *, int, int *, int); |