svn commit: r185884 - vendor-sys/pf/dist/net
Max Laier
mlaier at FreeBSD.org
Wed Dec 10 13:21:10 PST 2008
Author: mlaier
Date: Wed Dec 10 21:21:09 2008
New Revision: 185884
URL: http://svn.freebsd.org/changeset/base/185884
Log:
Import OPENBSD_4_2_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_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:09:09 2008 (r185883)
+++ vendor-sys/pf/dist/net/if_pflog.c Wed Dec 10 21:21:09 2008 (r185884)
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pflog.c,v 1.22 2006/12/15 09:31:20 otto Exp $ */
+/* $OpenBSD: if_pflog.c,v 1.24 2007/05/26 17:13:30 jason Exp $ */
/*
* The authors of this code are John Ioannidis (ji at tla.org),
* Angelos D. Keromytis (kermit at csd.uch.gr) and
@@ -87,8 +87,6 @@ struct if_clone pflog_cloner =
struct ifnet *pflogifs[PFLOGIFS_MAX]; /* for fast access */
-extern int ifqmaxlen;
-
void
pflogattach(int npflog)
{
@@ -96,7 +94,6 @@ pflogattach(int npflog)
LIST_INIT(&pflogif_list);
for (i = 0; i < PFLOGIFS_MAX; i++)
pflogifs[i] = NULL;
- (void) pflog_clone_create(&pflog_cloner, 0);
if_clone_attach(&pflog_cloner);
}
Modified: vendor-sys/pf/dist/net/if_pfsync.c
==============================================================================
--- vendor-sys/pf/dist/net/if_pfsync.c Wed Dec 10 21:09:09 2008 (r185883)
+++ vendor-sys/pf/dist/net/if_pfsync.c Wed Dec 10 21:21:09 2008 (r185884)
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pfsync.c,v 1.73 2006/11/16 13:13:38 henning Exp $ */
+/* $OpenBSD: if_pfsync.c,v 1.83 2007/06/26 14:44:12 mcbride Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff
@@ -106,7 +106,6 @@ void pfsync_bulk_update(void *);
void pfsync_bulkfail(void *);
int pfsync_sync_ok;
-extern int ifqmaxlen;
struct if_clone pfsync_cloner =
IF_CLONE_INITIALIZER("pfsync", pfsync_clone_create, pfsync_clone_destroy);
@@ -221,6 +220,7 @@ int
pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag)
{
struct pf_state *st = NULL;
+ struct pf_state_key *sk = NULL;
struct pf_rule *r = NULL;
struct pfi_kif *kif;
@@ -243,7 +243,9 @@ pfsync_insert_net_state(struct pfsync_st
* If the ruleset checksums match, it's safe to associate the state
* with the rule of that number.
*/
- if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) && chksum_flag)
+ if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) && chksum_flag &&
+ 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
@@ -257,6 +259,12 @@ pfsync_insert_net_state(struct pfsync_st
}
bzero(st, sizeof(*st));
+ if ((sk = pf_alloc_state_key(st)) == NULL) {
+ pool_put(&pf_state_pl, st);
+ pfi_kif_unref(kif, PFI_KIF_REF_NONE);
+ return (ENOMEM);
+ }
+
/* allocate memory for scrub info */
if (pfsync_alloc_scrub_memory(&sp->src, &st->src) ||
pfsync_alloc_scrub_memory(&sp->dst, &st->dst)) {
@@ -264,6 +272,7 @@ pfsync_insert_net_state(struct pfsync_st
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);
}
@@ -274,9 +283,9 @@ pfsync_insert_net_state(struct pfsync_st
r->states++;
/* fill in the rest of the state entry */
- pf_state_host_ntoh(&sp->lan, &st->lan);
- pf_state_host_ntoh(&sp->gwy, &st->gwy);
- pf_state_host_ntoh(&sp->ext, &st->ext);
+ pf_state_host_ntoh(&sp->lan, &sk->lan);
+ pf_state_host_ntoh(&sp->gwy, &sk->gwy);
+ pf_state_host_ntoh(&sp->ext, &sk->ext);
pf_state_peer_ntoh(&sp->src, &st->src);
pf_state_peer_ntoh(&sp->dst, &st->dst);
@@ -285,9 +294,9 @@ pfsync_insert_net_state(struct pfsync_st
st->creation = time_second - ntohl(sp->creation);
st->expire = ntohl(sp->expire) + time_second;
- st->af = sp->af;
- st->proto = sp->proto;
- st->direction = sp->direction;
+ sk->af = sp->af;
+ sk->proto = sp->proto;
+ sk->direction = sp->direction;
st->log = sp->log;
st->timeout = sp->timeout;
st->allow_opts = sp->allow_opts;
@@ -318,14 +327,17 @@ pfsync_input(struct mbuf *m, ...)
struct pfsync_header *ph;
struct pfsync_softc *sc = pfsyncif;
struct pf_state *st;
- struct pf_state_cmp key;
+ struct pf_state_key *sk;
+ struct pf_state_cmp id_key;
struct pfsync_state *sp;
struct pfsync_state_upd *up;
struct pfsync_state_del *dp;
struct pfsync_state_clr *cp;
struct pfsync_state_upd_req *rup;
struct pfsync_state_bus *bus;
+#ifdef IPSEC
struct pfsync_tdb *pt;
+#endif
struct in_addr src;
struct mbuf *mp;
int iplen, action, error, i, s, count, offp, sfail, stale = 0;
@@ -389,7 +401,8 @@ pfsync_input(struct mbuf *m, ...)
switch (action) {
case PFSYNC_ACT_CLR: {
struct pf_state *nexts;
- struct pfi_kif *kif;
+ struct pf_state_key *nextsk;
+ struct pfi_kif *kif;
u_int32_t creatorid;
if ((mp = m_pulldown(m, iplen + sizeof(*ph),
sizeof(*cp), &offp)) == NULL) {
@@ -414,13 +427,16 @@ pfsync_input(struct mbuf *m, ...)
splx(s);
return;
}
- for (st = RB_MIN(pf_state_tree_lan_ext,
- &kif->pfik_lan_ext); st; st = nexts) {
- nexts = RB_NEXT(pf_state_tree_lan_ext,
- &kif->pfik_lan_ext, st);
- if (st->creatorid == creatorid) {
- st->sync_flags |= PFSTATE_FROMSYNC;
- pf_unlink_state(st);
+ 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 |=
+ PFSTATE_FROMSYNC;
+ pf_unlink_state(st);
+ }
}
}
}
@@ -485,18 +501,19 @@ pfsync_input(struct mbuf *m, ...)
continue;
}
- bcopy(sp->id, &key.id, sizeof(key.id));
- key.creatorid = sp->creatorid;
+ bcopy(sp->id, &id_key.id, sizeof(id_key.id));
+ id_key.creatorid = sp->creatorid;
- st = pf_find_state_byid(&key);
+ st = pf_find_state_byid(&id_key);
if (st == NULL) {
/* insert the update */
if (pfsync_insert_net_state(sp, chksum_flag))
pfsyncstats.pfsyncs_badstate++;
continue;
}
+ sk = st->state_key;
sfail = 0;
- if (st->proto == IPPROTO_TCP) {
+ if (sk->proto == IPPROTO_TCP) {
/*
* The state should never go backwards except
* for syn-proxy states. Neither should the
@@ -579,10 +596,10 @@ pfsync_input(struct mbuf *m, ...)
s = splsoftnet();
for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp);
i < count; i++, sp++) {
- bcopy(sp->id, &key.id, sizeof(key.id));
- key.creatorid = sp->creatorid;
+ bcopy(sp->id, &id_key.id, sizeof(id_key.id));
+ id_key.creatorid = sp->creatorid;
- st = pf_find_state_byid(&key);
+ st = pf_find_state_byid(&id_key);
if (st == NULL) {
pfsyncstats.pfsyncs_badstate++;
continue;
@@ -616,10 +633,10 @@ pfsync_input(struct mbuf *m, ...)
continue;
}
- bcopy(up->id, &key.id, sizeof(key.id));
- key.creatorid = up->creatorid;
+ bcopy(up->id, &id_key.id, sizeof(id_key.id));
+ id_key.creatorid = up->creatorid;
- st = pf_find_state_byid(&key);
+ st = pf_find_state_byid(&id_key);
if (st == NULL) {
/* We don't have this state. Ask for it. */
error = pfsync_request_update(up, &src);
@@ -631,8 +648,9 @@ pfsync_input(struct mbuf *m, ...)
pfsyncstats.pfsyncs_badstate++;
continue;
}
+ sk = st->state_key;
sfail = 0;
- if (st->proto == IPPROTO_TCP) {
+ if (sk->proto == IPPROTO_TCP) {
/*
* The state should never go backwards except
* for syn-proxy states. Neither should the
@@ -702,10 +720,10 @@ pfsync_input(struct mbuf *m, ...)
s = splsoftnet();
for (i = 0, dp = (struct pfsync_state_del *)(mp->m_data + offp);
i < count; i++, dp++) {
- bcopy(dp->id, &key.id, sizeof(key.id));
- key.creatorid = dp->creatorid;
+ bcopy(dp->id, &id_key.id, sizeof(id_key.id));
+ id_key.creatorid = dp->creatorid;
- st = pf_find_state_byid(&key);
+ st = pf_find_state_byid(&id_key);
if (st == NULL) {
pfsyncstats.pfsyncs_badstate++;
continue;
@@ -732,10 +750,10 @@ pfsync_input(struct mbuf *m, ...)
for (i = 0,
rup = (struct pfsync_state_upd_req *)(mp->m_data + offp);
i < count; i++, rup++) {
- bcopy(rup->id, &key.id, sizeof(key.id));
- key.creatorid = rup->creatorid;
+ bcopy(rup->id, &id_key.id, sizeof(id_key.id));
+ id_key.creatorid = rup->creatorid;
- if (key.id == 0 && key.creatorid == 0) {
+ if (id_key.id == 0 && id_key.creatorid == 0) {
sc->sc_ureq_received = time_uptime;
if (sc->sc_bulk_send_next == NULL)
sc->sc_bulk_send_next =
@@ -747,7 +765,7 @@ pfsync_input(struct mbuf *m, ...)
pfsync_send_bus(sc, PFSYNC_BUS_START);
timeout_add(&sc->sc_bulk_tmo, 1 * hz);
} else {
- st = pf_find_state_byid(&key);
+ st = pf_find_state_byid(&id_key);
if (st == NULL) {
pfsyncstats.pfsyncs_badstate++;
continue;
@@ -804,6 +822,7 @@ pfsync_input(struct mbuf *m, ...)
break;
}
break;
+#ifdef IPSEC
case PFSYNC_ACT_TDB_UPD:
if ((mp = m_pulldown(m, iplen + sizeof(*ph),
count * sizeof(*pt), &offp)) == NULL) {
@@ -816,6 +835,7 @@ pfsync_input(struct mbuf *m, ...)
pfsync_update_net_tdb(pt);
splx(s);
break;
+#endif
}
done:
@@ -1080,6 +1100,7 @@ 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;
@@ -1164,10 +1185,10 @@ pfsync_pack_state(u_int8_t action, struc
bcopy(&st->id, sp->id, sizeof(sp->id));
sp->creatorid = st->creatorid;
- strlcpy(sp->ifname, st->u.s.kif->pfik_name, sizeof(sp->ifname));
- pf_state_host_hton(&st->lan, &sp->lan);
- pf_state_host_hton(&st->gwy, &sp->gwy);
- pf_state_host_hton(&st->ext, &sp->ext);
+ 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));
@@ -1184,9 +1205,9 @@ pfsync_pack_state(u_int8_t action, struc
sp->anchor = htonl(-1);
else
sp->anchor = htonl(r->nr);
- sp->af = st->af;
- sp->proto = st->proto;
- sp->direction = st->direction;
+ 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;
@@ -1418,7 +1439,7 @@ pfsync_bulk_update(void *v)
}
/* figure next state to send */
- state = TAILQ_NEXT(state, u.s.entry_list);
+ state = TAILQ_NEXT(state, entry_list);
/* wrap to start of list if we hit the end */
if (!state)
@@ -1577,6 +1598,7 @@ pfsync_sendout_mbuf(struct pfsync_softc
return (0);
}
+#ifdef IPSEC
/* Update an in-kernel tdb. Silently fail if no tdb is found. */
void
pfsync_update_net_tdb(struct pfsync_tdb *pt)
@@ -1727,3 +1749,4 @@ pfsync_update_tdb(struct tdb *tdb, int o
splx(s);
return (ret);
}
+#endif
Modified: vendor-sys/pf/dist/net/if_pfsync.h
==============================================================================
--- vendor-sys/pf/dist/net/if_pfsync.h Wed Dec 10 21:09:09 2008 (r185883)
+++ vendor-sys/pf/dist/net/if_pfsync.h Wed Dec 10 21:21:09 2008 (r185884)
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pfsync.h,v 1.30 2006/10/31 14:49:01 henning Exp $ */
+/* $OpenBSD: if_pfsync.h,v 1.31 2007/05/31 04:11:42 mcbride Exp $ */
/*
* Copyright (c) 2001 Michael Shalayeff
@@ -32,62 +32,6 @@
#define PFSYNC_ID_LEN sizeof(u_int64_t)
-struct pfsync_state_scrub {
- u_int16_t pfss_flags;
- u_int8_t pfss_ttl; /* stashed TTL */
-#define PFSYNC_SCRUB_FLAG_VALID 0x01
- u_int8_t scrub_flag;
- u_int32_t pfss_ts_mod; /* timestamp modulation */
-} __packed;
-
-struct pfsync_state_host {
- struct pf_addr addr;
- u_int16_t port;
- u_int16_t pad[3];
-} __packed;
-
-struct pfsync_state_peer {
- struct pfsync_state_scrub scrub; /* state is scrubbed */
- u_int32_t seqlo; /* Max sequence number sent */
- u_int32_t seqhi; /* Max the other end ACKd + win */
- u_int32_t seqdiff; /* Sequence number modulator */
- u_int16_t max_win; /* largest window (pre scaling) */
- u_int16_t mss; /* Maximum segment size option */
- u_int8_t state; /* active state level */
- u_int8_t wscale; /* window scaling factor */
- u_int8_t pad[6];
-} __packed;
-
-struct pfsync_state {
- u_int32_t id[2];
- char ifname[IFNAMSIZ];
- struct pfsync_state_host lan;
- struct pfsync_state_host gwy;
- struct pfsync_state_host ext;
- struct pfsync_state_peer src;
- struct pfsync_state_peer dst;
- struct pf_addr rt_addr;
- u_int32_t rule;
- u_int32_t anchor;
- u_int32_t nat_rule;
- u_int32_t creation;
- u_int32_t expire;
- u_int32_t packets[2][2];
- u_int32_t bytes[2][2];
- u_int32_t creatorid;
- sa_family_t af;
- u_int8_t proto;
- u_int8_t direction;
- u_int8_t log;
- u_int8_t allow_opts;
- u_int8_t timeout;
- u_int8_t sync_flags;
- u_int8_t updates;
-} __packed;
-
-#define PFSYNC_FLAG_COMPRESS 0x01
-#define PFSYNC_FLAG_STALE 0x02
-
struct pfsync_tdb {
u_int32_t spi;
union sockaddr_union dst;
@@ -251,6 +195,7 @@ struct pfsyncreq {
};
+/* for copies to/from network */
#define pf_state_peer_hton(s,d) do { \
(d)->seqlo = htonl((s)->seqlo); \
(d)->seqhi = htonl((s)->seqhi); \
@@ -312,7 +257,7 @@ int pfsync_clear_states(u_int32_t, char
int pfsync_pack_state(u_int8_t, struct pf_state *, int);
#define pfsync_insert_state(st) do { \
if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) || \
- (st->proto == IPPROTO_PFSYNC)) \
+ (st->state_key->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:09:09 2008 (r185883)
+++ vendor-sys/pf/dist/net/pf.c Wed Dec 10 21:21:09 2008 (r185884)
@@ -1,5 +1,4 @@
-/* $OpenBSD: pf.c,v 1.527 2007/02/22 15:23:23 pyr Exp $ */
-/* add: $OpenBSD: pf.c,v 1.559 2007/09/18 18:45:59 markus Exp $ */
+/* $OpenBSD: pf.c,v 1.552 2007/08/21 15:57:27 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -96,6 +95,10 @@
* Global variables
*/
+/* state tables */
+struct pf_state_tree_lan_ext pf_statetbl_lan_ext;
+struct pf_state_tree_ext_gwy pf_statetbl_ext_gwy;
+
struct pf_altqqueue pf_altqs[2];
struct pf_palist pf_pabuf;
struct pf_altqqueue *pf_altqs_active;
@@ -114,8 +117,9 @@ struct pf_anchor_stackframe {
struct pf_anchor *child;
} pf_anchor_stack[64];
-struct pool pf_src_tree_pl, pf_rule_pl;
-struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
+struct pool pf_src_tree_pl, pf_rule_pl, pf_pooladdr_pl;
+struct pool pf_state_pl, pf_state_key_pl;
+struct pool pf_altq_pl;
void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t);
@@ -153,22 +157,13 @@ struct pf_rule *pf_get_translation(stru
struct pf_addr *, u_int16_t,
struct pf_addr *, u_int16_t,
struct pf_addr *, u_int16_t *);
-int pf_test_tcp(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 *);
-int pf_test_udp(struct pf_rule **, struct pf_state **,
+void pf_attach_state(struct pf_state_key *,
+ struct pf_state *, int);
+void pf_detach_state(struct pf_state *, int);
+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 *);
-int pf_test_icmp(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 *);
-int pf_test_other(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 *);
int pf_test_fragment(struct pf_rule **, int,
struct pfi_kif *, struct mbuf *, void *,
struct pf_pdesc *, struct pf_rule **,
@@ -184,8 +179,9 @@ int pf_test_state_icmp(struct pf_stat
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 *,
- struct pf_mtag *, int *);
+int pf_match_tag(struct mbuf *, struct pf_rule *, int *);
+void pf_step_into_anchor(int *, struct pf_ruleset **, 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 *);
@@ -217,9 +213,11 @@ int pf_check_proto_cksum(struct mbuf
u_int8_t, sa_family_t);
int pf_addr_wrap_neq(struct pf_addr_wrap *,
struct pf_addr_wrap *);
-struct pf_state *pf_find_state_recurse(struct pfi_kif *,
- struct pf_state_cmp *, u_int8_t);
+struct pf_state *pf_find_state(struct pfi_kif *,
+ struct pf_state_key_cmp *, u_int8_t);
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;
@@ -236,11 +234,9 @@ struct pf_pool_limit pf_pool_limits[PF_L
#define STATE_LOOKUP() \
do { \
if (direction == PF_IN) \
- *state = pf_find_state_recurse( \
- kif, &key, PF_EXT_GWY); \
+ *state = pf_find_state(kif, &key, PF_EXT_GWY); \
else \
- *state = pf_find_state_recurse( \
- kif, &key, PF_LAN_EXT); \
+ *state = pf_find_state(kif, &key, PF_LAN_EXT); \
if (*state == NULL || (*state)->timeout == PFTM_PURGE) \
return (PF_DROP); \
if (direction == PF_OUT && \
@@ -253,13 +249,13 @@ struct pf_pool_limit pf_pool_limits[PF_L
return (PF_PASS); \
} while (0)
-#define STATE_TRANSLATE(s) \
- (s)->lan.addr.addr32[0] != (s)->gwy.addr.addr32[0] || \
- ((s)->af == AF_INET6 && \
- ((s)->lan.addr.addr32[1] != (s)->gwy.addr.addr32[1] || \
- (s)->lan.addr.addr32[2] != (s)->gwy.addr.addr32[2] || \
- (s)->lan.addr.addr32[3] != (s)->gwy.addr.addr32[3])) || \
- (s)->lan.port != (s)->gwy.port
+#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
@@ -283,10 +279,10 @@ struct pf_pool_limit pf_pool_limits[PF_L
} 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 *,
- struct pf_state *);
-static __inline int pf_state_compare_ext_gwy(struct pf_state *,
- struct pf_state *);
+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 *,
+ struct pf_state_key *);
static __inline int pf_state_compare_id(struct pf_state *,
struct pf_state *);
@@ -296,12 +292,15 @@ 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,
- u.s.entry_lan_ext, pf_state_compare_lan_ext);
-RB_GENERATE(pf_state_tree_ext_gwy, pf_state,
- u.s.entry_ext_gwy, pf_state_compare_ext_gwy);
+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_id, pf_state,
- u.s.entry_id, pf_state_compare_id);
+ 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)
@@ -348,7 +347,7 @@ pf_src_compare(struct pf_src_node *a, st
}
static __inline int
-pf_state_compare_lan_ext(struct pf_state *a, struct pf_state *b)
+pf_state_compare_lan_ext(struct pf_state_key *a, struct pf_state_key *b)
{
int diff;
@@ -416,7 +415,7 @@ pf_state_compare_lan_ext(struct pf_state
}
static __inline int
-pf_state_compare_ext_gwy(struct pf_state *a, struct pf_state *b)
+pf_state_compare_ext_gwy(struct pf_state_key *a, struct pf_state_key *b)
{
int diff;
@@ -522,74 +521,71 @@ 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_recurse(struct pfi_kif *kif, struct pf_state_cmp *key, u_int8_t tree)
+pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int8_t tree)
{
- struct pf_state *s;
+ struct pf_state_key *sk;
+ struct pf_state *s;
pf_status.fcounters[FCNT_STATE_SEARCH]++;
switch (tree) {
case PF_LAN_EXT:
- if ((s = RB_FIND(pf_state_tree_lan_ext, &kif->pfik_lan_ext,
- (struct pf_state *)key)) != NULL)
- return (s);
- if ((s = RB_FIND(pf_state_tree_lan_ext, &pfi_all->pfik_lan_ext,
- (struct pf_state *)key)) != NULL)
- return (s);
- return (NULL);
+ sk = RB_FIND(pf_state_tree_lan_ext, &pf_statetbl_lan_ext,
+ (struct pf_state_key *)key);
+ break;
case PF_EXT_GWY:
- if ((s = RB_FIND(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy,
- (struct pf_state *)key)) != NULL)
- return (s);
- if ((s = RB_FIND(pf_state_tree_ext_gwy, &pfi_all->pfik_ext_gwy,
- (struct pf_state *)key)) != NULL)
- return (s);
- return (NULL);
+ sk = RB_FIND(pf_state_tree_ext_gwy, &pf_statetbl_ext_gwy,
+ (struct pf_state_key *)key);
+ break;
default:
- panic("pf_find_state_recurse");
+ 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_cmp *key, u_int8_t tree, int *more)
+pf_find_state_all(struct pf_state_key_cmp *key, u_int8_t tree, int *more)
{
- struct pf_state *s, *ss = NULL;
- struct pfi_kif *kif;
+ struct pf_state_key *sk;
+ struct pf_state *s, *ret = NULL;
pf_status.fcounters[FCNT_STATE_SEARCH]++;
switch (tree) {
case PF_LAN_EXT:
- TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) {
- s = RB_FIND(pf_state_tree_lan_ext,
- &kif->pfik_lan_ext, (struct pf_state *)key);
- if (s == NULL)
- continue;
- if (more == NULL)
- return (s);
- ss = s;
- (*more)++;
- }
- return (ss);
+ sk = RB_FIND(pf_state_tree_lan_ext,
+ &pf_statetbl_lan_ext, (struct pf_state_key *)key);
+ break;
case PF_EXT_GWY:
- TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) {
- s = RB_FIND(pf_state_tree_ext_gwy,
- &kif->pfik_ext_gwy, (struct pf_state *)key);
- if (s == NULL)
- continue;
- if (more == NULL)
- return (s);
- ss = s;
- (*more)++;
- }
- return (ss);
+ sk = RB_FIND(pf_state_tree_ext_gwy,
+ &pf_statetbl_ext_gwy, (struct pf_state_key *)key);
+ break;
default:
panic("pf_find_state_all");
}
+
+ if (sk != NULL) {
+ ret = TAILQ_FIRST(&sk->states);
+ if (more == NULL)
+ return (ret);
+
+ TAILQ_FOREACH(s, &sk->states, next)
+ (*more)++;
+ }
+
+ return (ret);
}
void
@@ -625,7 +621,6 @@ pf_check_threshold(struct pf_threshold *
int
pf_src_connlimit(struct pf_state **state)
{
- struct pf_state *s;
int bad = 0;
(*state)->src_node->conn++;
@@ -656,12 +651,12 @@ pf_src_connlimit(struct pf_state **state
if (pf_status.debug >= PF_DEBUG_MISC) {
printf("pf_src_connlimit: blocking address ");
pf_print_host(&(*state)->src_node->addr, 0,
- (*state)->af);
+ (*state)->state_key->af);
}
bzero(&p, sizeof(p));
- p.pfra_af = (*state)->af;
- switch ((*state)->af) {
+ p.pfra_af = (*state)->state_key->af;
+ switch ((*state)->state_key->af) {
#ifdef INET
case AF_INET:
p.pfra_net = 32;
@@ -681,26 +676,31 @@ pf_src_connlimit(struct pf_state **state
/* kill existing states if that's required. */
if ((*state)->rule.ptr->flush) {
- pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
+ struct pf_state_key *sk;
+ struct pf_state *st;
- RB_FOREACH(s, pf_state_tree_id, &tree_id) {
+ pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
+ RB_FOREACH(st, pf_state_tree_id, &tree_id) {
+ sk = st->state_key;
/*
* Kill states from this source. (Only those
* from the same rule if PF_FLUSH_GLOBAL is not
* set)
*/
- if (s->af == (*state)->af &&
- (((*state)->direction == PF_OUT &&
+ if (sk->af ==
+ (*state)->state_key->af &&
+ (((*state)->state_key->direction ==
+ PF_OUT &&
PF_AEQ(&(*state)->src_node->addr,
- &s->lan.addr, s->af)) ||
- ((*state)->direction == PF_IN &&
+ &sk->lan.addr, sk->af)) ||
+ ((*state)->state_key->direction == PF_IN &&
PF_AEQ(&(*state)->src_node->addr,
- &s->ext.addr, s->af))) &&
+ &sk->ext.addr, sk->af))) &&
((*state)->rule.ptr->flush &
PF_FLUSH_GLOBAL ||
- (*state)->rule.ptr == s->rule.ptr)) {
- s->timeout = PFTM_PURGE;
- s->src.state = s->dst.state =
+ (*state)->rule.ptr == st->rule.ptr)) {
+ st->timeout = PFTM_PURGE;
+ st->src.state = st->dst.state =
TCPS_CLOSED;
killed++;
}
@@ -782,73 +782,80 @@ pf_insert_src_node(struct pf_src_node **
return (0);
}
+void
+pf_stateins_err(const char *tree, struct pf_state *s, struct pfi_kif *kif)
+{
+ struct pf_state_key *sk = s->state_key;
+
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+ printf("pf: state insert failed: %s %s", tree, kif->pfik_name);
+ printf(" lan: ");
+ pf_print_host(&sk->lan.addr, sk->lan.port,
+ sk->af);
+ printf(" gwy: ");
+ pf_print_host(&sk->gwy.addr, sk->gwy.port,
+ sk->af);
+ printf(" ext: ");
+ pf_print_host(&sk->ext.addr, sk->ext.port,
+ sk->af);
+ if (s->sync_flags & PFSTATE_FROMSYNC)
+ printf(" (from sync)");
+ printf("\n");
+ }
+}
+
int
-pf_insert_state(struct pfi_kif *kif, struct pf_state *state)
+pf_insert_state(struct pfi_kif *kif, struct pf_state *s)
{
- /* Thou MUST NOT insert multiple duplicate keys */
- state->u.s.kif = kif;
- if (RB_INSERT(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state)) {
- if (pf_status.debug >= PF_DEBUG_MISC) {
- printf("pf: state insert failed: tree_lan_ext");
- printf(" lan: ");
- pf_print_host(&state->lan.addr, state->lan.port,
- state->af);
- printf(" gwy: ");
- pf_print_host(&state->gwy.addr, state->gwy.port,
- state->af);
- printf(" ext: ");
- pf_print_host(&state->ext.addr, state->ext.port,
- state->af);
- if (state->sync_flags & PFSTATE_FROMSYNC)
- printf(" (from sync)");
- printf("\n");
- }
- return (-1);
+ struct pf_state_key *cur;
+ struct pf_state *sp;
+
+ KASSERT(s->state_key != NULL);
+ s->kif = kif;
+
+ if ((cur = RB_INSERT(pf_state_tree_lan_ext, &pf_statetbl_lan_ext,
+ s->state_key)) != NULL) {
+ /* key exists. check for same kif, if none, add to key */
+ TAILQ_FOREACH(sp, &cur->states, next)
+ if (sp->kif == kif) { /* collision! */
+ pf_stateins_err("tree_lan_ext", s, kif);
+ return (-1);
+ }
+ pf_detach_state(s, PF_DT_SKIP_LANEXT|PF_DT_SKIP_EXTGWY);
+ pf_attach_state(cur, s, kif == pfi_all ? 1 : 0);
}
- if (RB_INSERT(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state)) {
- if (pf_status.debug >= PF_DEBUG_MISC) {
- printf("pf: state insert failed: tree_ext_gwy");
- printf(" lan: ");
- pf_print_host(&state->lan.addr, state->lan.port,
- state->af);
- printf(" gwy: ");
- pf_print_host(&state->gwy.addr, state->gwy.port,
- state->af);
- printf(" ext: ");
- pf_print_host(&state->ext.addr, state->ext.port,
- state->af);
- if (state->sync_flags & PFSTATE_FROMSYNC)
- printf(" (from sync)");
- printf("\n");
- }
- RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state);
+ /* if cur != NULL, we already found a state key and attached to it */
+ if (cur == NULL && (cur = RB_INSERT(pf_state_tree_ext_gwy,
+ &pf_statetbl_ext_gwy, s->state_key)) != NULL) {
+ /* must not happen. we must have found the sk above! */
+ pf_stateins_err("tree_ext_gwy", s, kif);
+ pf_detach_state(s, PF_DT_SKIP_EXTGWY);
return (-1);
}
- if (state->id == 0 && state->creatorid == 0) {
- state->id = htobe64(pf_status.stateid++);
- state->creatorid = pf_status.hostid;
+ if (s->id == 0 && s->creatorid == 0) {
+ s->id = htobe64(pf_status.stateid++);
+ s->creatorid = pf_status.hostid;
}
- if (RB_INSERT(pf_state_tree_id, &tree_id, state) != NULL) {
+ if (RB_INSERT(pf_state_tree_id, &tree_id, s) != NULL) {
if (pf_status.debug >= PF_DEBUG_MISC) {
printf("pf: state insert failed: "
"id: %016llx creatorid: %08x",
- betoh64(state->id), ntohl(state->creatorid));
- if (state->sync_flags & PFSTATE_FROMSYNC)
+ betoh64(s->id), ntohl(s->creatorid));
+ if (s->sync_flags & PFSTATE_FROMSYNC)
printf(" (from sync)");
printf("\n");
}
- RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state);
- RB_REMOVE(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state);
+ pf_detach_state(s, 0);
return (-1);
}
- TAILQ_INSERT_TAIL(&state_list, state, u.s.entry_list);
+ TAILQ_INSERT_TAIL(&state_list, s, entry_list);
pf_status.fcounters[FCNT_STATE_INSERT]++;
pf_status.states++;
pfi_kif_ref(kif, PFI_KIF_REF_STATE);
#if NPFSYNC
- pfsync_insert_state(state);
+ pfsync_insert_state(s);
#endif
return (0);
}
@@ -954,7 +961,7 @@ pf_src_tree_remove_state(struct pf_state
u_int32_t timeout;
if (s->src_node != NULL) {
- if (s->proto == IPPROTO_TCP) {
+ if (s->state_key->proto == IPPROTO_TCP) {
if (s->src.tcp_est)
--s->src_node->conn;
}
@@ -983,16 +990,12 @@ void
pf_unlink_state(struct pf_state *cur)
{
if (cur->src.state == PF_TCPS_PROXY_DST) {
- pf_send_tcp(cur->rule.ptr, cur->af,
- &cur->ext.addr, &cur->lan.addr,
- cur->ext.port, cur->lan.port,
+ pf_send_tcp(cur->rule.ptr, cur->state_key->af,
+ &cur->state_key->ext.addr, &cur->state_key->lan.addr,
+ cur->state_key->ext.port, cur->state_key->lan.port,
cur->src.seqhi, cur->src.seqlo + 1,
TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL);
}
- RB_REMOVE(pf_state_tree_ext_gwy,
- &cur->u.s.kif->pfik_ext_gwy, cur);
- RB_REMOVE(pf_state_tree_lan_ext,
- &cur->u.s.kif->pfik_lan_ext, cur);
RB_REMOVE(pf_state_tree_id, &tree_id, cur);
#if NPFSYNC
if (cur->creatorid == pf_status.hostid)
@@ -1000,6 +1003,7 @@ pf_unlink_state(struct pf_state *cur)
#endif
cur->timeout = PFTM_UNLINKED;
pf_src_tree_remove_state(cur);
+ pf_detach_state(cur, 0);
}
/* callers should be at splsoftnet and hold the
@@ -1025,8 +1029,8 @@ pf_free_state(struct pf_state *cur)
if (--cur->anchor.ptr->states <= 0)
pf_rm_rule(NULL, cur->anchor.ptr);
pf_normalize_tcp_cleanup(cur);
- pfi_kif_unref(cur->u.s.kif, PFI_KIF_REF_STATE);
- TAILQ_REMOVE(&state_list, cur, u.s.entry_list);
+ pfi_kif_unref(cur->kif, PFI_KIF_REF_STATE);
+ TAILQ_REMOVE(&state_list, cur, entry_list);
if (cur->tag)
pf_tag_unref(cur->tag);
pool_put(&pf_state_pl, cur);
@@ -1050,7 +1054,7 @@ pf_purge_expired_states(u_int32_t maxche
}
/* get next state, as cur may get deleted */
- next = TAILQ_NEXT(cur, u.s.entry_list);
+ next = TAILQ_NEXT(cur, entry_list);
if (cur->timeout == PFTM_UNLINKED) {
/* free unlinked state */
@@ -1175,7 +1179,8 @@ pf_print_host(struct pf_addr *addr, u_in
void
pf_print_state(struct pf_state *s)
{
- switch (s->proto) {
+ struct pf_state_key *sk = s->state_key;
+ switch (sk->proto) {
case IPPROTO_TCP:
printf("TCP ");
break;
@@ -1189,14 +1194,14 @@ pf_print_state(struct pf_state *s)
printf("ICMPV6 ");
break;
default:
- printf("%u ", s->proto);
+ printf("%u ", sk->proto);
break;
}
- pf_print_host(&s->lan.addr, s->lan.port, s->af);
+ pf_print_host(&sk->lan.addr, sk->lan.port, sk->af);
printf(" ");
- pf_print_host(&s->gwy.addr, s->gwy.port, s->af);
+ pf_print_host(&sk->gwy.addr, sk->gwy.port, sk->af);
printf(" ");
- pf_print_host(&s->ext.addr, s->ext.port, s->af);
+ pf_print_host(&sk->ext.addr, sk->ext.port, sk->af);
printf(" [lo=%u high=%u win=%u modulator=%u", s->src.seqlo,
s->src.seqhi, s->src.max_win, s->src.seqdiff);
if (s->src.wscale && s->dst.wscale)
@@ -1565,7 +1570,6 @@ pf_send_tcp(const struct pf_rule *r, sa_
#endif /* INET6 */
struct tcphdr *th;
char *opt;
- struct pf_mtag *pf_mtag;
/* maximum segment size tcp option */
tlen = sizeof(struct tcphdr);
@@ -1589,24 +1593,18 @@ pf_send_tcp(const struct pf_rule *r, sa_
m = m_gethdr(M_DONTWAIT, MT_HEADER);
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-vendor
mailing list