mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 14:42:24 +00:00
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:
parent
b52f2198ac
commit
c1428b3f45
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user