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

Max Laier mlaier at FreeBSD.org
Wed Dec 10 13:22:58 PST 2008


Author: mlaier
Date: Wed Dec 10 21:22:57 2008
New Revision: 185886
URL: http://svn.freebsd.org/changeset/base/185886

Log:
  Import OPENBSD_4_3_BASE

Modified:
  vendor-sys/pf/dist/net/if_pflog.c
  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_pflog.c
==============================================================================
--- vendor-sys/pf/dist/net/if_pflog.c	Wed Dec 10 21:22:15 2008	(r185885)
+++ vendor-sys/pf/dist/net/if_pflog.c	Wed Dec 10 21:22:57 2008	(r185886)
@@ -1,4 +1,4 @@
-/*	$OpenBSD: if_pflog.c,v 1.24 2007/05/26 17:13:30 jason Exp $	*/
+/*	$OpenBSD: if_pflog.c,v 1.27 2007/12/20 02:53:02 brad Exp $	*/
 /*
  * The authors of this code are John Ioannidis (ji at tla.org),
  * Angelos D. Keromytis (kermit at csd.uch.gr) and 
@@ -107,9 +107,9 @@ pflog_clone_create(struct if_clone *ifc,
 	if (unit >= PFLOGIFS_MAX)
 		return (EINVAL);
 
-	if ((pflogif = malloc(sizeof(*pflogif), M_DEVBUF, M_NOWAIT)) == NULL)
+	if ((pflogif = malloc(sizeof(*pflogif),
+	    M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
 		return (ENOMEM);
-	bzero(pflogif, sizeof(*pflogif));
 
 	pflogif->sc_unit = unit;
 	ifp = &pflogif->sc_if;
@@ -191,9 +191,6 @@ int
 pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 {
 	switch (cmd) {
-	case SIOCSIFADDR:
-	case SIOCAIFADDR:
-	case SIOCSIFDSTADDR:
 	case SIOCSIFFLAGS:
 		if (ifp->if_flags & IFF_UP)
 			ifp->if_flags |= IFF_RUNNING;
@@ -201,7 +198,7 @@ pflogioctl(struct ifnet *ifp, u_long cmd
 			ifp->if_flags &= ~IFF_RUNNING;
 		break;
 	default:
-		return (EINVAL);
+		return (ENOTTY);
 	}
 
 	return (0);

Modified: vendor-sys/pf/dist/net/if_pfsync.c
==============================================================================
--- vendor-sys/pf/dist/net/if_pfsync.c	Wed Dec 10 21:22:15 2008	(r185885)
+++ vendor-sys/pf/dist/net/if_pfsync.c	Wed Dec 10 21:22:57 2008	(r185886)
@@ -1,4 +1,4 @@
-/*	$OpenBSD: if_pfsync.c,v 1.83 2007/06/26 14:44:12 mcbride Exp $	*/
+/*	$OpenBSD: if_pfsync.c,v 1.89 2008/01/12 17:08:33 mpf Exp $	*/
 
 /*
  * Copyright (c) 2002 Michael Shalayeff
@@ -36,6 +36,7 @@
 #include <sys/ioctl.h>
 #include <sys/timeout.h>
 #include <sys/kernel.h>
+#include <sys/sysctl.h>
 
 #include <net/if.h>
 #include <net/if_types.h>
@@ -45,6 +46,7 @@
 #include <netinet/if_ether.h>
 #include <netinet/tcp.h>
 #include <netinet/tcp_seq.h>
+#include <sys/pool.h>
 
 #ifdef	INET
 #include <netinet/in_systm.h>
@@ -124,9 +126,9 @@ pfsync_clone_create(struct if_clone *ifc
 		return (EINVAL);
 
 	pfsync_sync_ok = 1;
-	if ((pfsyncif = malloc(sizeof(*pfsyncif), M_DEVBUF, M_NOWAIT)) == NULL)
+	if ((pfsyncif = malloc(sizeof(*pfsyncif), M_DEVBUF,
+	    M_NOWAIT|M_ZERO)) == NULL)
 		return (ENOMEM);
-	bzero(pfsyncif, sizeof(*pfsyncif));
 	pfsyncif->sc_mbuf = NULL;
 	pfsyncif->sc_mbuf_net = NULL;
 	pfsyncif->sc_mbuf_tdb = NULL;
@@ -140,6 +142,10 @@ pfsync_clone_create(struct if_clone *ifc
 	pfsyncif->sc_ureq_sent = 0;
 	pfsyncif->sc_bulk_send_next = NULL;
 	pfsyncif->sc_bulk_terminator = NULL;
+	pfsyncif->sc_imo.imo_membership = (struct in_multi **)malloc(
+	    (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_IPMOPTS,
+	    M_WAITOK|M_ZERO);
+	pfsyncif->sc_imo.imo_max_memberships = IP_MIN_MEMBERSHIPS;
 	ifp = &pfsyncif->sc_if;
 	snprintf(ifp->if_xname, sizeof ifp->if_xname, "pfsync%d", unit);
 	ifp->if_softc = pfsyncif;
@@ -171,10 +177,21 @@ pfsync_clone_create(struct if_clone *ifc
 int
 pfsync_clone_destroy(struct ifnet *ifp)
 {
+	struct pfsync_softc *sc = ifp->if_softc;
+
+	timeout_del(&sc->sc_tmo);
+	timeout_del(&sc->sc_tdb_tmo);
+	timeout_del(&sc->sc_bulk_tmo);
+	timeout_del(&sc->sc_bulkfail_tmo);
+#if NCARP > 0
+	if (!pfsync_sync_ok)
+		carp_group_demote_adj(&sc->sc_if, -1);
+#endif
 #if NBPFILTER > 0
 	bpfdetach(ifp);
 #endif
 	if_detach(ifp);
+	free(pfsyncif->sc_imo.imo_membership, M_IPMOPTS);
 	free(pfsyncif, M_DEVBUF);
 	pfsyncif = NULL;
 	return (0);
@@ -461,9 +478,9 @@ pfsync_input(struct mbuf *m, ...)
 			    sp->direction > PF_OUT ||
 			    (sp->af != AF_INET && sp->af != AF_INET6)) {
 				if (pf_status.debug >= PF_DEBUG_MISC)
-					printf("pfsync_insert: PFSYNC_ACT_INS: "
+					printf("pfsync_input: PFSYNC_ACT_INS: "
 					    "invalid value\n");
-				pfsyncstats.pfsyncs_badstate++;
+				pfsyncstats.pfsyncs_badval++;
 				continue;
 			}
 
@@ -495,9 +512,9 @@ pfsync_input(struct mbuf *m, ...)
 			    sp->src.state > PF_TCPS_PROXY_DST ||
 			    sp->dst.state > PF_TCPS_PROXY_DST) {
 				if (pf_status.debug >= PF_DEBUG_MISC)
-					printf("pfsync_insert: PFSYNC_ACT_UPD: "
+					printf("pfsync_input: PFSYNC_ACT_UPD: "
 					    "invalid value\n");
-				pfsyncstats.pfsyncs_badstate++;
+				pfsyncstats.pfsyncs_badval++;
 				continue;
 			}
 
@@ -559,7 +576,7 @@ pfsync_input(struct mbuf *m, ...)
 					     : "partial"), sfail,
 					    betoh64(st->id),
 					    ntohl(st->creatorid));
-				pfsyncstats.pfsyncs_badstate++;
+				pfsyncstats.pfsyncs_stale++;
 
 				if (!(sp->sync_flags & PFSTATE_STALE)) {
 					/* we have a better state, send it */
