diff options
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if_pfsync.c | 41 | ||||
-rw-r--r-- | sys/net/pf.c | 948 | ||||
-rw-r--r-- | sys/net/pf_ioctl.c | 97 | ||||
-rw-r--r-- | sys/net/pfvar.h | 70 |
4 files changed, 544 insertions, 612 deletions
diff --git a/sys/net/if_pfsync.c b/sys/net/if_pfsync.c index 8c70ab56079..518181e8322 100644 --- a/sys/net/if_pfsync.c +++ b/sys/net/if_pfsync.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pfsync.c,v 1.91 2008/05/18 11:54:04 mcbride Exp $ */ +/* $OpenBSD: if_pfsync.c,v 1.92 2008/05/29 00:28:07 henning Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff @@ -276,7 +276,7 @@ pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag) } bzero(st, sizeof(*st)); - if ((sk = pf_alloc_state_key(st)) == NULL) { + if ((sk = pf_alloc_state_key()) == NULL) { pool_put(&pf_state_pl, st); pfi_kif_unref(kif, PFI_KIF_REF_NONE); return (ENOMEM); @@ -293,6 +293,7 @@ pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag) return (ENOMEM); } + pf_attach_state(sk, st, 0, PF_SK_BOTH); /* XXX RYAN NAT */ st->rule.ptr = r; /* XXX get pointers to nat_rule and anchor */ @@ -300,11 +301,12 @@ pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag) r->states_cur++; r->states_tot++; +#ifdef XXX_HENNING_RYAN_FIXED_PFSYNC /* fill in the rest of the state entry */ pf_state_host_ntoh(&sp->lan, &sk->lan); pf_state_host_ntoh(&sp->gwy, &sk->gwy); pf_state_host_ntoh(&sp->ext, &sk->ext); - +#endif pf_state_peer_ntoh(&sp->src, &st->src); pf_state_peer_ntoh(&sp->dst, &st->dst); @@ -314,7 +316,7 @@ pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag) sk->af = sp->af; sk->proto = sp->proto; - sk->direction = sp->direction; + st->direction = sp->direction; st->log = sp->log; st->timeout = sp->timeout; st->allow_opts = sp->allow_opts; @@ -323,7 +325,7 @@ pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag) st->creatorid = sp->creatorid; st->sync_flags = PFSTATE_FROMSYNC; - if (pf_insert_state(kif, st)) { + if (pf_state_insert(kif, sk, st)) { pfi_kif_unref(kif, PFI_KIF_REF_NONE); /* XXX when we have nat_rule/anchors, use STATE_DEC_COUNTERS */ r->states_cur--; @@ -346,6 +348,7 @@ pfsync_input(struct mbuf *m, ...) struct pfsync_softc *sc = pfsyncif; struct pf_state *st; struct pf_state_key *sk; + struct pf_state_item *si; struct pf_state_cmp id_key; struct pfsync_state *sp; struct pfsync_state_upd *up; @@ -445,15 +448,16 @@ pfsync_input(struct mbuf *m, ...) splx(s); return; } - for (sk = RB_MIN(pf_state_tree_lan_ext, - &pf_statetbl_lan_ext); sk; sk = nextsk) { - nextsk = RB_NEXT(pf_state_tree_lan_ext, - &pf_statetbl_lan_ext, sk); - TAILQ_FOREACH(st, &sk->states, next) { - if (st->creatorid == creatorid) { - st->sync_flags |= + /* XXX correct? */ + for (sk = RB_MIN(pf_state_tree, + &pf_statetbl); sk; sk = nextsk) { + nextsk = RB_NEXT(pf_state_tree, + &pf_statetbl, sk); + TAILQ_FOREACH(si, &sk->states, entry) { + if (si->s->creatorid == creatorid) { + si->s->sync_flags |= PFSTATE_FROMSYNC; - pf_unlink_state(st); + pf_unlink_state(si->s); } } } @@ -529,7 +533,7 @@ pfsync_input(struct mbuf *m, ...) pfsyncstats.pfsyncs_badstate++; continue; } - sk = st->state_key; + sk = st->key_wire; /* XXX right one? */ sfail = 0; if (sk->proto == IPPROTO_TCP) { /* @@ -666,7 +670,7 @@ pfsync_input(struct mbuf *m, ...) pfsyncstats.pfsyncs_badstate++; continue; } - sk = st->state_key; + sk = st->key_wire; /* XXX right one? */ sfail = 0; if (sk->proto == IPPROTO_TCP) { /* @@ -1118,7 +1122,7 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags) struct pfsync_state *sp = NULL; struct pfsync_state_upd *up = NULL; struct pfsync_state_del *dp = NULL; - struct pf_state_key *sk = st->state_key; + struct pf_state_key *sk = st->key_wire; struct pf_rule *r; u_long secs; int s, ret = 0; @@ -1204,10 +1208,11 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags) sp->creatorid = st->creatorid; strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname)); +#ifdef XXX_HENNING_RYAN_FIXED_PFSYNC pf_state_host_hton(&sk->lan, &sp->lan); pf_state_host_hton(&sk->gwy, &sp->gwy); pf_state_host_hton(&sk->ext, &sp->ext); - +#endif bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr)); sp->creation = htonl(secs - st->creation); @@ -1225,7 +1230,7 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags) sp->anchor = htonl(r->nr); sp->af = sk->af; sp->proto = sk->proto; - sp->direction = sk->direction; + sp->direction = st->direction; sp->log = st->log; sp->allow_opts = st->allow_opts; sp->timeout = st->timeout; diff --git a/sys/net/pf.c b/sys/net/pf.c index b204c420630..a332e304845 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,8 +1,8 @@ -/* $OpenBSD: pf.c,v 1.575 2008/05/18 11:54:04 mcbride Exp $ */ +/* $OpenBSD: pf.c,v 1.576 2008/05/29 00:28:07 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier - * Copyright (c) 2002,2003 Henning Brauer + * Copyright (c) 2002 - 2008 Henning Brauer * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -98,8 +98,7 @@ */ /* state tables */ -struct pf_state_tree_lan_ext pf_statetbl_lan_ext; -struct pf_state_tree_ext_gwy pf_statetbl_ext_gwy; +struct pf_state_tree pf_statetbl; struct pf_altqqueue pf_altqs[2]; struct pf_palist pf_pabuf; @@ -125,7 +124,7 @@ struct pf_anchor_stackframe { } pf_anchor_stack[64]; struct pool pf_src_tree_pl, pf_rule_pl, pf_pooladdr_pl; -struct pool pf_state_pl, pf_state_key_pl; +struct pool pf_state_pl, pf_state_key_pl, pf_state_item_pl; struct pool pf_altq_pl; void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t); @@ -164,9 +163,9 @@ struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *, struct pf_addr *, u_int16_t, struct pf_addr *, u_int16_t, struct pf_addr *, u_int16_t *); -void pf_attach_state(struct pf_state_key *, - struct pf_state *, int); void pf_detach_state(struct pf_state *, int); +void pf_state_key_detach(struct pf_state_key *, + struct pf_state *, int); u_int32_t pf_tcp_iss(struct pf_pdesc *); int pf_test_rule(struct pf_rule **, struct pf_state **, int, struct pfi_kif *, struct mbuf *, int, @@ -224,7 +223,7 @@ int pf_addr_wrap_neq(struct pf_addr_wrap *, struct pf_state *pf_find_state(struct pfi_kif *, struct pf_state_key_cmp *, u_int); int pf_src_connlimit(struct pf_state **); -void pf_stateins_err(const char *, struct pf_state *, +void pf_stateins_err(struct pf_state_key *, struct pfi_kif *); int pf_check_congestion(struct ifqueue *); @@ -289,9 +288,7 @@ struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = { } while (0) static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *); -static __inline int pf_state_compare_lan_ext(struct pf_state_key *, - struct pf_state_key *); -static __inline int pf_state_compare_ext_gwy(struct pf_state_key *, +static __inline int pf_state_compare_key(struct pf_state_key *, struct pf_state_key *); static __inline int pf_state_compare_id(struct pf_state *, struct pf_state *); @@ -302,15 +299,11 @@ struct pf_state_tree_id tree_id; struct pf_state_queue state_list; RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare); -RB_GENERATE(pf_state_tree_lan_ext, pf_state_key, - entry_lan_ext, pf_state_compare_lan_ext); -RB_GENERATE(pf_state_tree_ext_gwy, pf_state_key, - entry_ext_gwy, pf_state_compare_ext_gwy); +RB_GENERATE(pf_state_tree, pf_state_key, entry, pf_state_compare_key); RB_GENERATE(pf_state_tree_id, pf_state, entry_id, pf_state_compare_id); -#define PF_DT_SKIP_LANEXT 0x01 -#define PF_DT_SKIP_EXTGWY 0x02 +#define PF_DT_SKIP_STATETREE 0x01 static __inline int pf_src_compare(struct pf_src_node *a, struct pf_src_node *b) @@ -356,157 +349,6 @@ pf_src_compare(struct pf_src_node *a, struct pf_src_node *b) return (0); } -static __inline int -pf_state_compare_lan_ext(struct pf_state_key *a, struct pf_state_key *b) -{ - int diff; - - if ((diff = a->proto - b->proto) != 0) - return (diff); - if ((diff = a->af - b->af) != 0) - return (diff); - switch (a->af) { -#ifdef INET - case AF_INET: - if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0]) - return (1); - if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0]) - return (-1); - if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0]) - return (1); - if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0]) - return (-1); - break; -#endif /* INET */ -#ifdef INET6 - case AF_INET6: - if (a->lan.addr.addr32[3] > b->lan.addr.addr32[3]) - return (1); - if (a->lan.addr.addr32[3] < b->lan.addr.addr32[3]) - return (-1); - if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3]) - return (1); - if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3]) - return (-1); - if (a->lan.addr.addr32[2] > b->lan.addr.addr32[2]) - return (1); - if (a->lan.addr.addr32[2] < b->lan.addr.addr32[2]) - return (-1); - if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2]) - return (1); - if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2]) - return (-1); - if (a->lan.addr.addr32[1] > b->lan.addr.addr32[1]) - return (1); - if (a->lan.addr.addr32[1] < b->lan.addr.addr32[1]) - return (-1); - if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1]) - return (1); - if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1]) - return (-1); - if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0]) - return (1); - if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0]) - return (-1); - if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0]) - return (1); - if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0]) - return (-1); - break; -#endif /* INET6 */ - } - - if ((diff = a->lan.port - b->lan.port) != 0) - return (diff); - if ((diff = a->ext.port - b->ext.port) != 0) - return (diff); - - return (0); -} - -static __inline int -pf_state_compare_ext_gwy(struct pf_state_key *a, struct pf_state_key *b) -{ - int diff; - - if ((diff = a->proto - b->proto) != 0) - return (diff); - if ((diff = a->af - b->af) != 0) - return (diff); - switch (a->af) { -#ifdef INET - case AF_INET: - if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0]) - return (1); - if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0]) - return (-1); - if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0]) - return (1); - if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0]) - return (-1); - break; -#endif /* INET */ -#ifdef INET6 - case AF_INET6: - if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3]) - return (1); - if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3]) - return (-1); - if (a->gwy.addr.addr32[3] > b->gwy.addr.addr32[3]) - return (1); - if (a->gwy.addr.addr32[3] < b->gwy.addr.addr32[3]) - return (-1); - if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2]) - return (1); - if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2]) - return (-1); - if (a->gwy.addr.addr32[2] > b->gwy.addr.addr32[2]) - return (1); - if (a->gwy.addr.addr32[2] < b->gwy.addr.addr32[2]) - return (-1); - if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1]) - return (1); - if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1]) - return (-1); - if (a->gwy.addr.addr32[1] > b->gwy.addr.addr32[1]) - return (1); - if (a->gwy.addr.addr32[1] < b->gwy.addr.addr32[1]) - return (-1); - if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0]) - return (1); - if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0]) - return (-1); - if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0]) - return (1); - if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0]) - return (-1); - break; -#endif /* INET6 */ - } - - if ((diff = a->ext.port - b->ext.port) != 0) - return (diff); - if ((diff = a->gwy.port - b->gwy.port) != 0) - return (diff); - - return (0); -} - -static __inline int -pf_state_compare_id(struct pf_state *a, struct pf_state *b) -{ - if (a->id > b->id) - return (1); - if (a->id < b->id) - return (-1); - if (a->creatorid > b->creatorid) - return (1); - if (a->creatorid < b->creatorid) - return (-1); - - return (0); -} - #ifdef INET6 void pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af) @@ -527,77 +369,6 @@ pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af) } #endif /* INET6 */ -struct pf_state * -pf_find_state_byid(struct pf_state_cmp *key) -{ - pf_status.fcounters[FCNT_STATE_SEARCH]++; - - return (RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state *)key)); -} - -struct pf_state * -pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int dir) -{ - struct pf_state_key *sk; - struct pf_state *s; - - pf_status.fcounters[FCNT_STATE_SEARCH]++; - - switch (dir) { - case PF_OUT: - sk = RB_FIND(pf_state_tree_lan_ext, &pf_statetbl_lan_ext, - (struct pf_state_key *)key); - break; - case PF_IN: - sk = RB_FIND(pf_state_tree_ext_gwy, &pf_statetbl_ext_gwy, - (struct pf_state_key *)key); - break; - default: - panic("pf_find_state"); - } - - /* list is sorted, if-bound states before floating ones */ - if (sk != NULL) - TAILQ_FOREACH(s, &sk->states, next) - if (s->kif == pfi_all || s->kif == kif) - return (s); - - return (NULL); -} - -struct pf_state * -pf_find_state_all(struct pf_state_key_cmp *key, u_int dir, int *more) -{ - struct pf_state_key *sk; - struct pf_state *s, *ret = NULL; - - pf_status.fcounters[FCNT_STATE_SEARCH]++; - - switch (dir) { - case PF_OUT: - sk = RB_FIND(pf_state_tree_lan_ext, - &pf_statetbl_lan_ext, (struct pf_state_key *)key); - break; - case PF_IN: - sk = RB_FIND(pf_state_tree_ext_gwy, - &pf_statetbl_ext_gwy, (struct pf_state_key *)key); - break; - default: - panic("pf_find_state_all"); - } - - if (sk != NULL) { - ret = TAILQ_FIRST(&sk->states); - if (more == NULL) - return (ret); - - TAILQ_FOREACH(s, &sk->states, next) - (*more)++; - } - - return (ret); -} - void pf_init_threshold(struct pf_threshold *threshold, u_int32_t limit, u_int32_t seconds) @@ -661,12 +432,12 @@ pf_src_connlimit(struct pf_state **state) if (pf_status.debug >= PF_DEBUG_MISC) { printf("pf_src_connlimit: blocking address "); pf_print_host(&(*state)->src_node->addr, 0, - (*state)->state_key->af); + (*state)->key_wire->af); } bzero(&p, sizeof(p)); - p.pfra_af = (*state)->state_key->af; - switch ((*state)->state_key->af) { + p.pfra_af = (*state)->key_wire->af; + switch ((*state)->key_wire->af) { #ifdef INET case AF_INET: p.pfra_net = 32; @@ -691,21 +462,21 @@ pf_src_connlimit(struct pf_state **state) pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++; RB_FOREACH(st, pf_state_tree_id, &tree_id) { - sk = st->state_key; + sk = st->key_wire; /* * Kill states from this source. (Only those * from the same rule if PF_FLUSH_GLOBAL is not * set) */ if (sk->af == - (*state)->state_key->af && - (((*state)->state_key->direction == - PF_OUT && + (*state)->key_wire->af && + (((*state)->direction == + PF_OUT && PF_AEQ(&(*state)->src_node->addr, - &sk->lan.addr, sk->af)) || - ((*state)->state_key->direction == PF_IN && + &sk->addr1, sk->af)) || + ((*state)->direction == PF_IN && PF_AEQ(&(*state)->src_node->addr, - &sk->ext.addr, sk->af))) && + &sk->addr2, sk->af))) && ((*state)->rule.ptr->flush & PF_FLUSH_GLOBAL || (*state)->rule.ptr == st->rule.ptr)) { @@ -793,57 +564,194 @@ pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule, } void -pf_stateins_err(const char *tree, struct pf_state *s, struct pfi_kif *kif) +pf_stateins_err(struct pf_state_key *sk, struct pfi_kif *kif) { - struct pf_state_key *sk = s->state_key; - if (pf_status.debug >= PF_DEBUG_MISC) { - printf("pf: state insert failed: %s %s", tree, kif->pfik_name); - printf(" lan: "); - pf_print_host(&sk->lan.addr, sk->lan.port, + printf("pf: state insert failed: %s", kif->pfik_name); + printf(" addr1: "); + pf_print_host(&sk->addr1, sk->port1, sk->af); - printf(" gwy: "); - pf_print_host(&sk->gwy.addr, sk->gwy.port, + printf(" addr2: "); + pf_print_host(&sk->addr2, sk->port2, sk->af); - printf(" ext: "); - pf_print_host(&sk->ext.addr, sk->ext.port, - sk->af); - if (s->sync_flags & PFSTATE_FROMSYNC) - printf(" (from sync)"); printf("\n"); } } +/* state table stuff */ + +static __inline int +pf_state_compare_key(struct pf_state_key *a, struct pf_state_key *b) +{ + int diff; + + if ((diff = a->proto - b->proto) != 0) + return (diff); + if ((diff = a->af - b->af) != 0) + return (diff); + switch (a->af) { +#ifdef INET + case AF_INET: + if (a->addr1.addr32[0] > b->addr1.addr32[0]) + return (1); + if (a->addr1.addr32[0] < b->addr1.addr32[0]) + return (-1); + if (a->addr2.addr32[0] > b->addr2.addr32[0]) + return (1); + if (a->addr2.addr32[0] < b->addr2.addr32[0]) + return (-1); + break; +#endif /* INET */ +#ifdef INET6 + case AF_INET6: + if (a->addr1.addr32[3] > b->addr1.addr32[3]) + return (1); + if (a->addr1.addr32[3] < b->addr1.addr32[3]) + return (-1); + if (a->addr2.addr32[3] > b->addr2.addr32[3]) + return (1); + if (a->addr2.addr32[3] < b->addr2.addr32[3]) + return (-1); + if (a->addr1.addr32[2] > b->addr1.addr32[2]) + return (1); + if (a->addr1.addr32[2] < b->addr1.addr32[2]) + return (-1); + if (a->addr2.addr32[2] > b->addr2.addr32[2]) + return (1); + if (a->addr2.addr32[2] < b->addr2.addr32[2]) + return (-1); + if (a->addr1.addr32[1] > b->addr1.addr32[1]) + return (1); + if (a->addr1.addr32[1] < b->addr1.addr32[1]) + return (-1); + if (a->addr2.addr32[1] > b->addr2.addr32[1]) + return (1); + if (a->addr2.addr32[1] < b->addr2.addr32[1]) + return (-1); + if (a->addr1.addr32[0] > b->addr1.addr32[0]) + return (1); + if (a->addr1.addr32[0] < b->addr1.addr32[0]) + return (-1); + if (a->addr2.addr32[0] > b->addr2.addr32[0]) + return (1); + if (a->addr2.addr32[0] < b->addr2.addr32[0]) + return (-1); + break; +#endif /* INET6 */ + } + + if ((diff = a->port1 - b->port1) != 0) + return (diff); + if ((diff = a->port2 - b->port2) != 0) + return (diff); + + return (0); +} + +static __inline int +pf_state_compare_id(struct pf_state *a, struct pf_state *b) +{ + if (a->id > b->id) + return (1); + if (a->id < b->id) + return (-1); + if (a->creatorid > b->creatorid) + return (1); + if (a->creatorid < b->creatorid) + return (-1); + + return (0); +} + +void +pf_attach_state(struct pf_state_key *sk, struct pf_state *s, int tail, + int where) +{ + struct pf_state_item *si; + + if (where == PF_SK_WIRE || where == PF_SK_BOTH) + s->key_wire = sk; + if (where == PF_SK_STACK || where == PF_SK_BOTH) + s->key_stack = sk; + + si = pool_get(&pf_state_item_pl, PR_NOWAIT); + si->s = s; + + /* list is sorted, if-bound states before floating */ + if (tail) + TAILQ_INSERT_TAIL(&sk->states, si, entry); + else + TAILQ_INSERT_HEAD(&sk->states, si, entry); +} + +void +pf_detach_state(struct pf_state *s, int flags) +{ + if (s->key_wire == s->key_stack) { + pf_state_key_detach(s->key_wire, s, flags); + s->key_wire = s->key_stack = NULL; + } else { + pf_state_key_detach(s->key_stack, s, flags); + pf_state_key_detach(s->key_wire, s, flags); + s->key_wire = s->key_stack = NULL; + } +} + +void +pf_state_key_detach(struct pf_state_key *sk, struct pf_state *s, int flags) +{ + struct pf_state_item *si; + + for (si = TAILQ_FIRST(&sk->states); si->s != s; + si = TAILQ_NEXT(si, entry)); + +/* XXX DEBUG */ if (!si) { printf("pf_state_key_detach, si NULL\n"); } + + TAILQ_REMOVE(&sk->states, si, entry); + pool_put(&pf_state_item_pl, si); + + if (TAILQ_EMPTY(&sk->states)) { + if (!(flags & PF_DT_SKIP_STATETREE)) + RB_REMOVE(pf_state_tree, &pf_statetbl, sk); + pool_put(&pf_state_key_pl, sk); + } +} + +struct pf_state_key * +pf_alloc_state_key(void) +{ + struct pf_state_key *sk; + + if ((sk = pool_get(&pf_state_key_pl, PR_NOWAIT)) == NULL) + return (NULL); + bzero(sk, sizeof(*sk)); + TAILQ_INIT(&sk->states); + + return (sk); +} + int -pf_insert_state(struct pfi_kif *kif, struct pf_state *s) +pf_state_insert(struct pfi_kif *kif, struct pf_state_key *sk, + struct pf_state *s) { struct pf_state_key *cur; - struct pf_state *sp; + struct pf_state_item *si; - KASSERT(s->state_key != NULL); s->kif = kif; - if ((cur = RB_INSERT(pf_state_tree_lan_ext, &pf_statetbl_lan_ext, - s->state_key)) != NULL) { + if ((cur = RB_INSERT(pf_state_tree, &pf_statetbl, sk)) != NULL) { /* key exists. check for same kif, if none, add to key */ - TAILQ_FOREACH(sp, &cur->states, next) - if (sp->kif == kif) { /* collision! */ - pf_stateins_err("tree_lan_ext", s, kif); - pf_detach_state(s, - PF_DT_SKIP_LANEXT|PF_DT_SKIP_EXTGWY); + TAILQ_FOREACH(si, &cur->states, entry) + if (si->s->kif == kif && + si->s->direction == s->direction) { + /* collision! */ + pf_stateins_err(sk, kif); + pf_detach_state(s, PF_DT_SKIP_STATETREE); return (-1); } - pf_detach_state(s, PF_DT_SKIP_LANEXT|PF_DT_SKIP_EXTGWY); - pf_attach_state(cur, s, kif == pfi_all ? 1 : 0); - } - - /* if cur != NULL, we already found a state key and attached to it */ - if (cur == NULL && (cur = RB_INSERT(pf_state_tree_ext_gwy, - &pf_statetbl_ext_gwy, s->state_key)) != NULL) { - /* must not happen. we must have found the sk above! */ - pf_stateins_err("tree_ext_gwy", s, kif); - pf_detach_state(s, PF_DT_SKIP_EXTGWY); - return (-1); + pf_detach_state(s, PF_DT_SKIP_STATETREE); + /* RYAN PF_SK_BOTH not gut for nat shitz */ + pf_attach_state(cur, s, kif == pfi_all ? 1 : 0, PF_SK_BOTH); } if (s->id == 0 && s->creatorid == 0) { @@ -867,11 +775,65 @@ pf_insert_state(struct pfi_kif *kif, struct pf_state *s) pf_status.states++; pfi_kif_ref(kif, PFI_KIF_REF_STATE); #if NPFSYNC +#ifdef XXX_PFSYNC_FIXED pfsync_insert_state(s); #endif +#endif return (0); } +struct pf_state * +pf_find_state_byid(struct pf_state_cmp *key) +{ + pf_status.fcounters[FCNT_STATE_SEARCH]++; + + return (RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state *)key)); +} + +struct pf_state * +pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int dir) +{ + struct pf_state_key *sk; + struct pf_state_item *si; + + pf_status.fcounters[FCNT_STATE_SEARCH]++; + + if ((sk = RB_FIND(pf_state_tree, &pf_statetbl, + (struct pf_state_key *)key)) == NULL) + return (NULL); + + /* list is sorted, if-bound states before floating ones */ + TAILQ_FOREACH(si, &sk->states, entry) + if ((si->s->kif == pfi_all || si->s->kif == kif) && + ((dir == si->s->direction && si->s->key_wire == sk) || + (dir != si->s->direction && si->s->key_stack == sk))) + return (si->s); + return (NULL); +} + +struct pf_state * +pf_find_state_all(struct pf_state_key_cmp *key, u_int dir, int *more) +{ + struct pf_state_key *sk; + struct pf_state_item *si, *ret = NULL; + + pf_status.fcounters[FCNT_STATE_SEARCH]++; + + sk = RB_FIND(pf_state_tree, &pf_statetbl, (struct pf_state_key *)key); + + if (sk != NULL) { + ret = TAILQ_FIRST(&sk->states); + if (more != NULL) + TAILQ_FOREACH(si, &sk->states, entry) + (*more)++; + } + + return (ret ? ret->s : NULL); +} + +/* END state table stuff */ + + void pf_purge_thread(void *v) { @@ -1000,9 +962,10 @@ void pf_unlink_state(struct pf_state *cur) { if (cur->src.state == PF_TCPS_PROXY_DST) { - pf_send_tcp(cur->rule.ptr, cur->state_key->af, - &cur->state_key->ext.addr, &cur->state_key->lan.addr, - cur->state_key->ext.port, cur->state_key->lan.port, + /* XXX wire key the right one? */ + pf_send_tcp(cur->rule.ptr, cur->key_wire->af, + &cur->key_wire->addr2, &cur->key_wire->addr1, + cur->key_wire->port2, cur->key_wire->port1, cur->src.seqhi, cur->src.seqlo + 1, TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL); } @@ -1189,7 +1152,7 @@ pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af) void pf_print_state(struct pf_state *s) { - struct pf_state_key *sk = s->state_key; + struct pf_state_key *sk = s->key_wire; switch (sk->proto) { case IPPROTO_TCP: printf("TCP "); @@ -1207,11 +1170,13 @@ pf_print_state(struct pf_state *s) printf("%u ", sk->proto); break; } - pf_print_host(&sk->lan.addr, sk->lan.port, sk->af); + pf_print_host(&sk->addr1, sk->port1, sk->af); printf(" "); - pf_print_host(&sk->gwy.addr, sk->gwy.port, sk->af); + pf_print_host(&sk->addr2, sk->port2, sk->af); +#ifdef RYAN_NAT printf(" "); - pf_print_host(&sk->ext.addr, sk->ext.port, sk->af); + pf_print_host(&sk->addr2, sk->ext.port, sk->af); +#endif printf(" [lo=%u high=%u win=%u modulator=%u", s->src.seqlo, s->src.seqhi, s->src.max_win, s->src.seqdiff); if (s->src.wscale && s->dst.wscale) @@ -2289,6 +2254,7 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high, struct pf_src_node **sn) { +#ifdef RYAN_NAT struct pf_state_key_cmp key; struct pf_addr init_addr; u_int16_t cut; @@ -2305,9 +2271,9 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, do { key.af = af; key.proto = proto; - PF_ACPY(&key.ext.addr, daddr, key.af); - PF_ACPY(&key.gwy.addr, naddr, key.af); - key.ext.port = dport; + PF_ACPY(&key.addr2, daddr, key.af); + PF_ACPY(&key.addr1, naddr, key.af); + key.port2 = dport; /* * port search; start random, step; @@ -2370,7 +2336,7 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, return (1); } } while (! PF_AEQ(&init_addr, naddr, af) ); - +#endif return (1); /* none available */ } @@ -2821,7 +2787,7 @@ pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr) s->rt_kif = NULL; if (!r->rt || r->rt == PF_FASTROUTE) return; - switch (s->state_key->af) { + switch (s->key_wire->af) { #ifdef INET case AF_INET: pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, @@ -2839,53 +2805,6 @@ pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr) } } -void -pf_attach_state(struct pf_state_key *sk, struct pf_state *s, int tail) -{ - s->state_key = sk; - - /* list is sorted, if-bound states before floating */ - if (tail) - TAILQ_INSERT_TAIL(&sk->states, s, next); - else - TAILQ_INSERT_HEAD(&sk->states, s, next); -} - -void -pf_detach_state(struct pf_state *s, int flags) -{ - struct pf_state_key *sk = s->state_key; - - if (sk == NULL) - return; - - s->state_key = NULL; - TAILQ_REMOVE(&sk->states, s, next); - if (TAILQ_EMPTY(&sk->states)) { - if (!(flags & PF_DT_SKIP_EXTGWY)) - RB_REMOVE(pf_state_tree_ext_gwy, - &pf_statetbl_ext_gwy, sk); - if (!(flags & PF_DT_SKIP_LANEXT)) - RB_REMOVE(pf_state_tree_lan_ext, - &pf_statetbl_lan_ext, sk); - pool_put(&pf_state_key_pl, sk); - } -} - -struct pf_state_key * -pf_alloc_state_key(struct pf_state *s) -{ - struct pf_state_key *sk; - - if ((sk = pool_get(&pf_state_key_pl, PR_NOWAIT)) == NULL) - return (NULL); - bzero(sk, sizeof(*sk)); - TAILQ_INIT(&sk->states); - pf_attach_state(sk, s, 0); - - return (sk); -} - u_int32_t pf_tcp_iss(struct pf_pdesc *pd) { @@ -3327,6 +3246,7 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction, return (PF_DROP); } +/* XXX state creation should be really factored out */ if (!state_icmp && (r->keep_state || nr != NULL || (pd->flags & PFDESC_TCP_NORM))) { /* create new state */ @@ -3475,64 +3395,56 @@ cleanup: return (PF_DROP); } } + s->direction = direction; - if ((sk = pf_alloc_state_key(s)) == NULL) { + if ((sk = pf_alloc_state_key()) == NULL) { REASON_SET(&reason, PFRES_MEMORY); goto cleanup; } - sk->proto = pd->proto; - sk->direction = direction; sk->af = af; - if (direction == PF_OUT) { - PF_ACPY(&sk->gwy.addr, saddr, af); - PF_ACPY(&sk->ext.addr, daddr, af); + if (direction == PF_IN) { + PF_ACPY(&sk->addr1, saddr, af); + PF_ACPY(&sk->addr2, daddr, af); switch (pd->proto) { case IPPROTO_ICMP: #ifdef INET6 case IPPROTO_ICMPV6: #endif - sk->gwy.port = nport; - sk->ext.port = 0; + sk->port1 = nport; + sk->port2 = 0; break; default: - sk->gwy.port = sport; - sk->ext.port = dport; + sk->port1 = sport; + sk->port2 = dport; } if (nr != NULL) { - PF_ACPY(&sk->lan.addr, &pd->baddr, af); - sk->lan.port = bport; - } else { - PF_ACPY(&sk->lan.addr, &sk->gwy.addr, af); - sk->lan.port = sk->gwy.port; +/* RYAN NAT */ } } else { - PF_ACPY(&sk->lan.addr, daddr, af); - PF_ACPY(&sk->ext.addr, saddr, af); + PF_ACPY(&sk->addr2, saddr, af); + PF_ACPY(&sk->addr1, daddr, af); switch (pd->proto) { case IPPROTO_ICMP: #ifdef INET6 case IPPROTO_ICMPV6: #endif - sk->lan.port = nport; - sk->ext.port = 0; + sk->port2 = nport; + sk->port1 = 0; break; default: - sk->lan.port = dport; - sk->ext.port = sport; + sk->port2 = sport; + sk->port1 = dport; } if (nr != NULL) { - PF_ACPY(&sk->gwy.addr, &pd->baddr, af); - sk->gwy.port = bport; - } else { - PF_ACPY(&sk->gwy.addr, &sk->lan.addr, af); - sk->gwy.port = sk->lan.port; +/* RYAN NAT */ } } + pf_attach_state(sk, s, 0, PF_SK_BOTH); pf_set_rt_ifp(s, saddr); /* needs s->state_key set */ - if (pf_insert_state(BOUND_IFACE(r, kif), s)) { + if (pf_state_insert(BOUND_IFACE(r, kif), sk, s)) { if (pd->proto == IPPROTO_TCP) pf_normalize_tcp_cleanup(s); REASON_SET(&reason, PFRES_STATEINS); @@ -3687,21 +3599,21 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, key.af = pd->af; key.proto = IPPROTO_TCP; - if (direction == PF_IN) { - PF_ACPY(&key.ext.addr, pd->src, key.af); - PF_ACPY(&key.gwy.addr, pd->dst, key.af); - key.ext.port = th->th_sport; - key.gwy.port = th->th_dport; - } else { - PF_ACPY(&key.lan.addr, pd->src, key.af); - PF_ACPY(&key.ext.addr, pd->dst, key.af); - key.lan.port = th->th_sport; - key.ext.port = th->th_dport; + if (direction == PF_IN) { /* wire side, straight */ + PF_ACPY(&key.addr1, pd->src, key.af); + PF_ACPY(&key.addr2, pd->dst, key.af); + key.port1 = th->th_sport; + key.port2 = th->th_dport; + } else { /* stack side, reverse */ + PF_ACPY(&key.addr2, pd->src, key.af); + PF_ACPY(&key.addr1, pd->dst, key.af); + key.port2 = th->th_sport; + key.port1 = th->th_dport; } STATE_LOOKUP(); - if (direction == (*state)->state_key->direction) { + if (direction == (*state)->direction) { src = &(*state)->src; dst = &(*state)->dst; } else { @@ -3710,7 +3622,7 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, } if ((*state)->src.state == PF_TCPS_PROXY_SRC) { - if (direction != (*state)->state_key->direction) { + if (direction != (*state)->direction) { REASON_SET(reason, PFRES_SYNPROXY); return (PF_SYNPROXY_DROP); } @@ -3739,16 +3651,7 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, (*state)->src.state = PF_TCPS_PROXY_DST; } if ((*state)->src.state == PF_TCPS_PROXY_DST) { - struct pf_state_host *src, *dst; - - if (direction == PF_OUT) { - src = &(*state)->state_key->gwy; - dst = &(*state)->state_key->ext; - } else { - src = &(*state)->state_key->ext; - dst = &(*state)->state_key->lan; - } - if (direction == (*state)->state_key->direction) { + if (direction == (*state)->direction) { if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) || (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) { @@ -3758,8 +3661,8 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, (*state)->src.max_win = MAX(ntohs(th->th_win), 1); if ((*state)->dst.seqhi == 1) (*state)->dst.seqhi = htonl(arc4random()); - pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr, - &dst->addr, src->port, dst->port, + pf_send_tcp((*state)->rule.ptr, pd->af, &key.addr1, + &key.addr2, key.port1, key.port2, (*state)->dst.seqhi, 0, TH_SYN, 0, (*state)->src.mss, 0, 0, (*state)->tag, NULL, NULL); REASON_SET(reason, PFRES_SYNPROXY); @@ -3777,8 +3680,8 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, ntohl(th->th_ack), ntohl(th->th_seq) + 1, TH_ACK, (*state)->src.max_win, 0, 0, 0, (*state)->tag, NULL, NULL); - pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr, - &dst->addr, src->port, dst->port, + pf_send_tcp((*state)->rule.ptr, pd->af, &key.addr1, + &key.addr2, key.port1, key.port2, (*state)->src.seqhi + 1, (*state)->src.seqlo + 1, TH_ACK, (*state)->dst.max_win, 0, 0, 1, 0, NULL, NULL); @@ -4059,7 +3962,7 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, pd->p_len, ackskew, (*state)->packets[0], (*state)->packets[1], direction == PF_IN ? "in" : "out", - direction == (*state)->state_key->direction ? + direction == (*state)->direction ? "fwd" : "rev"); } @@ -4115,7 +4018,7 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, seq, orig_seq, ack, pd->p_len, ackskew, (*state)->packets[0], (*state)->packets[1], direction == PF_IN ? "in" : "out", - direction == (*state)->state_key->direction ? + direction == (*state)->direction ? "fwd" : "rev"); printf("pf: State failure on: %c %c %c %c | %c %c\n", SEQ_GEQ(src->seqhi, end) ? ' ' : '1', @@ -4132,6 +4035,8 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, /* Any packets which have gotten here are to be passed */ + +#ifdef RYAN_NAT /* translate source/destination address, if necessary */ if (STATE_TRANSLATE((*state)->state_key)) { if (direction == PF_OUT) @@ -4140,13 +4045,15 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, (*state)->state_key->gwy.port, 0, pd->af); else pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum, - &th->th_sum, &(*state)->state_key->lan.addr, + &th->th_sum, &(*state)->state_key->addr1, (*state)->state_key->lan.port, 0, pd->af); - m_copyback(m, off, sizeof(*th), th); - } else if (copyback) { - /* Copyback sequence modulation or stateful scrub changes */ - m_copyback(m, off, sizeof(*th), th); + copyback = 1; } +#endif + + /* Copyback sequence modulation or stateful scrub changes if needed */ + if (copyback) + m_copyback(m, off, sizeof(*th), th); return (PF_PASS); } @@ -4161,21 +4068,21 @@ pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif, key.af = pd->af; key.proto = IPPROTO_UDP; - if (direction == PF_IN) { - PF_ACPY(&key.ext.addr, pd->src, key.af); - PF_ACPY(&key.gwy.addr, pd->dst, key.af); - key.ext.port = uh->uh_sport; - key.gwy.port = uh->uh_dport; - } else { - PF_ACPY(&key.lan.addr, pd->src, key.af); - PF_ACPY(&key.ext.addr, pd->dst, key.af); - key.lan.port = uh->uh_sport; - key.ext.port = uh->uh_dport; + if (direction == PF_IN) { /* wire side, straight */ + PF_ACPY(&key.addr1, pd->src, key.af); + PF_ACPY(&key.addr2, pd->dst, key.af); + key.port1 = uh->uh_sport; + key.port2 = uh->uh_dport; + } else { /* stack side, reverse */ + PF_ACPY(&key.addr2, pd->src, key.af); + PF_ACPY(&key.addr1, pd->dst, key.af); + key.port2 = uh->uh_sport; + key.port1 = uh->uh_dport; } STATE_LOOKUP(); - if (direction == (*state)->state_key->direction) { + if (direction == (*state)->direction) { src = &(*state)->src; dst = &(*state)->dst; } else { @@ -4196,6 +4103,7 @@ pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif, else (*state)->timeout = PFTM_UDP_SINGLE; +#ifdef RYAN_NAT /* translate source/destination address, if necessary */ if (STATE_TRANSLATE((*state)->state_key)) { if (direction == PF_OUT) @@ -4204,10 +4112,11 @@ pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif, (*state)->state_key->gwy.port, 1, pd->af); else pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum, - &uh->uh_sum, &(*state)->state_key->lan.addr, + &uh->uh_sum, &(*state)->state_key->addr1, (*state)->state_key->lan.port, 1, pd->af); m_copyback(m, off, sizeof(*uh), uh); } +#endif return (PF_PASS); } @@ -4216,7 +4125,6 @@ int pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason) { - struct pf_addr *saddr = pd->src, *daddr = pd->dst; u_int16_t icmpid, *icmpsum; u_int8_t icmptype; int state_icmp = 0; @@ -4260,16 +4168,16 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, */ key.af = pd->af; key.proto = pd->proto; - if (direction == PF_IN) { - PF_ACPY(&key.ext.addr, pd->src, key.af); - PF_ACPY(&key.gwy.addr, pd->dst, key.af); - key.ext.port = 0; - key.gwy.port = icmpid; - } else { - PF_ACPY(&key.lan.addr, pd->src, key.af); - PF_ACPY(&key.ext.addr, pd->dst, key.af); - key.lan.port = icmpid; - key.ext.port = 0; + if (direction == PF_IN) { /* wire side, straight */ + PF_ACPY(&key.addr1, pd->src, key.af); + PF_ACPY(&key.addr2, pd->dst, key.af); + key.port1 = icmpid; + key.port2 = 0; + } else { /* stack side, reverse */ + PF_ACPY(&key.addr2, pd->src, key.af); + PF_ACPY(&key.addr1, pd->dst, key.af); + key.port2 = 0; + key.port1 = icmpid; } STATE_LOOKUP(); @@ -4277,6 +4185,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, (*state)->expire = time_second; (*state)->timeout = PFTM_ICMP_ERROR_REPLY; +#ifdef RYAN_NAT /* translate source/destination address, if necessary */ if (STATE_TRANSLATE((*state)->state_key)) { if (direction == PF_OUT) { @@ -4313,7 +4222,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, case AF_INET: pf_change_a(&daddr->v4.s_addr, pd->ip_sum, - (*state)->state_key->lan.addr.v4.s_addr, 0); + (*state)->state_key->addr1.v4.s_addr, 0); pd->hdr.icmp->icmp_cksum = pf_cksum_fixup( pd->hdr.icmp->icmp_cksum, icmpid, @@ -4328,7 +4237,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, case AF_INET6: pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum, - &(*state)->state_key->lan.addr, 0); + &(*state)->state_key->addr1, 0); m_copyback(m, off, sizeof(struct icmp6_hdr), pd->hdr.icmp6); @@ -4337,7 +4246,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, } } } - +#endif /* RYAN_NAT */ return (PF_PASS); } else { @@ -4468,21 +4377,21 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, key.af = pd2.af; key.proto = IPPROTO_TCP; - if (direction == PF_IN) { - PF_ACPY(&key.ext.addr, pd2.dst, key.af); - PF_ACPY(&key.gwy.addr, pd2.src, key.af); - key.ext.port = th.th_dport; - key.gwy.port = th.th_sport; - } else { - PF_ACPY(&key.lan.addr, pd2.dst, key.af); - PF_ACPY(&key.ext.addr, pd2.src, key.af); - key.lan.port = th.th_dport; - key.ext.port = th.th_sport; + if (direction == PF_IN) { /* wire, straight */ + PF_ACPY(&key.addr1, pd2.src, key.af); + PF_ACPY(&key.addr2, pd2.dst, key.af); + key.port1 = th.th_sport; + key.port2 = th.th_dport; + } else { /* stack, reverse */ + PF_ACPY(&key.addr2, pd2.src, key.af); + PF_ACPY(&key.addr1, pd2.dst, key.af); + key.port2 = th.th_sport; + key.port1 = th.th_dport; } STATE_LOOKUP(); - if (direction == (*state)->state_key->direction) { + if (direction == (*state)->direction) { src = &(*state)->dst; dst = &(*state)->src; } else { @@ -4519,10 +4428,11 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, return (PF_DROP); } +#ifdef RYAN_NAT if (STATE_TRANSLATE((*state)->state_key)) { if (direction == PF_IN) { pf_change_icmp(pd2.src, &th.th_sport, - daddr, &(*state)->state_key->lan.addr, + daddr, &(*state)->state_key->addr1, (*state)->state_key->lan.port, NULL, pd2.ip_sum, icmpsum, pd->ip_sum, 0, pd2.af); @@ -4535,7 +4445,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, } copyback = 1; } - +#endif if (copyback) { switch (pd2.af) { #ifdef INET @@ -4575,25 +4485,25 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, key.af = pd2.af; key.proto = IPPROTO_UDP; - if (direction == PF_IN) { - PF_ACPY(&key.ext.addr, pd2.dst, key.af); - PF_ACPY(&key.gwy.addr, pd2.src, key.af); - key.ext.port = uh.uh_dport; - key.gwy.port = uh.uh_sport; - } else { - PF_ACPY(&key.lan.addr, pd2.dst, key.af); - PF_ACPY(&key.ext.addr, pd2.src, key.af); - key.lan.port = uh.uh_dport; - key.ext.port = uh.uh_sport; + if (direction == PF_IN) { /* wire, straight */ + PF_ACPY(&key.addr1, pd2.src, key.af); + PF_ACPY(&key.addr2, pd2.dst, key.af); + key.port1 = uh.uh_sport; + key.port2 = uh.uh_dport; + } else { /* stack, reverse */ + PF_ACPY(&key.addr2, pd2.src, key.af); + PF_ACPY(&key.addr1, pd2.dst, key.af); + key.port2 = uh.uh_sport; + key.port1 = uh.uh_dport; } STATE_LOOKUP(); - +#ifdef RYAN_NAT if (STATE_TRANSLATE((*state)->state_key)) { if (direction == PF_IN) { pf_change_icmp(pd2.src, &uh.uh_sport, daddr, - &(*state)->state_key->lan.addr, + &(*state)->state_key->addr1, (*state)->state_key->lan.port, &uh.uh_sum, pd2.ip_sum, icmpsum, @@ -4626,7 +4536,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, } m_copyback(m, off2, sizeof(uh), &uh); } - +#endif return (PF_PASS); break; } @@ -4644,25 +4554,32 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, key.af = pd2.af; key.proto = IPPROTO_ICMP; - if (direction == PF_IN) { - PF_ACPY(&key.ext.addr, pd2.dst, key.af); - PF_ACPY(&key.gwy.addr, pd2.src, key.af); - key.ext.port = 0; - key.gwy.port = iih.icmp_id; - } else { - PF_ACPY(&key.lan.addr, pd2.dst, key.af); - PF_ACPY(&key.ext.addr, pd2.src, key.af); - key.lan.port = iih.icmp_id; - key.ext.port = 0; + if (direction == PF_IN) { /* wire, straight */ + PF_ACPY(&key.addr1, pd2.src, key.af); + PF_ACPY(&key.addr2, pd2.dst, key.af); + key.port1 = 0; + key.port2 = iih.icmp_id; + } else { /* stack, reverse */ + PF_ACPY(&key.addr2, pd2.src, key.af); + PF_ACPY(&key.addr1, pd2.dst, key.af); + key.port2 = 0; + key.port1 = iih.icmp_id; } +printf("pf: state search icmp repl: %s", kif->pfik_name); +printf(" addr1: "); +pf_print_host(&key.addr1, key.port1, pd->af); +printf(" addr2: "); +pf_print_host(&key.addr2, key.port2, pd->af); +printf("\n"); STATE_LOOKUP(); +#ifdef RYAN_NAT if (STATE_TRANSLATE((*state)->state_key)) { if (direction == PF_IN) { pf_change_icmp(pd2.src, &iih.icmp_id, daddr, - &(*state)->state_key->lan.addr, + &(*state)->state_key->addr1, (*state)->state_key->lan.port, NULL, pd2.ip_sum, icmpsum, pd->ip_sum, 0, AF_INET); @@ -4678,7 +4595,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, m_copyback(m, ipoff2, sizeof(h2), &h2); m_copyback(m, off2, ICMP_MINLEN, &iih); } - +#endif return (PF_PASS); break; } @@ -4698,24 +4615,25 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, key.af = pd2.af; key.proto = IPPROTO_ICMPV6; if (direction == PF_IN) { - PF_ACPY(&key.ext.addr, pd2.dst, key.af); - PF_ACPY(&key.gwy.addr, pd2.src, key.af); - key.ext.port = 0; - key.gwy.port = iih.icmp6_id; + PF_ACPY(&key.addr1, pd2.dst, key.af); + PF_ACPY(&key.addr2, pd2.src, key.af); + key.port1 = 0; + key.port2 = iih.icmp6_id; } else { - PF_ACPY(&key.lan.addr, pd2.dst, key.af); - PF_ACPY(&key.ext.addr, pd2.src, key.af); - key.lan.port = iih.icmp6_id; - key.ext.port = 0; + PF_ACPY(&key.addr2, pd2.src, key.af); + PF_ACPY(&key.addr1, pd2.dst, key.af); + key.port2 = 0; + key.port1 = iih.icmp6_id; } STATE_LOOKUP(); +#ifdef RYAN_NAT if (STATE_TRANSLATE((*state)->state_key)) { if (direction == PF_IN) { pf_change_icmp(pd2.src, &iih.icmp6_id, daddr, - &(*state)->state_key->lan.addr, + &(*state)->state_key->addr1, (*state)->state_key->lan.port, NULL, pd2.ip_sum, icmpsum, pd->ip_sum, 0, AF_INET6); @@ -4732,7 +4650,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, m_copyback(m, off2, sizeof(struct icmp6_hdr), &iih); } - +#endif return (PF_PASS); break; } @@ -4741,24 +4659,25 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, key.af = pd2.af; key.proto = pd2.proto; if (direction == PF_IN) { - PF_ACPY(&key.ext.addr, pd2.dst, key.af); - PF_ACPY(&key.gwy.addr, pd2.src, key.af); - key.ext.port = 0; - key.gwy.port = 0; + PF_ACPY(&key.addr1, pd2.src, key.af); + PF_ACPY(&key.addr2, pd2.dst, key.af); + key.port1 = 0; + key.port2 = 0; } else { - PF_ACPY(&key.lan.addr, pd2.dst, key.af); - PF_ACPY(&key.ext.addr, pd2.src, key.af); - key.lan.port = 0; - key.ext.port = 0; + PF_ACPY(&key.addr2, pd2.src, key.af); + PF_ACPY(&key.addr1, pd2.dst, key.af); + key.port2 = 0; + key.port1 = 0; } STATE_LOOKUP(); +#ifdef RYAN_NAT if (STATE_TRANSLATE((*state)->state_key)) { if (direction == PF_IN) { pf_change_icmp(pd2.src, NULL, daddr, - &(*state)->state_key->lan.addr, + &(*state)->state_key->addr1, 0, NULL, pd2.ip_sum, icmpsum, pd->ip_sum, 0, pd2.af); @@ -4789,7 +4708,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, #endif /* INET6 */ } } - +#endif return (PF_PASS); break; } @@ -4807,20 +4726,20 @@ pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif, key.af = pd->af; key.proto = pd->proto; if (direction == PF_IN) { - PF_ACPY(&key.ext.addr, pd->src, key.af); - PF_ACPY(&key.gwy.addr, pd->dst, key.af); - key.ext.port = 0; - key.gwy.port = 0; + PF_ACPY(&key.addr1, pd->src, key.af); + PF_ACPY(&key.addr2, pd->dst, key.af); + key.port1 = 0; + key.port2 = 0; } else { - PF_ACPY(&key.lan.addr, pd->src, key.af); - PF_ACPY(&key.ext.addr, pd->dst, key.af); - key.lan.port = 0; - key.ext.port = 0; + PF_ACPY(&key.addr2, pd->src, key.af); + PF_ACPY(&key.addr1, pd->dst, key.af); + key.port2 = 0; + key.port1 = 0; } STATE_LOOKUP(); - if (direction == (*state)->state_key->direction) { + if (direction == (*state)->direction) { src = &(*state)->src; dst = &(*state)->dst; } else { @@ -4841,6 +4760,7 @@ pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif, else (*state)->timeout = PFTM_OTHER_SINGLE; +#ifdef RYAN_NAT /* translate source/destination address, if necessary */ if (STATE_TRANSLATE((*state)->state_key)) { if (direction == PF_OUT) @@ -4866,19 +4786,19 @@ pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif, case AF_INET: pf_change_a(&pd->dst->v4.s_addr, pd->ip_sum, - (*state)->state_key->lan.addr.v4.s_addr, + (*state)->state_key->addr1.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: PF_ACPY(pd->dst, - &(*state)->state_key->lan.addr, pd->af); + &(*state)->state_key->addr1, pd->af); break; #endif /* INET6 */ } } - +#endif return (PF_PASS); } @@ -5498,7 +5418,6 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct ip *h; struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; struct pf_state *s = NULL; - struct pf_state_key *sk = NULL; struct pf_ruleset *ruleset = NULL; struct pf_pdesc pd; int off, dirndx, pqid = 0; @@ -5739,7 +5658,6 @@ done: a->bytes[dirndx] += pd.tot_len; } if (s != NULL) { - sk = s->state_key; if (s->nat_rule.ptr != NULL) { s->nat_rule.ptr->packets[dirndx]++; s->nat_rule.ptr->bytes[dirndx] += pd.tot_len; @@ -5752,7 +5670,7 @@ done: s->nat_src_node->packets[dirndx]++; s->nat_src_node->bytes[dirndx] += pd.tot_len; } - dirndx = (dir == sk->direction) ? 0 : 1; + dirndx = (dir == s->direction) ? 0 : 1; s->packets[dirndx]++; s->bytes[dirndx] += pd.tot_len; } @@ -5767,10 +5685,10 @@ done: */ if (r == &pf_default_rule) { tr = nr; - x = (sk == NULL || sk->direction == dir) ? + x = (s == NULL || s->direction == dir) ? &pd.baddr : &pd.naddr; } else - x = (sk == NULL || sk->direction == dir) ? + x = (s == NULL || s->direction == dir) ? &pd.naddr : &pd.baddr; if (x == &pd.baddr || s == NULL) { /* we need to change the address */ @@ -5781,14 +5699,14 @@ done: } } if (tr->src.addr.type == PF_ADDR_TABLE) - pfr_update_stats(tr->src.addr.p.tbl, (sk == NULL || - sk->direction == dir) ? + pfr_update_stats(tr->src.addr.p.tbl, (s == NULL || + s->direction == dir) ? pd.src : pd.dst, pd.af, pd.tot_len, dir == PF_OUT, r->action == PF_PASS, tr->src.neg); if (tr->dst.addr.type == PF_ADDR_TABLE) - pfr_update_stats(tr->dst.addr.p.tbl, (sk == NULL || - sk->direction == dir) ? pd.dst : pd.src, pd.af, + pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL || + s->direction == dir) ? pd.dst : pd.src, pd.af, pd.tot_len, dir == PF_OUT, r->action == PF_PASS, tr->dst.neg); } @@ -5817,7 +5735,6 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, struct ip6_hdr *h; struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; struct pf_state *s = NULL; - struct pf_state_key *sk = NULL; struct pf_ruleset *ruleset = NULL; struct pf_pdesc pd; int off, terminal = 0, dirndx, rh_cnt = 0; @@ -6125,7 +6042,6 @@ done: a->bytes[dirndx] += pd.tot_len; } if (s != NULL) { - sk = s->state_key; if (s->nat_rule.ptr != NULL) { s->nat_rule.ptr->packets[dirndx]++; s->nat_rule.ptr->bytes[dirndx] += pd.tot_len; @@ -6138,7 +6054,7 @@ done: s->nat_src_node->packets[dirndx]++; s->nat_src_node->bytes[dirndx] += pd.tot_len; } - dirndx = (dir == sk->direction) ? 0 : 1; + dirndx = (dir == s->direction) ? 0 : 1; s->packets[dirndx]++; s->bytes[dirndx] += pd.tot_len; } @@ -6153,10 +6069,10 @@ done: */ if (r == &pf_default_rule) { tr = nr; - x = (s == NULL || sk->direction == dir) ? + x = (s == NULL || s->direction == dir) ? &pd.baddr : &pd.naddr; } else { - x = (s == NULL || sk->direction == dir) ? + x = (s == NULL || s->direction == dir) ? &pd.naddr : &pd.baddr; } if (x == &pd.baddr || s == NULL) { @@ -6167,13 +6083,13 @@ done: } } if (tr->src.addr.type == PF_ADDR_TABLE) - pfr_update_stats(tr->src.addr.p.tbl, (sk == NULL || - sk->direction == dir) ? pd.src : pd.dst, pd.af, + pfr_update_stats(tr->src.addr.p.tbl, (s == NULL || + s->direction == dir) ? pd.src : pd.dst, pd.af, pd.tot_len, dir == PF_OUT, r->action == PF_PASS, tr->src.neg); if (tr->dst.addr.type == PF_ADDR_TABLE) - pfr_update_stats(tr->dst.addr.p.tbl, (sk == NULL || - sk->direction == dir) ? pd.dst : pd.src, pd.af, + pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL || + s->direction == dir) ? pd.dst : pd.src, pd.af, pd.tot_len, dir == PF_OUT, r->action == PF_PASS, tr->dst.neg); } diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c index 63065d66019..4b1469149a3 100644 --- a/sys/net/pf_ioctl.c +++ b/sys/net/pf_ioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_ioctl.c,v 1.197 2008/05/18 11:54:04 mcbride Exp $ */ +/* $OpenBSD: pf_ioctl.c,v 1.198 2008/05/29 00:28:08 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -110,7 +110,7 @@ void pf_hash_rule(MD5_CTX *, struct pf_rule *); void pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *); int pf_commit_rules(u_int32_t, int, char *); void pf_state_export(struct pfsync_state *, - struct pf_state_key *, struct pf_state *); + struct pf_state *); void pf_state_import(struct pfsync_state *, struct pf_state_key *, struct pf_state *); @@ -149,6 +149,8 @@ pfattach(int num) NULL); pool_init(&pf_state_key_pl, sizeof(struct pf_state_key), 0, 0, 0, "pfstatekeypl", NULL); + pool_init(&pf_state_item_pl, sizeof(struct pf_state_item), 0, 0, 0, + "pfstateitempl", NULL); pool_init(&pf_altq_pl, sizeof(struct pf_altq), 0, 0, 0, "pfaltqpl", &pool_allocator_nointr); pool_init(&pf_pooladdr_pl, sizeof(struct pf_pooladdr), 0, 0, 0, @@ -842,22 +844,22 @@ pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor) } void -pf_state_export(struct pfsync_state *sp, struct pf_state_key *sk, - struct pf_state *s) +pf_state_export(struct pfsync_state *sp, struct pf_state *s) { int secs = time_second; bzero(sp, sizeof(struct pfsync_state)); +/* XXX_RYAN_NAT */ /* copy from state key */ - sp->lan.addr = sk->lan.addr; - sp->lan.port = sk->lan.port; - sp->gwy.addr = sk->gwy.addr; - sp->gwy.port = sk->gwy.port; - sp->ext.addr = sk->ext.addr; - sp->ext.port = sk->ext.port; - sp->proto = sk->proto; - sp->af = sk->af; - sp->direction = sk->direction; + sp->lan.addr = s->key_wire->addr2; + sp->lan.port = s->key_wire->port2; + sp->gwy.addr = s->key_wire->addr2; + sp->gwy.port = s->key_wire->port2; + sp->ext.addr = s->key_wire->addr1; + sp->ext.port = s->key_wire->port1; + sp->proto = s->key_wire->proto; + sp->af = s->key_wire->af; + sp->direction = s->direction; /* copy from state */ memcpy(&sp->id, &s->id, sizeof(sp->id)); @@ -897,22 +899,23 @@ pf_state_import(struct pfsync_state *sp, struct pf_state_key *sk, struct pf_state *s) { /* copy to state key */ +#ifdef XXX_RYAN_HENNING_PFSYNC_FIXED sk->lan.addr = sp->lan.addr; sk->lan.port = sp->lan.port; sk->gwy.addr = sp->gwy.addr; sk->gwy.port = sp->gwy.port; sk->ext.addr = sp->ext.addr; sk->ext.port = sp->ext.port; +#endif sk->proto = sp->proto; sk->af = sp->af; - sk->direction = sp->direction; - /* copy to state */ memcpy(&s->id, &sp->id, sizeof(sp->id)); s->creatorid = sp->creatorid; pf_state_peer_from_pfsync(&sp->src, &s->src); pf_state_peer_from_pfsync(&sp->dst, &s->dst); + s->direction = sp->direction; s->rule.ptr = &pf_default_rule; s->nat_rule.ptr = NULL; s->anchor.ptr = NULL; @@ -1583,7 +1586,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) case DIOCKILLSTATES: { struct pf_state *s, *nexts; struct pf_state_key *sk; - struct pf_state_host *src, *dst; + struct pf_addr *srcaddr, *dstaddr; + u_int16_t srcport, dstport; struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr; u_int killed = 0; @@ -1605,14 +1609,18 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) for (s = RB_MIN(pf_state_tree_id, &tree_id); s; s = nexts) { nexts = RB_NEXT(pf_state_tree_id, &tree_id, s); - sk = s->state_key; + sk = s->key_wire; - if (sk->direction == PF_OUT) { - src = &sk->lan; - dst = &sk->ext; + if (s->direction == PF_OUT) { + srcaddr = &sk->addr2; + dstaddr = &sk->addr1; + srcport = sk->port2; + dstport = sk->port1; } else { - src = &sk->ext; - dst = &sk->lan; + srcaddr = &sk->addr1; + dstaddr = &sk->addr2; + srcport = sk->port2; + dstport = sk->port1; } if ((!psk->psk_af || sk->af == psk->psk_af) && (!psk->psk_proto || psk->psk_proto == @@ -1620,19 +1628,19 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) PF_MATCHA(psk->psk_src.neg, &psk->psk_src.addr.v.a.addr, &psk->psk_src.addr.v.a.mask, - &src->addr, sk->af) && + srcaddr, sk->af) && PF_MATCHA(psk->psk_dst.neg, &psk->psk_dst.addr.v.a.addr, &psk->psk_dst.addr.v.a.mask, - &dst->addr, sk->af) && + dstaddr, sk->af) && (psk->psk_src.port_op == 0 || pf_match_port(psk->psk_src.port_op, psk->psk_src.port[0], psk->psk_src.port[1], - src->port)) && + srcport)) && (psk->psk_dst.port_op == 0 || pf_match_port(psk->psk_dst.port_op, psk->psk_dst.port[0], psk->psk_dst.port[1], - dst->port)) && + dstport)) && (!psk->psk_label[0] || (s->rule.ptr->label[0] && !strcmp(psk->psk_label, s->rule.ptr->label))) && (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname, @@ -1668,12 +1676,13 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } bzero(s, sizeof(struct pf_state)); - if ((sk = pf_alloc_state_key(s)) == NULL) { + if ((sk = pf_alloc_state_key()) == NULL) { pool_put(&pf_state_pl, s); error = ENOMEM; break; } pf_state_import(sp, sk, s); +/* RYAN NAT */ pf_attach_state(sk, s, 0, PF_SK_BOTH); kif = pfi_kif_get(sp->ifname); if (kif == NULL) { pool_put(&pf_state_pl, s); @@ -1681,7 +1690,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = ENOENT; break; } - if (pf_insert_state(kif, s)) { + if (pf_state_insert(kif, sk, s)) { pfi_kif_unref(kif, PFI_KIF_REF_NONE); pool_put(&pf_state_pl, s); error = EEXIST; @@ -1705,7 +1714,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } - pf_state_export(&ps->state, s->state_key, s); + pf_state_export(&ps->state, s); break; } @@ -1730,9 +1739,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) if (state->timeout != PFTM_UNLINKED) { if ((nr+1) * sizeof(*p) > (unsigned)ps->ps_len) break; - - pf_state_export(pstore, - state->state_key, state); + pf_state_export(pstore, state); error = copyout(pstore, p, sizeof(*p)); if (error) { free(pstore, M_TEMP); @@ -1803,33 +1810,33 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) * state tree. */ if (direction == PF_IN) { - PF_ACPY(&key.ext.addr, &pnl->daddr, pnl->af); - key.ext.port = pnl->dport; - PF_ACPY(&key.gwy.addr, &pnl->saddr, pnl->af); - key.gwy.port = pnl->sport; + PF_ACPY(&key.addr1, &pnl->daddr, pnl->af); + key.port1 = pnl->dport; + PF_ACPY(&key.addr2, &pnl->saddr, pnl->af); + key.port2 = pnl->sport; state = pf_find_state_all(&key, PF_IN, &m); } else { - PF_ACPY(&key.lan.addr, &pnl->daddr, pnl->af); - key.lan.port = pnl->dport; - PF_ACPY(&key.ext.addr, &pnl->saddr, pnl->af); - key.ext.port = pnl->sport; + PF_ACPY(&key.addr2, &pnl->daddr, pnl->af); + key.port2 = pnl->dport; + PF_ACPY(&key.addr1, &pnl->saddr, pnl->af); + key.port1 = pnl->sport; state = pf_find_state_all(&key, PF_OUT, &m); } if (m > 1) error = E2BIG; /* more than one state */ else if (state != NULL) { - sk = state->state_key; + sk = state->key_wire; /* XXX which side? */ if (direction == PF_IN) { - PF_ACPY(&pnl->rsaddr, &sk->lan.addr, + PF_ACPY(&pnl->rsaddr, &sk->addr1, sk->af); - pnl->rsport = sk->lan.port; + pnl->rsport = sk->port1; PF_ACPY(&pnl->rdaddr, &pnl->daddr, pnl->af); pnl->rdport = pnl->dport; } else { - PF_ACPY(&pnl->rdaddr, &sk->gwy.addr, + PF_ACPY(&pnl->rdaddr, &sk->addr2, sk->af); - pnl->rdport = sk->gwy.port; + pnl->rdport = sk->port2; PF_ACPY(&pnl->rsaddr, &pnl->saddr, pnl->af); pnl->rsport = pnl->sport; diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index eedbdcf8614..a3515a08a05 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.267 2008/05/18 11:54:04 mcbride Exp $ */ +/* $OpenBSD: pfvar.h,v 1.268 2008/05/29 00:28:08 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -69,6 +69,7 @@ enum { PF_CHANGE_NONE, PF_CHANGE_ADD_HEAD, PF_CHANGE_ADD_TAIL, PF_CHANGE_ADD_BEFORE, PF_CHANGE_ADD_AFTER, PF_CHANGE_REMOVE, PF_CHANGE_GET_TICKET }; enum { PF_GET_NONE, PF_GET_CLR_CNTR }; +enum { PF_SK_NONE, PF_SK_WIRE, PF_SK_STACK, PF_SK_BOTH }; /* * Note about PFTM_*: real indices into pf_rule.timeout[] come before @@ -698,46 +699,50 @@ TAILQ_HEAD(pf_state_queue, pf_state); /* keep synced with struct pf_state_key, used in RB_FIND */ struct pf_state_key_cmp { - struct pf_state_host lan; - struct pf_state_host gwy; - struct pf_state_host ext; + struct pf_addr addr1; + struct pf_addr addr2; + u_int16_t port1; + u_int16_t port2; sa_family_t af; u_int8_t proto; - u_int8_t direction; - u_int8_t pad; + u_int8_t pad[2]; +}; + +struct pf_state_item { + TAILQ_ENTRY(pf_state_item) entry; + struct pf_state *s; }; -TAILQ_HEAD(pf_statelist, pf_state); +TAILQ_HEAD(pf_statelisthead, pf_state_item); struct pf_state_key { - struct pf_state_host lan; - struct pf_state_host gwy; - struct pf_state_host ext; + struct pf_addr addr1; + struct pf_addr addr2; + u_int16_t port1; + u_int16_t port2; sa_family_t af; u_int8_t proto; - u_int8_t direction; - u_int8_t pad; + u_int8_t pad[2]; - RB_ENTRY(pf_state_key) entry_lan_ext; - RB_ENTRY(pf_state_key) entry_ext_gwy; - struct pf_statelist states; + RB_ENTRY(pf_state_key) entry; + struct pf_statelisthead states; }; - /* keep synced with struct pf_state, used in RB_FIND */ struct pf_state_cmp { - u_int64_t id; - u_int32_t creatorid; - u_int32_t pad; + u_int64_t id; + u_int32_t creatorid; + u_int8_t direction; + u_int8_t pad[3]; }; struct pf_state { u_int64_t id; u_int32_t creatorid; - u_int32_t pad; + u_int8_t direction; + u_int8_t pad[3]; TAILQ_ENTRY(pf_state) entry_list; - TAILQ_ENTRY(pf_state) next; RB_ENTRY(pf_state) entry_id; struct pf_state_peer src; struct pf_state_peer dst; @@ -745,7 +750,8 @@ struct pf_state { union pf_rule_ptr anchor; union pf_rule_ptr nat_rule; struct pf_addr rt_addr; - struct pf_state_key *state_key; + struct pf_state_key *key_wire; /* addresses wire-side */ + struct pf_state_key *key_stack; /* addresses stack-side */ struct pfi_kif *kif; struct pfi_kif *rt_kif; struct pf_src_node *src_node; @@ -1013,9 +1019,8 @@ struct pfr_ktable { #define pfrkt_nomatch pfrkt_ts.pfrts_nomatch #define pfrkt_tzero pfrkt_ts.pfrts_tzero -RB_HEAD(pf_state_tree_lan_ext, pf_state_key); -RB_PROTOTYPE(pf_state_tree_lan_ext, pf_state_key, - entry_lan_ext, pf_state_compare_lan_ext); +RB_HEAD(pf_state_tree, pf_state_key); +RB_PROTOTYPE(pf_state_tree, pf_state_key, entry, pf_state_compare_key); RB_HEAD(pf_state_tree_ext_gwy, pf_state_key); RB_PROTOTYPE(pf_state_tree_ext_gwy, pf_state_key, @@ -1024,8 +1029,7 @@ RB_PROTOTYPE(pf_state_tree_ext_gwy, pf_state_key, RB_HEAD(pfi_ifhead, pfi_kif); /* state tables */ -extern struct pf_state_tree_lan_ext pf_statetbl_lan_ext; -extern struct pf_state_tree_ext_gwy pf_statetbl_ext_gwy; +extern struct pf_state_tree pf_statetbl; /* keep synced with pfi_kif, used in RB_FIND */ struct pfi_kif_cmp { @@ -1579,16 +1583,16 @@ extern void pf_tbladdr_remove(struct pf_addr_wrap *); extern void pf_tbladdr_copyout(struct pf_addr_wrap *); extern void pf_calc_skip_steps(struct pf_rulequeue *); extern struct pool pf_src_tree_pl, pf_rule_pl; -extern struct pool pf_state_pl, pf_state_key_pl, pf_altq_pl, - pf_pooladdr_pl; +extern struct pool pf_state_pl, pf_state_key_pl, pf_state_item_pl, + pf_altq_pl, pf_pooladdr_pl; extern struct pool pf_state_scrub_pl; extern void pf_purge_thread(void *); extern void pf_purge_expired_src_nodes(int); extern void pf_purge_expired_states(u_int32_t); extern void pf_unlink_state(struct pf_state *); extern void pf_free_state(struct pf_state *); -extern int pf_insert_state(struct pfi_kif *, - struct pf_state *); +extern int pf_state_insert(struct pfi_kif *, + struct pf_state_key *, struct pf_state *); extern int pf_insert_src_node(struct pf_src_node **, struct pf_rule *, struct pf_addr *, sa_family_t); @@ -1654,8 +1658,8 @@ void pf_purge_expired_fragments(void); int pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *); int pf_rtlabel_match(struct pf_addr *, sa_family_t, struct pf_addr_wrap *); int pf_socket_lookup(int, struct pf_pdesc *); -struct pf_state_key * - pf_alloc_state_key(struct pf_state *); +struct pf_state_key *pf_alloc_state_key(void); +void pf_attach_state(struct pf_state_key *, struct pf_state *, int, int); void pfr_initialize(void); 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, |