aboutsummaryrefslogtreecommitdiffstats
path: root/sys/contrib/ipfilter/netinet/fil.c
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 /sys/contrib/ipfilter/netinet/fil.c
parent103b406762fd9664783670aae8479f3a8ec71c61 (diff)
downloadsrc-e8e48c1c7b41ecab29b107b5ee35cdea9fdc5c20.tar.gz
src-e8e48c1c7b41ecab29b107b5ee35cdea9fdc5c20.zip
Import IPFilter 4.1.28
Notes
Notes: svn path=/vendor-sys/ipfilter/dist/; revision=172771
Diffstat (limited to 'sys/contrib/ipfilter/netinet/fil.c')
-rw-r--r--sys/contrib/ipfilter/netinet/fil.c286
1 files changed, 163 insertions, 123 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;