From 26c190d2802ebc17563c8fc467c8bb74eab6a2d9 Mon Sep 17 00:00:00 2001 From: "Alexander V. Chernikov" Date: Sat, 24 Sep 2022 19:17:27 +0000 Subject: [PATCH] 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 --- sys/net/if_clone.c | 81 ++++++++++++++++++++++++++++------------------ sys/net/if_clone.h | 3 ++ 2 files changed, 53 insertions(+), 31 deletions(-) diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c index 50664c28ff88..8360fb4d1d27 100644 --- a/sys/net/if_clone.c +++ b/sys/net/if_clone.c @@ -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); diff --git a/sys/net/if_clone.h b/sys/net/if_clone.h index de20eef993f4..1d918a012a5b 100644 --- a/sys/net/if_clone.h +++ b/sys/net/if_clone.h @@ -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