From owner-svn-src-head@freebsd.org Tue Oct 30 09:53:58 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5527B10DD70C; Tue, 30 Oct 2018 09:53:58 +0000 (UTC) (envelope-from araujo@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 056707AC71; Tue, 30 Oct 2018 09:53:58 +0000 (UTC) (envelope-from araujo@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id D96111BD92; Tue, 30 Oct 2018 09:53:57 +0000 (UTC) (envelope-from araujo@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w9U9rvMQ041117; Tue, 30 Oct 2018 09:53:57 GMT (envelope-from araujo@FreeBSD.org) Received: (from araujo@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w9U9rvOI041116; Tue, 30 Oct 2018 09:53:57 GMT (envelope-from araujo@FreeBSD.org) Message-Id: <201810300953.w9U9rvOI041116@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: araujo set sender to araujo@FreeBSD.org using -f From: Marcelo Araujo Date: Tue, 30 Oct 2018 09:53:57 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r339909 - head/sys/net X-SVN-Group: head X-SVN-Commit-Author: araujo X-SVN-Commit-Paths: head/sys/net X-SVN-Commit-Revision: 339909 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 30 Oct 2018 09:53:58 -0000 Author: araujo Date: Tue Oct 30 09:53:57 2018 New Revision: 339909 URL: https://svnweb.freebsd.org/changeset/base/339909 Log: Allow changing lagg(4) MTU. Previously, changing the MTU would require destroying the lagg and creating a new one. Now it is allowed to change the MTU of the lagg interface and the MTU of the ports will be set to match. If any port cannot set the new MTU, all ports are reverted to the original MTU of the lagg. Additionally, when adding ports, the MTU of a port will be automatically set to the MTU of the lagg. As always, the MTU of the lagg is initially determined by the MTU of the first port added. If adding an interface as a port for some reason fails, that interface is reverted to its original MTU. Submitted by: Ryan Moeller Reviewed by: mav Relnotes: Yes Sponsored by: iXsystems Inc. Differential Revision: https://reviews.freebsd.org/D17576 Modified: head/sys/net/if_lagg.c Modified: head/sys/net/if_lagg.c ============================================================================== --- head/sys/net/if_lagg.c Tue Oct 30 09:43:26 2018 (r339908) +++ head/sys/net/if_lagg.c Tue Oct 30 09:53:57 2018 (r339909) @@ -633,11 +633,18 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet * { 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 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet * 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 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet * 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_port_create(struct lagg_softc *sc, struct ifnet * 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 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet * 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 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data 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: