hi,

this is an update of the pf code to 4.5 -pfsyncv5 -pf_lb.c and
with "state key linking" still disabled.

should be compatible with the pfctl.

diff reduces the difference with openbsd + backports lots of fixes.

please read carefully, try (on aeriebsd or openbsd 4.4) and review.

thanks.

Index: pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.2
diff -u -r1.2 pf.c
--- pf.c        26 Dec 2008 18:51:52 -0000      1.2
+++ pf.c        21 May 2009 23:18:43 -0000
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2001 Daniel Hartmeier
  * Copyright (c) 2002 - 2008 Henning Brauer
@@ -660,6 +659,7 @@
 {
        struct pf_state_item    *si;
        struct pf_state_key     *cur;
+       struct pf_state         *olds = NULL;
 
        KASSERT(s->key[idx] == NULL);   /* XXX handle this? */
 
@@ -668,19 +668,36 @@
                TAILQ_FOREACH(si, &cur->states, entry)
                        if (si->s->kif == s->kif &&
                            si->s->direction == s->direction) {
-                               if (pf_status.debug >= PF_DEBUG_MISC) {
-                                       printf(
-                                           "pf: %s key attach failed on %s: ",
-                                           (idx == PF_SK_WIRE) ?
-                                           "wire" : "stack",
-                                           s->kif->pfik_name);
-                                       pf_print_state_parts(s,
-                                           (idx == PF_SK_WIRE) ? sk : NULL,
-                                           (idx == PF_SK_STACK) ? sk : NULL);
-                                       printf("\n");
+                               if (sk->proto == IPPROTO_TCP &&
+                                   si->s->src.state >= TCPS_FIN_WAIT_2 &&
+                                   si->s->dst.state >= TCPS_FIN_WAIT_2) {
+                                       si->s->src.state = si->s->dst.state =
+                                           TCPS_CLOSED;
+                                       /* unlink late or sks can go away */
+                                       olds = si->s;
+                               } else {
+                                       if (pf_status.debug >= PF_DEBUG_MISC) {
+                                               printf("pf: %s key attach "
+                                                   "failed on %s: ",
+                                                   (idx == PF_SK_WIRE) ?
+                                                   "wire" : "stack",
+                                                   s->kif->pfik_name);
+                                               pf_print_state_parts(s,
+                                                   (idx == PF_SK_WIRE) ?
+                                                   sk : NULL,
+                                                   (idx == PF_SK_STACK) ?
+                                                   sk : NULL);
+                                               printf(", existing: ");
+                                               pf_print_state_parts(si->s,
+                                                   (idx == PF_SK_WIRE) ?
+                                                   sk : NULL,
+                                                   (idx == PF_SK_STACK) ?
+                                                   sk : NULL);
+                                               printf("\n");
+                                       }
+                                       pool_put(&pf_state_key_pl, sk);
+                                       return (-1);    /* collision! */
                                }
-                               pool_put(&pf_state_key_pl, sk);
-                               return (-1);    /* collision! */
                        }
                pool_put(&pf_state_key_pl, sk);
                s->key[idx] = cur;
@@ -698,6 +715,10 @@
                TAILQ_INSERT_TAIL(&s->key[idx]->states, si, entry);
        else
                TAILQ_INSERT_HEAD(&s->key[idx]->states, si, entry);
+
+       if (olds)
+               pf_unlink_state(olds);
+
        return (0);
 }
 
@@ -1141,7 +1162,7 @@
 {
        if (aw->type != PF_ADDR_TABLE)
                return (0);
-       if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL)
+       if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname, 1)) == NULL)
                return (1);
        return (0);
 }
