summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/net/if_lagg.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c
index ba19c52..b7beb86 100644
--- a/sys/net/if_lagg.c
+++ b/sys/net/if_lagg.c
@@ -950,11 +950,11 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = EPROTONOSUPPORT;
break;
}
+ LAGG_WLOCK(sc);
if (sc->sc_proto != LAGG_PROTO_NONE) {
- LAGG_WLOCK(sc);
- error = sc->sc_detach(sc);
- /* Reset protocol and pointers */
+ /* Reset protocol first in case detach unlocks */
sc->sc_proto = LAGG_PROTO_NONE;
+ error = sc->sc_detach(sc);
sc->sc_detach = NULL;
sc->sc_start = NULL;
sc->sc_input = NULL;
@@ -966,10 +966,14 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
sc->sc_lladdr = NULL;
sc->sc_req = NULL;
sc->sc_portreq = NULL;
- LAGG_WUNLOCK(sc);
+ } else if (sc->sc_input != NULL) {
+ /* Still detaching */
+ error = EBUSY;
}
- if (error != 0)
+ if (error != 0) {
+ LAGG_WUNLOCK(sc);
break;
+ }
for (int i = 0; i < (sizeof(lagg_protos) /
sizeof(lagg_protos[0])); i++) {
if (lagg_protos[i].ti_proto == ra->ra_proto) {
@@ -977,7 +981,6 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
printf("%s: using proto %u\n",
sc->sc_ifname,
lagg_protos[i].ti_proto);
- LAGG_WLOCK(sc);
sc->sc_proto = lagg_protos[i].ti_proto;
if (sc->sc_proto != LAGG_PROTO_NONE)
error = lagg_protos[i].ti_attach(sc);
@@ -985,6 +988,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
return (error);
}
}
+ LAGG_WUNLOCK(sc);
error = EPROTONOSUPPORT;
break;
case SIOCGLAGGFLAGS:
OpenPOWER on IntegriCloud