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

Log:
  Import OPENBSD_4_2_BASE

Modified:
  vendor-sys/pf/dist/net/if_pflog.c
  vendor-sys/pf/dist/net/if_pfsync.c
  vendor-sys/pf/dist/net/if_pfsync.h
  vendor-sys/pf/dist/net/pf.c
  vendor-sys/pf/dist/net/pf_if.c
  vendor-sys/pf/dist/net/pf_ioctl.c
  vendor-sys/pf/dist/net/pf_norm.c
  vendor-sys/pf/dist/net/pf_table.c
  vendor-sys/pf/dist/net/pfvar.h

Modified: vendor-sys/pf/dist/net/if_pflog.c
==============================================================================
--- vendor-sys/pf/dist/net/if_pflog.c   Wed Dec 10 21:09:09 2008        
(r185883)
+++ vendor-sys/pf/dist/net/if_pflog.c   Wed Dec 10 21:21:09 2008        
(r185884)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_pflog.c,v 1.22 2006/12/15 09:31:20 otto Exp $      */
+/*     $OpenBSD: if_pflog.c,v 1.24 2007/05/26 17:13:30 jason Exp $     */
 /*
  * The authors of this code are John Ioannidis ([EMAIL PROTECTED]),
  * Angelos D. Keromytis ([EMAIL PROTECTED]) and 
@@ -87,8 +87,6 @@ struct if_clone       pflog_cloner =
 
 struct ifnet   *pflogifs[PFLOGIFS_MAX];        /* for fast access */
 
-extern int ifqmaxlen;
-
 void
 pflogattach(int npflog)
 {
@@ -96,7 +94,6 @@ pflogattach(int npflog)
        LIST_INIT(&pflogif_list);
        for (i = 0; i < PFLOGIFS_MAX; i++)
                pflogifs[i] = NULL;
-       (void) pflog_clone_create(&pflog_cloner, 0);
        if_clone_attach(&pflog_cloner);
 }
 

Modified: vendor-sys/pf/dist/net/if_pfsync.c
==============================================================================
--- vendor-sys/pf/dist/net/if_pfsync.c  Wed Dec 10 21:09:09 2008        
(r185883)
+++ vendor-sys/pf/dist/net/if_pfsync.c  Wed Dec 10 21:21:09 2008        
(r185884)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_pfsync.c,v 1.73 2006/11/16 13:13:38 henning Exp $  */
+/*     $OpenBSD: if_pfsync.c,v 1.83 2007/06/26 14:44:12 mcbride Exp $  */
 
 /*
  * Copyright (c) 2002 Michael Shalayeff
@@ -106,7 +106,6 @@ void        pfsync_bulk_update(void *);
 void   pfsync_bulkfail(void *);
 
 int    pfsync_sync_ok;
-extern int ifqmaxlen;
 
 struct if_clone        pfsync_cloner =
     IF_CLONE_INITIALIZER("pfsync", pfsync_clone_create, pfsync_clone_destroy);
@@ -221,6 +220,7 @@ int
 pfsync_insert_net_state(struct pfsync_state *sp, u_int8_t chksum_flag)
 {
        struct pf_state *st = NULL;
+       struct pf_state_key *sk = NULL;
        struct pf_rule *r = NULL;
        struct pfi_kif  *kif;
 
@@ -243,7 +243,9 @@ pfsync_insert_net_state(struct pfsync_st
         * If the ruleset checksums match, it's safe to associate the state
         * with the rule of that number.
         */
-       if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) && chksum_flag)
+       if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) && chksum_flag &&
+           ntohl(sp->rule) <
+           pf_main_ruleset.rules[PF_RULESET_FILTER].active.rcount)
                r = pf_main_ruleset.rules[
                    PF_RULESET_FILTER].active.ptr_array[ntohl(sp->rule)];
        else
@@ -257,6 +259,12 @@ pfsync_insert_net_state(struct pfsync_st
        }
        bzero(st, sizeof(*st));
 
