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>