if_tuntap: simplify storage of per-vnet cloners

There is no need for a separate structure neither for a linked list.
Provide each VNET with an array of pointers to if_clone that has the same
size as the driver list.

Reviewed by:		zlei, kevans, kp
Differential Revision:	https://reviews.freebsd.org/D44307
This commit is contained in:
Gleb Smirnoff 2024-03-29 12:35:41 -07:00
parent bdc903460b
commit fa93ba4097

View file

@ -328,16 +328,9 @@ static struct tuntap_driver {
.clone_destroy_fn = tun_clone_destroy,
},
};
#define NDRV nitems(tuntap_drivers)
struct tuntap_driver_cloner {
SLIST_ENTRY(tuntap_driver_cloner) link;
struct tuntap_driver *drv;
struct if_clone *cloner;
};
VNET_DEFINE_STATIC(SLIST_HEAD(, tuntap_driver_cloner), tuntap_driver_cloners) =
SLIST_HEAD_INITIALIZER(tuntap_driver_cloners);
VNET_DEFINE_STATIC(struct if_clone *, tuntap_driver_cloners[NDRV]);
#define V_tuntap_driver_cloners VNET(tuntap_driver_cloners)
/*
@ -406,7 +399,6 @@ static int
tuntap_name2info(const char *name, int *outunit, int *outflags)
{
struct tuntap_driver *drv;
struct tuntap_driver_cloner *drvc;
char *dname;
int flags, unit;
bool found;
@ -422,12 +414,8 @@ tuntap_name2info(const char *name, int *outunit, int *outflags)
dname = __DECONST(char *, name);
found = false;
KASSERT(!SLIST_EMPTY(&V_tuntap_driver_cloners),
("tuntap_driver_cloners failed to initialize"));
SLIST_FOREACH(drvc, &V_tuntap_driver_cloners, link) {
KASSERT(drvc->drv != NULL,
("tuntap_driver_cloners entry not properly initialized"));
drv = drvc->drv;
for (u_int i = 0; i < NDRV; i++) {
drv = &tuntap_drivers[i];
if (strcmp(name, drv->cdevsw.d_name) == 0) {
found = true;
@ -456,23 +444,16 @@ tuntap_name2info(const char *name, int *outunit, int *outflags)
/*
* Get driver information from a set of flags specified. Masks the identifying
* part of the flags and compares it against all of the available
* tuntap_drivers. Must be called with correct vnet context.
* tuntap_drivers.
*/
static struct tuntap_driver *
tuntap_driver_from_flags(int tun_flags)
{
struct tuntap_driver *drv;
struct tuntap_driver_cloner *drvc;
KASSERT(!SLIST_EMPTY(&V_tuntap_driver_cloners),
("tuntap_driver_cloners failed to initialize"));
SLIST_FOREACH(drvc, &V_tuntap_driver_cloners, link) {
KASSERT(drvc->drv != NULL,
("tuntap_driver_cloners entry not properly initialized"));
drv = drvc->drv;
if ((tun_flags & TUN_DRIVER_IDENT_MASK) == drv->ident_flags)
return (drv);
}
for (u_int i = 0; i < NDRV; i++)
if ((tun_flags & TUN_DRIVER_IDENT_MASK) ==
tuntap_drivers[i].ident_flags)
return (&tuntap_drivers[i]);
return (NULL);
}
@ -674,22 +655,15 @@ tun_clone_destroy(struct if_clone *ifc __unused, struct ifnet *ifp, uint32_t fla
static void
vnet_tun_init(const void *unused __unused)
{
struct tuntap_driver *drv;
struct tuntap_driver_cloner *drvc;
int i;
for (i = 0; i < nitems(tuntap_drivers); ++i) {
drv = &tuntap_drivers[i];
drvc = malloc(sizeof(*drvc), M_TUN, M_WAITOK | M_ZERO);
drvc->drv = drv;
for (u_int i = 0; i < NDRV; ++i) {
struct if_clone_addreq req = {
.match_f = drv->clone_match_fn,
.create_f = drv->clone_create_fn,
.destroy_f = drv->clone_destroy_fn,
.match_f = tuntap_drivers[i].clone_match_fn,
.create_f = tuntap_drivers[i].clone_create_fn,
.destroy_f = tuntap_drivers[i].clone_destroy_fn,
};
drvc->cloner = ifc_attach_cloner(drv->cdevsw.d_name, &req);
SLIST_INSERT_HEAD(&V_tuntap_driver_cloners, drvc, link);
V_tuntap_driver_cloners[i] =
ifc_attach_cloner(tuntap_drivers[i].cdevsw.d_name, &req);
};
}
VNET_SYSINIT(vnet_tun_init, SI_SUB_PROTO_IF, SI_ORDER_ANY,
@ -698,15 +672,9 @@ VNET_SYSINIT(vnet_tun_init, SI_SUB_PROTO_IF, SI_ORDER_ANY,
static void
vnet_tun_uninit(const void *unused __unused)
{
struct tuntap_driver_cloner *drvc;
while (!SLIST_EMPTY(&V_tuntap_driver_cloners)) {
drvc = SLIST_FIRST(&V_tuntap_driver_cloners);
SLIST_REMOVE_HEAD(&V_tuntap_driver_cloners, link);
if_clone_detach(drvc->cloner);
free(drvc, M_TUN);
}
for (u_int i = 0; i < NDRV; ++i)
if_clone_detach(V_tuntap_driver_cloners[i]);
}
VNET_SYSUNINIT(vnet_tun_uninit, SI_SUB_PROTO_IF, SI_ORDER_ANY,
vnet_tun_uninit, NULL);