aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarren Reed <darrenr@FreeBSD.org>2007-10-18 21:42:51 +0000
committerDarren Reed <darrenr@FreeBSD.org>2007-10-18 21:42:51 +0000
commite8e48c1c7b41ecab29b107b5ee35cdea9fdc5c20 (patch)
tree244554a59fc24e7a35e6085f00a0f0ed67863bac
parent103b406762fd9664783670aae8479f3a8ec71c61 (diff)
downloadsrc-e8e48c1c7b41ecab29b107b5ee35cdea9fdc5c20.tar.gz
src-e8e48c1c7b41ecab29b107b5ee35cdea9fdc5c20.zip
Import IPFilter 4.1.28
Notes
Notes: svn path=/vendor-sys/ipfilter/dist/; revision=172771
-rw-r--r--sys/contrib/ipfilter/netinet/fil.c286
-rw-r--r--sys/contrib/ipfilter/netinet/ip_auth.c34
-rw-r--r--sys/contrib/ipfilter/netinet/ip_compat.h180
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil.h51
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil_freebsd.c283
-rw-r--r--sys/contrib/ipfilter/netinet/ip_frag.c18
-rw-r--r--sys/contrib/ipfilter/netinet/ip_htable.c90
-rw-r--r--sys/contrib/ipfilter/netinet/ip_log.c34
-rw-r--r--sys/contrib/ipfilter/netinet/ip_lookup.c50
-rw-r--r--sys/contrib/ipfilter/netinet/ip_lookup.h3
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.c254
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.h6
-rw-r--r--sys/contrib/ipfilter/netinet/ip_pool.c87
-rw-r--r--sys/contrib/ipfilter/netinet/ip_pool.h4
-rw-r--r--sys/contrib/ipfilter/netinet/ip_proxy.c10
-rw-r--r--sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c2
-rw-r--r--sys/contrib/ipfilter/netinet/ip_scan.c6
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.c172
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.h8
-rw-r--r--sys/contrib/ipfilter/netinet/ip_sync.c10
-rw-r--r--sys/contrib/ipfilter/netinet/ipl.h6
-rw-r--r--sys/contrib/ipfilter/netinet/mlfk_ipl.c9
22 files changed, 953 insertions, 650 deletions
diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c
index e2b6e92895d9..3183dd1fb852 100644
--- a/sys/contrib/ipfilter/netinet/fil.c
+++ b/sys/contrib/ipfilter/netinet/fil.c
@@ -80,7 +80,7 @@ struct file;
#ifdef sun
# include <net/af.h>
#endif
-#if !defined(_KERNEL) && defined(__FreeBSD__)
+#if !defined(_KERNEL) && (defined(__FreeBSD__) || defined(SOLARIS2))
# if (__FreeBSD_version >= 504000)
# undef _RADIX_H_
# endif
@@ -151,7 +151,7 @@ struct file;
#if !defined(lint)
static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: fil.c,v 2.243.2.109 2007/05/31 12:27:33 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: fil.c,v 2.243.2.125 2007/10/10 09:27:20 darrenr Exp $";
#endif
#ifndef _KERNEL
@@ -357,7 +357,7 @@ static INLINE int frpr_hopopts6 __P((fr_info_t *));
static INLINE int frpr_mobility6 __P((fr_info_t *));
static INLINE int frpr_routing6 __P((fr_info_t *));
static INLINE int frpr_dstopts6 __P((fr_info_t *));
-static INLINE void frpr_fragment6 __P((fr_info_t *));
+static INLINE int frpr_fragment6 __P((fr_info_t *));
static INLINE int frpr_ipv6exthdr __P((fr_info_t *, int, int));
@@ -475,8 +475,9 @@ fr_info_t *fin;
break;
case IPPROTO_FRAGMENT :
- frpr_fragment6(fin);
- go = 0;
+ p = frpr_fragment6(fin);
+ if (fin->fin_off != 0)
+ go = 0;
break;
default :
@@ -647,7 +648,7 @@ fr_info_t *fin;
/* ------------------------------------------------------------------------ */
/* Function: frpr_fragment6 */
-/* Returns: void */
+/* Returns: int - value of the next header or IPPROTO_NONE if error */
/* Parameters: fin(I) - pointer to packet information */
/* */
/* IPv6 Only */
@@ -659,7 +660,7 @@ fr_info_t *fin;
/* upper layer header has been seen (or where it ends) and thus we are not */
/* able to continue processing beyond this header with any confidence. */
/* ------------------------------------------------------------------------ */
-static INLINE void frpr_fragment6(fin)
+static INLINE int frpr_fragment6(fin)
fr_info_t *fin;
{
struct ip6_frag *frag;
@@ -668,12 +669,12 @@ fr_info_t *fin;
fin->fin_flx |= FI_FRAG;
if (frpr_ipv6exthdr(fin, 0, IPPROTO_FRAGMENT) == IPPROTO_NONE)
- return;
+ return IPPROTO_NONE;
extoff = (char *)fin->fin_exthdr - (char *)fin->fin_dp;
if (frpr_pullup(fin, sizeof(*frag)) == -1)
- return;
+ return IPPROTO_NONE;
fin->fin_exthdr = (char *)fin->fin_dp + extoff;
frag = fin->fin_exthdr;
@@ -682,16 +683,18 @@ fr_info_t *fin;
*/
if (frag->ip6f_offlg == 0) {
fin->fin_flx |= FI_BAD;
- return;
+ return IPPROTO_NONE;
}
- fin->fin_off = frag->ip6f_offlg & IP6F_OFF_MASK;
+ fin->fin_off = ntohs(frag->ip6f_offlg & IP6F_OFF_MASK);
fin->fin_off <<= 3;
if (fin->fin_off != 0)
fin->fin_flx |= FI_FRAGBODY;
fin->fin_dp = (char *)fin->fin_dp + sizeof(*frag);
fin->fin_dlen -= sizeof(*frag);
+
+ return frag->ip6f_nxt;
}
@@ -747,26 +750,26 @@ fr_info_t *fin;
case ICMP6_TIME_EXCEEDED :
case ICMP6_PARAM_PROB :
fin->fin_flx |= FI_ICMPERR;
- if ((fin->fin_m != NULL) &&
- (M_LEN(fin->fin_m) < fin->fin_plen)) {
+ minicmpsz = ICMP6ERR_IPICMPHLEN - sizeof(ip6_t);
+ if (fin->fin_plen < ICMP6ERR_IPICMPHLEN)
+ break;
+
+ if (M_LEN(fin->fin_m) < fin->fin_plen) {
if (fr_coalesce(fin) != 1)
return;
}
- if (frpr_pullup(fin, ICMP6ERR_MINPKTLEN) == -1)
- return;
-
/*
* If the destination of this packet doesn't match the
* source of the original packet then this packet is
* not correct.
*/
+ icmp6 = fin->fin_dp;
ip6 = (ip6_t *)((char *)icmp6 + ICMPERR_ICMPHLEN);
if (IP6_NEQ(&fin->fin_fi.fi_dst,
(i6addr_t *)&ip6->ip6_src))
fin->fin_flx |= FI_BAD;
- minicmpsz = ICMP6ERR_IPICMPHLEN - sizeof(ip6_t);
break;
default :
break;
@@ -907,6 +910,14 @@ fr_info_t *fin;
/* Short inline function to cut down on code duplication to perform a call */
/* to fr_pullup to ensure there is the required amount of data, */
/* consecutively in the packet buffer. */
+/* */
+/* This function pulls up 'extra' data at the location of fin_dp. fin_dp */
+/* points to the first byte after the complete layer 3 header, which will */
+/* include all of the known extension headers for IPv6 or options for IPv4. */
+/* */
+/* Since fr_pullup() expects the total length of bytes to be pulled up, it */
+/* is necessary to add those we can already assume to be pulled up (fin_dp */
+/* - fin_ip) to what is passed through. */
/* ------------------------------------------------------------------------ */
static INLINE int frpr_pullup(fin, plen)
fr_info_t *fin;
@@ -995,6 +1006,9 @@ fr_info_t *fin;
fin->fin_data[0] = *(u_short *)icmp;
+ if (fin->fin_dlen >= 6) /* ID field */
+ fin->fin_data[1] = icmp->icmp_id;
+
switch (icmp->icmp_type)
{
case ICMP_ECHOREPLY :
@@ -1065,14 +1079,12 @@ fr_info_t *fin;
default :
break;
}
-
- if (fin->fin_dlen >= 6) /* ID field */
- fin->fin_data[1] = icmp->icmp_id;
}
frpr_short(fin, minicmpsz);
- fr_checkv4sum(fin);
+ if ((fin->fin_flx & FI_FRAG) == 0)
+ fr_checkv4sum(fin);
}
@@ -1188,6 +1200,7 @@ fr_info_t *fin;
return -1;
#if 0
+ tcp = fin->fin_dp;
ip = fin->fin_ip;
s = (u_char *)(tcp + 1);
off = IP_HL(ip) << 2;
@@ -1275,8 +1288,10 @@ fr_info_t *fin;
frpr_short(fin, sizeof(tcphdr_t));
- if (frpr_tcpcommon(fin) == 0)
- fr_checkv4sum(fin);
+ if (frpr_tcpcommon(fin) == 0) {
+ if ((fin->fin_flx & FI_FRAG) == 0)
+ fr_checkv4sum(fin);
+ }
}
@@ -1294,8 +1309,10 @@ fr_info_t *fin;
frpr_short(fin, sizeof(udphdr_t));
- if (frpr_udpcommon(fin) == 0)
- fr_checkv4sum(fin);
+ if (frpr_udpcommon(fin) == 0) {
+ if ((fin->fin_flx & FI_FRAG) == 0)
+ fr_checkv4sum(fin);
+ }
}
@@ -1945,7 +1962,7 @@ int fr_scanlist(fin, pass)
fr_info_t *fin;
u_32_t pass;
{
- int rulen, portcmp, off, logged, skip;
+ int rulen, portcmp, off, skip;
struct frentry *fr, *fnext;
u_32_t passt, passo;
@@ -1964,7 +1981,6 @@ u_32_t pass;
return pass;
skip = 0;
- logged = 0;
portcmp = 0;
fin->fin_depth++;
fin->fin_fr = NULL;
@@ -2098,7 +2114,7 @@ u_32_t pass;
ATOMIC_INCL(frstats[fin->fin_out].fr_skip);
}
ATOMIC_INCL(frstats[fin->fin_out].fr_pkl);
- logged = 1;
+ fin->fin_flx |= FI_DONTCACHE;
}
#endif /* IPFILTER_LOG */
fr->fr_bytes += (U_QUAD_T)fin->fin_plen;
@@ -2123,8 +2139,6 @@ u_32_t pass;
fin->fin_fr = fr;
passt = pass;
}
- if (fin->fin_flx & FI_DONTCACHE)
- logged = 1;
pass = passt;
}
@@ -2152,8 +2166,6 @@ u_32_t pass;
break;
}
}
- if (logged)
- fin->fin_flx |= FI_DONTCACHE;
fin->fin_depth--;
return pass;
}
@@ -2404,8 +2416,10 @@ int out;
# ifdef MENTAT
qpktinfo_t *qpi = qif;
+# if !defined(_INET_IP_STACK_H)
if ((u_int)ip & 0x3)
return 2;
+# endif
# else
SPL_INT(s);
# endif
@@ -2558,11 +2572,20 @@ int out;
if (!out)
(void) fr_acctpkt(fin, NULL);
- if (fr == NULL)
- if ((fin->fin_flx & (FI_FRAG|FI_BAD)) == FI_FRAG)
+ if (fr == NULL) {
+ if ((fin->fin_flx & (FI_FRAG|FI_BAD)) == FI_FRAG) {
fr = fr_knownfrag(fin, &pass);
- if (fr == NULL)
- fr = fr_checkstate(fin, &pass);
+ /*
+ * Reset the keep state flag here so that we don't
+ * try and add a new state entry because of it, leading
+ * to a blocked packet because the add will fail.
+ */
+ if (fr != NULL)
+ pass &= ~FR_KEEPSTATE;
+ }
+ if (fr == NULL)
+ fr = fr_checkstate(fin, &pass);
+ }
if ((pass & FR_NOMATCH) || (fr == NULL))
fr = fr_firewall(fin, &pass);
@@ -2625,7 +2648,14 @@ filterdone:
}
if (fin->fin_nat != NULL) {
- fr_natderef((nat_t **)&fin->fin_nat);
+ if (FR_ISBLOCK(pass) && (fin->fin_flx & FI_NEWNAT)) {
+ WRITE_ENTER(&ipf_nat);
+ nat_delete((nat_t *)fin->fin_nat, NL_DESTROY);
+ RWLOCK_EXIT(&ipf_nat);
+ fin->fin_nat = NULL;
+ } else {
+ fr_natderef((nat_t **)&fin->fin_nat);
+ }
}
/*
@@ -3065,8 +3095,8 @@ void *l4hdr;
* In case we had to copy the IP & TCP header out of mbufs,
* skip over the mbuf bits which are the header
*/
- if ((caddr_t)ip != mtod(m, caddr_t)) {
- hlen = (caddr_t)sp - (caddr_t)ip;
+ if ((char *)ip != mtod(m, char *)) {
+ hlen = (char *)sp - (char *)ip;
while (hlen) {
add = MIN(hlen, m->m_len);
sp = (u_short *)(mtod(m, caddr_t) + add);
@@ -3089,12 +3119,12 @@ void *l4hdr;
goto nodata;
while (len > 1) {
- if (((caddr_t)sp - mtod(m, caddr_t)) >= m->m_len) {
+ if (((char *)sp - mtod(m, char *)) >= m->m_len) {
m = m->m_next;
PANIC((!m),("fr_cksum(2): not enough data"));
sp = mtod(m, u_short *);
}
- if (((caddr_t)(sp + 1) - mtod(m, caddr_t)) > m->m_len) {
+ if (((char *)(sp + 1) - mtod(m, char *)) > m->m_len) {
bytes.c[0] = *(u_char *)sp;
m = m->m_next;
PANIC((!m),("fr_cksum(3): not enough data"));
@@ -3172,7 +3202,7 @@ nodata:
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
- * $Id: fil.c,v 2.243.2.109 2007/05/31 12:27:33 darrenr Exp $
+ * $Id: fil.c,v 2.243.2.125 2007/10/10 09:27:20 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
@@ -3478,7 +3508,7 @@ minor_t unit;
int *nfreedp;
frentry_t **listp;
{
- int freed = 0, i;
+ int freed = 0;
frentry_t *fp;
while ((fp = *listp) != NULL) {
@@ -3489,8 +3519,7 @@ frentry_t **listp;
}
*listp = fp->fr_next;
if (fp->fr_grp != NULL) {
- i = frflushlist(set, unit, nfreedp, fp->fr_grp);
- fp->fr_ref -= i;
+ (void) frflushlist(set, unit, nfreedp, fp->fr_grp);
}
if (fp->fr_grhead != NULL) {
@@ -3846,7 +3875,7 @@ size_t size;
int error;
# if SOLARIS
- error = COPYIN(src, (caddr_t)&ca, sizeof(ca));
+ error = COPYIN(src, &ca, sizeof(ca));
if (error != 0)
return error;
# else
@@ -3888,22 +3917,27 @@ size_t size;
/* ------------------------------------------------------------------------ */
/* Function: fr_lock */
-/* Returns: (void) */
+/* Returns: int - 0 = success, else error */
/* Parameters: data(I) - pointer to lock value to set */
/* lockp(O) - pointer to location to store old lock value */
/* */
/* Get the new value for the lock integer, set it and return the old value */
/* in *lockp. */
/* ------------------------------------------------------------------------ */
-void fr_lock(data, lockp)
+int fr_lock(data, lockp)
caddr_t data;
int *lockp;
{
- int arg;
+ int arg, err;
- BCOPYIN(data, (caddr_t)&arg, sizeof(arg));
- BCOPYOUT((caddr_t)lockp, data, sizeof(*lockp));
+ err = BCOPYIN(data, &arg, sizeof(arg));
+ if (err != 0)
+ return EFAULT;
+ err = BCOPYOUT(lockp, data, sizeof(*lockp));
+ if (err != 0)
+ return EFAULT;
*lockp = arg;
+ return 0;
}
@@ -4542,7 +4576,7 @@ caddr_t data;
/*
* Return EBUSY if the rule is being reference by
- * something else (eg state information.
+ * something else (eg state information.)
*/
if (f->fr_ref > 1) {
error = EBUSY;
@@ -4553,8 +4587,6 @@ caddr_t data;
(f->fr_isc != (struct ipscan *)-1))
ipsc_detachfr(f);
#endif
- if ((fg != NULL) && (fg->fg_head != NULL))
- fg->fg_head->fr_ref--;
if (unit == IPL_LOGAUTH) {
error = fr_preauthcmd(req, f, ftail);
goto done;
@@ -4582,8 +4614,6 @@ caddr_t data;
} else
f = fp;
if (f != NULL) {
- if (fg != NULL && fg->fg_head != NULL)
- fg->fg_head->fr_ref++;
if (fp != f)
bcopy((char *)fp, (char *)f,
sizeof(*f));
@@ -4683,8 +4713,11 @@ int fr_resolvefunc(data)
void *data;
{
ipfunc_resolve_t res, *ft;
+ int err;
- BCOPYIN(data, &res, sizeof(res));
+ err = BCOPYIN(data, &res, sizeof(res));
+ if (err != 0)
+ return EFAULT;
if (res.ipfu_addr == NULL && res.ipfu_name[0] != '\0') {
for (ft = fr_availfuncs; ft->ipfu_addr != NULL; ft++)
@@ -5453,7 +5486,9 @@ int type;
if ((type < 0) || (type >= IPFOBJ_COUNT))
return EINVAL;
- BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj));
+ error = BCOPYIN(data, &obj, sizeof(obj));
+ if (error != 0)
+ return EFAULT;
if (obj.ipfo_type != type)
return EINVAL;
@@ -5479,11 +5514,9 @@ int type;
#endif
if ((fr_objbytes[type][0] & 1) != 0) {
- error = COPYIN((caddr_t)obj.ipfo_ptr, (caddr_t)ptr,
- fr_objbytes[type][1]);
+ error = COPYIN(obj.ipfo_ptr, ptr, fr_objbytes[type][1]);
} else {
- error = COPYIN((caddr_t)obj.ipfo_ptr, (caddr_t)ptr,
- obj.ipfo_size);
+ error = COPYIN(obj.ipfo_ptr, ptr, obj.ipfo_size);
}
if (error != 0)
error = EFAULT;
@@ -5518,7 +5551,9 @@ int type, sz;
if (((fr_objbytes[type][0] & 1) == 0) || (sz < fr_objbytes[type][1]))
return EINVAL;
- BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj));
+ error = BCOPYIN(data, &obj, sizeof(obj));
+ if (error != 0)
+ return EFAULT;
if (obj.ipfo_type != type)
return EINVAL;
@@ -5535,7 +5570,7 @@ int type, sz;
return EINVAL;
#endif
- error = COPYIN((caddr_t)obj.ipfo_ptr, (caddr_t)ptr, sz);
+ error = COPYIN(obj.ipfo_ptr, ptr, sz);
if (error != 0)
error = EFAULT;
return error;
@@ -5564,12 +5599,14 @@ int type, sz;
ipfobj_t obj;
int error;
- if ((type < 0) || (type > IPFOBJ_COUNT) ||
+ if ((type < 0) || (type >= IPFOBJ_COUNT) ||
((fr_objbytes[type][0] & 1) == 0) ||
(sz < fr_objbytes[type][1]))
return EINVAL;
- BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj));
+ error = BCOPYIN(data, &obj, sizeof(obj));
+ if (error != 0)
+ return EFAULT;
if (obj.ipfo_type != type)
return EINVAL;
@@ -5586,7 +5623,7 @@ int type, sz;
return EINVAL;
#endif
- error = COPYOUT((caddr_t)ptr, (caddr_t)obj.ipfo_ptr, sz);
+ error = COPYOUT(ptr, obj.ipfo_ptr, sz);
if (error != 0)
error = EFAULT;
return error;
@@ -5612,10 +5649,12 @@ int type;
ipfobj_t obj;
int error;
- if ((type < 0) || (type > IPFOBJ_COUNT))
+ if ((type < 0) || (type >= IPFOBJ_COUNT))
return EINVAL;
- BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj));
+ error = BCOPYIN(data, &obj, sizeof(obj));
+ if (error != 0)
+ return EFAULT;
if (obj.ipfo_type != type)
return EINVAL;
@@ -5639,7 +5678,7 @@ int type;
return EINVAL;
#endif
- error = COPYOUT((caddr_t)ptr, (caddr_t)obj.ipfo_ptr, obj.ipfo_size);
+ error = COPYOUT(ptr, obj.ipfo_ptr, obj.ipfo_size);
if (error != 0)
error = EFAULT;
return error;
@@ -5665,6 +5704,12 @@ fr_info_t *fin;
if ((fin->fin_flx & FI_NOCKSUM) != 0)
return 0;
+ if (fin->fin_cksum == 1)
+ return 0;
+
+ if (fin->fin_cksum == -1)
+ return -1;
+
/*
* If the TCP packet isn't a fragment, isn't too short and otherwise
* isn't already considered "bad", then validate the checksum. If
@@ -5727,8 +5772,11 @@ fr_info_t *fin;
FR_DEBUG(("checkl4sum: %hx != %hx\n", sum, hdrsum));
}
#endif
- if (hdrsum == sum)
+ if (hdrsum == sum) {
+ fin->fin_cksum = 1;
return 0;
+ }
+ fin->fin_cksum = -1;
return -1;
}
@@ -5981,7 +6029,7 @@ ipftuneable_t ipf_tuneables[] = {
{ { &ipf_hostmap_sz }, "ipf_hostmap_sz", 1, 0x7fffffff,
sizeof(ipf_hostmap_sz), IPFT_WRDISABLED, NULL },
{ { &fr_nat_maxbucket }, "fr_nat_maxbucket", 1, 0x7fffffff,
- sizeof(fr_nat_maxbucket), IPFT_WRDISABLED, NULL },
+ sizeof(fr_nat_maxbucket), 0, NULL },
{ { &fr_nat_maxbucket_reset }, "fr_nat_maxbucket_reset", 0, 1,
sizeof(fr_nat_maxbucket_reset), IPFT_WRDISABLED, NULL },
{ { &nat_logging }, "nat_logging", 0, 1,
@@ -6424,7 +6472,7 @@ void fr_deinitialise()
/* the copyout may result in paging (ie network activity.) */
/* ------------------------------------------------------------------------ */
int fr_zerostats(data)
-caddr_t data;
+void *data;
{
friostat_t fio;
int error;
@@ -6530,15 +6578,12 @@ ipftoken_t *ipftokenhead = NULL, **ipftokentail = &ipftokenhead;
void ipf_expiretokens()
{
ipftoken_t *it;
- void *data;
WRITE_ENTER(&ipf_tokens);
while ((it = ipftokenhead) != NULL) {
if (it->ipt_die > fr_ticks)
break;
- data = it->ipt_data;
-
ipf_freetoken(it);
}
RWLOCK_EXIT(&ipf_tokens);
@@ -6715,7 +6760,9 @@ ipftoken_t *token;
#endif
break;
case IPFGENITER_HOSTMAP :
+ WRITE_ENTER(&ipf_nat);
fr_hostmapdel((hostmap_t **)datap);
+ RWLOCK_EXIT(&ipf_nat);
break;
default :
#ifdef IPFILTER_LOOKUP
@@ -6794,30 +6841,27 @@ int ipf_getnextrule(ipftoken_t *t, void *ptr)
}
dst = (char *)it.iri_rule;
+ count = it.iri_nrules;
/*
* The ipfruleiter may ask for more than 1 rule at a time to be
* copied out, so long as that many exist in the list to start with!
*/
- for (count = it.iri_nrules; count > 0; count--) {
+ for (;;) {
if (next != NULL) {
- MUTEX_ENTER(&next->fr_lock);
- next->fr_ref++;
- MUTEX_EXIT(&next->fr_lock);
- t->ipt_data = next;
+ if (count == 1) {
+ MUTEX_ENTER(&next->fr_lock);
+ next->fr_ref++;
+ MUTEX_EXIT(&next->fr_lock);
+ t->ipt_data = next;
+ }
} else {
bzero(&zero, sizeof(zero));
next = &zero;
- ipf_freetoken(t);
- fr = NULL;
- t = NULL;
count = 1;
+ t->ipt_data = NULL;
}
RWLOCK_EXIT(&ipf_mutex);
- if (fr != NULL) {
- (void) fr_derefrule(&fr);
- }
-
error = COPYOUT(next, dst, sizeof(*next));
if (error != 0)
return EFAULT;
@@ -6831,12 +6875,17 @@ int ipf_getnextrule(ipftoken_t *t, void *ptr)
dst += next->fr_dsize;
}
- if ((count == 1) || (next->fr_next == NULL) || (error != 0))
+ if ((count == 1) || (error != 0))
break;
+ count--;
+
READ_ENTER(&ipf_mutex);
- fr = next;
- next = fr->fr_next;
+ next = next->fr_next;
+ }
+
+ if (fr != NULL) {
+ (void) fr_derefrule(&fr);
}
return error;
@@ -6964,8 +7013,7 @@ void *ctx;
if (!(mode & FWRITE))
error = EPERM;
else {
- error = BCOPYIN((caddr_t)data, (caddr_t)&tmp,
- sizeof(tmp));
+ error = BCOPYIN(data, &tmp, sizeof(tmp));
if (error != 0) {
error = EFAULT;
break;
@@ -7005,16 +7053,14 @@ void *ctx;
if (!(mode & FWRITE))
error = EPERM;
else {
- error = BCOPYIN((caddr_t)data, (caddr_t)&fr_flags,
- sizeof(fr_flags));
+ error = BCOPYIN(data, &fr_flags, sizeof(fr_flags));
if (error != 0)
error = EFAULT;
}
break;
case SIOCGETFF :
- error = BCOPYOUT((caddr_t)&fr_flags, (caddr_t)data,
- sizeof(fr_flags));
+ error = BCOPYOUT(&fr_flags, data, sizeof(fr_flags));
if (error != 0)
error = EFAULT;
break;
@@ -7030,8 +7076,7 @@ void *ctx;
if (!(mode & FWRITE))
error = EPERM;
else
- error = frrequest(IPL_LOGIPF, cmd, (caddr_t)data,
- fr_active, 1);
+ error = frrequest(IPL_LOGIPF, cmd, data, fr_active, 1);
break;
case SIOCINIFR :
@@ -7040,7 +7085,7 @@ void *ctx;
if (!(mode & FWRITE))
error = EPERM;
else
- error = frrequest(IPL_LOGIPF, cmd, (caddr_t)data,
+ error = frrequest(IPL_LOGIPF, cmd, data,
1 - fr_active, 1);
break;
@@ -7050,8 +7095,7 @@ void *ctx;
else {
WRITE_ENTER(&ipf_mutex);
bzero((char *)frcache, sizeof(frcache[0]) * 2);
- error = BCOPYOUT((caddr_t)&fr_active, (caddr_t)data,
- sizeof(fr_active));
+ error = BCOPYOUT(&fr_active, data, sizeof(fr_active));
if (error != 0)
error = EFAULT;
else
@@ -7069,19 +7113,17 @@ void *ctx;
if (!(mode & FWRITE))
error = EPERM;
else
- error = fr_zerostats((caddr_t)data);
+ error = fr_zerostats(data);
break;
case SIOCIPFFL :
if (!(mode & FWRITE))
error = EPERM;
else {
- error = BCOPYIN((caddr_t)data, (caddr_t)&tmp,
- sizeof(tmp));
+ error = BCOPYIN(data, &tmp, sizeof(tmp));
if (!error) {
tmp = frflush(IPL_LOGIPF, 4, tmp);
- error = BCOPYOUT((caddr_t)&tmp, (caddr_t)data,
- sizeof(tmp));
+ error = BCOPYOUT(&tmp, data, sizeof(tmp));
if (error != 0)
error = EFAULT;
} else
@@ -7094,12 +7136,10 @@ void *ctx;
if (!(mode & FWRITE))
error = EPERM;
else {
- error = BCOPYIN((caddr_t)data, (caddr_t)&tmp,
- sizeof(tmp));
+ error = BCOPYIN(data, &tmp, sizeof(tmp));
if (!error) {
tmp = frflush(IPL_LOGIPF, 6, tmp);
- error = BCOPYOUT((caddr_t)&tmp, (caddr_t)data,
- sizeof(tmp));
+ error = BCOPYOUT(&tmp, data, sizeof(tmp));
if (error != 0)
error = EFAULT;
} else
@@ -7109,7 +7149,7 @@ void *ctx;
#endif
case SIOCSTLCK :
- error = BCOPYIN((caddr_t)data, (caddr_t)&tmp, sizeof(tmp));
+ error = BCOPYIN(data, &tmp, sizeof(tmp));
if (error == 0) {
fr_state_lock = tmp;
fr_nat_lock = tmp;
@@ -7125,8 +7165,7 @@ void *ctx;
error = EPERM;
else {
tmp = ipflog_clear(IPL_LOGIPF);
- error = BCOPYOUT((caddr_t)&tmp, (caddr_t)data,
- sizeof(tmp));
+ error = BCOPYOUT(&tmp, data, sizeof(tmp));
if (error)
error = EFAULT;
}
@@ -7158,7 +7197,7 @@ void *ctx;
case FIONREAD :
tmp = (int)iplused[IPL_LOGIPF];
- error = BCOPYOUT((caddr_t)&tmp, (caddr_t)data, sizeof(tmp));
+ error = BCOPYOUT(&tmp, data, sizeof(tmp));
break;
#endif
@@ -7173,16 +7212,14 @@ void *ctx;
error = ipf_genericiter(data, uid, ctx);
SPL_X(s);
break;
- break;
case SIOCIPFDELTOK :
SPL_SCHED(s);
- error = BCOPYIN((caddr_t)data, (caddr_t)&tmp, sizeof(tmp));
+ error = BCOPYIN(data, &tmp, sizeof(tmp));
if (error == 0)
error = ipf_deltoken(tmp, uid, ctx);
SPL_X(s);
break;
- break;
default :
error = EINVAL;
@@ -7258,15 +7295,16 @@ ipftq_t *ipfqs, *userqs;
return 0;
}
if (istart > fr_ticks) {
- istart = (fr_ticks / interval) * interval;
+ if (fr_ticks - interval < interval)
+ istart = interval;
+ else
+ istart = (fr_ticks / interval) * interval;
}
iend = fr_ticks - interval;
- if (istart > iend)
- istart = iend - interval;
removed = 0;
- while (removed == 0) {
+ for (;;) {
u_long try;
try = fr_ticks - istart;
@@ -7293,8 +7331,9 @@ ipftq_t *ipfqs, *userqs;
}
}
- istart -= interval;
if (try >= iend) {
+ if (removed > 0)
+ break;
if (interval == IPF_TTLVAL(43200)) {
interval = IPF_TTLVAL(1800);
} else if (interval == IPF_TTLVAL(1800)) {
@@ -7307,6 +7346,7 @@ ipftq_t *ipfqs, *userqs;
iend = fr_ticks - interval;
}
+ istart -= interval;
}
return removed;
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c
index 50d6b953687e..11bd07bafa27 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.c
+++ b/sys/contrib/ipfilter/netinet/ip_auth.c
@@ -117,7 +117,7 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.73.2.20 2007/05/29 13:48:54 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.73.2.24 2007/09/09 11:32:04 darrenr Exp $";
#endif
@@ -324,16 +324,10 @@ fr_info_t *fin;
return 0;
WRITE_ENTER(&ipf_auth);
- if (fr_authstart > fr_authend) {
+ if (((fr_authend + 1) % fr_authsize) == fr_authstart) {
fr_authstats.fas_nospace++;
RWLOCK_EXIT(&ipf_auth);
return 0;
- } else {
- if (fr_authused == fr_authsize) {
- fr_authstats.fas_nospace++;
- RWLOCK_EXIT(&ipf_auth);
- return 0;
- }
}
fr_authstats.fas_added++;
@@ -370,10 +364,12 @@ fr_info_t *fin;
}
#endif
#if SOLARIS && defined(_KERNEL)
- COPYIFNAME(fin->fin_ifp, fra->fra_info.fin_ifname);
+ COPYIFNAME(fin->fin_v, fin->fin_ifp, fra->fra_info.fin_ifname);
m->b_rptr -= qpi->qpi_off;
fr_authpkts[i] = *(mblk_t **)fin->fin_mp;
+# if !defined(_INET_IP_STACK_H)
fra->fra_q = qpi->qpi_q; /* The queue can disappear! */
+# endif
fra->fra_m = *fin->fin_mp;
fra->fra_info.fin_mp = &fra->fra_m;
cv_signal(&ipfauthwait);
@@ -444,7 +440,7 @@ void *ctx;
error = EPERM;
break;
}
- fr_lock(data, &fr_auth_lock);
+ error = fr_lock(data, &fr_auth_lock);
break;
case SIOCATHST:
@@ -712,15 +708,15 @@ int fr_authflush()
/* ------------------------------------------------------------------------ */
/* Function: fr_auth_waiting */
-/* Returns: int - number of packets in the auth queue */
+/* Returns: int - 0 = no pakcets wiating, 1 = packets waiting. */
/* Parameters: None */
/* */
-/* Returns the numbers of packets queued up, waiting to be processed with */
-/* a pair of SIOCAUTHW and SIOCAUTHR calls. */
+/* Simple truth check to see if there are any packets waiting in the auth */
+/* queue. */
/* ------------------------------------------------------------------------ */
int fr_auth_waiting()
{
- return (fr_authnext != fr_authend) && fr_authpkts[fr_authnext];
+ return (fr_authused != 0);
}
@@ -857,7 +853,13 @@ fr_authioctlloop:
* is a packet waiting to be delt with in the fr_authpkts array. We
* copy as much of that out to user space as requested.
*/
- if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) {
+ if (fr_authused > 0) {
+ while (fr_authpkts[fr_authnext] == NULL) {
+ fr_authnext++;
+ if (fr_authnext == fr_authsize)
+ fr_authnext = 0;
+ }
+
error = fr_outobj(data, &fr_auth[fr_authnext], IPFOBJ_FRAUTH);
if (error != 0)
return error;
@@ -884,8 +886,6 @@ fr_authioctlloop:
}
}
RWLOCK_EXIT(&ipf_auth);
- if (error != 0)
- return error;
SPL_NET(s);
WRITE_ENTER(&ipf_auth);
diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h
index 5dc1d442ea26..901d21b3ea09 100644
--- a/sys/contrib/ipfilter/netinet/ip_compat.h
+++ b/sys/contrib/ipfilter/netinet/ip_compat.h
@@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_compat.h 1.8 1/14/96
- * $Id: ip_compat.h,v 2.142.2.48 2007/05/31 12:27:34 darrenr Exp $
+ * $Id: ip_compat.h,v 2.142.2.57 2007/10/10 09:51:42 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@@ -168,6 +168,11 @@ struct file;
# ifdef i386
# define _SYS_PROMIF_H
# endif
+# ifndef _KERNEL
+# include "radix_ipf.h"
+# else
+# include "radix_ipf_local.h"
+# endif
# include <inet/ip.h>
# undef COPYOUT
# include <inet/ip_ire.h>
@@ -200,8 +205,28 @@ typedef unsigned int u_32_t;
# ifdef _KERNEL
# define KRWLOCK_T krwlock_t
# define KMUTEX_T kmutex_t
-# include "qif.h"
-# include "pfil.h"
+
+# if !defined(FW_HOOKS)
+# include "qif.h"
+# include "pfil.h"
+# else
+# include <sys/neti.h>
+
+extern net_data_t ipfipv4;
+extern net_data_t ipfipv6;
+
+typedef struct qpktinfo {
+ void *qpi_data;
+ mblk_t **qpi_mp;
+ mblk_t *qpi_m;
+ uintptr_t qpi_real;
+ int qpi_flags;
+ int qpi_num;
+ int qpi_off;
+} qpktinfo_t;
+# define QF_GROUP 0x01
+# endif
+
# if SOLARIS2 >= 6
# if SOLARIS2 == 6
# define ATOMIC_INCL(x) atomic_add_long((uint32_t*)&(x), 1)
@@ -259,10 +284,24 @@ typedef unsigned int u_32_t;
# define GET_MINOR(x) getminor(x)
extern void *get_unit __P((char *, int));
# define GETIFP(n, v) get_unit(n, v)
-# define IFNAME(x) ((qif_t *)x)->qf_name
-# define COPYIFNAME(x, b) \
+# if defined(_INET_IP_STACK_H)
+# define COPYIFNAME(v, x, b) \
+ do { \
+ if ((v) == 4) { \
+ (void) net_getifname(ipfipv4,\
+ (uintptr_t)x, b, \
+ LIFNAMSIZ); \
+ } else { \
+ (void) net_getifname(ipfipv6,\
+ (uintptr_t)x, b, \
+ LIFNAMSIZ); \
+ } \
+ } while (0)
+# else
+# define COPYIFNAME(v, x, b) \
(void) strncpy(b, ((qif_t *)x)->qf_name, \
LIFNAMSIZ)
+# endif
# define GETKTIME(x) uniqtime((struct timeval *)x)
# define MSGDSIZE(x) msgdsize(x)
# define M_LEN(x) ((x)->b_wptr - (x)->b_rptr)
@@ -271,7 +310,11 @@ extern void *get_unit __P((char *, int));
# define MTYPE(m) ((m)->b_datap->db_type)
# define FREE_MB_T(m) freemsg(m)
# define m_next b_cont
-# define CACHE_HASH(x) (((qpktinfo_t *)(x)->fin_qpi)->qpi_num & 7)
+# if !defined(_INET_IP_STACK_H)
+# define CACHE_HASH(x) (((qpktinfo_t *)(x)->fin_qpi)->qpi_num & 7)
+# else
+# define CACHE_HASH(x) ((uintptr_t)(x)->fin_ifp & 7)
+# endif
# define IPF_PANIC(x,y) if (x) { printf y; cmn_err(CE_PANIC, "ipf_panic"); }
typedef mblk_t mb_t;
# endif /* _KERNEL */
@@ -423,8 +466,7 @@ typedef struct iplog_select_s {
# define SPL_X(x) ;
extern void *get_unit __P((char *, int));
# define GETIFP(n, v) get_unit(n, v)
-# define IFNAME(x, b) ((ill_t *)x)->ill_name
-# define COPYIFNAME(x, b) \
+# define COPYIFNAME(v, x, b) \
(void) strncpy(b, ((qif_t *)x)->qf_name, \
LIFNAMSIZ)
# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
@@ -592,6 +634,7 @@ extern void m_copyback __P((struct mbuf *, int, int, caddr_t));
# define M_LEN(x) (x)->m_len
# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL)
# define GETKTIME(x) microtime((struct timeval *)x)
+# define IFNAME(x) ((struct ifnet *)x)->if_name
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); }
@@ -668,6 +711,7 @@ typedef struct mbuf mb_t;
# define M_LEN(x) (x)->m_len
# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL)
# define GETKTIME(x) microtime((struct timeval *)x)
+# define IFNAME(x) ((struct ifnet *)x)->if_name
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); }
@@ -751,12 +795,13 @@ typedef struct mbuf mb_t;
# endif /* _KERNEL */
# if (NetBSD <= 1991011) && (NetBSD >= 199606)
# define IFNAME(x) ((struct ifnet *)x)->if_xname
-# define COPYIFNAME(x, b) \
+# define COPYIFNAME(v, x, b) \
(void) strncpy(b, \
((struct ifnet *)x)->if_xname, \
LIFNAMSIZ)
# define CACHE_HASH(x) ((((struct ifnet *)fin->fin_ifp)->if_index)&7)
# else
+# define IFNAME(x) ((struct ifnet *)x)->if_name
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# endif
@@ -809,24 +854,66 @@ typedef u_int32_t u_32_t;
# if (__FreeBSD_version >= 500043)
# include <sys/mutex.h>
-# include <sys/sx.h>
+# if (__FreeBSD_version > 700014)
+# include <sys/rwlock.h>
+# define KRWLOCK_T struct rwlock
+# ifdef _KERNEL
+# define READ_ENTER(x) rw_rlock(&(x)->ipf_lk)
+# define WRITE_ENTER(x) rw_wlock(&(x)->ipf_lk)
+# define MUTEX_DOWNGRADE(x) rw_downgrade(&(x)->ipf_lk)
+# define RWLOCK_INIT(x, y) rw_init(&(x)->ipf_lk, (y))
+# define RW_DESTROY(x) rw_destroy(&(x)->ipf_lk)
+# define RWLOCK_EXIT(x) do { \
+ if (rw_wowned(&(x)->ipf_lk)) \
+ rw_wunlock(&(x)->ipf_lk); \
+ else \
+ rw_runlock(&(x)->ipf_lk); \
+ } while (0)
+# endif
+# else
+# include <sys/sx.h>
/*
* Whilst the sx(9) locks on FreeBSD have the right semantics and interface
* for what we want to use them for, despite testing showing they work -
* with a WITNESS kernel, it generates LOR messages.
*/
-# define KMUTEX_T struct mtx
-# if (__FreeBSD_version < 700000)
-# define KRWLOCK_T struct mtx
-# else
-# define KRWLOCK_T struct sx
+# ifdef _KERNEL
+# if (__FreeBSD_version < 700000)
+# define KRWLOCK_T struct mtx
+# define READ_ENTER(x) mtx_lock(&(x)->ipf_lk)
+# define WRITE_ENTER(x) mtx_lock(&(x)->ipf_lk)
+# define RWLOCK_EXIT(x) mtx_unlock(&(x)->ipf_lk)
+# define MUTEX_DOWNGRADE(x) ;
+# define RWLOCK_INIT(x,y) mtx_init(&(x)->ipf_lk, (y), NULL,\
+ MTX_DEF)
+# define RW_DESTROY(x) mtx_destroy(&(x)->ipf_lk)
+# else
+# define KRWLOCK_T struct sx
+# define READ_ENTER(x) sx_slock(&(x)->ipf_lk)
+# define WRITE_ENTER(x) sx_xlock(&(x)->ipf_lk)
+# define MUTEX_DOWNGRADE(x) sx_downgrade(&(x)->ipf_lk)
+# define RWLOCK_INIT(x, y) sx_init(&(x)->ipf_lk, (y))
+# define RW_DESTROY(x) sx_destroy(&(x)->ipf_lk)
+# ifdef sx_unlock
+# define RWLOCK_EXIT(x) sx_unlock(&(x)->ipf_lk)
+# else
+# define RWLOCK_EXIT(x) do { \
+ if ((x)->ipf_lk.sx_cnt < 0) \
+ sx_xunlock(&(x)->ipf_lk); \
+ else \
+ sx_sunlock(&(x)->ipf_lk); \
+ } while (0)
+# endif
+# endif
+# endif
# endif
+# define KMUTEX_T struct mtx
# endif
# if (__FreeBSD_version >= 501113)
# include <net/if_var.h>
# define IFNAME(x) ((struct ifnet *)x)->if_xname
-# define COPYIFNAME(x, b) \
+# define COPYIFNAME(v, x, b) \
(void) strncpy(b, \
((struct ifnet *)x)->if_xname, \
LIFNAMSIZ)
@@ -834,6 +921,7 @@ typedef u_int32_t u_32_t;
# if (__FreeBSD_version >= 500043)
# define CACHE_HASH(x) ((((struct ifnet *)fin->fin_ifp)->if_index) & 7)
# else
+# define IFNAME(x) ((struct ifnet *)x)->if_name
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# endif
@@ -855,36 +943,6 @@ typedef u_int32_t u_32_t;
MTX_DEF)
# define MUTEX_DESTROY(x) mtx_destroy(&(x)->ipf_lk)
# define MUTEX_NUKE(x) bzero((x), sizeof(*(x)))
-/*
- * Whilst the sx(9) locks on FreeBSD have the right semantics and interface
- * for what we want to use them for, despite testing showing they work -
- * with a WITNESS kernel, it generates LOR messages.
- */
-# if (__FreeBSD_version < 700000)
-# define READ_ENTER(x) mtx_lock(&(x)->ipf_lk)
-# define WRITE_ENTER(x) mtx_lock(&(x)->ipf_lk)
-# define RWLOCK_EXIT(x) mtx_unlock(&(x)->ipf_lk)
-# define MUTEX_DOWNGRADE(x) ;
-# define RWLOCK_INIT(x,y) mtx_init(&(x)->ipf_lk, (y), NULL,\
- MTX_DEF)
-# define RW_DESTROY(x) mtx_destroy(&(x)->ipf_lk)
-# else
-# define READ_ENTER(x) sx_slock(&(x)->ipf_lk)
-# define WRITE_ENTER(x) sx_xlock(&(x)->ipf_lk)
-# define MUTEX_DOWNGRADE(x) sx_downgrade(&(x)->ipf_lk)
-# define RWLOCK_INIT(x, y) sx_init(&(x)->ipf_lk, (y))
-# define RW_DESTROY(x) sx_destroy(&(x)->ipf_lk)
-# ifdef sx_unlock
-# define RWLOCK_EXIT(x) sx_unlock(&(x)->ipf_lk)
-# else
-# define RWLOCK_EXIT(x) do { \
- if ((x)->ipf_lk.sx_cnt < 0) \
- sx_xunlock(&(x)->ipf_lk); \
- else \
- sx_sunlock(&(x)->ipf_lk); \
- } while (0)
-# endif
-# endif
# include <machine/atomic.h>
# define ATOMIC_INC(x) { mtx_lock(&ipf_rw.ipf_lk); (x)++; \
mtx_unlock(&ipf_rw.ipf_lk); }
@@ -903,6 +961,8 @@ typedef u_int32_t u_32_t;
# define SPL_IMP(x) ;
# define SPL_SCHED(x) ;
extern int in_cksum __P((struct mbuf *, int));
+# else
+# define SPL_SCHED(x) x = splhigh()
# endif /* __FreeBSD_version >= 500043 */
# define MSGDSIZE(x) mbufchainlen(x)
# define M_LEN(x) (x)->m_len
@@ -968,12 +1028,13 @@ typedef struct mbuf mb_t;
# endif /* _KERNEL */
# if (OpenBSD >= 199603)
# define IFNAME(x, b) ((struct ifnet *)x)->if_xname
-# define COPYIFNAME(x, b) \
+# define COPYIFNAME(v, x, b) \
(void) strncpy(b, \
((struct ifnet *)x)->if_xname, \
LIFNAMSIZ)
# define CACHE_HASH(x) ((((struct ifnet *)fin->fin_ifp)->if_index)&7)
# else
+# define IFNAME(x, b) ((struct ifnet *)x)->if_name
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# endif
@@ -1001,6 +1062,7 @@ typedef u_int32_t u_32_t;
# define MSGDSIZE(x) mbufchainlen(x)
# define M_LEN(x) (x)->m_len
# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL)
+# define IFNAME(x, b) ((struct ifnet *)x)->if_name
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
typedef struct mbuf mb_t;
@@ -1027,6 +1089,7 @@ typedef u_int32_t u_32_t;
# define MSGDSIZE(x) mbufchainlen(x)
# define M_LEN(x) (x)->m_len
# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL)
+# define IFNAME(x, b) ((struct ifnet *)x)->if_name
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# define GETIFP(n, v) ifunit(n, IFNAMSIZ)
@@ -1084,7 +1147,7 @@ struct ip6_ext {
# define SLEEP(x,s) 0, interruptible_sleep_on(x##_linux)
# endif
# define WAKEUP(x,y) wake_up(x##_linux + y)
-# define UIOMOVE(a,b,c,d) uiomove(a,b,c,d)
+# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
# define USE_MUTEXES
# define KRWLOCK_T rwlock_t
# define KMUTEX_T spinlock_t
@@ -1178,7 +1241,7 @@ struct ifnet {
# endif /* _KERNEL */
-# define COPYIFNAME(x, b) \
+# define COPYIFNAME(v, x, b) \
(void) strncpy(b, \
((struct ifnet *)x)->if_xname, \
LIFNAMSIZ)
@@ -1288,6 +1351,7 @@ extern void* getifp __P((char *, int));
# define M_LEN(x) (x)->m_len
# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL)
# define GETKTIME(x)
+# define IFNAME(x, b) ((struct ifnet *)x)->if_name
# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \
((struct ifnet *)fin->fin_ifp)->if_unit) & 7)
# define IPF_PANIC(x,y)
@@ -1459,7 +1523,7 @@ typedef struct mb_s {
# define COPYBACK(m, o, l, b) bcopy((b), \
MTOD((mb_t *)m, char *) + (o), \
(l))
-# define UIOMOVE(a,b,c,d) ipfuiomove(a,b,c,d)
+# define UIOMOVE(a,b,c,d) ipfuiomove((caddr_t)a,b,c,d)
extern void m_copydata __P((mb_t *, int, int, caddr_t));
extern int ipfuiomove __P((caddr_t, int, int, struct uio *));
extern int bcopywrap __P((void *, void *, size_t));
@@ -1589,7 +1653,7 @@ MALLOC_DECLARE(M_IPFILTER);
# endif
# define KFREE(x) FREE((x), _M_IPF)
# define KFREES(x,s) FREE((x), _M_IPF)
-# define UIOMOVE(a,b,c,d) uiomove(a,b,d)
+# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,d)
# define SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0)
# define WAKEUP(id,x) wakeup(id+x)
# define POLLWAKEUP(x) selwakeup(ipfselwait+x)
@@ -1604,7 +1668,9 @@ MALLOC_DECLARE(M_IPFILTER);
# define SPL_IMP(x) x = splimp()
# define SPL_NET(x) x = splnet()
# endif /* NetBSD && (NetBSD <= 1991011) && (NetBSD >= 199407) */
-# define SPL_SCHED(x) x = splsched()
+# if !defined(SPL_SCHED)
+# define SPL_SCHED(x) x = splsched()
+# endif
# define SPL_X(x) (void) splx(x)
# endif /* !USE_MUTEXES */
@@ -1633,18 +1699,22 @@ MALLOC_DECLARE(M_IPFILTER);
# define PANIC(x,y) if (x) panic y
#endif /* _KERNEL */
-#ifndef IFNAME
+#if !defined(IFNAME) && !defined(_KERNEL)
# define IFNAME(x) ((struct ifnet *)x)->if_name
#endif
#ifndef COPYIFNAME
# define NEED_FRGETIFNAME
extern char *fr_getifname __P((struct ifnet *, char *));
-# define COPYIFNAME(x, b) \
+# define COPYIFNAME(v, x, b) \
fr_getifname((struct ifnet *)x, b)
#endif
#ifndef ASSERT
-# define ASSERT(x)
+# ifdef _KERNEL
+# define ASSERT(x)
+# else
+# define ASSERT(x) do { if (!(x)) abort(); } while (0)
+# endif
#endif
#ifndef BCOPYIN
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.h b/sys/contrib/ipfilter/netinet/ip_fil.h
index da710c1d21a7..8236cef27f29 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.h
+++ b/sys/contrib/ipfilter/netinet/ip_fil.h
@@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_fil.h 1.35 6/5/96
- * $Id: ip_fil.h,v 2.170.2.45 2007/05/28 11:56:22 darrenr Exp $
+ * $Id: ip_fil.h,v 2.170.2.51 2007/10/10 09:48:03 darrenr Exp $
*/
#ifndef __IP_FIL_H__
@@ -156,14 +156,14 @@ typedef union i6addr {
#define iplookupptr vptr[0]
#define iplookupfunc lptr[1]
-#define I60(x) (((i6addr_t *)(x))->i6[0])
-#define I61(x) (((i6addr_t *)(x))->i6[1])
-#define I62(x) (((i6addr_t *)(x))->i6[2])
-#define I63(x) (((i6addr_t *)(x))->i6[3])
-#define HI60(x) ntohl(((i6addr_t *)(x))->i6[0])
-#define HI61(x) ntohl(((i6addr_t *)(x))->i6[1])
-#define HI62(x) ntohl(((i6addr_t *)(x))->i6[2])
-#define HI63(x) ntohl(((i6addr_t *)(x))->i6[3])
+#define I60(x) (((u_32_t *)(x))[0])
+#define I61(x) (((u_32_t *)(x))[1])
+#define I62(x) (((u_32_t *)(x))[2])
+#define I63(x) (((u_32_t *)(x))[3])
+#define HI60(x) ntohl(((u_32_t *)(x))[0])
+#define HI61(x) ntohl(((u_32_t *)(x))[1])
+#define HI62(x) ntohl(((u_32_t *)(x))[2])
+#define HI63(x) ntohl(((u_32_t *)(x))[3])
#define IP6_EQ(a,b) ((I63(a) == I63(b)) && (I62(a) == I62(b)) && \
(I61(a) == I61(b)) && (I60(a) == I60(b)))
@@ -181,14 +181,14 @@ typedef union i6addr {
HI63(a) < HI63(b)))))))
#define NLADD(n,x) htonl(ntohl(n) + (x))
#define IP6_INC(a) \
- { i6addr_t *_i6 = (i6addr_t *)(a); \
- _i6->i6[0] = NLADD(_i6->i6[0], 1); \
- if (_i6->i6[0] == 0) { \
- _i6->i6[0] = NLADD(_i6->i6[1], 1); \
- if (_i6->i6[1] == 0) { \
- _i6->i6[0] = NLADD(_i6->i6[2], 1); \
- if (_i6->i6[2] == 0) { \
- _i6->i6[0] = NLADD(_i6->i6[3], 1); \
+ { u_32_t *_i6 = (u_32_t *)(a); \
+ _i6[3] = NLADD(_i6[3], 1); \
+ if (_i6[3] == 0) { \
+ _i6[2] = NLADD(_i6[2], 1); \
+ if (_i6[2] == 0) { \
+ _i6[1] = NLADD(_i6[1], 1); \
+ if (_i6[1] == 0) { \
+ _i6[0] = NLADD(_i6[0], 1); \
} \
} \
} \
@@ -262,11 +262,12 @@ typedef struct fr_ip {
#define FI_FRAGBODY 0x2000
#define FI_BADSRC 0x4000
#define FI_LOWTTL 0x8000
-#define FI_CMP 0xcfe3 /* Not FI_FRAG,FI_NATED,FI_FRAGTAIL */
+#define FI_CMP 0xcf03 /* Not FI_FRAG,FI_NATED,FI_FRAGTAIL,broadcast */
#define FI_ICMPCMP 0x0003 /* Flags we can check for ICMP error packets */
#define FI_WITH 0xeffe /* Not FI_TCPUDP */
#define FI_V6EXTHDR 0x10000
#define FI_COALESCE 0x20000
+#define FI_NEWNAT 0x40000
#define FI_NOCKSUM 0x20000000 /* don't do a L4 checksum validation */
#define FI_DONTCACHE 0x40000000 /* don't cache the result */
#define FI_IGNORE 0x80000000
@@ -326,6 +327,7 @@ typedef struct fr_info {
u_short fin_off;
int fin_depth; /* Group nesting depth */
int fin_error; /* Error code to return */
+ int fin_cksum; /* -1 bad, 1 good, 0 not done */
void *fin_nat;
void *fin_state;
void *fin_nattag;
@@ -1203,6 +1205,8 @@ typedef struct ipftable {
} ipftable_t;
#define IPFTABLE_BUCKETS 1
+#define IPFTABLE_BUCKETS_NATIN 2
+#define IPFTABLE_BUCKETS_NATOUT 3
/*
@@ -1402,6 +1406,13 @@ extern int iplwrite __P((dev_t, struct uio *));
# endif /* __ sgi */
# endif /* MENTAT */
+# if defined(__FreeBSD_version)
+extern int ipf_pfil_hook __P((void));
+extern int ipf_pfil_unhook __P((void));
+extern void ipf_event_reg __P((void));
+extern void ipf_event_dereg __P((void));
+# endif
+
#endif /* #ifndef _KERNEL */
extern ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_hostmap;
@@ -1488,7 +1499,7 @@ extern void fr_getstat __P((struct friostat *));
extern int fr_ifpaddr __P((int, int, void *,
struct in_addr *, struct in_addr *));
extern int fr_initialise __P((void));
-extern void fr_lock __P((caddr_t, int *));
+extern int fr_lock __P((caddr_t, int *));
extern int fr_makefrip __P((int, ip_t *, fr_info_t *));
extern int fr_matchtag __P((ipftag_t *, ipftag_t *));
extern int fr_matchicmpqueryreply __P((int, icmpinfo_t *,
@@ -1501,7 +1512,7 @@ extern int fr_scanlist __P((fr_info_t *, u_32_t));
extern frentry_t *fr_srcgrpmap __P((fr_info_t *, u_32_t *));
extern int fr_tcpudpchk __P((fr_info_t *, frtuc_t *));
extern int fr_verifysrc __P((fr_info_t *fin));
-extern int fr_zerostats __P((char *));
+extern int fr_zerostats __P((void *));
extern ipftoken_t *ipf_findtoken __P((int, int, void *));
extern int ipf_getnextrule __P((ipftoken_t *, void *));
extern void ipf_expiretokens __P((void));
diff --git a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
index 02e0030fe174..fbecdad8e24f 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
+++ b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
@@ -5,7 +5,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.46 2007/05/11 13:41:53 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.50 2007/09/20 12:51:50 darrenr Exp $";
#endif
#if defined(KERNEL) || defined(_KERNEL)
@@ -203,15 +203,6 @@ int ipfattach()
#ifdef USE_SPL
int s;
#endif
-#if defined(NETBSD_PF) && (__FreeBSD_version >= 500011)
- int error = 0;
-# if __FreeBSD_version >= 501108
- struct pfil_head *ph_inet;
-# ifdef USE_INET6
- struct pfil_head *ph_inet6;
-# endif
-# endif
-#endif
SPL_NET(s);
if (fr_running > 0) {
@@ -231,77 +222,6 @@ int ipfattach()
}
-# ifdef NETBSD_PF
-# if __FreeBSD_version >= 500011
-# if __FreeBSD_version >= 501108
- ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
-# ifdef USE_INET6
- ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
-# endif
- if (ph_inet == NULL
-# ifdef USE_INET6
- && ph_inet6 == NULL
-# endif
- )
- return ENODEV;
-
- if (ph_inet != NULL)
- error = pfil_add_hook((void *)fr_check_wrapper, NULL,
- PFIL_IN|PFIL_OUT, ph_inet);
- else
- error = 0;
-# else
- error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
-# endif
- if (error) {
-# ifdef USE_INET6
- goto pfil_error;
-# else
- fr_deinitialise();
- SPL_X(s);
- return error;
-# endif
- }
-# else
- pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
-# endif
-# ifdef USE_INET6
-# if __FreeBSD_version >= 501108
- if (ph_inet6 != NULL)
- error = pfil_add_hook((void *)fr_check_wrapper6, NULL,
- PFIL_IN|PFIL_OUT, ph_inet6);
- else
- error = 0;
- if (error) {
- pfil_remove_hook((void *)fr_check_wrapper6, NULL,
- PFIL_IN|PFIL_OUT, ph_inet6);
-# else
- error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh);
- if (error) {
- pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
-# endif
-pfil_error:
- fr_deinitialise();
- SPL_X(s);
- return error;
- }
-# endif
-# endif
-
-#if (__FreeBSD_version >= 502103)
- ipf_arrivetag = EVENTHANDLER_REGISTER(ifnet_arrival_event, \
- ipf_ifevent, NULL, \
- EVENTHANDLER_PRI_ANY);
- ipf_departtag = EVENTHANDLER_REGISTER(ifnet_departure_event, \
- ipf_ifevent, NULL, \
- EVENTHANDLER_PRI_ANY);
- ipf_clonetag = EVENTHANDLER_REGISTER(if_clone_event, ipf_ifevent, \
- NULL, EVENTHANDLER_PRI_ANY);
-#endif
-
if (fr_checkp != fr_check) {
fr_savep = fr_checkp;
fr_checkp = fr_check;
@@ -334,31 +254,9 @@ int ipfdetach()
#ifdef USE_SPL
int s;
#endif
-#if defined(NETBSD_PF) && (__FreeBSD_version >= 500011)
- int error = 0;
-# if __FreeBSD_version >= 501108
- struct pfil_head *ph_inet;
-# ifdef USE_INET6
- struct pfil_head *ph_inet6;
-# endif
-# endif
-#endif
-
if (fr_control_forwarding & 2)
ipforwarding = 0;
-#if (__FreeBSD_version >= 502103)
- if (ipf_arrivetag != NULL) {
- EVENTHANDLER_DEREGISTER(ifnet_arrival_event, ipf_arrivetag);
- }
- if (ipf_departtag != NULL) {
- EVENTHANDLER_DEREGISTER(ifnet_departure_event, ipf_departtag);
- }
- if (ipf_clonetag != NULL) {
- EVENTHANDLER_DEREGISTER(if_clone_event, ipf_clonetag);
- }
-#endif
-
SPL_NET(s);
#if (__FreeBSD_version >= 300000)
@@ -375,44 +273,6 @@ int ipfdetach()
fr_savep = NULL;
#endif
-#ifdef NETBSD_PF
-# if (__FreeBSD_version >= 500011)
-# if (__FreeBSD_version >= 501108)
- ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
- if (ph_inet != NULL)
- error = pfil_remove_hook((void *)fr_check_wrapper, NULL,
- PFIL_IN|PFIL_OUT, ph_inet);
- else
- error = 0;
-# else
- error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
-# endif
- if (error) {
- SPL_X(s);
- return error;
- }
-# else
- pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
-# endif
-# ifdef USE_INET6
-# if (__FreeBSD_version >= 501108)
- ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
- if (ph_inet6 != NULL)
- error = pfil_remove_hook((void *)fr_check_wrapper6, NULL,
- PFIL_IN|PFIL_OUT, ph_inet6);
- else
- error = 0;
-# else
- error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh);
-# endif
- if (error) {
- SPL_X(s);
- return error;
- }
-# endif
-#endif
fr_deinitialise();
fr_running = -2;
@@ -690,10 +550,8 @@ fr_info_t *fin;
if (tcp->th_flags & TH_RST)
return -1; /* feedback loop */
-#ifndef IPFILTER_CKSUM
if (fr_checkl4sum(fin) == -1)
return -1;
-#endif
tlen = fin->fin_dlen - (TCP_OFF(tcp) << 2) +
((tcp->th_flags & TH_SYN) ? 1 : 0) +
@@ -852,7 +710,7 @@ int dst;
#endif
ip_t *ip, *ip2;
- if ((type < 0) || (type > ICMP_MAXTYPE))
+ if ((type < 0) || (type >= ICMP_MAXTYPE))
return -1;
code = fin->fin_icode;
@@ -861,10 +719,8 @@ int dst;
return -1;
#endif
-#ifndef IPFILTER_CKSUM
if (fr_checkl4sum(fin) == -1)
return -1;
-#endif
#ifdef MGETHDR
MGETHDR(m, M_DONTWAIT, MT_HEADER);
#else
@@ -1468,6 +1324,9 @@ fr_info_t *fin;
if ((fin->fin_flx & FI_NOCKSUM) != 0)
return;
+ if (fin->fin_cksum != 0)
+ return;
+
m = fin->fin_m;
if (m == NULL) {
manual = 1;
@@ -1483,8 +1342,12 @@ fr_info_t *fin;
htonl(m->m_pkthdr.csum_data +
fin->fin_ip->ip_len + fin->fin_p));
sum ^= 0xffff;
- if (sum != 0)
+ if (sum != 0) {
fin->fin_flx |= FI_BAD;
+ fin->fin_cksum = -1;
+ } else {
+ fin->fin_cksum = 1;
+ }
} else
manual = 1;
skipauto:
@@ -1596,11 +1459,16 @@ int len;
m = m_pullup(m, len);
}
*fin->fin_mp = m;
- fin->fin_m = m;
if (m == NULL) {
+ fin->fin_m = NULL;
ATOMIC_INCL(frstats[out].fr_pull[1]);
return NULL;
}
+
+ while (M_LEN(m) == 0) {
+ m = m->m_next;
+ }
+ fin->fin_m = m;
ip = MTOD(m, char *) + ipoff;
}
@@ -1656,3 +1524,122 @@ mb_t *m;
return error;
}
+
+int ipf_pfil_unhook(void) {
+#if defined(NETBSD_PF) && (__FreeBSD_version >= 500011)
+# if __FreeBSD_version >= 501108
+ struct pfil_head *ph_inet;
+# ifdef USE_INET6
+ struct pfil_head *ph_inet6;
+# endif
+# endif
+#endif
+
+#ifdef NETBSD_PF
+# if (__FreeBSD_version >= 500011)
+# if (__FreeBSD_version >= 501108)
+ ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
+ if (ph_inet != NULL)
+ pfil_remove_hook((void *)fr_check_wrapper, NULL,
+ PFIL_IN|PFIL_OUT|PFIL_WAITOK, ph_inet);
+# else
+ pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK,
+ &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
+# endif
+# else
+ pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK);
+# endif
+# ifdef USE_INET6
+# if (__FreeBSD_version >= 501108)
+ ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
+ if (ph_inet6 != NULL)
+ pfil_remove_hook((void *)fr_check_wrapper6, NULL,
+ PFIL_IN|PFIL_OUT|PFIL_WAITOK, ph_inet6);
+# else
+ pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK,
+ &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh);
+# endif
+# endif
+#endif
+
+ return (0);
+}
+
+int ipf_pfil_hook(void) {
+#if defined(NETBSD_PF) && (__FreeBSD_version >= 500011)
+# if __FreeBSD_version >= 501108
+ struct pfil_head *ph_inet;
+# ifdef USE_INET6
+ struct pfil_head *ph_inet6;
+# endif
+# endif
+#endif
+
+# ifdef NETBSD_PF
+# if __FreeBSD_version >= 500011
+# if __FreeBSD_version >= 501108
+ ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
+# ifdef USE_INET6
+ ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
+# endif
+ if (ph_inet == NULL
+# ifdef USE_INET6
+ && ph_inet6 == NULL
+# endif
+ )
+ return ENODEV;
+
+ if (ph_inet != NULL)
+ pfil_add_hook((void *)fr_check_wrapper, NULL,
+ PFIL_IN|PFIL_OUT|PFIL_WAITOK, ph_inet);
+# else
+ pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK,
+ &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
+# endif
+# else
+ pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK);
+# endif
+# ifdef USE_INET6
+# if __FreeBSD_version >= 501108
+ if (ph_inet6 != NULL)
+ pfil_add_hook((void *)fr_check_wrapper6, NULL,
+ PFIL_IN|PFIL_OUT|PFIL_WAITOK, ph_inet6);
+# else
+ pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK,
+ &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh);
+# endif
+# endif
+# endif
+ return (0);
+}
+
+void
+ipf_event_reg(void)
+{
+#if (__FreeBSD_version >= 502103)
+ ipf_arrivetag = EVENTHANDLER_REGISTER(ifnet_arrival_event, \
+ ipf_ifevent, NULL, \
+ EVENTHANDLER_PRI_ANY);
+ ipf_departtag = EVENTHANDLER_REGISTER(ifnet_departure_event, \
+ ipf_ifevent, NULL, \
+ EVENTHANDLER_PRI_ANY);
+ ipf_clonetag = EVENTHANDLER_REGISTER(if_clone_event, ipf_ifevent, \
+ NULL, EVENTHANDLER_PRI_ANY);
+#endif
+}
+
+void
+ipf_event_dereg(void)
+{
+#if (__FreeBSD_version >= 502103)
+ if (ipf_arrivetag != NULL) {
+ EVENTHANDLER_DEREGISTER(ifnet_arrival_event, ipf_arrivetag);
+ }
+ if (ipf_departtag != NULL) {
+ EVENTHANDLER_DEREGISTER(ifnet_departure_event, ipf_departtag);
+ }
+ if (ipf_clonetag != NULL) {
+ EVENTHANDLER_DEREGISTER(if_clone_event, ipf_clonetag);
+ }
+#endif
+}
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.c b/sys/contrib/ipfilter/netinet/ip_frag.c
index df75a0d31541..fd738f247e3c 100644
--- a/sys/contrib/ipfilter/netinet/ip_frag.c
+++ b/sys/contrib/ipfilter/netinet/ip_frag.c
@@ -100,7 +100,7 @@ extern struct timeout fr_slowtimer_ch;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.77.2.9 2007/05/27 11:13:44 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.77.2.12 2007/09/20 12:51:51 darrenr Exp $";
#endif
@@ -400,7 +400,7 @@ u_32_t ipid;
WRITE_ENTER(&ipf_ipidfrag);
fra = ipfr_newfrag(fin, 0, ipfr_ipidtab);
if (fra != NULL) {
- fra->ipfr_data = (void *)ipid;
+ fra->ipfr_data = (void *)((u_long)ipid);
*ipfr_ipidtail = fra;
fra->ipfr_prev = ipfr_ipidtail;
ipfr_ipidtail = &fra->ipfr_next;
@@ -585,7 +585,7 @@ fr_info_t *fin;
READ_ENTER(&ipf_ipidfrag);
ipf = fr_fraglookup(fin, ipfr_ipidtab);
if (ipf != NULL)
- id = (u_32_t)ipf->ipfr_data;
+ id = (u_32_t)((u_long)ipf->ipfr_data & 0xffffffff);
else
id = 0xffffffff;
RWLOCK_EXIT(&ipf_ipidfrag);
@@ -936,16 +936,16 @@ ipfrwlock_t *lock;
} else {
bzero(&zero, sizeof(zero));
next = &zero;
- token->ipt_data = (void *)-1;
+ token->ipt_data = NULL;
}
RWLOCK_EXIT(lock);
if (frag != NULL) {
- WRITE_ENTER(lock);
- frag->ipfr_ref--;
- if (frag->ipfr_ref <= 0)
- fr_fragfree(frag);
- RWLOCK_EXIT(lock);
+#ifdef USE_MUTEXES
+ fr_fragderef(&frag, lock);
+#else
+ fr_fragderef(&frag);
+#endif
}
error = COPYOUT(next, itp->igi_data, sizeof(*next));
diff --git a/sys/contrib/ipfilter/netinet/ip_htable.c b/sys/contrib/ipfilter/netinet/ip_htable.c
index e5a0ad2a42b2..1bed371b4ac4 100644
--- a/sys/contrib/ipfilter/netinet/ip_htable.c
+++ b/sys/contrib/ipfilter/netinet/ip_htable.c
@@ -51,7 +51,7 @@ struct file;
/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_htable.c,v 2.34.2.9 2007/02/02 23:06:16 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_htable.c,v 2.34.2.11 2007/09/20 12:51:51 darrenr Exp $";
#endif
#ifdef IPFILTER_LOOKUP
@@ -102,31 +102,29 @@ iplookupop_t *op;
int err, i, unit;
unit = op->iplo_unit;
- if ((op->iplo_arg & IPHASH_ANON) == 0)
+ if ((op->iplo_arg & IPHASH_ANON) == 0) {
iph = fr_existshtable(unit, op->iplo_name);
- else
- iph = NULL;
+ if (iph != NULL) {
+ if ((iph->iph_flags & IPHASH_DELETE) == 0)
+ return EEXIST;
+ iph->iph_flags &= ~IPHASH_DELETE;
+ return 0;
+ }
+ }
+ KMALLOC(iph, iphtable_t *);
if (iph == NULL) {
- KMALLOC(iph, iphtable_t *);
- if (iph == NULL) {
- ipht_nomem[op->iplo_unit]++;
- return ENOMEM;
- }
- err = COPYIN(op->iplo_struct, iph, sizeof(*iph));
- if (err != 0) {
- KFREE(iph);
- return EFAULT;
- }
- } else {
- if ((iph->iph_flags & IPHASH_DELETE) == 0)
- return EEXIST;
+ ipht_nomem[op->iplo_unit]++;
+ return ENOMEM;
+ }
+ err = COPYIN(op->iplo_struct, iph, sizeof(*iph));
+ if (err != 0) {
+ KFREE(iph);
+ return EFAULT;
}
if (iph->iph_unit != unit) {
- if ((iph->iph_flags & IPHASH_DELETE) == 0) {
- KFREE(iph);
- }
+ KFREE(iph);
return EINVAL;
}
@@ -151,33 +149,25 @@ iplookupop_t *op;
iph->iph_type |= IPHASH_ANON;
}
- if ((iph->iph_flags & IPHASH_DELETE) == 0) {
- KMALLOCS(iph->iph_table, iphtent_t **,
- iph->iph_size * sizeof(*iph->iph_table));
- if (iph->iph_table == NULL) {
- if ((iph->iph_flags & IPHASH_DELETE) == 0) {
- KFREE(iph);
- }
- ipht_nomem[unit]++;
- return ENOMEM;
- }
-
- bzero((char *)iph->iph_table,
- iph->iph_size * sizeof(*iph->iph_table));
- iph->iph_masks = 0;
- iph->iph_list = NULL;
-
- iph->iph_ref = 1;
- iph->iph_next = ipf_htables[unit];
- iph->iph_pnext = &ipf_htables[unit];
- if (ipf_htables[unit] != NULL)
- ipf_htables[unit]->iph_pnext = &iph->iph_next;
- ipf_htables[unit] = iph;
-
- ipf_nhtables[unit]++;
+ KMALLOCS(iph->iph_table, iphtent_t **,
+ iph->iph_size * sizeof(*iph->iph_table));
+ if (iph->iph_table == NULL) {
+ KFREE(iph);
+ ipht_nomem[unit]++;
+ return ENOMEM;
}
- iph->iph_flags &= ~IPHASH_DELETE;
+ bzero((char *)iph->iph_table, iph->iph_size * sizeof(*iph->iph_table));
+ iph->iph_masks = 0;
+ iph->iph_list = NULL;
+
+ iph->iph_ref = 1;
+ iph->iph_next = ipf_htables[unit];
+ iph->iph_pnext = &ipf_htables[unit];
+ if (ipf_htables[unit] != NULL)
+ ipf_htables[unit]->iph_pnext = &iph->iph_next;
+ ipf_htables[unit] = iph;
+ ipf_nhtables[unit]++;
return 0;
}
@@ -549,11 +539,11 @@ ipflookupiter_t *ilp;
if (nextiph != NULL) {
ATOMIC_INC(nextiph->iph_ref);
- if (nextiph->iph_next == NULL)
- token->ipt_alive = 0;
+ token->ipt_data = nextiph;
} else {
bzero((char *)&zp, sizeof(zp));
nextiph = &zp;
+ token->ipt_data = NULL;
}
break;
@@ -572,11 +562,11 @@ ipflookupiter_t *ilp;
if (nextnode != NULL) {
ATOMIC_INC(nextnode->ipe_ref);
- if (nextnode->ipe_next == NULL)
- token->ipt_alive = 0;
+ token->ipt_data = nextnode;
} else {
bzero((char *)&zn, sizeof(zn));
nextnode = &zn;
+ token->ipt_data = NULL;
}
break;
default :
@@ -596,7 +586,6 @@ ipflookupiter_t *ilp;
fr_derefhtable(iph);
RWLOCK_EXIT(&ip_poolrw);
}
- token->ipt_data = nextiph;
err = COPYOUT(nextiph, ilp->ili_data, sizeof(*nextiph));
if (err != 0)
err = EFAULT;
@@ -608,7 +597,6 @@ ipflookupiter_t *ilp;
fr_derefhtent(node);
RWLOCK_EXIT(&ip_poolrw);
}
- token->ipt_data = nextnode;
err = COPYOUT(nextnode, ilp->ili_data, sizeof(*nextnode));
if (err != 0)
err = EFAULT;
diff --git a/sys/contrib/ipfilter/netinet/ip_log.c b/sys/contrib/ipfilter/netinet/ip_log.c
index 2a0c72ef291c..aed828eae435 100644
--- a/sys/contrib/ipfilter/netinet/ip_log.c
+++ b/sys/contrib/ipfilter/netinet/ip_log.c
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_log.c,v 2.75.2.15 2007/02/03 00:49:30 darrenr Exp $
+ * $Id: ip_log.c,v 2.75.2.19 2007/09/09 11:32:06 darrenr Exp $
*/
#include <sys/param.h>
#if defined(KERNEL) || defined(_KERNEL)
@@ -256,7 +256,8 @@ u_int flags;
ipflog_t ipfl;
u_char p;
mb_t *m;
-# if (SOLARIS || defined(__hpux)) && defined(_KERNEL)
+# if (SOLARIS || defined(__hpux)) && defined(_KERNEL) && \
+ !defined(_INET_IP_STACK_H)
qif_t *ifp;
# else
struct ifnet *ifp;
@@ -268,7 +269,10 @@ u_int flags;
ipfl.fl_nattag.ipt_num[0] = 0;
ifp = fin->fin_ifp;
- hlen = fin->fin_hlen;
+ if (fin->fin_exthdr != NULL)
+ hlen = (char *)fin->fin_dp - (char *)fin->fin_ip;
+ else
+ hlen = fin->fin_hlen;
/*
* calculate header size.
*/
@@ -329,14 +333,16 @@ u_int flags;
* Get the interface number and name to which this packet is
* currently associated.
*/
-# if (SOLARIS || defined(__hpux)) && defined(_KERNEL)
+# if (SOLARIS || defined(__hpux)) && defined(_KERNEL) && \
+ !defined(_INET_IP_STACK_H)
ipfl.fl_unit = (u_int)ifp->qf_ppa;
- COPYIFNAME(ifp, ipfl.fl_ifname);
+ COPYIFNAME(fin->fin_v, ifp, ipfl.fl_ifname);
# else
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
(defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
- (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
- COPYIFNAME(ifp, ipfl.fl_ifname);
+ (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) || \
+ (SOLARIS && defined(_INET_IP_STACK_H))
+ COPYIFNAME(fin->fin_v, ifp, ipfl.fl_ifname);
# else
ipfl.fl_unit = (u_int)ifp->if_unit;
# if defined(_KERNEL)
@@ -345,7 +351,7 @@ u_int flags;
if ((ipfl.fl_ifname[2] = ifp->if_name[2]))
ipfl.fl_ifname[3] = ifp->if_name[3];
# else
- (void) strncpy(ipfl.fl_ifname, IFNAME(ifp), sizeof(ipfl.fl_ifname));
+ COPYIFNAME(fin->fin_v, ifp, ipfl.fl_ifname);
ipfl.fl_ifname[sizeof(ipfl.fl_ifname) - 1] = '\0';
# endif
# endif
@@ -421,7 +427,7 @@ void **items;
size_t *itemsz;
int *types, cnt;
{
- caddr_t buf, ptr;
+ u_char *buf, *ptr;
iplog_t *ipl;
size_t len;
int i;
@@ -458,7 +464,7 @@ int *types, cnt;
* check that we have space to record this information and can
* allocate that much.
*/
- KMALLOCS(buf, caddr_t, len);
+ KMALLOCS(buf, u_char *, len);
if (buf == NULL)
return -1;
SPL_NET(s);
@@ -497,7 +503,7 @@ int *types, cnt;
if (types[i] == 0) {
bcopy(items[i], ptr, itemsz[i]);
} else if (types[i] == 1) {
- COPYDATA(items[i], 0, itemsz[i], ptr);
+ COPYDATA(items[i], 0, itemsz[i], (char *)ptr);
}
ptr += itemsz[i];
}
@@ -622,7 +628,7 @@ struct uio *uio;
iplused[unit] -= dlen;
MUTEX_EXIT(&ipl_mutex);
SPL_X(s);
- error = UIOMOVE((caddr_t)ipl, dlen, UIO_READ, uio);
+ error = UIOMOVE(ipl, dlen, UIO_READ, uio);
if (error) {
SPL_NET(s);
MUTEX_ENTER(&ipl_mutex);
@@ -632,7 +638,7 @@ struct uio *uio;
break;
}
MUTEX_ENTER(&ipl_mutex);
- KFREES((caddr_t)ipl, dlen);
+ KFREES(ipl, dlen);
SPL_NET(s);
}
if (!iplt[unit]) {
@@ -665,7 +671,7 @@ minor_t unit;
MUTEX_ENTER(&ipl_mutex);
while ((ipl = iplt[unit]) != NULL) {
iplt[unit] = ipl->ipl_next;
- KFREES((caddr_t)ipl, ipl->ipl_dsize);
+ KFREES(ipl, ipl->ipl_dsize);
}
iplh[unit] = &iplt[unit];
ipll[unit] = NULL;
diff --git a/sys/contrib/ipfilter/netinet/ip_lookup.c b/sys/contrib/ipfilter/netinet/ip_lookup.c
index 12b1f4aee3d0..e33a6fe5cbe0 100644
--- a/sys/contrib/ipfilter/netinet/ip_lookup.c
+++ b/sys/contrib/ipfilter/netinet/ip_lookup.c
@@ -58,7 +58,7 @@ struct file;
/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_lookup.c,v 2.35.2.15 2007/05/26 13:05:13 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_lookup.c,v 2.35.2.19 2007/10/11 09:05:51 darrenr Exp $";
#endif
#ifdef IPFILTER_LOOKUP
@@ -70,6 +70,8 @@ static int iplookup_addtable __P((caddr_t));
static int iplookup_deltable __P((caddr_t));
static int iplookup_stats __P((caddr_t));
static int iplookup_flush __P((caddr_t));
+static int iplookup_iterate __P((void *, int, void *));
+static int iplookup_deltok __P((void *, int, void *));
/* ------------------------------------------------------------------------ */
@@ -181,7 +183,11 @@ void *ctx;
break;
case SIOCLOOKUPITER :
- err = ip_lookup_iterate(data, uid, ctx);
+ err = iplookup_iterate(data, uid, ctx);
+ break;
+
+ case SIOCIPFDELTOK :
+ err = iplookup_deltok(data, uid, ctx);
break;
default :
@@ -287,8 +293,9 @@ caddr_t data;
ip_pool_t *p;
int err;
- err = 0;
- BCOPYIN(data, &op, sizeof(op));
+ err = BCOPYIN(data, &op, sizeof(op));
+ if (err != 0)
+ return EFAULT;
if (op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX)
return EINVAL;
@@ -558,13 +565,15 @@ void *ptr;
/* ------------------------------------------------------------------------ */
-/* Function: ip_lookup_iterate */
+/* Function: iplookup_iterate */
/* Returns: int - 0 = success, else error */
/* Parameters: data(I) - pointer to data from ioctl call */
+/* uid(I) - uid of caller */
+/* ctx(I) - pointer to give the uid context */
/* */
/* Decodes ioctl request to step through either hash tables or pools. */
/* ------------------------------------------------------------------------ */
-int ip_lookup_iterate(data, uid, ctx)
+static int iplookup_iterate(data, uid, ctx)
void *data;
int uid;
void *ctx;
@@ -578,7 +587,7 @@ void *ctx;
if (err != 0)
return err;
- if (iter.ili_unit < 0 || iter.ili_unit > IPL_LOGMAX)
+ if (iter.ili_unit > IPL_LOGMAX)
return EINVAL;
if (iter.ili_ival != IPFGENITER_LOOKUP)
@@ -644,6 +653,33 @@ void *data;
}
+/* ------------------------------------------------------------------------ */
+/* Function: iplookup_deltok */
+/* Returns: int - 0 = success, else error */
+/* Parameters: data(I) - pointer to data from ioctl call */
+/* uid(I) - uid of caller */
+/* ctx(I) - pointer to give the uid context */
+/* */
+/* Deletes the token identified by the combination of (type,uid,ctx) */
+/* "key" is a combination of the table type, iterator type and the unit for */
+/* which the token was being used. */
+/* ------------------------------------------------------------------------ */
+static int iplookup_deltok(data, uid, ctx)
+void *data;
+int uid;
+void *ctx;
+{
+ int error, key;
+ SPL_INT(s);
+
+ SPL_SCHED(s);
+ error = BCOPYIN(data, &key, sizeof(key));
+ if (error == 0)
+ error = ipf_deltoken(key, uid, ctx);
+ SPL_X(s);
+ return error;
+}
+
#else /* IPFILTER_LOOKUP */
diff --git a/sys/contrib/ipfilter/netinet/ip_lookup.h b/sys/contrib/ipfilter/netinet/ip_lookup.h
index 4b90655d2e62..3886df16303d 100644
--- a/sys/contrib/ipfilter/netinet/ip_lookup.h
+++ b/sys/contrib/ipfilter/netinet/ip_lookup.h
@@ -64,7 +64,7 @@ typedef union {
char ilik_ival;
u_char ilik_type; /* IPLT_* */
u_char ilik_otype;
- char ilik_unit; /* IPL_LOG* */
+ u_char ilik_unit; /* IPL_LOG* */
} ilik_unstr;
u_32_t ilik_key;
} iplookupiterkey_t;
@@ -90,7 +90,6 @@ extern int ip_lookup_init __P((void));
extern int ip_lookup_ioctl __P((caddr_t, ioctlcmd_t, int, int, void *));
extern void ip_lookup_unload __P((void));
extern void ip_lookup_deref __P((int, void *));
-extern int ip_lookup_iterate __P((void *, int, void *));
extern void ip_lookup_iterderef __P((u_32_t, void *));
#endif /* __IP_LOOKUP_H__ */
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c
index 554fbc80d86d..3df185038f0a 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.c
+++ b/sys/contrib/ipfilter/netinet/ip_nat.c
@@ -115,7 +115,7 @@ extern struct ifnet vpnif;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.195.2.87 2007/05/31 10:17:17 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.195.2.102 2007/10/16 10:08:10 darrenr Exp $";
#endif
@@ -176,7 +176,7 @@ u_long fr_defnatage = DEF_NAT_AGE,
natstat_t nat_stats;
int fr_nat_lock = 0;
int fr_nat_init = 0;
-#if SOLARIS
+#if SOLARIS && !defined(_INET_IP_STACK_H)
extern int pfil_delayed_copy;
#endif
@@ -185,13 +185,13 @@ static int nat_flushtable __P((void));
static int nat_clearlist __P((void));
static void nat_addnat __P((struct ipnat *));
static void nat_addrdr __P((struct ipnat *));
-static void nat_delete __P((struct nat *, int));
static void nat_delrdr __P((struct ipnat *));
static void nat_delnat __P((struct ipnat *));
static int fr_natgetent __P((caddr_t));
static int fr_natgetsz __P((caddr_t));
static int fr_natputent __P((caddr_t, int));
static int nat_extraflush __P((int));
+static int nat_gettable __P((char *));
static void nat_tabmove __P((nat_t *));
static int nat_match __P((fr_info_t *, ipnat_t *));
static INLINE int nat_newmap __P((fr_info_t *, nat_t *, natinfo_t *));
@@ -871,7 +871,7 @@ void *ctx;
if (!(mode & FWRITE)) {
error = EPERM;
} else {
- fr_lock(data, &fr_nat_lock);
+ error = fr_lock(data, &fr_nat_lock);
}
break;
@@ -942,6 +942,10 @@ void *ctx;
error = fr_outobj(data, nat_tqb, IPFOBJ_STATETQTAB);
break;
+ case SIOCGTABL :
+ error = nat_gettable(data);
+ break;
+
default :
error = EINVAL;
break;
@@ -1079,7 +1083,7 @@ int getlock;
n = NULL;
nat_stats.ns_rules++;
-#if SOLARIS
+#if SOLARIS && !defined(_INET_IP_STACK_H)
pfil_delayed_copy = 0;
#endif
if (getlock) {
@@ -1167,9 +1171,10 @@ int getlock;
if (n->in_use == 0) {
if (n->in_apr)
appr_free(n->in_apr);
+ MUTEX_DESTROY(&n->in_lock);
KFREE(n);
nat_stats.ns_rules--;
-#if SOLARIS
+#if SOLARIS && !defined(_INET_IP_STACK_H)
if (nat_stats.ns_rules == 0)
pfil_delayed_copy = 1;
#endif
@@ -1643,22 +1648,23 @@ junkput:
/* Delete a nat entry from the various lists and table. If NAT logging is */
/* enabled then generate a NAT log record for this event. */
/* ------------------------------------------------------------------------ */
-static void nat_delete(nat, logtype)
+void nat_delete(nat, logtype)
struct nat *nat;
int logtype;
{
struct ipnat *ipn;
+ int removed = 0;
if (logtype != 0 && nat_logging != 0)
nat_log(nat, logtype);
- MUTEX_ENTER(&ipf_nat_new);
-
/*
* Take it as a general indication that all the pointers are set if
* nat_pnext is set.
*/
if (nat->nat_pnext != NULL) {
+ removed = 1;
+
nat_stats.ns_bucketlen[0][nat->nat_hv[0]]--;
nat_stats.ns_bucketlen[1][nat->nat_hv[1]]--;
@@ -1698,15 +1704,35 @@ int logtype;
if (logtype == NL_EXPIRE)
nat_stats.ns_expire++;
- nat->nat_ref--;
- if (nat->nat_ref > 0) {
- MUTEX_EXIT(&ipf_nat_new);
+ MUTEX_ENTER(&nat->nat_lock);
+ /*
+ * NL_DESTROY should only be passed in when we've got nat_ref >= 2.
+ * This happens when a nat'd packet is blocked and we want to throw
+ * away the NAT session.
+ */
+ if (logtype == NL_DESTROY) {
+ if (nat->nat_ref > 2) {
+ nat->nat_ref -= 2;
+ MUTEX_EXIT(&nat->nat_lock);
+ if (removed)
+ nat_stats.ns_orphans++;
+ return;
+ }
+ } else if (nat->nat_ref > 1) {
+ nat->nat_ref--;
+ MUTEX_EXIT(&nat->nat_lock);
+ if (removed)
+ nat_stats.ns_orphans++;
return;
}
+ MUTEX_EXIT(&nat->nat_lock);
/*
- * At this point, nat_ref can be either 0 or -1
+ * At this point, nat_ref is 1, doing "--" would make it 0..
*/
+ nat->nat_ref = 0;
+ if (!removed)
+ nat_stats.ns_orphans--;
#ifdef IPFILTER_SYNC
if (nat->nat_sync)
@@ -1733,7 +1759,6 @@ int logtype;
aps_free(nat->nat_aps);
nat_stats.ns_inuse--;
- MUTEX_EXIT(&ipf_nat_new);
/*
* If there's a fragment table entry too for this nat entry, then
@@ -1807,6 +1832,7 @@ static int nat_clearlist()
if (n->in_use == 0) {
if (n->in_apr != NULL)
appr_free(n->in_apr);
+ MUTEX_DESTROY(&n->in_lock);
KFREE(n);
nat_stats.ns_rules--;
} else {
@@ -1815,7 +1841,7 @@ static int nat_clearlist()
}
i++;
}
-#if SOLARIS
+#if SOLARIS && !defined(_INET_IP_STACK_H)
pfil_delayed_copy = 1;
#endif
nat_masks = 0;
@@ -2479,10 +2505,12 @@ int direction;
}
if (nat_finalise(fin, nat, &ni, tcp, natsave, direction) == -1) {
+ fr_nat_doflush = 1;
goto badnat;
}
if (flags & SI_WILDP)
nat_stats.ns_wilds++;
+ fin->fin_flx |= FI_NEWNAT;
goto done;
badnat:
nat_stats.ns_badnat++;
@@ -2525,10 +2553,10 @@ int direction;
np = ni->nai_np;
if (np->in_ifps[0] != NULL) {
- COPYIFNAME(np->in_ifps[0], nat->nat_ifnames[0]);
+ COPYIFNAME(4, np->in_ifps[0], nat->nat_ifnames[0]);
}
if (np->in_ifps[1] != NULL) {
- COPYIFNAME(np->in_ifps[1], nat->nat_ifnames[1]);
+ COPYIFNAME(4, np->in_ifps[1], nat->nat_ifnames[1]);
}
#ifdef IPFILTER_SYNC
if ((nat->nat_flags & SI_CLONE) == 0)
@@ -2542,6 +2570,8 @@ int direction;
nat->nat_ptr = np;
nat->nat_p = fin->fin_p;
nat->nat_mssclamp = np->in_mssclamp;
+ if (nat->nat_p == IPPROTO_TCP)
+ nat->nat_seqnext[0] = ntohl(tcp->th_seq);
if ((np->in_apr != NULL) && ((ni->nai_flags & NAT_SLAVE) == 0))
if (appr_new(fin, nat) == -1)
@@ -2989,10 +3019,22 @@ int dir;
}
if (sumd2 != 0) {
+ ipnat_t *np;
+
+ np = nat->nat_ptr;
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
- fix_incksum(fin, &icmp->icmp_cksum, sumd2);
+
+ if ((odst == 0) && (dir == NAT_OUTBOUND) &&
+ (fin->fin_rev == 0) && (np != NULL) &&
+ (np->in_redir & NAT_REDIRECT)) {
+ fix_outcksum(fin, &icmp->icmp_cksum,
+ sumd2);
+ } else {
+ fix_incksum(fin, &icmp->icmp_cksum,
+ sumd2);
+ }
}
}
} else if (((flags & IPN_ICMPQUERY) != 0) && (dlen >= 8)) {
@@ -3619,6 +3661,26 @@ ipnat_t *np;
ifq2 = NULL;
if (nat->nat_p == IPPROTO_TCP && ifq2 == NULL) {
+ u_32_t end, ack;
+ u_char tcpflags;
+ tcphdr_t *tcp;
+ int dsize;
+
+ tcp = fin->fin_dp;
+ tcpflags = tcp->th_flags;
+ dsize = fin->fin_dlen - (TCP_OFF(tcp) << 2) +
+ ((tcpflags & TH_SYN) ? 1 : 0) +
+ ((tcpflags & TH_FIN) ? 1 : 0);
+
+ ack = ntohl(tcp->th_ack);
+ end = ntohl(tcp->th_seq) + dsize;
+
+ if (SEQ_GT(ack, nat->nat_seqnext[1 - fin->fin_rev]))
+ nat->nat_seqnext[1 - fin->fin_rev] = ack;
+
+ if (nat->nat_seqnext[fin->fin_rev] == 0)
+ nat->nat_seqnext[fin->fin_rev] = end;
+
(void) fr_tcp_age(&nat->nat_tqe, fin, nat_tqb, 0);
} else {
if (ifq2 == NULL) {
@@ -4640,9 +4702,10 @@ ipnat_t **inp;
if (in->in_use == 0 && (in->in_flags & IPN_DELETE)) {
if (in->in_apr)
appr_free(in->in_apr);
+ MUTEX_DESTROY(&in->in_lock);
KFREE(in);
nat_stats.ns_rules--;
-#if SOLARIS
+#if SOLARIS && !defined(_INET_IP_STACK_H)
if (nat_stats.ns_rules == 0)
pfil_delayed_copy = 1;
#endif
@@ -4657,6 +4720,14 @@ ipnat_t **inp;
/* */
/* Decrement the reference counter for this NAT table entry and free it if */
/* there are no more things using it. */
+/* */
+/* IF nat_ref == 1 when this function is called, then we have an orphan nat */
+/* structure *because* it only gets called on paths _after_ nat_ref has been*/
+/* incremented. If nat_ref == 1 then we shouldn't decrement it here */
+/* because nat_delete() will do that and send nat_ref to -1. */
+/* */
+/* Holding the lock on nat_lock is required to serialise nat_delete() being */
+/* called from a NAT flush ioctl with a deref happening because of a packet.*/
/* ------------------------------------------------------------------------ */
void fr_natderef(natp)
nat_t **natp;
@@ -4665,10 +4736,17 @@ nat_t **natp;
nat = *natp;
*natp = NULL;
+
+ MUTEX_ENTER(&nat->nat_lock);
+ if (nat->nat_ref > 1) {
+ nat->nat_ref--;
+ MUTEX_EXIT(&nat->nat_lock);
+ return;
+ }
+ MUTEX_EXIT(&nat->nat_lock);
+
WRITE_ENTER(&ipf_nat);
- nat->nat_ref--;
- if (nat->nat_ref == 0)
- nat_delete(nat, NL_EXPIRE);
+ nat_delete(nat, NL_EXPIRE);
RWLOCK_EXIT(&ipf_nat);
}
@@ -4954,10 +5032,11 @@ ipfgeniter_t *itp;
ipnat_t *ipn, *nextipnat = NULL, zeroipn;
nat_t *nat, *nextnat = NULL, zeronat;
int error = 0, count;
- ipftoken_t *freet;
char *dst;
- freet = NULL;
+ count = itp->igi_nitems;
+ if (count < 1)
+ return ENOSPC;
READ_ENTER(&ipf_nat);
@@ -4995,61 +5074,52 @@ ipfgeniter_t *itp;
}
dst = itp->igi_data;
- for (count = itp->igi_nitems; count > 0; count--) {
+ for (;;) {
switch (itp->igi_type)
{
case IPFGENITER_HOSTMAP :
if (nexthm != NULL) {
- if (nexthm->hm_next == NULL) {
- freet = t;
- count = 1;
- hm = NULL;
- }
if (count == 1) {
ATOMIC_INC32(nexthm->hm_ref);
+ t->ipt_data = nexthm;
}
} else {
bzero(&zerohm, sizeof(zerohm));
nexthm = &zerohm;
count = 1;
+ t->ipt_data = NULL;
}
break;
case IPFGENITER_IPNAT :
if (nextipnat != NULL) {
- if (nextipnat->in_next == NULL) {
- freet = t;
- count = 1;
- ipn = NULL;
- }
if (count == 1) {
MUTEX_ENTER(&nextipnat->in_lock);
nextipnat->in_use++;
MUTEX_EXIT(&nextipnat->in_lock);
+ t->ipt_data = nextipnat;
}
} else {
bzero(&zeroipn, sizeof(zeroipn));
nextipnat = &zeroipn;
count = 1;
+ t->ipt_data = NULL;
}
break;
case IPFGENITER_NAT :
if (nextnat != NULL) {
- if (nextnat->nat_next == NULL) {
- count = 1;
- freet = t;
- nat = NULL;
- }
if (count == 1) {
MUTEX_ENTER(&nextnat->nat_lock);
nextnat->nat_ref++;
MUTEX_EXIT(&nextnat->nat_lock);
+ t->ipt_data = nextnat;
}
} else {
bzero(&zeronat, sizeof(zeronat));
nextnat = &zeronat;
count = 1;
+ t->ipt_data = NULL;
}
break;
default :
@@ -5057,20 +5127,12 @@ ipfgeniter_t *itp;
}
RWLOCK_EXIT(&ipf_nat);
- if (freet != NULL) {
- ipf_freetoken(freet);
- freet = NULL;
- }
-
+ /*
+ * Copying out to user space needs to be done without the lock.
+ */
switch (itp->igi_type)
{
case IPFGENITER_HOSTMAP :
- if (hm != NULL) {
- WRITE_ENTER(&ipf_nat);
- fr_hostmapdel(&hm);
- RWLOCK_EXIT(&ipf_nat);
- }
- t->ipt_data = nexthm;
error = COPYOUT(nexthm, dst, sizeof(*nexthm));
if (error != 0)
error = EFAULT;
@@ -5079,9 +5141,6 @@ ipfgeniter_t *itp;
break;
case IPFGENITER_IPNAT :
- if (ipn != NULL)
- fr_ipnatderef(&ipn);
- t->ipt_data = nextipnat;
error = COPYOUT(nextipnat, dst, sizeof(*nextipnat));
if (error != 0)
error = EFAULT;
@@ -5090,9 +5149,6 @@ ipfgeniter_t *itp;
break;
case IPFGENITER_NAT :
- if (nat != NULL)
- fr_natderef(&nat);
- t->ipt_data = nextnat;
error = COPYOUT(nextnat, dst, sizeof(*nextnat));
if (error != 0)
error = EFAULT;
@@ -5104,29 +5160,52 @@ ipfgeniter_t *itp;
if ((count == 1) || (error != 0))
break;
+ count--;
+
READ_ENTER(&ipf_nat);
+ /*
+ * We need to have the lock again here to make sure that
+ * using _next is consistent.
+ */
switch (itp->igi_type)
{
case IPFGENITER_HOSTMAP :
- hm = nexthm;
- nexthm = hm->hm_next;
+ nexthm = nexthm->hm_next;
break;
-
case IPFGENITER_IPNAT :
- ipn = nextipnat;
- nextipnat = ipn->in_next;
+ nextipnat = nextipnat->in_next;
break;
-
case IPFGENITER_NAT :
- nat = nextnat;
- nextnat = nat->nat_next;
- break;
- default :
+ nextnat = nextnat->nat_next;
break;
}
}
+
+ switch (itp->igi_type)
+ {
+ case IPFGENITER_HOSTMAP :
+ if (hm != NULL) {
+ WRITE_ENTER(&ipf_nat);
+ fr_hostmapdel(&hm);
+ RWLOCK_EXIT(&ipf_nat);
+ }
+ break;
+ case IPFGENITER_IPNAT :
+ if (ipn != NULL) {
+ fr_ipnatderef(&ipn);
+ }
+ break;
+ case IPFGENITER_NAT :
+ if (nat != NULL) {
+ fr_natderef(&nat);
+ }
+ break;
+ default :
+ break;
+ }
+
return error;
}
@@ -5335,3 +5414,44 @@ void *entry;
nat_delete(entry, NL_FLUSH);
return 0;
}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: nat_gettable */
+/* Returns: int - 0 = success, else error */
+/* Parameters: data(I) - pointer to ioctl data */
+/* */
+/* This function handles ioctl requests for tables of nat information. */
+/* At present the only table it deals with is the hash bucket statistics. */
+/* ------------------------------------------------------------------------ */
+static int nat_gettable(data)
+char *data;
+{
+ ipftable_t table;
+ int error;
+
+ error = fr_inobj(data, &table, IPFOBJ_GTABLE);
+ if (error != 0)
+ return error;
+
+ switch (table.ita_type)
+ {
+ case IPFTABLE_BUCKETS_NATIN :
+ error = COPYOUT(nat_stats.ns_bucketlen[0], table.ita_table,
+ ipf_nattable_sz * sizeof(u_long));
+ break;
+
+ case IPFTABLE_BUCKETS_NATOUT :
+ error = COPYOUT(nat_stats.ns_bucketlen[1], table.ita_table,
+ ipf_nattable_sz * sizeof(u_long));
+ break;
+
+ default :
+ return EINVAL;
+ }
+
+ if (error != 0) {
+ error = EFAULT;
+ }
+ return error;
+}
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.h b/sys/contrib/ipfilter/netinet/ip_nat.h
index d478942aabe6..f25c0d8f86d8 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.h
+++ b/sys/contrib/ipfilter/netinet/ip_nat.h
@@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_nat.h 1.5 2/4/96
- * $Id: ip_nat.h,v 2.90.2.17 2007/05/11 10:19:11 darrenr Exp $
+ * $Id: ip_nat.h,v 2.90.2.20 2007/09/25 08:27:32 darrenr Exp $
*/
#ifndef __IP_NAT_H__
@@ -122,6 +122,7 @@ typedef struct nat {
char nat_ifnames[2][LIFNAMSIZ];
int nat_rev; /* 0 = forward, 1 = reverse */
int nat_redir; /* copy of in_redir */
+ u_32_t nat_seqnext[2];
} nat_t;
#define nat_inip nat_inip6.in4
@@ -360,6 +361,7 @@ typedef struct natstat {
hostmap_t *ns_maplist;
u_long *ns_bucketlen[2];
u_long ns_ticks;
+ u_int ns_orphans;
} natstat_t;
typedef struct natlog {
@@ -381,6 +383,7 @@ typedef struct natlog {
#define NL_NEWRDR NAT_REDIRECT
#define NL_NEWBIMAP NAT_BIMAP
#define NL_NEWBLOCK NAT_MAPBLK
+#define NL_DESTROY 0xfffc
#define NL_CLONE 0xfffd
#define NL_FLUSH 0xfffe
#define NL_EXPIRE 0xffff
@@ -444,6 +447,7 @@ extern nat_t *nat_maplookup __P((void *, u_int, struct in_addr,
extern nat_t *nat_lookupredir __P((natlookup_t *));
extern nat_t *nat_icmperrorlookup __P((fr_info_t *, int));
extern nat_t *nat_icmperror __P((fr_info_t *, u_int *, int));
+extern void nat_delete __P((struct nat *, int));
extern int nat_insert __P((nat_t *, int));
extern int fr_checknatout __P((fr_info_t *, u_32_t *));
diff --git a/sys/contrib/ipfilter/netinet/ip_pool.c b/sys/contrib/ipfilter/netinet/ip_pool.c
index b7e994604adf..eab33108a567 100644
--- a/sys/contrib/ipfilter/netinet/ip_pool.c
+++ b/sys/contrib/ipfilter/netinet/ip_pool.c
@@ -53,6 +53,9 @@ struct file;
# include <sys/malloc.h>
#endif
+#if defined(SOLARIS2) && !defined(_KERNEL)
+# include "radix_ipf.h"
+#endif
#if defined(_KERNEL) && (defined(__osf__) || defined(AIX) || \
defined(__hpux) || defined(__sgi))
# include "radix_ipf_local.h"
@@ -75,15 +78,16 @@ static int rn_freenode __P((struct radix_node *, void *));
#if !defined(lint)
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_pool.c,v 2.55.2.20 2007/05/31 12:27:35 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_pool.c,v 2.55.2.24 2007/10/10 09:45:37 darrenr Exp $";
#endif
#ifdef IPFILTER_LOOKUP
-# ifndef RADIX_NODE_HEAD_LOCK
+# if !defined(RADIX_NODE_HEAD_LOCK) || !defined(RADIX_NODE_HEAD_UNLOCK) || \
+ !defined(_KERNEL)
+# undef RADIX_NODE_HEAD_LOCK
+# undef RADIX_NODE_HEAD_UNLOCK
# define RADIX_NODE_HEAD_LOCK(x) ;
-# endif
-# ifndef RADIX_NODE_HEAD_UNLOCK
# define RADIX_NODE_HEAD_UNLOCK(x) ;
# endif
@@ -264,8 +268,6 @@ void ip_pool_fini()
ip_pool_t *p, *q;
int i;
- ASSERT(rw_read_locked(&ipf_global.ipf_lk) == 0);
-
for (i = 0; i <= IPL_LOGMAX; i++) {
for (q = ip_pool_list[i]; (p = q) != NULL; ) {
q = p->ipo_next;
@@ -463,8 +465,6 @@ int info;
struct radix_node *rn;
ip_pool_node_t *x;
- ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0);
-
KMALLOC(x, ip_pool_node_t *);
if (x == NULL) {
return ENOMEM;
@@ -529,32 +529,27 @@ iplookupop_t *op;
int poolnum, unit;
ip_pool_t *h;
- ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0);
-
unit = op->iplo_unit;
- if ((op->iplo_arg & LOOKUP_ANON) == 0)
+ if ((op->iplo_arg & LOOKUP_ANON) == 0) {
h = ip_pool_exists(unit, op->iplo_name);
- else
- h = NULL;
-
- if (h != NULL) {
- if ((h->ipo_flags & IPOOL_DELETE) != 0) {
+ if (h != NULL) {
+ if ((h->ipo_flags & IPOOL_DELETE) == 0)
+ return EEXIST;
h->ipo_flags &= ~IPOOL_DELETE;
return 0;
}
- return EEXIST;
- } else {
- KMALLOC(h, ip_pool_t *);
- if (h == NULL)
- return ENOMEM;
- bzero(h, sizeof(*h));
-
- if (rn_inithead((void **)&h->ipo_head,
- offsetof(addrfamily_t, adf_addr) << 3) == 0) {
- KFREE(h);
- return ENOMEM;
- }
+ }
+
+ KMALLOC(h, ip_pool_t *);
+ if (h == NULL)
+ return ENOMEM;
+ bzero(h, sizeof(*h));
+
+ if (rn_inithead((void **)&h->ipo_head,
+ offsetof(addrfamily_t, adf_addr) << 3) == 0) {
+ KFREE(h);
+ return ENOMEM;
}
if ((op->iplo_arg & LOOKUP_ANON) != 0) {
@@ -589,18 +584,16 @@ iplookupop_t *op;
(void)strncpy(h->ipo_name, op->iplo_name, sizeof(h->ipo_name));
}
- if ((h->ipo_flags & IPOOL_DELETE) == 0) {
- h->ipo_ref = 1;
- h->ipo_list = NULL;
- h->ipo_unit = unit;
- h->ipo_next = ip_pool_list[unit];
- if (ip_pool_list[unit] != NULL)
- ip_pool_list[unit]->ipo_pnext = &h->ipo_next;
- h->ipo_pnext = &ip_pool_list[unit];
- ip_pool_list[unit] = h;
-
- ipoolstat.ipls_pools++;
- }
+ h->ipo_ref = 1;
+ h->ipo_list = NULL;
+ h->ipo_unit = unit;
+ h->ipo_next = ip_pool_list[unit];
+ if (ip_pool_list[unit] != NULL)
+ ip_pool_list[unit]->ipo_pnext = &h->ipo_next;
+ h->ipo_pnext = &ip_pool_list[unit];
+ ip_pool_list[unit] = h;
+
+ ipoolstat.ipls_pools++;
return 0;
}
@@ -620,8 +613,6 @@ ip_pool_t *ipo;
ip_pool_node_t *ipe;
{
- ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0);
-
if (ipe->ipn_pnext != NULL)
*ipe->ipn_pnext = ipe->ipn_next;
if (ipe->ipn_next != NULL)
@@ -789,8 +780,6 @@ void ip_pool_deref(ipo)
ip_pool_t *ipo;
{
- ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0);
-
ipo->ipo_ref--;
if (ipo->ipo_ref == 0)
@@ -858,11 +847,11 @@ ipflookupiter_t *ilp;
if (nextipo != NULL) {
ATOMIC_INC(nextipo->ipo_ref);
- if (nextipo->ipo_next == NULL)
- token->ipt_alive = 0;
+ token->ipt_data = nextipo;
} else {
bzero((char *)&zp, sizeof(zp));
nextipo = &zp;
+ token->ipt_data = NULL;
}
break;
@@ -882,11 +871,11 @@ ipflookupiter_t *ilp;
if (nextnode != NULL) {
ATOMIC_INC(nextnode->ipn_ref);
- if (nextnode->ipn_next == NULL)
- token->ipt_alive = 0;
+ token->ipt_data = nextnode;
} else {
bzero((char *)&zn, sizeof(zn));
nextnode = &zn;
+ token->ipt_data = NULL;
}
break;
default :
@@ -907,7 +896,6 @@ ipflookupiter_t *ilp;
ip_pool_deref(ipo);
RWLOCK_EXIT(&ip_poolrw);
}
- token->ipt_data = nextipo;
err = COPYOUT(nextipo, ilp->ili_data, sizeof(*nextipo));
if (err != 0)
err = EFAULT;
@@ -919,7 +907,6 @@ ipflookupiter_t *ilp;
ip_pool_node_deref(node);
RWLOCK_EXIT(&ip_poolrw);
}
- token->ipt_data = nextnode;
err = COPYOUT(nextnode, ilp->ili_data, sizeof(*nextnode));
if (err != 0)
err = EFAULT;
diff --git a/sys/contrib/ipfilter/netinet/ip_pool.h b/sys/contrib/ipfilter/netinet/ip_pool.h
index 927276f9ce4f..9968ef012f5b 100644
--- a/sys/contrib/ipfilter/netinet/ip_pool.h
+++ b/sys/contrib/ipfilter/netinet/ip_pool.h
@@ -3,7 +3,7 @@
*
* See the IPFILTER.LICENCE file for details on licencing.
*
- * $Id: ip_pool.h,v 2.26.2.5 2007/01/14 14:06:12 darrenr Exp $
+ * $Id: ip_pool.h,v 2.26.2.6 2007/10/10 09:51:43 darrenr Exp $
*/
#ifndef __IP_POOL_H__
@@ -16,7 +16,7 @@ extern void rn_freehead __P((struct radix_node_head *));
# define FreeS(p, z) KFREES(p, z)
extern int max_keylen;
#else
-# if defined(__osf__) || defined(__hpux)
+# if defined(__osf__) || defined(__hpux) || defined(sun)
# include "radix_ipf_local.h"
# define radix_mask ipf_radix_mask
# define radix_node ipf_radix_node
diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.c b/sys/contrib/ipfilter/netinet/ip_proxy.c
index 96eb172f8fa5..04e9f89d5c9c 100644
--- a/sys/contrib/ipfilter/netinet/ip_proxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_proxy.c
@@ -103,7 +103,7 @@ struct file;
/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.62.2.20 2007/05/31 12:27:36 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.62.2.21 2007/06/02 21:22:28 darrenr Exp $";
#endif
static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int ));
@@ -295,7 +295,7 @@ int mode;
void *ctx;
{
ap_ctl_t ctl;
- caddr_t ptr;
+ u_char *ptr;
int error;
mode = mode; /* LINT */
@@ -303,11 +303,13 @@ void *ctx;
switch (cmd)
{
case SIOCPROXY :
- BCOPYIN(data, &ctl, sizeof(ctl));
+ error = BCOPYIN(data, &ctl, sizeof(ctl));
+ if (error != 0)
+ return EFAULT;
ptr = NULL;
if (ctl.apc_dsize > 0) {
- KMALLOCS(ptr, caddr_t, ctl.apc_dsize);
+ KMALLOCS(ptr, u_char *, ctl.apc_dsize);
if (ptr == NULL)
error = ENOMEM;
else {
diff --git a/sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c b/sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c
index 4350bf408c55..da76fde4d155 100644
--- a/sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c
@@ -37,7 +37,7 @@
* o The enclosed hack of STREAMS support is pretty sick and most likely
* broken.
*
- * $Id: ip_rpcb_pxy.c,v 2.25.2.6 2007/01/17 11:34:54 darrenr Exp $
+ * $Id: ip_rpcb_pxy.c,v 2.25.2.7 2007/06/04 09:16:31 darrenr Exp $
*/
#define IPF_RPCB_PROXY
diff --git a/sys/contrib/ipfilter/netinet/ip_scan.c b/sys/contrib/ipfilter/netinet/ip_scan.c
index ad372166f3bc..54acb2aa4297 100644
--- a/sys/contrib/ipfilter/netinet/ip_scan.c
+++ b/sys/contrib/ipfilter/netinet/ip_scan.c
@@ -58,7 +58,7 @@ struct file;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_scan.c,v 2.40.2.9 2007/03/13 09:42:05 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_scan.c,v 2.40.2.10 2007/06/02 21:22:28 darrenr Exp $";
#endif
#ifdef IPFILTER_SCAN /* endif at bottom of file */
@@ -587,7 +587,9 @@ void *ctx;
case SIOCGSCST :
bcopy((char *)&ipsc_stat, (char *)&ipscs, sizeof(ipscs));
ipscs.iscs_list = ipsc_list;
- BCOPYOUT(&ipscs, data, sizeof(ipscs));
+ err = BCOPYOUT(&ipscs, data, sizeof(ipscs));
+ if (err != 0)
+ err = EFAULT;
break;
default :
err = EINVAL;
diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c
index 774dff3321c7..a63f9245b1c8 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.c
+++ b/sys/contrib/ipfilter/netinet/ip_state.c
@@ -111,7 +111,7 @@ struct file;
#if !defined(lint)
static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.186.2.69 2007/05/26 13:05:14 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.186.2.80 2007/10/16 09:33:23 darrenr Exp $";
#endif
static ipstate_t **ips_table = NULL;
@@ -548,7 +548,7 @@ void *ctx;
if (!(mode & FWRITE)) {
error = EPERM;
} else {
- fr_lock(data, &fr_state_lock);
+ error = fr_lock(data, &fr_state_lock);
}
break;
@@ -650,8 +650,8 @@ caddr_t data;
int error;
error = fr_inobj(data, &ips, IPFOBJ_STATESAVE);
- if (error)
- return EFAULT;
+ if (error != 0)
+ return error;
isn = ips.ips_next;
if (isn == NULL) {
@@ -680,9 +680,7 @@ caddr_t data;
bcopy((char *)isn->is_rule, (char *)&ips.ips_fr,
sizeof(ips.ips_fr));
error = fr_outobj(data, &ips, IPFOBJ_STATESAVE);
- if (error)
- return EFAULT;
- return 0;
+ return error;
}
@@ -991,6 +989,16 @@ u_int flags;
hv += is->is_src.i6[3];
}
#endif
+ if ((fin->fin_v == 4) &&
+ (fin->fin_flx & (FI_MULTICAST|FI_BROADCAST|FI_MBCAST))) {
+ if (fin->fin_out == 0) {
+ flags |= SI_W_DADDR|SI_CLONE;
+ hv -= is->is_daddr;
+ } else {
+ flags |= SI_W_SADDR|SI_CLONE;
+ hv -= is->is_saddr;
+ }
+ }
switch (is->is_p)
{
@@ -1188,7 +1196,8 @@ u_int flags;
sizeof(fr->fr_ifnames[0]));
} else {
is->is_ifp[out << 1] = fin->fin_ifp;
- COPYIFNAME(fin->fin_ifp, is->is_ifname[out << 1]);
+ COPYIFNAME(is->is_v, fin->fin_ifp,
+ is->is_ifname[out << 1]);
}
is->is_ifp[(out << 1) + 1] = fr->fr_ifas[1];
@@ -1208,7 +1217,8 @@ u_int flags;
if (fin->fin_ifp != NULL) {
is->is_ifp[out << 1] = fin->fin_ifp;
- COPYIFNAME(fin->fin_ifp, is->is_ifname[out << 1]);
+ COPYIFNAME(is->is_v, fin->fin_ifp,
+ is->is_ifname[out << 1]);
}
}
@@ -1437,12 +1447,13 @@ ipstate_t *is;
is->is_state[!source] = IPF_TCPS_CLOSED;
fr_movequeue(&is->is_sti, is->is_sti.tqe_ifq,
&ips_deletetq);
- MUTEX_ENTER(&is->is_lock);
+ MUTEX_EXIT(&is->is_lock);
return 0;
}
}
- if (fr_tcpinwindow(fin, fdata, tdata, tcp, is->is_flags)) {
+ ret = fr_tcpinwindow(fin, fdata, tdata, tcp, is->is_flags);
+ if (ret > 0) {
#ifdef IPFILTER_SCAN
if (is->is_flags & (IS_SC_CLIENT|IS_SC_SERVER)) {
ipsc_packet(fin, is);
@@ -1538,7 +1549,8 @@ ipstate_t *is;
/* ------------------------------------------------------------------------ */
/* Function: fr_tcpinwindow */
-/* Returns: int - 1 == packet inside TCP "window", 0 == not inside. */
+/* Returns: int - 1 == packet inside TCP "window", 0 == not inside, */
+/* 2 == packet seq number matches next expected */
/* Parameters: fin(I) - pointer to packet information */
/* fdata(I) - pointer to tcp state informatio (forward) */
/* tdata(I) - pointer to tcp state informatio (reverse) */
@@ -1622,14 +1634,12 @@ int flags;
/*
* Strict sequencing only allows in-order delivery.
*/
- if ((flags & IS_STRICT) != 0) {
- if (seq != fdata->td_end) {
+ if (seq != fdata->td_end) {
+ if ((flags & IS_STRICT) != 0) {
return 0;
}
}
-#define SEQ_GE(a,b) ((int)((a) - (b)) >= 0)
-#define SEQ_GT(a,b) ((int)((a) - (b)) > 0)
inseq = 0;
if ((SEQ_GE(fdata->td_maxend, end)) &&
(SEQ_GE(seq, fdata->td_end - maxwin)) &&
@@ -2026,7 +2036,7 @@ u_32_t cmask;
if (is->is_ifp[idx] == NULL &&
(*is->is_ifname[idx] == '\0' || *is->is_ifname[idx] == '*')) {
is->is_ifp[idx] = ifp;
- COPYIFNAME(ifp, is->is_ifname[idx]);
+ COPYIFNAME(is->is_v, ifp, is->is_ifname[idx]);
}
fin->fin_rev = rev;
return is;
@@ -2297,8 +2307,6 @@ u_int hv;
ipstate_t **isp;
u_int hvm;
- ASSERT(rw_read_locked(&ipf_state.ipf_lk) == 0);
-
hvm = is->is_hv;
/*
* Remove the hash from the old location...
@@ -2381,6 +2389,14 @@ ipftq_t **ifqp;
}
}
#endif
+ if ((v == 4) &&
+ (fin->fin_flx & (FI_MULTICAST|FI_BROADCAST|FI_MBCAST))) {
+ if (fin->fin_out == 0) {
+ hv -= src.in4.s_addr;
+ } else {
+ hv -= dst.in4.s_addr;
+ }
+ }
/*
* Search the hash table for matching packet header info.
@@ -2529,12 +2545,31 @@ retry_tcpudp:
}
RWLOCK_EXIT(&ipf_state);
- if (!tryagain && ips_stats.iss_wild) {
- hv -= dport;
- hv -= sport;
- tryagain = 1;
- WRITE_ENTER(&ipf_state);
- goto retry_tcpudp;
+ if (ips_stats.iss_wild) {
+ if (tryagain == 0) {
+ hv -= dport;
+ hv -= sport;
+ } else if (tryagain == 1) {
+ hv = fin->fin_fi.fi_p;
+ /*
+ * If we try to pretend this is a reply to a
+ * multicast/broadcast packet then we need to
+ * exclude part of the address from the hash
+ * calculation.
+ */
+ if (fin->fin_out == 0) {
+ hv += src.in4.s_addr;
+ } else {
+ hv += dst.in4.s_addr;
+ }
+ hv += dport;
+ hv += sport;
+ }
+ tryagain++;
+ if (tryagain <= 2) {
+ WRITE_ENTER(&ipf_state);
+ goto retry_tcpudp;
+ }
}
fin->fin_flx |= oow;
break;
@@ -2886,8 +2921,6 @@ ipstate_t *is;
int why;
{
- ASSERT(rw_read_locked(&ipf_state.ipf_lk) == 0);
-
/*
* Since we want to delete this, remove it from the state table,
* where it can be found & used, first.
@@ -2935,9 +2968,15 @@ int why;
* entry (such as ipfstat), it'll do the deref path that'll bring
* us back here to do the real delete & free.
*/
- is->is_ref--;
- if (is->is_ref > 0)
+ MUTEX_ENTER(&is->is_lock);
+ if (is->is_ref > 1) {
+ is->is_ref--;
+ MUTEX_EXIT(&is->is_lock);
return is->is_ref;
+ }
+ MUTEX_EXIT(&is->is_lock);
+
+ is->is_ref = 0;
if (is->is_tqehead[0] != NULL) {
if (fr_deletetimeoutqueue(is->is_tqehead[0]) == 0)
@@ -3534,7 +3573,7 @@ int flags;
if ((tcpflags & (TH_FIN|TH_ACK)) == TH_ACK) {
nstate = IPF_TCPS_TIME_WAIT;
}
- rval = 1;
+ rval = 2;
break;
case IPF_TCPS_LAST_ACK: /* 8 */
@@ -3558,24 +3597,14 @@ int flags;
case IPF_TCPS_FIN_WAIT_2: /* 9 */
/* NOT USED */
-#if 0
- rval = 1;
- if ((tcpflags & TH_OPENING) == TH_OPENING) {
- nstate = IPF_TCPS_SYN_RECEIVED;
- } else if (tcpflags & TH_SYN) {
- nstate = IPF_TCPS_SYN_SENT;
- } else if ((tcpflags & (TH_FIN|TH_ACK)) != 0) {
- nstate = IPF_TCPS_TIME_WAIT;
- }
-#endif
break;
case IPF_TCPS_TIME_WAIT: /* 10 */
/* we're in 2MSL timeout now */
- rval = 2;
if (ostate == IPF_TCPS_LAST_ACK) {
nstate = IPF_TCPS_CLOSED;
}
+ rval = 1;
break;
case IPF_TCPS_CLOSED: /* 11 */
@@ -3930,6 +3959,14 @@ ipftq_t *tqp;
/* Decrement the reference counter for this state table entry and free it */
/* if there are no more things using it. */
/* */
+/* This function is only called when cleaning up after increasing is_ref by */
+/* one earlier in the 'code path' so if is_ref is 1 when entering, we do */
+/* have an orphan, otherwise not. However there is a possible race between */
+/* the entry being deleted via flushing with an ioctl call (that calls the */
+/* delete function directly) and the tail end of packet processing so we */
+/* need to grab is_lock before doing the check to synchronise the two code */
+/* paths. */
+/* */
/* When operating in userland (ipftest), we have no timers to clear a state */
/* entry. Therefore, we make a few simple tests before deleting an entry */
/* outright. We compare states on each side looking for a combination of */
@@ -3952,17 +3989,23 @@ ipstate_t **isp;
is = *isp;
*isp = NULL;
- WRITE_ENTER(&ipf_state);
- is->is_ref--;
- if (is->is_ref == 0) {
- is->is_ref++; /* To counter ref-- in fr_delstate() */
- fr_delstate(is, ISL_EXPIRE);
+
+ MUTEX_ENTER(&is->is_lock);
+ if (is->is_ref > 1) {
+ is->is_ref--;
+ MUTEX_EXIT(&is->is_lock);
#ifndef _KERNEL
- } else if ((is->is_sti.tqe_state[0] > IPF_TCPS_ESTABLISHED) ||
+ if ((is->is_sti.tqe_state[0] > IPF_TCPS_ESTABLISHED) ||
(is->is_sti.tqe_state[1] > IPF_TCPS_ESTABLISHED)) {
- fr_delstate(is, ISL_ORPHAN);
+ fr_delstate(is, ISL_ORPHAN);
+ }
#endif
+ return;
}
+ MUTEX_EXIT(&is->is_lock);
+
+ WRITE_ENTER(&ipf_state);
+ fr_delstate(is, ISL_EXPIRE);
RWLOCK_EXIT(&ipf_state);
}
@@ -4056,7 +4099,7 @@ ipfgeniter_t *itp;
if (itp->igi_data == NULL)
return EFAULT;
- if (itp->igi_nitems == 0)
+ if (itp->igi_nitems < 1)
return ENOSPC;
if (itp->igi_type != IPFGENITER_STATE)
@@ -4078,33 +4121,29 @@ ipfgeniter_t *itp;
next = is->is_next;
}
- for (count = itp->igi_nitems; count > 0; count--) {
+ count = itp->igi_nitems;
+ for (;;) {
if (next != NULL) {
/*
* If we find a state entry to use, bump its
* reference count so that it can be used for
* is_next when we come back.
*/
- MUTEX_ENTER(&next->is_lock);
- next->is_ref++;
- MUTEX_EXIT(&next->is_lock);
- token->ipt_data = next;
+ if (count == 1) {
+ MUTEX_ENTER(&next->is_lock);
+ next->is_ref++;
+ MUTEX_EXIT(&next->is_lock);
+ token->ipt_data = next;
+ }
} else {
bzero(&zero, sizeof(zero));
next = &zero;
- token->ipt_data = (void *)-1;
count = 1;
+ token->ipt_data = NULL;
}
RWLOCK_EXIT(&ipf_state);
/*
- * If we had a prior pointer to a state entry, release it.
- */
- if (is != NULL) {
- fr_statederef(&is);
- }
-
- /*
* This should arguably be via fr_outobj() so that the state
* structure can (if required) be massaged going out.
*/
@@ -4115,9 +4154,14 @@ ipfgeniter_t *itp;
break;
dst += sizeof(*next);
+ count--;
+
READ_ENTER(&ipf_state);
- is = next;
- next = is->is_next;
+ next = next->is_next;
+ }
+
+ if (is != NULL) {
+ fr_statederef(&is);
}
return error;
diff --git a/sys/contrib/ipfilter/netinet/ip_state.h b/sys/contrib/ipfilter/netinet/ip_state.h
index e19df1e3553c..71dae1d0abe9 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.h
+++ b/sys/contrib/ipfilter/netinet/ip_state.h
@@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed
- * $Id: ip_state.h,v 2.68.2.8 2007/05/11 10:44:14 darrenr Exp $
+ * $Id: ip_state.h,v 2.68.2.10 2007/10/16 09:33:24 darrenr Exp $
*/
#ifndef __IP_STATE_H__
#define __IP_STATE_H__
@@ -24,10 +24,8 @@ struct ipscan;
# define IPSTATE_MAX 4013 /* Maximum number of states held */
#endif
-#define PAIRS(s1,d1,s2,d2) ((((s1) == (s2)) && ((d1) == (d2))) ||\
- (((s1) == (d2)) && ((d1) == (s2))))
-#define IPPAIR(s1,d1,s2,d2) PAIRS((s1).s_addr, (d1).s_addr, \
- (s2).s_addr, (d2).s_addr)
+#define SEQ_GE(a,b) ((int)((a) - (b)) >= 0)
+#define SEQ_GT(a,b) ((int)((a) - (b)) > 0)
typedef struct ipstate {
diff --git a/sys/contrib/ipfilter/netinet/ip_sync.c b/sys/contrib/ipfilter/netinet/ip_sync.c
index c2eff0eaff45..b145539336cd 100644
--- a/sys/contrib/ipfilter/netinet/ip_sync.c
+++ b/sys/contrib/ipfilter/netinet/ip_sync.c
@@ -96,7 +96,7 @@ struct file;
/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_sync.c,v 2.40.2.8 2006/07/14 06:12:20 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_sync.c,v 2.40.2.9 2007/06/02 21:22:28 darrenr Exp $";
#endif
#define SYNC_STATETABSZ 256
@@ -299,7 +299,7 @@ struct uio *uio;
if (uio->uio_resid >= sizeof(sh)) {
- err = UIOMOVE((caddr_t)&sh, sizeof(sh), UIO_WRITE, uio);
+ err = UIOMOVE(&sh, sizeof(sh), UIO_WRITE, uio);
if (err) {
if (ipf_sync_debug > 2)
@@ -371,7 +371,7 @@ struct uio *uio;
if (uio->uio_resid >= sh.sm_len) {
- err = UIOMOVE((caddr_t)data, sh.sm_len, UIO_WRITE, uio);
+ err = UIOMOVE(data, sh.sm_len, UIO_WRITE, uio);
if (err) {
if (ipf_sync_debug > 2)
@@ -471,7 +471,7 @@ struct uio *uio;
READ_ENTER(&ipf_syncstate);
while ((sl_tail < sl_idx) && (uio->uio_resid > sizeof(*sl))) {
sl = synclog + sl_tail++;
- err = UIOMOVE((caddr_t)sl, sizeof(*sl), UIO_READ, uio);
+ err = UIOMOVE(sl, sizeof(*sl), UIO_READ, uio);
if (err != 0)
break;
}
@@ -479,7 +479,7 @@ struct uio *uio;
while ((su_tail < su_idx) && (uio->uio_resid > sizeof(*su))) {
su = syncupd + su_tail;
su_tail++;
- err = UIOMOVE((caddr_t)su, sizeof(*su), UIO_READ, uio);
+ err = UIOMOVE(su, sizeof(*su), UIO_READ, uio);
if (err != 0)
break;
if (su->sup_hdr.sm_sl != NULL)
diff --git a/sys/contrib/ipfilter/netinet/ipl.h b/sys/contrib/ipfilter/netinet/ipl.h
index 2bc9a1dda220..614250acf3d0 100644
--- a/sys/contrib/ipfilter/netinet/ipl.h
+++ b/sys/contrib/ipfilter/netinet/ipl.h
@@ -4,14 +4,14 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ipl.h 1.21 6/5/96
- * $Id: ipl.h,v 2.52.2.25 2007/05/31 11:40:43 darrenr Exp $
+ * $Id: ipl.h,v 2.52.2.30 2007/10/16 09:41:00 darrenr Exp $
*/
#ifndef __IPL_H__
#define __IPL_H__
-#define IPL_VERSION "IP Filter: v4.1.23"
+#define IPL_VERSION "IP Filter: v4.1.28"
-#define IPFILTER_VERSION 4012300
+#define IPFILTER_VERSION 4012800
#endif
diff --git a/sys/contrib/ipfilter/netinet/mlfk_ipl.c b/sys/contrib/ipfilter/netinet/mlfk_ipl.c
index 3f042352b22d..7718bd97cd50 100644
--- a/sys/contrib/ipfilter/netinet/mlfk_ipl.c
+++ b/sys/contrib/ipfilter/netinet/mlfk_ipl.c
@@ -204,6 +204,11 @@ ipf_modload()
ipf_devs[i] = make_dev(&ipl_cdevsw, i, 0, 0, 0600, c);
}
+ error = ipf_pfil_hook();
+ if (error != 0)
+ return error;
+ ipf_event_reg();
+
if (FR_ISPASS(fr_pass))
defpass = "pass";
else if (FR_ISBLOCK(fr_pass))
@@ -237,7 +242,11 @@ ipf_modunload()
return EBUSY;
if (fr_running >= 0) {
+ ipf_pfil_unhook();
+ ipf_event_dereg();
+ WRITE_ENTER(&ipf_global);
error = ipfdetach();
+ RWLOCK_EXIT(&ipf_global);
if (error != 0)
return error;
} else