Page MenuHomeFreeBSD

D19248.id54460.diff
No OneTemporary

D19248.id54460.diff

Index: sys/net/if_tun.c
===================================================================
--- sys/net/if_tun.c
+++ sys/net/if_tun.c
@@ -105,6 +105,7 @@
* which is static after setup.
*/
static struct mtx tunmtx;
+static eventhandler_tag tag;
static const char tunname[] = "tun";
static MALLOC_DEFINE(M_TUN, tunname, "Tunnel Interface");
static int tundebug = 0;
@@ -129,9 +130,12 @@
const struct sockaddr *, struct route *ro);
static void tunstart(struct ifnet *);
-static int tun_clone_create(struct if_clone *, int, caddr_t);
-static void tun_clone_destroy(struct ifnet *);
-static struct if_clone *tun_cloner;
+static int tun_clone_match(struct if_clone *ifc, const char *name);
+static int tun_clone_create(struct if_clone *, char *, size_t, caddr_t);
+static int tun_clone_destroy(struct if_clone *, struct ifnet *);
+static struct unrhdr *tun_unrhdr;
+VNET_DEFINE(struct if_clone *, tun_cloner);
+#define V_tun_cloner VNET(tun_cloner)
static d_open_t tunopen;
static d_close_t tunclose;
@@ -173,10 +177,35 @@
};
static int
-tun_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+tun_clone_match(struct if_clone *ifc, const char *name)
+{
+ if (strncmp("tun", name, 3) == 0)
+ return (1);
+
+ return (0);
+}
+
+static int
+tun_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
{
struct cdev *dev;
- int i;
+ int err, unit, i;
+
+ printf("KP: %s(%p, %s, %zu)\n", __FUNCTION__, ifc, name, len);
+ err = ifc_name2unit(name, &unit);
+ printf("KP: %s() unit %d, err %d\n", __FUNCTION__, unit, err);
+ if (err != 0)
+ return (err);
+
+ if (unit != -1) {
+ /* If this unit number is still available that/s okay. */
+ if (alloc_unr_specific(tun_unrhdr, unit) == -1)
+ return (EEXIST);
+ } else {
+ unit = alloc_unr(tun_unrhdr);
+ }
+
+ snprintf(name, IFNAMSIZ, "tun%d", unit);
/* find any existing device, or allocate new unit number */
i = clone_create(&tunclones, &tun_cdevsw, &unit, &dev, 0);
@@ -252,6 +281,7 @@
dev = tp->tun_dev;
bpfdetach(TUN2IFP(tp));
if_detach(TUN2IFP(tp));
+ free_unr(tun_unrhdr, TUN2IFP(tp)->if_dunit);
if_free(TUN2IFP(tp));
destroy_dev(dev);
seldrain(&tp->tun_rsel);
@@ -263,8 +293,8 @@
CURVNET_RESTORE();
}
-static void
-tun_clone_destroy(struct ifnet *ifp)
+static int
+tun_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
{
struct tun_softc *tp = ifp->if_softc;
@@ -272,39 +302,64 @@
TAILQ_REMOVE(&tunhead, tp, tun_list);
mtx_unlock(&tunmtx);
tun_destroy(tp);
+
+ return (0);
+}
+
+static void
+vnet_tun_init(const void *unused __unused)
+{
+ V_tun_cloner = if_clone_advanced(tunname, 0, tun_clone_match,
+ tun_clone_create, tun_clone_destroy);
+}
+VNET_SYSINIT(vnet_tun_init, SI_SUB_PROTO_IF, SI_ORDER_ANY,
+ vnet_tun_init, NULL);
+
+static void
+vnet_tun_uninit(const void *unused __unused)
+{
+ if_clone_detach(V_tun_cloner);
}
+VNET_SYSUNINIT(vnet_tun_uninit, SI_SUB_PROTO_IF, SI_ORDER_ANY,
+ vnet_tun_uninit, NULL);
+
+static void
+tun_uninit(const void *unused __unused)
+{
+ struct tun_softc *tp;
+
+ EVENTHANDLER_DEREGISTER(dev_clone, tag);
+ drain_dev_clone_events();
+
+ mtx_lock(&tunmtx);
+ while ((tp = TAILQ_FIRST(&tunhead)) != NULL) {
+ TAILQ_REMOVE(&tunhead, tp, tun_list);
+ mtx_unlock(&tunmtx);
+ tun_destroy(tp);
+ mtx_lock(&tunmtx);
+ }
+ mtx_unlock(&tunmtx);
+ delete_unrhdr(tun_unrhdr);
+ clone_cleanup(&tunclones);
+ mtx_destroy(&tunmtx);
+}
+SYSUNINIT(tun_uninit, SI_SUB_PROTO_IF, SI_ORDER_ANY, tun_uninit, NULL);
static int
tunmodevent(module_t mod, int type, void *data)
{
- static eventhandler_tag tag;
- struct tun_softc *tp;
switch (type) {
case MOD_LOAD:
mtx_init(&tunmtx, "tunmtx", NULL, MTX_DEF);
clone_setup(&tunclones);
+ tun_unrhdr = new_unrhdr(0, IF_MAXUNIT, &tunmtx);
tag = EVENTHANDLER_REGISTER(dev_clone, tunclone, 0, 1000);
if (tag == NULL)
return (ENOMEM);
- tun_cloner = if_clone_simple(tunname, tun_clone_create,
- tun_clone_destroy, 0);
break;
case MOD_UNLOAD:
- if_clone_detach(tun_cloner);
- EVENTHANDLER_DEREGISTER(dev_clone, tag);
- drain_dev_clone_events();
-
- mtx_lock(&tunmtx);
- while ((tp = TAILQ_FIRST(&tunhead)) != NULL) {
- TAILQ_REMOVE(&tunhead, tp, tun_list);
- mtx_unlock(&tunmtx);
- tun_destroy(tp);
- mtx_lock(&tunmtx);
- }
- mtx_unlock(&tunmtx);
- clone_cleanup(&tunclones);
- mtx_destroy(&tunmtx);
+ /* See tun_uninit, so it's done after the vnet_sysuninit() */
break;
default:
return EOPNOTSUPP;

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 2, 5:04 PM (8 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30730738
Default Alt Text
D19248.id54460.diff (4 KB)

Event Timeline