summaryrefslogtreecommitdiffstats
path: root/sys/net/if_bridge.c
diff options
context:
space:
mode:
authorhrs <hrs@FreeBSD.org>2010-01-31 08:16:37 +0000
committerhrs <hrs@FreeBSD.org>2010-01-31 08:16:37 +0000
commit0f402c23311b40ba88b3ea3c95cf73ee0b6cf4d4 (patch)
tree1402a70aed70b20c781fa78b6f1ad15dd0a24f72 /sys/net/if_bridge.c
parent68c0faaca6c6be70bf107bd698487ce090374471 (diff)
downloadFreeBSD-src-0f402c23311b40ba88b3ea3c95cf73ee0b6cf4d4.zip
FreeBSD-src-0f402c23311b40ba88b3ea3c95cf73ee0b6cf4d4.tar.gz
- Check if_type of "addm <interface>" before setting the
interface's MTU to the if_bridge(4) interface. This fixes a bug that MTU value of "addm <interface>" is used even when it is invalid for the if_bridge(4) member: # ifconfig bridge0 create # ifconfig bridge0 bridge0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500 ... # ifconfig bridge0 addm lo0 ifconfig: BRDGADD lo0: Invalid argument # ifconfig bridge0 bridge0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 16384 ... - Do not ignore MTU value of an interface even when if_type == IFT_GIF. This fixes MTU mismatch when an if_bridge(4) interface has a gif(4) interface and no other interface as the member, and it is directly used for L2 communication with EtherIP tunneling enabled. - Implement SIOCSIFMTU ioctl. Changing the MTU is allowed only when all members have the same MTU value.
Diffstat (limited to 'sys/net/if_bridge.c')
-rw-r--r--sys/net/if_bridge.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 7084fe6..d985e98 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -683,6 +683,8 @@ static int
bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
struct bridge_softc *sc = ifp->if_softc;
+ struct ifreq *ifr = (struct ifreq *)data;
+ struct bridge_iflist *bif;
struct thread *td = curthread;
union {
struct ifbreq ifbreq;
@@ -772,10 +774,29 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
case SIOCSIFMTU:
- /* Do not allow the MTU to be changed on the bridge */
- error = EINVAL;
+ if (ifr->ifr_mtu < 576) {
+ error = EINVAL;
+ break;
+ }
+ if (LIST_EMPTY(&sc->sc_iflist)) {
+ sc->sc_ifp->if_mtu = ifr->ifr_mtu;
+ break;
+ }
+ BRIDGE_LOCK(sc);
+ LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
+ if (bif->bif_ifp->if_mtu != ifr->ifr_mtu) {
+ log(LOG_NOTICE, "%s: invalid MTU: %lu(%s)"
+ " != %d\n", sc->sc_ifp->if_xname,
+ bif->bif_ifp->if_mtu,
+ bif->bif_ifp->if_xname, ifr->ifr_mtu);
+ error = EINVAL;
+ break;
+ }
+ }
+ if (!error)
+ sc->sc_ifp->if_mtu = ifr->ifr_mtu;
+ BRIDGE_UNLOCK(sc);
break;
-
default:
/*
* drop the lock as ether_ioctl() will call bridge_start() and
@@ -989,17 +1010,6 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
if (ifs == bif->bif_ifp)
return (EBUSY);
- /* Allow the first Ethernet member to define the MTU */
- if (ifs->if_type != IFT_GIF) {
- if (LIST_EMPTY(&sc->sc_iflist))
- sc->sc_ifp->if_mtu = ifs->if_mtu;
- else if (sc->sc_ifp->if_mtu != ifs->if_mtu) {
- if_printf(sc->sc_ifp, "invalid MTU for %s\n",
- ifs->if_xname);
- return (EINVAL);
- }
- }
-
if (ifs->if_bridge == sc)
return (EEXIST);
@@ -1025,6 +1035,16 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
goto out;
}
+ /* Allow the first Ethernet member to define the MTU */
+ if (LIST_EMPTY(&sc->sc_iflist))
+ sc->sc_ifp->if_mtu = ifs->if_mtu;
+ else if (sc->sc_ifp->if_mtu != ifs->if_mtu) {
+ if_printf(sc->sc_ifp, "invalid MTU: %lu(%s) != %lu\n",
+ ifs->if_mtu, ifs->if_xname, sc->sc_ifp->if_mtu);
+ error = EINVAL;
+ goto out;
+ }
+
/*
* Assign the interface's MAC address to the bridge if it's the first
* member and the MAC address of the bridge has not been changed from
OpenPOWER on IntegriCloud