source: trunk/package/mac80211/patches/531-mac80211_fix_iftype_wds.patch @ 26912

Last change on this file since 26912 was 26912, checked in by nbd, 5 years ago

mac80211: update to 2011-05-13

File size: 4.3 KB
  • net/mac80211/rx.c

    a b ieee80211_rx_h_mgmt(struct ieee80211_rx_ 
    23352335 
    23362336        if (!ieee80211_vif_is_mesh(&sdata->vif) && 
    23372337            sdata->vif.type != NL80211_IFTYPE_ADHOC && 
    2338             sdata->vif.type != NL80211_IFTYPE_STATION) 
     2338            sdata->vif.type != NL80211_IFTYPE_STATION && 
     2339            sdata->vif.type != NL80211_IFTYPE_WDS) 
    23392340                return RX_DROP_MONITOR; 
    23402341 
    23412342        switch (stype) { 
    23422343        case cpu_to_le16(IEEE80211_STYPE_BEACON): 
    23432344        case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP): 
    2344                 /* process for all: mesh, mlme, ibss */ 
     2345                /* process for all: mesh, mlme, ibss, wds */ 
    23452346                break; 
    23462347        case cpu_to_le16(IEEE80211_STYPE_DEAUTH): 
    23472348        case cpu_to_le16(IEEE80211_STYPE_DISASSOC): 
    static int prepare_for_handlers(struct i 
    26802681                } 
    26812682                break; 
    26822683        case NL80211_IFTYPE_WDS: 
    2683                 if (bssid || !ieee80211_is_data(hdr->frame_control)) 
     2684                if (bssid) { 
     2685                        if (!ieee80211_is_beacon(hdr->frame_control)) 
     2686                                return 0; 
     2687                } else if (!ieee80211_is_data(hdr->frame_control)) 
    26842688                        return 0; 
    26852689                if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) 
    26862690                        return 0; 
  • net/mac80211/iface.c

    a b static int ieee80211_do_open(struct net_ 
    178178{ 
    179179        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 
    180180        struct ieee80211_local *local = sdata->local; 
    181         struct sta_info *sta; 
    182181        u32 changed = 0; 
    183182        int res; 
    184183        u32 hw_reconf_flags = 0; 
    static int ieee80211_do_open(struct net_ 
    290289 
    291290        set_bit(SDATA_STATE_RUNNING, &sdata->state); 
    292291 
    293         if (sdata->vif.type == NL80211_IFTYPE_WDS) { 
    294                 /* Create STA entry for the WDS peer */ 
    295                 sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, 
    296                                      GFP_KERNEL); 
    297                 if (!sta) { 
    298                         res = -ENOMEM; 
    299                         goto err_del_interface; 
    300                 } 
    301  
    302                 /* no locking required since STA is not live yet */ 
    303                 sta->flags |= WLAN_STA_AUTHORIZED; 
    304  
    305                 res = sta_info_insert(sta); 
    306                 if (res) { 
    307                         /* STA has been freed */ 
    308                         goto err_del_interface; 
    309                 } 
    310  
    311                 rate_control_rate_init(sta); 
    312         } 
    313  
    314292        /* 
    315293         * set_multicast_list will be invoked by the networking core 
    316294         * which will check whether any increments here were done in 
    static int ieee80211_do_open(struct net_ 
    344322        netif_tx_start_all_queues(dev); 
    345323 
    346324        return 0; 
    347  err_del_interface: 
    348         drv_remove_interface(local, &sdata->vif); 
     325 
    349326 err_stop: 
    350327        if (!local->open_count) 
    351328                drv_stop(local); 
    static void ieee80211_if_setup(struct ne 
    718695        dev->destructor = free_netdev; 
    719696} 
    720697 
     698static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 
     699                                         struct sk_buff *skb) 
     700{ 
     701        struct ieee80211_local *local = sdata->local; 
     702        struct ieee80211_rx_status *rx_status; 
     703        struct ieee802_11_elems elems; 
     704        struct ieee80211_mgmt *mgmt; 
     705        struct sta_info *sta; 
     706        size_t baselen; 
     707        u32 rates = 0; 
     708        u16 stype; 
     709        bool new = false; 
     710        enum ieee80211_band band = local->hw.conf.channel->band; 
     711        struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; 
     712 
     713        rx_status = IEEE80211_SKB_RXCB(skb); 
     714        mgmt = (struct ieee80211_mgmt *) skb->data; 
     715        stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; 
     716 
     717        if (stype != IEEE80211_STYPE_BEACON) 
     718                return; 
     719 
     720        baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; 
     721        if (baselen > skb->len) 
     722                return; 
     723 
     724        ieee802_11_parse_elems(mgmt->u.probe_resp.variable, 
     725                               skb->len - baselen, &elems); 
     726 
     727        rates = ieee80211_sta_get_rates(local, &elems, band); 
     728 
     729        rcu_read_lock(); 
     730 
     731        sta = sta_info_get(sdata, sdata->u.wds.remote_addr); 
     732 
     733        if (!sta) { 
     734                rcu_read_unlock(); 
     735                sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, 
     736                                     GFP_KERNEL); 
     737                if (!sta) 
     738                        return; 
     739 
     740                new = true; 
     741        } 
     742 
     743        sta->last_rx = jiffies; 
     744        sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 
     745 
     746        if (elems.ht_cap_elem) 
     747                ieee80211_ht_cap_ie_to_sta_ht_cap(sband, 
     748                                elems.ht_cap_elem, &sta->sta.ht_cap); 
     749 
     750        if (elems.wmm_param) 
     751                set_sta_flags(sta, WLAN_STA_WME); 
     752 
     753        if (new) { 
     754                sta->flags = WLAN_STA_AUTHORIZED; 
     755                rate_control_rate_init(sta); 
     756                sta_info_insert_rcu(sta); 
     757        } 
     758 
     759        rcu_read_unlock(); 
     760} 
     761 
    721762static void ieee80211_iface_work(struct work_struct *work) 
    722763{ 
    723764        struct ieee80211_sub_if_data *sdata = 
    static void ieee80211_iface_work(struct  
    822863                                break; 
    823864                        ieee80211_mesh_rx_queued_mgmt(sdata, skb); 
    824865                        break; 
     866                case NL80211_IFTYPE_WDS: 
     867                        ieee80211_wds_rx_queued_mgmt(sdata, skb); 
     868                        break; 
    825869                default: 
    826870                        WARN(1, "frame for unexpected interface type"); 
    827871                        break; 
Note: See TracBrowser for help on using the repository browser.