Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F111571810
D33941.id101879.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D33941.id101879.diff
View Options
diff --git a/sys/net/if.c b/sys/net/if.c
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -285,8 +285,8 @@
static int if_getgroup(struct ifgroupreq *, struct ifnet *);
static int if_getgroupmembers(struct ifgroupreq *);
static void if_delgroups(struct ifnet *);
-static void if_attach_internal(struct ifnet *, int, struct if_clone *);
-static int if_detach_internal(struct ifnet *, int, struct if_clone **);
+static void if_attach_internal(struct ifnet *, bool);
+static int if_detach_internal(struct ifnet *, bool);
static void if_siocaddmulti(void *, int);
static void if_link_ifnet(struct ifnet *);
static bool if_unlink_ifnet(struct ifnet *, bool);
@@ -775,7 +775,7 @@
if_attach(struct ifnet *ifp)
{
- if_attach_internal(ifp, 0, NULL);
+ if_attach_internal(ifp, false);
}
/*
@@ -830,7 +830,7 @@
}
static void
-if_attach_internal(struct ifnet *ifp, int vmove, struct if_clone *ifc)
+if_attach_internal(struct ifnet *ifp, bool vmove)
{
unsigned socksize, ifasize;
int namelen, masklen;
@@ -847,9 +847,11 @@
if_addgroup(ifp, IFG_ALL);
- /* Restore group membership for cloned interfaces. */
- if (vmove && ifc != NULL)
- if_clone_addgroup(ifp, ifc);
+#ifdef VIMAGE
+ /* Restore group membership for cloned interface. */
+ if (vmove)
+ if_clone_restoregroup(ifp);
+#endif
getmicrotime(&ifp->if_lastchange);
ifp->if_epoch = time_uptime;
@@ -1097,7 +1099,7 @@
found = if_unlink_ifnet(ifp, false);
if (found) {
sx_xlock(&ifnet_detach_sxlock);
- if_detach_internal(ifp, 0, NULL);
+ if_detach_internal(ifp, false);
sx_xunlock(&ifnet_detach_sxlock);
}
CURVNET_RESTORE();
@@ -1114,7 +1116,7 @@
* the cloned interfaces are destoyed as first thing of teardown.
*/
static int
-if_detach_internal(struct ifnet *ifp, int vmove, struct if_clone **ifcp)
+if_detach_internal(struct ifnet *ifp, bool vmove)
{
struct ifaddr *ifa;
int i;
@@ -1149,15 +1151,6 @@
taskqueue_drain(taskqueue_swi, &ifp->if_linktask);
taskqueue_drain(taskqueue_swi, &ifp->if_addmultitask);
- /*
- * Check if this is a cloned interface or not. Must do even if
- * shutting down as a if_vmove_reclaim() would move the ifp and
- * the if_clone_addgroup() will have a corrupted string overwise
- * from a gibberish pointer.
- */
- if (vmove && ifcp != NULL)
- *ifcp = if_clone_findifc(ifp);
-
if_down(ifp);
#ifdef VIMAGE
@@ -1271,7 +1264,6 @@
static int
if_vmove(struct ifnet *ifp, struct vnet *new_vnet)
{
- struct if_clone *ifc;
#ifdef DEV_BPF
u_int bif_dlt, bif_hdrlen;
#endif
@@ -1291,7 +1283,7 @@
* mark as dead etc. so that the ifnet can be reattached later.
* If we cannot find it, we lost the race to someone else.
*/
- rc = if_detach_internal(ifp, 1, &ifc);
+ rc = if_detach_internal(ifp, true);
if (rc != 0)
return (rc);
@@ -1318,7 +1310,7 @@
*/
CURVNET_SET_QUIET(new_vnet);
ifindex_alloc(ifp);
- if_attach_internal(ifp, 1, ifc);
+ if_attach_internal(ifp, true);
#ifdef DEV_BPF
if (ifp->if_bpf == NULL)
diff --git a/sys/net/if_clone.h b/sys/net/if_clone.h
--- a/sys/net/if_clone.h
+++ b/sys/net/if_clone.h
@@ -76,8 +76,7 @@
int if_clone_create(char *, size_t, caddr_t);
int if_clone_destroy(const char *);
int if_clone_list(struct if_clonereq *);
-struct if_clone *if_clone_findifc(struct ifnet *);
-void if_clone_addgroup(struct ifnet *, struct if_clone *);
+void if_clone_restoregroup(struct ifnet *);
/* The below interfaces are used only by epair(4). */
void if_clone_addif(struct if_clone *, struct ifnet *);
diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c
--- a/sys/net/if_clone.c
+++ b/sys/net/if_clone.c
@@ -525,49 +525,48 @@
return (err);
}
+#ifdef VIMAGE
/*
- * if_clone_findifc() looks up ifnet from the current
- * cloner list, and returns ifc if found. Note that ifc_refcnt
- * is incremented.
+ * if_clone_restoregroup() is used in context of if_vmove().
+ *
+ * Since if_detach_internal() has removed the interface from ALL groups, we
+ * need to "restore" interface membership in the cloner's group. Note that
+ * interface belongs to cloner in its home vnet, so we first find the original
+ * cloner, and then we confirm that cloner with the same name exists in the
+ * current vnet.
*/
-struct if_clone *
-if_clone_findifc(struct ifnet *ifp)
+void
+if_clone_restoregroup(struct ifnet *ifp)
{
- struct if_clone *ifc, *ifc0;
+ struct if_clone *ifc;
struct ifnet *ifcifp;
+ char ifc_name[IFCLOSIZ] = { [0] = '\0' };
- ifc0 = NULL;
+ CURVNET_SET_QUIET(ifp->if_home_vnet);
IF_CLONERS_LOCK();
LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
IF_CLONE_LOCK(ifc);
LIST_FOREACH(ifcifp, &ifc->ifc_iflist, if_clones) {
if (ifp == ifcifp) {
- ifc0 = ifc;
- IF_CLONE_ADDREF_LOCKED(ifc);
+ strncpy(ifc_name, ifc->ifc_name, IFCLOSIZ-1);
break;
}
}
IF_CLONE_UNLOCK(ifc);
- if (ifc0 != NULL)
+ if (ifc_name[0] != '\0')
break;
}
+ CURVNET_RESTORE();
+ LIST_FOREACH(ifc, &V_if_cloners, ifc_list)
+ if (strcmp(ifc->ifc_name, ifc_name) == 0 &&
+ ((ifc->ifc_flags & IFC_NOGROUP) == 0))
+ break;
IF_CLONERS_UNLOCK();
- return (ifc0);
-}
-
-/*
- * if_clone_addgroup() decrements ifc_refcnt because it is called after
- * if_clone_findifc().
- */
-void
-if_clone_addgroup(struct ifnet *ifp, struct if_clone *ifc)
-{
- if ((ifc->ifc_flags & IFC_NOGROUP) == 0) {
- if_addgroup(ifp, ifc->ifc_name);
- IF_CLONE_REMREF(ifc);
- }
+ if (ifc != NULL)
+ if_addgroup(ifp, ifc_name);
}
+#endif
/*
* A utility function to extract unit numbers from interface names of
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 6, 10:31 AM (2 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17012795
Default Alt Text
D33941.id101879.diff (5 KB)
Attached To
Mode
D33941: if_vmove: improve restoration in cloner's ifgroup membership
Attached
Detach File
Event Timeline
Log In to Comment