netbsd-bugs@netbsd.org
[Top] [All Lists]

Re: kern/37037

Subject: Re: kern/37037
From: Martti Kuparinen
Date: Sat, 29 Sep 2007 20:35:58 UTC
Newsgroups: fa.netbsd.bugs

The following reply was made to PR kern/37037; it has been noted by GNATS.

From: Martti Kuparinen <martti.kuparinen@xxxxxx>
To: gnats-bugs@xxxxxxxxxx
Cc: juan@xxxxxxxxxxx, darrenr@xxxxxxxxxx
Subject: Re: kern/37037
Date: Sat, 29 Sep 2007 21:37:22 +0300 (EEST)

 After some help from Darren, I created this patch? Does it help?
 
 Darren: does it look correct? I took 4.1.27 and added our local changes
 to it (caddr_t -> void * etc.)
 
 
 Index: ip_frag.c
 ===================================================================
 RCS file: /cvsroot/src/sys/dist/ipf/netinet/ip_frag.c,v
 retrieving revision 1.7
 diff -u -r1.7 ip_frag.c
 --- ip_frag.c  16 Jun 2007 10:52:28 -0000      1.7
 +++ ip_frag.c  29 Sep 2007 18:29:12 -0000
 @@ -106,7 +106,7 @@
   __KERNEL_RCSID(0, "$NetBSD: ip_frag.c,v 1.7 2007/06/16 10:52:28 martin Exp 
$");
   #else
   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
   #endif
 
 @@ -943,16 +943,16 @@
        } 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));
 Index: ip_state.c
 ===================================================================
 RCS file: /cvsroot/src/sys/dist/ipf/netinet/ip_state.c,v
 retrieving revision 1.29
 diff -u -r1.29 ip_state.c
 --- ip_state.c 17 Sep 2007 06:56:15 -0000      1.29
 +++ ip_state.c 29 Sep 2007 18:29:15 -0000
 @@ -117,7 +117,7 @@
   __KERNEL_RCSID(0, "$NetBSD: ip_state.c,v 1.29 2007/09/17 06:56:15 martti Exp 
$");
   #else
   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.78 2007/09/20 
12:51:53 darrenr Exp $";
   #endif
   #endif
 
 @@ -657,8 +657,8 @@
        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) {
 @@ -687,9 +687,7 @@
                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;
   }
 
 
 @@ -1444,7 +1442,7 @@
                        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;
                }
        }
 @@ -2308,8 +2306,6 @@
        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...
 @@ -2897,8 +2893,6 @@
   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.
 @@ -4072,7 +4066,7 @@
        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)
 @@ -4094,33 +4088,29 @@
                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.
                 */
 @@ -4131,9 +4121,14 @@
                        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;
 

<Prev in Thread] Current Thread [Next in Thread>