@@ -626,10 +643,10 @@ pfsync_input(struct mbuf *m, ...)
 			    up->src.state > PF_TCPS_PROXY_DST ||
 			    up->dst.state > PF_TCPS_PROXY_DST) {
 				if (pf_status.debug >= PF_DEBUG_MISC)
-					printf("pfsync_insert: "
+					printf("pfsync_input: "
 					    "PFSYNC_ACT_UPD_C: "
 					    "invalid value\n");
-				pfsyncstats.pfsyncs_badstate++;
+				pfsyncstats.pfsyncs_badval++;
 				continue;
 			}
 
@@ -685,7 +702,7 @@ pfsync_input(struct mbuf *m, ...)
 					    "creatorid: %08x\n", sfail,
 					    betoh64(st->id),
 					    ntohl(st->creatorid));
-				pfsyncstats.pfsyncs_badstate++;
+				pfsyncstats.pfsyncs_stale++;
 
 				/* we have a better state, send it out */
 				if ((!stale || update_requested) &&
@@ -1750,3 +1767,22 @@ pfsync_update_tdb(struct tdb *tdb, int o
 	return (ret);
 }
 #endif
+
+int
+pfsync_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
+    size_t newlen)
+{
+	/* All sysctl names at this level are terminal. */
+	if (namelen != 1)
+		return (ENOTDIR);
+
+	switch (name[0]) {
+	case PFSYNCCTL_STATS:
+		if (newp != NULL)
+			return (EPERM);
+		return (sysctl_struct(oldp, oldlenp, newp, newlen,
+		    &pfsyncstats, sizeof(pfsyncstats)));
+	default:
+		return (ENOPROTOOPT);
+	}
+}

Modified: vendor-sys/pf/dist/net/if_pfsync.h
==============================================================================
--- vendor-sys/pf/dist/net/if_pfsync.h	Wed Dec 10 21:22:15 2008	(r185885)
+++ vendor-sys/pf/dist/net/if_pfsync.h	Wed Dec 10 21:22:57 2008	(r185886)
@@ -1,4 +1,4 @@
-/*	$OpenBSD: if_pfsync.h,v 1.31 2007/05/31 04:11:42 mcbride Exp $	*/
+/*	$OpenBSD: if_pfsync.h,v 1.32 2007/12/14 18:33:37 deraadt Exp $	*/
 
 /*
  * Copyright (c) 2001 Michael Shalayeff
@@ -86,6 +86,17 @@ struct pfsync_state_bus {
 	u_int8_t		pad[7];
 } __packed;
 
+/*
+ * Names for PFSYNC sysctl objects
+ */
+#define	PFSYNCCTL_STATS		1	/* PFSYNC stats */
+#define	PFSYNCCTL_MAXID		2
+
+#define	PFSYNCCTL_NAMES { \
+	{ 0, 0 }, \
+	{ "stats", CTLTYPE_STRUCT }, \
+}
+
 #ifdef _KERNEL
 
 union sc_statep {
@@ -255,6 +266,8 @@ struct pfsyncreq {
 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);
+
 #define pfsync_insert_state(st)	do {				\
 	if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) ||	\
 	    (st->state_key->proto == IPPROTO_PFSYNC))			\

