svn commit: r185888 - vendor-sys/pf/dist/net

Max Laier mlaier at FreeBSD.org
Wed Dec 10 13:24:31 PST 2008


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 ***


More information about the svn-src-all mailing list