Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=c1428b3f45d152a300e4f18638ebf30ceafda6c3
Commit:     c1428b3f45d152a300e4f18638ebf30ceafda6c3
Parent:     b52f2198ac889561d341c6990d669a671f93f450
Author:     Johannes Berg <[EMAIL PROTECTED]>
AuthorDate: Fri Nov 16 02:54:53 2007 +0100
Committer:  John W. Linville <[EMAIL PROTECTED]>
CommitDate: Tue Nov 20 16:20:31 2007 -0500

    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 <[EMAIL PROTECTED]>
    Signed-off-by: John W. Linville <[EMAIL PROTECTED]>
---
 net/mac80211/ieee80211.c |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index c38e2cd..59350b8 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -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 */
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to