svn commit: r185888 - vendor-sys/pf/dist/net
Max Laier
mlaier at FreeBSD.org
Wed Dec 10 13:24:31 PST 2008
Author: mlaier
Date: Wed Dec 10 21:24:31 2008
New Revision: 185888
URL: http://svn.freebsd.org/changeset/base/185888
Log:
Import OPENBSD_4_4_BASE
Modified:
vendor-sys/pf/dist/net/if_pfsync.c
vendor-sys/pf/dist/net/if_pfsync.h
vendor-sys/pf/dist/net/pf.c
vendor-sys/pf/dist/net/pf_if.c
vendor-sys/pf/dist/net/pf_ioctl.c
vendor-sys/pf/dist/net/pf_norm.c
vendor-sys/pf/dist/net/pf_osfp.c
vendor-sys/pf/dist/net/pf_table.c
vendor-sys/pf/dist/net/pfvar.h
Modified: vendor-sys/pf/dist/net/if_pfsync.c
==============================================================================
--- vendor-sys/pf/dist/net/if_pfsync.c Wed Dec 10 21:23:23 2008 (r185887)
+++ vendor-sys/pf/dist/net/if_pfsync.c Wed Dec 10 21:24:31 2008 (r185888)
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pfsync.c,v 1.89 2008/01/12 17:08:33 mpf Exp $ */
+/* $OpenBSD: if_pfsync.c,v 1.98 2008/06/29 08:42:15 mcbride Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff
@@ -89,7 +89,6 @@ int pfsync_clone_destroy(struct ifnet *)
void pfsync_setmtu(struct pfsync_softc *, int);
int pfsync_alloc_scrub_memory(struct pfsync_state_peer *,
struct pf_state_peer *);
-int pfsync_insert_net_state(struct pfsync_state *, u_int8_t);
void pfsync_update_net_tdb(struct pfsync_tdb *);
int pfsyncoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *);
@@ -224,117 +223,218 @@ pfsync_alloc_scrub_memory(struct pfsync_
struct pf_state_peer *d)
{
if (s->scrub.scrub_flag && d->scrub == NULL) {
- d->scrub = pool_get(&pf_state_scrub_pl, PR_NOWAIT);
+ d->scrub = pool_get(&pf_state_scrub_pl, PR_NOWAIT | PR_ZERO);
if (d->scrub == NULL)
return (ENOMEM);
- bzero(d->scrub, sizeof(*d->scrub));
}
return (0);
}
+void
+pfsync_state_export(struct pfsync_state *sp, struct pf_state *st)
+{
+ bzero(sp, sizeof(struct pfsync_state));
+
+ /* copy from state key */
+ sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
+ sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
+ sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
+ sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
+ sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
+ sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
+ sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
+ sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
+ sp->proto = st->key[PF_SK_WIRE]->proto;
+ sp->af = st->key[PF_SK_WIRE]->af;
+
+ /* copy from state */
+ strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
+ bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
+ sp->creation = htonl(time_second - st->creation);
+ sp->expire = pf_state_expires(st);
+ if (sp->expire <= time_second)
+ sp->expire = htonl(0);
+ else
+ sp->expire = htonl(sp->expire - time_second);
+
+ sp->direction = st->direction;
+ sp->log = st->log;
+ sp->timeout = st->timeout;
+ sp->state_flags = st->state_flags;
+ if (st->src_node)
+ sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
+ if (st->nat_src_node)
+ sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
+
+ bcopy(&st->id, &sp->id, sizeof(sp->id));
+ sp->creatorid = st->creatorid;
+ pf_state_peer_hton(&st->src, &sp->src);
+ pf_state_peer_hton(&st->dst, &sp->dst);
+
+ if (st->rule.ptr == NULL)
+ sp->rule = htonl(-1);
+ else
+ sp->rule = htonl(st->rule.ptr->nr);
+ if (st->anchor.ptr == NULL)
+ sp->anchor = htonl(-1);
+ else
+ sp->anchor = htonl(st->anchor.ptr->nr);
+ if (st->nat_rule.ptr == NULL)
+ sp->nat_rule = htonl(-1);
+ else
+ sp->nat_rule = htonl(st->nat_rule.ptr->nr);
+
+ pf_state_counter_hton(st->packets[0], sp->packets[0]);
+ pf_state_counter_hton(st->packets[1], sp->packets[1]);
+ pf_state_counter_hton(st->bytes[0], sp->bytes[0]);
+ pf_state_counter_hton(st->bytes[1], sp->bytes[1]);
+
+}
+
int
-pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag)
+pfsync_state_import(struct pfsync_state *sp, u_int8_t flags)
{
struct pf_state *st = NULL;
- struct pf_state_key *sk = NULL;
+ struct pf_state_key *skw = NULL, *sks = NULL;
struct pf_rule *r = NULL;
struct pfi_kif *kif;
+ int pool_flags;
+ int error;
if (sp->creatorid == 0 && pf_status.debug >= PF_DEBUG_MISC) {
- printf("pfsync_insert_net_state: invalid creator id:"
+ printf("pfsync_state_import: invalid creator id:"
" %08x\n", ntohl(sp->creatorid));
return (EINVAL);
}
- kif = pfi_kif_get(sp->ifname);
- if (kif == NULL) {
+ if ((kif = pfi_kif_get(sp->ifname)) == NULL) {
if (pf_status.debug >= PF_DEBUG_MISC)
- printf("pfsync_insert_net_state: "
+ printf("pfsync_state_import: "
"unknown interface: %s\n", sp->ifname);
- /* skip this state */
- return (0);
+ if (flags & PFSYNC_SI_IOCTL)
+ return (EINVAL);
+ return (0); /* skip this state */
}
/*
- * If the ruleset checksums match, it's safe to associate the state
- * with the rule of that number.
+ * If the ruleset checksums match or the state is coming from the ioctl,
+ * it's safe to associate the state with the rule of that number.
*/
- if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) && chksum_flag &&
- ntohl(sp->rule) <
+ if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) &&
+ (flags & (PFSYNC_SI_IOCTL | PFSYNC_SI_CKSUM)) && ntohl(sp->rule) <
pf_main_ruleset.rules[PF_RULESET_FILTER].active.rcount)
r = pf_main_ruleset.rules[
PF_RULESET_FILTER].active.ptr_array[ntohl(sp->rule)];
else
r = &pf_default_rule;
- if (!r->max_states || r->states < r->max_states)
- st = pool_get(&pf_state_pl, PR_NOWAIT);
- if (st == NULL) {
- pfi_kif_unref(kif, PFI_KIF_REF_NONE);
- return (ENOMEM);
- }
- bzero(st, sizeof(*st));
+ if ((r->max_states && r->states_cur >= r->max_states))
+ goto cleanup;
- if ((sk = pf_alloc_state_key(st)) == NULL) {
- pool_put(&pf_state_pl, st);
- pfi_kif_unref(kif, PFI_KIF_REF_NONE);
- return (ENOMEM);
- }
+ if (flags & PFSYNC_SI_IOCTL)
+ pool_flags = PR_WAITOK | PR_LIMITFAIL | PR_ZERO;
+ else
+ pool_flags = PR_LIMITFAIL | PR_ZERO;
- /* allocate memory for scrub info */
- if (pfsync_alloc_scrub_memory(&sp->src, &st->src) ||
- pfsync_alloc_scrub_memory(&sp->dst, &st->dst)) {
- pfi_kif_unref(kif, PFI_KIF_REF_NONE);
- if (st->src.scrub)
- pool_put(&pf_state_scrub_pl, st->src.scrub);
- pool_put(&pf_state_pl, st);
- pool_put(&pf_state_key_pl, sk);
- return (ENOMEM);
- }
+ if ((st = pool_get(&pf_state_pl, pool_flags)) == NULL)
+ goto cleanup;
- st->rule.ptr = r;
- /* XXX get pointers to nat_rule and anchor */
+ if ((skw = pf_alloc_state_key(pool_flags)) == NULL)
+ goto cleanup;
- /* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */
- r->states++;
+ if (PF_ANEQ(&sp->key[PF_SK_WIRE].addr[0],
+ &sp->key[PF_SK_STACK].addr[0], sp->af) ||
+ PF_ANEQ(&sp->key[PF_SK_WIRE].addr[1],
+ &sp->key[PF_SK_STACK].addr[1], sp->af) ||
+ sp->key[PF_SK_WIRE].port[0] != sp->key[PF_SK_STACK].port[0] ||
+ sp->key[PF_SK_WIRE].port[1] != sp->key[PF_SK_STACK].port[1]) {
+ if ((sks = pf_alloc_state_key(pool_flags)) == NULL)
+ goto cleanup;
+ } else
+ sks = skw;
- /* fill in the rest of the state entry */
- pf_state_host_ntoh(&sp->lan, &sk->lan);
- pf_state_host_ntoh(&sp->gwy, &sk->gwy);
- pf_state_host_ntoh(&sp->ext, &sk->ext);
+ /* allocate memory for scrub info */
+ if (pfsync_alloc_scrub_memory(&sp->src, &st->src) ||
+ pfsync_alloc_scrub_memory(&sp->dst, &st->dst))
+ goto cleanup;
- pf_state_peer_ntoh(&sp->src, &st->src);
- pf_state_peer_ntoh(&sp->dst, &st->dst);
+ /* copy to state key(s) */
+ skw->addr[0] = sp->key[PF_SK_WIRE].addr[0];
+ skw->addr[1] = sp->key[PF_SK_WIRE].addr[1];
+ skw->port[0] = sp->key[PF_SK_WIRE].port[0];
+ skw->port[1] = sp->key[PF_SK_WIRE].port[1];
+ skw->proto = sp->proto;
+ skw->af = sp->af;
+ if (sks != skw) {
+ sks->addr[0] = sp->key[PF_SK_STACK].addr[0];
+ sks->addr[1] = sp->key[PF_SK_STACK].addr[1];
+ sks->port[0] = sp->key[PF_SK_STACK].port[0];
+ sks->port[1] = sp->key[PF_SK_STACK].port[1];
+ sks->proto = sp->proto;
+ sks->af = sp->af;
+ }
+ /* copy to state */
bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr));
st->creation = time_second - ntohl(sp->creation);
- st->expire = ntohl(sp->expire) + time_second;
+ st->expire = time_second;
+ if (sp->expire) {
+ /* XXX No adaptive scaling. */
+ st->expire -= r->timeout[sp->timeout] - ntohl(sp->expire);
+ }
- sk->af = sp->af;
- sk->proto = sp->proto;
- sk->direction = sp->direction;
+ st->expire = ntohl(sp->expire) + time_second;
+ st->direction = sp->direction;
st->log = sp->log;
st->timeout = sp->timeout;
- st->allow_opts = sp->allow_opts;
+ st->state_flags = sp->state_flags;
+ if (!(flags & PFSYNC_SI_IOCTL))
+ st->sync_flags = PFSTATE_FROMSYNC;
bcopy(sp->id, &st->id, sizeof(st->id));
st->creatorid = sp->creatorid;
- st->sync_flags = PFSTATE_FROMSYNC;
+ pf_state_peer_ntoh(&sp->src, &st->src);
+ pf_state_peer_ntoh(&sp->dst, &st->dst);
- if (pf_insert_state(kif, st)) {
- pfi_kif_unref(kif, PFI_KIF_REF_NONE);
+ st->rule.ptr = r;
+ st->nat_rule.ptr = NULL;
+ st->anchor.ptr = NULL;
+ st->rt_kif = NULL;
+
+ st->pfsync_time = 0;
+
+
+ /* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */
+ r->states_cur++;
+ r->states_tot++;
+
+ if ((error = pf_state_insert(kif, skw, sks, st)) != 0) {
/* XXX when we have nat_rule/anchors, use STATE_DEC_COUNTERS */
- r->states--;
+ r->states_cur--;
+ goto cleanup_state;
+ }
+
+ return (0);
+
+ cleanup:
+ error = ENOMEM;
+ if (skw == sks)
+ sks = NULL;
+ if (skw != NULL)
+ pool_put(&pf_state_key_pl, skw);
+ if (sks != NULL)
+ pool_put(&pf_state_key_pl, sks);
+
+ cleanup_state: /* pf_state_insert frees the state keys */
+ if (st) {
if (st->dst.scrub)
pool_put(&pf_state_scrub_pl, st->dst.scrub);
if (st->src.scrub)
pool_put(&pf_state_scrub_pl, st->src.scrub);
pool_put(&pf_state_pl, st);
- return (EINVAL);
}
-
- return (0);
+ return (error);
}
void
@@ -345,6 +445,7 @@ pfsync_input(struct mbuf *m, ...)
struct pfsync_softc *sc = pfsyncif;
struct pf_state *st;
struct pf_state_key *sk;
+ struct pf_state_item *si;
struct pf_state_cmp id_key;
struct pfsync_state *sp;
struct pfsync_state_upd *up;
@@ -358,7 +459,7 @@ pfsync_input(struct mbuf *m, ...)
struct in_addr src;
struct mbuf *mp;
int iplen, action, error, i, s, count, offp, sfail, stale = 0;
- u_int8_t chksum_flag = 0;
+ u_int8_t flags = 0;
pfsyncstats.pfsyncs_ipackets++;
@@ -413,7 +514,7 @@ pfsync_input(struct mbuf *m, ...)
src = ip->ip_src;
if (!bcmp(&ph->pf_chksum, &pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH))
- chksum_flag++;
+ flags |= PFSYNC_SI_CKSUM;
switch (action) {
case PFSYNC_ACT_CLR: {
@@ -444,15 +545,16 @@ pfsync_input(struct mbuf *m, ...)
splx(s);
return;
}
- for (sk = RB_MIN(pf_state_tree_lan_ext,
- &pf_statetbl_lan_ext); sk; sk = nextsk) {
- nextsk = RB_NEXT(pf_state_tree_lan_ext,
- &pf_statetbl_lan_ext, sk);
- TAILQ_FOREACH(st, &sk->states, next) {
- if (st->creatorid == creatorid) {
- st->sync_flags |=
+ /* XXX correct? */
+ for (sk = RB_MIN(pf_state_tree,
+ &pf_statetbl); sk; sk = nextsk) {
+ nextsk = RB_NEXT(pf_state_tree,
+ &pf_statetbl, sk);
+ TAILQ_FOREACH(si, &sk->states, entry) {
+ if (si->s->creatorid == creatorid) {
+ si->s->sync_flags |=
PFSTATE_FROMSYNC;
- pf_unlink_state(st);
+ pf_unlink_state(si->s);
}
}
}
@@ -484,8 +586,7 @@ pfsync_input(struct mbuf *m, ...)
continue;
}
- if ((error = pfsync_insert_net_state(sp,
- chksum_flag))) {
+ if ((error = pfsync_state_import(sp, flags))) {
if (error == ENOMEM) {
splx(s);
goto done;
@@ -524,11 +625,11 @@ pfsync_input(struct mbuf *m, ...)
st = pf_find_state_byid(&id_key);
if (st == NULL) {
/* insert the update */
- if (pfsync_insert_net_state(sp, chksum_flag))
+ if (pfsync_state_import(sp, flags))
pfsyncstats.pfsyncs_badstate++;
continue;
}
- sk = st->state_key;
+ sk = st->key[PF_SK_WIRE]; /* XXX right one? */
sfail = 0;
if (sk->proto == IPPROTO_TCP) {
/*
@@ -589,7 +690,7 @@ pfsync_input(struct mbuf *m, ...)
}
continue;
}
- pfsync_alloc_scrub_memory(&sp->dst, &st->dst);
+ pfsync_alloc_scrub_memory(&sp->dst, &st->dst);
pf_state_peer_ntoh(&sp->src, &st->src);
pf_state_peer_ntoh(&sp->dst, &st->dst);
st->expire = ntohl(sp->expire) + time_second;
@@ -665,7 +766,7 @@ pfsync_input(struct mbuf *m, ...)
pfsyncstats.pfsyncs_badstate++;
continue;
}
- sk = st->state_key;
+ sk = st->key[PF_SK_WIRE]; /* XXX right one? */
sfail = 0;
if (sk->proto == IPPROTO_TCP) {
/*
@@ -716,7 +817,7 @@ pfsync_input(struct mbuf *m, ...)
PFSYNC_FLAG_STALE);
continue;
}
- pfsync_alloc_scrub_memory(&up->dst, &st->dst);
+ pfsync_alloc_scrub_memory(&up->dst, &st->dst);
pf_state_peer_ntoh(&up->src, &st->src);
pf_state_peer_ntoh(&up->dst, &st->dst);
st->expire = ntohl(up->expire) + time_second;
@@ -1117,9 +1218,6 @@ pfsync_pack_state(u_int8_t action, struc
struct pfsync_state *sp = NULL;
struct pfsync_state_upd *up = NULL;
struct pfsync_state_del *dp = NULL;
- struct pf_state_key *sk = st->state_key;
- struct pf_rule *r;
- u_long secs;
int s, ret = 0;
u_int8_t i = 255, newaction = 0;
@@ -1186,8 +1284,6 @@ pfsync_pack_state(u_int8_t action, struc
}
}
- secs = time_second;
-
st->pfsync_time = time_uptime;
if (sp == NULL) {
@@ -1199,47 +1295,19 @@ pfsync_pack_state(u_int8_t action, struc
h->count++;
bzero(sp, sizeof(*sp));
- bcopy(&st->id, sp->id, sizeof(sp->id));
- sp->creatorid = st->creatorid;
-
- strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
- pf_state_host_hton(&sk->lan, &sp->lan);
- pf_state_host_hton(&sk->gwy, &sp->gwy);
- pf_state_host_hton(&sk->ext, &sp->ext);
-
- bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
-
- sp->creation = htonl(secs - st->creation);
- pf_state_counter_hton(st->packets[0], sp->packets[0]);
- pf_state_counter_hton(st->packets[1], sp->packets[1]);
- pf_state_counter_hton(st->bytes[0], sp->bytes[0]);
- pf_state_counter_hton(st->bytes[1], sp->bytes[1]);
- if ((r = st->rule.ptr) == NULL)
- sp->rule = htonl(-1);
- else
- sp->rule = htonl(r->nr);
- if ((r = st->anchor.ptr) == NULL)
- sp->anchor = htonl(-1);
- else
- sp->anchor = htonl(r->nr);
- sp->af = sk->af;
- sp->proto = sk->proto;
- sp->direction = sk->direction;
- sp->log = st->log;
- sp->allow_opts = st->allow_opts;
- sp->timeout = st->timeout;
+ pfsync_state_export(sp, st);
if (flags & PFSYNC_FLAG_STALE)
sp->sync_flags |= PFSTATE_STALE;
- }
-
- pf_state_peer_hton(&st->src, &sp->src);
- pf_state_peer_hton(&st->dst, &sp->dst);
+ } else {
+ pf_state_peer_hton(&st->src, &sp->src);
+ pf_state_peer_hton(&st->dst, &sp->dst);
- if (st->expire <= secs)
- sp->expire = htonl(0);
- else
- sp->expire = htonl(st->expire - secs);
+ if (st->expire <= time_second)
+ sp->expire = htonl(0);
+ else
+ sp->expire = htonl(st->expire - time_second);
+ }
/* do we need to build "compressed" actions for network transfer? */
if (sc->sc_sync_ifp && flags & PFSYNC_FLAG_COMPRESS) {
@@ -1715,7 +1783,7 @@ pfsync_update_tdb(struct tdb *tdb, int o
for (i = 0; !pt && i < h->count; i++) {
if (tdb->tdb_spi == u->spi &&
tdb->tdb_sproto == u->sproto &&
- !bcmp(&tdb->tdb_dst, &u->dst,
+ !bcmp(&tdb->tdb_dst, &u->dst,
SA_LEN(&u->dst.sa))) {
pt = u;
pt->updates++;
Modified: vendor-sys/pf/dist/net/if_pfsync.h
==============================================================================
--- vendor-sys/pf/dist/net/if_pfsync.h Wed Dec 10 21:23:23 2008 (r185887)
+++ vendor-sys/pf/dist/net/if_pfsync.h Wed Dec 10 21:24:31 2008 (r185888)
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pfsync.h,v 1.32 2007/12/14 18:33:37 deraadt Exp $ */
+/* $OpenBSD: if_pfsync.h,v 1.35 2008/06/29 08:42:15 mcbride Exp $ */
/*
* Copyright (c) 2001 Michael Shalayeff
@@ -146,7 +146,7 @@ extern struct pfsync_softc *pfsyncif;
struct pfsync_header {
u_int8_t version;
-#define PFSYNC_VERSION 3
+#define PFSYNC_VERSION 4
u_int8_t af;
u_int8_t action;
#define PFSYNC_ACT_CLR 0 /* clear all states */
@@ -205,72 +205,22 @@ struct pfsyncreq {
int pfsyncr_authlevel;
};
-
-/* for copies to/from network */
-#define pf_state_peer_hton(s,d) do { \
- (d)->seqlo = htonl((s)->seqlo); \
- (d)->seqhi = htonl((s)->seqhi); \
- (d)->seqdiff = htonl((s)->seqdiff); \
- (d)->max_win = htons((s)->max_win); \
- (d)->mss = htons((s)->mss); \
- (d)->state = (s)->state; \
- (d)->wscale = (s)->wscale; \
- if ((s)->scrub) { \
- (d)->scrub.pfss_flags = \
- htons((s)->scrub->pfss_flags & PFSS_TIMESTAMP); \
- (d)->scrub.pfss_ttl = (s)->scrub->pfss_ttl; \
- (d)->scrub.pfss_ts_mod = htonl((s)->scrub->pfss_ts_mod);\
- (d)->scrub.scrub_flag = PFSYNC_SCRUB_FLAG_VALID; \
- } \
-} while (0)
-
-#define pf_state_peer_ntoh(s,d) do { \
- (d)->seqlo = ntohl((s)->seqlo); \
- (d)->seqhi = ntohl((s)->seqhi); \
- (d)->seqdiff = ntohl((s)->seqdiff); \
- (d)->max_win = ntohs((s)->max_win); \
- (d)->mss = ntohs((s)->mss); \
- (d)->state = (s)->state; \
- (d)->wscale = (s)->wscale; \
- if ((s)->scrub.scrub_flag == PFSYNC_SCRUB_FLAG_VALID && \
- (d)->scrub != NULL) { \
- (d)->scrub->pfss_flags = \
- ntohs((s)->scrub.pfss_flags) & PFSS_TIMESTAMP; \
- (d)->scrub->pfss_ttl = (s)->scrub.pfss_ttl; \
- (d)->scrub->pfss_ts_mod = ntohl((s)->scrub.pfss_ts_mod);\
- } \
-} while (0)
-
-#define pf_state_host_hton(s,d) do { \
- bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \
- (d)->port = (s)->port; \
-} while (0)
-
-#define pf_state_host_ntoh(s,d) do { \
- bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \
- (d)->port = (s)->port; \
-} while (0)
-
-#define pf_state_counter_hton(s,d) do { \
- d[0] = htonl((s>>32)&0xffffffff); \
- d[1] = htonl(s&0xffffffff); \
-} while (0)
-
-#define pf_state_counter_ntoh(s,d) do { \
- d = ntohl(s[0]); \
- d = d<<32; \
- d += ntohl(s[1]); \
-} while (0)
-
#ifdef _KERNEL
-void pfsync_input(struct mbuf *, ...);
-int pfsync_clear_states(u_int32_t, char *);
-int pfsync_pack_state(u_int8_t, struct pf_state *, int);
-int pfsync_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+void pfsync_input(struct mbuf *, ...);
+int pfsync_clear_states(u_int32_t, char *);
+int pfsync_pack_state(u_int8_t, struct pf_state *, int);
+int pfsync_sysctl(int *, u_int, void *, size_t *,
+ void *, size_t);
+void pfsync_state_export(struct pfsync_state *,
+ struct pf_state *);
+
+#define PFSYNC_SI_IOCTL 0x01
+#define PFSYNC_SI_CKSUM 0x02
+int pfsync_state_import(struct pfsync_state *, u_int8_t);
#define pfsync_insert_state(st) do { \
if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) || \
- (st->state_key->proto == IPPROTO_PFSYNC)) \
+ (st->key[PF_SK_WIRE]->proto == IPPROTO_PFSYNC)) \
st->sync_flags |= PFSTATE_NOSYNC; \
else if (!st->sync_flags) \
pfsync_pack_state(PFSYNC_ACT_INS, (st), \
Modified: vendor-sys/pf/dist/net/pf.c
==============================================================================
--- vendor-sys/pf/dist/net/pf.c Wed Dec 10 21:23:23 2008 (r185887)
+++ vendor-sys/pf/dist/net/pf.c Wed Dec 10 21:24:31 2008 (r185888)
@@ -1,8 +1,8 @@
-/* $OpenBSD: pf.c,v 1.567 2008/02/20 23:40:13 henning Exp $ */
+/* $OpenBSD: pf.c,v 1.614 2008/08/02 12:34:37 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
- * Copyright (c) 2002,2003 Henning Brauer
+ * Copyright (c) 2002 - 2008 Henning Brauer
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -98,8 +98,7 @@
*/
/* state tables */
-struct pf_state_tree_lan_ext pf_statetbl_lan_ext;
-struct pf_state_tree_ext_gwy pf_statetbl_ext_gwy;
+struct pf_state_tree pf_statetbl;
struct pf_altqqueue pf_altqs[2];
struct pf_palist pf_pabuf;
@@ -125,7 +124,7 @@ struct pf_anchor_stackframe {
} pf_anchor_stack[64];
struct pool pf_src_tree_pl, pf_rule_pl, pf_pooladdr_pl;
-struct pool pf_state_pl, pf_state_key_pl;
+struct pool pf_state_pl, pf_state_key_pl, pf_state_item_pl;
struct pool pf_altq_pl;
void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t);
@@ -161,21 +160,41 @@ struct pf_rule *pf_match_translation(st
u_int16_t, int);
struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *,
int, int, struct pfi_kif *, struct pf_src_node **,
- struct pf_addr *, u_int16_t,
- struct pf_addr *, u_int16_t,
- struct pf_addr *, u_int16_t *);
-void pf_attach_state(struct pf_state_key *,
- struct pf_state *, int);
-void pf_detach_state(struct pf_state *, int);
+ struct pf_state_key **, struct pf_state_key **,
+ struct pf_state_key **, struct pf_state_key **,
+ struct pf_addr *, struct pf_addr *,
+ u_int16_t, u_int16_t);
+void pf_detach_state(struct pf_state *);
+int pf_state_key_setup(struct pf_pdesc *, struct pf_rule *,
+ struct pf_state_key **, struct pf_state_key **,
+ struct pf_state_key **, struct pf_state_key **,
+ struct pf_addr *, struct pf_addr *,
+ u_int16_t, u_int16_t);
+void pf_state_key_detach(struct pf_state *, int);
u_int32_t pf_tcp_iss(struct pf_pdesc *);
int pf_test_rule(struct pf_rule **, struct pf_state **,
int, struct pfi_kif *, struct mbuf *, int,
void *, struct pf_pdesc *, struct pf_rule **,
struct pf_ruleset **, struct ifqueue *);
+static __inline int pf_create_state(struct pf_rule *, struct pf_rule *,
+ struct pf_rule *, struct pf_pdesc *,
+ struct pf_src_node *, struct pf_state_key *,
+ struct pf_state_key *, struct pf_state_key *,
+ struct pf_state_key *, struct mbuf *, int,
+ u_int16_t, u_int16_t, int *, struct pfi_kif *,
+ struct pf_state **, int, u_int16_t, u_int16_t,
+ int);
int pf_test_fragment(struct pf_rule **, int,
struct pfi_kif *, struct mbuf *, void *,
struct pf_pdesc *, struct pf_rule **,
struct pf_ruleset **);
+int pf_tcp_track_full(struct pf_state_peer *,
+ struct pf_state_peer *, struct pf_state **,
+ struct pfi_kif *, struct mbuf *, int,
+ struct pf_pdesc *, u_short *, int *);
+int pf_tcp_track_sloppy(struct pf_state_peer *,
+ struct pf_state_peer *, struct pf_state **,
+ struct pf_pdesc *, u_short *);
int pf_test_state_tcp(struct pf_state **, int,
struct pfi_kif *, struct mbuf *, int,
void *, struct pf_pdesc *, u_short *);
@@ -186,10 +205,9 @@ int pf_test_state_icmp(struct pf_stat
struct pfi_kif *, struct mbuf *, int,
void *, struct pf_pdesc *, u_short *);
int pf_test_state_other(struct pf_state **, int,
- struct pfi_kif *, struct pf_pdesc *);
-int pf_match_tag(struct mbuf *, struct pf_rule *, int *);
+ struct pfi_kif *, struct mbuf *, struct pf_pdesc *);
void pf_step_into_anchor(int *, struct pf_ruleset **, int,
- struct pf_rule **, struct pf_rule **, int *);
+ struct pf_rule **, struct pf_rule **, int *);
int pf_step_out_of_anchor(int *, struct pf_ruleset **,
int, struct pf_rule **, struct pf_rule **,
int *);
@@ -219,13 +237,14 @@ void pf_set_rt_ifp(struct pf_state *,
struct pf_addr *);
int pf_check_proto_cksum(struct mbuf *, int, int,
u_int8_t, sa_family_t);
+struct pf_divert *pf_get_divert(struct mbuf *);
+void pf_print_state_parts(struct pf_state *,
+ struct pf_state_key *, struct pf_state_key *);
int pf_addr_wrap_neq(struct pf_addr_wrap *,
struct pf_addr_wrap *);
struct pf_state *pf_find_state(struct pfi_kif *,
- struct pf_state_key_cmp *, u_int);
+ struct pf_state_key_cmp *, u_int, struct mbuf *);
int pf_src_connlimit(struct pf_state **);
-void pf_stateins_err(const char *, struct pf_state *,
- struct pfi_kif *);
int pf_check_congestion(struct ifqueue *);
extern struct pool pfr_ktable_pl;
@@ -239,54 +258,49 @@ struct pf_pool_limit pf_pool_limits[PF_L
{ &pfr_kentry_pl, PFR_KENTRY_HIWAT }
};
-#define STATE_LOOKUP() \
+#define STATE_LOOKUP(i, k, d, s, m) \
do { \
- *state = pf_find_state(kif, &key, direction); \
- if (*state == NULL || (*state)->timeout == PFTM_PURGE) \
+ s = pf_find_state(i, k, d, m); \
+ if (s == NULL || (s)->timeout == PFTM_PURGE) \
return (PF_DROP); \
- if (direction == PF_OUT && \
- (((*state)->rule.ptr->rt == PF_ROUTETO && \
- (*state)->rule.ptr->direction == PF_OUT) || \
- ((*state)->rule.ptr->rt == PF_REPLYTO && \
- (*state)->rule.ptr->direction == PF_IN)) && \
- (*state)->rt_kif != NULL && \
- (*state)->rt_kif != kif) \
+ if (d == PF_OUT && \
+ (((s)->rule.ptr->rt == PF_ROUTETO && \
+ (s)->rule.ptr->direction == PF_OUT) || \
+ ((s)->rule.ptr->rt == PF_REPLYTO && \
+ (s)->rule.ptr->direction == PF_IN)) && \
+ (s)->rt_kif != NULL && \
+ (s)->rt_kif != i) \
return (PF_PASS); \
} while (0)
-#define STATE_TRANSLATE(sk) \
- (sk)->lan.addr.addr32[0] != (sk)->gwy.addr.addr32[0] || \
- ((sk)->af == AF_INET6 && \
- ((sk)->lan.addr.addr32[1] != (sk)->gwy.addr.addr32[1] || \
- (sk)->lan.addr.addr32[2] != (sk)->gwy.addr.addr32[2] || \
- (sk)->lan.addr.addr32[3] != (sk)->gwy.addr.addr32[3])) || \
- (sk)->lan.port != (sk)->gwy.port
-
#define BOUND_IFACE(r, k) \
((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all
#define STATE_INC_COUNTERS(s) \
do { \
- s->rule.ptr->states++; \
- if (s->anchor.ptr != NULL) \
- s->anchor.ptr->states++; \
- if (s->nat_rule.ptr != NULL) \
- s->nat_rule.ptr->states++; \
+ s->rule.ptr->states_cur++; \
+ s->rule.ptr->states_tot++; \
+ if (s->anchor.ptr != NULL) { \
+ s->anchor.ptr->states_cur++; \
+ s->anchor.ptr->states_tot++; \
+ } \
+ if (s->nat_rule.ptr != NULL) { \
+ s->nat_rule.ptr->states_cur++; \
+ s->nat_rule.ptr->states_tot++; \
+ } \
} while (0)
#define STATE_DEC_COUNTERS(s) \
do { \
if (s->nat_rule.ptr != NULL) \
- s->nat_rule.ptr->states--; \
+ s->nat_rule.ptr->states_cur--; \
if (s->anchor.ptr != NULL) \
- s->anchor.ptr->states--; \
- s->rule.ptr->states--; \
+ s->anchor.ptr->states_cur--; \
+ s->rule.ptr->states_cur--; \
} while (0)
static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
-static __inline int pf_state_compare_lan_ext(struct pf_state_key *,
- struct pf_state_key *);
-static __inline int pf_state_compare_ext_gwy(struct pf_state_key *,
+static __inline int pf_state_compare_key(struct pf_state_key *,
struct pf_state_key *);
static __inline int pf_state_compare_id(struct pf_state *,
struct pf_state *);
@@ -297,16 +311,10 @@ struct pf_state_tree_id tree_id;
struct pf_state_queue state_list;
RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare);
-RB_GENERATE(pf_state_tree_lan_ext, pf_state_key,
- entry_lan_ext, pf_state_compare_lan_ext);
-RB_GENERATE(pf_state_tree_ext_gwy, pf_state_key,
- entry_ext_gwy, pf_state_compare_ext_gwy);
+RB_GENERATE(pf_state_tree, pf_state_key, entry, pf_state_compare_key);
RB_GENERATE(pf_state_tree_id, pf_state,
entry_id, pf_state_compare_id);
-#define PF_DT_SKIP_LANEXT 0x01
-#define PF_DT_SKIP_EXTGWY 0x02
-
static __inline int
pf_src_compare(struct pf_src_node *a, struct pf_src_node *b)
{
@@ -351,157 +359,6 @@ pf_src_compare(struct pf_src_node *a, st
return (0);
}
-static __inline int
-pf_state_compare_lan_ext(struct pf_state_key *a, struct pf_state_key *b)
-{
- int diff;
-
- if ((diff = a->proto - b->proto) != 0)
- return (diff);
- if ((diff = a->af - b->af) != 0)
- return (diff);
- switch (a->af) {
-#ifdef INET
- case AF_INET:
- if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0])
- return (1);
- if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0])
- return (-1);
- if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
- return (1);
- if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
- return (-1);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- if (a->lan.addr.addr32[3] > b->lan.addr.addr32[3])
- return (1);
- if (a->lan.addr.addr32[3] < b->lan.addr.addr32[3])
- return (-1);
- if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3])
- return (1);
- if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3])
- return (-1);
- if (a->lan.addr.addr32[2] > b->lan.addr.addr32[2])
- return (1);
- if (a->lan.addr.addr32[2] < b->lan.addr.addr32[2])
- return (-1);
- if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2])
- return (1);
- if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2])
- return (-1);
- if (a->lan.addr.addr32[1] > b->lan.addr.addr32[1])
- return (1);
- if (a->lan.addr.addr32[1] < b->lan.addr.addr32[1])
- return (-1);
- if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1])
- return (1);
- if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1])
- return (-1);
- if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0])
- return (1);
- if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0])
- return (-1);
- if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
- return (1);
- if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
- return (-1);
- break;
-#endif /* INET6 */
- }
-
- if ((diff = a->lan.port - b->lan.port) != 0)
- return (diff);
- if ((diff = a->ext.port - b->ext.port) != 0)
- return (diff);
-
- return (0);
-}
-
-static __inline int
-pf_state_compare_ext_gwy(struct pf_state_key *a, struct pf_state_key *b)
-{
- int diff;
-
- if ((diff = a->proto - b->proto) != 0)
- return (diff);
- if ((diff = a->af - b->af) != 0)
- return (diff);
- switch (a->af) {
-#ifdef INET
- case AF_INET:
- if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
- return (1);
- if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
- return (-1);
- if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0])
- return (1);
- if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0])
- return (-1);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3])
- return (1);
- if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3])
- return (-1);
- if (a->gwy.addr.addr32[3] > b->gwy.addr.addr32[3])
- return (1);
- if (a->gwy.addr.addr32[3] < b->gwy.addr.addr32[3])
- return (-1);
- if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2])
- return (1);
- if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2])
- return (-1);
- if (a->gwy.addr.addr32[2] > b->gwy.addr.addr32[2])
- return (1);
- if (a->gwy.addr.addr32[2] < b->gwy.addr.addr32[2])
- return (-1);
- if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1])
- return (1);
- if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1])
- return (-1);
- if (a->gwy.addr.addr32[1] > b->gwy.addr.addr32[1])
- return (1);
- if (a->gwy.addr.addr32[1] < b->gwy.addr.addr32[1])
- return (-1);
- if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
- return (1);
- if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
- return (-1);
- if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0])
- return (1);
- if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0])
- return (-1);
- break;
-#endif /* INET6 */
- }
-
- if ((diff = a->ext.port - b->ext.port) != 0)
- return (diff);
- if ((diff = a->gwy.port - b->gwy.port) != 0)
- return (diff);
-
- return (0);
-}
-
-static __inline int
-pf_state_compare_id(struct pf_state *a, struct pf_state *b)
-{
- if (a->id > b->id)
- return (1);
- if (a->id < b->id)
- return (-1);
- if (a->creatorid > b->creatorid)
- return (1);
- if (a->creatorid < b->creatorid)
- return (-1);
-
- return (0);
-}
-
#ifdef INET6
void
pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af)
@@ -522,77 +379,6 @@ pf_addrcpy(struct pf_addr *dst, struct p
}
#endif /* INET6 */
-struct pf_state *
-pf_find_state_byid(struct pf_state_cmp *key)
-{
- pf_status.fcounters[FCNT_STATE_SEARCH]++;
-
- return (RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state *)key));
-}
-
-struct pf_state *
-pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int dir)
-{
- struct pf_state_key *sk;
- struct pf_state *s;
-
- pf_status.fcounters[FCNT_STATE_SEARCH]++;
-
- switch (dir) {
- case PF_OUT:
- sk = RB_FIND(pf_state_tree_lan_ext, &pf_statetbl_lan_ext,
- (struct pf_state_key *)key);
- break;
- case PF_IN:
- sk = RB_FIND(pf_state_tree_ext_gwy, &pf_statetbl_ext_gwy,
- (struct pf_state_key *)key);
- break;
- default:
- panic("pf_find_state");
- }
-
- /* list is sorted, if-bound states before floating ones */
- if (sk != NULL)
- TAILQ_FOREACH(s, &sk->states, next)
- if (s->kif == pfi_all || s->kif == kif)
- return (s);
-
- return (NULL);
-}
-
-struct pf_state *
-pf_find_state_all(struct pf_state_key_cmp *key, u_int dir, int *more)
-{
- struct pf_state_key *sk;
- struct pf_state *s, *ret = NULL;
-
- pf_status.fcounters[FCNT_STATE_SEARCH]++;
-
- switch (dir) {
- case PF_OUT:
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list