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:
parent
8bdb2695d6
commit
26c190d280
@ -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);
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user