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);