[NET]: Make the device list and device lookups per namespace.
[deliverable/linux.git] / net / mac80211 / ieee80211.c
index 4715a9525918ca9b89f61e79e9758c66e2709327..506cfa06b18415f01cfa5f118b092f73ded0e6e6 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/wireless.h>
 #include <linux/rtnetlink.h>
 #include <linux/bitmap.h>
+#include <net/net_namespace.h>
 #include <net/cfg80211.h>
 
 #include "ieee80211_common.h"
@@ -201,34 +202,6 @@ ieee80211_rx_mgmt(struct ieee80211_local *local, struct sk_buff *skb,
        netif_rx(skb);
 }
 
-int ieee80211_radar_status(struct ieee80211_hw *hw, int channel,
-                          int radar, int radar_type)
-{
-       struct sk_buff *skb;
-       struct ieee80211_radar_info *msg;
-       struct ieee80211_local *local = hw_to_local(hw);
-
-       if (!local->apdev)
-               return 0;
-
-       skb = dev_alloc_skb(sizeof(struct ieee80211_frame_info) +
-                           sizeof(struct ieee80211_radar_info));
-
-       if (!skb)
-               return -ENOMEM;
-       skb_reserve(skb, sizeof(struct ieee80211_frame_info));
-
-       msg = (struct ieee80211_radar_info *)
-               skb_put(skb, sizeof(struct ieee80211_radar_info));
-       msg->channel = channel;
-       msg->radar = radar;
-       msg->radar_type = radar_type;
-
-       ieee80211_rx_mgmt(local, skb, NULL, ieee80211_msg_radar);
-       return 0;
-}
-EXPORT_SYMBOL(ieee80211_radar_status);
-
 void ieee80211_key_threshold_notify(struct net_device *dev,
                                    struct ieee80211_key *key,
                                    struct sta_info *sta)
@@ -382,7 +355,7 @@ static void ieee80211_if_open(struct net_device *dev)
        switch (sdata->type) {
        case IEEE80211_IF_TYPE_STA:
        case IEEE80211_IF_TYPE_IBSS:
-               sdata->u.sta.prev_bssid_set = 0;
+               sdata->u.sta.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
                break;
        }
 }
@@ -425,7 +398,10 @@ static int ieee80211_open(struct net_device *dev)
 
        conf.if_id = dev->ifindex;
        conf.type = sdata->type;
