Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 13 Jan 2006 23:08:00 +1300
From:      Andrew Thompson <thompsa@freebsd.org>
To:        Bruce Walker <bmw@borderware.com>
Cc:        freebsd-net@freebsd.org
Subject:   Re: if_bridge FreeBSD 6.0 on a Broadcom interface not working
Message-ID:  <20060113100800.GN2332@heff.fud.org.nz>
In-Reply-To: <43C710C8.6000401@borderware.com>
References:  <3e1162e60601061523k742d46cdreade7fb276232f13@mail.gmail.com> <43C53E09.9020108@borderware.com> <20060112234328.GL2332@heff.fud.org.nz> <43C710C8.6000401@borderware.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--J5MfuwkIyy7RmF4Q
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Thu, Jan 12, 2006 at 09:30:32PM -0500, Bruce Walker wrote:
> Andrew Thompson wrote:
> > 
> >if_bridge doesnt handle interfaces with TXCSUM at the moment, you can
> >work around this by clearing this with 'ifconfig xxx -txcsum', where xxx
> >is your em or bge card.
> >
> >Im testing a patch to fix this.
> 
> W00t!  :-)  That's it; perfect. No checksum errors, and bridging works 
> great.
> 
> I'll watch for your patch and test it asap.
> 

Can you give this patch a test. Im a bit concerned that the conditional
grabbing of Giant may cause a LOR, witness didnt complain with
debug.mpsafenet=0


cheers,
Andrew

--J5MfuwkIyy7RmF4Q
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="bridge-caps2.diff"

Index: if_bridge.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_bridge.c,v
retrieving revision 1.49
diff -u -p -r1.49 if_bridge.c
--- if_bridge.c	2 Jan 2006 23:02:43 -0000	1.49
+++ if_bridge.c	13 Jan 2006 10:01:02 -0000
@@ -170,6 +170,11 @@ __FBSDID("$FreeBSD: src/sys/net/if_bridg
 #define	BRIDGE_RTABLE_PRUNE_PERIOD	(5 * 60)
 #endif
 
+/*
+ * List of capabilities to mask on the member interface.
+ */
+#define	BRIDGE_IFCAPS_MASK		IFCAP_TXCSUM
+
 static struct mtx 	bridge_list_mtx;
 eventhandler_tag	bridge_detach_cookie = NULL;
 
@@ -181,6 +186,7 @@ static int	bridge_clone_create(struct if
 static void	bridge_clone_destroy(struct ifnet *);
 
 static int	bridge_ioctl(struct ifnet *, u_long, caddr_t);
+static void	bridge_mutecaps(struct bridge_iflist *, int);
 static void	bridge_ifdetach(void *arg __unused, struct ifnet *);
 static void	bridge_init(void *);
 static void	bridge_dummynet(struct mbuf *, struct ifnet *);
@@ -665,6 +671,42 @@ bridge_ioctl(struct ifnet *ifp, u_long c
 }
 
 /*
+ * bridge_mutecaps:
+ *
+ *	Clear or restore unwanted capabilities on the member interface
+ */
+static void
+bridge_mutecaps(struct bridge_iflist *bif, int mute)
+{
+	struct ifnet *ifp = bif->bif_ifp;
+	struct ifreq ifr;
+	int error;
+
+	if (ifp->if_ioctl == NULL)
+		return;
+
+	bzero(&ifr, sizeof ifr);
+	ifr.ifr_reqcap = ifp->if_capenable;
+
+	if (mute) {
+		/* mask off and save capabilities */
+		bif->bif_mutecap = ifr.ifr_reqcap & BRIDGE_IFCAPS_MASK;
+		if (bif->bif_mutecap != 0)
+			ifr.ifr_reqcap &= ~BRIDGE_IFCAPS_MASK;
+	} else
+		/* restore muted capabilities */
+		ifr.ifr_reqcap |= bif->bif_mutecap;
+
+
+	if (bif->bif_mutecap != 0) {
+		IFF_LOCKGIANT(ifp);
+		error = (*ifp->if_ioctl)(ifp, SIOCSIFCAP, (caddr_t)&ifr);
+		IFF_UNLOCKGIANT(ifp);
+	}
+}
+	
+
+/*
  * bridge_lookup_member:
  *
  *	Lookup a bridge member interface.
@@ -727,6 +769,7 @@ bridge_delete_member(struct bridge_softc
 			 * Take the interface out of promiscuous mode.
 			 */
 			(void) ifpromisc(ifs, 0);
+			bridge_mutecaps(bif, 0);
 			break;
 
 		case IFT_GIF:
@@ -810,6 +853,11 @@ bridge_ioctl_add(struct bridge_softc *sc
 	if (bif == NULL)
 		return (ENOMEM);
 
+	bif->bif_ifp = ifs;
+	bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
+	bif->bif_priority = BSTP_DEFAULT_PORT_PRIORITY;
+	bif->bif_path_cost = BSTP_DEFAULT_PATH_COST;
+
 	switch (ifs->if_type) {
 	case IFT_ETHER:
 	case IFT_L2VLAN:
@@ -819,6 +867,8 @@ bridge_ioctl_add(struct bridge_softc *sc
 		error = ifpromisc(ifs, 1);
 		if (error)
 			goto out;
+
+		bridge_mutecaps(bif, 1);
 		break;
 
 	case IFT_GIF:
@@ -829,11 +879,6 @@ bridge_ioctl_add(struct bridge_softc *sc
 		goto out;
 	}
 
-	bif->bif_ifp = ifs;
-	bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
-	bif->bif_priority = BSTP_DEFAULT_PORT_PRIORITY;
-	bif->bif_path_cost = BSTP_DEFAULT_PATH_COST;
-
 	ifs->if_bridge = sc;
 	/*
 	 * XXX: XLOCK HERE!?!
@@ -1436,11 +1481,6 @@ bridge_enqueue(struct bridge_softc *sc, 
 	int len, err;
 	short mflags;
 
-	/*
-	 * Clear any in-bound checksum flags for this packet.
-	 */
-	m->m_pkthdr.csum_flags = 0;
-
 	len = m->m_pkthdr.len;
 	mflags = m->m_flags;
 
Index: if_bridgevar.h
===================================================================
RCS file: /home/ncvs/src/sys/net/if_bridgevar.h,v
retrieving revision 1.9
diff -u -p -r1.9 if_bridgevar.h
--- if_bridgevar.h	2 Jan 2006 09:50:34 -0000	1.9
+++ if_bridgevar.h	13 Jan 2006 04:02:10 -0000
@@ -248,6 +248,7 @@ struct bridge_iflist {
 	uint8_t			bif_priority;
 	struct ifnet		*bif_ifp;	/* member if */
 	uint32_t		bif_flags;	/* member if flags */
+	int			bif_mutecap;	/* member muted caps */
 };
 
 /*

--J5MfuwkIyy7RmF4Q--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060113100800.GN2332>