Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 24 Jan 2010 16:17:59 +0000 (UTC)
From:      Shteryana Shopova <syrinx@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r202935 - in head/sys: net net80211
Message-ID:  <201001241617.o0OGHxxq079021@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: syrinx
Date: Sun Jan 24 16:17:58 2010
New Revision: 202935
URL: http://svn.freebsd.org/changeset/base/202935

Log:
  While flushing the multicast filter of an interface, do not zero the relevant
  ifmultiaddr structures' reference to the parent interface, unless the parent
  interface is really detaching. While here, program only link layer multicast
  filters to a wlan's hardware parent interface.
  
  PR:		kern/142391, kern/142392
  Reviewed by:	sam, rpaolo, bms
  MFC after:	1 week

Modified:
  head/sys/net/if.c
  head/sys/net/if_var.h
  head/sys/net80211/ieee80211_ioctl.c

Modified: head/sys/net/if.c
==============================================================================
--- head/sys/net/if.c	Sun Jan 24 15:12:27 2010	(r202934)
+++ head/sys/net/if.c	Sun Jan 24 16:17:58 2010	(r202935)
@@ -740,9 +740,10 @@ if_purgeaddrs(struct ifnet *ifp)
 }
 
 /*
- * Remove any multicast network addresses from an interface.
+ * Remove any multicast network addresses from an interface when an ifnet
+ * is going away.
  */
-void
+static void
 if_purgemaddrs(struct ifnet *ifp)
 {
 	struct ifmultiaddr *ifma;
@@ -2940,6 +2941,22 @@ if_delmulti(struct ifnet *ifp, struct so
 }
 
 /*
+ * Delete all multicast group membership for an interface.
+ * Should be used to quickly flush all multicast filters.
+ */
+void
+if_delallmulti(struct ifnet *ifp)
+{
+	struct ifmultiaddr *ifma;
+	struct ifmultiaddr *next;
+
+	IF_ADDR_LOCK(ifp);
+	TAILQ_FOREACH_SAFE(ifma, &ifp->if_multiaddrs, ifma_link, next)
+		if_delmulti_locked(ifp, ifma, 0);
+	IF_ADDR_UNLOCK(ifp);
+}
+
+/*
  * Delete a multicast group membership by group membership pointer.
  * Network-layer protocol domains must use this routine.
  *

Modified: head/sys/net/if_var.h
==============================================================================
--- head/sys/net/if_var.h	Sun Jan 24 15:12:27 2010	(r202934)
+++ head/sys/net/if_var.h	Sun Jan 24 16:17:58 2010	(r202935)
@@ -833,7 +833,7 @@ void	if_delmulti_ifma(struct ifmultiaddr
 void	if_detach(struct ifnet *);
 void	if_vmove(struct ifnet *, struct vnet *);
 void	if_purgeaddrs(struct ifnet *);
-void	if_purgemaddrs(struct ifnet *);
+void	if_delallmulti(struct ifnet *);
 void	if_down(struct ifnet *);
 struct ifmultiaddr *
 	if_findmulti(struct ifnet *, struct sockaddr *);

Modified: head/sys/net80211/ieee80211_ioctl.c
==============================================================================
--- head/sys/net80211/ieee80211_ioctl.c	Sun Jan 24 15:12:27 2010	(r202934)
+++ head/sys/net80211/ieee80211_ioctl.c	Sun Jan 24 16:17:58 2010	(r202935)
@@ -3199,15 +3199,18 @@ ieee80211_ioctl_updatemulti(struct ieee8
 	void *ioctl;
 
 	IEEE80211_LOCK(ic);
-	if_purgemaddrs(parent);
+	if_delallmulti(parent);
 	ioctl = parent->if_ioctl;	/* XXX WAR if_allmulti */
 	parent->if_ioctl = NULL;
 	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
 		struct ifnet *ifp = vap->iv_ifp;
 		struct ifmultiaddr *ifma;
 
-		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
+		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+			if (ifma->ifma_addr->sa_family != AF_LINK)
+				continue;
 			(void) if_addmulti(parent, ifma->ifma_addr, NULL);
+		}
 	}
 	parent->if_ioctl = ioctl;
 	ieee80211_runtask(ic, &ic->ic_mcast_task);



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