@@ -1188,34 +1209,33 @@
 #ifdef INET6
        case AF_INET6: {
                u_int16_t b;
-               u_int8_t i, curstart = 255, curend = 0,
-                   maxstart = 0, maxend = 0;
+               u_int8_t i, curstart, curend, maxstart, maxend;
+               curstart = curend = maxstart = maxend = 255;
                for (i = 0; i < 8; i++) {
                        if (!addr->addr16[i]) {
                                if (curstart == 255)
                                        curstart = i;
-                               else
-                                       curend = i;
+                               curend = i;
                        } else {
-                               if (curstart) {
-                                       if ((curend - curstart) >
-                                           (maxend - maxstart)) {
-                                               maxstart = curstart;
-                                               maxend = curend;
-                                               curstart = 255;
-                                       }
+                               if ((curend - curstart) >
+                                   (maxend - maxstart)) {
+                                       maxstart = curstart;
+                                       maxend = curend;
                                }
+                               curstart = curend = 255;
                        }
                }
+               if ((curend - curstart) >
+                   (maxend - maxstart)) {
+                       maxstart = curstart;
+                       maxend = curend;
+               }
                for (i = 0; i < 8; i++) {
                        if (i >= maxstart && i <= maxend) {
-                               if (maxend != 7) {
-                                       if (i == maxstart)
-                                               printf(":");
-                               } else {
-                                       if (i == maxend)
-                                               printf(":");
-                               }
+                               if (i == 0)
+                                       printf(":");
+                               if (i == maxend)
+                                       printf(":");
                        } else {
                                b = ntohs(addr->addr16[i]);
                                printf("%x", b);
@@ -1253,6 +1273,12 @@
        dir = s ? s->direction : 0;
 
        switch (proto) {
+       case IPPROTO_IPV4:
+               printf("IPv4");
+               break;
+       case IPPROTO_IPV6:
+               printf("IPv6");
+               break;
        case IPPROTO_TCP:
                printf("TCP");
                break;
@@ -1263,7 +1289,7 @@
                printf("ICMP");
                break;
        case IPPROTO_ICMPV6:
-               printf("ICMPV6");
+               printf("ICMPv6");
                break;
        default:
                printf("%u", skw->proto);
@@ -2706,6 +2732,16 @@
                default:
                        return (NULL);
                }
+               /* 
+                * Translation was a NOP.
+                * Pretend there was no match.
+                */
+               if (!bcmp(*skp, *nkp, sizeof(struct pf_state_key_cmp))) {
+                       pool_put(&pf_state_key_pl, *nkp);
+                       pool_put(&pf_state_key_pl, *skp);
+                       *skw = *sks = *nkp = *skp = NULL;
+                       return (NULL);
+               }
        }
 
        return (r);
@@ -2922,6 +2958,7 @@
 pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr)
 {
        struct pf_rule *r = s->rule.ptr;
+       struct pf_src_node *sn = NULL;
 
        s->rt_kif = NULL;
        if (!r->rt || r->rt == PF_FASTROUTE)
@@ -2929,15 +2966,13 @@
        switch (s->key[PF_SK_WIRE]->af) {
 #ifdef INET
        case AF_INET:
-               pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL,
-                   &s->nat_src_node);
+               pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, &sn);
                s->rt_kif = r->rpool.cur->kif;
                break;
 #endif /* INET */
 #ifdef INET6
        case AF_INET6:
-               pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL,
-                   &s->nat_src_node);
+               pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, &sn);
                s->rt_kif = r->rpool.cur->kif;
                break;
 #endif /* INET6 */
@@ -2995,7 +3030,6 @@
        int                      match = 0;
        int                      state_icmp = 0;
        u_int16_t                sport, dport;
-       u_int16_t                nport = 0, bport = 0;
        u_int16_t                bproto_sum = 0, bip_sum;
        u_int8_t                 icmptype = 0, icmpcode = 0;
 
@@ -3056,7 +3090,6 @@
 
        r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
 
-       bport = nport = sport;
        /* check packet for BINAT/NAT/RDR */
        if ((nr = pf_get_translation(pd, m, off, direction, kif, &nsn,
            &skw, &sks, &sk, &nk, saddr, daddr, sport, dport)) != NULL) {
@@ -3356,6 +3389,11 @@
                    bip_sum, hdrlen);
                if (action != PF_PASS)
                        return (action);
+       } else {
+               if (sk != NULL)
+                       pool_put(&pf_state_key_pl, sk);
+               if (nk != NULL)
+                       pool_put(&pf_state_key_pl, nk);
        }
 
        /* copy back packet headers if we performed NAT operations */
@@ -5061,6 +5099,12 @@
                break;
 #ifdef INET6
        case AF_INET6:
+               /*
+                * Skip check for addresses with embedded interface scope,
+                * as they would always match anyway.
+                */
+               if (IN6_IS_SCOPE_EMBED(&addr->v6))
+                       goto out;
                dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
                dst6->sin6_family = AF_INET6;
                dst6->sin6_len = sizeof(*dst6);