Modified: vendor-sys/pf/dist/net/pf.c
==============================================================================
--- vendor-sys/pf/dist/net/pf.c	Wed Dec 10 21:22:15 2008	(r185885)
+++ vendor-sys/pf/dist/net/pf.c	Wed Dec 10 21:22:57 2008	(r185886)
@@ -1,4 +1,4 @@
-/*	$OpenBSD: pf.c,v 1.552 2007/08/21 15:57:27 dhartmei Exp $ */
+/*	$OpenBSD: pf.c,v 1.567 2008/02/20 23:40:13 henning Exp $ */
 
 /*
  * Copyright (c) 2001 Daniel Hartmeier
@@ -51,6 +51,8 @@
 #include <sys/proc.h>
 #include <sys/rwlock.h>
 
+#include <crypto/md5.h>
+
 #include <net/if.h>
 #include <net/if_types.h>
 #include <net/bpf.h>
@@ -110,6 +112,11 @@ u_int32_t		 ticket_altqs_inactive;
 int			 altqs_inactive_open;
 u_int32_t		 ticket_pabuf;
 
+MD5_CTX			 pf_tcp_secret_ctx;
+u_char			 pf_tcp_secret[16];
+int			 pf_tcp_secret_init;
+int			 pf_tcp_iss_off;
+
 struct pf_anchor_stackframe {
 	struct pf_ruleset			*rs;
 	struct pf_rule				*r;
@@ -160,6 +167,7 @@ struct pf_rule		*pf_get_translation(stru
 void			 pf_attach_state(struct pf_state_key *,
 			    struct pf_state *, int);
 void			 pf_detach_state(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 **,
@@ -214,7 +222,7 @@ int			 pf_check_proto_cksum(struct mbuf 
 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_int8_t);
+			    struct pf_state_key_cmp *, u_int);
 int			 pf_src_connlimit(struct pf_state **);
 void			 pf_stateins_err(const char *, struct pf_state *,
 			    struct pfi_kif *);
@@ -233,10 +241,7 @@ struct pf_pool_limit pf_pool_limits[PF_L
 
 #define STATE_LOOKUP()							\
 	do {								\
-		if (direction == PF_IN)					\
-			*state = pf_find_state(kif, &key, PF_EXT_GWY);	\
-		else							\
-			*state = pf_find_state(kif, &key, PF_LAN_EXT);	\
+		*state = pf_find_state(kif, &key, direction);		\
 		if (*state == NULL || (*state)->timeout == PFTM_PURGE)	\
 			return (PF_DROP);				\
 		if (direction == PF_OUT &&				\
@@ -526,19 +531,19 @@ pf_find_state_byid(struct pf_state_cmp *
 }
 
 struct pf_state *
-pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int8_t tree)
+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 (tree) {
-	case PF_LAN_EXT:
+	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_EXT_GWY:
+	case PF_IN:
 		sk = RB_FIND(pf_state_tree_ext_gwy, &pf_statetbl_ext_gwy,
 		    (struct pf_state_key *)key);
 		break;
@@ -556,19 +561,19 @@ pf_find_state(struct pfi_kif *kif, struc
 }
 
 struct pf_state *
-pf_find_state_all(struct pf_state_key_cmp *key, u_int8_t tree, int *more)
+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 (tree) {
-	case PF_LAN_EXT:
+	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_EXT_GWY:
+	case PF_IN:
 		sk = RB_FIND(pf_state_tree_ext_gwy,
 		    &pf_statetbl_ext_gwy, (struct pf_state_key *)key);
 		break;
@@ -819,6 +824,8 @@ pf_insert_state(struct pfi_kif *kif, str
 		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);
 				return (-1);
 			}
 		pf_detach_state(s, PF_DT_SKIP_LANEXT|PF_DT_SKIP_EXTGWY);
@@ -961,10 +968,8 @@ pf_src_tree_remove_state(struct pf_state
 	u_int32_t timeout;
 
 	if (s->src_node != NULL) {
-		if (s->state_key->proto == IPPROTO_TCP) {
-			if (s->src.tcp_est)
-				--s->src_node->conn;
-		}
+		if (s->src.tcp_est)
+			--s->src_node->conn;
 		if (--s->src_node->states <= 0) {
 			timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
 			if (!timeout)
@@ -1295,6 +1300,7 @@ pf_addr_wrap_neq(struct pf_addr_wrap *aw
 		return (1);
 	switch (aw1->type) {
 	case PF_ADDR_ADDRMASK:
+	case PF_ADDR_RANGE:
 		if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0))
 			return (1);
 		if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0))
@@ -1598,7 +1604,7 @@ pf_send_tcp(const struct pf_rule *r, sa_
 	m->m_pkthdr.pf.tag = rtag;
 
 	if (r != NULL && r->rtableid >= 0)
-		m->m_pkthdr.pf.rtableid = m->m_pkthdr.pf.rtableid;
+		m->m_pkthdr.pf.rtableid = r->rtableid;
 
 #ifdef ALTQ
 	if (r != NULL && r->qid) {
@@ -1790,6 +1796,44 @@ pf_match_addr(u_int8_t n, struct pf_addr
 	}
 }
 
+/*
+ * Return 1 if b <= a <= e, otherwise return 0.
+ */
+int
+pf_match_addr_range(struct pf_addr *b, struct pf_addr *e,
+    struct pf_addr *a, sa_family_t af)
+{
+	switch (af) {
+#ifdef INET
+	case AF_INET:
+		if ((a->addr32[0] < b->addr32[0]) ||
+		    (a->addr32[0] > e->addr32[0]))
+			return (0);
+		break;
+#endif /* INET */
+#ifdef INET6
+	case AF_INET6: {
+		int	i;
+
+		/* check a >= b */
+		for (i = 0; i < 4; ++i)
+			if (a->addr32[i] > b->addr32[i])
+				break;
+			else if (a->addr32[i] < b->addr32[i])
+				return (0);
+		/* check a <= e */
+		for (i = 0; i < 4; ++i)
+			if (a->addr32[i] < e->addr32[i])
+				break;
+			else if (a->addr32[i] > e->addr32[i])
+				return (0);
+		break;
+	}
+#endif /* INET6 */
+	}
+	return (1);
+}
+
 int
 pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p)
 {
@@ -2267,15 +2311,15 @@ pf_get_sport(sa_family_t af, u_int8_t pr
 		if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP ||
 		    proto == IPPROTO_ICMP)) {
 			key.gwy.port = dport;
-			if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
+			if (pf_find_state_all(&key, PF_IN, NULL) == NULL)
 				return (0);
 		} else if (low == 0 && high == 0) {
 			key.gwy.port = *nport;
-			if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
+			if (pf_find_state_all(&key, PF_IN, NULL) == NULL)
 				return (0);
 		} else if (low == high) {
 			key.gwy.port = htons(low);
-			if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) {
+			if (pf_find_state_all(&key, PF_IN, NULL) == NULL) {
 				*nport = htons(low);
 				return (0);
 			}
@@ -2292,7 +2336,7 @@ pf_get_sport(sa_family_t af, u_int8_t pr
 			/* low <= cut <= high */
 			for (tmp = cut; tmp <= high; ++(tmp)) {
 				key.gwy.port = htons(tmp);
-				if (pf_find_state_all(&key, PF_EXT_GWY, NULL) ==
+				if (pf_find_state_all(&key, PF_IN, NULL) ==
 				    NULL) {
 					*nport = htons(tmp);
 					return (0);
@@ -2300,7 +2344,7 @@ pf_get_sport(sa_family_t af, u_int8_t pr
 			}
 			for (tmp = cut - 1; tmp >= low; --(tmp)) {
 				key.gwy.port = htons(tmp);
-				if (pf_find_state_all(&key, PF_EXT_GWY, NULL) ==
+				if (pf_find_state_all(&key, PF_IN, NULL) ==
 				    NULL) {
 					*nport = htons(tmp);
 					return (0);
@@ -2836,6 +2880,34 @@ pf_alloc_state_key(struct pf_state *s)
 	return (sk);
 }
 
+u_int32_t
+pf_tcp_iss(struct pf_pdesc *pd)
+{
+	MD5_CTX ctx;
+	u_int32_t digest[4];
+
+	if (pf_tcp_secret_init == 0) {
+		arc4random_bytes(pf_tcp_secret, sizeof(pf_tcp_secret));
+		MD5Init(&pf_tcp_secret_ctx);
+		MD5Update(&pf_tcp_secret_ctx, pf_tcp_secret, sizeof(pf_tcp_secret));
+		pf_tcp_secret_init = 1;
+	}
+	ctx = pf_tcp_secret_ctx;
+
+	MD5Update(&ctx, (char *)&pd->hdr.tcp->th_sport, sizeof(u_short));
+	MD5Update(&ctx, (char *)&pd->hdr.tcp->th_dport, sizeof(u_short));
+	if (pd->af == AF_INET6) {
+		MD5Update(&ctx, (char *)&pd->src->v6, sizeof(struct in6_addr));
+		MD5Update(&ctx, (char *)&pd->dst->v6, sizeof(struct in6_addr));
+	} else {
+		MD5Update(&ctx, (char *)&pd->src->v4, sizeof(struct in_addr));
+		MD5Update(&ctx, (char *)&pd->dst->v4, sizeof(struct in_addr));
+	}
+	MD5Final((u_char *)digest, &ctx);
+	pf_tcp_iss_off += 4096;
+	return (digest[0] + tcp_iss + pf_tcp_iss_off);
+}
+
 int
 pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
     struct pfi_kif *kif, struct mbuf *m, int off, void *h,
@@ -3077,7 +3149,8 @@ pf_test_rule(struct pf_rule **rm, struct
 		    !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
 		    pd->lookup.gid))
 			r = TAILQ_NEXT(r, entries);
-		else if (r->prob && r->prob <= arc4random())
+		else if (r->prob && r->prob <=
+		    (arc4random() % (UINT_MAX - 1) + 1))
 			r = TAILQ_NEXT(r, entries);
 		else if (r->match_tag && !pf_match_tag(m, r, &tag))
 			r = TAILQ_NEXT(r, entries);
@@ -3203,10 +3276,22 @@ pf_test_rule(struct pf_rule **rm, struct
 		    (r->rule_flag & PFRULE_RETURN)) &&
 		    !(th->th_flags & TH_RST)) {
 			u_int32_t	 ack = ntohl(th->th_seq) + pd->p_len;
-			struct ip	*h = mtod(m, struct ip *);
+			int		 len = 0;
+			struct ip	*h4;
+			struct ip6_hdr	*h6;
+
+			switch (af) {
+			case AF_INET:
+				h4 = mtod(m, struct ip *);
+				len = ntohs(h4->ip_len) - off;
+				break;
+			case AF_INET6:
+				h6 = mtod(m, struct ip6_hdr *);
+				len = ntohs(h6->ip6_plen) - (off - sizeof(*h6));
+				break;
+			}
 
-			if (pf_check_proto_cksum(m, off,
-			    ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET))
+			if (pf_check_proto_cksum(m, off, len, IPPROTO_TCP, af))
 				REASON_SET(&reason, PFRES_PROTCKSUM);
 			else {
 				if (th->th_flags & TH_SYN)
@@ -3218,10 +3303,12 @@ pf_test_rule(struct pf_rule **rm, struct
 				    ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0,
 				    r->return_ttl, 1, 0, pd->eh, kif->pfik_ifp);
 			}
-		} else if ((af == AF_INET) && r->return_icmp)
+		} else if (pd->proto != IPPROTO_ICMP && af == AF_INET &&
+		    r->return_icmp)
 			pf_send_icmp(m, r->return_icmp >> 8,
 			    r->return_icmp & 255, af, r);
-		else if ((af == AF_INET6) && r->return_icmp6)
+		else if (pd->proto != IPPROTO_ICMPV6 && af == AF_INET6 &&
+		    r->return_icmp6)
 			pf_send_icmp(m, r->return_icmp6 >> 8,
 			    r->return_icmp6 & 255, af, r);
 	}
@@ -3237,7 +3324,6 @@ pf_test_rule(struct pf_rule **rm, struct
 	if (!state_icmp && (r->keep_state || nr != NULL ||
 	    (pd->flags & PFDESC_TCP_NORM))) {
 		/* create new state */
-		u_int16_t	 len;
 		struct pf_state	*s = NULL;
 		struct pf_state_key *sk = NULL;
 		struct pf_src_node *sn = NULL;
@@ -3296,15 +3382,14 @@ cleanup:
 			s->log |= nr->log & PF_LOG_ALL;
 		switch (pd->proto) {
 		case IPPROTO_TCP:
-			len = pd->tot_len - off - (th->th_off << 2);
 			s->src.seqlo = ntohl(th->th_seq);
-			s->src.seqhi = s->src.seqlo + len + 1;
+			s->src.seqhi = s->src.seqlo + pd->p_len + 1;
 			if ((th->th_flags & (TH_SYN|TH_ACK)) ==
 			TH_SYN && r->keep_state == PF_STATE_MODULATE) {
 				/* Generate sequence number modulator */
-				while ((s->src.seqdiff =
-				    tcp_rndiss_next() - s->src.seqlo) == 0)
-					;
+				if ((s->src.seqdiff = pf_tcp_iss(pd) -
+				    s->src.seqlo) == 0)
+					s->src.seqdiff = 1;
 				pf_change_a(&th->th_seq, &th->th_sum,
 				    htonl(s->src.seqlo + s->src.seqdiff), 0);
 				rewrite = 1;
@@ -3525,11 +3610,20 @@ pf_test_fragment(struct pf_rule **rm, in
 			r = r->skip[PF_SKIP_DST_ADDR].ptr;
 		else if (r->tos && !(r->tos == pd->tos))
 			r = TAILQ_NEXT(r, entries);
-		else if (r->src.port_op || r->dst.port_op ||
-		    r->flagset || r->type || r->code ||
-		    r->os_fingerprint != PF_OSFP_ANY)
+		else if (r->os_fingerprint != PF_OSFP_ANY)
+			r = TAILQ_NEXT(r, entries);
+		else if (pd->proto == IPPROTO_UDP &&
+		    (r->src.port_op || r->dst.port_op))
 			r = TAILQ_NEXT(r, entries);
-		else if (r->prob && r->prob <= arc4random())
+		else if (pd->proto == IPPROTO_TCP &&
+		    (r->src.port_op || r->dst.port_op || r->flagset))
+			r = TAILQ_NEXT(r, entries);
+		else if ((pd->proto == IPPROTO_ICMP ||
+		    pd->proto == IPPROTO_ICMPV6) &&
+		    (r->type || r->code))
+			r = TAILQ_NEXT(r, entries);
+		else if (r->prob && r->prob <=
+		    (arc4random() % (UINT_MAX - 1) + 1))
 			r = TAILQ_NEXT(r, entries);
 		else if (r->match_tag && !pf_match_tag(m, r, &tag))
 			r = TAILQ_NEXT(r, entries);
@@ -3698,6 +3792,22 @@ pf_test_state_tcp(struct pf_state **stat
 		}
 	}
 
+	if (((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN) &&
+	    dst->state >= TCPS_FIN_WAIT_2 &&
+	    src->state >= TCPS_FIN_WAIT_2) {
+		if (pf_status.debug >= PF_DEBUG_MISC) {
+			printf("pf: state reuse ");
+			pf_print_state(*state);
+			pf_print_flags(th->th_flags);
+			printf("\n");
+		}
+		/* XXX make sure it's the same direction ?? */
+		(*state)->src.state = (*state)->dst.state = TCPS_CLOSED;
+		pf_unlink_state(*state);
+		*state = NULL;
+		return (PF_DROP);
+	}
+
 	if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) {
 		sws = src->wscale & PF_WSCALE_MASK;
 		dws = dst->wscale & PF_WSCALE_MASK;
@@ -3724,7 +3834,8 @@ pf_test_state_tcp(struct pf_state **stat
 
 		/* Deferred generation of sequence number modulator */
 		if (dst->seqdiff && !src->seqdiff) {
-			while ((src->seqdiff = tcp_rndiss_next() - seq) == 0)
+			/* use random iss for the TCP server */
+			while ((src->seqdiff = arc4random() - seq) == 0)
 				;
 			ack = ntohl(th->th_ack) - dst->seqdiff;
 			pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
@@ -3842,7 +3953,8 @@ pf_test_state_tcp(struct pf_state **stat
 	    (ackskew <= (MAXACKWINDOW << sws)) &&
 	    /* Acking not more than one window forward */
 	    ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo ||
-	    (orig_seq == src->seqlo + 1) || (pd->flags & PFDESC_IP_REAS) == 0)) {
+	    (orig_seq == src->seqlo + 1) || (orig_seq + 1 == src->seqlo) ||
+	    (pd->flags & PFDESC_IP_REAS) == 0)) {
 	    /* Require an exact/+1 sequence match on resets when possible */
 
 		if (dst->scrub || src->scrub) {
@@ -3937,9 +4049,12 @@ pf_test_state_tcp(struct pf_state **stat
 			pf_print_state(*state);
 			pf_print_flags(th->th_flags);
 			printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
-			    "pkts=%llu:%llu\n", seq, orig_seq, ack, pd->p_len,
-			    ackskew, (*state)->packets[0],
-			    (*state)->packets[1]);
+			    "pkts=%llu:%llu dir=%s,%s\n", seq, orig_seq, ack,
+			    pd->p_len, ackskew, (*state)->packets[0],
+			    (*state)->packets[1],
+			    direction == PF_IN ? "in" : "out",
+			    direction == (*state)->state_key->direction ?
+				"fwd" : "rev");
 		}
 
 		if (dst->scrub || src->scrub) {

Modified: vendor-sys/pf/dist/net/pf_if.c
==============================================================================
--- vendor-sys/pf/dist/net/pf_if.c	Wed Dec 10 21:22:15 2008	(r185885)
+++ vendor-sys/pf/dist/net/pf_if.c	Wed Dec 10 21:22:57 2008	(r185886)
@@ -1,4 +1,4 @@
-/*	$OpenBSD: pf_if.c,v 1.47 2007/07/13 09:17:48 markus Exp $ */
+/*	$OpenBSD: pf_if.c,v 1.51 2007/11/07 17:28:40 mpf Exp $ */
 
 /*
  * Copyright 2005 Henning Brauer <henning at openbsd.org>
@@ -41,6 +41,7 @@
 #include <sys/kernel.h>
 #include <sys/device.h>
 #include <sys/time.h>
+#include <sys/pool.h>
 
 #include <net/if.h>
 #include <net/if_types.h>
@@ -110,10 +111,9 @@ pfi_kif_get(const char *kif_name)
 		return (kif);
 
 	/* create new one */
-	if ((kif = malloc(sizeof(*kif), PFI_MTYPE, M_DONTWAIT)) == NULL)
+	if ((kif = malloc(sizeof(*kif), PFI_MTYPE, M_DONTWAIT|M_ZERO)) == NULL)
 		return (NULL);
 
-	bzero(kif, sizeof(*kif));
 	strlcpy(kif->pfik_name, kif_name, sizeof(kif->pfik_name));
 	kif->pfik_tzero = time_second;
 	TAILQ_INIT(&kif->pfik_dynaddrs);
@@ -603,49 +603,57 @@ pfi_if_compare(struct pfi_kif *p, struct
 }
 
 void
-pfi_fill_oldstatus(struct pf_status *pfs)
+pfi_update_status(const char *name, struct pf_status *pfs)
 {
 	struct pfi_kif		*p;
 	struct pfi_kif_cmp 	 key;
+	struct ifg_member	 p_member, *ifgm;
+	TAILQ_HEAD(, ifg_member) ifg_members;
 	int			 i, j, k, s;
 
-	strlcpy(key.pfik_name, pfs->ifname, sizeof(key.pfik_name));
+	strlcpy(key.pfik_name, name, sizeof(key.pfik_name));
 	s = splsoftnet();
 	p = RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&key);
 	if (p == NULL) {
 		splx(s);
 		return;
 	}
-	bzero(pfs->pcounters, sizeof(pfs->pcounters));
-	bzero(pfs->bcounters, sizeof(pfs->bcounters));
-	for (i = 0; i < 2; i++)
-		for (j = 0; j < 2; j++)
-			for (k = 0; k < 2; k++) {
-				pfs->pcounters[i][j][k] =
-					p->pfik_packets[i][j][k];
-				pfs->bcounters[i][j] +=
-					p->pfik_bytes[i][j][k];
-			}
-	splx(s);
-}
-
-int
-pfi_clr_istats(const char *name)
-{
-	struct pfi_kif	*p;
-	int		 s;
+	if (p->pfik_group != NULL) {
+		bcopy(&p->pfik_group->ifg_members, &ifg_members,
+		    sizeof(ifg_members));
+	} else {
+		/* build a temporary list for p only */
+		bzero(&p_member, sizeof(p_member));
+		p_member.ifgm_ifp = p->pfik_ifp;
+		TAILQ_INIT(&ifg_members);
+		TAILQ_INSERT_TAIL(&ifg_members, &p_member, ifgm_next);
+	}
+	if (pfs) {
+		bzero(pfs->pcounters, sizeof(pfs->pcounters));
+		bzero(pfs->bcounters, sizeof(pfs->bcounters));
+	}
+	TAILQ_FOREACH(ifgm, &ifg_members, ifgm_next) {
+		if (ifgm->ifgm_ifp == NULL)
+			continue;
+		p = (struct pfi_kif *)ifgm->ifgm_ifp->if_pf_kif;
 
-	s = splsoftnet();
-	RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
-		if (pfi_skip_if(name, p))
+		/* just clear statistics */
+		if (pfs == NULL) {
+			bzero(p->pfik_packets, sizeof(p->pfik_packets));
+			bzero(p->pfik_bytes, sizeof(p->pfik_bytes));
+			p->pfik_tzero = time_second;
 			continue;
-		bzero(p->pfik_packets, sizeof(p->pfik_packets));
-		bzero(p->pfik_bytes, sizeof(p->pfik_bytes));
-		p->pfik_tzero = time_second;
+		}
+		for (i = 0; i < 2; i++)
+			for (j = 0; j < 2; j++)
+				for (k = 0; k < 2; k++) {
+					pfs->pcounters[i][j][k] +=
+						p->pfik_packets[i][j][k];
+					pfs->bcounters[i][j] +=
+						p->pfik_bytes[i][j][k];
+				}
 	}
 	splx(s);
-
-	return (0);
 }
 
 int

Modified: vendor-sys/pf/dist/net/pf_ioctl.c
==============================================================================
--- vendor-sys/pf/dist/net/pf_ioctl.c	Wed Dec 10 21:22:15 2008	(r185885)
+++ vendor-sys/pf/dist/net/pf_ioctl.c	Wed Dec 10 21:22:57 2008	(r185886)
@@ -1,4 +1,4 @@
-/*	$OpenBSD: pf_ioctl.c,v 1.182 2007/06/24 11:17:13 mcbride Exp $ */
+/*	$OpenBSD: pf_ioctl.c,v 1.193 2007/12/02 12:08:04 pascoe Exp $ */
 
 /*
  * Copyright (c) 2001 Daniel Hartmeier
@@ -160,7 +160,7 @@ pfattach(int num)
 	pool_sethardlimit(pf_pool_limits[PF_LIMIT_STATES].pp,
 	    pf_pool_limits[PF_LIMIT_STATES].limit, NULL, 0);
 
-	if (ctob(physmem) <= 100*1024*1024)
+	if (ptoa(physmem) <= 100*1024*1024)
 		pf_pool_limits[PF_LIMIT_TABLE_ENTRIES].limit =
 		    PFR_KENTRY_HIWAT_SMALL;
 
@@ -379,11 +379,9 @@ tagname2tag(struct pf_tags *head, char *
 		return (0);
 
 	/* allocate and fill new struct pf_tagname */
-	tag = (struct pf_tagname *)malloc(sizeof(struct pf_tagname),
-	    M_TEMP, M_NOWAIT);
+	tag = malloc(sizeof(*tag), M_TEMP, M_NOWAIT|M_ZERO);
 	if (tag == NULL)
 		return (0);
-	bzero(tag, sizeof(struct pf_tagname));
 	strlcpy(tag->name, tagname, sizeof(tag->name));
 	tag->tag = new_tagid;
 	tag->ref++;
@@ -912,7 +910,6 @@ pf_state_import(struct pfsync_state *sp,
 	/* copy to state */
 	memcpy(&s->id, &sp->id, sizeof(sp->id));
 	s->creatorid = sp->creatorid;
-	strlcpy(sp->ifname, s->kif->pfik_name, sizeof(sp->ifname));
 	pf_state_peer_from_pfsync(&sp->src, &s->src);
 	pf_state_peer_from_pfsync(&sp->dst, &s->dst);
 
@@ -921,6 +918,9 @@ pf_state_import(struct pfsync_state *sp,
 	s->anchor.ptr = NULL;
 	s->rt_kif = NULL;
 	s->creation = time_second;
+	s->expire = time_second;
+	if (sp->expire > 0)
+		s->expire -= pf_default_rule.timeout[sp->timeout] - sp->expire;
 	s->pfsync_time = 0;
 	s->packets[0] = s->packets[1] = 0;
 	s->bytes[0] = s->bytes[1] = 0;
@@ -1633,7 +1633,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
 
 	case DIOCADDSTATE: {
 		struct pfioc_state	*ps = (struct pfioc_state *)addr;
-		struct pfsync_state 	*sp = (struct pfsync_state *)ps->state;
+		struct pfsync_state 	*sp = &ps->state;
 		struct pf_state		*s;
 		struct pf_state_key	*sk;
 		struct pfi_kif		*kif;
@@ -1650,6 +1650,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
 		}
 		bzero(s, sizeof(struct pf_state));
 		if ((sk = pf_alloc_state_key(s)) == NULL) {
+			pool_put(&pf_state_pl, s);
 			error = ENOMEM;
 			break;
 		}
@@ -1664,30 +1665,28 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
 		if (pf_insert_state(kif, s)) {
 			pfi_kif_unref(kif, PFI_KIF_REF_NONE);
 			pool_put(&pf_state_pl, s);
-			pool_put(&pf_state_key_pl, sk);
-			error = ENOMEM;
+			error = EEXIST;
+			break;
 		}
+		pf_default_rule.states++;
 		break;
 	}
 
 	case DIOCGETSTATE: {
 		struct pfioc_state	*ps = (struct pfioc_state *)addr;
 		struct pf_state		*s;
-		u_int32_t		 nr;
+		struct pf_state_cmp	 id_key;
 
-		nr = 0;
-		RB_FOREACH(s, pf_state_tree_id, &tree_id) {
-			if (nr >= ps->nr)
-				break;
-			nr++;
-		}
+		bcopy(ps->state.id, &id_key.id, sizeof(id_key.id));
+		id_key.creatorid = ps->state.creatorid;
+
+		s = pf_find_state_byid(&id_key);
 		if (s == NULL) {
-			error = EBUSY;
+			error = ENOENT;
 			break;
 		}
 
-		pf_state_export((struct pfsync_state *)&ps->state,
-		    s->state_key, s);
+		pf_state_export(&ps->state, s->state_key, s);
 		break;
 	}
 
@@ -1735,7 +1734,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
 	case DIOCGETSTATUS: {
 		struct pf_status *s = (struct pf_status *)addr;
 		bcopy(&pf_status, s, sizeof(struct pf_status));
-		pfi_fill_oldstatus(s);
+		pfi_update_status(s->ifname, s);
 		break;
 	}
 
@@ -1746,10 +1745,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
 			bzero(pf_status.ifname, IFNAMSIZ);
 			break;
 		}
-		if (ifunit(pi->ifname) == NULL) {
-			error = EINVAL;
-			break;
-		}
 		strlcpy(pf_status.ifname, pi->ifname, IFNAMSIZ);
 		break;
 	}
@@ -1760,7 +1755,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
 		bzero(pf_status.scounters, sizeof(pf_status.scounters));
 		pf_status.since = time_second;
 		if (*pf_status.ifname)
-			pfi_clr_istats(pf_status.ifname);
+			pfi_update_status(pf_status.ifname, NULL);
 		break;
 	}
 
@@ -1793,13 +1788,13 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
 				key.ext.port = pnl->dport;
 				PF_ACPY(&key.gwy.addr, &pnl->saddr, pnl->af);
 				key.gwy.port = pnl->sport;
-				state = pf_find_state_all(&key, PF_EXT_GWY, &m);
+				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;
-				state = pf_find_state_all(&key, PF_LAN_EXT, &m);
+				state = pf_find_state_all(&key, PF_OUT, &m);
 			}
 			if (m > 1)
 				error = E2BIG;	/* more than one state */
@@ -1968,6 +1963,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
 				pool_put(&pf_altq_pl, altq);
 				break;
 			}
+			altq->altq_disc = NULL;
 			TAILQ_FOREACH(a, pf_altqs_inactive, entries) {
 				if (strncmp(a->ifname, altq->ifname,
 				    IFNAMSIZ) == 0 && a->qname[0] == 0) {
@@ -2547,10 +2543,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
 			error = ENODEV;
 			goto fail;
 		}
-		ioe = (struct pfioc_trans_e *)malloc(sizeof(*ioe),
-		    M_TEMP, M_WAITOK);
-		table = (struct pfr_table *)malloc(sizeof(*table),
-		    M_TEMP, M_WAITOK);
+		ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK);
+		table = malloc(sizeof(*table), M_TEMP, M_WAITOK);
 		for (i = 0; i < io->size; i++) {
 			if (copyin(io->array+i, ioe, sizeof(*ioe))) {
 				free(table, M_TEMP);
@@ -2616,10 +2610,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
 			error = ENODEV;
 			goto fail;
 		}
-		ioe = (struct pfioc_trans_e *)malloc(sizeof(*ioe),
-		    M_TEMP, M_WAITOK);
-		table = (struct pfr_table *)malloc(sizeof(*table),
-		    M_TEMP, M_WAITOK);
+		ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK);
+		table = malloc(sizeof(*table), M_TEMP, M_WAITOK);
 		for (i = 0; i < io->size; i++) {
 			if (copyin(io->array+i, ioe, sizeof(*ioe))) {
 				free(table, M_TEMP);
@@ -2680,10 +2672,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
 			error = ENODEV;
 			goto fail;
 		}
-		ioe = (struct pfioc_trans_e *)malloc(sizeof(*ioe),
-		    M_TEMP, M_WAITOK);
-		table = (struct pfr_table *)malloc(sizeof(*table),
-		    M_TEMP, M_WAITOK);
+		ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK);
+		table = malloc(sizeof(*table), M_TEMP, M_WAITOK);
 		/* first makes sure everything will succeed */
 		for (i = 0; i < io->size; i++) {
 			if (copyin(io->array+i, ioe, sizeof(*ioe))) {

Modified: vendor-sys/pf/dist/net/pf_norm.c
==============================================================================
--- vendor-sys/pf/dist/net/pf_norm.c	Wed Dec 10 21:22:15 2008	(r185885)
+++ vendor-sys/pf/dist/net/pf_norm.c	Wed Dec 10 21:22:57 2008	(r185886)
@@ -1,4 +1,4 @@
-/*	$OpenBSD: pf_norm.c,v 1.109 2007/05/28 17:16:39 henning Exp $ */
+/*	$OpenBSD: pf_norm.c,v 1.111 2007/12/30 10:32:24 mglocker Exp $ */
 
 /*
  * Copyright 2001 Niels Provos <provos at citi.umich.edu>
@@ -115,7 +115,7 @@ struct mbuf		*pf_reassemble(struct mbuf 
 struct mbuf		*pf_fragcache(struct mbuf **, struct ip*,
 			    struct pf_fragment **, int, int, int *);
 int			 pf_normalize_tcpopt(struct pf_rule *, struct mbuf *,
-			    struct tcphdr *, int);
+			    struct tcphdr *, int, sa_family_t);
 
 #define	DPFPRINTF(x) do {				\
 	if (pf_status.debug >= PF_DEBUG_MISC) {		\
@@ -1316,7 +1316,7 @@ pf_normalize_tcp(int dir, struct pfi_kif
 	}
 
 	/* Process options */
-	if (r->max_mss && pf_normalize_tcpopt(r, m, th, off))
+	if (r->max_mss && pf_normalize_tcpopt(r, m, th, off, pd->af))
 		rewrite = 1;
 
 	/* copy back packet headers if we sanitized */
@@ -1819,17 +1819,21 @@ pf_normalize_tcp_stateful(struct mbuf *m
 
 int
 pf_normalize_tcpopt(struct pf_rule *r, struct mbuf *m, struct tcphdr *th,
-    int off)
+    int off, sa_family_t af)
 {
 	u_int16_t	*mss;
 	int		 thoff;
 	int		 opt, cnt, optlen = 0;
 	int		 rewrite = 0;
-	u_char		*optp;
+	u_char		 opts[MAX_TCPOPTLEN];
+	u_char		*optp = opts;
 
 	thoff = th->th_off << 2;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-vendor mailing list