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
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)
@ -238,6 +238,50 @@ if_clone_addif(struct if_clone *ifc, struct ifnet *ifp)
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.
*/
@ -281,16 +325,7 @@ if_clone_destroy(const char *name)
if (ifp == NULL)
return (ENXIO);
/* Find the cloner for this interface */
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();
ifc = ifc_find_cloner(ifp->if_dname, ifp->if_home_vnet);
if (ifc == NULL) {
if_rele(ifp);
return (EINVAL);
@ -308,7 +343,6 @@ static int
if_clone_destroyif_flags(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
{
int err;
struct ifnet *ifcifp;
/*
* 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);
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) {
if (!ifc_unlink_ifp(ifc, ifp)) {
CURVNET_RESTORE();
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;
err = (*ifc->ifc_destroy)(ifc, ifp, flags);
if (err != 0) {
if ((ifc->ifc_flags & IFC_F_NOGROUP) == 0)
if_addgroup(ifp, ifc->ifc_name);
IF_CLONE_LOCK(ifc);
IFC_IFLIST_INSERT(ifc, ifp);
IF_CLONE_UNLOCK(ifc);
} else if (ifc->ifc_flags & IFC_F_AUTOUNIT)
if (err != 0)
ifc_link_ifp(ifc, ifp);
else if (ifc->ifc_flags & IFC_F_AUTOUNIT)
ifc_free_unit(ifc, unit);
CURVNET_RESTORE();
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,
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);
#ifdef CLONE_COMPAT_13