+       if ((sk = pf_alloc_state_key(st)) == NULL) {
+               pool_put(&pf_state_pl, st);
+               pfi_kif_unref(kif, PFI_KIF_REF_NONE);
+               return (ENOMEM);
+       }
+
        /* allocate memory for scrub info */
        if (pfsync_alloc_scrub_memory(&sp->src, &st->src) ||
            pfsync_alloc_scrub_memory(&sp->dst, &st->dst)) {
@@ -264,6 +272,7 @@ pfsync_insert_net_state(struct pfsync_st
                if (st->src.scrub)
                        pool_put(&pf_state_scrub_pl, st->src.scrub);
                pool_put(&pf_state_pl, st);
+               pool_put(&pf_state_key_pl, sk);
                return (ENOMEM);
        }
 
@@ -274,9 +283,9 @@ pfsync_insert_net_state(struct pfsync_st
        r->states++;
 
        /* fill in the rest of the state entry */
-       pf_state_host_ntoh(&sp->lan, &st->lan);
-       pf_state_host_ntoh(&sp->gwy, &st->gwy);
-       pf_state_host_ntoh(&sp->ext, &st->ext);
+       pf_state_host_ntoh(&sp->lan, &sk->lan);
+       pf_state_host_ntoh(&sp->gwy, &sk->gwy);
+       pf_state_host_ntoh(&sp->ext, &sk->ext);
 
        pf_state_peer_ntoh(&sp->src, &st->src);
        pf_state_peer_ntoh(&sp->dst, &st->dst);
@@ -285,9 +294,9 @@ pfsync_insert_net_state(struct pfsync_st
        st->creation = time_second - ntohl(sp->creation);
        st->expire = ntohl(sp->expire) + time_second;
 
-       st->af = sp->af;
-       st->proto = sp->proto;
-       st->direction = sp->direction;
+       sk->af = sp->af;
+       sk->proto = sp->proto;
+       sk->direction = sp->direction;
        st->log = sp->log;
        st->timeout = sp->timeout;
        st->allow_opts = sp->allow_opts;
@@ -318,14 +327,17 @@ pfsync_input(struct mbuf *m, ...)
        struct pfsync_header *ph;
        struct pfsync_softc *sc = pfsyncif;
        struct pf_state *st;
-       struct pf_state_cmp key;
+       struct pf_state_key *sk;
+       struct pf_state_cmp id_key;
        struct pfsync_state *sp;
        struct pfsync_state_upd *up;
        struct pfsync_state_del *dp;
        struct pfsync_state_clr *cp;
        struct pfsync_state_upd_req *rup;
        struct pfsync_state_bus *bus;
+#ifdef IPSEC
        struct pfsync_tdb *pt;
+#endif
        struct in_addr src;
        struct mbuf *mp;
        int iplen, action, error, i, s, count, offp, sfail, stale = 0;
@@ -389,7 +401,8 @@ pfsync_input(struct mbuf *m, ...)
        switch (action) {
        case PFSYNC_ACT_CLR: {
                struct pf_state *nexts;
-               struct pfi_kif  *kif;
+               struct pf_state_key *nextsk;
+               struct pfi_kif *kif;
                u_int32_t creatorid;
                if ((mp = m_pulldown(m, iplen + sizeof(*ph),
                    sizeof(*cp), &offp)) == NULL) {
@@ -414,13 +427,16 @@ pfsync_input(struct mbuf *m, ...)
                                splx(s);
                                return;
                        }
-                       for (st = RB_MIN(pf_state_tree_lan_ext,
-                           &kif->pfik_lan_ext); st; st = nexts) {
-                               nexts = RB_NEXT(pf_state_tree_lan_ext,
-                                   &kif->pfik_lan_ext, st);
-                               if (st->creatorid == creatorid) {
-                                       st->sync_flags |= PFSTATE_FROMSYNC;
-                                       pf_unlink_state(st);
+                       for (sk = RB_MIN(pf_state_tree_lan_ext,
+                           &pf_statetbl_lan_ext); sk; sk = nextsk) {
+                               nextsk = RB_NEXT(pf_state_tree_lan_ext,
+                                   &pf_statetbl_lan_ext, sk);
+                               TAILQ_FOREACH(st, &sk->states, next) {
+                                       if (st->creatorid == creatorid) {
+                                               st->sync_flags |=
+                                                   PFSTATE_FROMSYNC;
+                                               pf_unlink_state(st);
+                                       }
                                }
                        }
                }
@@ -485,18 +501,19 @@ pfsync_input(struct mbuf *m, ...)
                                continue;
                        }
 
-                       bcopy(sp->id, &key.id, sizeof(key.id));
-                       key.creatorid = sp->creatorid;
+                       bcopy(sp->id, &id_key.id, sizeof(id_key.id));
+                       id_key.creatorid = sp->creatorid;
 
-                       st = pf_find_state_byid(&key);
+                       st = pf_find_state_byid(&id_key);
                        if (st == NULL) {
                                /* insert the update */
                                if (pfsync_insert_net_state(sp, chksum_flag))
                                        pfsyncstats.pfsyncs_badstate++;
                                continue;
                        }
+                       sk = st->state_key;
                        sfail = 0;
-                       if (st->proto == IPPROTO_TCP) {
+                       if (sk->proto == IPPROTO_TCP) {
                                /*
                                 * The state should never go backwards except
                                 * for syn-proxy states.  Neither should the
@@ -579,10 +596,10 @@ pfsync_input(struct mbuf *m, ...)
                s = splsoftnet();
                for (i = 0, sp = (struct pfsync_state *)(mp->m_data + offp);
                    i < count; i++, sp++) {
-                       bcopy(sp->id, &key.id, sizeof(key.id));
-                       key.creatorid = sp->creatorid;
+                       bcopy(sp->id, &id_key.id, sizeof(id_key.id));
+                       id_key.creatorid = sp->creatorid;
 
-                       st = pf_find_state_byid(&key);
+                       st = pf_find_state_byid(&id_key);
                        if (st == NULL) {
                                pfsyncstats.pfsyncs_badstate++;
                                continue;
@@ -616,10 +633,10 @@ pfsync_input(struct mbuf *m, ...)
                                continue;
                        }
 
-                       bcopy(up->id, &key.id, sizeof(key.id));
-                       key.creatorid = up->creatorid;
+                       bcopy(up->id, &id_key.id, sizeof(id_key.id));
+                       id_key.creatorid = up->creatorid;
 
-                       st = pf_find_state_byid(&key);
+                       st = pf_find_state_byid(&id_key);
                        if (st == NULL) {
                                /* We don't have this state. Ask for it. */
                                error = pfsync_request_update(up, &src);
@@ -631,8 +648,9 @@ pfsync_input(struct mbuf *m, ...)
                                pfsyncstats.pfsyncs_badstate++;
                                continue;
                        }
+                       sk = st->state_key;
                        sfail = 0;
-                       if (st->proto == IPPROTO_TCP) {
+                       if (sk->proto == IPPROTO_TCP) {
                                /*
                                 * The state should never go backwards except
                                 * for syn-proxy states.  Neither should the
@@ -702,10 +720,10 @@ pfsync_input(struct mbuf *m, ...)
                s = splsoftnet();
                for (i = 0, dp = (struct pfsync_state_del *)(mp->m_data + offp);
                    i < count; i++, dp++) {
-                       bcopy(dp->id, &key.id, sizeof(key.id));
-                       key.creatorid = dp->creatorid;
+                       bcopy(dp->id, &id_key.id, sizeof(id_key.id));
+                       id_key.creatorid = dp->creatorid;
 
-                       st = pf_find_state_byid(&key);
+                       st = pf_find_state_byid(&id_key);
                        if (st == NULL) {
                                pfsyncstats.pfsyncs_badstate++;
                                continue;
@@ -732,10 +750,10 @@ pfsync_input(struct mbuf *m, ...)
                for (i = 0,
                    rup = (struct pfsync_state_upd_req *)(mp->m_data + offp);
                    i < count; i++, rup++) {
-                       bcopy(rup->id, &key.id, sizeof(key.id));
-                       key.creatorid = rup->creatorid;
+                       bcopy(rup->id, &id_key.id, sizeof(id_key.id));
+                       id_key.creatorid = rup->creatorid;
 
-                       if (key.id == 0 && key.creatorid == 0) {
+                       if (id_key.id == 0 && id_key.creatorid == 0) {
                                sc->sc_ureq_received = time_uptime;
                                if (sc->sc_bulk_send_next == NULL)
                                        sc->sc_bulk_send_next =
@@ -747,7 +765,7 @@ pfsync_input(struct mbuf *m, ...)
                                pfsync_send_bus(sc, PFSYNC_BUS_START);
                                timeout_add(&sc->sc_bulk_tmo, 1 * hz);
                        } else {
-                               st = pf_find_state_byid(&key);
+                               st = pf_find_state_byid(&id_key);
                                if (st == NULL) {
                                        pfsyncstats.pfsyncs_badstate++;
                                        continue;
@@ -804,6 +822,7 @@ pfsync_input(struct mbuf *m, ...)
                        break;
                }
                break;
+#ifdef IPSEC
        case PFSYNC_ACT_TDB_UPD:
                if ((mp = m_pulldown(m, iplen + sizeof(*ph),
                    count * sizeof(*pt), &offp)) == NULL) {
@@ -816,6 +835,7 @@ pfsync_input(struct mbuf *m, ...)
                        pfsync_update_net_tdb(pt);
                splx(s);
                break;
+#endif
        }
 
 done:
@@ -1080,6 +1100,7 @@ pfsync_pack_state(u_int8_t action, struc
        struct pfsync_state *sp = NULL;
        struct pfsync_state_upd *up = NULL;
        struct pfsync_state_del *dp = NULL;
+       struct pf_state_key *sk = st->state_key;
        struct pf_rule *r;
        u_long secs;
        int s, ret = 0;
@@ -1164,10 +1185,10 @@ pfsync_pack_state(u_int8_t action, struc
                bcopy(&st->id, sp->id, sizeof(sp->id));
                sp->creatorid = st->creatorid;
 
-               strlcpy(sp->ifname, st->u.s.kif->pfik_name, sizeof(sp->ifname));
-               pf_state_host_hton(&st->lan, &sp->lan);
-               pf_state_host_hton(&st->gwy, &sp->gwy);
-               pf_state_host_hton(&st->ext, &sp->ext);
+               strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
+               pf_state_host_hton(&sk->lan, &sp->lan);
+               pf_state_host_hton(&sk->gwy, &sp->gwy);
+               pf_state_host_hton(&sk->ext, &sp->ext);
 
                bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
 
@@ -1184,9 +1205,9 @@ pfsync_pack_state(u_int8_t action, struc
                        sp->anchor = htonl(-1);
                else
                        sp->anchor = htonl(r->nr);
-               sp->af = st->af;
-               sp->proto = st->proto;
-               sp->direction = st->direction;
+               sp->af = sk->af;
+               sp->proto = sk->proto;
+               sp->direction = sk->direction;
                sp->log = st->log;
                sp->allow_opts = st->allow_opts;
                sp->timeout = st->timeout;
@@ -1418,7 +1439,7 @@ pfsync_bulk_update(void *v)
                        }
 
                        /* figure next state to send */
-                       state = TAILQ_NEXT(state, u.s.entry_list);
+                       state = TAILQ_NEXT(state, entry_list);
 
                        /* wrap to start of list if we hit the end */
                        if (!state)
@@ -1577,6 +1598,7 @@ pfsync_sendout_mbuf(struct pfsync_softc 
        return (0);
 }
 
+#ifdef IPSEC
 /* Update an in-kernel tdb. Silently fail if no tdb is found. */
 void
 pfsync_update_net_tdb(struct pfsync_tdb *pt)
@@ -1727,3 +1749,4 @@ pfsync_update_tdb(struct tdb *tdb, int o
        splx(s);
        return (ret);
 }
+#endif

Modified: vendor-sys/pf/dist/net/if_pfsync.h
==============================================================================
--- vendor-sys/pf/dist/net/if_pfsync.h  Wed Dec 10 21:09:09 2008        
(r185883)
+++ vendor-sys/pf/dist/net/if_pfsync.h  Wed Dec 10 21:21:09 2008        
(r185884)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_pfsync.h,v 1.30 2006/10/31 14:49:01 henning Exp $  */
+/*     $OpenBSD: if_pfsync.h,v 1.31 2007/05/31 04:11:42 mcbride Exp $  */
 
 /*
  * Copyright (c) 2001 Michael Shalayeff
@@ -32,62 +32,6 @@
 
 #define PFSYNC_ID_LEN  sizeof(u_int64_t)
 
-struct pfsync_state_scrub {
-       u_int16_t       pfss_flags;
-       u_int8_t        pfss_ttl;       /* stashed TTL          */
-#define PFSYNC_SCRUB_FLAG_VALID        0x01
-       u_int8_t        scrub_flag;
-       u_int32_t       pfss_ts_mod;    /* timestamp modulation */
-} __packed;
-
-struct pfsync_state_host {
-       struct pf_addr  addr;
-       u_int16_t       port;
-       u_int16_t       pad[3];
-} __packed;
-
-struct pfsync_state_peer {
-       struct pfsync_state_scrub scrub;        /* state is scrubbed    */
-       u_int32_t       seqlo;          /* Max sequence number sent     */
-       u_int32_t       seqhi;          /* Max the other end ACKd + win */
-       u_int32_t       seqdiff;        /* Sequence number modulator    */
-       u_int16_t       max_win;        /* largest window (pre scaling) */
-       u_int16_t       mss;            /* Maximum segment size option  */
-       u_int8_t        state;          /* active state level           */
-       u_int8_t        wscale;         /* window scaling factor        */
-       u_int8_t        pad[6];
-} __packed;
-
-struct pfsync_state {
-       u_int32_t        id[2];
-       char             ifname[IFNAMSIZ];
-       struct pfsync_state_host lan;
-       struct pfsync_state_host gwy;
-       struct pfsync_state_host ext;
-       struct pfsync_state_peer src;
-       struct pfsync_state_peer dst;
-       struct pf_addr   rt_addr;
-       u_int32_t        rule;
-       u_int32_t        anchor;
-       u_int32_t        nat_rule;
-       u_int32_t        creation;
-       u_int32_t        expire;
-       u_int32_t        packets[2][2];
-       u_int32_t        bytes[2][2];
-       u_int32_t        creatorid;
-       sa_family_t      af;
-       u_int8_t         proto;
-       u_int8_t         direction;
-       u_int8_t         log;
-       u_int8_t         allow_opts;
-       u_int8_t         timeout;
-       u_int8_t         sync_flags;
-       u_int8_t         updates;
-} __packed;
-
-#define PFSYNC_FLAG_COMPRESS   0x01
-#define PFSYNC_FLAG_STALE      0x02
-
 struct pfsync_tdb {
        u_int32_t       spi;
        union sockaddr_union dst;
@@ -251,6 +195,7 @@ struct pfsyncreq {
 };
 
 
+/* for copies to/from network */
 #define pf_state_peer_hton(s,d) do {           \
        (d)->seqlo = htonl((s)->seqlo);         \
        (d)->seqhi = htonl((s)->seqhi);         \
@@ -312,7 +257,7 @@ int pfsync_clear_states(u_int32_t, char 
 int pfsync_pack_state(u_int8_t, struct pf_state *, int);
 #define pfsync_insert_state(st)        do {                            \
        if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) ||        \
-           (st->proto == IPPROTO_PFSYNC))                      \
+           (st->state_key->proto == IPPROTO_PFSYNC))                   \
                st->sync_flags |= PFSTATE_NOSYNC;               \
        else if (!st->sync_flags)                               \
                pfsync_pack_state(PFSYNC_ACT_INS, (st),         \

Modified: vendor-sys/pf/dist/net/pf.c
==============================================================================
--- vendor-sys/pf/dist/net/pf.c Wed Dec 10 21:09:09 2008        (r185883)
+++ vendor-sys/pf/dist/net/pf.c Wed Dec 10 21:21:09 2008        (r185884)
@@ -1,5 +1,4 @@
-/*     $OpenBSD: pf.c,v 1.527 2007/02/22 15:23:23 pyr Exp $ */
-/* add:        $OpenBSD: pf.c,v 1.559 2007/09/18 18:45:59 markus Exp $ */
+/*     $OpenBSD: pf.c,v 1.552 2007/08/21 15:57:27 dhartmei Exp $ */
 
 /*
  * Copyright (c) 2001 Daniel Hartmeier
@@ -96,6 +95,10 @@
  * Global variables
  */
 
+/* state tables */
+struct pf_state_tree_lan_ext    pf_statetbl_lan_ext;
+struct pf_state_tree_ext_gwy    pf_statetbl_ext_gwy;
+
 struct pf_altqqueue     pf_altqs[2];
 struct pf_palist        pf_pabuf;
 struct pf_altqqueue    *pf_altqs_active;
@@ -114,8 +117,9 @@ struct pf_anchor_stackframe {
        struct pf_anchor                        *child;
 } pf_anchor_stack[64];
 
-struct pool             pf_src_tree_pl, pf_rule_pl;
-struct pool             pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
+struct pool             pf_src_tree_pl, pf_rule_pl, pf_pooladdr_pl;
+struct pool             pf_state_pl, pf_state_key_pl;
+struct pool             pf_altq_pl;
 
 void                    pf_print_host(struct pf_addr *, u_int16_t, u_int8_t);
 
@@ -153,22 +157,13 @@ struct pf_rule            *pf_get_translation(stru
                            struct pf_addr *, u_int16_t,
                            struct pf_addr *, u_int16_t,
                            struct pf_addr *, u_int16_t *);
-int                     pf_test_tcp(struct pf_rule **, struct pf_state **,
-                           int, struct pfi_kif *, struct mbuf *, int,
-                           void *, struct pf_pdesc *, struct pf_rule **,
-                           struct pf_ruleset **, struct ifqueue *);
-int                     pf_test_udp(struct pf_rule **, struct pf_state **,
+void                    pf_attach_state(struct pf_state_key *,
+                           struct pf_state *, int);
+void                    pf_detach_state(struct pf_state *, int);
+int                     pf_test_rule(struct pf_rule **, struct pf_state **,
                            int, struct pfi_kif *, struct mbuf *, int,
                            void *, struct pf_pdesc *, struct pf_rule **,
                            struct pf_ruleset **, struct ifqueue *);
-int                     pf_test_icmp(struct pf_rule **, struct pf_state **,
-                           int, struct pfi_kif *, struct mbuf *, int,
-                           void *, struct pf_pdesc *, struct pf_rule **,
-                           struct pf_ruleset **, struct ifqueue *);
-int                     pf_test_other(struct pf_rule **, struct pf_state **,
-                           int, struct pfi_kif *, struct mbuf *, int, void *,
-                           struct pf_pdesc *, struct pf_rule **,
-                           struct pf_ruleset **, struct ifqueue *);
 int                     pf_test_fragment(struct pf_rule **, int,
                            struct pfi_kif *, struct mbuf *, void *,
                            struct pf_pdesc *, struct pf_rule **,
@@ -184,8 +179,9 @@ int                  pf_test_state_icmp(struct pf_stat
                            void *, struct pf_pdesc *, u_short *);
 int                     pf_test_state_other(struct pf_state **, int,
                            struct pfi_kif *, struct pf_pdesc *);
-int                     pf_match_tag(struct mbuf *, struct pf_rule *,
-                            struct pf_mtag *, int *);
+int                     pf_match_tag(struct mbuf *, struct pf_rule *, int *);
+void                    pf_step_into_anchor(int *, struct pf_ruleset **, int,
+                           struct pf_rule **, struct pf_rule **,  int *);
 int                     pf_step_out_of_anchor(int *, struct pf_ruleset **,
                             int, struct pf_rule **, struct pf_rule **,
                             int *);
@@ -217,9 +213,11 @@ int                         pf_check_proto_cksum(struct 
mbuf 
                            u_int8_t, sa_family_t);
 int                     pf_addr_wrap_neq(struct pf_addr_wrap *,
                            struct pf_addr_wrap *);
-struct pf_state                *pf_find_state_recurse(struct pfi_kif *,
-                           struct pf_state_cmp *, u_int8_t);
+struct pf_state                *pf_find_state(struct pfi_kif *,
+                           struct pf_state_key_cmp *, u_int8_t);
 int                     pf_src_connlimit(struct pf_state **);
+void                    pf_stateins_err(const char *, struct pf_state *,
+                           struct pfi_kif *);
 int                     pf_check_congestion(struct ifqueue *);
 
 extern struct pool pfr_ktable_pl;
@@ -236,11 +234,9 @@ struct pf_pool_limit pf_pool_limits[PF_L
 #define STATE_LOOKUP()                                                 \
        do {                                                            \
                if (direction == PF_IN)                                 \
-                       *state = pf_find_state_recurse(                 \
-                           kif, &key, PF_EXT_GWY);                     \
+                       *state = pf_find_state(kif, &key, PF_EXT_GWY);  \
                else                                                    \
-                       *state = pf_find_state_recurse(                 \
-                           kif, &key, PF_LAN_EXT);                     \
+                       *state = pf_find_state(kif, &key, PF_LAN_EXT);  \
                if (*state == NULL || (*state)->timeout == PFTM_PURGE)  \
                        return (PF_DROP);                               \
                if (direction == PF_OUT &&                              \
@@ -253,13 +249,13 @@ struct pf_pool_limit pf_pool_limits[PF_L
                        return (PF_PASS);                               \
        } while (0)
 
-#define        STATE_TRANSLATE(s) \
-       (s)->lan.addr.addr32[0] != (s)->gwy.addr.addr32[0] || \
-       ((s)->af == AF_INET6 && \
-       ((s)->lan.addr.addr32[1] != (s)->gwy.addr.addr32[1] || \
-       (s)->lan.addr.addr32[2] != (s)->gwy.addr.addr32[2] || \
-       (s)->lan.addr.addr32[3] != (s)->gwy.addr.addr32[3])) || \
-       (s)->lan.port != (s)->gwy.port
+#define        STATE_TRANSLATE(sk) \
+       (sk)->lan.addr.addr32[0] != (sk)->gwy.addr.addr32[0] || \
+       ((sk)->af == AF_INET6 && \
+       ((sk)->lan.addr.addr32[1] != (sk)->gwy.addr.addr32[1] || \
+       (sk)->lan.addr.addr32[2] != (sk)->gwy.addr.addr32[2] || \
+       (sk)->lan.addr.addr32[3] != (sk)->gwy.addr.addr32[3])) || \
+       (sk)->lan.port != (sk)->gwy.port
 
 #define BOUND_IFACE(r, k) \
        ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all
@@ -283,10 +279,10 @@ struct pf_pool_limit pf_pool_limits[PF_L
        } while (0)
 
 static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
-static __inline int pf_state_compare_lan_ext(struct pf_state *,
-       struct pf_state *);
-static __inline int pf_state_compare_ext_gwy(struct pf_state *,
-       struct pf_state *);
+static __inline int pf_state_compare_lan_ext(struct pf_state_key *,
+       struct pf_state_key *);
+static __inline int pf_state_compare_ext_gwy(struct pf_state_key *,
+       struct pf_state_key *);
 static __inline int pf_state_compare_id(struct pf_state *,
        struct pf_state *);
 
@@ -296,12 +292,15 @@ struct pf_state_tree_id tree_id;
 struct pf_state_queue state_list;
 
 RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare);
-RB_GENERATE(pf_state_tree_lan_ext, pf_state,
-    u.s.entry_lan_ext, pf_state_compare_lan_ext);
-RB_GENERATE(pf_state_tree_ext_gwy, pf_state,
-    u.s.entry_ext_gwy, pf_state_compare_ext_gwy);
+RB_GENERATE(pf_state_tree_lan_ext, pf_state_key,
+    entry_lan_ext, pf_state_compare_lan_ext);
+RB_GENERATE(pf_state_tree_ext_gwy, pf_state_key,
+    entry_ext_gwy, pf_state_compare_ext_gwy);
 RB_GENERATE(pf_state_tree_id, pf_state,
-    u.s.entry_id, pf_state_compare_id);
+    entry_id, pf_state_compare_id);
+
+#define        PF_DT_SKIP_LANEXT       0x01
+#define        PF_DT_SKIP_EXTGWY       0x02
 
 static __inline int
 pf_src_compare(struct pf_src_node *a, struct pf_src_node *b)
@@ -348,7 +347,7 @@ pf_src_compare(struct pf_src_node *a, st
 }
 
 static __inline int
-pf_state_compare_lan_ext(struct pf_state *a, struct pf_state *b)
+pf_state_compare_lan_ext(struct pf_state_key *a, struct pf_state_key *b)
 {
        int     diff;
 
@@ -416,7 +415,7 @@ pf_state_compare_lan_ext(struct pf_state
 }
 
 static __inline int
-pf_state_compare_ext_gwy(struct pf_state *a, struct pf_state *b)
+pf_state_compare_ext_gwy(struct pf_state_key *a, struct pf_state_key *b)
 {
        int     diff;
 
@@ -522,74 +521,71 @@ struct pf_state *
 pf_find_state_byid(struct pf_state_cmp *key)
 {
        pf_status.fcounters[FCNT_STATE_SEARCH]++;
+       
        return (RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state *)key));
 }
 
 struct pf_state *
-pf_find_state_recurse(struct pfi_kif *kif, struct pf_state_cmp *key, u_int8_t 
tree)
+pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int8_t tree)
 {
-       struct pf_state *s;
+       struct pf_state_key     *sk;
+       struct pf_state         *s;
 
        pf_status.fcounters[FCNT_STATE_SEARCH]++;
 
        switch (tree) {
        case PF_LAN_EXT:
-               if ((s = RB_FIND(pf_state_tree_lan_ext, &kif->pfik_lan_ext,
-                   (struct pf_state *)key)) != NULL)
-                       return (s);
-               if ((s = RB_FIND(pf_state_tree_lan_ext, &pfi_all->pfik_lan_ext,
-                   (struct pf_state *)key)) != NULL)
-                       return (s);
-               return (NULL);
+               sk = RB_FIND(pf_state_tree_lan_ext, &pf_statetbl_lan_ext,
+                   (struct pf_state_key *)key);
+               break;
        case PF_EXT_GWY:
-               if ((s = RB_FIND(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy,
-                   (struct pf_state *)key)) != NULL)
-                       return (s);
-               if ((s = RB_FIND(pf_state_tree_ext_gwy, &pfi_all->pfik_ext_gwy,
-                   (struct pf_state *)key)) != NULL)
-                       return (s);
-               return (NULL);
+               sk = RB_FIND(pf_state_tree_ext_gwy, &pf_statetbl_ext_gwy,
+                   (struct pf_state_key *)key);
+               break;
        default:
-               panic("pf_find_state_recurse");
+               panic("pf_find_state");
        }
+
+       /* list is sorted, if-bound states before floating ones */
+       if (sk != NULL)
+               TAILQ_FOREACH(s, &sk->states, next)
+                       if (s->kif == pfi_all || s->kif == kif)
+                               return (s);
+
+       return (NULL);
 }
 
 struct pf_state *
-pf_find_state_all(struct pf_state_cmp *key, u_int8_t tree, int *more)
+pf_find_state_all(struct pf_state_key_cmp *key, u_int8_t tree, int *more)
 {
-       struct pf_state *s, *ss = NULL;
-       struct pfi_kif  *kif;
+       struct pf_state_key     *sk;
+       struct pf_state         *s, *ret = NULL;
 
        pf_status.fcounters[FCNT_STATE_SEARCH]++;
 
        switch (tree) {
        case PF_LAN_EXT:
-               TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) {
-                       s = RB_FIND(pf_state_tree_lan_ext,
-                           &kif->pfik_lan_ext, (struct pf_state *)key);
-                       if (s == NULL)
-                               continue;
-                       if (more == NULL)
-                               return (s);
-                       ss = s;
-                       (*more)++;
-               }
-               return (ss);
+               sk = RB_FIND(pf_state_tree_lan_ext,
+                   &pf_statetbl_lan_ext, (struct pf_state_key *)key);
+               break;
        case PF_EXT_GWY:
-               TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) {
-                       s = RB_FIND(pf_state_tree_ext_gwy,
-                           &kif->pfik_ext_gwy, (struct pf_state *)key);
-                       if (s == NULL)
-                               continue;
-                       if (more == NULL)
-                               return (s);
-                       ss = s;
-                       (*more)++;
-               }
-               return (ss);
+               sk = RB_FIND(pf_state_tree_ext_gwy,
+                   &pf_statetbl_ext_gwy, (struct pf_state_key *)key);
+               break;
        default:
                panic("pf_find_state_all");
        }
+
+       if (sk != NULL) {
+               ret = TAILQ_FIRST(&sk->states);
+               if (more == NULL)
+                       return (ret);
+
+               TAILQ_FOREACH(s, &sk->states, next)
+                       (*more)++;
+       }
+
+       return (ret);
 }
 
 void
@@ -625,7 +621,6 @@ pf_check_threshold(struct pf_threshold *
 int
 pf_src_connlimit(struct pf_state **state)
 {
-       struct pf_state *s;
        int bad = 0;
 
        (*state)->src_node->conn++;
@@ -656,12 +651,12 @@ pf_src_connlimit(struct pf_state **state
                if (pf_status.debug >= PF_DEBUG_MISC) {
                        printf("pf_src_connlimit: blocking address ");
                        pf_print_host(&(*state)->src_node->addr, 0,
-                           (*state)->af);
+                           (*state)->state_key->af);
                }
 
                bzero(&p, sizeof(p));
-               p.pfra_af = (*state)->af;
-               switch ((*state)->af) {
+               p.pfra_af = (*state)->state_key->af;
+               switch ((*state)->state_key->af) {
 #ifdef INET
                case AF_INET:
                        p.pfra_net = 32;
@@ -681,26 +676,31 @@ pf_src_connlimit(struct pf_state **state
 
                /* kill existing states if that's required. */
                if ((*state)->rule.ptr->flush) {
-                       pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
+                       struct pf_state_key *sk;
+                       struct pf_state *st;
 
-                       RB_FOREACH(s, pf_state_tree_id, &tree_id) {
+                       pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
+                       RB_FOREACH(st, pf_state_tree_id, &tree_id) {
+                               sk = st->state_key;
                                /*
                                 * Kill states from this source.  (Only those
                                 * from the same rule if PF_FLUSH_GLOBAL is not
                                 * set)
                                 */
-                               if (s->af == (*state)->af &&
-                                   (((*state)->direction == PF_OUT &&
+                               if (sk->af ==
+                                   (*state)->state_key->af &&
+                                   (((*state)->state_key->direction ==
+                                       PF_OUT &&
                                    PF_AEQ(&(*state)->src_node->addr,
-                                   &s->lan.addr, s->af)) ||
-                                   ((*state)->direction == PF_IN &&
+                                       &sk->lan.addr, sk->af)) ||
+                                   ((*state)->state_key->direction == PF_IN &&
                                    PF_AEQ(&(*state)->src_node->addr,
-                                   &s->ext.addr, s->af))) &&
+                                       &sk->ext.addr, sk->af))) &&
                                    ((*state)->rule.ptr->flush &
                                    PF_FLUSH_GLOBAL ||
-                                   (*state)->rule.ptr == s->rule.ptr)) {
-                                       s->timeout = PFTM_PURGE;
-                                       s->src.state = s->dst.state =
+                                   (*state)->rule.ptr == st->rule.ptr)) {
+                                       st->timeout = PFTM_PURGE;
+                                       st->src.state = st->dst.state =
                                            TCPS_CLOSED;
                                        killed++;
                                }
@@ -782,73 +782,80 @@ pf_insert_src_node(struct pf_src_node **
        return (0);
 }
 
+void
+pf_stateins_err(const char *tree, struct pf_state *s, struct pfi_kif *kif)
+{
+       struct pf_state_key     *sk = s->state_key;
+
+       if (pf_status.debug >= PF_DEBUG_MISC) {
+               printf("pf: state insert failed: %s %s", tree, kif->pfik_name);
+               printf(" lan: ");
+               pf_print_host(&sk->lan.addr, sk->lan.port,
+                   sk->af);
+               printf(" gwy: ");
+               pf_print_host(&sk->gwy.addr, sk->gwy.port,
+                   sk->af);
+               printf(" ext: ");
+               pf_print_host(&sk->ext.addr, sk->ext.port,
+                   sk->af);
+               if (s->sync_flags & PFSTATE_FROMSYNC)
+                       printf(" (from sync)");
+               printf("\n");
+       }
+}
+
 int
-pf_insert_state(struct pfi_kif *kif, struct pf_state *state)
+pf_insert_state(struct pfi_kif *kif, struct pf_state *s)
 {
-       /* Thou MUST NOT insert multiple duplicate keys */
-       state->u.s.kif = kif;
-       if (RB_INSERT(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state)) {
-               if (pf_status.debug >= PF_DEBUG_MISC) {
-                       printf("pf: state insert failed: tree_lan_ext");
-                       printf(" lan: ");
-                       pf_print_host(&state->lan.addr, state->lan.port,
-                           state->af);
-                       printf(" gwy: ");
-                       pf_print_host(&state->gwy.addr, state->gwy.port,
-                           state->af);
-                       printf(" ext: ");
-                       pf_print_host(&state->ext.addr, state->ext.port,
-                           state->af);
-                       if (state->sync_flags & PFSTATE_FROMSYNC)
-                               printf(" (from sync)");
-                       printf("\n");
-               }
-               return (-1);
+       struct pf_state_key     *cur;
+       struct pf_state         *sp;
+
+       KASSERT(s->state_key != NULL);
+       s->kif = kif;
+
+       if ((cur = RB_INSERT(pf_state_tree_lan_ext, &pf_statetbl_lan_ext,
+           s->state_key)) != NULL) {
+               /* key exists. check for same kif, if none, add to key */
+               TAILQ_FOREACH(sp, &cur->states, next)
+                       if (sp->kif == kif) {   /* collision! */
+                               pf_stateins_err("tree_lan_ext", s, kif);
+                               return (-1);
+                       }
+               pf_detach_state(s, PF_DT_SKIP_LANEXT|PF_DT_SKIP_EXTGWY);
+               pf_attach_state(cur, s, kif == pfi_all ? 1 : 0);
        }
 
-       if (RB_INSERT(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state)) {
-               if (pf_status.debug >= PF_DEBUG_MISC) {
-                       printf("pf: state insert failed: tree_ext_gwy");
-                       printf(" lan: ");
-                       pf_print_host(&state->lan.addr, state->lan.port,
-                           state->af);
-                       printf(" gwy: ");
-                       pf_print_host(&state->gwy.addr, state->gwy.port,
-                           state->af);
-                       printf(" ext: ");
-                       pf_print_host(&state->ext.addr, state->ext.port,
-                           state->af);
-                       if (state->sync_flags & PFSTATE_FROMSYNC)
-                               printf(" (from sync)");
-                       printf("\n");
-               }
-               RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state);
+       /* if cur != NULL, we already found a state key and attached to it */
+       if (cur == NULL && (cur = RB_INSERT(pf_state_tree_ext_gwy,
+           &pf_statetbl_ext_gwy, s->state_key)) != NULL) {
+               /* must not happen. we must have found the sk above! */
+               pf_stateins_err("tree_ext_gwy", s, kif);
+               pf_detach_state(s, PF_DT_SKIP_EXTGWY);
                return (-1);
        }
 
-       if (state->id == 0 && state->creatorid == 0) {
-               state->id = htobe64(pf_status.stateid++);
-               state->creatorid = pf_status.hostid;
+       if (s->id == 0 && s->creatorid == 0) {
+               s->id = htobe64(pf_status.stateid++);
+               s->creatorid = pf_status.hostid;
        }
-       if (RB_INSERT(pf_state_tree_id, &tree_id, state) != NULL) {
+       if (RB_INSERT(pf_state_tree_id, &tree_id, s) != NULL) {
                if (pf_status.debug >= PF_DEBUG_MISC) {
                        printf("pf: state insert failed: "
                            "id: %016llx creatorid: %08x",
-                           betoh64(state->id), ntohl(state->creatorid));
-                       if (state->sync_flags & PFSTATE_FROMSYNC)
+                           betoh64(s->id), ntohl(s->creatorid));
+                       if (s->sync_flags & PFSTATE_FROMSYNC)
                                printf(" (from sync)");
                        printf("\n");
                }
-               RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state);
-               RB_REMOVE(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state);
+               pf_detach_state(s, 0);
                return (-1);
        }
-       TAILQ_INSERT_TAIL(&state_list, state, u.s.entry_list);
+       TAILQ_INSERT_TAIL(&state_list, s, entry_list);
        pf_status.fcounters[FCNT_STATE_INSERT]++;
        pf_status.states++;
        pfi_kif_ref(kif, PFI_KIF_REF_STATE);
 #if NPFSYNC
-       pfsync_insert_state(state);
+       pfsync_insert_state(s);
 #endif
        return (0);
 }
@@ -954,7 +961,7 @@ pf_src_tree_remove_state(struct pf_state
        u_int32_t timeout;
 
        if (s->src_node != NULL) {
-               if (s->proto == IPPROTO_TCP) {
+               if (s->state_key->proto == IPPROTO_TCP) {
                        if (s->src.tcp_est)
                                --s->src_node->conn;
                }
@@ -983,16 +990,12 @@ void
 pf_unlink_state(struct pf_state *cur)
 {
        if (cur->src.state == PF_TCPS_PROXY_DST) {
-               pf_send_tcp(cur->rule.ptr, cur->af,
-                   &cur->ext.addr, &cur->lan.addr,
-                   cur->ext.port, cur->lan.port,
+               pf_send_tcp(cur->rule.ptr, cur->state_key->af,
+                   &cur->state_key->ext.addr, &cur->state_key->lan.addr,
+                   cur->state_key->ext.port, cur->state_key->lan.port,
                    cur->src.seqhi, cur->src.seqlo + 1,
                    TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL);
        }
-       RB_REMOVE(pf_state_tree_ext_gwy,
-           &cur->u.s.kif->pfik_ext_gwy, cur);
-       RB_REMOVE(pf_state_tree_lan_ext,
-           &cur->u.s.kif->pfik_lan_ext, cur);
        RB_REMOVE(pf_state_tree_id, &tree_id, cur);
 #if NPFSYNC
        if (cur->creatorid == pf_status.hostid)
@@ -1000,6 +1003,7 @@ pf_unlink_state(struct pf_state *cur)
 #endif
        cur->timeout = PFTM_UNLINKED;
        pf_src_tree_remove_state(cur);
+       pf_detach_state(cur, 0);
 }
 
 /* callers should be at splsoftnet and hold the
@@ -1025,8 +1029,8 @@ pf_free_state(struct pf_state *cur)
                if (--cur->anchor.ptr->states <= 0)
                        pf_rm_rule(NULL, cur->anchor.ptr);
        pf_normalize_tcp_cleanup(cur);
-       pfi_kif_unref(cur->u.s.kif, PFI_KIF_REF_STATE);
-       TAILQ_REMOVE(&state_list, cur, u.s.entry_list);
+       pfi_kif_unref(cur->kif, PFI_KIF_REF_STATE);
+       TAILQ_REMOVE(&state_list, cur, entry_list);
        if (cur->tag)
                pf_tag_unref(cur->tag);
        pool_put(&pf_state_pl, cur);
@@ -1050,7 +1054,7 @@ pf_purge_expired_states(u_int32_t maxche
                }
 
                /* get next state, as cur may get deleted */
-               next = TAILQ_NEXT(cur, u.s.entry_list);
+               next = TAILQ_NEXT(cur, entry_list);
 
                if (cur->timeout == PFTM_UNLINKED) {
                        /* free unlinked state */
@@ -1175,7 +1179,8 @@ pf_print_host(struct pf_addr *addr, u_in
 void
 pf_print_state(struct pf_state *s)
 {
-       switch (s->proto) {
+       struct pf_state_key *sk = s->state_key;
+       switch (sk->proto) {
        case IPPROTO_TCP:
                printf("TCP ");
                break;
@@ -1189,14 +1194,14 @@ pf_print_state(struct pf_state *s)
                printf("ICMPV6 ");
                break;
        default:
-               printf("%u ", s->proto);
+               printf("%u ", sk->proto);
                break;
        }
-       pf_print_host(&s->lan.addr, s->lan.port, s->af);
+       pf_print_host(&sk->lan.addr, sk->lan.port, sk->af);
        printf(" ");
-       pf_print_host(&s->gwy.addr, s->gwy.port, s->af);
+       pf_print_host(&sk->gwy.addr, sk->gwy.port, sk->af);
        printf(" ");
-       pf_print_host(&s->ext.addr, s->ext.port, s->af);
+       pf_print_host(&sk->ext.addr, sk->ext.port, sk->af);
        printf(" [lo=%u high=%u win=%u modulator=%u", s->src.seqlo,
            s->src.seqhi, s->src.max_win, s->src.seqdiff);
        if (s->src.wscale && s->dst.wscale)
@@ -1565,7 +1570,6 @@ pf_send_tcp(const struct pf_rule *r, sa_
 #endif /* INET6 */
        struct tcphdr   *th;
        char            *opt;
-       struct pf_mtag  *pf_mtag;
 
        /* maximum segment size tcp option */
        tlen = sizeof(struct tcphdr);
@@ -1589,24 +1593,18 @@ pf_send_tcp(const struct pf_rule *r, sa_
        m = m_gethdr(M_DONTWAIT, MT_HEADER);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to