Page MenuHomeFreeBSD

D22691.id65265.diff
No OneTemporary

D22691.id65265.diff

Index: sys/net/if.c
===================================================================
--- sys/net/if.c
+++ sys/net/if.c
@@ -602,10 +602,14 @@
static void
if_free_internal(struct ifnet *ifp)
{
+ void *softc;
+ if_freed_fn_t freed_fn;
KASSERT((ifp->if_flags & IFF_DYING),
("if_free_internal: interface not dying"));
+ softc = ifp->if_softc;
+ freed_fn = ifp->if_freed;
if (if_com_free[ifp->if_alloctype] != NULL)
if_com_free[ifp->if_alloctype](ifp->if_l2com,
ifp->if_alloctype);
@@ -626,6 +630,8 @@
free(ifp, M_IFNET);
else
free_domain(ifp, M_IFNET);
+ if (freed_fn != NULL)
+ freed_fn(softc);
}
static void
Index: sys/net/if_tuntap.c
===================================================================
--- sys/net/if_tuntap.c
+++ sys/net/if_tuntap.c
@@ -190,9 +190,6 @@
static TAILQ_HEAD(,tuntap_softc) tunhead = TAILQ_HEAD_INITIALIZER(tunhead);
SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
-static struct sx tun_ioctl_sx;
-SX_SYSINIT(tun_ioctl_sx, &tun_ioctl_sx, "tun_ioctl");
-
SYSCTL_DECL(_net_link);
/* tun */
static SYSCTL_NODE(_net_link, OID_AUTO, tun, CTLFLAG_RW, 0,
@@ -217,6 +214,7 @@
static void tun_unbusy_locked(struct tuntap_softc *tp);
static int tun_busy(struct tuntap_softc *tp);
static void tun_unbusy(struct tuntap_softc *tp);
+static void tunifdtor(void *softc);
static int tuntap_name2info(const char *name, int *unit, int *flags);
static void tunclone(void *arg, struct ucred *cred, char *name,
@@ -617,6 +615,17 @@
CURVNET_RESTORE();
}
+static void
+tunifdtor(void *softc)
+{
+ struct tuntap_softc *tp;
+
+ tp = softc;
+ mtx_destroy(&tp->tun_mtx);
+ cv_destroy(&tp->tun_cv);
+ free(tp, M_TUN);
+}
+
static void
tun_destroy(struct tuntap_softc *tp)
{
@@ -641,14 +650,9 @@
bpfdetach(TUN2IFP(tp));
if_detach(TUN2IFP(tp));
}
- sx_xlock(&tun_ioctl_sx);
- TUN2IFP(tp)->if_softc = NULL;
- sx_xunlock(&tun_ioctl_sx);
free_unr(tp->tun_drv->unrhdr, TUN2IFP(tp)->if_dunit);
if_free(TUN2IFP(tp));
- mtx_destroy(&tp->tun_mtx);
- cv_destroy(&tp->tun_cv);
- free(tp, M_TUN);
+ /* softc cleanup deferred to tunifdtor. */
CURVNET_RESTORE();
}
@@ -959,6 +963,7 @@
ifp->if_softc = tp;
if_initname(ifp, drv->cdevsw.d_name, dev2unit(dev));
ifp->if_ioctl = tunifioctl;
+ ifp->if_freed = tunifdtor;
ifp->if_flags = iflags;
IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
ifp->if_capabilities |= IFCAP_LINKSTATE;
@@ -1011,14 +1016,11 @@
* from dying until we've created the alias (that will then be
* subsequently destroyed).
*/
- sx_xlock(&tun_ioctl_sx);
tp = ifp->if_softc;
if (tp == NULL) {
- sx_xunlock(&tun_ioctl_sx);
return;
}
error = tun_busy(tp);
- sx_xunlock(&tun_ioctl_sx);
if (error != 0)
return;
if (tp->tun_alias != NULL) {
@@ -1324,12 +1326,7 @@
bool l2tun;
ifmr = NULL;
- sx_xlock(&tun_ioctl_sx);
tp = ifp->if_softc;
- if (tp == NULL) {
- error = ENXIO;
- goto bad;
- }
l2tun = (tp->tun_flags & TUN_L2) != 0;
switch(cmd) {
case SIOCGIFSTATUS:
@@ -1391,8 +1388,6 @@
error = EINVAL;
}
}
-bad:
- sx_xunlock(&tun_ioctl_sx);
return (error);
}
Index: sys/net/if_var.h
===================================================================
--- sys/net/if_var.h
+++ sys/net/if_var.h
@@ -133,6 +133,7 @@
typedef int (*if_ioctl_fn_t)(if_t, u_long, caddr_t);
typedef void (*if_init_fn_t)(void *);
typedef void (*if_qflush_fn_t)(if_t);
+typedef void (*if_freed_fn_t)(void *);
typedef int (*if_transmit_fn_t)(if_t, struct mbuf *);
typedef uint64_t (*if_get_counter_t)(if_t, ift_counter);
@@ -368,6 +369,7 @@
if_start_fn_t if_start; /* initiate output routine */
if_ioctl_fn_t if_ioctl; /* ioctl routine */
if_init_fn_t if_init; /* Init routine */
+ if_freed_fn_t if_freed; /* Post-free cleanup routine */
int (*if_resolvemulti) /* validate/resolve multicast */
(struct ifnet *, struct sockaddr **, struct sockaddr *);
if_qflush_fn_t if_qflush; /* flush any queue */

File Metadata

Mime Type
text/plain
Expires
Wed, May 20, 9:14 PM (19 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33356980
Default Alt Text
D22691.id65265.diff (3 KB)

Event Timeline