diff options
Diffstat (limited to 'sys/net/if_lagg.c')
-rw-r--r-- | sys/net/if_lagg.c | 57 |
1 files changed, 35 insertions, 22 deletions
diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c index 554d8c2c1bcb..bb882ac819ad 100644 --- a/sys/net/if_lagg.c +++ b/sys/net/if_lagg.c @@ -137,6 +137,7 @@ static void lagg_port_ifdetach(void *arg __unused, struct ifnet *); static int lagg_port_checkstacking(struct lagg_softc *); #endif static void lagg_port2req(struct lagg_port *, struct lagg_reqport *); +static void lagg_if_updown(struct lagg_softc *, bool); static void lagg_init(void *); static void lagg_stop(struct lagg_softc *); static int lagg_ioctl(struct ifnet *, u_long, caddr_t); @@ -1014,7 +1015,6 @@ lagg_port_destroy(struct lagg_port *lp, int rundelport) static int lagg_port_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { - struct epoch_tracker et; struct lagg_reqport *rp = (struct lagg_reqport *)data; struct lagg_softc *sc; struct lagg_port *lp = NULL; @@ -1039,17 +1039,13 @@ lagg_port_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; } - NET_EPOCH_ENTER(et); - if ((lp = ifp->if_lagg) == NULL || lp->lp_softc != sc) { - error = ENOENT; - NET_EPOCH_EXIT(et); - break; - } - LAGG_SLOCK(sc); - lagg_port2req(lp, rp); + if (__predict_true((lp = ifp->if_lagg) != NULL && + lp->lp_softc == sc)) + lagg_port2req(lp, rp); + else + error = ENOENT; /* XXXGL: can happen? */ LAGG_SUNLOCK(sc); - NET_EPOCH_EXIT(et); break; case SIOCSIFCAP: @@ -1266,6 +1262,25 @@ lagg_watchdog_infiniband(void *arg) } static void +lagg_if_updown(struct lagg_softc *sc, bool up) +{ + struct ifreq ifr = {}; + struct lagg_port *lp; + + LAGG_XLOCK_ASSERT(sc); + + CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { + if (up) + if_up(lp->lp_ifp); + else + if_down(lp->lp_ifp); + + if (lp->lp_ioctl != NULL) + lp->lp_ioctl(lp->lp_ifp, SIOCSIFFLAGS, (caddr_t)&ifr); + } +} + +static void lagg_init(void *xsc) { struct lagg_softc *sc = (struct lagg_softc *)xsc; @@ -1291,6 +1306,8 @@ lagg_init(void *xsc) if_setlladdr(lp->lp_ifp, IF_LLADDR(ifp), ifp->if_addrlen); } + lagg_if_updown(sc, true); + lagg_proto_init(sc); if (ifp->if_type == IFT_INFINIBAND) { @@ -1320,13 +1337,14 @@ lagg_stop(struct lagg_softc *sc) callout_stop(&sc->sc_watchdog); mtx_unlock(&sc->sc_mtx); + lagg_if_updown(sc, false); + callout_drain(&sc->sc_watchdog); } static int lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { - struct epoch_tracker et; struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc; struct lagg_reqall *ra = (struct lagg_reqall *)data; struct lagg_reqopts *ro = (struct lagg_reqopts *)data; @@ -1576,21 +1594,16 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; } - NET_EPOCH_ENTER(et); - if ((lp = (struct lagg_port *)tpif->if_lagg) == NULL || - lp->lp_softc != sc) { - error = ENOENT; - NET_EPOCH_EXIT(et); - if_rele(tpif); - break; - } - LAGG_SLOCK(sc); - lagg_port2req(lp, rp); + if (__predict_true((lp = tpif->if_lagg) != NULL && + lp->lp_softc == sc)) + lagg_port2req(lp, rp); + else + error = ENOENT; /* XXXGL: can happen? */ LAGG_SUNLOCK(sc); - NET_EPOCH_EXIT(et); if_rele(tpif); break; + case SIOCSLAGGPORT: error = priv_check(td, PRIV_NET_LAGG); if (error) |