@@ -5284,14 +5328,13 @@
        }
 
        if (ntohs(ip->ip_len) <= ifp->if_mtu) {
+               ip->ip_sum = 0;
                if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) &&
                    ifp->if_bridge == NULL) {
                        m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT;
                        ipstat.ips_outhwcsum++;
-               } else {
-                       ip->ip_sum = 0;
+               } else
                        ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
-               }
                /* Update relevant hardware checksum stats for TCP/UDP */
                if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT)
                        tcpstat.tcps_outhwcsum++;
@@ -5361,7 +5404,6 @@
        struct ifnet            *ifp = NULL;
        struct pf_addr           naddr;
        struct pf_src_node      *sn = NULL;
-       int                      error = 0;
 
        if (m == NULL || *m == NULL || r == NULL ||
            (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
@@ -5444,7 +5486,7 @@
        if (IN6_IS_SCOPE_EMBED(&dst->sin6_addr))
                dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
        if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
-               error = nd6_output(ifp, ifp, m0, dst, NULL);
+               nd6_output(ifp, ifp, m0, dst, NULL);
        } else {
                in6_ifstat_inc(ifp, ifs6_in_toobig);
                if (r->rt != PF_DUPTO)
@@ -5688,7 +5730,7 @@
                action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
                    &reason);
                if (action == PF_PASS) {
-#if NPFSYNC
+#if NPFSYNC > 0
                        pfsync_update_state(s);
 #endif /* NPFSYNC */
                        r = s->rule.ptr;
@@ -5718,7 +5760,7 @@
                }
                action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
                if (action == PF_PASS) {
-#if NPFSYNC
+#if NPFSYNC > 0
                        pfsync_update_state(s);
 #endif /* NPFSYNC */
                        r = s->rule.ptr;
@@ -5742,7 +5784,7 @@
                action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd,
                    &reason);
                if (action == PF_PASS) {
-#if NPFSYNC
+#if NPFSYNC > 0
                        pfsync_update_state(s);
 #endif /* NPFSYNC */
                        r = s->rule.ptr;
@@ -5754,10 +5796,19 @@
                break;
        }
 
+#ifdef INET6
+       case IPPROTO_ICMPV6: {
+               action = PF_DROP;
+               DPFPRINTF(PF_DEBUG_MISC,
+                   ("pf: dropping IPv4 packet with ICMPv6 payload\n"));
+               goto done;
+       }
+#endif
+
        default:
                action = pf_test_state_other(&s, dir, kif, m, &pd);
                if (action == PF_PASS) {
-#if NPFSYNC
+#if NPFSYNC > 0
                        pfsync_update_state(s);
 #endif /* NPFSYNC */
                        r = s->rule.ptr;
@@ -6063,7 +6114,7 @@
                action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
                    &reason);
                if (action == PF_PASS) {
-#if NPFSYNC
+#if NPFSYNC > 0
                        pfsync_update_state(s);
 #endif /* NPFSYNC */
                        r = s->rule.ptr;
@@ -6093,7 +6144,7 @@
                }
                action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
                if (action == PF_PASS) {
-#if NPFSYNC
+#if NPFSYNC > 0
                        pfsync_update_state(s);
 #endif /* NPFSYNC */
                        r = s->rule.ptr;
@@ -6105,6 +6156,13 @@
                break;
        }
 
+       case IPPROTO_ICMP: {
+               action = PF_DROP;
+               DPFPRINTF(PF_DEBUG_MISC,
+                   ("pf: dropping IPv6 packet with ICMPv4 payload\n"));
+               goto done;
+       }
+
        case IPPROTO_ICMPV6: {
                struct icmp6_hdr        ih;
 
@@ -6117,7 +6175,7 @@
                action = pf_test_state_icmp(&s, dir, kif,
                    m, off, h, &pd, &reason);
                if (action == PF_PASS) {
-#if NPFSYNC
+#if NPFSYNC > 0
                        pfsync_update_state(s);
 #endif /* NPFSYNC */
                        r = s->rule.ptr;
@@ -6132,7 +6190,7 @@
        default:
                action = pf_test_state_other(&s, dir, kif, m, &pd);
                if (action == PF_PASS) {
-#if NPFSYNC
+#if NPFSYNC > 0
                        pfsync_update_state(s);
 #endif /* NPFSYNC */
                        r = s->rule.ptr;
Index: pf_if.c
===================================================================
RCS file: /cvs/src/sys/net/pf_if.c,v
retrieving revision 1.2
diff -u -r1.2 pf_if.c
--- pf_if.c     26 Dec 2008 18:51:52 -0000      1.2
+++ pf_if.c     21 May 2009 23:18:44 -0000
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2005 Henning Brauer <[email protected]>
  * Copyright 2005 Ryan McBride <[email protected]>
@@ -366,7 +365,7 @@
                goto _bad;
        }
 
-       if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname)) == NULL) {
+       if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname, 1)) == NULL) {
                rv = 1;
                goto _bad;
        }
Index: pf_ioctl.c
===================================================================
RCS file: /cvs/src/sys/net/pf_ioctl.c,v
retrieving revision 1.2
diff -u -r1.2 pf_ioctl.c
--- pf_ioctl.c  26 Dec 2008 18:51:52 -0000      1.2
+++ pf_ioctl.c  21 May 2009 23:18:47 -0000
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2001 Daniel Hartmeier
  * Copyright (c) 2002,2003 Henning Brauer
@@ -1163,7 +1162,7 @@
 
                if (rule->overload_tblname[0]) {
                        if ((rule->overload_tbl = pfr_attach_table(ruleset,
-                           rule->overload_tblname)) == NULL)
+                           rule->overload_tblname, 0)) == NULL)
                                error = EINVAL;
                        else
                                rule->overload_tbl->pfrkt_flags |=
@@ -1400,7 +1399,7 @@
 
                        if (newrule->overload_tblname[0]) {
                                if ((newrule->overload_tbl = pfr_attach_table(
-                                   ruleset, newrule->overload_tblname)) ==
+                                   ruleset, newrule->overload_tblname, 0)) ==
                                    NULL)
                                        error = EINVAL;
                                else
@@ -1488,7 +1487,7 @@
 
                        if (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname,
                            s->kif->pfik_name)) {
-#if NPFSYNC
+#if NPFSYNC > 0
                                /* don't send out individual delete messages */
                                s->sync_flags = PFSTATE_NOSYNC;
 #endif
@@ -1497,7 +1496,7 @@
                        }
                }
                psk->psk_killed = killed;
-#if NPFSYNC
+#if NPFSYNC > 0
                pfsync_clear_states(pf_status.hostid, psk->psk_ifname);
 #endif
                break;
Index: pf_norm.c
===================================================================
RCS file: /cvs/src/sys/net/pf_norm.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 pf_norm.c
--- pf_norm.c   26 Aug 2008 14:42:27 -0000      1.1.1.1
+++ pf_norm.c   21 May 2009 23:18:49 -0000
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2001 Niels Provos <[email protected]>
  * All rights reserved.
@@ -115,7 +114,11 @@
                            struct pf_fragment **, int, int, int *);
 int                     pf_normalize_tcpopt(struct pf_rule *, struct mbuf *,
                            struct tcphdr *, int, sa_family_t);
-
+void                    pf_scrub_ip(struct mbuf **, u_int32_t, u_int8_t,
+                           u_int8_t);
+#ifdef INET6
+void                    pf_scrub_ip6(struct mbuf **, u_int8_t);
+#endif
 #define        DPFPRINTF(x) do {                               \
        if (pf_status.debug >= PF_DEBUG_MISC) {         \
                printf("%s: ", __func__);               \
@@ -983,54 +986,11 @@
                h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
        }
 
-       /* Enforce a minimum ttl, may cause endless packet loops */
-       if (r->min_ttl && h->ip_ttl < r->min_ttl) {
-               u_int16_t ip_ttl = h->ip_ttl;
-
-               h->ip_ttl = r->min_ttl;
-               h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_ttl, h->ip_ttl, 0);
-       }
-
-       /* Enforce tos */
-       if (r->rule_flag & PFRULE_SET_TOS) {
-               u_int16_t       ov, nv;
-
-               ov = *(u_int16_t *)h;
-               h->ip_tos = r->set_tos;
-               nv = *(u_int16_t *)h;
-
-               h->ip_sum = pf_cksum_fixup(h->ip_sum, ov, nv, 0);
-       }
-
-       if (r->rule_flag & PFRULE_RANDOMID) {
-               u_int16_t ip_id = h->ip_id;
-
-               h->ip_id = ip_randomid();
-               h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_id, h->ip_id, 0);
-       }
-       if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0)
-               pd->flags |= PFDESC_IP_REAS;
-
-       return (PF_PASS);
+       /* not missing a return here */
 
  fragment_pass:
-       /* Enforce a minimum ttl, may cause endless packet loops */
-       if (r->min_ttl && h->ip_ttl < r->min_ttl) {
-               u_int16_t ip_ttl = h->ip_ttl;
+       pf_scrub_ip(&m, r->rule_flag, r->min_ttl, r->set_tos);
 
-               h->ip_ttl = r->min_ttl;
-               h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_ttl, h->ip_ttl, 0);
-       }
-       /* Enforce tos */
-       if (r->rule_flag & PFRULE_SET_TOS) {
-               u_int16_t       ov, nv;
-
-               ov = *(u_int16_t *)h;
-               h->ip_tos = r->set_tos;
-               nv = *(u_int16_t *)h;
-
-               h->ip_sum = pf_cksum_fixup(h->ip_sum, ov, nv, 0);
-       }
        if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0)
                pd->flags |= PFDESC_IP_REAS;
        return (PF_PASS);
@@ -1199,9 +1159,7 @@
        if (sizeof(struct ip6_hdr) + plen > m->m_pkthdr.len)
                goto shortpkt;
 
-       /* Enforce a minimum ttl, may cause endless packet loops */
-       if (r->min_ttl && h->ip6_hlim < r->min_ttl)
-               h->ip6_hlim = r->min_ttl;
+       pf_scrub_ip6(&m, r->min_ttl);
 
        return (PF_PASS);
 
@@ -1891,3 +1849,58 @@
 
        return (rewrite);
 }
+
+void
+pf_scrub_ip(struct mbuf **m0, u_int32_t flags, u_int8_t min_ttl, u_int8_t tos)
+{
+       struct mbuf             *m = *m0;
+       struct ip               *h = mtod(m, struct ip *);
+
+       /* Clear IP_DF if no-df was requested */
+       if (flags & PFRULE_NODF && h->ip_off & htons(IP_DF)) {
+               u_int16_t ip_off = h->ip_off;
+
+               h->ip_off &= htons(~IP_DF);
+               h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
+       }
+
+       /* Enforce a minimum ttl, may cause endless packet loops */
+       if (min_ttl && h->ip_ttl < min_ttl) {
+               u_int16_t ip_ttl = h->ip_ttl;
+
+               h->ip_ttl = min_ttl;
+               h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_ttl, h->ip_ttl, 0);
+       }
+
+       /* Enforce tos */
+       if (flags & PFRULE_SET_TOS) {
+               u_int16_t       ov, nv;
+
+               ov = *(u_int16_t *)h;
+               h->ip_tos = tos;
+               nv = *(u_int16_t *)h;
+
+               h->ip_sum = pf_cksum_fixup(h->ip_sum, ov, nv, 0);
+       }
+
+       /* random-id, but not for fragments */
+       if (flags & PFRULE_RANDOMID && !(h->ip_off & ~htons(IP_DF))) {
+               u_int16_t ip_id = h->ip_id;
+
+               h->ip_id = ip_randomid();
+               h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_id, h->ip_id, 0);
+       }
+}
+
+#ifdef INET6
+void
+pf_scrub_ip6(struct mbuf **m0, u_int8_t min_ttl)
+{
+       struct mbuf             *m = *m0;
+       struct ip6_hdr          *h = mtod(m, struct ip6_hdr *);
+
+       /* Enforce a minimum ttl, may cause endless packet loops */
+       if (min_ttl && h->ip6_hlim < min_ttl)
+               h->ip6_hlim = min_ttl;
+}
+#endif
Index: pf_osfp.c
===================================================================
RCS file: /cvs/src/sys/net/pf_osfp.c,v
retrieving revision 1.2
diff -u -r1.2 pf_osfp.c
--- pf_osfp.c   26 Dec 2008 18:51:52 -0000      1.2
+++ pf_osfp.c   21 May 2009 23:18:50 -0000
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2003 Mike Frantzen <[email protected]>
  *
Index: pf_ruleset.c
===================================================================
RCS file: /cvs/src/sys/net/pf_ruleset.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 pf_ruleset.c
--- pf_ruleset.c        26 Aug 2008 14:42:27 -0000      1.1.1.1
+++ pf_ruleset.c        21 May 2009 23:18:50 -0000
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2001 Daniel Hartmeier
  * Copyright (c) 2002,2003 Henning Brauer