-       conf.mac_addr = dev->dev_addr;
+       if (sdata->type == IEEE80211_IF_TYPE_MNTR)
+               conf.mac_addr = NULL;
+       else
+               conf.mac_addr = dev->dev_addr;
        res = local->ops->add_interface(local_to_hw(local), &conf);
        if (res) {
                if (sdata->type == IEEE80211_IF_TYPE_MNTR)
@@ -467,6 +443,7 @@ static int ieee80211_open(struct net_device *dev)
        } else {
                ieee80211_if_config(dev);
                ieee80211_reset_erp_info(dev);
+               ieee80211_enable_keys(sdata);
        }
 
        if (sdata->type == IEEE80211_IF_TYPE_STA &&
@@ -490,7 +467,16 @@ static void ieee80211_if_shutdown(struct net_device *dev)
        case IEEE80211_IF_TYPE_IBSS:
                sdata->u.sta.state = IEEE80211_DISABLED;
                del_timer_sync(&sdata->u.sta.timer);
+               /*
+                * Holding the sub_if_lock for writing here blocks
+                * out the receive path and makes sure it's not
+                * currently processing a packet that may get
+                * added to the queue.
+                */
+               write_lock_bh(&local->sub_if_lock);
                skb_queue_purge(&sdata->u.sta.skb_queue);
+               write_unlock_bh(&local->sub_if_lock);
+
                if (!local->ops->hw_scan &&
                    local->scan_dev == sdata->dev) {
                        local->sta_scanning = 0;
@@ -526,6 +512,9 @@ static int ieee80211_stop(struct net_device *dev)
                local->monitors--;
                if (!local->monitors)
                        local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
+       } else {
+               /* disable all keys for as long as this netdev is down */
+               ieee80211_disable_keys(sdata);
        }
 
        local->open_count--;
@@ -571,23 +560,21 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
        unsigned short flags;
 
        netif_tx_lock_nested(local->mdev, TX_LOCK_MASTER);
-       if (((dev->flags & IFF_ALLMULTI) != 0) ^ (sdata->allmulti != 0)) {
-               if (sdata->allmulti) {
-                       sdata->allmulti = 0;
+       if (((dev->flags & IFF_ALLMULTI) != 0) ^
+           ((sdata->flags & IEEE80211_SDATA_ALLMULTI) != 0)) {
+               if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
                        local->iff_allmultis--;
-               } else {
-                       sdata->allmulti = 1;
+               else
                        local->iff_allmultis++;
-               }
+               sdata->flags ^= IEEE80211_SDATA_ALLMULTI;
        }
-       if (((dev->flags & IFF_PROMISC) != 0) ^ (sdata->promisc != 0)) {
-               if (sdata->promisc) {
-                       sdata->promisc = 0;
+       if (((dev->flags & IFF_PROMISC) != 0) ^
+           ((sdata->flags & IEEE80211_SDATA_PROMISC) != 0)) {
+               if (sdata->flags & IEEE80211_SDATA_PROMISC)
                        local->iff_promiscs--;
-               } else {
-                       sdata->promisc = 1;
+               else
                        local->iff_promiscs++;
-               }
+               sdata->flags ^= IEEE80211_SDATA_PROMISC;
        }
        if (dev->mc_count != sdata->mc_count) {
                local->mc_count = local->mc_count - sdata->mc_count +
@@ -756,16 +743,16 @@ void ieee80211_erp_info_change_notify(struct net_device *dev, u8 changes)
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        if (local->ops->erp_ie_changed)
                local->ops->erp_ie_changed(local_to_hw(local), changes,
-                                          sdata->use_protection,
-                                          !sdata->short_preamble);
+                       !!(sdata->flags & IEEE80211_SDATA_USE_PROTECTION),
+                       !(sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE));
 }
 
 void ieee80211_reset_erp_info(struct net_device *dev)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-       sdata->short_preamble = 0;
-       sdata->use_protection = 0;
+       sdata->flags &= ~(IEEE80211_SDATA_USE_PROTECTION |
+                       IEEE80211_SDATA_SHORT_PREAMBLE);
        ieee80211_erp_info_change_notify(dev,
                                         IEEE80211_ERP_CHANGE_PROTECTION |
                                         IEEE80211_ERP_CHANGE_PREAMBLE);
@@ -802,42 +789,6 @@ struct dev_mc_list *ieee80211_get_mc_list_item(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL(ieee80211_get_mc_list_item);
 
-static void ieee80211_stat_refresh(unsigned long data)
-{
-       struct ieee80211_local *local = (struct ieee80211_local *) data;
-       struct sta_info *sta;
-       struct ieee80211_sub_if_data *sdata;
-
-       if (!local->stat_time)
-               return;
-
-       /* go through all stations */
-       read_lock_bh(&local->sta_lock);
-       list_for_each_entry(sta, &local->sta_list, list) {
-               sta->channel_use = (sta->channel_use_raw / local->stat_time) /
-                       CHAN_UTIL_PER_10MS;
-               sta->channel_use_raw = 0;
-       }
-       read_unlock_bh(&local->sta_lock);
-
-       /* go through all subinterfaces */
-       read_lock(&local->sub_if_lock);
-       list_for_each_entry(sdata, &local->sub_if_list, list) {
-               sdata->channel_use = (sdata->channel_use_raw /
-                                     local->stat_time) / CHAN_UTIL_PER_10MS;
-               sdata->channel_use_raw = 0;
-       }
-       read_unlock(&local->sub_if_lock);
-
-       /* hardware interface */
-       local->channel_use = (local->channel_use_raw /
-                             local->stat_time) / CHAN_UTIL_PER_10MS;
-       local->channel_use_raw = 0;
-
-       local->stat_timer.expires = jiffies + HZ * local->stat_time / 100;
-       add_timer(&local->stat_timer);
-}
-
 void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
                                 struct sk_buff *skb,
                                 struct ieee80211_tx_status *status)
@@ -928,10 +879,15 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
 
        pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
        pkt_data->ifindex = control->ifindex;
-       pkt_data->mgmt_iface = (control->type == IEEE80211_IF_TYPE_MGMT);
-       pkt_data->req_tx_status = !!(control->flags & IEEE80211_TXCTL_REQ_TX_STATUS);
-       pkt_data->do_not_encrypt = !!(control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT);
-       pkt_data->requeue = !!(control->flags & IEEE80211_TXCTL_REQUEUE);
+       pkt_data->flags = 0;
+       if (control->flags & IEEE80211_TXCTL_REQ_TX_STATUS)
+               pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS;
+       if (control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)
+               pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
+       if (control->flags & IEEE80211_TXCTL_REQUEUE)
+               pkt_data->flags |= IEEE80211_TXPD_REQUEUE;
+       if (control->type == IEEE80211_IF_TYPE_MGMT)
+               pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE;
        pkt_data->queue = control->queue;
 
        hdrlen = ieee80211_get_hdrlen_from_skb(skb);
@@ -939,7 +895,7 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
        if (!key)
                goto no_key;
 
-       switch (key->alg) {
+       switch (key->conf.alg) {
        case ALG_WEP:
                iv_len = WEP_IV_LEN;
                mic_len = WEP_ICV_LEN;
@@ -956,7 +912,8 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
                goto no_key;
        }
 
-       if (skb->len >= mic_len && key->force_sw_encrypt)
+       if (skb->len >= mic_len &&
+           !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
                skb_trim(skb, skb->len - mic_len);
        if (skb->len >= iv_len && skb->len > hdrlen) {
                memmove(skb->data + iv_len, skb->data, hdrlen);
@@ -1276,9 +1233,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
        INIT_LIST_HEAD(&local->sub_if_list);
 
        INIT_DELAYED_WORK(&local->scan_work, ieee80211_sta_scan_work);
-       init_timer(&local->stat_timer);
-       local->stat_timer.function = ieee80211_stat_refresh;
-       local->stat_timer.data = (unsigned long) local;
        ieee80211_rx_bss_list_init(mdev);
 
        sta_info_init(local);
@@ -1477,9 +1431,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
 
        rtnl_unlock();
 
-       if (local->stat_time)
-               del_timer_sync(&local->stat_timer);
-
        ieee80211_rx_bss_list_deinit(local->mdev);
        ieee80211_clear_tx_pending(local);
        sta_info_stop(local);
This page took 0.031332 seconds and 5 git commands to generate.