Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Apr 2009 19:16:14 +0000 (UTC)
From:      Max Laier <mlaier@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r190903 - head/sys/net
Message-ID:  <200904101916.n3AJGEwm058792@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mlaier
Date: Fri Apr 10 19:16:14 2009
New Revision: 190903
URL: http://svn.freebsd.org/changeset/base/190903

Log:
  Follow up for r190895  It's not only the "all" group that is affected, but
  all groups on the given interface.
  
  PR:		kern/130977, kern/131310
  MFC after:	3 days (%vnet)

Modified:
  head/sys/net/if.c

Modified: head/sys/net/if.c
==============================================================================
--- head/sys/net/if.c	Fri Apr 10 18:46:46 2009	(r190902)
+++ head/sys/net/if.c	Fri Apr 10 19:16:14 2009	(r190903)
@@ -141,6 +141,7 @@ static int	if_delmulti_locked(struct ifn
 static void	do_link_state_change(void *, int);
 static int	if_getgroup(struct ifgroupreq *, struct ifnet *);
 static int	if_getgroupmembers(struct ifgroupreq *);
+static void	if_delgroups(struct ifnet *);
 
 #ifdef INET6
 /*
@@ -887,7 +888,7 @@ if_detach(struct ifnet *ifp)
 	rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
 	EVENTHANDLER_INVOKE(ifnet_departure_event, ifp);
 	devctl_notify("IFNET", ifp->if_xname, "DETACH", NULL);
-	if_delgroup(ifp, IFG_ALL);
+	if_delgroups(ifp);
 
 	IF_AFDATA_LOCK(ifp);
 	for (dp = domains; dp; dp = dp->dom_next) {
@@ -1025,6 +1026,54 @@ if_delgroup(struct ifnet *ifp, const cha
 }
 
 /*
+ * Remove an interface from all groups
+ */
+static void
+if_delgroups(struct ifnet *ifp)
+{
+	INIT_VNET_NET(ifp->if_vnet);
+	struct ifg_list		*ifgl;
+	struct ifg_member	*ifgm;
+	char groupname[IFNAMSIZ];
+
+	IFNET_WLOCK();
+	while (!TAILQ_EMPTY(&ifp->if_groups)) {
+		ifgl = TAILQ_FIRST(&ifp->if_groups);
+
+		strlcpy(groupname, ifgl->ifgl_group->ifg_group, IFNAMSIZ);
+
+		IF_ADDR_LOCK(ifp);
+		TAILQ_REMOVE(&ifp->if_groups, ifgl, ifgl_next);
+		IF_ADDR_UNLOCK(ifp);
+
+		TAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next)
+			if (ifgm->ifgm_ifp == ifp)
+				break;
+
+		if (ifgm != NULL) {
+			TAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm,
+			    ifgm_next);
+			free(ifgm, M_TEMP);
+		}
+
+		if (--ifgl->ifgl_group->ifg_refcnt == 0) {
+			TAILQ_REMOVE(&V_ifg_head, ifgl->ifgl_group, ifg_next);
+			EVENTHANDLER_INVOKE(group_detach_event,
+			    ifgl->ifgl_group);
+			free(ifgl->ifgl_group, M_TEMP);
+		}
+		IFNET_WUNLOCK();
+
+		free(ifgl, M_TEMP);
+
+		EVENTHANDLER_INVOKE(group_change_event, groupname);
+
+		IFNET_WLOCK();
+	}
+	IFNET_WUNLOCK();
+}
+
+/*
  * Stores all groups from an interface in memory pointed
  * to by data
  */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200904101916.n3AJGEwm058792>