aboutsummaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorAlexander V. Chernikov <melifaro@FreeBSD.org>2022-09-24 19:17:27 +0000
committerAlexander V. Chernikov <melifaro@FreeBSD.org>2022-09-24 19:42:42 +0000
commit26c190d2802ebc17563c8fc467c8bb74eab6a2d9 (patch)
treec11e31a8506dd5cc102cc606ea187a3d83121915 /sys/net
parent8bdb2695d69710b7f2e7cc20820aab8b3f4668a6 (diff)
downloadsrc-26c190d2802ebc17563c8fc467c8bb74eab6a2d9.tar.gz
src-26c190d2802ebc17563c8fc467c8bb74eab6a2d9.zip
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
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_clone.c81
-rw-r--r--sys/net/if_clone.h3
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