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: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
committed by
John W. Linville
parent
b52f2198ac
commit
c1428b3f45
@@ -267,6 +267,17 @@ static int ieee80211_open(struct net_device *dev)
|
|||||||
tasklet_enable(&local->tasklet);
|
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++;
|
local->open_count++;
|
||||||
|
|
||||||
netif_start_queue(dev);
|
netif_start_queue(dev);
|
||||||
@@ -284,6 +295,18 @@ static int ieee80211_stop(struct net_device *dev)
|
|||||||
|
|
||||||
netif_stop_queue(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);
|
dev_mc_unsync(local->mdev, dev);
|
||||||
|
|
||||||
/* down all dependent devices, that is VLANs */
|
/* down all dependent devices, that is VLANs */
|
||||||
|
Reference in New Issue
Block a user