提交 c1428b3f 编写于 作者: J Johannes Berg 提交者: John W. Linville

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: NJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 b52f2198
...@@ -267,6 +267,17 @@ static int ieee80211_open(struct net_device *dev) ...@@ -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) ...@@ -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 */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册