if_clone: add ifc_link_ifp() / ifc_unlink_ifp() to the KPI

Factor cloner ifp addition/deletion into separate functions and
 make them public. This change simlifies the current cloner code
 and paves the way to the other upcoming cloner / epair changes.

MFC after:	2 weeks
This commit is contained in:
Alexander V. Chernikov 2022-09-24 19:17:27 +00:00
parent 8bdb2695d6
commit 26c190d280
2 changed files with 53 additions and 31 deletions

View File

@ -227,7 +227,7 @@ if_clone_create(char *name, size_t len, caddr_t params)
} }
void void
if_clone_addif(struct if_clone *ifc, struct ifnet *ifp) ifc_link_ifp(struct if_clone *ifc, struct ifnet *ifp)
{ {
if ((ifc->ifc_flags & IFC_NOGROUP) == 0) if ((ifc->ifc_flags & IFC_NOGROUP) == 0)
@ -238,6 +238,50 @@ if_clone_addif(struct if_clone *ifc, struct ifnet *ifp)
IF_CLONE_UNLOCK(ifc); IF_CLONE_UNLOCK(ifc);
} }
void
if_clone_addif(struct if_clone *ifc, struct ifnet *ifp)
{
ifc_link_ifp(ifc, ifp);
}
bool
ifc_unlink_ifp(struct if_clone *ifc, struct ifnet *ifp)
{
struct ifnet *ifcifp;
IF_CLONE_LOCK(ifc);
LIST_FOREACH(ifcifp, &ifc->ifc_iflist, if_clones) {
if (ifcifp == ifp) {
IFC_IFLIST_REMOVE(ifc, ifp);
break;
}
}
IF_CLONE_UNLOCK(ifc);
if (ifcifp != NULL && (ifc->ifc_flags & IFC_F_NOGROUP) == 0)
if_delgroup(ifp, ifc->ifc_name);
return (ifcifp != NULL);
}
static struct if_clone *
ifc_find_cloner(const char *name, struct vnet *vnet)
{
struct if_clone *ifc;
CURVNET_SET_QUIET(vnet);
IF_CLONERS_LOCK();
LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
if (strcmp(ifc->ifc_name, name) == 0) {
break;
}
}
IF_CLONERS_UNLOCK();
CURVNET_RESTORE();
return (ifc);
}
/* /*
* Create a clone network interface. * Create a clone network interface.
*/ */
@ -281,16 +325,7 @@ if_clone_destroy(const char *name)
if (ifp == NULL) if (ifp == NULL)
return (ENXIO); return (ENXIO);
/* Find the cloner for this interface */ ifc = ifc_find_cloner(ifp->if_dname, ifp->if_home_vnet);
CURVNET_SET_QUIET(ifp->if_home_vnet);
IF_CLONERS_LOCK();
LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
if (strcmp(ifc->ifc_name, ifp->if_dname) == 0) {
break;
}
}
IF_CLONERS_UNLOCK();
CURVNET_RESTORE();
if (ifc == NULL) { if (ifc == NULL) {
if_rele(ifp); if_rele(ifp);
return (EINVAL); return (EINVAL);
@ -308,7 +343,6 @@ static int
if_clone_destroyif_flags(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags) if_clone_destroyif_flags(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
{ {
int err; int err;
struct ifnet *ifcifp;
/* /*
* Given that the cloned ifnet might be attached to a different * Given that the cloned ifnet might be attached to a different
@ -317,32 +351,17 @@ if_clone_destroyif_flags(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags
*/ */
CURVNET_SET_QUIET(ifp->if_vnet); CURVNET_SET_QUIET(ifp->if_vnet);
IF_CLONE_LOCK(ifc); if (!ifc_unlink_ifp(ifc, ifp)) {
LIST_FOREACH(ifcifp, &ifc->ifc_iflist, if_clones) {
if (ifcifp == ifp) {
IFC_IFLIST_REMOVE(ifc, ifp);
break;
}
}
IF_CLONE_UNLOCK(ifc);
if (ifcifp == NULL) {
CURVNET_RESTORE(); CURVNET_RESTORE();
return (ENXIO); /* ifp is not on the list. */ return (ENXIO); /* ifp is not on the list. */
} }
if ((ifc->ifc_flags & IFC_F_NOGROUP) == 0)
if_delgroup(ifp, ifc->ifc_name);
int unit = ifp->if_dunit; int unit = ifp->if_dunit;
err = (*ifc->ifc_destroy)(ifc, ifp, flags); err = (*ifc->ifc_destroy)(ifc, ifp, flags);
if (err != 0) { if (err != 0)
if ((ifc->ifc_flags & IFC_F_NOGROUP) == 0) ifc_link_ifp(ifc, ifp);
if_addgroup(ifp, ifc->ifc_name); else if (ifc->ifc_flags & IFC_F_AUTOUNIT)
IF_CLONE_LOCK(ifc);
IFC_IFLIST_INSERT(ifc, ifp);
IF_CLONE_UNLOCK(ifc);
} else if (ifc->ifc_flags & IFC_F_AUTOUNIT)
ifc_free_unit(ifc, unit); ifc_free_unit(ifc, unit);
CURVNET_RESTORE(); CURVNET_RESTORE();
return (err); return (err);

View File

@ -78,6 +78,9 @@ void ifc_detach_cloner(struct if_clone *ifc);
int ifc_create_ifp(const char *name, struct ifc_data *ifd, int ifc_create_ifp(const char *name, struct ifc_data *ifd,
struct ifnet **ifpp); struct ifnet **ifpp);
void ifc_link_ifp(struct if_clone *ifc, struct ifnet *ifp);
bool ifc_unlink_ifp(struct if_clone *ifc, struct ifnet *ifp);
int ifc_copyin(const struct ifc_data *ifd, void *target, size_t len); int ifc_copyin(const struct ifc_data *ifd, void *target, size_t len);
#ifdef CLONE_COMPAT_13 #ifdef CLONE_COMPAT_13