Add code that clears certain capabilities from the member interface, these are
restored when its removed from the bridge. At the moment we only clear IFCAP_TXCSUM. Since a locally generated packet on the bridge may be sent out any one or more interfaces it cant be assumed that every card does hardware csums. Most bridges don't generate a lot of traffic themselves so turning off offloading won't hurt, bridged packets are unaffected. Tested by: Bruce Walker (bmw borderware.com) MFC after: 5 days
This commit is contained in:
parent
a008796617
commit
7c2fb83a0b
@ -146,6 +146,9 @@ as on the interface on which the packet arrives or departs.
|
||||
.Pp
|
||||
The MTU of the first member interface to be added is used as the bridge MTU,
|
||||
all additional members are required to have exactly the same value.
|
||||
.Pp
|
||||
The TXCSUM capability is disabled for any interface added to the bridge, this
|
||||
is restored when the interface is removed again.
|
||||
.Sh EXAMPLES
|
||||
The following when placed in the file
|
||||
.Pa /etc/rc.conf
|
||||
|
@ -170,6 +170,11 @@ __FBSDID("$FreeBSD$");
|
||||
#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_clone *, int);
|
||||
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 *);
|
||||
@ -664,6 +670,42 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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:
|
||||
*
|
||||
@ -727,6 +769,7 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
|
||||
* 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, void *arg)
|
||||
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, void *arg)
|
||||
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, void *arg)
|
||||
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, struct ifnet *dst_ifp, struct mbuf *m)
|
||||
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;
|
||||
|
||||
|
@ -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 */
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user