PF routing broken

Matthew Dillon dillon at apollo.backplane.com
Tue Jan 17 12:19:32 PST 2006


:I had the pleasure to experience this with ipf+if_bridge today.  Of 
:course the ruleset wasn't what i had intended, but yet this works with 
:oldbridge...
:
:cheers
:   simon

    Please try this patch.  This patch releases the serializer on
    ifp before calling any IPF functions.  Before it was only conditionally
    releasing the serializer in certain cases.

						-Matt


Index: if_bridge.c
===================================================================
RCS file: /cvs/src/sys/net/bridge/if_bridge.c,v
retrieving revision 1.4
diff -u -r1.4 if_bridge.c
--- if_bridge.c	14 Jan 2006 11:05:17 -0000	1.4
+++ if_bridge.c	17 Jan 2006 20:12:28 -0000
@@ -1391,6 +1391,12 @@
 	eh = mtod(m, struct ether_header *);
 
 	/*
+	 * Various ifp's are used below, release the serializer for
+	 * the bridge ifp so other ifp serializers can be acquired.
+	 */
+	lwkt_serialize_exit(ifp->if_serializer);
+
+	/*
 	 * If the interface is learning, and the source
 	 * address is valid and not multicast, record
 	 * the address.
@@ -1409,7 +1415,7 @@
 	if ((bif->bif_flags & IFBIF_STP) != 0 &&
 	    bif->bif_state == BSTP_IFSTATE_LEARNING) {
 		m_freem(m);
-		return;
+		goto done;
 	}
 
 	/*
@@ -1425,7 +1431,7 @@
 		dst_if = bridge_rtlookup(sc, eh->ether_dhost);
 		if (src_if == dst_if) {
 			m_freem(m);
-			return;
+			goto done;
 		}
 	} else {
 		/* ...forward it to all interfaces. */
@@ -1440,16 +1446,14 @@
 #endif
 	    ) {
 		if (bridge_pfil(&m, ifp, src_if, PFIL_IN) != 0)
-			return;
+			goto done;
 		if (m == NULL)
-			return;
+			goto done;
 	}
 
 	if (dst_if == NULL) {
-		lwkt_serialize_exit(ifp->if_serializer);
 		bridge_broadcast(sc, src_if, m, 1);
-		lwkt_serialize_enter(ifp->if_serializer);
-		return;
+		goto done;
 	}
 
 	/*
@@ -1458,13 +1462,13 @@
 	 */
 	if ((dst_if->if_flags & IFF_RUNNING) == 0) {
 		m_freem(m);
-		return;
+		goto done;
 	}
 	bif = bridge_lookup_member_if(sc, dst_if);
 	if (bif == NULL) {
 		/* Not a member of the bridge (anymore?) */
 		m_freem(m);
-		return;
+		goto done;
 	}
 
 	if (bif->bif_flags & IFBIF_STP) {
@@ -1472,7 +1476,7 @@
 		case BSTP_IFSTATE_DISABLED:
 		case BSTP_IFSTATE_BLOCKING:
 			m_freem(m);
-			return;
+			goto done;
 		}
 	}
 
@@ -1482,12 +1486,17 @@
 #endif
 	    ) {
 		if (bridge_pfil(&m, sc->sc_ifp, dst_if, PFIL_OUT) != 0)
-			return;
+			goto done;
 		if (m == NULL)
-			return;
+			goto done;
 	}
-	lwkt_serialize_exit(ifp->if_serializer);
 	bridge_enqueue(sc, dst_if, m);
+
+	/*
+	 * ifp's serializer was held on entry and is expected to be held
+	 * on return.
+	 */
+done:
 	lwkt_serialize_enter(ifp->if_serializer);
 }
 





More information about the Bugs mailing list