@@ -58,7 +57,7 @@
 # define DPFPRINTF(format, x...)               \
        if (pf_status.debug >= PF_DEBUG_NOISY)  \
                printf(format , ##x)
-#define rs_malloc(x)           malloc(x, M_TEMP, M_WAITOK)
+#define rs_malloc(x)           malloc(x, M_TEMP, M_WAITOK|M_CANFAIL|M_ZERO)
 #define rs_free(x)             free(x, M_TEMP)
 
 #else
@@ -69,7 +68,7 @@
 # include <stdio.h>
 # include <stdlib.h>
 # include <string.h>
-# define rs_malloc(x)           malloc(x)
+# define rs_malloc(x)           calloc(1, x)
 # define rs_free(x)             free(x)
 
 # ifdef PFDEBUG
@@ -84,14 +83,6 @@
 struct pf_anchor_global         pf_anchors;
 struct pf_anchor        pf_main_anchor;
 
-int                     pf_get_ruleset_number(u_int8_t);
-void                    pf_init_ruleset(struct pf_ruleset *);
-int                     pf_anchor_setup(struct pf_rule *,
-                           const struct pf_ruleset *, const char *);
-int                     pf_anchor_copyout(const struct pf_ruleset *,
-                           const struct pf_rule *, struct pfioc_rule *);
-void                    pf_anchor_remove(struct pf_rule *);
-
 static __inline int pf_anchor_compare(struct pf_anchor *, struct pf_anchor *);
 
 RB_GENERATE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare);
@@ -155,7 +146,8 @@
        struct pf_anchor        *key, *found;
 
        key = (struct pf_anchor *)rs_malloc(sizeof(*key));
-       memset(key, 0, sizeof(*key));
+       if (key == NULL)
+               return (NULL);
        strlcpy(key->path, path, sizeof(key->path));
        found = RB_FIND(pf_anchor_global, &pf_anchors, key);
        rs_free(key);
@@ -193,7 +185,8 @@
        if (ruleset != NULL)
                return (ruleset);
        p = (char *)rs_malloc(MAXPATHLEN);
-       bzero(p, MAXPATHLEN);
+       if (p == NULL)
+               return (NULL);
        strlcpy(p, path, MAXPATHLEN);
        while (parent == NULL && (q = strrchr(p, '/')) != NULL) {
                *q = 0;
@@ -225,7 +218,6 @@
                        rs_free(p);
                        return (NULL);
                }
-               memset(anchor, 0, sizeof(*anchor));
                RB_INIT(&anchor->children);
                strlcpy(anchor->name, q, sizeof(anchor->name));
                if (parent != NULL) {
@@ -311,7 +303,8 @@
        if (!name[0])
                return (0);
        path = (char *)rs_malloc(MAXPATHLEN);
-       bzero(path, MAXPATHLEN);
+       if (path == NULL)
+               return (1);
        if (name[0] == '/')
                strlcpy(path, name + 1, MAXPATHLEN);
        else {
@@ -369,7 +362,8 @@
                int      i;
 
                a = (char *)rs_malloc(MAXPATHLEN);
-               bzero(a, MAXPATHLEN);
+               if (a == NULL)
+                       return (1);
                if (rs->anchor == NULL)
                        a[0] = 0;
                else
Index: pf_table.c
===================================================================
RCS file: /cvs/src/sys/net/pf_table.c,v
retrieving revision 1.2
diff -u -r1.2 pf_table.c
--- pf_table.c  26 Dec 2008 18:51:52 -0000      1.2
+++ pf_table.c  21 May 2009 23:18:53 -0000
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2002 Cedric Berger
  * All rights reserved.
@@ -125,7 +124,6 @@
 
 struct pool             pfr_ktable_pl;
 struct pool             pfr_kentry_pl;
-struct pool             pfr_kentry_pl2;
 struct pool             pfr_kcounters_pl;
 struct sockaddr_in      pfr_sin;
 struct sockaddr_in6     pfr_sin6;
@@ -166,7 +164,7 @@
 void                    pfr_clstats_ktables(struct pfr_ktableworkq *, long,
                            int);
 void                    pfr_clstats_ktable(struct pfr_ktable *, long, int);
-struct pfr_ktable      *pfr_create_ktable(struct pfr_table *, long, int);
+struct pfr_ktable      *pfr_create_ktable(struct pfr_table *, long, int, int);
 void                    pfr_destroy_ktables(struct pfr_ktableworkq *, int);
 void                    pfr_destroy_ktable(struct pfr_ktable *, int);
 int                     pfr_ktable_compare(struct pfr_ktable *,
@@ -193,8 +191,6 @@
            "pfrktable", NULL);
        pool_init(&pfr_kentry_pl, sizeof(struct pfr_kentry), 0, 0, 0,
            "pfrkentry", NULL);
-       pool_init(&pfr_kentry_pl2, sizeof(struct pfr_kentry), 0, 0, 0,
-           "pfrkentry2", NULL);
        pool_init(&pfr_kcounters_pl, sizeof(struct pfr_kcounters), 0, 0, 0,
            "pfrkcounters", NULL);
 
@@ -258,7 +254,8 @@
                return (ESRCH);
        if (kt->pfrkt_flags & PFR_TFLAG_CONST)
                return (EPERM);
-       tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0);
+       tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0,
+           !(flags & PFR_FLAG_USERIOCTL));
        if (tmpkt == NULL)
                return (ENOMEM);
        SLIST_INIT(&workq);
