svn commit: r203272 - head/sys/net

Hiroki Sato hrs at FreeBSD.org
Sun Jan 31 08:16:38 UTC 2010


Author: hrs
Date: Sun Jan 31 08:16:37 2010
New Revision: 203272
URL: http://svn.freebsd.org/changeset/base/203272

Log:
  - 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.

Modified:
  head/sys/net/if_bridge.c

Modified: head/sys/net/if_bridge.c
==============================================================================
--- head/sys/net/if_bridge.c	Sun Jan 31 03:06:12 2010	(r203271)
+++ head/sys/net/if_bridge.c	Sun Jan 31 08:16:37 2010	(r203272)
@@ -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 c
 		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
 		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
 		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


More information about the svn-src-all mailing list