summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Thomas McBride <mcbride@cvs.openbsd.org>2007-05-31 04:11:43 +0000
committerRyan Thomas McBride <mcbride@cvs.openbsd.org>2007-05-31 04:11:43 +0000
commit8ed7c1731b5bd668dfc182b9ac3e5723d45f030b (patch)
tree167c59edf4ee1a321a20d6b6750c1c691eabfec0
parent457178550d6d623e3bdb779fb56c93ec291aa971 (diff)
First step of rearranging pf's state table internals...
- Split pf_state into pf_state (used for tracking connection information), and pf_state_key (used for searching the state table) - Use pfsync_state in the ioctl for userland access to the state table. This will sheild userland somewhat from future changes. ok henning@ toby@ pyr@
-rw-r--r--sys/net/if_pfsync.c97
-rw-r--r--sys/net/if_pfsync.h61
-rw-r--r--sys/net/pf.c598
-rw-r--r--sys/net/pf_ioctl.c264
-rw-r--r--sys/net/pfvar.h162
5 files changed, 709 insertions, 473 deletions
diff --git a/sys/net/if_pfsync.c b/sys/net/if_pfsync.c
index a106049d24e..b16b5ed8bd6 100644
--- a/sys/net/if_pfsync.c
+++ b/sys/net/if_pfsync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pfsync.c,v 1.74 2007/05/26 17:13:31 jason Exp $ */
+/* $OpenBSD: if_pfsync.c,v 1.75 2007/05/31 04:11:42 mcbride Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff
@@ -220,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;
@@ -254,7 +255,16 @@ pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag)
pfi_kif_unref(kif, PFI_KIF_REF_NONE);
return (ENOMEM);
}
+ sk = pool_get(&pf_state_key_pl, PR_NOWAIT);
+ if (sk == NULL) {
+ pool_put(&pf_state_pl, st);
+ pfi_kif_unref(kif, PFI_KIF_REF_NONE);
+ return (ENOMEM);
+ }
bzero(st, sizeof(*st));
+ bzero(sk, sizeof(*sk));
+ sk->state = st;
+ st->state_key = sk;
/* allocate memory for scrub info */
if (pfsync_alloc_scrub_memory(&sp->src, &st->src) ||
@@ -263,6 +273,7 @@ pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag)
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);
}
@@ -273,9 +284,9 @@ pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag)
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);
@@ -284,15 +295,15 @@ pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag)
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;
- bcopy(sp->id, &st->id, sizeof(st->id));
- st->creatorid = sp->creatorid;
+ bcopy(sp->id, &sk->id, sizeof(sk->id));
+ sk->creatorid = sp->creatorid;
st->sync_flags = PFSTATE_FROMSYNC;
if (pf_insert_state(kif, st)) {
@@ -317,7 +328,8 @@ 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_key_cmp key;
struct pfsync_state *sp;
struct pfsync_state_upd *up;
struct pfsync_state_del *dp;
@@ -387,7 +399,7 @@ pfsync_input(struct mbuf *m, ...)
switch (action) {
case PFSYNC_ACT_CLR: {
- struct pf_state *nexts;
+ struct pf_state_key *nexts;
struct pfi_kif *kif;
u_int32_t creatorid;
if ((mp = m_pulldown(m, iplen + sizeof(*ph),
@@ -400,12 +412,12 @@ pfsync_input(struct mbuf *m, ...)
s = splsoftnet();
if (cp->ifname[0] == '\0') {
- for (st = RB_MIN(pf_state_tree_id, &tree_id);
- st; st = nexts) {
- nexts = RB_NEXT(pf_state_tree_id, &tree_id, st);
- if (st->creatorid == creatorid) {
+ for (sk = RB_MIN(pf_state_tree_id, &tree_id);
+ sk; sk = nexts) {
+ nexts = RB_NEXT(pf_state_tree_id, &tree_id, sk);
+ if (sk->creatorid == creatorid) {
st->sync_flags |= PFSTATE_FROMSYNC;
- pf_unlink_state(st);
+ pf_unlink_state(sk->state);
}
}
} else {
@@ -413,13 +425,13 @@ pfsync_input(struct mbuf *m, ...)
splx(s);
return;
}
- for (st = RB_MIN(pf_state_tree_lan_ext,
- &kif->pfik_lan_ext); st; st = nexts) {
+ for (sk = RB_MIN(pf_state_tree_lan_ext,
+ &kif->pfik_lan_ext); sk; sk = nexts) {
nexts = RB_NEXT(pf_state_tree_lan_ext,
- &kif->pfik_lan_ext, st);
- if (st->creatorid == creatorid) {
+ &kif->pfik_lan_ext, sk);
+ if (sk->creatorid == creatorid) {
st->sync_flags |= PFSTATE_FROMSYNC;
- pf_unlink_state(st);
+ pf_unlink_state(sk->state);
}
}
}
@@ -494,8 +506,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
@@ -539,8 +552,8 @@ pfsync_input(struct mbuf *m, ...)
"creatorid: %08x\n",
(sfail < 7 ? "ignoring"
: "partial"), sfail,
- betoh64(st->id),
- ntohl(st->creatorid));
+ betoh64(sk->id),
+ ntohl(sk->creatorid));
pfsyncstats.pfsyncs_badstate++;
if (!(sp->sync_flags & PFSTATE_STALE)) {
@@ -630,8 +643,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
@@ -664,8 +678,8 @@ pfsync_input(struct mbuf *m, ...)
printf("pfsync: ignoring stale update "
"(%d) id: %016llx "
"creatorid: %08x\n", sfail,
- betoh64(st->id),
- ntohl(st->creatorid));
+ betoh64(sk->id),
+ ntohl(sk->creatorid));
pfsyncstats.pfsyncs_badstate++;
/* we have a better state, send it out */
@@ -1079,6 +1093,7 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags)
struct pfsync_state *sp = NULL;
struct pfsync_state_upd *up = NULL;
struct pfsync_state_del *dp = NULL;
+ struct pf_state_key *sk = st->state_key;
struct pf_rule *r;
u_long secs;
int s, ret = 0;
@@ -1134,9 +1149,9 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags)
(void *)((char *)h + PFSYNC_HDRLEN);
for (i = 0; i < h->count; i++) {
- if (!memcmp(usp->id, &st->id,
+ if (!memcmp(usp->id, &sk->id,
PFSYNC_ID_LEN) &&
- usp->creatorid == st->creatorid) {
+ usp->creatorid == sk->creatorid) {
sp = usp;
sp->updates++;
break;
@@ -1160,13 +1175,13 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags)
h->count++;
bzero(sp, sizeof(*sp));
- bcopy(&st->id, sp->id, sizeof(sp->id));
- sp->creatorid = st->creatorid;
+ bcopy(&sk->id, sp->id, sizeof(sp->id));
+ sp->creatorid = sk->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);
+ 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));
@@ -1183,9 +1198,9 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags)
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;
@@ -1240,8 +1255,8 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags)
up = sc->sc_statep_net.u++;
bzero(up, sizeof(*up));
- bcopy(&st->id, up->id, sizeof(up->id));
- up->creatorid = st->creatorid;
+ bcopy(&sk->id, up->id, sizeof(up->id));
+ up->creatorid = sk->creatorid;
}
up->timeout = st->timeout;
up->expire = sp->expire;
@@ -1255,8 +1270,8 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags)
h_net->count++;
bzero(dp, sizeof(*dp));
- bcopy(&st->id, dp->id, sizeof(dp->id));
- dp->creatorid = st->creatorid;
+ bcopy(&sk->id, dp->id, sizeof(dp->id));
+ dp->creatorid = sk->creatorid;
break;
}
}
diff --git a/sys/net/if_pfsync.h b/sys/net/if_pfsync.h
index 5ed465e716a..6e9059660cf 100644
--- a/sys/net/if_pfsync.h
+++ b/sys/net/if_pfsync.h
@@ -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), \
diff --git a/sys/net/pf.c b/sys/net/pf.c
index ab0f998baf5..99d88eeb128 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.534 2007/05/29 00:50:41 henning Exp $ */
+/* $OpenBSD: pf.c,v 1.535 2007/05/31 04:11:42 mcbride Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -113,8 +113,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);
@@ -218,7 +219,7 @@ int pf_check_proto_cksum(struct mbuf *, int, int,
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_key_cmp *, u_int8_t);
int pf_src_connlimit(struct pf_state **);
int pf_check_congestion(struct ifqueue *);
@@ -253,13 +254,13 @@ struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
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,12 +284,12 @@ struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
} while (0)
static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
-static __inline int pf_state_compare_lan_ext(struct pf_state *,
- struct pf_state *);
-static __inline int pf_state_compare_ext_gwy(struct pf_state *,
- struct pf_state *);
-static __inline int pf_state_compare_id(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_key *,
+ struct pf_state_key *);
struct pf_src_tree tree_src_tracking;
@@ -296,11 +297,11 @@ struct pf_state_tree_id tree_id;
struct pf_state_queue state_list;
RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare);
-RB_GENERATE(pf_state_tree_lan_ext, pf_state,
+RB_GENERATE(pf_state_tree_lan_ext, pf_state_key,
u.s.entry_lan_ext, pf_state_compare_lan_ext);
-RB_GENERATE(pf_state_tree_ext_gwy, pf_state,
+RB_GENERATE(pf_state_tree_ext_gwy, pf_state_key,
u.s.entry_ext_gwy, pf_state_compare_ext_gwy);
-RB_GENERATE(pf_state_tree_id, pf_state,
+RB_GENERATE(pf_state_tree_id, pf_state_key,
u.s.entry_id, pf_state_compare_id);
static __inline int
@@ -348,7 +349,7 @@ pf_src_compare(struct pf_src_node *a, struct pf_src_node *b)
}
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 +417,7 @@ pf_state_compare_lan_ext(struct pf_state *a, struct pf_state *b)
}
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;
@@ -484,7 +485,7 @@ pf_state_compare_ext_gwy(struct pf_state *a, struct pf_state *b)
}
static __inline int
-pf_state_compare_id(struct pf_state *a, struct pf_state *b)
+pf_state_compare_id(struct pf_state_key *a, struct pf_state_key *b)
{
if (a->id > b->id)
return (1);
@@ -519,35 +520,39 @@ pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af)
#endif /* INET6 */
struct pf_state *
-pf_find_state_byid(struct pf_state_cmp *key)
+pf_find_state_byid(struct pf_state_key_cmp *key)
{
+ struct pf_state_key *sk;
pf_status.fcounters[FCNT_STATE_SEARCH]++;
- return (RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state *)key));
+
+ sk = RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state_key *)key);
+ return (sk ? sk->state : NULL);
}
struct pf_state *
-pf_find_state_recurse(struct pfi_kif *kif, struct pf_state_cmp *key, u_int8_t tree)
+pf_find_state_recurse(struct pfi_kif *kif, struct pf_state_key_cmp *key,
+ u_int8_t tree)
{
- struct pf_state *s;
+ struct pf_state_key *sk;
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);
+ if ((sk = RB_FIND(pf_state_tree_lan_ext, &kif->pfik_lan_ext,
+ (struct pf_state_key *)key)) != NULL)
+ return (sk->state);
+ if ((sk = RB_FIND(pf_state_tree_lan_ext, &pfi_all->pfik_lan_ext,
+ (struct pf_state_key *)key)) != NULL)
+ return (sk->state);
return (NULL);
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);
+ if ((sk = RB_FIND(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy,
+ (struct pf_state_key *)key)) != NULL)
+ return (sk->state);
+ if ((sk = RB_FIND(pf_state_tree_ext_gwy, &pfi_all->pfik_ext_gwy,
+ (struct pf_state_key *)key)) != NULL)
+ return (sk->state);
return (NULL);
default:
panic("pf_find_state_recurse");
@@ -555,41 +560,45 @@ pf_find_state_recurse(struct pfi_kif *kif, struct pf_state_cmp *key, u_int8_t tr
}
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, *sks = NULL;
+ struct pfi_kif *kif;
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)
+ sk = RB_FIND(pf_state_tree_lan_ext,
+ &kif->pfik_lan_ext, (struct pf_state_key *)key);
+ if (sk == NULL)
continue;
if (more == NULL)
- return (s);
- ss = s;
+ return (sk->state);
+ sks = sk;
(*more)++;
}
- return (ss);
+ 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)
+ sk = RB_FIND(pf_state_tree_ext_gwy,
+ &kif->pfik_ext_gwy, (struct pf_state_key *)key);
+ if (sk == NULL)
continue;
if (more == NULL)
- return (s);
- ss = s;
+ return (sk->state);
+ sks = sk;
(*more)++;
}
- return (ss);
+ break;
default:
panic("pf_find_state_all");
}
+ if (sks != NULL)
+ return (sks->state);
+ else
+ return (NULL);
}
void
@@ -625,7 +634,7 @@ pf_check_threshold(struct pf_threshold *threshold)
int
pf_src_connlimit(struct pf_state **state)
{
- struct pf_state *s;
+ struct pf_state_key *sk;
int bad = 0;
(*state)->src_node->conn++;
@@ -656,12 +665,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;
@@ -683,24 +692,28 @@ pf_src_connlimit(struct pf_state **state)
if ((*state)->rule.ptr->flush) {
pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
- RB_FOREACH(s, pf_state_tree_id, &tree_id) {
+ RB_FOREACH(sk, pf_state_tree_id, &tree_id) {
/*
* 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 ==
+ sk->state->rule.ptr)) {
+ sk->state->timeout = PFTM_PURGE;
+ sk->state->src.state =
+ sk->state->dst.state =
TCPS_CLOSED;
killed++;
}
@@ -783,72 +796,75 @@ pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
}
int
-pf_insert_state(struct pfi_kif *kif, struct pf_state *state)
+pf_insert_state(struct pfi_kif *kif, struct pf_state *s)
{
+ KASSERT(s->state_key != NULL);
+
/* 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)) {
+ struct pf_state_key *sk = s->state_key;
+ s->u.s.kif = kif;
+ if (RB_INSERT(pf_state_tree_lan_ext, &kif->pfik_lan_ext, sk)) {
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);
+ pf_print_host(&sk->lan.addr, sk->lan.port,
+ sk->af);
printf(" gwy: ");
- pf_print_host(&state->gwy.addr, state->gwy.port,
- state->af);
+ pf_print_host(&sk->gwy.addr, sk->gwy.port,
+ sk->af);
printf(" ext: ");
- pf_print_host(&state->ext.addr, state->ext.port,
- state->af);
- if (state->sync_flags & PFSTATE_FROMSYNC)
+ pf_print_host(&sk->ext.addr, sk->ext.port,
+ sk->af);
+ if (s->sync_flags & PFSTATE_FROMSYNC)
printf(" (from sync)");
printf("\n");
}
return (-1);
}
- if (RB_INSERT(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state)) {
+ if (RB_INSERT(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, sk)) {
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);
+ pf_print_host(&sk->lan.addr, sk->lan.port,
+ sk->af);
printf(" gwy: ");
- pf_print_host(&state->gwy.addr, state->gwy.port,
- state->af);
+ pf_print_host(&sk->gwy.addr, sk->gwy.port,
+ sk->af);
printf(" ext: ");
- pf_print_host(&state->ext.addr, state->ext.port,
- state->af);
- if (state->sync_flags & PFSTATE_FROMSYNC)
+ pf_print_host(&sk->ext.addr, sk->ext.port,
+ sk->af);
+ 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_lan_ext, &kif->pfik_lan_ext, sk);
return (-1);
}
- if (state->id == 0 && state->creatorid == 0) {
- state->id = htobe64(pf_status.stateid++);
- state->creatorid = pf_status.hostid;
+ if (sk->id == 0 && sk->creatorid == 0) {
+ sk->id = htobe64(pf_status.stateid++);
+ sk->creatorid = pf_status.hostid;
}
- if (RB_INSERT(pf_state_tree_id, &tree_id, state) != NULL) {
+ if (RB_INSERT(pf_state_tree_id, &tree_id, sk) != 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(sk->id), ntohl(sk->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);
+ RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, sk);
+ RB_REMOVE(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, sk);
return (-1);
}
- TAILQ_INSERT_TAIL(&state_list, state, u.s.entry_list);
+ TAILQ_INSERT_TAIL(&state_list, s, u.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 +970,7 @@ pf_src_tree_remove_state(struct pf_state *s)
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,19 +999,19 @@ 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);
+ &cur->u.s.kif->pfik_ext_gwy, cur->state_key);
RB_REMOVE(pf_state_tree_lan_ext,
- &cur->u.s.kif->pfik_lan_ext, cur);
- RB_REMOVE(pf_state_tree_id, &tree_id, cur);
+ &cur->u.s.kif->pfik_lan_ext, cur->state_key);
+ RB_REMOVE(pf_state_tree_id, &tree_id, cur->state_key);
#if NPFSYNC
- if (cur->creatorid == pf_status.hostid)
+ if (cur->state_key->creatorid == pf_status.hostid)
pfsync_delete_state(cur);
#endif
cur->timeout = PFTM_UNLINKED;
@@ -1029,6 +1045,7 @@ pf_free_state(struct pf_state *cur)
TAILQ_REMOVE(&state_list, cur, u.s.entry_list);
if (cur->tag)
pf_tag_unref(cur->tag);
+ pool_put(&pf_state_key_pl, cur->state_key);
pool_put(&pf_state_pl, cur);
pf_status.fcounters[FCNT_STATE_REMOVALS]++;
pf_status.states--;
@@ -1175,7 +1192,8 @@ pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af)
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 +1207,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)
@@ -2235,7 +2253,7 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high,
struct pf_src_node **sn)
{
- struct pf_state_cmp key;
+ struct pf_state_key_cmp key;
struct pf_addr init_addr;
u_int16_t cut;
@@ -2765,7 +2783,7 @@ pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr)
s->rt_kif = NULL;
if (!r->rt || r->rt == PF_FASTROUTE)
return;
- switch (s->af) {
+ switch (s->state_key->af) {
#ifdef INET
case AF_INET:
pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL,
@@ -2976,6 +2994,7 @@ pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
/* create new state */
u_int16_t len;
struct pf_state *s = NULL;
+ struct pf_state_key *sk = NULL;
struct pf_src_node *sn = NULL;
len = pd->tot_len - off - (th->th_off << 2);
@@ -3001,6 +3020,12 @@ pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
REASON_SET(&reason, PFRES_SRCLIMIT);
goto cleanup;
}
+ /* state key */
+ sk = pool_get(&pf_state_key_pl, PR_NOWAIT);
+ if (sk == NULL) {
+ REASON_SET(&reason, PFRES_MEMORY);
+ goto cleanup;
+ }
s = pool_get(&pf_state_pl, PR_NOWAIT);
if (s == NULL) {
REASON_SET(&reason, PFRES_MEMORY);
@@ -3018,9 +3043,15 @@ cleanup:
pf_status.src_nodes--;
pool_put(&pf_src_tree_pl, nsn);
}
+ if (sk != NULL) {
+ pool_put(&pf_state_key_pl, sk);
+ }
return (PF_DROP);
}
bzero(s, sizeof(*s));
+ bzero(sk, sizeof(*sk));
+ sk->state = s;
+ s->state_key = sk;
s->rule.ptr = r;
s->nat_rule.ptr = nr;
s->anchor.ptr = a;
@@ -3029,32 +3060,32 @@ cleanup:
s->log = r->log & PF_LOG_ALL;
if (nr != NULL)
s->log |= nr->log & PF_LOG_ALL;
- s->proto = IPPROTO_TCP;
- s->direction = direction;
- s->af = af;
+ sk->proto = IPPROTO_TCP;
+ sk->direction = direction;
+ sk->af = af;
if (direction == PF_OUT) {
- PF_ACPY(&s->gwy.addr, saddr, af);
- s->gwy.port = th->th_sport; /* sport */
- PF_ACPY(&s->ext.addr, daddr, af);
- s->ext.port = th->th_dport;
+ PF_ACPY(&sk->gwy.addr, saddr, af);
+ sk->gwy.port = th->th_sport; /* sport */
+ PF_ACPY(&sk->ext.addr, daddr, af);
+ sk->ext.port = th->th_dport;
if (nr != NULL) {
- PF_ACPY(&s->lan.addr, &pd->baddr, af);
- s->lan.port = bport;
+ PF_ACPY(&sk->lan.addr, &pd->baddr, af);
+ sk->lan.port = bport;
} else {
- PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
- s->lan.port = s->gwy.port;
+ PF_ACPY(&sk->lan.addr, &sk->gwy.addr, af);
+ sk->lan.port = sk->gwy.port;
}
} else {
- PF_ACPY(&s->lan.addr, daddr, af);
- s->lan.port = th->th_dport;
- PF_ACPY(&s->ext.addr, saddr, af);
- s->ext.port = th->th_sport;
+ PF_ACPY(&sk->lan.addr, daddr, af);
+ sk->lan.port = th->th_dport;
+ PF_ACPY(&sk->ext.addr, saddr, af);
+ sk->ext.port = th->th_sport;
if (nr != NULL) {
- PF_ACPY(&s->gwy.addr, &pd->baddr, af);
- s->gwy.port = bport;
+ PF_ACPY(&sk->gwy.addr, &pd->baddr, af);
+ sk->gwy.port = bport;
} else {
- PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
- s->gwy.port = s->lan.port;
+ PF_ACPY(&sk->gwy.addr, &sk->lan.addr, af);
+ sk->gwy.port = sk->lan.port;
}
}
@@ -3337,6 +3368,7 @@ pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction,
if (r->keep_state || nr != NULL) {
/* create new state */
struct pf_state *s = NULL;
+ struct pf_state_key *sk = NULL;
struct pf_src_node *sn = NULL;
/* check maximums */
@@ -3360,6 +3392,12 @@ pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction,
REASON_SET(&reason, PFRES_SRCLIMIT);
goto cleanup;
}
+ /* state key */
+ sk = pool_get(&pf_state_key_pl, PR_NOWAIT);
+ if (sk == NULL) {
+ REASON_SET(&reason, PFRES_MEMORY);
+ goto cleanup;
+ }
s = pool_get(&pf_state_pl, PR_NOWAIT);
if (s == NULL) {
REASON_SET(&reason, PFRES_MEMORY);
@@ -3377,9 +3415,15 @@ cleanup:
pf_status.src_nodes--;
pool_put(&pf_src_tree_pl, nsn);
}
+ if (sk != NULL) {
+ pool_put(&pf_state_key_pl, sk);
+ }
return (PF_DROP);
}
bzero(s, sizeof(*s));
+ bzero(sk, sizeof(*sk));
+ sk->state = s;
+ s->state_key = sk;
s->rule.ptr = r;
s->nat_rule.ptr = nr;
s->anchor.ptr = a;
@@ -3388,32 +3432,32 @@ cleanup:
s->log = r->log & PF_LOG_ALL;
if (nr != NULL)
s->log |= nr->log & PF_LOG_ALL;
- s->proto = IPPROTO_UDP;
- s->direction = direction;
- s->af = af;
+ sk->proto = IPPROTO_UDP;
+ sk->direction = direction;
+ sk->af = af;
if (direction == PF_OUT) {
- PF_ACPY(&s->gwy.addr, saddr, af);
- s->gwy.port = uh->uh_sport;
- PF_ACPY(&s->ext.addr, daddr, af);
- s->ext.port = uh->uh_dport;
+ PF_ACPY(&sk->gwy.addr, saddr, af);
+ sk->gwy.port = uh->uh_sport;
+ PF_ACPY(&sk->ext.addr, daddr, af);
+ sk->ext.port = uh->uh_dport;
if (nr != NULL) {
- PF_ACPY(&s->lan.addr, &pd->baddr, af);
- s->lan.port = bport;
+ PF_ACPY(&sk->lan.addr, &pd->baddr, af);
+ sk->lan.port = bport;
} else {
- PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
- s->lan.port = s->gwy.port;
+ PF_ACPY(&sk->lan.addr, &sk->gwy.addr, af);
+ sk->lan.port = sk->gwy.port;
}
} else {
- PF_ACPY(&s->lan.addr, daddr, af);
- s->lan.port = uh->uh_dport;
- PF_ACPY(&s->ext.addr, saddr, af);
- s->ext.port = uh->uh_sport;
+ PF_ACPY(&sk->lan.addr, daddr, af);
+ sk->lan.port = uh->uh_dport;
+ PF_ACPY(&sk->ext.addr, saddr, af);
+ sk->ext.port = uh->uh_sport;
if (nr != NULL) {
- PF_ACPY(&s->gwy.addr, &pd->baddr, af);
- s->gwy.port = bport;
+ PF_ACPY(&sk->gwy.addr, &pd->baddr, af);
+ sk->gwy.port = bport;
} else {
- PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
- s->gwy.port = s->lan.port;
+ PF_ACPY(&sk->gwy.addr, &sk->lan.addr, af);
+ sk->gwy.port = sk->lan.port;
}
}
s->src.state = PFUDPS_SINGLE;
@@ -3648,6 +3692,7 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
if (!state_icmp && (r->keep_state || nr != NULL)) {
/* create new state */
struct pf_state *s = NULL;
+ struct pf_state_key *sk = NULL;
struct pf_src_node *sn = NULL;
/* check maximums */
@@ -3671,6 +3716,12 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
REASON_SET(&reason, PFRES_SRCLIMIT);
goto cleanup;
}
+ /* state key */
+ sk = pool_get(&pf_state_key_pl, PR_NOWAIT);
+ if (sk == NULL) {
+ REASON_SET(&reason, PFRES_MEMORY);
+ goto cleanup;
+ }
s = pool_get(&pf_state_pl, PR_NOWAIT);
if (s == NULL) {
REASON_SET(&reason, PFRES_MEMORY);
@@ -3688,9 +3739,15 @@ cleanup:
pf_status.src_nodes--;
pool_put(&pf_src_tree_pl, nsn);
}
+ if (sk != NULL) {
+ pool_put(&pf_state_key_pl, sk);
+ }
return (PF_DROP);
}
bzero(s, sizeof(*s));
+ bzero(sk, sizeof(*sk));
+ sk->state = s;
+ s->state_key = sk;
s->rule.ptr = r;
s->nat_rule.ptr = nr;
s->anchor.ptr = a;
@@ -3699,32 +3756,32 @@ cleanup:
s->log = r->log & PF_LOG_ALL;
if (nr != NULL)
s->log |= nr->log & PF_LOG_ALL;
- s->proto = pd->proto;
- s->direction = direction;
- s->af = af;
+ sk->proto = pd->proto;
+ sk->direction = direction;
+ sk->af = af;
if (direction == PF_OUT) {
- PF_ACPY(&s->gwy.addr, saddr, af);
- s->gwy.port = nport;
- PF_ACPY(&s->ext.addr, daddr, af);
- s->ext.port = 0;
+ PF_ACPY(&sk->gwy.addr, saddr, af);
+ sk->gwy.port = nport;
+ PF_ACPY(&sk->ext.addr, daddr, af);
+ sk->ext.port = 0;
if (nr != NULL) {
- PF_ACPY(&s->lan.addr, &pd->baddr, af);
- s->lan.port = bport;
+ PF_ACPY(&sk->lan.addr, &pd->baddr, af);
+ sk->lan.port = bport;
} else {
- PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
- s->lan.port = s->gwy.port;
+ PF_ACPY(&sk->lan.addr, &sk->gwy.addr, af);
+ sk->lan.port = sk->gwy.port;
}
} else {
- PF_ACPY(&s->lan.addr, daddr, af);
- s->lan.port = nport;
- PF_ACPY(&s->ext.addr, saddr, af);
- s->ext.port = 0;
+ PF_ACPY(&sk->lan.addr, daddr, af);
+ sk->lan.port = nport;
+ PF_ACPY(&sk->ext.addr, saddr, af);
+ sk->ext.port = 0;
if (nr != NULL) {
- PF_ACPY(&s->gwy.addr, &pd->baddr, af);
- s->gwy.port = bport;
+ PF_ACPY(&sk->gwy.addr, &pd->baddr, af);
+ sk->gwy.port = bport;
} else {
- PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
- s->gwy.port = s->lan.port;
+ PF_ACPY(&sk->gwy.addr, &sk->lan.addr, af);
+ sk->gwy.port = sk->lan.port;
}
}
s->creation = time_second;
@@ -3935,6 +3992,7 @@ pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction,
if (r->keep_state || nr != NULL) {
/* create new state */
struct pf_state *s = NULL;
+ struct pf_state_key *sk = NULL;
struct pf_src_node *sn = NULL;
/* check maximums */
@@ -3958,6 +4016,12 @@ pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction,
REASON_SET(&reason, PFRES_SRCLIMIT);
goto cleanup;
}
+ /* state key */
+ sk = pool_get(&pf_state_key_pl, PR_NOWAIT);
+ if (sk == NULL) {
+ REASON_SET(&reason, PFRES_MEMORY);
+ goto cleanup;
+ }
s = pool_get(&pf_state_pl, PR_NOWAIT);
if (s == NULL) {
REASON_SET(&reason, PFRES_MEMORY);
@@ -3975,9 +4039,15 @@ cleanup:
pf_status.src_nodes--;
pool_put(&pf_src_tree_pl, nsn);
}
+ if (sk != NULL) {
+ pool_put(&pf_state_key_pl, sk);
+ }
return (PF_DROP);
}
bzero(s, sizeof(*s));
+ bzero(sk, sizeof(*sk));
+ sk->state = s;
+ s->state_key = sk;
s->rule.ptr = r;
s->nat_rule.ptr = nr;
s->anchor.ptr = a;
@@ -3986,23 +4056,23 @@ cleanup:
s->log = r->log & PF_LOG_ALL;
if (nr != NULL)
s->log |= nr->log & PF_LOG_ALL;
- s->proto = pd->proto;
- s->direction = direction;
- s->af = af;
+ sk->proto = pd->proto;
+ sk->direction = direction;
+ sk->af = af;
if (direction == PF_OUT) {
- PF_ACPY(&s->gwy.addr, saddr, af);
- PF_ACPY(&s->ext.addr, daddr, af);
+ PF_ACPY(&sk->gwy.addr, saddr, af);
+ PF_ACPY(&sk->ext.addr, daddr, af);
if (nr != NULL)
- PF_ACPY(&s->lan.addr, &pd->baddr, af);
+ PF_ACPY(&sk->lan.addr, &pd->baddr, af);
else
- PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
+ PF_ACPY(&sk->lan.addr, &sk->gwy.addr, af);
} else {
- PF_ACPY(&s->lan.addr, daddr, af);
- PF_ACPY(&s->ext.addr, saddr, af);
+ PF_ACPY(&sk->lan.addr, daddr, af);
+ PF_ACPY(&sk->ext.addr, saddr, af);
if (nr != NULL)
- PF_ACPY(&s->gwy.addr, &pd->baddr, af);
+ PF_ACPY(&sk->gwy.addr, &pd->baddr, af);
else
- PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
+ PF_ACPY(&sk->gwy.addr, &sk->lan.addr, af);
}
s->src.state = PFOTHERS_SINGLE;
s->dst.state = PFOTHERS_NO_TRAFFIC;
@@ -4119,7 +4189,7 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
u_short *reason)
{
- struct pf_state_cmp key;
+ struct pf_state_key_cmp key;
struct tcphdr *th = pd->hdr.tcp;
u_int16_t win = ntohs(th->th_win);
u_int32_t ack, end, seq, orig_seq;
@@ -4144,7 +4214,7 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
STATE_LOOKUP();
- if (direction == (*state)->direction) {
+ if (direction == (*state)->state_key->direction) {
src = &(*state)->src;
dst = &(*state)->dst;
} else {
@@ -4153,7 +4223,7 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
}
if ((*state)->src.state == PF_TCPS_PROXY_SRC) {
- if (direction != (*state)->direction) {
+ if (direction != (*state)->state_key->direction) {
REASON_SET(reason, PFRES_SYNPROXY);
return (PF_SYNPROXY_DROP);
}
@@ -4185,13 +4255,13 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
struct pf_state_host *src, *dst;
if (direction == PF_OUT) {
- src = &(*state)->gwy;
- dst = &(*state)->ext;
+ src = &(*state)->state_key->gwy;
+ dst = &(*state)->state_key->ext;
} else {
- src = &(*state)->ext;
- dst = &(*state)->lan;
+ src = &(*state)->state_key->ext;
+ dst = &(*state)->state_key->lan;
}
- if (direction == (*state)->direction) {
+ if (direction == (*state)->state_key->direction) {
if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) ||
(ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
(ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
@@ -4537,7 +4607,8 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
seq, orig_seq, ack, pd->p_len, ackskew,
(*state)->packets[0], (*state)->packets[1],
direction == PF_IN ? "in" : "out",
- direction == (*state)->direction ? "fwd" : "rev");
+ direction == (*state)->state_key->direction ?
+ "fwd" : "rev");
printf("pf: State failure on: %c %c %c %c | %c %c\n",
SEQ_GEQ(src->seqhi, end) ? ' ' : '1',
SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ?
@@ -4554,15 +4625,15 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
/* Any packets which have gotten here are to be passed */
/* translate source/destination address, if necessary */
- if (STATE_TRANSLATE(*state)) {
+ if (STATE_TRANSLATE((*state)->state_key)) {
if (direction == PF_OUT)
pf_change_ap(pd->src, &th->th_sport, pd->ip_sum,
- &th->th_sum, &(*state)->gwy.addr,
- (*state)->gwy.port, 0, pd->af);
+ &th->th_sum, &(*state)->state_key->gwy.addr,
+ (*state)->state_key->gwy.port, 0, pd->af);
else
pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum,
- &th->th_sum, &(*state)->lan.addr,
- (*state)->lan.port, 0, pd->af);
+ &th->th_sum, &(*state)->state_key->lan.addr,
+ (*state)->state_key->lan.port, 0, pd->af);
m_copyback(m, off, sizeof(*th), th);
} else if (copyback) {
/* Copyback sequence modulation or stateful scrub changes */
@@ -4577,7 +4648,7 @@ pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif,
struct mbuf *m, int off, void *h, struct pf_pdesc *pd)
{
struct pf_state_peer *src, *dst;
- struct pf_state_cmp key;
+ struct pf_state_key_cmp key;
struct udphdr *uh = pd->hdr.udp;
key.af = pd->af;
@@ -4596,7 +4667,7 @@ pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif,
STATE_LOOKUP();
- if (direction == (*state)->direction) {
+ if (direction == (*state)->state_key->direction) {
src = &(*state)->src;
dst = &(*state)->dst;
} else {
@@ -4618,15 +4689,15 @@ pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif,
(*state)->timeout = PFTM_UDP_SINGLE;
/* translate source/destination address, if necessary */
- if (STATE_TRANSLATE(*state)) {
+ if (STATE_TRANSLATE((*state)->state_key)) {
if (direction == PF_OUT)
pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum,
- &uh->uh_sum, &(*state)->gwy.addr,
- (*state)->gwy.port, 1, pd->af);
+ &uh->uh_sum, &(*state)->state_key->gwy.addr,
+ (*state)->state_key->gwy.port, 1, pd->af);
else
pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum,
- &uh->uh_sum, &(*state)->lan.addr,
- (*state)->lan.port, 1, pd->af);
+ &uh->uh_sum, &(*state)->state_key->lan.addr,
+ (*state)->state_key->lan.port, 1, pd->af);
m_copyback(m, off, sizeof(*uh), uh);
}
@@ -4641,7 +4712,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
u_int16_t icmpid, *icmpsum;
u_int8_t icmptype;
int state_icmp = 0;
- struct pf_state_cmp key;
+ struct pf_state_key_cmp key;
switch (pd->proto) {
#ifdef INET
@@ -4699,20 +4770,20 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
(*state)->timeout = PFTM_ICMP_ERROR_REPLY;
/* translate source/destination address, if necessary */
- if (STATE_TRANSLATE(*state)) {
+ if (STATE_TRANSLATE((*state)->state_key)) {
if (direction == PF_OUT) {
switch (pd->af) {
#ifdef INET
case AF_INET:
pf_change_a(&saddr->v4.s_addr,
pd->ip_sum,
- (*state)->gwy.addr.v4.s_addr, 0);
+ (*state)->state_key->gwy.addr.v4.s_addr, 0);
pd->hdr.icmp->icmp_cksum =
pf_cksum_fixup(
pd->hdr.icmp->icmp_cksum, icmpid,
- (*state)->gwy.port, 0);
+ (*state)->state_key->gwy.port, 0);
pd->hdr.icmp->icmp_id =
- (*state)->gwy.port;
+ (*state)->state_key->gwy.port;
m_copyback(m, off, ICMP_MINLEN,
pd->hdr.icmp);
break;
@@ -4721,7 +4792,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
case AF_INET6:
pf_change_a6(saddr,
&pd->hdr.icmp6->icmp6_cksum,
- &(*state)->gwy.addr, 0);
+ &(*state)->state_key->gwy.addr, 0);
m_copyback(m, off,
sizeof(struct icmp6_hdr),
pd->hdr.icmp6);
@@ -4734,13 +4805,13 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
case AF_INET:
pf_change_a(&daddr->v4.s_addr,
pd->ip_sum,
- (*state)->lan.addr.v4.s_addr, 0);
+ (*state)->state_key->lan.addr.v4.s_addr, 0);
pd->hdr.icmp->icmp_cksum =
pf_cksum_fixup(
pd->hdr.icmp->icmp_cksum, icmpid,
- (*state)->lan.port, 0);
+ (*state)->state_key->lan.port, 0);
pd->hdr.icmp->icmp_id =
- (*state)->lan.port;
+ (*state)->state_key->lan.port;
m_copyback(m, off, ICMP_MINLEN,
pd->hdr.icmp);
break;
@@ -4749,7 +4820,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
case AF_INET6:
pf_change_a6(daddr,
&pd->hdr.icmp6->icmp6_cksum,
- &(*state)->lan.addr, 0);
+ &(*state)->state_key->lan.addr, 0);
m_copyback(m, off,
sizeof(struct icmp6_hdr),
pd->hdr.icmp6);
@@ -4903,7 +4974,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
STATE_LOOKUP();
- if (direction == (*state)->direction) {
+ if (direction == (*state)->state_key->direction) {
src = &(*state)->dst;
dst = &(*state)->src;
} else {
@@ -4941,17 +5012,17 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
return (PF_DROP);
}
- if (STATE_TRANSLATE(*state)) {
+ if (STATE_TRANSLATE((*state)->state_key)) {
if (direction == PF_IN) {
pf_change_icmp(pd2.src, &th.th_sport,
- daddr, &(*state)->lan.addr,
- (*state)->lan.port, NULL,
+ daddr, &(*state)->state_key->lan.addr,
+ (*state)->state_key->lan.port, NULL,
pd2.ip_sum, icmpsum,
pd->ip_sum, 0, pd2.af);
} else {
pf_change_icmp(pd2.dst, &th.th_dport,
- saddr, &(*state)->gwy.addr,
- (*state)->gwy.port, NULL,
+ saddr, &(*state)->state_key->gwy.addr,
+ (*state)->state_key->gwy.port, NULL,
pd2.ip_sum, icmpsum,
pd->ip_sum, 0, pd2.af);
}
@@ -5011,17 +5082,20 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
STATE_LOOKUP();
- if (STATE_TRANSLATE(*state)) {
+ if (STATE_TRANSLATE((*state)->state_key)) {
if (direction == PF_IN) {
pf_change_icmp(pd2.src, &uh.uh_sport,
- daddr, &(*state)->lan.addr,
- (*state)->lan.port, &uh.uh_sum,
+ daddr,
+ &(*state)->state_key->lan.addr,
+ (*state)->state_key->lan.port,
+ &uh.uh_sum,
pd2.ip_sum, icmpsum,
pd->ip_sum, 1, pd2.af);
} else {
pf_change_icmp(pd2.dst, &uh.uh_dport,
- saddr, &(*state)->gwy.addr,
- (*state)->gwy.port, &uh.uh_sum,
+ saddr,
+ &(*state)->state_key->gwy.addr,
+ (*state)->state_key->gwy.port, &uh.uh_sum,
pd2.ip_sum, icmpsum,
pd->ip_sum, 1, pd2.af);
}
@@ -5077,17 +5151,19 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
STATE_LOOKUP();
- if (STATE_TRANSLATE(*state)) {
+ if (STATE_TRANSLATE((*state)->state_key)) {
if (direction == PF_IN) {
pf_change_icmp(pd2.src, &iih.icmp_id,
- daddr, &(*state)->lan.addr,
- (*state)->lan.port, NULL,
+ daddr,
+ &(*state)->state_key->lan.addr,
+ (*state)->state_key->lan.port, NULL,
pd2.ip_sum, icmpsum,
pd->ip_sum, 0, AF_INET);
} else {
pf_change_icmp(pd2.dst, &iih.icmp_id,
- saddr, &(*state)->gwy.addr,
- (*state)->gwy.port, NULL,
+ saddr,
+ &(*state)->state_key->gwy.addr,
+ (*state)->state_key->gwy.port, NULL,
pd2.ip_sum, icmpsum,
pd->ip_sum, 0, AF_INET);
}
@@ -5128,17 +5204,18 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
STATE_LOOKUP();
- if (STATE_TRANSLATE(*state)) {
+ if (STATE_TRANSLATE((*state)->state_key)) {
if (direction == PF_IN) {
pf_change_icmp(pd2.src, &iih.icmp6_id,
- daddr, &(*state)->lan.addr,
- (*state)->lan.port, NULL,
+ daddr,
+ &(*state)->state_key->lan.addr,
+ (*state)->state_key->lan.port, NULL,
pd2.ip_sum, icmpsum,
pd->ip_sum, 0, AF_INET6);
} else {
pf_change_icmp(pd2.dst, &iih.icmp6_id,
- saddr, &(*state)->gwy.addr,
- (*state)->gwy.port, NULL,
+ saddr, &(*state)->state_key->gwy.addr,
+ (*state)->state_key->gwy.port, NULL,
pd2.ip_sum, icmpsum,
pd->ip_sum, 0, AF_INET6);
}
@@ -5170,16 +5247,18 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
STATE_LOOKUP();
- if (STATE_TRANSLATE(*state)) {
+ if (STATE_TRANSLATE((*state)->state_key)) {
if (direction == PF_IN) {
pf_change_icmp(pd2.src, NULL,
- daddr, &(*state)->lan.addr,
+ daddr,
+ &(*state)->state_key->lan.addr,
0, NULL,
pd2.ip_sum, icmpsum,
pd->ip_sum, 0, pd2.af);
} else {
pf_change_icmp(pd2.dst, NULL,
- saddr, &(*state)->gwy.addr,
+ saddr,
+ &(*state)->state_key->gwy.addr,
0, NULL,
pd2.ip_sum, icmpsum,
pd->ip_sum, 0, pd2.af);
@@ -5216,7 +5295,7 @@ pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif,
struct pf_pdesc *pd)
{
struct pf_state_peer *src, *dst;
- struct pf_state_cmp key;
+ struct pf_state_key_cmp key;
key.af = pd->af;
key.proto = pd->proto;
@@ -5234,7 +5313,7 @@ pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif,
STATE_LOOKUP();
- if (direction == (*state)->direction) {
+ if (direction == (*state)->state_key->direction) {
src = &(*state)->src;
dst = &(*state)->dst;
} else {
@@ -5256,19 +5335,21 @@ pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif,
(*state)->timeout = PFTM_OTHER_SINGLE;
/* translate source/destination address, if necessary */
- if (STATE_TRANSLATE(*state)) {
+ if (STATE_TRANSLATE((*state)->state_key)) {
if (direction == PF_OUT)
switch (pd->af) {
#ifdef INET
case AF_INET:
pf_change_a(&pd->src->v4.s_addr,
- pd->ip_sum, (*state)->gwy.addr.v4.s_addr,
+ pd->ip_sum,
+ (*state)->state_key->gwy.addr.v4.s_addr,
0);
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
- PF_ACPY(pd->src, &(*state)->gwy.addr, pd->af);
+ PF_ACPY(pd->src,
+ &(*state)->state_key->gwy.addr, pd->af);
break;
#endif /* INET6 */
}
@@ -5277,13 +5358,15 @@ pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif,
#ifdef INET
case AF_INET:
pf_change_a(&pd->dst->v4.s_addr,
- pd->ip_sum, (*state)->lan.addr.v4.s_addr,
+ pd->ip_sum,
+ (*state)->state_key->lan.addr.v4.s_addr,
0);
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
- PF_ACPY(pd->dst, &(*state)->lan.addr, pd->af);
+ PF_ACPY(pd->dst,
+ &(*state)->state_key->lan.addr, pd->af);
break;
#endif /* INET6 */
}
@@ -5880,6 +5963,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
struct ip *h;
struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
struct pf_state *s = NULL;
+ struct pf_state_key *sk = NULL;
struct pf_ruleset *ruleset = NULL;
struct pf_pdesc pd;
int off, dirndx, pqid = 0;
@@ -6110,6 +6194,7 @@ done:
a->bytes[dirndx] += pd.tot_len;
}
if (s != NULL) {
+ sk = s->state_key;
if (s->nat_rule.ptr != NULL) {
s->nat_rule.ptr->packets[dirndx]++;
s->nat_rule.ptr->bytes[dirndx] += pd.tot_len;
@@ -6122,7 +6207,7 @@ done:
s->nat_src_node->packets[dirndx]++;
s->nat_src_node->bytes[dirndx] += pd.tot_len;
}
- dirndx = (dir == s->direction) ? 0 : 1;
+ dirndx = (dir == sk->direction) ? 0 : 1;
s->packets[dirndx]++;
s->bytes[dirndx] += pd.tot_len;
}
@@ -6137,10 +6222,10 @@ done:
*/
if (r == &pf_default_rule) {
tr = nr;
- x = (s == NULL || s->direction == dir) ?
+ x = (sk == NULL || sk->direction == dir) ?
&pd.baddr : &pd.naddr;
} else
- x = (s == NULL || s->direction == dir) ?
+ x = (sk == NULL || sk->direction == dir) ?
&pd.naddr : &pd.baddr;
if (x == &pd.baddr || s == NULL) {
/* we need to change the address */
@@ -6151,13 +6236,14 @@ done:
}
}
if (tr->src.addr.type == PF_ADDR_TABLE)
- pfr_update_stats(tr->src.addr.p.tbl, (s == NULL ||
- s->direction == dir) ? pd.src : pd.dst, pd.af,
+ pfr_update_stats(tr->src.addr.p.tbl, (sk == NULL ||
+ sk->direction == dir) ?
+ pd.src : pd.dst, pd.af,
pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
tr->src.neg);
if (tr->dst.addr.type == PF_ADDR_TABLE)
- pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL ||
- s->direction == dir) ? pd.dst : pd.src, pd.af,
+ pfr_update_stats(tr->dst.addr.p.tbl, (sk == NULL ||
+ sk->direction == dir) ? pd.dst : pd.src, pd.af,
pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
tr->dst.neg);
}
@@ -6186,6 +6272,7 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
struct ip6_hdr *h;
struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
struct pf_state *s = NULL;
+ struct pf_state_key *sk = NULL;
struct pf_ruleset *ruleset = NULL;
struct pf_pdesc pd;
int off, terminal = 0, dirndx, rh_cnt = 0;
@@ -6483,6 +6570,7 @@ done:
a->bytes[dirndx] += pd.tot_len;
}
if (s != NULL) {
+ sk = s->state_key;
if (s->nat_rule.ptr != NULL) {
s->nat_rule.ptr->packets[dirndx]++;
s->nat_rule.ptr->bytes[dirndx] += pd.tot_len;
@@ -6495,7 +6583,7 @@ done:
s->nat_src_node->packets[dirndx]++;
s->nat_src_node->bytes[dirndx] += pd.tot_len;
}
- dirndx = (dir == s->direction) ? 0 : 1;
+ dirndx = (dir == sk->direction) ? 0 : 1;
s->packets[dirndx]++;
s->bytes[dirndx] += pd.tot_len;
}
@@ -6510,10 +6598,10 @@ done:
*/
if (r == &pf_default_rule) {
tr = nr;
- x = (s == NULL || s->direction == dir) ?
+ x = (s == NULL || sk->direction == dir) ?
&pd.baddr : &pd.naddr;
} else {
- x = (s == NULL || s->direction == dir) ?
+ x = (s == NULL || sk->direction == dir) ?
&pd.naddr : &pd.baddr;
}
if (x == &pd.baddr || s == NULL) {
@@ -6524,13 +6612,13 @@ done:
}
}
if (tr->src.addr.type == PF_ADDR_TABLE)
- pfr_update_stats(tr->src.addr.p.tbl, (s == NULL ||
- s->direction == dir) ? pd.src : pd.dst, pd.af,
+ pfr_update_stats(tr->src.addr.p.tbl, (sk == NULL ||
+ sk->direction == dir) ? pd.src : pd.dst, pd.af,
pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
tr->src.neg);
if (tr->dst.addr.type == PF_ADDR_TABLE)
- pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL ||
- s->direction == dir) ? pd.dst : pd.src, pd.af,
+ pfr_update_stats(tr->dst.addr.p.tbl, (sk == NULL ||
+ sk->direction == dir) ? pd.dst : pd.src, pd.af,
pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
tr->dst.neg);
}
diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
index f6a20e71751..2fc576c00d4 100644
--- a/sys/net/pf_ioctl.c
+++ b/sys/net/pf_ioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_ioctl.c,v 1.176 2007/05/29 00:17:32 thib Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.177 2007/05/31 04:11:42 mcbride Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -109,6 +109,10 @@ int pf_setup_pfsync_matching(struct pf_ruleset *);
void pf_hash_rule(MD5_CTX *, struct pf_rule *);
void pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *);
int pf_commit_rules(u_int32_t, int, char *);
+void pf_state_export(struct pfsync_state *,
+ struct pf_state_key *, struct pf_state *);
+void pf_state_import(struct pfsync_state *,
+ struct pf_state_key *, struct pf_state *);
struct pf_rule pf_default_rule;
struct rwlock pf_consistency_lock = RWLOCK_INITIALIZER("pfcnslk");
@@ -143,6 +147,8 @@ pfattach(int num)
"pfsrctrpl", NULL);
pool_init(&pf_state_pl, sizeof(struct pf_state), 0, 0, 0, "pfstatepl",
NULL);
+ pool_init(&pf_state_key_pl, sizeof(struct pf_state_key), 0, 0, 0,
+ "pfstatekeypl", NULL);
pool_init(&pf_altq_pl, sizeof(struct pf_altq), 0, 0, 0, "pfaltqpl",
&pool_allocator_nointr);
pool_init(&pf_pooladdr_pl, sizeof(struct pf_pooladdr), 0, 0, 0,
@@ -837,6 +843,94 @@ pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
return (0);
}
+void
+pf_state_export(struct pfsync_state *sp, struct pf_state_key *sk,
+ struct pf_state *s)
+{
+ int secs = time_second;
+ bzero(sp, sizeof(struct pfsync_state));
+
+ /* copy from state key */
+ memcpy(&sp->id, &sk->id, sizeof(sp->id));
+ sp->creatorid = sk->creatorid;
+ sp->lan.addr = sk->lan.addr;
+ sp->lan.port = sk->lan.port;
+ sp->gwy.addr = sk->gwy.addr;
+ sp->gwy.port = sk->gwy.port;
+ sp->ext.addr = sk->ext.addr;
+ sp->ext.port = sk->ext.port;
+ sp->proto = sk->proto;
+ sp->af = sk->af;
+ sp->direction = sk->direction;
+
+ /* copy from state */
+ strlcpy(sp->ifname, s->u.s.kif->pfik_name, sizeof(sp->ifname));
+ pf_state_peer_to_pfsync(&s->src, &sp->src);
+ pf_state_peer_to_pfsync(&s->dst, &sp->dst);
+
+ sp->rule = s->rule.ptr->nr;
+ sp->nat_rule = (s->nat_rule.ptr == NULL) ? -1 : s->nat_rule.ptr->nr;
+ sp->anchor = (s->anchor.ptr == NULL) ? -1 : s->anchor.ptr->nr;
+
+ pf_state_counter_to_pfsync(s->bytes[0], sp->bytes[0]);
+ pf_state_counter_to_pfsync(s->bytes[1], sp->bytes[1]);
+ pf_state_counter_to_pfsync(s->packets[0], sp->packets[0]);
+ pf_state_counter_to_pfsync(s->packets[1], sp->packets[1]);
+ sp->creation = secs - s->creation;
+ sp->expire = pf_state_expires(s);
+ sp->log = s->log;
+ sp->allow_opts = s->allow_opts;
+ sp->timeout = s->timeout;
+
+ if (s->src_node)
+ sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
+ if (s->nat_src_node)
+ sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
+
+ if (sp->expire > secs)
+ sp->expire -= secs;
+ else
+ sp->expire = 0;
+
+}
+
+void
+pf_state_import(struct pfsync_state *sp, struct pf_state_key *sk,
+ struct pf_state *s)
+{
+ bzero(sk, sizeof(struct pf_state_key));
+ bzero(s, sizeof(struct pf_state));
+ sk->state = s;
+ s->state_key = sk;
+
+ /* copy to state key */
+ memcpy(&sk->id, &sp->id, sizeof(sp->id));
+ sk->creatorid = sp->creatorid;
+ sk->lan.addr = sp->lan.addr;
+ sk->lan.port = sp->lan.port;
+ sk->gwy.addr = sp->gwy.addr;
+ sk->gwy.port = sp->gwy.port;
+ sk->ext.addr = sp->ext.addr;
+ sk->ext.port = sp->ext.port;
+ sk->proto = sp->proto;
+ sk->af = sp->af;
+ sk->direction = sp->direction;
+
+ /* copy to state */
+ strlcpy(sp->ifname, s->u.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);
+
+ s->rule.ptr = &pf_default_rule;
+ s->nat_rule.ptr = NULL;
+ s->anchor.ptr = NULL;
+ s->rt_kif = NULL;
+ s->creation = time_second;
+ s->pfsync_time = 0;
+ s->packets[0] = s->packets[1] = 0;
+ s->bytes[0] = s->bytes[1] = 0;
+}
+
int
pf_setup_pfsync_matching(struct pf_ruleset *rs)
{
@@ -1457,21 +1551,21 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
case DIOCCLRSTATES: {
- struct pf_state *state, *nexts;
+ struct pf_state_key *sk, *nextsk;
struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
int killed = 0;
- for (state = RB_MIN(pf_state_tree_id, &tree_id); state;
- state = nexts) {
- nexts = RB_NEXT(pf_state_tree_id, &tree_id, state);
+ for (sk = RB_MIN(pf_state_tree_id, &tree_id); sk;
+ sk = nextsk) {
+ nextsk = RB_NEXT(pf_state_tree_id, &tree_id, sk);
if (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname,
- state->u.s.kif->pfik_name)) {
+ sk->state->u.s.kif->pfik_name)) {
#if NPFSYNC
/* don't send out individual delete messages */
- state->sync_flags = PFSTATE_NOSYNC;
+ sk->state->sync_flags = PFSTATE_NOSYNC;
#endif
- pf_unlink_state(state);
+ pf_unlink_state(sk->state);
killed++;
}
}
@@ -1483,33 +1577,33 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
case DIOCKILLSTATES: {
- struct pf_state *state, *nexts;
+ struct pf_state_key *sk, *nextsk;
struct pf_state_host *src, *dst;
struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
int killed = 0;
- for (state = RB_MIN(pf_state_tree_id, &tree_id); state;
- state = nexts) {
- nexts = RB_NEXT(pf_state_tree_id, &tree_id, state);
+ for (sk = RB_MIN(pf_state_tree_id, &tree_id); sk;
+ sk = nextsk) {
+ nextsk = RB_NEXT(pf_state_tree_id, &tree_id, sk);
- if (state->direction == PF_OUT) {
- src = &state->lan;
- dst = &state->ext;
+ if (sk->direction == PF_OUT) {
+ src = &sk->lan;
+ dst = &sk->ext;
} else {
- src = &state->ext;
- dst = &state->lan;
+ src = &sk->ext;
+ dst = &sk->lan;
}
- if ((!psk->psk_af || state->af == psk->psk_af)
+ if ((!psk->psk_af || sk->af == psk->psk_af)
&& (!psk->psk_proto || psk->psk_proto ==
- state->proto) &&
+ sk->proto) &&
PF_MATCHA(psk->psk_src.neg,
&psk->psk_src.addr.v.a.addr,
&psk->psk_src.addr.v.a.mask,
- &src->addr, state->af) &&
+ &src->addr, sk->af) &&
PF_MATCHA(psk->psk_dst.neg,
&psk->psk_dst.addr.v.a.addr,
&psk->psk_dst.addr.v.a.mask,
- &dst->addr, state->af) &&
+ &dst->addr, sk->af) &&
(psk->psk_src.port_op == 0 ||
pf_match_port(psk->psk_src.port_op,
psk->psk_src.port[0], psk->psk_src.port[1],
@@ -1519,13 +1613,13 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
psk->psk_dst.port[0], psk->psk_dst.port[1],
dst->port)) &&
(!psk->psk_ifname[0] || !strcmp(psk->psk_ifname,
- state->u.s.kif->pfik_name))) {
+ sk->state->u.s.kif->pfik_name))) {
#if NPFSYNC > 0
/* send immediate delete of state */
- pfsync_delete_state(state);
- state->sync_flags |= PFSTATE_NOSYNC;
+ pfsync_delete_state(sk->state);
+ sk->state->sync_flags |= PFSTATE_NOSYNC;
#endif
- pf_unlink_state(state);
+ pf_unlink_state(sk->state);
killed++;
}
}
@@ -1535,39 +1629,38 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCADDSTATE: {
struct pfioc_state *ps = (struct pfioc_state *)addr;
- struct pf_state *state;
+ struct pfsync_state *sp = (struct pfsync_state *)ps->state;
+ struct pf_state *s;
+ struct pf_state_key *sk;
struct pfi_kif *kif;
- if (ps->state.timeout >= PFTM_MAX &&
- ps->state.timeout != PFTM_UNTIL_PACKET) {
+ if (sp->timeout >= PFTM_MAX &&
+ sp->timeout != PFTM_UNTIL_PACKET) {
error = EINVAL;
break;
}
- state = pool_get(&pf_state_pl, PR_NOWAIT);
- if (state == NULL) {
+ s = pool_get(&pf_state_pl, PR_NOWAIT);
+ if (s == NULL) {
error = ENOMEM;
break;
}
- kif = pfi_kif_get(ps->state.u.ifname);
+ sk = pool_get(&pf_state_key_pl, PR_NOWAIT);
+ if (sk == NULL) {
+ error = ENOMEM;
+ break;
+ }
+ pf_state_import(sp, sk, s);
+ kif = pfi_kif_get(sp->ifname);
if (kif == NULL) {
- pool_put(&pf_state_pl, state);
+ pool_put(&pf_state_pl, s);
+ pool_put(&pf_state_key_pl, sk);
error = ENOENT;
break;
}
- bcopy(&ps->state, state, sizeof(struct pf_state));
- bzero(&state->u, sizeof(state->u));
- state->rule.ptr = &pf_default_rule;
- state->nat_rule.ptr = NULL;
- state->anchor.ptr = NULL;
- state->rt_kif = NULL;
- state->creation = time_second;
- state->pfsync_time = 0;
- state->packets[0] = state->packets[1] = 0;
- state->bytes[0] = state->bytes[1] = 0;
-
- if (pf_insert_state(kif, state)) {
+ if (pf_insert_state(kif, s)) {
pfi_kif_unref(kif, PFI_KIF_REF_NONE);
- pool_put(&pf_state_pl, state);
+ pool_put(&pf_state_pl, s);
+ pool_put(&pf_state_key_pl, sk);
error = ENOMEM;
}
break;
@@ -1575,48 +1668,34 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCGETSTATE: {
struct pfioc_state *ps = (struct pfioc_state *)addr;
- struct pf_state *state;
+ struct pf_state_key *sk;
u_int32_t nr;
- int secs;
nr = 0;
- RB_FOREACH(state, pf_state_tree_id, &tree_id) {
+ RB_FOREACH(sk, pf_state_tree_id, &tree_id) {
if (nr >= ps->nr)
break;
nr++;
}
- if (state == NULL) {
+ if (sk == NULL) {
error = EBUSY;
break;
}
- secs = time_second;
- bcopy(state, &ps->state, sizeof(ps->state));
- strlcpy(ps->state.u.ifname, state->u.s.kif->pfik_name,
- sizeof(ps->state.u.ifname));
- ps->state.rule.nr = state->rule.ptr->nr;
- ps->state.nat_rule.nr = (state->nat_rule.ptr == NULL) ?
- -1 : state->nat_rule.ptr->nr;
- ps->state.anchor.nr = (state->anchor.ptr == NULL) ?
- -1 : state->anchor.ptr->nr;
- ps->state.creation = secs - ps->state.creation;
- ps->state.expire = pf_state_expires(state);
- if (ps->state.expire > secs)
- ps->state.expire -= secs;
- else
- ps->state.expire = 0;
+
+ pf_state_export((struct pfsync_state *)&ps->state,
+ sk, sk->state);
break;
}
case DIOCGETSTATES: {
struct pfioc_states *ps = (struct pfioc_states *)addr;
struct pf_state *state;
- struct pf_state *p, *pstore;
+ struct pfsync_state *p, *pstore;
u_int32_t nr = 0;
- int space = ps->ps_len;
- if (space == 0) {
+ if (ps->ps_len == 0) {
nr = pf_status.states;
- ps->ps_len = sizeof(struct pf_state) * nr;
+ ps->ps_len = sizeof(struct pfsync_state) * nr;
break;
}
@@ -1627,26 +1706,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
state = TAILQ_FIRST(&state_list);
while (state) {
if (state->timeout != PFTM_UNLINKED) {
- int secs = time_second;
-
if ((nr+1) * sizeof(*p) > (unsigned)ps->ps_len)
break;
- bcopy(state, pstore, sizeof(*pstore));
- strlcpy(pstore->u.ifname,
- state->u.s.kif->pfik_name,
- sizeof(pstore->u.ifname));
- pstore->rule.nr = state->rule.ptr->nr;
- pstore->nat_rule.nr = (state->nat_rule.ptr ==
- NULL) ? -1 : state->nat_rule.ptr->nr;
- pstore->anchor.nr = (state->anchor.ptr ==
- NULL) ? -1 : state->anchor.ptr->nr;
- pstore->creation = secs - pstore->creation;
- pstore->expire = pf_state_expires(state);
- if (pstore->expire > secs)
- pstore->expire -= secs;
- else
- pstore->expire = 0;
+ pf_state_export(pstore,
+ state->state_key, state);
error = copyout(pstore, p, sizeof(*p));
if (error) {
free(pstore, M_TEMP);
@@ -1658,7 +1722,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
state = TAILQ_NEXT(state, u.s.entry_list);
}
- ps->ps_len = sizeof(struct pf_state) * nr;
+ ps->ps_len = sizeof(struct pfsync_state) * nr;
free(pstore, M_TEMP);
break;
@@ -1698,8 +1762,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCNATLOOK: {
struct pfioc_natlook *pnl = (struct pfioc_natlook *)addr;
+ struct pf_state_key *sk;
struct pf_state *state;
- struct pf_state_cmp key;
+ struct pf_state_key_cmp key;
int m = 0, direction = pnl->direction;
key.af = pnl->af;
@@ -1735,17 +1800,18 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
if (m > 1)
error = E2BIG; /* more than one state */
else if (state != NULL) {
+ sk = state->state_key;
if (direction == PF_IN) {
- PF_ACPY(&pnl->rsaddr, &state->lan.addr,
- state->af);
- pnl->rsport = state->lan.port;
+ PF_ACPY(&pnl->rsaddr, &sk->lan.addr,
+ sk->af);
+ pnl->rsport = sk->lan.port;
PF_ACPY(&pnl->rdaddr, &pnl->daddr,
pnl->af);
pnl->rdport = pnl->dport;
} else {
- PF_ACPY(&pnl->rdaddr, &state->gwy.addr,
- state->af);
- pnl->rdport = state->gwy.port;
+ PF_ACPY(&pnl->rdaddr, &sk->gwy.addr,
+ sk->af);
+ pnl->rdport = sk->gwy.port;
PF_ACPY(&pnl->rsaddr, &pnl->saddr,
pnl->af);
pnl->rsport = pnl->sport;
@@ -2771,11 +2837,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCCLRSRCNODES: {
struct pf_src_node *n;
- struct pf_state *state;
+ struct pf_state_key *state_key;
- RB_FOREACH(state, pf_state_tree_id, &tree_id) {
- state->src_node = NULL;
- state->nat_src_node = NULL;
+ RB_FOREACH(state_key, pf_state_tree_id, &tree_id) {
+ state_key->state->src_node = NULL;
+ state_key->state->nat_src_node = NULL;
}
RB_FOREACH(n, pf_src_tree, &tree_src_tracking) {
n->expire = 1;
@@ -2789,6 +2855,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCKILLSRCNODES: {
struct pf_src_node *sn;
struct pf_state *s;
+ struct pf_state_key *sk;
struct pfioc_src_node_kill *psnk = \
(struct pfioc_src_node_kill *) addr;
int killed = 0;
@@ -2804,8 +2871,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
&sn->raddr, sn->af)) {
/* Handle state to src_node linkage */
if (sn->states != 0) {
- RB_FOREACH(s, pf_state_tree_id,
+ RB_FOREACH(sk, pf_state_tree_id,
&tree_id) {
+ s = sk->state;
if (s->src_node == sn)
s->src_node = NULL;
if (s->nat_src_node == sn)
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index d55c600f6a6..bc9a6d63a79 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.245 2007/05/28 17:16:39 henning Exp $ */
+/* $OpenBSD: pfvar.h,v 1.246 2007/05/31 04:11:42 mcbride Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -685,8 +685,8 @@ struct pf_state_peer {
TAILQ_HEAD(pf_state_queue, pf_state);
-/* keep synced with struct pf_state, used in RB_FIND */
-struct pf_state_cmp {
+/* keep synced with struct pf_state_key, used in RB_FIND */
+struct pf_state_key_cmp {
u_int64_t id;
u_int32_t creatorid;
struct pf_state_host lan;
@@ -698,7 +698,7 @@ struct pf_state_cmp {
u_int8_t pad;
};
-struct pf_state {
+struct pf_state_key {
u_int64_t id;
u_int32_t creatorid;
struct pf_state_host lan;
@@ -708,6 +708,20 @@ struct pf_state {
u_int8_t proto;
u_int8_t direction;
u_int8_t pad;
+
+ union {
+ struct {
+ RB_ENTRY(pf_state_key) entry_lan_ext;
+ RB_ENTRY(pf_state_key) entry_ext_gwy;
+ RB_ENTRY(pf_state_key) entry_id;
+ } s;
+ } u;
+ struct pf_state *state;
+};
+
+
+struct pf_state {
+ struct pf_state_key *state_key;
u_int8_t log;
u_int8_t allow_opts;
u_int8_t timeout;
@@ -717,9 +731,6 @@ struct pf_state {
#define PFSTATE_STALE 0x04
union {
struct {
- RB_ENTRY(pf_state) entry_lan_ext;
- RB_ENTRY(pf_state) entry_ext_gwy;
- RB_ENTRY(pf_state) entry_id;
TAILQ_ENTRY(pf_state) entry_list;
struct pfi_kif *kif;
} s;
@@ -742,6 +753,114 @@ struct pf_state {
u_int16_t tag;
};
+
+/*
+ * Unified state structures for pulling states out of the kernel
+ * used by pfsync(4) and the pf(4) ioctl.
+ */
+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
+#define PFSYNC_FLAG_SRCNODE 0x04
+#define PFSYNC_FLAG_NATSRCNODE 0x08
+
+/* for copies to/from userland via pf_ioctl() */
+#define pf_state_peer_to_pfsync(s,d) do { \
+ (d)->seqlo = (s)->seqlo; \
+ (d)->seqhi = (s)->seqhi; \
+ (d)->seqdiff = (s)->seqdiff; \
+ (d)->max_win = (s)->max_win; \
+ (d)->mss = (s)->mss; \
+ (d)->state = (s)->state; \
+ (d)->wscale = (s)->wscale; \
+ if ((s)->scrub) { \
+ (d)->scrub.pfss_flags = \
+ (s)->scrub->pfss_flags & PFSS_TIMESTAMP; \
+ (d)->scrub.pfss_ttl = (s)->scrub->pfss_ttl; \
+ (d)->scrub.pfss_ts_mod = (s)->scrub->pfss_ts_mod; \
+ (d)->scrub.scrub_flag = PFSYNC_SCRUB_FLAG_VALID; \
+ } \
+} while (0)
+
+#define pf_state_peer_from_pfsync(s,d) do { \
+ (d)->seqlo = (s)->seqlo; \
+ (d)->seqhi = (s)->seqhi; \
+ (d)->seqdiff = (s)->seqdiff; \
+ (d)->max_win = (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 = (s)->scrub.pfss_ts_mod; \
+ } \
+} while (0)
+
+#define pf_state_counter_to_pfsync(s,d) do { \
+ d[0] = (s>>32)&0xffffffff; \
+ d[1] = s&0xffffffff; \
+} while (0)
+
+#define pf_state_counter_from_pfsync(s) \
+ (((u_int64_t)(s[0])<<32) | (u_int64_t)(s[1]))
+
+
+
TAILQ_HEAD(pf_rulequeue, pf_rule);
struct pf_anchor;
@@ -883,12 +1002,12 @@ struct pfr_ktable {
#define pfrkt_nomatch pfrkt_ts.pfrts_nomatch
#define pfrkt_tzero pfrkt_ts.pfrts_tzero
-RB_HEAD(pf_state_tree_lan_ext, pf_state);
-RB_PROTOTYPE(pf_state_tree_lan_ext, pf_state,
+RB_HEAD(pf_state_tree_lan_ext, pf_state_key);
+RB_PROTOTYPE(pf_state_tree_lan_ext, pf_state_key,
u.s.entry_lan_ext, pf_state_compare_lan_ext);
-RB_HEAD(pf_state_tree_ext_gwy, pf_state);
-RB_PROTOTYPE(pf_state_tree_ext_gwy, pf_state,
+RB_HEAD(pf_state_tree_ext_gwy, pf_state_key);
+RB_PROTOTYPE(pf_state_tree_ext_gwy, pf_state_key,
u.s.entry_ext_gwy, pf_state_compare_ext_gwy);
TAILQ_HEAD(pfi_statehead, pfi_kif);
@@ -1217,8 +1336,8 @@ struct pfioc_natlook {
};
struct pfioc_state {
- u_int32_t nr;
- struct pf_state state;
+ u_int32_t nr;
+ void *state;
};
struct pfioc_src_node_kill {
@@ -1240,8 +1359,8 @@ struct pfioc_state_kill {
struct pfioc_states {
int ps_len;
union {
- caddr_t psu_buf;
- struct pf_state *psu_states;
+ caddr_t psu_buf;
+ struct pfsync_state *psu_states;
} ps_u;
#define ps_buf ps_u.psu_buf
#define ps_states ps_u.psu_states
@@ -1422,8 +1541,8 @@ RB_HEAD(pf_src_tree, pf_src_node);
RB_PROTOTYPE(pf_src_tree, pf_src_node, entry, pf_src_compare);
extern struct pf_src_tree tree_src_tracking;
-RB_HEAD(pf_state_tree_id, pf_state);
-RB_PROTOTYPE(pf_state_tree_id, pf_state,
+RB_HEAD(pf_state_tree_id, pf_state_key);
+RB_PROTOTYPE(pf_state_tree_id, pf_state_key,
entry_id, pf_state_compare_id);
extern struct pf_state_tree_id tree_id;
extern struct pf_state_queue state_list;
@@ -1448,7 +1567,8 @@ extern void pf_tbladdr_remove(struct pf_addr_wrap *);
extern void pf_tbladdr_copyout(struct pf_addr_wrap *);
extern void pf_calc_skip_steps(struct pf_rulequeue *);
extern struct pool pf_src_tree_pl, pf_rule_pl;
-extern struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
+extern struct pool pf_state_pl, pf_state_key_pl, pf_altq_pl,
+ pf_pooladdr_pl;
extern struct pool pf_state_scrub_pl;
extern void pf_purge_thread(void *);
extern void pf_purge_expired_src_nodes(int);
@@ -1461,9 +1581,9 @@ extern int pf_insert_src_node(struct pf_src_node **,
struct pf_rule *, struct pf_addr *,
sa_family_t);
void pf_src_tree_remove_state(struct pf_state *);
-extern struct pf_state *pf_find_state_byid(struct pf_state_cmp *);
-extern struct pf_state *pf_find_state_all(struct pf_state_cmp *key,
- u_int8_t tree, int *more);
+extern struct pf_state *pf_find_state_byid(struct pf_state_key_cmp *);
+extern struct pf_state *pf_find_state_all(struct pf_state_key_cmp *,
+ u_int8_t, int *);
extern void pf_print_state(struct pf_state *);
extern void pf_print_flags(u_int8_t);
extern u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t,