Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c1428b3f authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

mac80211: fix allmulti/promisc behaviour



When an interface with promisc/allmulti bit is taken down,
the mac80211 state can become confused. This fixes it by
making mac80211 keep track of all *active* interfaces that
have the promisc/allmulti bit set in the sdata, we sync
the interface bit into sdata at set_multicast_list() time
so this works.

Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent b52f2198
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -267,6 +267,17 @@ static int ieee80211_open(struct net_device *dev)
		tasklet_enable(&local->tasklet);
	}

	/*
	 * set_multicast_list will be invoked by the networking core
	 * which will check whether any increments here were done in
	 * error and sync them down to the hardware as filter flags.
	 */
	if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
		atomic_inc(&local->iff_allmultis);

	if (sdata->flags & IEEE80211_SDATA_PROMISC)
		atomic_inc(&local->iff_promiscs);

	local->open_count++;

	netif_start_queue(dev);
@@ -284,6 +295,18 @@ static int ieee80211_stop(struct net_device *dev)

	netif_stop_queue(dev);

	/*
	 * Don't count this interface for promisc/allmulti while it
	 * is down. dev_mc_unsync() will invoke set_multicast_list
	 * on the master interface which will sync these down to the
	 * hardware as filter flags.
	 */
	if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
		atomic_dec(&local->iff_allmultis);

	if (sdata->flags & IEEE80211_SDATA_PROMISC)
		atomic_dec(&local->iff_promiscs);

	dev_mc_unsync(local->mdev, dev);

	/* down all dependent devices, that is VLANs */