source: branches/backfire/package/mac80211/patches/551-mac80211_fix_iftype_wds.patch @ 26536

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

mac80211: update to trunk as of r26534

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

    a b ieee80211_rx_h_mgmt(struct ieee80211_rx_ 
    23302330 
    23312331        if (!ieee80211_vif_is_mesh(&sdata->vif) && 
    23322332            sdata->vif.type != NL80211_IFTYPE_ADHOC && 
    2333             sdata->vif.type != NL80211_IFTYPE_STATION) 
     2333            sdata->vif.type != NL80211_IFTYPE_STATION && 
     2334            sdata->vif.type != NL80211_IFTYPE_WDS) 
    23342335                return RX_DROP_MONITOR; 
    23352336 
    23362337        switch (stype) { 
    23372338        case cpu_to_le16(IEEE80211_STYPE_BEACON): 
    23382339        case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP): 
    2339                 /* process for all: mesh, mlme, ibss */ 
     2340                /* process for all: mesh, mlme, ibss, wds */ 
    23402341                break; 
    23412342        case cpu_to_le16(IEEE80211_STYPE_DEAUTH): 
    23422343        case cpu_to_le16(IEEE80211_STYPE_DISASSOC): 
    static int prepare_for_handlers(struct i 
    27162717                } 
    27172718                break; 
    27182719        case NL80211_IFTYPE_WDS: 
    2719                 if (bssid || !ieee80211_is_data(hdr->frame_control)) 
     2720                if (bssid) { 
     2721                        if (!ieee80211_is_beacon(hdr->frame_control)) 
     2722                                return 0; 
     2723                } else if (!ieee80211_is_data(hdr->frame_control)) 
    27202724                        return 0; 
    27212725                if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) 
    27222726                        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 
    717694        dev->destructor = free_netdev; 
    718695} 
    719696 
     697static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 
     698                                         struct sk_buff *skb) 
     699{ 
     700        struct ieee80211_local *local = sdata->local; 
     701        struct ieee80211_rx_status *rx_status; 
     702        struct ieee802_11_elems elems; 
     703        struct ieee80211_mgmt *mgmt; 
     704        struct sta_info *sta; 
     705        size_t baselen; 
     706        u32 rates = 0; 
     707        u16 stype; 
     708        bool new = false; 
     709        enum ieee80211_band band = local->hw.conf.channel->band; 
     710        struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; 
     711 
     712        rx_status = IEEE80211_SKB_RXCB(skb); 
     713        mgmt = (struct ieee80211_mgmt *) skb->data; 
     714        stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; 
     715 
     716        if (stype != IEEE80211_STYPE_BEACON) 
     717                return; 
     718 
     719        baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; 
     720        if (baselen > skb->len) 
     721                return; 
     722 
     723        ieee802_11_parse_elems(mgmt->u.probe_resp.variable, 
     724                               skb->len - baselen, &elems); 
     725 
     726        rates = ieee80211_sta_get_rates(local, &elems, band); 
     727 
     728        rcu_read_lock(); 
     729 
     730        sta = sta_info_get(sdata, sdata->u.wds.remote_addr); 
     731 
     732        if (!sta) { 
     733                rcu_read_unlock(); 
     734                sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, 
     735                                     GFP_KERNEL); 
     736                if (!sta) 
     737                        return; 
     738 
     739                new = true; 
     740        } 
     741 
     742        sta->last_rx = jiffies; 
     743        sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 
     744 
     745        if (elems.ht_cap_elem) 
     746                ieee80211_ht_cap_ie_to_sta_ht_cap(sband, 
     747                                elems.ht_cap_elem, &sta->sta.ht_cap); 
     748 
     749        if (elems.wmm_param) 
     750                set_sta_flags(sta, WLAN_STA_WME); 
     751 
     752        if (new) { 
     753                sta->flags = WLAN_STA_AUTHORIZED; 
     754                rate_control_rate_init(sta); 
     755                sta_info_insert_rcu(sta); 
     756        } 
     757 
     758        rcu_read_unlock(); 
     759} 
     760 
    720761static void ieee80211_iface_work(struct work_struct *work) 
    721762{ 
    722763        struct ieee80211_sub_if_data *sdata = 
    static void ieee80211_iface_work(struct  
    821862                                break; 
    822863                        ieee80211_mesh_rx_queued_mgmt(sdata, skb); 
    823864                        break; 
     865                case NL80211_IFTYPE_WDS: 
     866                        ieee80211_wds_rx_queued_mgmt(sdata, skb); 
     867                        break; 
    824868                default: 
    825869                        WARN(1, "frame for unexpected interface type"); 
    826870                        break; 
Note: See TracBrowser for help on using the repository browser.