Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 15 Mar 2008 22:48:12 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 137807 for review
Message-ID:  <200803152248.m2FMmCMc085982@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=137807

Change 137807 by sam@sam_ebb on 2008/03/15 22:47:59

	fill in missing bits to merge vap's multicast lists into a single
	list for the parent device and call the update method to notify
	the driver it should push the result; note this is prone with
	terrible hackery to workaround bogosity in the ifnet code and
	we still pay a terrible price as we must rebuild the parent's
	mcast list from scratch each time as we have no context to know
	how to optimize work

Affected files ...

.. //depot/projects/vap/sys/net80211/ieee80211_ioctl.c#43 edit

Differences ...

==== //depot/projects/vap/sys/net80211/ieee80211_ioctl.c#43 (text+ko) ====

@@ -3143,12 +3143,44 @@
 	return error;
 }
 
+/*
+ * Rebuild the parent's multicast address list after an add/del
+ * of a multicast address for a vap.  We have no way to tell
+ * what happened above to optimize the work so we purge the entire
+ * list and rebuild from scratch.  This is way expensive.
+ * Note also the half-baked workaround for if_addmulti calling
+ * back to the parent device; there's no way to insert mcast
+ * entries quietly and/or cheaply.
+ */
+static void
+ieee80211_ioctl_updatemulti(struct ieee80211com *ic)
+{
+	struct ifnet *parent = ic->ic_ifp;
+	struct ieee80211vap *vap;
+	void *ioctl;
+
+	IEEE80211_LOCK(ic);
+	if_purgemaddrs(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)
+			(void) if_addmulti(parent, ifma->ifma_addr, NULL);
+	}
+	parent->if_ioctl = ioctl;
+	IEEE80211_UNLOCK(ic);
+
+	ic->ic_update_mcast(ic->ic_ifp);
+}
+
 int
 ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 {
 	struct ieee80211vap *vap;
 	struct ieee80211com *ic;
-	struct ifnet *parent;
 	int error = 0;
 	struct ifreq *ifr;
 	struct ifaddr *ifa;			/* XXX */
@@ -3193,12 +3225,7 @@
 		break;
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
-		/* XXX merge vap lists into parent */
-		parent = vap->iv_ic->ic_ifp;
-		if (parent->if_drv_flags & IFF_DRV_RUNNING) {
-			/* XXX propagate multicast address to device */
-			error = parent->if_ioctl(parent, cmd, data);
-		}
+		ieee80211_ioctl_updatemulti(vap->iv_ic);
 		break;
 	case SIOCSIFMEDIA:
 	case SIOCGIFMEDIA:



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