@@ -430,7 +427,8 @@
                return (ESRCH);
        if (kt->pfrkt_flags & PFR_TFLAG_CONST)
                return (EPERM);
-       tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0);
+       tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0,
+           !(flags & PFR_FLAG_USERIOCTL));
        if (tmpkt == NULL)
                return (ENOMEM);
        pfr_mark_addrs(kt);
@@ -810,7 +808,7 @@
        struct pfr_kentry       *ke;
 
        if (intr)
-               ke = pool_get(&pfr_kentry_pl2, PR_NOWAIT | PR_ZERO);
+               ke = pool_get(&pfr_kentry_pl, PR_NOWAIT | PR_ZERO);
        else
                ke = pool_get(&pfr_kentry_pl, PR_WAITOK|PR_ZERO|PR_LIMITFAIL);
        if (ke == NULL)
@@ -823,7 +821,6 @@
        ke->pfrke_af = ad->pfra_af;
        ke->pfrke_net = ad->pfra_net;
        ke->pfrke_not = ad->pfra_not;
-       ke->pfrke_intrpool = intr;
        return (ke);
 }
 
@@ -843,10 +840,7 @@
 {
        if (ke->pfrke_counters)
                pool_put(&pfr_kcounters_pl, ke->pfrke_counters);
-       if (ke->pfrke_intrpool)
-               pool_put(&pfr_kentry_pl2, ke);
-       else
-               pool_put(&pfr_kentry_pl, ke);
+       pool_put(&pfr_kentry_pl, ke);
 }
 
 void
@@ -1187,7 +1181,8 @@
                key.pfrkt_flags |= PFR_TFLAG_ACTIVE;
                p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
                if (p == NULL) {
-                       p = pfr_create_ktable(&key.pfrkt_t, tzero, 1);
+                       p = pfr_create_ktable(&key.pfrkt_t, tzero, 1,
+                           !(flags & PFR_FLAG_USERIOCTL));
                        if (p == NULL)
                                senderr(ENOMEM);
                        SLIST_FOREACH(q, &addq, pfrkt_workq) {
@@ -1213,7 +1208,8 @@
                                }
                        }
                        key.pfrkt_flags = 0;
-                       r = pfr_create_ktable(&key.pfrkt_t, 0, 1);
+                       r = pfr_create_ktable(&key.pfrkt_t, 0, 1,
+                           !(flags & PFR_FLAG_USERIOCTL));
                        if (r == NULL)
                                senderr(ENOMEM);
                        SLIST_INSERT_HEAD(&addq, r, pfrkt_workq);
@@ -1517,7 +1513,8 @@
        SLIST_INIT(&tableq);
        kt = RB_FIND(pfr_ktablehead, &pfr_ktables, (struct pfr_ktable *)tbl);
        if (kt == NULL) {
-               kt = pfr_create_ktable(tbl, 0, 1);
+               kt = pfr_create_ktable(tbl, 0, 1,
+                   !(flags & PFR_FLAG_USERIOCTL));
                if (kt == NULL)
                        return (ENOMEM);
                SLIST_INSERT_HEAD(&tableq, kt, pfrkt_workq);
@@ -1533,7 +1530,8 @@
                        kt->pfrkt_root = rt;
                        goto _skip;
                }
