Page MenuHomeFreeBSD

D17576.diff
No OneTemporary

D17576.diff

Index: head/sys/net/if_lagg.c
===================================================================
--- head/sys/net/if_lagg.c
+++ head/sys/net/if_lagg.c
@@ -633,11 +633,18 @@
{
struct lagg_softc *sc_ptr;
struct lagg_port *lp, *tlp;
- int error, i;
+ struct ifreq ifr;
+ int error, i, oldmtu;
uint64_t *pval;
LAGG_XLOCK_ASSERT(sc);
+ if (sc->sc_ifp == ifp) {
+ if_printf(sc->sc_ifp,
+ "cannot add a lagg to itself as a port\n");
+ return (EINVAL);
+ }
+
/* Limit the maximal number of lagg ports */
if (sc->sc_count >= LAGG_MAX_PORTS)
return (ENOSPC);
@@ -656,12 +663,25 @@
return (EPROTONOSUPPORT);
/* Allow the first Ethernet member to define the MTU */
- if (CK_SLIST_EMPTY(&sc->sc_ports))
+ oldmtu = -1;
+ if (CK_SLIST_EMPTY(&sc->sc_ports)) {
sc->sc_ifp->if_mtu = ifp->if_mtu;
- else if (sc->sc_ifp->if_mtu != ifp->if_mtu) {
- if_printf(sc->sc_ifp, "invalid MTU for %s\n",
- ifp->if_xname);
- return (EINVAL);
+ } else if (sc->sc_ifp->if_mtu != ifp->if_mtu) {
+ if (ifp->if_ioctl == NULL) {
+ if_printf(sc->sc_ifp, "cannot change MTU for %s\n",
+ ifp->if_xname);
+ return (EINVAL);
+ }
+ oldmtu = ifp->if_mtu;
+ strlcpy(ifr.ifr_name, ifp->if_xname, sizeof(ifr.ifr_name));
+ ifr.ifr_mtu = sc->sc_ifp->if_mtu;
+ error = (*ifp->if_ioctl)(ifp, SIOCSIFMTU, (caddr_t)&ifr);
+ if (error != 0) {
+ if_printf(sc->sc_ifp, "invalid MTU for %s\n",
+ ifp->if_xname);
+ return (error);
+ }
+ ifr.ifr_mtu = oldmtu;
}
lp = malloc(sizeof(struct lagg_port), M_DEVBUF, M_WAITOK|M_ZERO);
@@ -673,6 +693,9 @@
if (ifp == sc_ptr->sc_ifp) {
LAGG_LIST_UNLOCK();
free(lp, M_DEVBUF);
+ if (oldmtu != -1)
+ (*ifp->if_ioctl)(ifp, SIOCSIFMTU,
+ (caddr_t)&ifr);
return (EINVAL);
/* XXX disable stacking for the moment, its untested */
#ifdef LAGG_PORT_STACKING
@@ -681,6 +704,9 @@
LAGG_MAX_STACKING) {
LAGG_LIST_UNLOCK();
free(lp, M_DEVBUF);
+ if (oldmtu != -1)
+ (*ifp->if_ioctl)(ifp, SIOCSIFMTU,
+ (caddr_t)&ifr);
return (E2BIG);
}
#endif
@@ -746,6 +772,8 @@
if ((error = lagg_proto_addport(sc, lp)) != 0) {
/* Remove the port, without calling pr_delport. */
lagg_port_destroy(lp, 0);
+ if (oldmtu != -1)
+ (*ifp->if_ioctl)(ifp, SIOCSIFMTU, (caddr_t)&ifr);
return (error);
}
@@ -1464,8 +1492,31 @@
break;
case SIOCSIFMTU:
- /* Do not allow the MTU to be directly changed */
- error = EINVAL;
+ LAGG_XLOCK(sc);
+ CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
+ if (lp->lp_ioctl != NULL)
+ error = (*lp->lp_ioctl)(lp->lp_ifp, cmd, data);
+ else
+ error = EINVAL;
+ if (error != 0) {
+ if_printf(ifp,
+ "failed to change MTU to %d on port %s, "
+ "reverting all ports to original MTU (%d)\n",
+ ifr->ifr_mtu, lp->lp_ifp->if_xname, ifp->if_mtu);
+ break;
+ }
+ }
+ if (error == 0) {
+ ifp->if_mtu = ifr->ifr_mtu;
+ } else {
+ /* set every port back to the original MTU */
+ ifr->ifr_mtu = ifp->if_mtu;
+ CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
+ if (lp->lp_ioctl != NULL)
+ (*lp->lp_ioctl)(lp->lp_ifp, cmd, data);
+ }
+ }
+ LAGG_XUNLOCK(sc);
break;
default:

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 15, 6:45 AM (8 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28730608
Default Alt Text
D17576.diff (3 KB)

Event Timeline