From c92a456b5537ceb711011c014e68ae0201ab4290 Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Mon, 2 Mar 2015 20:00:03 +0000 Subject: Fix group membership of cloned interfaces when one is moved by if_vmove(). In if_vmove(), if_detach_internal() and if_attach_internal() were called in series to detach and reattach the interface. When detaching, if_delgroup() was called and the interface leaves all of the group membership. And then upon attachment, if_addgroup(ifp, IFG_ALL) was called and it joined only "all" group again. This had a problem. Normally, a cloned interface automatically joins a group whose name is ifc_name of the cloner in addition to "all" upon creation. However, if_vmove() removed the membership and did not restore upon attachment. Differential Revision: https://reviews.freebsd.org/D1859 --- sys/net/if_clone.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'sys/net/if_clone.c') diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c index 09f8d2a613bf..dc71bfc04f1e 100644 --- a/sys/net/if_clone.c +++ b/sys/net/if_clone.c @@ -517,6 +517,49 @@ done: return (err); } +/* + * if_clone_findifc() looks up ifnet from the current + * cloner list, and returns ifc if found. Note that ifc_refcnt + * is incremented. + */ +struct if_clone * +if_clone_findifc(struct ifnet *ifp) +{ + struct if_clone *ifc, *ifc0; + struct ifnet *ifcifp; + + ifc0 = NULL; + 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); + break; + } + } + IF_CLONE_UNLOCK(ifc); + if (ifc0 != NULL) + 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_addgroup(ifp, ifc->ifc_name); + IF_CLONE_REMREF(ifc); +} + /* * A utility function to extract unit numbers from interface names of * the form name###. -- cgit v1.2.3