svn commit: r236559 - head/sys/net

Alexander V. Chernikov melifaro at FreeBSD.org
Mon Jun 4 12:36:59 UTC 2012


Author: melifaro
Date: Mon Jun  4 12:36:58 2012
New Revision: 236559
URL: http://svn.freebsd.org/changeset/base/236559

Log:
  Fix panic introduced by r235745. Panic occurs after first packet traverse renamed interface.
  Add several comments on locking
  
  Found by:         avg
  Approved by:      ae(mentor)
  Tested by:        avg
  MFC after:        1 week

Modified:
  head/sys/net/bpf.c

Modified: head/sys/net/bpf.c
==============================================================================
--- head/sys/net/bpf.c	Mon Jun  4 12:28:56 2012	(r236558)
+++ head/sys/net/bpf.c	Mon Jun  4 12:36:58 2012	(r236559)
@@ -1704,6 +1704,14 @@ bpfioctl(struct cdev *dev, u_long cmd, c
 /*
  * Set d's packet filter program to fp.  If this file already has a filter,
  * free it and replace it.  Returns EINVAL for bogus requests.
+ *
+ * Note we need global lock here to serialize bpf_setf() and bpf_setif() calls
+ * since reading d->bd_bif can't be protected by d or interface lock due to
+ * lock order.
+ *
+ * Additionally, we have to acquire interface write lock due to bpf_mtap() uses
+ * interface read lock to read all filers.
+ *
  */
 static int
 bpf_setf(struct bpf_d *d, struct bpf_program *fp, u_long cmd)
@@ -2535,20 +2543,32 @@ bpfdetach(struct ifnet *ifp)
 }
 
 /*
- * Interface departure handler
+ * Interface departure handler.
+ * Note departure event does not guagantee interface is going down.
  */
 static void
 bpf_ifdetach(void *arg __unused, struct ifnet *ifp)
 {
 	struct bpf_if *bp;
 
-	if ((bp = ifp->if_bpf) == NULL)
+	BPF_LOCK();
+	if ((bp = ifp->if_bpf) == NULL) {
+		BPF_UNLOCK();
+		return;
+	}
+
+	/* Check if bpfdetach() was called previously */
+	if ((bp->flags & BPFIF_FLAG_DYING) == 0) {
+		BPF_UNLOCK();
 		return;
+	}
 
 	CTR3(KTR_NET, "%s: freing BPF instance %p for interface %p",
 	    __func__, bp, ifp);
 
 	ifp->if_bpf = NULL;
+	BPF_UNLOCK();
+
 	rw_destroy(&bp->bif_lock);
 	free(bp, M_BPF);
 }


More information about the svn-src-head mailing list