From owner-svn-src-all@FreeBSD.ORG Wed Dec 10 21:24:31 2008 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 701B11065675; Wed, 10 Dec 2008 21:24:31 +0000 (UTC) (envelope-from mlaier@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 5BA7E8FC25; Wed, 10 Dec 2008 21:24:31 +0000 (UTC) (envelope-from mlaier@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id mBALOVBB043443; Wed, 10 Dec 2008 21:24:31 GMT (envelope-from mlaier@svn.freebsd.org) Received: (from mlaier@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id mBALOVYN043439; Wed, 10 Dec 2008 21:24:31 GMT (envelope-from mlaier@svn.freebsd.org) Message-Id: <200812102124.mBALOVYN043439@svn.freebsd.org> From: Max Laier Date: Wed, 10 Dec 2008 21:24:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org X-SVN-Group: vendor-sys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r185888 - vendor-sys/pf/dist/net X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Dec 2008 21:24:31 -0000 Author: mlaier Date: Wed Dec 10 21:24:31 2008 New Revision: 185888 URL: http://svn.freebsd.org/changeset/base/185888 Log: Import OPENBSD_4_4_BASE Modified: vendor-sys/pf/dist/net/if_pfsync.c vendor-sys/pf/dist/net/if_pfsync.h vendor-sys/pf/dist/net/pf.c vendor-sys/pf/dist/net/pf_if.c vendor-sys/pf/dist/net/pf_ioctl.c vendor-sys/pf/dist/net/pf_norm.c vendor-sys/pf/dist/net/pf_osfp.c vendor-sys/pf/dist/net/pf_table.c vendor-sys/pf/dist/net/pfvar.h Modified: vendor-sys/pf/dist/net/if_pfsync.c ============================================================================== --- vendor-sys/pf/dist/net/if_pfsync.c Wed Dec 10 21:23:23 2008 (r185887) +++ vendor-sys/pf/dist/net/if_pfsync.c Wed Dec 10 21:24:31 2008 (r185888) @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pfsync.c,v 1.89 2008/01/12 17:08:33 mpf Exp $ */ +/* $OpenBSD: if_pfsync.c,v 1.98 2008/06/29 08:42:15 mcbride Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff @@ -89,7 +89,6 @@ int pfsync_clone_destroy(struct ifnet *) void pfsync_setmtu(struct pfsync_softc *, int); int pfsync_alloc_scrub_memory(struct pfsync_state_peer *, struct pf_state_peer *); -int pfsync_insert_net_state(struct pfsync_state *, u_int8_t); void pfsync_update_net_tdb(struct pfsync_tdb *); int pfsyncoutput(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); @@ -224,117 +223,218 @@ pfsync_alloc_scrub_memory(struct pfsync_ struct pf_state_peer *d) { if (s->scrub.scrub_flag && d->scrub == NULL) { - d->scrub = pool_get(&pf_state_scrub_pl, PR_NOWAIT); + d->scrub = pool_get(&pf_state_scrub_pl, PR_NOWAIT | PR_ZERO); if (d->scrub == NULL) return (ENOMEM); - bzero(d->scrub, sizeof(*d->scrub)); } return (0); } +void +pfsync_state_export(struct pfsync_state *sp, struct pf_state *st) +{ + bzero(sp, sizeof(struct pfsync_state)); + + /* copy from state key */ + sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0]; + sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1]; + sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0]; + sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1]; + sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0]; + sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1]; + sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0]; + sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1]; + sp->proto = st->key[PF_SK_WIRE]->proto; + sp->af = st->key[PF_SK_WIRE]->af; + + /* copy from state */ + strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname)); + bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr)); + sp->creation = htonl(time_second - st->creation); + sp->expire = pf_state_expires(st); + if (sp->expire <= time_second) + sp->expire = htonl(0); + else + sp->expire = htonl(sp->expire - time_second); + + sp->direction = st->direction; + sp->log = st->log; + sp->timeout = st->timeout; + sp->state_flags = st->state_flags; + if (st->src_node) + sp->sync_flags |= PFSYNC_FLAG_SRCNODE; + if (st->nat_src_node) + sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE; + + bcopy(&st->id, &sp->id, sizeof(sp->id)); + sp->creatorid = st->creatorid; + pf_state_peer_hton(&st->src, &sp->src); + pf_state_peer_hton(&st->dst, &sp->dst); + + if (st->rule.ptr == NULL) + sp->rule = htonl(-1); + else + sp->rule = htonl(st->rule.ptr->nr); + if (st->anchor.ptr == NULL) + sp->anchor = htonl(-1); + else + sp->anchor = htonl(st->anchor.ptr->nr); + if (st->nat_rule.ptr == NULL) + sp->nat_rule = htonl(-1); + else + sp->nat_rule = htonl(st->nat_rule.ptr->nr); + + pf_state_counter_hton(st->packets[0], sp->packets[0]); + pf_state_counter_hton(st->packets[1], sp->packets[1]); + pf_state_counter_hton(st->bytes[0], sp->bytes[0]); + pf_state_counter_hton(st->bytes[1], sp->bytes[1]); + +} + int -pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag) +pfsync_state_import(struct pfsync_state *sp, u_int8_t flags) { struct pf_state *st = NULL; - struct pf_state_key *sk = NULL; + struct pf_state_key *skw = NULL, *sks = NULL; struct pf_rule *r = NULL; struct pfi_kif *kif; + int pool_flags; + int error; if (sp->creatorid == 0 && pf_status.debug >= PF_DEBUG_MISC) { - printf("pfsync_insert_net_state: invalid creator id:" + printf("pfsync_state_import: invalid creator id:" " %08x\n", ntohl(sp->creatorid)); return (EINVAL); } - kif = pfi_kif_get(sp->ifname); - if (kif == NULL) { + if ((kif = pfi_kif_get(sp->ifname)) == NULL) { if (pf_status.debug >= PF_DEBUG_MISC) - printf("pfsync_insert_net_state: " + printf("pfsync_state_import: " "unknown interface: %s\n", sp->ifname); - /* skip this state */ - return (0); + if (flags & PFSYNC_SI_IOCTL) + return (EINVAL); + return (0); /* skip this state */ } /* - * If the ruleset checksums match, it's safe to associate the state - * with the rule of that number. + * If the ruleset checksums match or the state is coming from the ioctl, + * it's safe to associate the state with the rule of that number. */ - if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) && chksum_flag && - ntohl(sp->rule) < + if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) && + (flags & (PFSYNC_SI_IOCTL | PFSYNC_SI_CKSUM)) && ntohl(sp->rule) < pf_main_ruleset.rules[PF_RULESET_FILTER].active.rcount) r = pf_main_ruleset.rules[ PF_RULESET_FILTER].active.ptr_array[ntohl(sp->rule)]; else r = &pf_default_rule; - if (!r->max_states || r->states < r->max_states) - st = pool_get(&pf_state_pl, PR_NOWAIT); - if (st == NULL) { - pfi_kif_unref(kif, PFI_KIF_REF_NONE); - return (ENOMEM); - } - bzero(st, sizeof(*st)); + if ((r->max_states && r->states_cur >= r->max_states)) + goto cleanup; - if ((sk = pf_alloc_state_key(st)) == NULL) { - pool_put(&pf_state_pl, st); - pfi_kif_unref(kif, PFI_KIF_REF_NONE); - return (ENOMEM); - } + if (flags & PFSYNC_SI_IOCTL) + pool_flags = PR_WAITOK | PR_LIMITFAIL | PR_ZERO; + else + pool_flags = PR_LIMITFAIL | PR_ZERO; - /* allocate memory for scrub info */ - if (pfsync_alloc_scrub_memory(&sp->src, &st->src) || - pfsync_alloc_scrub_memory(&sp->dst, &st->dst)) { - pfi_kif_unref(kif, PFI_KIF_REF_NONE); - if (st->src.scrub) - pool_put(&pf_state_scrub_pl, st->src.scrub); - pool_put(&pf_state_pl, st); - pool_put(&pf_state_key_pl, sk); - return (ENOMEM); - } + if ((st = pool_get(&pf_state_pl, pool_flags)) == NULL) + goto cleanup; - st->rule.ptr = r; - /* XXX get pointers to nat_rule and anchor */ + if ((skw = pf_alloc_state_key(pool_flags)) == NULL) + goto cleanup; - /* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */ - r->states++; + if (PF_ANEQ(&sp->key[PF_SK_WIRE].addr[0], + &sp->key[PF_SK_STACK].addr[0], sp->af) || + PF_ANEQ(&sp->key[PF_SK_WIRE].addr[1], + &sp->key[PF_SK_STACK].addr[1], sp->af) || + sp->key[PF_SK_WIRE].port[0] != sp->key[PF_SK_STACK].port[0] || + sp->key[PF_SK_WIRE].port[1] != sp->key[PF_SK_STACK].port[1]) { + if ((sks = pf_alloc_state_key(pool_flags)) == NULL) + goto cleanup; + } else + sks = skw; - /* 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); + /* allocate memory for scrub info */ + if (pfsync_alloc_scrub_memory(&sp->src, &st->src) || + pfsync_alloc_scrub_memory(&sp->dst, &st->dst)) + goto cleanup; - pf_state_peer_ntoh(&sp->src, &st->src); - pf_state_peer_ntoh(&sp->dst, &st->dst); + /* copy to state key(s) */ + skw->addr[0] = sp->key[PF_SK_WIRE].addr[0]; + skw->addr[1] = sp->key[PF_SK_WIRE].addr[1]; + skw->port[0] = sp->key[PF_SK_WIRE].port[0]; + skw->port[1] = sp->key[PF_SK_WIRE].port[1]; + skw->proto = sp->proto; + skw->af = sp->af; + if (sks != skw) { + sks->addr[0] = sp->key[PF_SK_STACK].addr[0]; + sks->addr[1] = sp->key[PF_SK_STACK].addr[1]; + sks->port[0] = sp->key[PF_SK_STACK].port[0]; + sks->port[1] = sp->key[PF_SK_STACK].port[1]; + sks->proto = sp->proto; + sks->af = sp->af; + } + /* copy to state */ bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr)); st->creation = time_second - ntohl(sp->creation); - st->expire = ntohl(sp->expire) + time_second; + st->expire = time_second; + if (sp->expire) { + /* XXX No adaptive scaling. */ + st->expire -= r->timeout[sp->timeout] - ntohl(sp->expire); + } - sk->af = sp->af; - sk->proto = sp->proto; - sk->direction = sp->direction; + st->expire = ntohl(sp->expire) + time_second; + st->direction = sp->direction; st->log = sp->log; st->timeout = sp->timeout; - st->allow_opts = sp->allow_opts; + st->state_flags = sp->state_flags; + if (!(flags & PFSYNC_SI_IOCTL)) + st->sync_flags = PFSTATE_FROMSYNC; bcopy(sp->id, &st->id, sizeof(st->id)); st->creatorid = sp->creatorid; - st->sync_flags = PFSTATE_FROMSYNC; + pf_state_peer_ntoh(&sp->src, &st->src); + pf_state_peer_ntoh(&sp->dst, &st->dst); - if (pf_insert_state(kif, st)) { - pfi_kif_unref(kif, PFI_KIF_REF_NONE); + st->rule.ptr = r; + st->nat_rule.ptr = NULL; + st->anchor.ptr = NULL; + st->rt_kif = NULL; + + st->pfsync_time = 0; + + + /* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */ + r->states_cur++; + r->states_tot++; + + if ((error = pf_state_insert(kif, skw, sks, st)) != 0) { /* XXX when we have nat_rule/anchors, use STATE_DEC_COUNTERS */ - r->states--; + r->states_cur--; + goto cleanup_state; + } + + return (0); + + cleanup: + error = ENOMEM; + if (skw == sks) + sks = NULL; + if (skw != NULL) + pool_put(&pf_state_key_pl, skw); + if (sks != NULL) + pool_put(&pf_state_key_pl, sks); + + cleanup_state: /* pf_state_insert frees the state keys */ + if (st) { if (st->dst.scrub) pool_put(&pf_state_scrub_pl, st->dst.scrub); if (st->src.scrub) pool_put(&pf_state_scrub_pl, st->src.scrub); pool_put(&pf_state_pl, st); - return (EINVAL); } - - return (0); + return (error); } void @@ -345,6 +445,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; @@ -358,7 +459,7 @@ pfsync_input(struct mbuf *m, ...) struct in_addr src; struct mbuf *mp; int iplen, action, error, i, s, count, offp, sfail, stale = 0; - u_int8_t chksum_flag = 0; + u_int8_t flags = 0; pfsyncstats.pfsyncs_ipackets++; @@ -413,7 +514,7 @@ pfsync_input(struct mbuf *m, ...) src = ip->ip_src; if (!bcmp(&ph->pf_chksum, &pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH)) - chksum_flag++; + flags |= PFSYNC_SI_CKSUM; switch (action) { case PFSYNC_ACT_CLR: { @@ -444,15 +545,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); } } } @@ -484,8 +586,7 @@ pfsync_input(struct mbuf *m, ...) continue; } - if ((error = pfsync_insert_net_state(sp, - chksum_flag))) { + if ((error = pfsync_state_import(sp, flags))) { if (error == ENOMEM) { splx(s); goto done; @@ -524,11 +625,11 @@ pfsync_input(struct mbuf *m, ...) st = pf_find_state_byid(&id_key); if (st == NULL) { /* insert the update */ - if (pfsync_insert_net_state(sp, chksum_flag)) + if (pfsync_state_import(sp, flags)) pfsyncstats.pfsyncs_badstate++; continue; } - sk = st->state_key; + sk = st->key[PF_SK_WIRE]; /* XXX right one? */ sfail = 0; if (sk->proto == IPPROTO_TCP) { /* @@ -589,7 +690,7 @@ pfsync_input(struct mbuf *m, ...) } continue; } - pfsync_alloc_scrub_memory(&sp->dst, &st->dst); + pfsync_alloc_scrub_memory(&sp->dst, &st->dst); pf_state_peer_ntoh(&sp->src, &st->src); pf_state_peer_ntoh(&sp->dst, &st->dst); st->expire = ntohl(sp->expire) + time_second; @@ -665,7 +766,7 @@ pfsync_input(struct mbuf *m, ...) pfsyncstats.pfsyncs_badstate++; continue; } - sk = st->state_key; + sk = st->key[PF_SK_WIRE]; /* XXX right one? */ sfail = 0; if (sk->proto == IPPROTO_TCP) { /* @@ -716,7 +817,7 @@ pfsync_input(struct mbuf *m, ...) PFSYNC_FLAG_STALE); continue; } - pfsync_alloc_scrub_memory(&up->dst, &st->dst); + pfsync_alloc_scrub_memory(&up->dst, &st->dst); pf_state_peer_ntoh(&up->src, &st->src); pf_state_peer_ntoh(&up->dst, &st->dst); st->expire = ntohl(up->expire) + time_second; @@ -1117,9 +1218,6 @@ pfsync_pack_state(u_int8_t action, struc 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_rule *r; - u_long secs; int s, ret = 0; u_int8_t i = 255, newaction = 0; @@ -1186,8 +1284,6 @@ pfsync_pack_state(u_int8_t action, struc } } - secs = time_second; - st->pfsync_time = time_uptime; if (sp == NULL) { @@ -1199,47 +1295,19 @@ pfsync_pack_state(u_int8_t action, struc h->count++; bzero(sp, sizeof(*sp)); - bcopy(&st->id, sp->id, sizeof(sp->id)); - sp->creatorid = st->creatorid; - - strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname)); - pf_state_host_hton(&sk->lan, &sp->lan); - pf_state_host_hton(&sk->gwy, &sp->gwy); - pf_state_host_hton(&sk->ext, &sp->ext); - - bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr)); - - sp->creation = htonl(secs - st->creation); - pf_state_counter_hton(st->packets[0], sp->packets[0]); - pf_state_counter_hton(st->packets[1], sp->packets[1]); - pf_state_counter_hton(st->bytes[0], sp->bytes[0]); - pf_state_counter_hton(st->bytes[1], sp->bytes[1]); - if ((r = st->rule.ptr) == NULL) - sp->rule = htonl(-1); - else - sp->rule = htonl(r->nr); - if ((r = st->anchor.ptr) == NULL) - sp->anchor = htonl(-1); - else - sp->anchor = htonl(r->nr); - sp->af = sk->af; - sp->proto = sk->proto; - sp->direction = sk->direction; - sp->log = st->log; - sp->allow_opts = st->allow_opts; - sp->timeout = st->timeout; + pfsync_state_export(sp, st); if (flags & PFSYNC_FLAG_STALE) sp->sync_flags |= PFSTATE_STALE; - } - - pf_state_peer_hton(&st->src, &sp->src); - pf_state_peer_hton(&st->dst, &sp->dst); + } else { + pf_state_peer_hton(&st->src, &sp->src); + pf_state_peer_hton(&st->dst, &sp->dst); - if (st->expire <= secs) - sp->expire = htonl(0); - else - sp->expire = htonl(st->expire - secs); + if (st->expire <= time_second) + sp->expire = htonl(0); + else + sp->expire = htonl(st->expire - time_second); + } /* do we need to build "compressed" actions for network transfer? */ if (sc->sc_sync_ifp && flags & PFSYNC_FLAG_COMPRESS) { @@ -1715,7 +1783,7 @@ pfsync_update_tdb(struct tdb *tdb, int o for (i = 0; !pt && i < h->count; i++) { if (tdb->tdb_spi == u->spi && tdb->tdb_sproto == u->sproto && - !bcmp(&tdb->tdb_dst, &u->dst, + !bcmp(&tdb->tdb_dst, &u->dst, SA_LEN(&u->dst.sa))) { pt = u; pt->updates++; Modified: vendor-sys/pf/dist/net/if_pfsync.h ============================================================================== --- vendor-sys/pf/dist/net/if_pfsync.h Wed Dec 10 21:23:23 2008 (r185887) +++ vendor-sys/pf/dist/net/if_pfsync.h Wed Dec 10 21:24:31 2008 (r185888) @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pfsync.h,v 1.32 2007/12/14 18:33:37 deraadt Exp $ */ +/* $OpenBSD: if_pfsync.h,v 1.35 2008/06/29 08:42:15 mcbride Exp $ */ /* * Copyright (c) 2001 Michael Shalayeff @@ -146,7 +146,7 @@ extern struct pfsync_softc *pfsyncif; struct pfsync_header { u_int8_t version; -#define PFSYNC_VERSION 3 +#define PFSYNC_VERSION 4 u_int8_t af; u_int8_t action; #define PFSYNC_ACT_CLR 0 /* clear all states */ @@ -205,72 +205,22 @@ struct pfsyncreq { int pfsyncr_authlevel; }; - -/* for copies to/from network */ -#define pf_state_peer_hton(s,d) do { \ - (d)->seqlo = htonl((s)->seqlo); \ - (d)->seqhi = htonl((s)->seqhi); \ - (d)->seqdiff = htonl((s)->seqdiff); \ - (d)->max_win = htons((s)->max_win); \ - (d)->mss = htons((s)->mss); \ - (d)->state = (s)->state; \ - (d)->wscale = (s)->wscale; \ - if ((s)->scrub) { \ - (d)->scrub.pfss_flags = \ - htons((s)->scrub->pfss_flags & PFSS_TIMESTAMP); \ - (d)->scrub.pfss_ttl = (s)->scrub->pfss_ttl; \ - (d)->scrub.pfss_ts_mod = htonl((s)->scrub->pfss_ts_mod);\ - (d)->scrub.scrub_flag = PFSYNC_SCRUB_FLAG_VALID; \ - } \ -} while (0) - -#define pf_state_peer_ntoh(s,d) do { \ - (d)->seqlo = ntohl((s)->seqlo); \ - (d)->seqhi = ntohl((s)->seqhi); \ - (d)->seqdiff = ntohl((s)->seqdiff); \ - (d)->max_win = ntohs((s)->max_win); \ - (d)->mss = ntohs((s)->mss); \ - (d)->state = (s)->state; \ - (d)->wscale = (s)->wscale; \ - if ((s)->scrub.scrub_flag == PFSYNC_SCRUB_FLAG_VALID && \ - (d)->scrub != NULL) { \ - (d)->scrub->pfss_flags = \ - ntohs((s)->scrub.pfss_flags) & PFSS_TIMESTAMP; \ - (d)->scrub->pfss_ttl = (s)->scrub.pfss_ttl; \ - (d)->scrub->pfss_ts_mod = ntohl((s)->scrub.pfss_ts_mod);\ - } \ -} while (0) - -#define pf_state_host_hton(s,d) do { \ - bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \ - (d)->port = (s)->port; \ -} while (0) - -#define pf_state_host_ntoh(s,d) do { \ - bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \ - (d)->port = (s)->port; \ -} while (0) - -#define pf_state_counter_hton(s,d) do { \ - d[0] = htonl((s>>32)&0xffffffff); \ - d[1] = htonl(s&0xffffffff); \ -} while (0) - -#define pf_state_counter_ntoh(s,d) do { \ - d = ntohl(s[0]); \ - d = d<<32; \ - d += ntohl(s[1]); \ -} while (0) - #ifdef _KERNEL -void pfsync_input(struct mbuf *, ...); -int pfsync_clear_states(u_int32_t, char *); -int pfsync_pack_state(u_int8_t, struct pf_state *, int); -int pfsync_sysctl(int *, u_int, void *, size_t *, void *, size_t); +void pfsync_input(struct mbuf *, ...); +int pfsync_clear_states(u_int32_t, char *); +int pfsync_pack_state(u_int8_t, struct pf_state *, int); +int pfsync_sysctl(int *, u_int, void *, size_t *, + void *, size_t); +void pfsync_state_export(struct pfsync_state *, + struct pf_state *); + +#define PFSYNC_SI_IOCTL 0x01 +#define PFSYNC_SI_CKSUM 0x02 +int pfsync_state_import(struct pfsync_state *, u_int8_t); #define pfsync_insert_state(st) do { \ if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) || \ - (st->state_key->proto == IPPROTO_PFSYNC)) \ + (st->key[PF_SK_WIRE]->proto == IPPROTO_PFSYNC)) \ st->sync_flags |= PFSTATE_NOSYNC; \ else if (!st->sync_flags) \ pfsync_pack_state(PFSYNC_ACT_INS, (st), \ Modified: vendor-sys/pf/dist/net/pf.c ============================================================================== --- vendor-sys/pf/dist/net/pf.c Wed Dec 10 21:23:23 2008 (r185887) +++ vendor-sys/pf/dist/net/pf.c Wed Dec 10 21:24:31 2008 (r185888) @@ -1,8 +1,8 @@ -/* $OpenBSD: pf.c,v 1.567 2008/02/20 23:40:13 henning Exp $ */ +/* $OpenBSD: pf.c,v 1.614 2008/08/02 12:34:37 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); @@ -161,21 +160,41 @@ struct pf_rule *pf_match_translation(st u_int16_t, int); struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *, int, int, struct pfi_kif *, struct pf_src_node **, - 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); + struct pf_state_key **, struct pf_state_key **, + struct pf_state_key **, struct pf_state_key **, + struct pf_addr *, struct pf_addr *, + u_int16_t, u_int16_t); +void pf_detach_state(struct pf_state *); +int pf_state_key_setup(struct pf_pdesc *, struct pf_rule *, + struct pf_state_key **, struct pf_state_key **, + struct pf_state_key **, struct pf_state_key **, + struct pf_addr *, struct pf_addr *, + u_int16_t, u_int16_t); +void pf_state_key_detach(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, void *, struct pf_pdesc *, struct pf_rule **, struct pf_ruleset **, struct ifqueue *); +static __inline int pf_create_state(struct pf_rule *, struct pf_rule *, + struct pf_rule *, struct pf_pdesc *, + struct pf_src_node *, struct pf_state_key *, + struct pf_state_key *, struct pf_state_key *, + struct pf_state_key *, struct mbuf *, int, + u_int16_t, u_int16_t, int *, struct pfi_kif *, + struct pf_state **, int, u_int16_t, u_int16_t, + int); int pf_test_fragment(struct pf_rule **, int, struct pfi_kif *, struct mbuf *, void *, struct pf_pdesc *, struct pf_rule **, struct pf_ruleset **); +int pf_tcp_track_full(struct pf_state_peer *, + struct pf_state_peer *, struct pf_state **, + struct pfi_kif *, struct mbuf *, int, + struct pf_pdesc *, u_short *, int *); +int pf_tcp_track_sloppy(struct pf_state_peer *, + struct pf_state_peer *, struct pf_state **, + struct pf_pdesc *, u_short *); int pf_test_state_tcp(struct pf_state **, int, struct pfi_kif *, struct mbuf *, int, void *, struct pf_pdesc *, u_short *); @@ -186,10 +205,9 @@ int pf_test_state_icmp(struct pf_stat struct pfi_kif *, struct mbuf *, int, void *, struct pf_pdesc *, u_short *); int pf_test_state_other(struct pf_state **, int, - struct pfi_kif *, struct pf_pdesc *); -int pf_match_tag(struct mbuf *, struct pf_rule *, int *); + struct pfi_kif *, struct mbuf *, struct pf_pdesc *); void pf_step_into_anchor(int *, struct pf_ruleset **, int, - struct pf_rule **, struct pf_rule **, int *); + struct pf_rule **, struct pf_rule **, int *); int pf_step_out_of_anchor(int *, struct pf_ruleset **, int, struct pf_rule **, struct pf_rule **, int *); @@ -219,13 +237,14 @@ void pf_set_rt_ifp(struct pf_state *, struct pf_addr *); int pf_check_proto_cksum(struct mbuf *, int, int, u_int8_t, sa_family_t); +struct pf_divert *pf_get_divert(struct mbuf *); +void pf_print_state_parts(struct pf_state *, + struct pf_state_key *, struct pf_state_key *); int pf_addr_wrap_neq(struct pf_addr_wrap *, struct pf_addr_wrap *); struct pf_state *pf_find_state(struct pfi_kif *, - struct pf_state_key_cmp *, u_int); + struct pf_state_key_cmp *, u_int, struct mbuf *); int pf_src_connlimit(struct pf_state **); -void pf_stateins_err(const char *, struct pf_state *, - struct pfi_kif *); int pf_check_congestion(struct ifqueue *); extern struct pool pfr_ktable_pl; @@ -239,54 +258,49 @@ struct pf_pool_limit pf_pool_limits[PF_L { &pfr_kentry_pl, PFR_KENTRY_HIWAT } }; -#define STATE_LOOKUP() \ +#define STATE_LOOKUP(i, k, d, s, m) \ do { \ - *state = pf_find_state(kif, &key, direction); \ - if (*state == NULL || (*state)->timeout == PFTM_PURGE) \ + s = pf_find_state(i, k, d, m); \ + if (s == NULL || (s)->timeout == PFTM_PURGE) \ return (PF_DROP); \ - if (direction == PF_OUT && \ - (((*state)->rule.ptr->rt == PF_ROUTETO && \ - (*state)->rule.ptr->direction == PF_OUT) || \ - ((*state)->rule.ptr->rt == PF_REPLYTO && \ - (*state)->rule.ptr->direction == PF_IN)) && \ - (*state)->rt_kif != NULL && \ - (*state)->rt_kif != kif) \ + if (d == PF_OUT && \ + (((s)->rule.ptr->rt == PF_ROUTETO && \ + (s)->rule.ptr->direction == PF_OUT) || \ + ((s)->rule.ptr->rt == PF_REPLYTO && \ + (s)->rule.ptr->direction == PF_IN)) && \ + (s)->rt_kif != NULL && \ + (s)->rt_kif != i) \ return (PF_PASS); \ } while (0) -#define STATE_TRANSLATE(sk) \ - (sk)->lan.addr.addr32[0] != (sk)->gwy.addr.addr32[0] || \ - ((sk)->af == AF_INET6 && \ - ((sk)->lan.addr.addr32[1] != (sk)->gwy.addr.addr32[1] || \ - (sk)->lan.addr.addr32[2] != (sk)->gwy.addr.addr32[2] || \ - (sk)->lan.addr.addr32[3] != (sk)->gwy.addr.addr32[3])) || \ - (sk)->lan.port != (sk)->gwy.port - #define BOUND_IFACE(r, k) \ ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all #define STATE_INC_COUNTERS(s) \ do { \ - s->rule.ptr->states++; \ - if (s->anchor.ptr != NULL) \ - s->anchor.ptr->states++; \ - if (s->nat_rule.ptr != NULL) \ - s->nat_rule.ptr->states++; \ + s->rule.ptr->states_cur++; \ + s->rule.ptr->states_tot++; \ + if (s->anchor.ptr != NULL) { \ + s->anchor.ptr->states_cur++; \ + s->anchor.ptr->states_tot++; \ + } \ + if (s->nat_rule.ptr != NULL) { \ + s->nat_rule.ptr->states_cur++; \ + s->nat_rule.ptr->states_tot++; \ + } \ } while (0) #define STATE_DEC_COUNTERS(s) \ do { \ if (s->nat_rule.ptr != NULL) \ - s->nat_rule.ptr->states--; \ + s->nat_rule.ptr->states_cur--; \ if (s->anchor.ptr != NULL) \ - s->anchor.ptr->states--; \ - s->rule.ptr->states--; \ + s->anchor.ptr->states_cur--; \ + s->rule.ptr->states_cur--; \ } 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 *); @@ -297,16 +311,10 @@ 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 - static __inline int pf_src_compare(struct pf_src_node *a, struct pf_src_node *b) { @@ -351,157 +359,6 @@ pf_src_compare(struct pf_src_node *a, st 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) @@ -522,77 +379,6 @@ pf_addrcpy(struct pf_addr *dst, struct p } #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: *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***