-               rt = pfr_create_ktable(&key.pfrkt_t, 0, 1);
+               rt = pfr_create_ktable(&key.pfrkt_t, 0, 1,
+                   !(flags & PFR_FLAG_USERIOCTL));
                if (rt == NULL) {
                        pfr_destroy_ktables(&tableq, 0);
                        return (ENOMEM);
@@ -1543,7 +1541,7 @@
        } else if (!(kt->pfrkt_flags & PFR_TFLAG_INACTIVE))
                xadd++;
 _skip:
-       shadow = pfr_create_ktable(tbl, 0, 0);
+       shadow = pfr_create_ktable(tbl, 0, 0, !(flags & PFR_FLAG_USERIOCTL));
        if (shadow == NULL) {
                pfr_destroy_ktables(&tableq, 0);
                return (ENOMEM);
@@ -1894,12 +1892,16 @@
 }
 
 struct pfr_ktable *
-pfr_create_ktable(struct pfr_table *tbl, long tzero, int attachruleset)
+pfr_create_ktable(struct pfr_table *tbl, long tzero, int attachruleset,
+    int intr)
 {
        struct pfr_ktable       *kt;
        struct pf_ruleset       *rs;
 
-       kt = pool_get(&pfr_ktable_pl, PR_WAITOK | PR_ZERO | PR_LIMITFAIL);
+       if (intr)
+               kt = pool_get(&pfr_ktable_pl, PR_NOWAIT|PR_ZERO|PR_LIMITFAIL);
+       else
+               kt = pool_get(&pfr_ktable_pl, PR_WAITOK|PR_ZERO|PR_LIMITFAIL);
        if (kt == NULL)
                return (NULL);
        kt->pfrkt_t = *tbl;
@@ -2066,7 +2068,7 @@
 }
 
 struct pfr_ktable *
-pfr_attach_table(struct pf_ruleset *rs, char *name)
+pfr_attach_table(struct pf_ruleset *rs, char *name, int intr)
 {
        struct pfr_ktable       *kt, *rt;
        struct pfr_table         tbl;
@@ -2078,14 +2080,14 @@
                strlcpy(tbl.pfrt_anchor, ac->path, sizeof(tbl.pfrt_anchor));
        kt = pfr_lookup_table(&tbl);
        if (kt == NULL) {
-               kt = pfr_create_ktable(&tbl, time_second, 1);
+               kt = pfr_create_ktable(&tbl, time_second, 1, intr);
                if (kt == NULL)
                        return (NULL);
                if (ac != NULL) {
                        bzero(tbl.pfrt_anchor, sizeof(tbl.pfrt_anchor));
                        rt = pfr_lookup_table(&tbl);
                        if (rt == NULL) {
-                               rt = pfr_create_ktable(&tbl, 0, 1);
+                               rt = pfr_create_ktable(&tbl, 0, 1, intr);
                                if (rt == NULL) {
                                        pfr_destroy_ktable(kt, 0);
                                        return (NULL);
Index: pfvar.h
===================================================================
RCS file: /cvs/src/sys/net/pfvar.h,v
retrieving revision 1.2
diff -u -r1.2 pfvar.h
--- pfvar.h     26 Dec 2008 18:51:53 -0000      1.2
+++ pfvar.h     21 May 2009 23:18:54 -0000
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2001 Daniel Hartmeier
  * All rights reserved.
@@ -1001,7 +1000,6 @@
        u_int8_t                 pfrke_net;
        u_int8_t                 pfrke_not;
        u_int8_t                 pfrke_mark;
-       u_int8_t                 pfrke_intrpool;
 };
 #define pfrke_counters u.pfrke_counters
 #define pfrke_route    u.pfrke_route
@@ -1692,7 +1690,7 @@
            struct pf_addr **, struct pf_addr **, sa_family_t);
 void   pfr_dynaddr_update(struct pfr_ktable *, struct pfi_dynaddr *);
 struct pfr_ktable *
-       pfr_attach_table(struct pf_ruleset *, char *);
+       pfr_attach_table(struct pf_ruleset *, char *, int);
 void   pfr_detach_table(struct pfr_ktable *);
 int    pfr_clr_tables(struct pfr_table *, int *, int);
 int    pfr_add_tables(struct pfr_table *, int, int *, int);

Reply via email to