Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'mac80211-next-for-davem-2017-10-11' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next

Johannes Berg says:

====================
Work continues in various areas:
* port authorized event for 4-way-HS offload (Avi)
* enable MFP optional for such devices (Emmanuel)
* Kees's timer setup patch for mac80211 mesh
(the part that isn't trivially scripted)
* improve VLAN vs. TXQ handling (myself)
* load regulatory database as firmware file (myself)
* with various other small improvements and cleanups

I merged net-next once in the meantime to allow Kees's
timer setup patch to go in.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+1287 -908
-3
Documentation/driver-api/80211/cfg80211.rst
··· 300 300 :functions: ieee80211_data_to_8023 301 301 302 302 .. kernel-doc:: include/net/cfg80211.h 303 - :functions: ieee80211_data_from_8023 304 - 305 - .. kernel-doc:: include/net/cfg80211.h 306 303 :functions: ieee80211_amsdu_to_8023s 307 304 308 305 .. kernel-doc:: include/net/cfg80211.h
+10 -20
Documentation/networking/regulatory.txt
··· 19 19 How to get regulatory domains to the kernel 20 20 ------------------------------------------- 21 21 22 + When the regulatory domain is first set up, the kernel will request a 23 + database file (regulatory.db) containing all the regulatory rules. It 24 + will then use that database when it needs to look up the rules for a 25 + given country. 26 + 27 + How to get regulatory domains to the kernel (old CRDA solution) 28 + --------------------------------------------------------------- 29 + 22 30 Userspace gets a regulatory domain in the kernel by having 23 31 a userspace agent build it and send it via nl80211. Only 24 32 expected regulatory domains will be respected by the kernel. ··· 200 192 Statically compiled regulatory database 201 193 --------------------------------------- 202 194 203 - In most situations the userland solution using CRDA as described 204 - above is the preferred solution. However in some cases a set of 205 - rules built into the kernel itself may be desirable. To account 206 - for this situation, a configuration option has been provided 207 - (i.e. CONFIG_CFG80211_INTERNAL_REGDB). With this option enabled, 208 - the wireless database information contained in net/wireless/db.txt is 209 - used to generate a data structure encoded in net/wireless/regdb.c. 210 - That option also enables code in net/wireless/reg.c which queries 211 - the data in regdb.c as an alternative to using CRDA. 212 - 213 - The file net/wireless/db.txt should be kept up-to-date with the db.txt 214 - file available in the git repository here: 215 - 216 - git://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git 217 - 218 - Again, most users in most situations should be using the CRDA package 219 - provided with their distribution, and in most other situations users 220 - should be building and using CRDA on their own rather than using 221 - this option. If you are not absolutely sure that you should be using 222 - CONFIG_CFG80211_INTERNAL_REGDB then _DO_NOT_USE_IT_. 195 + When a database should be fixed into the kernel, it can be provided as a 196 + firmware file at build time that is then linked into the kernel.
+10 -3
MAINTAINERS
··· 3329 3329 F: drivers/auxdisplay/cfag12864bfb.c 3330 3330 F: include/linux/cfag12864b.h 3331 3331 3332 - CFG80211 and NL80211 3332 + 802.11 (including CFG80211/NL80211) 3333 3333 M: Johannes Berg <johannes@sipsolutions.net> 3334 3334 L: linux-wireless@vger.kernel.org 3335 3335 W: http://wireless.kernel.org/ 3336 3336 T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git 3337 3337 T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git 3338 3338 S: Maintained 3339 + F: net/wireless/ 3339 3340 F: include/uapi/linux/nl80211.h 3341 + F: include/linux/ieee80211.h 3342 + F: include/net/wext.h 3340 3343 F: include/net/cfg80211.h 3341 - F: net/wireless/* 3342 - X: net/wireless/wext* 3344 + F: include/net/iw_handler.h 3345 + F: include/net/ieee80211_radiotap.h 3346 + F: Documentation/driver-api/80211/cfg80211.rst 3347 + F: Documentation/networking/regulatory.txt 3343 3348 3344 3349 CHAR and MISC DRIVERS 3345 3350 M: Arnd Bergmann <arnd@arndb.de> ··· 8213 8208 F: include/net/mac80211.h 8214 8209 F: net/mac80211/ 8215 8210 F: drivers/net/wireless/mac80211_hwsim.[ch] 8211 + F: Documentation/networking/mac80211_hwsim/README 8216 8212 8217 8213 MAILBOX API 8218 8214 M: Jassi Brar <jassisinghbrar@gmail.com> ··· 11498 11492 T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git 11499 11493 S: Maintained 11500 11494 F: Documentation/rfkill.txt 11495 + F: Documentation/ABI/stable/sysfs-class-rfkill 11501 11496 F: net/rfkill/ 11502 11497 11503 11498 RHASHTABLE
+96 -96
drivers/net/wireless/mac80211_hwsim.c
··· 396 396 if (!tb[QCA_WLAN_VENDOR_ATTR_TEST]) 397 397 return -EINVAL; 398 398 val = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_TEST]); 399 - wiphy_debug(wiphy, "%s: test=%u\n", __func__, val); 399 + wiphy_dbg(wiphy, "%s: test=%u\n", __func__, val); 400 400 401 401 /* Send a vendor event as a test. Note that this would not normally be 402 402 * done within a command handler, but rather, based on some other ··· 643 643 if (!vp->assoc) 644 644 return; 645 645 646 - wiphy_debug(data->hw->wiphy, 647 - "%s: send PS-Poll to %pM for aid %d\n", 648 - __func__, vp->bssid, vp->aid); 646 + wiphy_dbg(data->hw->wiphy, 647 + "%s: send PS-Poll to %pM for aid %d\n", 648 + __func__, vp->bssid, vp->aid); 649 649 650 650 skb = dev_alloc_skb(sizeof(*pspoll)); 651 651 if (!skb) ··· 674 674 if (!vp->assoc) 675 675 return; 676 676 677 - wiphy_debug(data->hw->wiphy, 678 - "%s: send data::nullfunc to %pM ps=%d\n", 679 - __func__, vp->bssid, ps); 677 + wiphy_dbg(data->hw->wiphy, 678 + "%s: send data::nullfunc to %pM ps=%d\n", 679 + __func__, vp->bssid, ps); 680 680 681 681 skb = dev_alloc_skb(sizeof(*hdr)); 682 682 if (!skb) ··· 1034 1034 msg_head = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0, 1035 1035 HWSIM_CMD_FRAME); 1036 1036 if (msg_head == NULL) { 1037 - printk(KERN_DEBUG "mac80211_hwsim: problem with msg_head\n"); 1037 + pr_debug("mac80211_hwsim: problem with msg_head\n"); 1038 1038 goto nla_put_failure; 1039 1039 } 1040 1040 ··· 1093 1093 nla_put_failure: 1094 1094 nlmsg_free(skb); 1095 1095 err_free_txskb: 1096 - printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); 1096 + pr_debug("mac80211_hwsim: error occurred in %s\n", __func__); 1097 1097 ieee80211_free_txskb(hw, my_skb); 1098 1098 data->tx_failed++; 1099 1099 } ··· 1347 1347 } 1348 1348 1349 1349 if (data->idle && !data->tmp_chan) { 1350 - wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n"); 1350 + wiphy_dbg(hw->wiphy, "Trying to TX when idle - reject\n"); 1351 1351 ieee80211_free_txskb(hw, skb); 1352 1352 return; 1353 1353 } ··· 1408 1408 static int mac80211_hwsim_start(struct ieee80211_hw *hw) 1409 1409 { 1410 1410 struct mac80211_hwsim_data *data = hw->priv; 1411 - wiphy_debug(hw->wiphy, "%s\n", __func__); 1411 + wiphy_dbg(hw->wiphy, "%s\n", __func__); 1412 1412 data->started = true; 1413 1413 return 0; 1414 1414 } ··· 1419 1419 struct mac80211_hwsim_data *data = hw->priv; 1420 1420 data->started = false; 1421 1421 tasklet_hrtimer_cancel(&data->beacon_timer); 1422 - wiphy_debug(hw->wiphy, "%s\n", __func__); 1422 + wiphy_dbg(hw->wiphy, "%s\n", __func__); 1423 1423 } 1424 1424 1425 1425 1426 1426 static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, 1427 1427 struct ieee80211_vif *vif) 1428 1428 { 1429 - wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n", 1430 - __func__, ieee80211_vif_type_p2p(vif), 1431 - vif->addr); 1429 + wiphy_dbg(hw->wiphy, "%s (type=%d mac_addr=%pM)\n", 1430 + __func__, ieee80211_vif_type_p2p(vif), 1431 + vif->addr); 1432 1432 hwsim_set_magic(vif); 1433 1433 1434 1434 vif->cab_queue = 0; ··· 1447 1447 bool newp2p) 1448 1448 { 1449 1449 newtype = ieee80211_iftype_p2p(newtype, newp2p); 1450 - wiphy_debug(hw->wiphy, 1451 - "%s (old type=%d, new type=%d, mac_addr=%pM)\n", 1452 - __func__, ieee80211_vif_type_p2p(vif), 1450 + wiphy_dbg(hw->wiphy, 1451 + "%s (old type=%d, new type=%d, mac_addr=%pM)\n", 1452 + __func__, ieee80211_vif_type_p2p(vif), 1453 1453 newtype, vif->addr); 1454 1454 hwsim_check_magic(vif); 1455 1455 ··· 1465 1465 static void mac80211_hwsim_remove_interface( 1466 1466 struct ieee80211_hw *hw, struct ieee80211_vif *vif) 1467 1467 { 1468 - wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n", 1469 - __func__, ieee80211_vif_type_p2p(vif), 1470 - vif->addr); 1468 + wiphy_dbg(hw->wiphy, "%s (type=%d mac_addr=%pM)\n", 1469 + __func__, ieee80211_vif_type_p2p(vif), 1470 + vif->addr); 1471 1471 hwsim_check_magic(vif); 1472 1472 hwsim_clear_magic(vif); 1473 1473 } ··· 1589 1589 int idx; 1590 1590 1591 1591 if (conf->chandef.chan) 1592 - wiphy_debug(hw->wiphy, 1593 - "%s (freq=%d(%d - %d)/%s idle=%d ps=%d smps=%s)\n", 1594 - __func__, 1595 - conf->chandef.chan->center_freq, 1596 - conf->chandef.center_freq1, 1597 - conf->chandef.center_freq2, 1598 - hwsim_chanwidths[conf->chandef.width], 1599 - !!(conf->flags & IEEE80211_CONF_IDLE), 1600 - !!(conf->flags & IEEE80211_CONF_PS), 1601 - smps_modes[conf->smps_mode]); 1592 + wiphy_dbg(hw->wiphy, 1593 + "%s (freq=%d(%d - %d)/%s idle=%d ps=%d smps=%s)\n", 1594 + __func__, 1595 + conf->chandef.chan->center_freq, 1596 + conf->chandef.center_freq1, 1597 + conf->chandef.center_freq2, 1598 + hwsim_chanwidths[conf->chandef.width], 1599 + !!(conf->flags & IEEE80211_CONF_IDLE), 1600 + !!(conf->flags & IEEE80211_CONF_PS), 1601 + smps_modes[conf->smps_mode]); 1602 1602 else 1603 - wiphy_debug(hw->wiphy, 1604 - "%s (freq=0 idle=%d ps=%d smps=%s)\n", 1605 - __func__, 1606 - !!(conf->flags & IEEE80211_CONF_IDLE), 1607 - !!(conf->flags & IEEE80211_CONF_PS), 1608 - smps_modes[conf->smps_mode]); 1603 + wiphy_dbg(hw->wiphy, 1604 + "%s (freq=0 idle=%d ps=%d smps=%s)\n", 1605 + __func__, 1606 + !!(conf->flags & IEEE80211_CONF_IDLE), 1607 + !!(conf->flags & IEEE80211_CONF_PS), 1608 + smps_modes[conf->smps_mode]); 1609 1609 1610 1610 data->idle = !!(conf->flags & IEEE80211_CONF_IDLE); 1611 1611 ··· 1659 1659 { 1660 1660 struct mac80211_hwsim_data *data = hw->priv; 1661 1661 1662 - wiphy_debug(hw->wiphy, "%s\n", __func__); 1662 + wiphy_dbg(hw->wiphy, "%s\n", __func__); 1663 1663 1664 1664 data->rx_filter = 0; 1665 1665 if (*total_flags & FIF_ALLMULTI) ··· 1688 1688 1689 1689 hwsim_check_magic(vif); 1690 1690 1691 - wiphy_debug(hw->wiphy, "%s(changed=0x%x vif->addr=%pM)\n", 1692 - __func__, changed, vif->addr); 1691 + wiphy_dbg(hw->wiphy, "%s(changed=0x%x vif->addr=%pM)\n", 1692 + __func__, changed, vif->addr); 1693 1693 1694 1694 if (changed & BSS_CHANGED_BSSID) { 1695 - wiphy_debug(hw->wiphy, "%s: BSSID changed: %pM\n", 1696 - __func__, info->bssid); 1695 + wiphy_dbg(hw->wiphy, "%s: BSSID changed: %pM\n", 1696 + __func__, info->bssid); 1697 1697 memcpy(vp->bssid, info->bssid, ETH_ALEN); 1698 1698 } 1699 1699 1700 1700 if (changed & BSS_CHANGED_ASSOC) { 1701 - wiphy_debug(hw->wiphy, " ASSOC: assoc=%d aid=%d\n", 1702 - info->assoc, info->aid); 1701 + wiphy_dbg(hw->wiphy, " ASSOC: assoc=%d aid=%d\n", 1702 + info->assoc, info->aid); 1703 1703 vp->assoc = info->assoc; 1704 1704 vp->aid = info->aid; 1705 1705 } 1706 1706 1707 1707 if (changed & BSS_CHANGED_BEACON_ENABLED) { 1708 - wiphy_debug(hw->wiphy, " BCN EN: %d (BI=%u)\n", 1709 - info->enable_beacon, info->beacon_int); 1708 + wiphy_dbg(hw->wiphy, " BCN EN: %d (BI=%u)\n", 1709 + info->enable_beacon, info->beacon_int); 1710 1710 vp->bcn_en = info->enable_beacon; 1711 1711 if (data->started && 1712 1712 !hrtimer_is_queued(&data->beacon_timer.timer) && ··· 1725 1725 ieee80211_iterate_active_interfaces_atomic( 1726 1726 data->hw, IEEE80211_IFACE_ITER_NORMAL, 1727 1727 mac80211_hwsim_bcn_en_iter, &count); 1728 - wiphy_debug(hw->wiphy, " beaconing vifs remaining: %u", 1729 - count); 1728 + wiphy_dbg(hw->wiphy, " beaconing vifs remaining: %u", 1729 + count); 1730 1730 if (count == 0) { 1731 1731 tasklet_hrtimer_cancel(&data->beacon_timer); 1732 1732 data->beacon_int = 0; ··· 1735 1735 } 1736 1736 1737 1737 if (changed & BSS_CHANGED_ERP_CTS_PROT) { 1738 - wiphy_debug(hw->wiphy, " ERP_CTS_PROT: %d\n", 1739 - info->use_cts_prot); 1738 + wiphy_dbg(hw->wiphy, " ERP_CTS_PROT: %d\n", 1739 + info->use_cts_prot); 1740 1740 } 1741 1741 1742 1742 if (changed & BSS_CHANGED_ERP_PREAMBLE) { 1743 - wiphy_debug(hw->wiphy, " ERP_PREAMBLE: %d\n", 1744 - info->use_short_preamble); 1743 + wiphy_dbg(hw->wiphy, " ERP_PREAMBLE: %d\n", 1744 + info->use_short_preamble); 1745 1745 } 1746 1746 1747 1747 if (changed & BSS_CHANGED_ERP_SLOT) { 1748 - wiphy_debug(hw->wiphy, " ERP_SLOT: %d\n", info->use_short_slot); 1748 + wiphy_dbg(hw->wiphy, " ERP_SLOT: %d\n", info->use_short_slot); 1749 1749 } 1750 1750 1751 1751 if (changed & BSS_CHANGED_HT) { 1752 - wiphy_debug(hw->wiphy, " HT: op_mode=0x%x\n", 1753 - info->ht_operation_mode); 1752 + wiphy_dbg(hw->wiphy, " HT: op_mode=0x%x\n", 1753 + info->ht_operation_mode); 1754 1754 } 1755 1755 1756 1756 if (changed & BSS_CHANGED_BASIC_RATES) { 1757 - wiphy_debug(hw->wiphy, " BASIC_RATES: 0x%llx\n", 1758 - (unsigned long long) info->basic_rates); 1757 + wiphy_dbg(hw->wiphy, " BASIC_RATES: 0x%llx\n", 1758 + (unsigned long long) info->basic_rates); 1759 1759 } 1760 1760 1761 1761 if (changed & BSS_CHANGED_TXPOWER) 1762 - wiphy_debug(hw->wiphy, " TX Power: %d dBm\n", info->txpower); 1762 + wiphy_dbg(hw->wiphy, " TX Power: %d dBm\n", info->txpower); 1763 1763 } 1764 1764 1765 1765 static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw, ··· 1813 1813 struct ieee80211_vif *vif, u16 queue, 1814 1814 const struct ieee80211_tx_queue_params *params) 1815 1815 { 1816 - wiphy_debug(hw->wiphy, 1817 - "%s (queue=%d txop=%d cw_min=%d cw_max=%d aifs=%d)\n", 1818 - __func__, queue, 1819 - params->txop, params->cw_min, 1820 - params->cw_max, params->aifs); 1816 + wiphy_dbg(hw->wiphy, 1817 + "%s (queue=%d txop=%d cw_min=%d cw_max=%d aifs=%d)\n", 1818 + __func__, queue, 1819 + params->txop, params->cw_min, 1820 + params->cw_max, params->aifs); 1821 1821 return 0; 1822 1822 } 1823 1823 ··· 1981 1981 .aborted = false, 1982 1982 }; 1983 1983 1984 - wiphy_debug(hwsim->hw->wiphy, "hw scan complete\n"); 1984 + wiphy_dbg(hwsim->hw->wiphy, "hw scan complete\n"); 1985 1985 ieee80211_scan_completed(hwsim->hw, &info); 1986 1986 hwsim->hw_scan_request = NULL; 1987 1987 hwsim->hw_scan_vif = NULL; ··· 1990 1990 return; 1991 1991 } 1992 1992 1993 - wiphy_debug(hwsim->hw->wiphy, "hw scan %d MHz\n", 1994 - req->channels[hwsim->scan_chan_idx]->center_freq); 1993 + wiphy_dbg(hwsim->hw->wiphy, "hw scan %d MHz\n", 1994 + req->channels[hwsim->scan_chan_idx]->center_freq); 1995 1995 1996 1996 hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx]; 1997 1997 if (hwsim->tmp_chan->flags & (IEEE80211_CHAN_NO_IR | ··· 2060 2060 memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data)); 2061 2061 mutex_unlock(&hwsim->mutex); 2062 2062 2063 - wiphy_debug(hw->wiphy, "hwsim hw_scan request\n"); 2063 + wiphy_dbg(hw->wiphy, "hwsim hw_scan request\n"); 2064 2064 2065 2065 ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, 0); 2066 2066 ··· 2075 2075 .aborted = true, 2076 2076 }; 2077 2077 2078 - wiphy_debug(hw->wiphy, "hwsim cancel_hw_scan\n"); 2078 + wiphy_dbg(hw->wiphy, "hwsim cancel_hw_scan\n"); 2079 2079 2080 2080 cancel_delayed_work_sync(&hwsim->hw_scan); 2081 2081 ··· 2096 2096 mutex_lock(&hwsim->mutex); 2097 2097 2098 2098 if (hwsim->scanning) { 2099 - printk(KERN_DEBUG "two hwsim sw_scans detected!\n"); 2099 + pr_debug("two hwsim sw_scans detected!\n"); 2100 2100 goto out; 2101 2101 } 2102 2102 2103 - printk(KERN_DEBUG "hwsim sw_scan request, prepping stuff\n"); 2103 + pr_debug("hwsim sw_scan request, prepping stuff\n"); 2104 2104 2105 2105 memcpy(hwsim->scan_addr, mac_addr, ETH_ALEN); 2106 2106 hwsim->scanning = true; ··· 2117 2117 2118 2118 mutex_lock(&hwsim->mutex); 2119 2119 2120 - printk(KERN_DEBUG "hwsim sw_scan_complete\n"); 2120 + pr_debug("hwsim sw_scan_complete\n"); 2121 2121 hwsim->scanning = false; 2122 2122 eth_zero_addr(hwsim->scan_addr); 2123 2123 ··· 2131 2131 2132 2132 mutex_lock(&hwsim->mutex); 2133 2133 2134 - wiphy_debug(hwsim->hw->wiphy, "hwsim ROC begins\n"); 2134 + wiphy_dbg(hwsim->hw->wiphy, "hwsim ROC begins\n"); 2135 2135 hwsim->tmp_chan = hwsim->roc_chan; 2136 2136 ieee80211_ready_on_channel(hwsim->hw); 2137 2137 ··· 2151 2151 hwsim->tmp_chan = NULL; 2152 2152 mutex_unlock(&hwsim->mutex); 2153 2153 2154 - wiphy_debug(hwsim->hw->wiphy, "hwsim ROC expired\n"); 2154 + wiphy_dbg(hwsim->hw->wiphy, "hwsim ROC expired\n"); 2155 2155 } 2156 2156 2157 2157 static int mac80211_hwsim_roc(struct ieee80211_hw *hw, ··· 2172 2172 hwsim->roc_duration = duration; 2173 2173 mutex_unlock(&hwsim->mutex); 2174 2174 2175 - wiphy_debug(hw->wiphy, "hwsim ROC (%d MHz, %d ms)\n", 2176 - chan->center_freq, duration); 2175 + wiphy_dbg(hw->wiphy, "hwsim ROC (%d MHz, %d ms)\n", 2176 + chan->center_freq, duration); 2177 2177 ieee80211_queue_delayed_work(hw, &hwsim->roc_start, HZ/50); 2178 2178 2179 2179 return 0; ··· 2190 2190 hwsim->tmp_chan = NULL; 2191 2191 mutex_unlock(&hwsim->mutex); 2192 2192 2193 - wiphy_debug(hw->wiphy, "hwsim ROC canceled\n"); 2193 + wiphy_dbg(hw->wiphy, "hwsim ROC canceled\n"); 2194 2194 2195 2195 return 0; 2196 2196 } ··· 2199 2199 struct ieee80211_chanctx_conf *ctx) 2200 2200 { 2201 2201 hwsim_set_chanctx_magic(ctx); 2202 - wiphy_debug(hw->wiphy, 2203 - "add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n", 2204 - ctx->def.chan->center_freq, ctx->def.width, 2205 - ctx->def.center_freq1, ctx->def.center_freq2); 2202 + wiphy_dbg(hw->wiphy, 2203 + "add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n", 2204 + ctx->def.chan->center_freq, ctx->def.width, 2205 + ctx->def.center_freq1, ctx->def.center_freq2); 2206 2206 return 0; 2207 2207 } 2208 2208 2209 2209 static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw, 2210 2210 struct ieee80211_chanctx_conf *ctx) 2211 2211 { 2212 - wiphy_debug(hw->wiphy, 2213 - "remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n", 2214 - ctx->def.chan->center_freq, ctx->def.width, 2215 - ctx->def.center_freq1, ctx->def.center_freq2); 2212 + wiphy_dbg(hw->wiphy, 2213 + "remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n", 2214 + ctx->def.chan->center_freq, ctx->def.width, 2215 + ctx->def.center_freq1, ctx->def.center_freq2); 2216 2216 hwsim_check_chanctx_magic(ctx); 2217 2217 hwsim_clear_chanctx_magic(ctx); 2218 2218 } ··· 2222 2222 u32 changed) 2223 2223 { 2224 2224 hwsim_check_chanctx_magic(ctx); 2225 - wiphy_debug(hw->wiphy, 2226 - "change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n", 2227 - ctx->def.chan->center_freq, ctx->def.width, 2228 - ctx->def.center_freq1, ctx->def.center_freq2); 2225 + wiphy_dbg(hw->wiphy, 2226 + "change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n", 2227 + ctx->def.chan->center_freq, ctx->def.width, 2228 + ctx->def.center_freq1, ctx->def.center_freq2); 2229 2229 } 2230 2230 2231 2231 static int mac80211_hwsim_assign_vif_chanctx(struct ieee80211_hw *hw, ··· 2479 2479 ops = &mac80211_hwsim_mchan_ops; 2480 2480 hw = ieee80211_alloc_hw_nm(sizeof(*data), ops, param->hwname); 2481 2481 if (!hw) { 2482 - printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw failed\n"); 2482 + pr_debug("mac80211_hwsim: ieee80211_alloc_hw failed\n"); 2483 2483 err = -ENOMEM; 2484 2484 goto failed; 2485 2485 } ··· 2507 2507 data->dev->driver = &mac80211_hwsim_driver.driver; 2508 2508 err = device_bind_driver(data->dev); 2509 2509 if (err != 0) { 2510 - printk(KERN_DEBUG "mac80211_hwsim: device_bind_driver failed (%d)\n", 2510 + pr_debug("mac80211_hwsim: device_bind_driver failed (%d)\n", 2511 2511 err); 2512 2512 goto failed_bind; 2513 2513 } ··· 2698 2698 2699 2699 err = ieee80211_register_hw(hw); 2700 2700 if (err < 0) { 2701 - printk(KERN_DEBUG "mac80211_hwsim: ieee80211_register_hw failed (%d)\n", 2701 + pr_debug("mac80211_hwsim: ieee80211_register_hw failed (%d)\n", 2702 2702 err); 2703 2703 goto failed_hw; 2704 2704 } 2705 2705 2706 - wiphy_debug(hw->wiphy, "hwaddr %pM registered\n", hw->wiphy->perm_addr); 2706 + wiphy_dbg(hw->wiphy, "hwaddr %pM registered\n", hw->wiphy->perm_addr); 2707 2707 2708 2708 if (param->reg_alpha2) { 2709 2709 data->alpha2[0] = param->reg_alpha2[0]; ··· 3067 3067 3068 3068 return 0; 3069 3069 err: 3070 - printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); 3070 + pr_debug("mac80211_hwsim: error occurred in %s\n", __func__); 3071 3071 out: 3072 3072 dev_kfree_skb(skb); 3073 3073 return -EINVAL; ··· 3098 3098 3099 3099 hwsim_register_wmediumd(net, info->snd_portid); 3100 3100 3101 - printk(KERN_DEBUG "mac80211_hwsim: received a REGISTER, " 3101 + pr_debug("mac80211_hwsim: received a REGISTER, " 3102 3102 "switching to wmediumd mode with pid %d\n", info->snd_portid); 3103 3103 3104 3104 return 0; ··· 3387 3387 return 0; 3388 3388 3389 3389 failure: 3390 - printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); 3390 + pr_debug("mac80211_hwsim: error occurred in %s\n", __func__); 3391 3391 return -EINVAL; 3392 3392 } 3393 3393 ··· 3578 3578 3579 3579 static void __exit exit_mac80211_hwsim(void) 3580 3580 { 3581 - printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n"); 3581 + pr_debug("mac80211_hwsim: unregister radios\n"); 3582 3582 3583 3583 hwsim_exit_netlink(); 3584 3584
+1
include/linux/ieee80211.h
··· 2445 2445 #define WLAN_OUI_TYPE_MICROSOFT_WPA 1 2446 2446 #define WLAN_OUI_TYPE_MICROSOFT_WMM 2 2447 2447 #define WLAN_OUI_TYPE_MICROSOFT_WPS 4 2448 + #define WLAN_OUI_TYPE_MICROSOFT_TPC 8 2448 2449 2449 2450 /* 2450 2451 * WMM/802.11e Tspec Element
+21 -19
include/net/cfg80211.h
··· 4347 4347 } 4348 4348 4349 4349 /** 4350 - * ieee80211_data_from_8023 - convert an 802.3 frame to 802.11 4351 - * @skb: the 802.3 frame 4352 - * @addr: the device MAC address 4353 - * @iftype: the virtual interface type 4354 - * @bssid: the network bssid (used only for iftype STATION and ADHOC) 4355 - * @qos: build 802.11 QoS data frame 4356 - * Return: 0 on success, or a negative error code. 4357 - */ 4358 - int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, 4359 - enum nl80211_iftype iftype, const u8 *bssid, 4360 - bool qos); 4361 - 4362 - /** 4363 4350 * ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame 4364 4351 * 4365 4352 * Decode an IEEE 802.11 A-MSDU and convert it to a list of 802.3 frames. ··· 5428 5441 * @req_ie_len: association request IEs length 5429 5442 * @resp_ie: association response IEs (may be %NULL) 5430 5443 * @resp_ie_len: assoc response IEs length 5431 - * @authorized: true if the 802.1X authentication was done by the driver or is 5432 - * not needed (e.g., when Fast Transition protocol was used), false 5433 - * otherwise. Ignored for networks that don't use 802.1X authentication. 5434 5444 */ 5435 5445 struct cfg80211_roam_info { 5436 5446 struct ieee80211_channel *channel; ··· 5437 5453 size_t req_ie_len; 5438 5454 const u8 *resp_ie; 5439 5455 size_t resp_ie_len; 5440 - bool authorized; 5441 5456 }; 5442 5457 5443 5458 /** ··· 5459 5476 */ 5460 5477 void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info, 5461 5478 gfp_t gfp); 5479 + 5480 + /** 5481 + * cfg80211_port_authorized - notify cfg80211 of successful security association 5482 + * 5483 + * @dev: network device 5484 + * @bssid: the BSSID of the AP 5485 + * @gfp: allocation flags 5486 + * 5487 + * This function should be called by a driver that supports 4 way handshake 5488 + * offload after a security association was successfully established (i.e., 5489 + * the 4 way handshake was completed successfully). The call to this function 5490 + * should be preceded with a call to cfg80211_connect_result(), 5491 + * cfg80211_connect_done(), cfg80211_connect_bss() or cfg80211_roamed() to 5492 + * indicate the 802.11 association. 5493 + */ 5494 + void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid, 5495 + gfp_t gfp); 5462 5496 5463 5497 /** 5464 5498 * cfg80211_disconnected - notify cfg80211 that connection was dropped ··· 5934 5934 * @ies: the IE buffer 5935 5935 * @ielen: the length of the IE buffer 5936 5936 * @ids: an array with element IDs that are allowed before 5937 - * the split 5937 + * the split. A WLAN_EID_EXTENSION value means that the next 5938 + * EID in the list is a sub-element of the EXTENSION IE. 5938 5939 * @n_ids: the size of the element ID array 5939 5940 * @after_ric: array IE types that come after the RIC element 5940 5941 * @n_after_ric: size of the @after_ric array ··· 5966 5965 * @ies: the IE buffer 5967 5966 * @ielen: the length of the IE buffer 5968 5967 * @ids: an array with element IDs that are allowed before 5969 - * the split 5968 + * the split. A WLAN_EID_EXTENSION value means that the next 5969 + * EID in the list is a sub-element of the EXTENSION IE. 5970 5970 * @n_ids: the size of the element ID array 5971 5971 * @offset: offset where to start splitting in the buffer 5972 5972 *
+7
include/net/fq.h
··· 90 90 struct fq_flow *, 91 91 struct sk_buff *); 92 92 93 + /* Return %true to filter (drop) the frame. */ 94 + typedef bool fq_skb_filter_t(struct fq *, 95 + struct fq_tin *, 96 + struct fq_flow *, 97 + struct sk_buff *, 98 + void *); 99 + 93 100 typedef struct fq_flow *fq_flow_get_default_t(struct fq *, 94 101 struct fq_tin *, 95 102 int idx,
+62 -10
include/net/fq_impl.h
··· 12 12 13 13 /* functions that are embedded into includer */ 14 14 15 - static struct sk_buff *fq_flow_dequeue(struct fq *fq, 16 - struct fq_flow *flow) 15 + static void fq_adjust_removal(struct fq *fq, 16 + struct fq_flow *flow, 17 + struct sk_buff *skb) 17 18 { 18 19 struct fq_tin *tin = flow->tin; 19 - struct fq_flow *i; 20 - struct sk_buff *skb; 21 - 22 - lockdep_assert_held(&fq->lock); 23 - 24 - skb = __skb_dequeue(&flow->queue); 25 - if (!skb) 26 - return NULL; 27 20 28 21 tin->backlog_bytes -= skb->len; 29 22 tin->backlog_packets--; 30 23 flow->backlog -= skb->len; 31 24 fq->backlog--; 32 25 fq->memory_usage -= skb->truesize; 26 + } 27 + 28 + static void fq_rejigger_backlog(struct fq *fq, struct fq_flow *flow) 29 + { 30 + struct fq_flow *i; 33 31 34 32 if (flow->backlog == 0) { 35 33 list_del_init(&flow->backlogchain); ··· 41 43 list_move_tail(&flow->backlogchain, 42 44 &i->backlogchain); 43 45 } 46 + } 47 + 48 + static struct sk_buff *fq_flow_dequeue(struct fq *fq, 49 + struct fq_flow *flow) 50 + { 51 + struct sk_buff *skb; 52 + 53 + lockdep_assert_held(&fq->lock); 54 + 55 + skb = __skb_dequeue(&flow->queue); 56 + if (!skb) 57 + return NULL; 58 + 59 + fq_adjust_removal(fq, flow, skb); 60 + fq_rejigger_backlog(fq, flow); 44 61 45 62 return skb; 46 63 } ··· 199 186 if (fq->memory_usage > fq->memory_limit) 200 187 fq->overmemory++; 201 188 } 189 + } 190 + 191 + static void fq_flow_filter(struct fq *fq, 192 + struct fq_flow *flow, 193 + fq_skb_filter_t filter_func, 194 + void *filter_data, 195 + fq_skb_free_t free_func) 196 + { 197 + struct fq_tin *tin = flow->tin; 198 + struct sk_buff *skb, *tmp; 199 + 200 + lockdep_assert_held(&fq->lock); 201 + 202 + skb_queue_walk_safe(&flow->queue, skb, tmp) { 203 + if (!filter_func(fq, tin, flow, skb, filter_data)) 204 + continue; 205 + 206 + __skb_unlink(skb, &flow->queue); 207 + fq_adjust_removal(fq, flow, skb); 208 + free_func(fq, tin, flow, skb); 209 + } 210 + 211 + fq_rejigger_backlog(fq, flow); 212 + } 213 + 214 + static void fq_tin_filter(struct fq *fq, 215 + struct fq_tin *tin, 216 + fq_skb_filter_t filter_func, 217 + void *filter_data, 218 + fq_skb_free_t free_func) 219 + { 220 + struct fq_flow *flow; 221 + 222 + lockdep_assert_held(&fq->lock); 223 + 224 + list_for_each_entry(flow, &tin->new_flows, flowchain) 225 + fq_flow_filter(fq, flow, filter_func, filter_data, free_func); 226 + list_for_each_entry(flow, &tin->old_flows, flowchain) 227 + fq_flow_filter(fq, flow, filter_func, filter_data, free_func); 202 228 } 203 229 204 230 static void fq_flow_reset(struct fq *fq,
+7 -1
include/net/mac80211.h
··· 5441 5441 */ 5442 5442 void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn); 5443 5443 5444 + /** 5445 + * ieee80211_manage_rx_ba_offl - helper to queue an RX BA work 5446 + * @vif: &struct ieee80211_vif pointer from the add_interface callback 5447 + * @addr: station mac address 5448 + * @tid: the rx tid 5449 + */ 5444 5450 void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif, const u8 *addr, 5445 - unsigned int bit); 5451 + unsigned int tid); 5446 5452 5447 5453 /** 5448 5454 * ieee80211_start_rx_ba_session_offl - start a Rx BA session
+65 -17
include/uapi/linux/nl80211.h
··· 569 569 * authentication/association or not receiving a response from the AP. 570 570 * Non-zero %NL80211_ATTR_STATUS_CODE value is indicated in that case as 571 571 * well to remain backwards compatible. 572 - * @NL80211_CMD_ROAM: notifcation indicating the card/driver roamed by itself. 573 - * When the driver roamed in a network that requires 802.1X authentication, 574 - * %NL80211_ATTR_PORT_AUTHORIZED should be set if the 802.1X authentication 575 - * was done by the driver or if roaming was done using Fast Transition 576 - * protocol (in which case 802.1X authentication is not needed). If 577 - * %NL80211_ATTR_PORT_AUTHORIZED is not set, user space is responsible for 578 - * the 802.1X authentication. 572 + * When establishing a security association, drivers that support 4 way 573 + * handshake offload should send %NL80211_CMD_PORT_AUTHORIZED event when 574 + * the 4 way handshake is completed successfully. 575 + * @NL80211_CMD_ROAM: Notification indicating the card/driver roamed by itself. 576 + * When a security association was established with the new AP (e.g. if 577 + * the FT protocol was used for roaming or the driver completed the 4 way 578 + * handshake), this event should be followed by an 579 + * %NL80211_CMD_PORT_AUTHORIZED event. 579 580 * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify 580 581 * userspace that a connection was dropped by the AP or due to other 581 582 * reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and ··· 983 982 * @NL80211_CMD_DEL_PMK: For offloaded 4-Way handshake, delete the previously 984 983 * configured PMK for the authenticator address identified by 985 984 * &NL80211_ATTR_MAC. 985 + * @NL80211_CMD_PORT_AUTHORIZED: An event that indicates that the 4 way 986 + * handshake was completed successfully by the driver. The BSSID is 987 + * specified with &NL80211_ATTR_MAC. Drivers that support 4 way handshake 988 + * offload should send this event after indicating 802.11 association with 989 + * &NL80211_CMD_CONNECT or &NL80211_CMD_ROAM. If the 4 way handshake failed 990 + * &NL80211_CMD_DISCONNECT should be indicated instead. 991 + * 992 + * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded. 986 993 * 987 994 * @NL80211_CMD_MAX: highest used command number 988 995 * @__NL80211_CMD_AFTER_LAST: internal use ··· 1193 1184 1194 1185 NL80211_CMD_SET_PMK, 1195 1186 NL80211_CMD_DEL_PMK, 1187 + 1188 + NL80211_CMD_PORT_AUTHORIZED, 1189 + 1190 + NL80211_CMD_RELOAD_REGDB, 1196 1191 1197 1192 /* add new commands above here */ 1198 1193 ··· 1420 1407 * 1421 1408 * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is 1422 1409 * used for the association (&enum nl80211_mfp, represented as a u32); 1423 - * this attribute can be used 1424 - * with %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests 1410 + * this attribute can be used with %NL80211_CMD_ASSOCIATE and 1411 + * %NL80211_CMD_CONNECT requests. %NL80211_MFP_OPTIONAL is not allowed for 1412 + * %NL80211_CMD_ASSOCIATE since user space SME is expected and hence, it 1413 + * must have decided whether to use management frame protection or not. 1414 + * Setting %NL80211_MFP_OPTIONAL with a %NL80211_CMD_CONNECT request will 1415 + * let the driver (or the firmware) decide whether to use MFP or not. 1425 1416 * 1426 1417 * @NL80211_ATTR_STA_FLAGS2: Attribute containing a 1427 1418 * &struct nl80211_sta_flag_update. ··· 2151 2134 * in %NL80211_CMD_CONNECT to indicate that for 802.1X authentication it 2152 2135 * wants to use the supported offload of the 4-way handshake. 2153 2136 * @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT. 2154 - * @NL80211_ATTR_PORT_AUTHORIZED: flag attribute used in %NL80211_CMD_ROAMED 2155 - * notification indicating that that 802.1X authentication was done by 2156 - * the driver or is not needed (because roaming used the Fast Transition 2157 - * protocol). 2137 + * @NL80211_ATTR_PORT_AUTHORIZED: (reserved) 2158 2138 * 2159 2139 * @NUM_NL80211_ATTR: total number of nl80211_attrs available 2160 2140 * @NL80211_ATTR_MAX: highest attribute number currently defined ··· 3961 3947 * enum nl80211_mfp - Management frame protection state 3962 3948 * @NL80211_MFP_NO: Management frame protection not used 3963 3949 * @NL80211_MFP_REQUIRED: Management frame protection required 3950 + * @NL80211_MFP_OPTIONAL: Management frame protection is optional 3964 3951 */ 3965 3952 enum nl80211_mfp { 3966 3953 NL80211_MFP_NO, 3967 3954 NL80211_MFP_REQUIRED, 3955 + NL80211_MFP_OPTIONAL, 3968 3956 }; 3969 3957 3970 3958 enum nl80211_wpa_versions { ··· 4930 4914 * handshake with 802.1X in station mode (will pass EAP frames to the host 4931 4915 * and accept the set_pmk/del_pmk commands), doing it in the host might not 4932 4916 * be supported. 4917 + * @NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME: Driver is capable of overriding 4918 + * the max channel attribute in the FILS request params IE with the 4919 + * actual dwell time. 4920 + * @NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP: Driver accepts broadcast probe 4921 + * response 4922 + * @NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE: Driver supports sending 4923 + * the first probe request in each channel at rate of at least 5.5Mbps. 4924 + * @NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION: Driver supports 4925 + * probe request tx deferral and suppression 4926 + * @NL80211_EXT_FEATURE_MFP_OPTIONAL: Driver supports the %NL80211_MFP_OPTIONAL 4927 + * value in %NL80211_ATTR_USE_MFP. 4933 4928 * 4934 4929 * @NUM_NL80211_EXT_FEATURES: number of extended features. 4935 4930 * @MAX_NL80211_EXT_FEATURES: highest extended feature index. ··· 4963 4936 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD, 4964 4937 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK, 4965 4938 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X, 4939 + NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME, 4940 + NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP, 4941 + NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE, 4942 + NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION, 4943 + NL80211_EXT_FEATURE_MFP_OPTIONAL, 4966 4944 4967 4945 /* add new features before the definition below */ 4968 4946 NUM_NL80211_EXT_FEATURES, ··· 5044 5012 * locally administered 1, multicast 0) is assumed. 5045 5013 * This flag must not be requested when the feature isn't supported, check 5046 5014 * the nl80211 feature flags for the device. 5015 + * @NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME: fill the dwell time in the FILS 5016 + * request parameters IE in the probe request 5017 + * @NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP: accept broadcast probe responses 5018 + * @NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE: send probe request frames at 5019 + * rate of at least 5.5M. In case non OCE AP is dicovered in the channel, 5020 + * only the first probe req in the channel will be sent in high rate. 5021 + * @NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION: allow probe request 5022 + * tx deferral (dot11FILSProbeDelay shall be set to 15ms) 5023 + * and suppression (if it has received a broadcast Probe Response frame, 5024 + * Beacon frame or FILS Discovery frame from an AP that the STA considers 5025 + * a suitable candidate for (re-)association - suitable in terms of 5026 + * SSID and/or RSSI 5047 5027 */ 5048 5028 enum nl80211_scan_flags { 5049 - NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0, 5050 - NL80211_SCAN_FLAG_FLUSH = 1<<1, 5051 - NL80211_SCAN_FLAG_AP = 1<<2, 5052 - NL80211_SCAN_FLAG_RANDOM_ADDR = 1<<3, 5029 + NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0, 5030 + NL80211_SCAN_FLAG_FLUSH = 1<<1, 5031 + NL80211_SCAN_FLAG_AP = 1<<2, 5032 + NL80211_SCAN_FLAG_RANDOM_ADDR = 1<<3, 5033 + NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME = 1<<4, 5034 + NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP = 1<<5, 5035 + NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE = 1<<6, 5036 + NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 1<<7, 5053 5037 }; 5054 5038 5055 5039 /**
+1 -2
net/mac80211/Makefile
··· 6 6 driver-ops.o \ 7 7 sta_info.o \ 8 8 wep.o \ 9 + aead_api.o \ 9 10 wpa.o \ 10 11 scan.o offchannel.o \ 11 12 ht.o agg-tx.o agg-rx.o \ ··· 16 15 rate.o \ 17 16 michael.o \ 18 17 tkip.o \ 19 - aes_ccm.o \ 20 - aes_gcm.o \ 21 18 aes_cmac.o \ 22 19 aes_gmac.o \ 23 20 fils_aead.o \
+27
net/mac80211/aead_api.h
··· 1 + /* 2 + * This program is free software; you can redistribute it and/or modify 3 + * it under the terms of the GNU General Public License version 2 as 4 + * published by the Free Software Foundation. 5 + */ 6 + 7 + #ifndef _AEAD_API_H 8 + #define _AEAD_API_H 9 + 10 + #include <crypto/aead.h> 11 + #include <linux/crypto.h> 12 + 13 + struct crypto_aead * 14 + aead_key_setup_encrypt(const char *alg, const u8 key[], 15 + size_t key_len, size_t mic_len); 16 + 17 + int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, 18 + size_t aad_len, u8 *data, 19 + size_t data_len, u8 *mic); 20 + 21 + int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, 22 + size_t aad_len, u8 *data, 23 + size_t data_len, u8 *mic); 24 + 25 + void aead_key_free(struct crypto_aead *tfm); 26 + 27 + #endif /* _AEAD_API_H */
-115
net/mac80211/aes_ccm.c
··· 1 - /* 2 - * Copyright 2003-2004, Instant802 Networks, Inc. 3 - * Copyright 2005-2006, Devicescape Software, Inc. 4 - * 5 - * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org> 6 - * 7 - * This program is free software; you can redistribute it and/or modify 8 - * it under the terms of the GNU General Public License version 2 as 9 - * published by the Free Software Foundation. 10 - */ 11 - 12 - #include <linux/kernel.h> 13 - #include <linux/types.h> 14 - #include <linux/err.h> 15 - #include <crypto/aead.h> 16 - 17 - #include <net/mac80211.h> 18 - #include "key.h" 19 - #include "aes_ccm.h" 20 - 21 - int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, 22 - u8 *data, size_t data_len, u8 *mic, 23 - size_t mic_len) 24 - { 25 - struct scatterlist sg[3]; 26 - struct aead_request *aead_req; 27 - int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); 28 - u8 *__aad; 29 - 30 - aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC); 31 - if (!aead_req) 32 - return -ENOMEM; 33 - 34 - __aad = (u8 *)aead_req + reqsize; 35 - memcpy(__aad, aad, CCM_AAD_LEN); 36 - 37 - sg_init_table(sg, 3); 38 - sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); 39 - sg_set_buf(&sg[1], data, data_len); 40 - sg_set_buf(&sg[2], mic, mic_len); 41 - 42 - aead_request_set_tfm(aead_req, tfm); 43 - aead_request_set_crypt(aead_req, sg, sg, data_len, b_0); 44 - aead_request_set_ad(aead_req, sg[0].length); 45 - 46 - crypto_aead_encrypt(aead_req); 47 - kzfree(aead_req); 48 - 49 - return 0; 50 - } 51 - 52 - int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, 53 - u8 *data, size_t data_len, u8 *mic, 54 - size_t mic_len) 55 - { 56 - struct scatterlist sg[3]; 57 - struct aead_request *aead_req; 58 - int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); 59 - u8 *__aad; 60 - int err; 61 - 62 - if (data_len == 0) 63 - return -EINVAL; 64 - 65 - aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC); 66 - if (!aead_req) 67 - return -ENOMEM; 68 - 69 - __aad = (u8 *)aead_req + reqsize; 70 - memcpy(__aad, aad, CCM_AAD_LEN); 71 - 72 - sg_init_table(sg, 3); 73 - sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); 74 - sg_set_buf(&sg[1], data, data_len); 75 - sg_set_buf(&sg[2], mic, mic_len); 76 - 77 - aead_request_set_tfm(aead_req, tfm); 78 - aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0); 79 - aead_request_set_ad(aead_req, sg[0].length); 80 - 81 - err = crypto_aead_decrypt(aead_req); 82 - kzfree(aead_req); 83 - 84 - return err; 85 - } 86 - 87 - struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[], 88 - size_t key_len, 89 - size_t mic_len) 90 - { 91 - struct crypto_aead *tfm; 92 - int err; 93 - 94 - tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC); 95 - if (IS_ERR(tfm)) 96 - return tfm; 97 - 98 - err = crypto_aead_setkey(tfm, key, key_len); 99 - if (err) 100 - goto free_aead; 101 - err = crypto_aead_setauthsize(tfm, mic_len); 102 - if (err) 103 - goto free_aead; 104 - 105 - return tfm; 106 - 107 - free_aead: 108 - crypto_free_aead(tfm); 109 - return ERR_PTR(err); 110 - } 111 - 112 - void ieee80211_aes_key_free(struct crypto_aead *tfm) 113 - { 114 - crypto_free_aead(tfm); 115 - }
+31 -11
net/mac80211/aes_ccm.h
··· 10 10 #ifndef AES_CCM_H 11 11 #define AES_CCM_H 12 12 13 - #include <linux/crypto.h> 13 + #include "aead_api.h" 14 14 15 15 #define CCM_AAD_LEN 32 16 16 17 - struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[], 18 - size_t key_len, 19 - size_t mic_len); 20 - int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, 21 - u8 *data, size_t data_len, u8 *mic, 22 - size_t mic_len); 23 - int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, 24 - u8 *data, size_t data_len, u8 *mic, 25 - size_t mic_len); 26 - void ieee80211_aes_key_free(struct crypto_aead *tfm); 17 + static inline struct crypto_aead * 18 + ieee80211_aes_key_setup_encrypt(const u8 key[], size_t key_len, size_t mic_len) 19 + { 20 + return aead_key_setup_encrypt("ccm(aes)", key, key_len, mic_len); 21 + } 22 + 23 + static inline int 24 + ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, 25 + u8 *b_0, u8 *aad, u8 *data, 26 + size_t data_len, u8 *mic) 27 + { 28 + return aead_encrypt(tfm, b_0, aad + 2, 29 + be16_to_cpup((__be16 *)aad), 30 + data, data_len, mic); 31 + } 32 + 33 + static inline int 34 + ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, 35 + u8 *b_0, u8 *aad, u8 *data, 36 + size_t data_len, u8 *mic) 37 + { 38 + return aead_decrypt(tfm, b_0, aad + 2, 39 + be16_to_cpup((__be16 *)aad), 40 + data, data_len, mic); 41 + } 42 + 43 + static inline void ieee80211_aes_key_free(struct crypto_aead *tfm) 44 + { 45 + return aead_key_free(tfm); 46 + } 27 47 28 48 #endif /* AES_CCM_H */
+29 -23
net/mac80211/aes_gcm.c net/mac80211/aead_api.c
··· 1 1 /* 2 + * Copyright 2003-2004, Instant802 Networks, Inc. 3 + * Copyright 2005-2006, Devicescape Software, Inc. 2 4 * Copyright 2014-2015, Qualcomm Atheros, Inc. 5 + * 6 + * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org> 3 7 * 4 8 * This program is free software; you can redistribute it and/or modify 5 9 * it under the terms of the GNU General Public License version 2 as ··· 13 9 #include <linux/kernel.h> 14 10 #include <linux/types.h> 15 11 #include <linux/err.h> 12 + #include <linux/scatterlist.h> 16 13 #include <crypto/aead.h> 17 14 18 - #include <net/mac80211.h> 19 - #include "key.h" 20 - #include "aes_gcm.h" 15 + #include "aead_api.h" 21 16 22 - int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, 23 - u8 *data, size_t data_len, u8 *mic) 17 + int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, 18 + u8 *data, size_t data_len, u8 *mic) 24 19 { 20 + size_t mic_len = tfm->authsize; 25 21 struct scatterlist sg[3]; 26 22 struct aead_request *aead_req; 27 23 int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); 28 24 u8 *__aad; 29 25 30 - aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC); 26 + aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC); 31 27 if (!aead_req) 32 28 return -ENOMEM; 33 29 34 30 __aad = (u8 *)aead_req + reqsize; 35 - memcpy(__aad, aad, GCM_AAD_LEN); 31 + memcpy(__aad, aad, aad_len); 36 32 37 33 sg_init_table(sg, 3); 38 - sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); 34 + sg_set_buf(&sg[0], __aad, aad_len); 39 35 sg_set_buf(&sg[1], data, data_len); 40 - sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN); 36 + sg_set_buf(&sg[2], mic, mic_len); 41 37 42 38 aead_request_set_tfm(aead_req, tfm); 43 - aead_request_set_crypt(aead_req, sg, sg, data_len, j_0); 39 + aead_request_set_crypt(aead_req, sg, sg, data_len, b_0); 44 40 aead_request_set_ad(aead_req, sg[0].length); 45 41 46 42 crypto_aead_encrypt(aead_req); 47 43 kzfree(aead_req); 44 + 48 45 return 0; 49 46 } 50 47 51 - int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, 52 - u8 *data, size_t data_len, u8 *mic) 48 + int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, 49 + u8 *data, size_t data_len, u8 *mic) 53 50 { 51 + size_t mic_len = tfm->authsize; 54 52 struct scatterlist sg[3]; 55 53 struct aead_request *aead_req; 56 54 int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); ··· 62 56 if (data_len == 0) 63 57 return -EINVAL; 64 58 65 - aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC); 59 + aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC); 66 60 if (!aead_req) 67 61 return -ENOMEM; 68 62 69 63 __aad = (u8 *)aead_req + reqsize; 70 - memcpy(__aad, aad, GCM_AAD_LEN); 64 + memcpy(__aad, aad, aad_len); 71 65 72 66 sg_init_table(sg, 3); 73 - sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); 67 + sg_set_buf(&sg[0], __aad, aad_len); 74 68 sg_set_buf(&sg[1], data, data_len); 75 - sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN); 69 + sg_set_buf(&sg[2], mic, mic_len); 76 70 77 71 aead_request_set_tfm(aead_req, tfm); 78 - aead_request_set_crypt(aead_req, sg, sg, 79 - data_len + IEEE80211_GCMP_MIC_LEN, j_0); 72 + aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0); 80 73 aead_request_set_ad(aead_req, sg[0].length); 81 74 82 75 err = crypto_aead_decrypt(aead_req); ··· 84 79 return err; 85 80 } 86 81 87 - struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], 88 - size_t key_len) 82 + struct crypto_aead * 83 + aead_key_setup_encrypt(const char *alg, const u8 key[], 84 + size_t key_len, size_t mic_len) 89 85 { 90 86 struct crypto_aead *tfm; 91 87 int err; 92 88 93 - tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC); 89 + tfm = crypto_alloc_aead(alg, 0, CRYPTO_ALG_ASYNC); 94 90 if (IS_ERR(tfm)) 95 91 return tfm; 96 92 97 93 err = crypto_aead_setkey(tfm, key, key_len); 98 94 if (err) 99 95 goto free_aead; 100 - err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN); 96 + err = crypto_aead_setauthsize(tfm, mic_len); 101 97 if (err) 102 98 goto free_aead; 103 99 ··· 109 103 return ERR_PTR(err); 110 104 } 111 105 112 - void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) 106 + void aead_key_free(struct crypto_aead *tfm) 113 107 { 114 108 crypto_free_aead(tfm); 115 109 }
+30 -8
net/mac80211/aes_gcm.h
··· 9 9 #ifndef AES_GCM_H 10 10 #define AES_GCM_H 11 11 12 - #include <linux/crypto.h> 12 + #include "aead_api.h" 13 13 14 14 #define GCM_AAD_LEN 32 15 15 16 - int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, 17 - u8 *data, size_t data_len, u8 *mic); 18 - int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, 19 - u8 *data, size_t data_len, u8 *mic); 20 - struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], 21 - size_t key_len); 22 - void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm); 16 + static inline int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, 17 + u8 *j_0, u8 *aad, u8 *data, 18 + size_t data_len, u8 *mic) 19 + { 20 + return aead_encrypt(tfm, j_0, aad + 2, 21 + be16_to_cpup((__be16 *)aad), 22 + data, data_len, mic); 23 + } 24 + 25 + static inline int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, 26 + u8 *j_0, u8 *aad, u8 *data, 27 + size_t data_len, u8 *mic) 28 + { 29 + return aead_decrypt(tfm, j_0, aad + 2, 30 + be16_to_cpup((__be16 *)aad), 31 + data, data_len, mic); 32 + } 33 + 34 + static inline struct crypto_aead * 35 + ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len) 36 + { 37 + return aead_key_setup_encrypt("gcm(aes)", key, 38 + key_len, IEEE80211_GCMP_MIC_LEN); 39 + } 40 + 41 + static inline void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) 42 + { 43 + return aead_key_free(tfm); 44 + } 23 45 24 46 #endif /* AES_GCM_H */
+2 -2
net/mac80211/agg-rx.c
··· 459 459 } 460 460 461 461 void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif, 462 - const u8 *addr, unsigned int bit) 462 + const u8 *addr, unsigned int tid) 463 463 { 464 464 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 465 465 struct ieee80211_local *local = sdata->local; ··· 470 470 if (!sta) 471 471 goto unlock; 472 472 473 - set_bit(bit, sta->ampdu_mlme.tid_rx_manage_offl); 473 + set_bit(tid, sta->ampdu_mlme.tid_rx_manage_offl); 474 474 ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work); 475 475 unlock: 476 476 rcu_read_unlock();
+7 -5
net/mac80211/ht.c
··· 290 290 { 291 291 int i; 292 292 293 + mutex_lock(&sta->ampdu_mlme.mtx); 293 294 for (i = 0; i < IEEE80211_NUM_TIDS; i++) { 294 - __ieee80211_stop_tx_ba_session(sta, i, reason); 295 - __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, 296 - WLAN_REASON_QSTA_LEAVE_QBSS, 297 - reason != AGG_STOP_DESTROY_STA && 298 - reason != AGG_STOP_PEER_REQUEST); 295 + ___ieee80211_stop_tx_ba_session(sta, i, reason); 296 + ___ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, 297 + WLAN_REASON_QSTA_LEAVE_QBSS, 298 + reason != AGG_STOP_DESTROY_STA && 299 + reason != AGG_STOP_PEER_REQUEST); 299 300 } 301 + mutex_unlock(&sta->ampdu_mlme.mtx); 300 302 301 303 /* stopping might queue the work again - so cancel only afterwards */ 302 304 cancel_work_sync(&sta->ampdu_mlme.work);
+2
net/mac80211/ieee80211_i.h
··· 2009 2009 struct txq_info *txq, int tid); 2010 2010 void ieee80211_txq_purge(struct ieee80211_local *local, 2011 2011 struct txq_info *txqi); 2012 + void ieee80211_txq_remove_vlan(struct ieee80211_local *local, 2013 + struct ieee80211_sub_if_data *sdata); 2012 2014 void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 2013 2015 u16 transaction, u16 auth_alg, u16 status, 2014 2016 const u8 *extra, size_t extra_len, const u8 *bssid,
+6 -23
net/mac80211/iface.c
··· 793 793 static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, 794 794 bool going_down) 795 795 { 796 - struct ieee80211_sub_if_data *txq_sdata = sdata; 797 796 struct ieee80211_local *local = sdata->local; 798 - struct fq *fq = &local->fq; 799 797 unsigned long flags; 800 798 struct sk_buff *skb, *tmp; 801 799 u32 hw_reconf_flags = 0; ··· 937 939 938 940 switch (sdata->vif.type) { 939 941 case NL80211_IFTYPE_AP_VLAN: 940 - txq_sdata = container_of(sdata->bss, 941 - struct ieee80211_sub_if_data, u.ap); 942 - 943 942 mutex_lock(&local->mtx); 944 943 list_del(&sdata->u.vlan.list); 945 944 mutex_unlock(&local->mtx); ··· 993 998 skb_queue_purge(&sdata->skb_queue); 994 999 } 995 1000 996 - sdata->bss = NULL; 997 - 998 1001 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 999 1002 for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { 1000 1003 skb_queue_walk_safe(&local->pending[i], skb, tmp) { ··· 1005 1012 } 1006 1013 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 1007 1014 1008 - if (txq_sdata->vif.txq) { 1009 - struct txq_info *txqi = to_txq_info(txq_sdata->vif.txq); 1015 + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 1016 + ieee80211_txq_remove_vlan(local, sdata); 1010 1017 1011 - /* 1012 - * FIXME FIXME 1013 - * 1014 - * We really shouldn't purge the *entire* txqi since that 1015 - * contains frames for the other AP_VLANs (and possibly 1016 - * the AP itself) as well, but there's no API in FQ now 1017 - * to be able to filter. 1018 - */ 1019 - 1020 - spin_lock_bh(&fq->lock); 1021 - ieee80211_txq_purge(local, txqi); 1022 - spin_unlock_bh(&fq->lock); 1023 - } 1018 + sdata->bss = NULL; 1024 1019 1025 1020 if (local->open_count == 0) 1026 1021 ieee80211_clear_tx_pending(local); ··· 1753 1772 sizeof(void *)); 1754 1773 int txq_size = 0; 1755 1774 1756 - if (local->ops->wake_tx_queue) 1775 + if (local->ops->wake_tx_queue && 1776 + type != NL80211_IFTYPE_AP_VLAN && 1777 + type != NL80211_IFTYPE_MONITOR) 1757 1778 txq_size += sizeof(struct txq_info) + 1758 1779 local->hw.txq_data_size; 1759 1780
+1 -2
net/mac80211/mesh.c
··· 675 675 enum nl80211_band band; 676 676 u8 *pos; 677 677 struct ieee80211_sub_if_data *sdata; 678 - int hdr_len = offsetof(struct ieee80211_mgmt, u.beacon) + 679 - sizeof(mgmt->u.beacon); 678 + int hdr_len = offsetofend(struct ieee80211_mgmt, u.beacon); 680 679 681 680 sdata = container_of(ifmsh, struct ieee80211_sub_if_data, u.mesh); 682 681 rcu_read_lock();
+1
net/mac80211/mesh.h
··· 275 275 u8 *hw_addr, struct ieee802_11_elems *ie); 276 276 bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); 277 277 u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); 278 + void mesh_plink_timer(struct timer_list *t); 278 279 void mesh_plink_broken(struct sta_info *sta); 279 280 u32 mesh_plink_deactivate(struct sta_info *sta); 280 281 u32 mesh_plink_open(struct sta_info *sta);
+4 -4
net/mac80211/mesh_hwmp.c
··· 111 111 struct sk_buff *skb; 112 112 struct ieee80211_mgmt *mgmt; 113 113 u8 *pos, ie_len; 114 - int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) + 115 - sizeof(mgmt->u.action.u.mesh_action); 114 + int hdr_len = offsetofend(struct ieee80211_mgmt, 115 + u.action.u.mesh_action); 116 116 117 117 skb = dev_alloc_skb(local->tx_headroom + 118 118 hdr_len + ··· 242 242 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 243 243 struct ieee80211_mgmt *mgmt; 244 244 u8 *pos, ie_len; 245 - int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) + 246 - sizeof(mgmt->u.action.u.mesh_action); 245 + int hdr_len = offsetofend(struct ieee80211_mgmt, 246 + u.action.u.mesh_action); 247 247 248 248 if (time_before(jiffies, ifmsh->next_perr)) 249 249 return -EAGAIN;
+5 -8
net/mac80211/mesh_plink.c
··· 220 220 bool include_plid = false; 221 221 u16 peering_proto = 0; 222 222 u8 *pos, ie_len = 4; 223 - int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) + 224 - sizeof(mgmt->u.action.u.self_prot); 223 + int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.self_prot); 225 224 int err = -ENOMEM; 226 225 227 226 skb = dev_alloc_skb(local->tx_headroom + ··· 603 604 ieee80211_mbss_info_change_notify(sdata, changed); 604 605 } 605 606 606 - static void mesh_plink_timer(unsigned long data) 607 + void mesh_plink_timer(struct timer_list *t) 607 608 { 609 + struct mesh_sta *mesh = from_timer(mesh, t, plink_timer); 608 610 struct sta_info *sta; 609 611 u16 reason = 0; 610 612 struct ieee80211_sub_if_data *sdata; ··· 617 617 * del_timer_sync() this timer after having made sure 618 618 * it cannot be readded (by deleting the plink.) 619 619 */ 620 - sta = (struct sta_info *) data; 620 + sta = mesh->plink_sta; 621 621 622 622 if (sta->sdata->local->quiescing) 623 623 return; ··· 697 697 698 698 static inline void mesh_plink_timer_set(struct sta_info *sta, u32 timeout) 699 699 { 700 - sta->mesh->plink_timer.expires = jiffies + msecs_to_jiffies(timeout); 701 - sta->mesh->plink_timer.data = (unsigned long) sta; 702 - sta->mesh->plink_timer.function = mesh_plink_timer; 703 700 sta->mesh->plink_timeout = timeout; 704 - add_timer(&sta->mesh->plink_timer); 701 + mod_timer(&sta->mesh->plink_timer, jiffies + msecs_to_jiffies(timeout)); 705 702 } 706 703 707 704 static bool llid_in_use(struct ieee80211_sub_if_data *sdata,
+7 -12
net/mac80211/mlme.c
··· 780 780 WLAN_EID_SUPPORTED_REGULATORY_CLASSES, 781 781 WLAN_EID_HT_CAPABILITY, 782 782 WLAN_EID_BSS_COEX_2040, 783 + /* luckily this is almost always there */ 783 784 WLAN_EID_EXT_CAPABILITY, 784 785 WLAN_EID_QOS_TRAFFIC_CAPA, 785 786 WLAN_EID_TIM_BCAST_REQ, 786 787 WLAN_EID_INTERWORKING, 787 - /* 60GHz doesn't happen right now */ 788 + /* 60 GHz (Multi-band, DMG, MMS) can't happen */ 788 789 WLAN_EID_VHT_CAPABILITY, 789 790 WLAN_EID_OPMODE_NOTIF, 790 791 }; ··· 812 811 /* if present, add any custom IEs that go before VHT */ 813 812 if (assoc_data->ie_len) { 814 813 static const u8 before_vht[] = { 815 - WLAN_EID_SSID, 816 - WLAN_EID_SUPP_RATES, 817 - WLAN_EID_EXT_SUPP_RATES, 818 - WLAN_EID_PWR_CAPABILITY, 819 - WLAN_EID_SUPPORTED_CHANNELS, 820 - WLAN_EID_RSN, 821 - WLAN_EID_QOS_CAPA, 822 - WLAN_EID_RRM_ENABLED_CAPABILITIES, 823 - WLAN_EID_MOBILITY_DOMAIN, 824 - WLAN_EID_SUPPORTED_REGULATORY_CLASSES, 825 - WLAN_EID_HT_CAPABILITY, 814 + /* 815 + * no need to list the ones split off before HT 816 + * or generated here 817 + */ 826 818 WLAN_EID_BSS_COEX_2040, 827 819 WLAN_EID_EXT_CAPABILITY, 828 820 WLAN_EID_QOS_TRAFFIC_CAPA, 829 821 WLAN_EID_TIM_BCAST_REQ, 830 822 WLAN_EID_INTERWORKING, 823 + /* 60 GHz (Multi-band, DMG, MMS) can't happen */ 831 824 }; 832 825 833 826 /* RIC already taken above, so no need to handle here anymore */
+28 -9
net/mac80211/scan.c
··· 7 7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 8 8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 9 9 * Copyright 2013-2015 Intel Mobile Communications GmbH 10 - * Copyright 2016 Intel Deutschland GmbH 10 + * Copyright 2016-2017 Intel Deutschland GmbH 11 11 * 12 12 * This program is free software; you can redistribute it and/or modify 13 13 * it under the terms of the GNU General Public License version 2 as ··· 183 183 return bss; 184 184 } 185 185 186 + static bool ieee80211_scan_accept_presp(struct ieee80211_sub_if_data *sdata, 187 + u32 scan_flags, const u8 *da) 188 + { 189 + if (!sdata) 190 + return false; 191 + /* accept broadcast for OCE */ 192 + if (scan_flags & NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP && 193 + is_broadcast_ether_addr(da)) 194 + return true; 195 + if (scan_flags & NL80211_SCAN_FLAG_RANDOM_ADDR) 196 + return true; 197 + return ether_addr_equal(da, sdata->vif.addr); 198 + } 199 + 186 200 void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb) 187 201 { 188 202 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); ··· 222 208 if (ieee80211_is_probe_resp(mgmt->frame_control)) { 223 209 struct cfg80211_scan_request *scan_req; 224 210 struct cfg80211_sched_scan_request *sched_scan_req; 211 + u32 scan_req_flags = 0, sched_scan_req_flags = 0; 225 212 226 213 scan_req = rcu_dereference(local->scan_req); 227 214 sched_scan_req = rcu_dereference(local->sched_scan_req); 228 215 229 - /* ignore ProbeResp to foreign address unless scanning 230 - * with randomised address 216 + if (scan_req) 217 + scan_req_flags = scan_req->flags; 218 + 219 + if (sched_scan_req) 220 + sched_scan_req_flags = sched_scan_req->flags; 221 + 222 + /* ignore ProbeResp to foreign address or non-bcast (OCE) 223 + * unless scanning with randomised address 231 224 */ 232 - if (!(sdata1 && 233 - (ether_addr_equal(mgmt->da, sdata1->vif.addr) || 234 - scan_req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) && 235 - !(sdata2 && 236 - (ether_addr_equal(mgmt->da, sdata2->vif.addr) || 237 - sched_scan_req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))) 225 + if (!ieee80211_scan_accept_presp(sdata1, scan_req_flags, 226 + mgmt->da) && 227 + !ieee80211_scan_accept_presp(sdata2, sched_scan_req_flags, 228 + mgmt->da)) 238 229 return; 239 230 240 231 elements = mgmt->u.probe_resp.variable;
+35 -26
net/mac80211/sta_info.c
··· 329 329 sta->mesh = kzalloc(sizeof(*sta->mesh), gfp); 330 330 if (!sta->mesh) 331 331 goto free; 332 + sta->mesh->plink_sta = sta; 332 333 spin_lock_init(&sta->mesh->plink_lock); 333 334 if (ieee80211_vif_is_mesh(&sdata->vif) && 334 335 !sdata->u.mesh.user_mpm) 335 - init_timer(&sta->mesh->plink_timer); 336 + timer_setup(&sta->mesh->plink_timer, mesh_plink_timer, 337 + 0); 336 338 sta->mesh->nonpeer_pm = NL80211_MESH_POWER_ACTIVE; 337 339 } 338 340 #endif ··· 517 515 return err; 518 516 } 519 517 518 + static void 519 + ieee80211_recalc_p2p_go_ps_allowed(struct ieee80211_sub_if_data *sdata) 520 + { 521 + struct ieee80211_local *local = sdata->local; 522 + bool allow_p2p_go_ps = sdata->vif.p2p; 523 + struct sta_info *sta; 524 + 525 + rcu_read_lock(); 526 + list_for_each_entry_rcu(sta, &local->sta_list, list) { 527 + if (sdata != sta->sdata || 528 + !test_sta_flag(sta, WLAN_STA_ASSOC)) 529 + continue; 530 + if (!sta->sta.support_p2p_ps) { 531 + allow_p2p_go_ps = false; 532 + break; 533 + } 534 + } 535 + rcu_read_unlock(); 536 + 537 + if (allow_p2p_go_ps != sdata->vif.bss_conf.allow_p2p_go_ps) { 538 + sdata->vif.bss_conf.allow_p2p_go_ps = allow_p2p_go_ps; 539 + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_P2P_PS); 540 + } 541 + } 542 + 520 543 /* 521 544 * should be called with sta_mtx locked 522 545 * this function replaces the mutex lock ··· 588 561 goto out_remove; 589 562 590 563 set_sta_flag(sta, WLAN_STA_INSERTED); 564 + 565 + if (sta->sta_state >= IEEE80211_STA_ASSOC) { 566 + ieee80211_recalc_min_chandef(sta->sdata); 567 + if (!sta->sta.support_p2p_ps) 568 + ieee80211_recalc_p2p_go_ps_allowed(sta->sdata); 569 + } 570 + 591 571 /* accept BA sessions now */ 592 572 clear_sta_flag(sta, WLAN_STA_BLOCK_BA); 593 573 ··· 1821 1787 sta_info_recalc_tim(sta); 1822 1788 } 1823 1789 EXPORT_SYMBOL(ieee80211_sta_set_buffered); 1824 - 1825 - static void 1826 - ieee80211_recalc_p2p_go_ps_allowed(struct ieee80211_sub_if_data *sdata) 1827 - { 1828 - struct ieee80211_local *local = sdata->local; 1829 - bool allow_p2p_go_ps = sdata->vif.p2p; 1830 - struct sta_info *sta; 1831 - 1832 - rcu_read_lock(); 1833 - list_for_each_entry_rcu(sta, &local->sta_list, list) { 1834 - if (sdata != sta->sdata || 1835 - !test_sta_flag(sta, WLAN_STA_ASSOC)) 1836 - continue; 1837 - if (!sta->sta.support_p2p_ps) { 1838 - allow_p2p_go_ps = false; 1839 - break; 1840 - } 1841 - } 1842 - rcu_read_unlock(); 1843 - 1844 - if (allow_p2p_go_ps != sdata->vif.bss_conf.allow_p2p_go_ps) { 1845 - sdata->vif.bss_conf.allow_p2p_go_ps = allow_p2p_go_ps; 1846 - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_P2P_PS); 1847 - } 1848 - } 1849 1790 1850 1791 int sta_info_move_state(struct sta_info *sta, 1851 1792 enum ieee80211_sta_state new_state)
+3 -1
net/mac80211/sta_info.h
··· 344 344 * @plink_state: peer link state 345 345 * @plink_timeout: timeout of peer link 346 346 * @plink_timer: peer link watch timer 347 + * @plink_sta: peer link watch timer's sta_info 347 348 * @t_offset: timing offset relative to this host 348 349 * @t_offset_setpoint: reference timing offset of this sta to be used when 349 350 * calculating clockdrift ··· 357 356 */ 358 357 struct mesh_sta { 359 358 struct timer_list plink_timer; 359 + struct sta_info *plink_sta; 360 360 361 361 s64 t_offset; 362 362 s64 t_offset_setpoint; ··· 400 398 u64 msdu[IEEE80211_NUM_TIDS + 1]; 401 399 }; 402 400 403 - /** 401 + /* 404 402 * The bandwidth threshold below which the per-station CoDel parameters will be 405 403 * scaled to be more lenient (to prevent starvation of slow stations). This 406 404 * value will be scaled by the number of active stations when it is being
+34
net/mac80211/tx.c
··· 1396 1396 fq_flow_get_default_func); 1397 1397 } 1398 1398 1399 + static bool fq_vlan_filter_func(struct fq *fq, struct fq_tin *tin, 1400 + struct fq_flow *flow, struct sk_buff *skb, 1401 + void *data) 1402 + { 1403 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1404 + 1405 + return info->control.vif == data; 1406 + } 1407 + 1408 + void ieee80211_txq_remove_vlan(struct ieee80211_local *local, 1409 + struct ieee80211_sub_if_data *sdata) 1410 + { 1411 + struct fq *fq = &local->fq; 1412 + struct txq_info *txqi; 1413 + struct fq_tin *tin; 1414 + struct ieee80211_sub_if_data *ap; 1415 + 1416 + if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN)) 1417 + return; 1418 + 1419 + ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); 1420 + 1421 + if (!ap->vif.txq) 1422 + return; 1423 + 1424 + txqi = to_txq_info(ap->vif.txq); 1425 + tin = &txqi->tin; 1426 + 1427 + spin_lock_bh(&fq->lock); 1428 + fq_tin_filter(fq, tin, fq_vlan_filter_func, &sdata->vif, 1429 + fq_skb_free_func); 1430 + spin_unlock_bh(&fq->lock); 1431 + } 1432 + 1399 1433 void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata, 1400 1434 struct sta_info *sta, 1401 1435 struct txq_info *txqi, int tid)
+11 -14
net/mac80211/util.c
··· 1392 1392 /* insert custom IEs that go before HT */ 1393 1393 if (ie && ie_len) { 1394 1394 static const u8 before_ht[] = { 1395 - WLAN_EID_SSID, 1396 - WLAN_EID_SUPP_RATES, 1397 - WLAN_EID_REQUEST, 1398 - WLAN_EID_EXT_SUPP_RATES, 1395 + /* 1396 + * no need to list the ones split off already 1397 + * (or generated here) 1398 + */ 1399 1399 WLAN_EID_DS_PARAMS, 1400 1400 WLAN_EID_SUPPORTED_REGULATORY_CLASSES, 1401 1401 }; ··· 1424 1424 /* insert custom IEs that go before VHT */ 1425 1425 if (ie && ie_len) { 1426 1426 static const u8 before_vht[] = { 1427 - WLAN_EID_SSID, 1428 - WLAN_EID_SUPP_RATES, 1429 - WLAN_EID_REQUEST, 1430 - WLAN_EID_EXT_SUPP_RATES, 1431 - WLAN_EID_DS_PARAMS, 1432 - WLAN_EID_SUPPORTED_REGULATORY_CLASSES, 1433 - WLAN_EID_HT_CAPABILITY, 1427 + /* 1428 + * no need to list the ones split off already 1429 + * (or generated here) 1430 + */ 1434 1431 WLAN_EID_BSS_COEX_2040, 1435 1432 WLAN_EID_EXT_CAPABILITY, 1436 1433 WLAN_EID_SSID_LIST, 1437 1434 WLAN_EID_CHANNEL_USAGE, 1438 1435 WLAN_EID_INTERWORKING, 1439 1436 WLAN_EID_MESH_ID, 1440 - /* 60 GHz can't happen here right now */ 1437 + /* 60 GHz (Multi-band, DMG, MMS) can't happen */ 1441 1438 }; 1442 1439 noffset = ieee80211_ie_split(ie, ie_len, 1443 1440 before_vht, ARRAY_SIZE(before_vht), ··· 2977 2980 struct ieee80211_mgmt *mgmt; 2978 2981 struct ieee80211_local *local = sdata->local; 2979 2982 int freq; 2980 - int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.chan_switch) + 2981 - sizeof(mgmt->u.action.u.chan_switch); 2983 + int hdr_len = offsetofend(struct ieee80211_mgmt, 2984 + u.action.u.chan_switch); 2982 2985 u8 *pos; 2983 2986 2984 2987 if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
+10
net/mac80211/vht.c
··· 386 386 387 387 bw = ieee80211_sta_cap_rx_bw(sta); 388 388 bw = min(bw, sta->cur_max_bandwidth); 389 + 390 + /* Don't consider AP's bandwidth for TDLS peers, section 11.23.1 of 391 + * IEEE80211-2016 specification makes higher bandwidth operation 392 + * possible on the TDLS link if the peers have wider bandwidth 393 + * capability. 394 + */ 395 + if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && 396 + test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW)) 397 + return bw; 398 + 389 399 bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width)); 390 400 391 401 return bw;
+2 -2
net/mac80211/wpa.c
··· 464 464 pos += IEEE80211_CCMP_HDR_LEN; 465 465 ccmp_special_blocks(skb, pn, b_0, aad); 466 466 return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, 467 - skb_put(skb, mic_len), mic_len); 467 + skb_put(skb, mic_len)); 468 468 } 469 469 470 470 ··· 543 543 key->u.ccmp.tfm, b_0, aad, 544 544 skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN, 545 545 data_len, 546 - skb->data + skb->len - mic_len, mic_len)) 546 + skb->data + skb->len - mic_len)) 547 547 return RX_DROP_UNUSABLE; 548 548 } 549 549
+2 -1
net/wireless/.gitignore
··· 1 - regdb.c 1 + shipped-certs.c 2 + extra-certs.c
+34 -24
net/wireless/Kconfig
··· 19 19 config CFG80211 20 20 tristate "cfg80211 - wireless configuration API" 21 21 depends on RFKILL || !RFKILL 22 + select FW_LOADER 22 23 ---help--- 23 24 cfg80211 is the Linux wireless LAN (802.11) configuration API. 24 25 Enable this if you have a wireless device. ··· 83 82 you are a wireless researcher and are working in a controlled 84 83 and approved environment by your local regulatory agency. 85 84 85 + config CFG80211_REQUIRE_SIGNED_REGDB 86 + bool "require regdb signature" if CFG80211_CERTIFICATION_ONUS 87 + default y 88 + select SYSTEM_DATA_VERIFICATION 89 + help 90 + Require that in addition to the "regulatory.db" file a 91 + "regulatory.db.p7s" can be loaded with a valid PKCS#7 92 + signature for the regulatory.db file made by one of the 93 + keys in the certs/ directory. 94 + 95 + config CFG80211_USE_KERNEL_REGDB_KEYS 96 + bool "allow regdb keys shipped with the kernel" if CFG80211_CERTIFICATION_ONUS 97 + default y 98 + depends on CFG80211_REQUIRE_SIGNED_REGDB 99 + help 100 + Allow the regulatory database to be signed by one of the keys for 101 + which certificates are part of the kernel sources 102 + (in net/wireless/certs/). 103 + 104 + This is currently only Seth Forshee's key, who is the regulatory 105 + database maintainer. 106 + 107 + config CFG80211_EXTRA_REGDB_KEYDIR 108 + string "additional regdb key directory" if CFG80211_CERTIFICATION_ONUS 109 + depends on CFG80211_REQUIRE_SIGNED_REGDB 110 + help 111 + If selected, point to a directory with DER-encoded X.509 112 + certificates like in the kernel sources (net/wireless/certs/) 113 + that shall be accepted for a signed regulatory database. 114 + 86 115 config CFG80211_REG_CELLULAR_HINTS 87 116 bool "cfg80211 regulatory support for cellular base station hints" 88 117 depends on CFG80211_CERTIFICATION_ONUS ··· 170 139 171 140 If unsure, say N. 172 141 173 - config CFG80211_INTERNAL_REGDB 174 - bool "use statically compiled regulatory rules database" if EXPERT 175 - default n 176 - depends on CFG80211 177 - ---help--- 178 - This option generates an internal data structure representing 179 - the wireless regulatory rules described in net/wireless/db.txt 180 - and includes code to query that database. This is an alternative 181 - to using CRDA for defining regulatory rules for the kernel. 182 - 183 - Using this option requires some parsing of the db.txt at build time, 184 - the parser will be upkept with the latest wireless-regdb updates but 185 - older wireless-regdb formats will be ignored. The parser may later 186 - be replaced to avoid issues with conflicts on versions of 187 - wireless-regdb. 188 - 189 - For details see: 190 - 191 - http://wireless.kernel.org/en/developers/Regulatory 192 - 193 - Most distributions have a CRDA package. So if unsure, say N. 194 - 195 142 config CFG80211_CRDA_SUPPORT 196 - bool "support CRDA" if CFG80211_INTERNAL_REGDB 143 + bool "support CRDA" if EXPERT 197 144 default y 198 145 depends on CFG80211 199 146 help 200 147 You should enable this option unless you know for sure you have no 201 - need for it, for example when using internal regdb (above.) 148 + need for it, for example when using internal regdb (above) or the 149 + database loaded as a firmware file. 202 150 203 151 If unsure, say Y. 204 152
+20 -4
net/wireless/Makefile
··· 14 14 cfg80211-$(CONFIG_OF) += of.o 15 15 cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o 16 16 cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o 17 - cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o 18 17 19 18 CFLAGS_trace.o := -I$(src) 20 19 21 - $(obj)/regdb.c: $(src)/db.txt $(src)/genregdb.awk 22 - @$(AWK) -f $(srctree)/$(src)/genregdb.awk < $< > $@ 20 + cfg80211-$(CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS) += shipped-certs.o 21 + ifneq ($(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR),) 22 + cfg80211-y += extra-certs.o 23 + endif 23 24 24 - clean-files := regdb.c 25 + $(obj)/shipped-certs.c: $(wildcard $(srctree)/$(src)/certs/*.x509) 26 + @echo " GEN $@" 27 + @echo '#include "reg.h"' > $@ 28 + @echo 'const u8 shipped_regdb_certs[] = {' >> $@ 29 + @for f in $^ ; do hexdump -v -e '1/1 "0x%.2x," "\n"' < $$f >> $@ ; done 30 + @echo '};' >> $@ 31 + @echo 'unsigned int shipped_regdb_certs_len = sizeof(shipped_regdb_certs);' >> $@ 32 + 33 + $(obj)/extra-certs.c: $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%) \ 34 + $(wildcard $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%)/*.x509) 35 + @echo " GEN $@" 36 + @echo '#include "reg.h"' > $@ 37 + @echo 'const u8 extra_regdb_certs[] = {' >> $@ 38 + @for f in $^ ; do test -f $$f && hexdump -v -e '1/1 "0x%.2x," "\n"' < $$f >> $@ || true ; done 39 + @echo '};' >> $@ 40 + @echo 'unsigned int extra_regdb_certs_len = sizeof(extra_regdb_certs);' >> $@
net/wireless/certs/sforshee.x509

This is a binary file and will not be displayed.

+1 -1
net/wireless/core.c
··· 1384 1384 out_fail_pernet: 1385 1385 return err; 1386 1386 } 1387 - subsys_initcall(cfg80211_init); 1387 + fs_initcall(cfg80211_init); 1388 1388 1389 1389 static void __exit cfg80211_exit(void) 1390 1390 {
+5
net/wireless/core.h
··· 216 216 EVENT_DISCONNECTED, 217 217 EVENT_IBSS_JOINED, 218 218 EVENT_STOPPED, 219 + EVENT_PORT_AUTHORIZED, 219 220 }; 220 221 221 222 struct cfg80211_event { ··· 236 235 u8 bssid[ETH_ALEN]; 237 236 struct ieee80211_channel *channel; 238 237 } ij; 238 + struct { 239 + u8 bssid[ETH_ALEN]; 240 + } pa; 239 241 }; 240 242 }; 241 243 ··· 389 385 bool wextev); 390 386 void __cfg80211_roamed(struct wireless_dev *wdev, 391 387 struct cfg80211_roam_info *info); 388 + void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid); 392 389 int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, 393 390 struct wireless_dev *wdev); 394 391 void cfg80211_autodisconnect_wk(struct work_struct *work);
-17
net/wireless/db.txt
··· 1 - # 2 - # This file is a placeholder to prevent accidental build breakage if someone 3 - # enables CONFIG_CFG80211_INTERNAL_REGDB. Almost no one actually needs to 4 - # enable that build option. 5 - # 6 - # You should be using CRDA instead. It is even better if you use the CRDA 7 - # package provided by your distribution, since they will probably keep it 8 - # up-to-date on your behalf. 9 - # 10 - # If you _really_ intend to use CONFIG_CFG80211_INTERNAL_REGDB then you will 11 - # need to replace this file with one containing appropriately formatted 12 - # regulatory rules that cover the regulatory domains you will be using. Your 13 - # best option is to extract the db.txt file from the wireless-regdb git 14 - # repository: 15 - # 16 - # git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-regdb.git 17 - #
-158
net/wireless/genregdb.awk
··· 1 - #!/usr/bin/awk -f 2 - # 3 - # genregdb.awk -- generate regdb.c from db.txt 4 - # 5 - # Actually, it reads from stdin (presumed to be db.txt) and writes 6 - # to stdout (presumed to be regdb.c), but close enough... 7 - # 8 - # Copyright 2009 John W. Linville <linville@tuxdriver.com> 9 - # 10 - # Permission to use, copy, modify, and/or distribute this software for any 11 - # purpose with or without fee is hereby granted, provided that the above 12 - # copyright notice and this permission notice appear in all copies. 13 - # 14 - # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 15 - # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 16 - # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 17 - # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 - # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 19 - # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 20 - # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 - 22 - BEGIN { 23 - active = 0 24 - rules = 0; 25 - print "/*" 26 - print " * DO NOT EDIT -- file generated from data in db.txt" 27 - print " */" 28 - print "" 29 - print "#include <linux/nl80211.h>" 30 - print "#include <net/cfg80211.h>" 31 - print "#include \"regdb.h\"" 32 - print "" 33 - regdb = "const struct ieee80211_regdomain *reg_regdb[] = {\n" 34 - } 35 - 36 - function parse_country_head() { 37 - country=$2 38 - sub(/:/, "", country) 39 - printf "static const struct ieee80211_regdomain regdom_%s = {\n", country 40 - printf "\t.alpha2 = \"%s\",\n", country 41 - if ($NF ~ /DFS-ETSI/) 42 - printf "\t.dfs_region = NL80211_DFS_ETSI,\n" 43 - else if ($NF ~ /DFS-FCC/) 44 - printf "\t.dfs_region = NL80211_DFS_FCC,\n" 45 - else if ($NF ~ /DFS-JP/) 46 - printf "\t.dfs_region = NL80211_DFS_JP,\n" 47 - printf "\t.reg_rules = {\n" 48 - active = 1 49 - regdb = regdb "\t&regdom_" country ",\n" 50 - } 51 - 52 - function parse_reg_rule() 53 - { 54 - flag_starts_at = 7 55 - 56 - start = $1 57 - sub(/\(/, "", start) 58 - end = $3 59 - bw = $5 60 - sub(/\),/, "", bw) 61 - gain = 0 62 - power = $6 63 - # power might be in mW... 64 - units = $7 65 - dfs_cac = 0 66 - 67 - sub(/\(/, "", power) 68 - sub(/\),/, "", power) 69 - sub(/\),/, "", units) 70 - sub(/\)/, "", units) 71 - 72 - if (units == "mW") { 73 - flag_starts_at = 8 74 - power = 10 * log(power)/log(10) 75 - if ($8 ~ /[[:digit:]]/) { 76 - flag_starts_at = 9 77 - dfs_cac = $8 78 - } 79 - } else { 80 - if ($7 ~ /[[:digit:]]/) { 81 - flag_starts_at = 8 82 - dfs_cac = $7 83 - } 84 - } 85 - sub(/\(/, "", dfs_cac) 86 - sub(/\),/, "", dfs_cac) 87 - flagstr = "" 88 - for (i=flag_starts_at; i<=NF; i++) 89 - flagstr = flagstr $i 90 - split(flagstr, flagarray, ",") 91 - flags = "" 92 - for (arg in flagarray) { 93 - if (flagarray[arg] == "NO-OFDM") { 94 - flags = flags "\n\t\t\tNL80211_RRF_NO_OFDM | " 95 - } else if (flagarray[arg] == "NO-CCK") { 96 - flags = flags "\n\t\t\tNL80211_RRF_NO_CCK | " 97 - } else if (flagarray[arg] == "NO-INDOOR") { 98 - flags = flags "\n\t\t\tNL80211_RRF_NO_INDOOR | " 99 - } else if (flagarray[arg] == "NO-OUTDOOR") { 100 - flags = flags "\n\t\t\tNL80211_RRF_NO_OUTDOOR | " 101 - } else if (flagarray[arg] == "DFS") { 102 - flags = flags "\n\t\t\tNL80211_RRF_DFS | " 103 - } else if (flagarray[arg] == "PTP-ONLY") { 104 - flags = flags "\n\t\t\tNL80211_RRF_PTP_ONLY | " 105 - } else if (flagarray[arg] == "PTMP-ONLY") { 106 - flags = flags "\n\t\t\tNL80211_RRF_PTMP_ONLY | " 107 - } else if (flagarray[arg] == "PASSIVE-SCAN") { 108 - flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " 109 - } else if (flagarray[arg] == "NO-IBSS") { 110 - flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " 111 - } else if (flagarray[arg] == "NO-IR") { 112 - flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " 113 - } else if (flagarray[arg] == "AUTO-BW") { 114 - flags = flags "\n\t\t\tNL80211_RRF_AUTO_BW | " 115 - } 116 - 117 - } 118 - flags = flags "0" 119 - printf "\t\tREG_RULE_EXT(%d, %d, %d, %d, %.0f, %d, %s),\n", start, end, bw, gain, power, dfs_cac, flags 120 - rules++ 121 - } 122 - 123 - function print_tail_country() 124 - { 125 - active = 0 126 - printf "\t},\n" 127 - printf "\t.n_reg_rules = %d\n", rules 128 - printf "};\n\n" 129 - rules = 0; 130 - } 131 - 132 - /^[ \t]*#/ { 133 - # Ignore 134 - } 135 - 136 - !active && /^[ \t]*$/ { 137 - # Ignore 138 - } 139 - 140 - !active && /country/ { 141 - parse_country_head() 142 - } 143 - 144 - active && /^[ \t]*\(/ { 145 - parse_reg_rule() 146 - } 147 - 148 - active && /^[ \t]*$/ { 149 - print_tail_country() 150 - } 151 - 152 - END { 153 - if (active) 154 - print_tail_country() 155 - print regdb "};" 156 - print "" 157 - print "int reg_regdb_size = ARRAY_SIZE(reg_regdb);" 158 - }
+136 -63
net/wireless/nl80211.c
··· 2130 2130 case NL80211_CHAN_HT40MINUS: 2131 2131 cfg80211_chandef_create(chandef, chandef->chan, 2132 2132 chantype); 2133 + /* user input for center_freq is incorrect */ 2134 + if (info->attrs[NL80211_ATTR_CENTER_FREQ1] && 2135 + chandef->center_freq1 != nla_get_u32( 2136 + info->attrs[NL80211_ATTR_CENTER_FREQ1])) 2137 + return -EINVAL; 2138 + /* center_freq2 must be zero */ 2139 + if (info->attrs[NL80211_ATTR_CENTER_FREQ2] && 2140 + nla_get_u32(info->attrs[NL80211_ATTR_CENTER_FREQ2])) 2141 + return -EINVAL; 2133 2142 break; 2134 2143 default: 2135 2144 return -EINVAL; ··· 5686 5677 } 5687 5678 } 5688 5679 5680 + static int nl80211_reload_regdb(struct sk_buff *skb, struct genl_info *info) 5681 + { 5682 + return reg_reload_regdb(); 5683 + } 5684 + 5689 5685 static int nl80211_get_mesh_config(struct sk_buff *skb, 5690 5686 struct genl_info *info) 5691 5687 { ··· 6632 6618 return regulatory_pre_cac_allowed(wdev->wiphy); 6633 6619 } 6634 6620 6621 + static int 6622 + nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev, 6623 + void *request, struct nlattr **attrs, 6624 + bool is_sched_scan) 6625 + { 6626 + u8 *mac_addr, *mac_addr_mask; 6627 + u32 *flags; 6628 + enum nl80211_feature_flags randomness_flag; 6629 + 6630 + if (!attrs[NL80211_ATTR_SCAN_FLAGS]) 6631 + return 0; 6632 + 6633 + if (is_sched_scan) { 6634 + struct cfg80211_sched_scan_request *req = request; 6635 + 6636 + randomness_flag = wdev ? 6637 + NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR : 6638 + NL80211_FEATURE_ND_RANDOM_MAC_ADDR; 6639 + flags = &req->flags; 6640 + mac_addr = req->mac_addr; 6641 + mac_addr_mask = req->mac_addr_mask; 6642 + } else { 6643 + struct cfg80211_scan_request *req = request; 6644 + 6645 + randomness_flag = NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; 6646 + flags = &req->flags; 6647 + mac_addr = req->mac_addr; 6648 + mac_addr_mask = req->mac_addr_mask; 6649 + } 6650 + 6651 + *flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]); 6652 + 6653 + if ((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && 6654 + !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) 6655 + return -EOPNOTSUPP; 6656 + 6657 + if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { 6658 + int err; 6659 + 6660 + if (!(wiphy->features & randomness_flag) || 6661 + (wdev && wdev->current_bss)) 6662 + return -EOPNOTSUPP; 6663 + 6664 + err = nl80211_parse_random_mac(attrs, mac_addr, mac_addr_mask); 6665 + if (err) 6666 + return err; 6667 + } 6668 + 6669 + if ((*flags & NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME) && 6670 + !wiphy_ext_feature_isset(wiphy, 6671 + NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME)) 6672 + return -EOPNOTSUPP; 6673 + 6674 + if ((*flags & NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP) && 6675 + !wiphy_ext_feature_isset(wiphy, 6676 + NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP)) 6677 + return -EOPNOTSUPP; 6678 + 6679 + if ((*flags & NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) && 6680 + !wiphy_ext_feature_isset(wiphy, 6681 + NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION)) 6682 + return -EOPNOTSUPP; 6683 + 6684 + if ((*flags & NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE) && 6685 + !wiphy_ext_feature_isset(wiphy, 6686 + NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE)) 6687 + return -EOPNOTSUPP; 6688 + 6689 + return 0; 6690 + } 6691 + 6635 6692 static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) 6636 6693 { 6637 6694 struct cfg80211_registered_device *rdev = info->user_ptr[0]; ··· 6908 6823 nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]); 6909 6824 } 6910 6825 6911 - if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) { 6912 - request->flags = nla_get_u32( 6913 - info->attrs[NL80211_ATTR_SCAN_FLAGS]); 6914 - if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && 6915 - !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) { 6916 - err = -EOPNOTSUPP; 6917 - goto out_free; 6918 - } 6919 - 6920 - if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { 6921 - if (!(wiphy->features & 6922 - NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR)) { 6923 - err = -EOPNOTSUPP; 6924 - goto out_free; 6925 - } 6926 - 6927 - if (wdev->current_bss) { 6928 - err = -EOPNOTSUPP; 6929 - goto out_free; 6930 - } 6931 - 6932 - err = nl80211_parse_random_mac(info->attrs, 6933 - request->mac_addr, 6934 - request->mac_addr_mask); 6935 - if (err) 6936 - goto out_free; 6937 - } 6938 - } 6826 + err = nl80211_check_scan_flags(wiphy, wdev, request, info->attrs, 6827 + false); 6828 + if (err) 6829 + goto out_free; 6939 6830 6940 6831 request->no_cck = 6941 6832 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); ··· 7359 7298 request->ie_len); 7360 7299 } 7361 7300 7362 - if (attrs[NL80211_ATTR_SCAN_FLAGS]) { 7363 - request->flags = nla_get_u32( 7364 - attrs[NL80211_ATTR_SCAN_FLAGS]); 7365 - if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && 7366 - !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) { 7367 - err = -EOPNOTSUPP; 7368 - goto out_free; 7369 - } 7370 - 7371 - if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { 7372 - u32 flg = NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR; 7373 - 7374 - if (!wdev) /* must be net-detect */ 7375 - flg = NL80211_FEATURE_ND_RANDOM_MAC_ADDR; 7376 - 7377 - if (!(wiphy->features & flg)) { 7378 - err = -EOPNOTSUPP; 7379 - goto out_free; 7380 - } 7381 - 7382 - if (wdev && wdev->current_bss) { 7383 - err = -EOPNOTSUPP; 7384 - goto out_free; 7385 - } 7386 - 7387 - err = nl80211_parse_random_mac(attrs, request->mac_addr, 7388 - request->mac_addr_mask); 7389 - if (err) 7390 - goto out_free; 7391 - } 7392 - } 7301 + err = nl80211_check_scan_flags(wiphy, wdev, request, attrs, true); 7302 + if (err) 7303 + goto out_free; 7393 7304 7394 7305 if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY]) 7395 7306 request->delay = ··· 8965 8932 8966 8933 if (info->attrs[NL80211_ATTR_USE_MFP]) { 8967 8934 connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]); 8935 + if (connect.mfp == NL80211_MFP_OPTIONAL && 8936 + !wiphy_ext_feature_isset(&rdev->wiphy, 8937 + NL80211_EXT_FEATURE_MFP_OPTIONAL)) 8938 + return -EOPNOTSUPP; 8939 + 8968 8940 if (connect.mfp != NL80211_MFP_REQUIRED && 8969 - connect.mfp != NL80211_MFP_NO) 8941 + connect.mfp != NL80211_MFP_NO && 8942 + connect.mfp != NL80211_MFP_OPTIONAL) 8970 8943 return -EINVAL; 8971 8944 } else { 8972 8945 connect.mfp = NL80211_MFP_NO; ··· 12724 12685 .flags = GENL_ADMIN_PERM, 12725 12686 }, 12726 12687 { 12688 + .cmd = NL80211_CMD_RELOAD_REGDB, 12689 + .doit = nl80211_reload_regdb, 12690 + .policy = nl80211_policy, 12691 + .flags = GENL_ADMIN_PERM, 12692 + }, 12693 + { 12727 12694 .cmd = NL80211_CMD_GET_MESH_CONFIG, 12728 12695 .doit = nl80211_get_mesh_config, 12729 12696 .policy = nl80211_policy, ··· 13857 13812 info->req_ie)) || 13858 13813 (info->resp_ie && 13859 13814 nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len, 13860 - info->resp_ie)) || 13861 - (info->authorized && 13862 - nla_put_flag(msg, NL80211_ATTR_PORT_AUTHORIZED))) 13815 + info->resp_ie))) 13863 13816 goto nla_put_failure; 13864 13817 13865 13818 genlmsg_end(msg, hdr); 13866 13819 13867 13820 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, 13868 13821 NL80211_MCGRP_MLME, gfp); 13822 + return; 13823 + 13824 + nla_put_failure: 13825 + genlmsg_cancel(msg, hdr); 13826 + nlmsg_free(msg); 13827 + } 13828 + 13829 + void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev, 13830 + struct net_device *netdev, const u8 *bssid) 13831 + { 13832 + struct sk_buff *msg; 13833 + void *hdr; 13834 + 13835 + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 13836 + if (!msg) 13837 + return; 13838 + 13839 + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PORT_AUTHORIZED); 13840 + if (!hdr) { 13841 + nlmsg_free(msg); 13842 + return; 13843 + } 13844 + 13845 + if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) 13846 + goto nla_put_failure; 13847 + 13848 + genlmsg_end(msg, hdr); 13849 + 13850 + genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, 13851 + NL80211_MCGRP_MLME, GFP_KERNEL); 13869 13852 return; 13870 13853 13871 13854 nla_put_failure:
+2
net/wireless/nl80211.h
··· 58 58 void nl80211_send_roamed(struct cfg80211_registered_device *rdev, 59 59 struct net_device *netdev, 60 60 struct cfg80211_roam_info *info, gfp_t gfp); 61 + void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev, 62 + struct net_device *netdev, const u8 *bssid); 61 63 void nl80211_send_disconnected(struct cfg80211_registered_device *rdev, 62 64 struct net_device *netdev, u16 reason, 63 65 const u8 *ie, size_t ie_len, bool from_ap);
+411 -41
net/wireless/reg.c
··· 53 53 #include <linux/ctype.h> 54 54 #include <linux/nl80211.h> 55 55 #include <linux/platform_device.h> 56 + #include <linux/verification.h> 56 57 #include <linux/moduleparam.h> 58 + #include <linux/firmware.h> 57 59 #include <net/cfg80211.h> 58 60 #include "core.h" 59 61 #include "reg.h" 60 62 #include "rdev-ops.h" 61 - #include "regdb.h" 62 63 #include "nl80211.h" 63 64 64 65 /* ··· 101 100 static struct regulatory_request __rcu *last_request = 102 101 (void __force __rcu *)&core_request_world; 103 102 104 - /* To trigger userspace events */ 103 + /* To trigger userspace events and load firmware */ 105 104 static struct platform_device *reg_pdev; 106 105 107 106 /* ··· 444 443 return regd; 445 444 } 446 445 447 - #ifdef CONFIG_CFG80211_INTERNAL_REGDB 448 446 struct reg_regdb_apply_request { 449 447 struct list_head list; 450 448 const struct ieee80211_regdomain *regdom; ··· 475 475 476 476 static DECLARE_WORK(reg_regdb_work, reg_regdb_apply); 477 477 478 - static int reg_query_builtin(const char *alpha2) 478 + static int reg_schedule_apply(const struct ieee80211_regdomain *regdom) 479 479 { 480 - const struct ieee80211_regdomain *regdom = NULL; 481 480 struct reg_regdb_apply_request *request; 482 - unsigned int i; 483 - 484 - for (i = 0; i < reg_regdb_size; i++) { 485 - if (alpha2_equal(alpha2, reg_regdb[i]->alpha2)) { 486 - regdom = reg_regdb[i]; 487 - break; 488 - } 489 - } 490 - 491 - if (!regdom) 492 - return -ENODATA; 493 481 494 482 request = kzalloc(sizeof(struct reg_regdb_apply_request), GFP_KERNEL); 495 - if (!request) 496 - return -ENOMEM; 497 - 498 - request->regdom = reg_copy_regd(regdom); 499 - if (IS_ERR_OR_NULL(request->regdom)) { 500 - kfree(request); 483 + if (!request) { 484 + kfree(regdom); 501 485 return -ENOMEM; 502 486 } 487 + 488 + request->regdom = regdom; 503 489 504 490 mutex_lock(&reg_regdb_apply_mutex); 505 491 list_add_tail(&request->list, &reg_regdb_apply_list); 506 492 mutex_unlock(&reg_regdb_apply_mutex); 507 493 508 494 schedule_work(&reg_regdb_work); 509 - 510 495 return 0; 511 496 } 512 - 513 - /* Feel free to add any other sanity checks here */ 514 - static void reg_regdb_size_check(void) 515 - { 516 - /* We should ideally BUILD_BUG_ON() but then random builds would fail */ 517 - WARN_ONCE(!reg_regdb_size, "db.txt is empty, you should update it..."); 518 - } 519 - #else 520 - static inline void reg_regdb_size_check(void) {} 521 - static inline int reg_query_builtin(const char *alpha2) 522 - { 523 - return -ENODATA; 524 - } 525 - #endif /* CONFIG_CFG80211_INTERNAL_REGDB */ 526 497 527 498 #ifdef CONFIG_CFG80211_CRDA_SUPPORT 528 499 /* Max number of consecutive attempts to communicate with CRDA */ ··· 570 599 } 571 600 #endif /* CONFIG_CFG80211_CRDA_SUPPORT */ 572 601 602 + /* code to directly load a firmware database through request_firmware */ 603 + static const struct fwdb_header *regdb; 604 + 605 + struct fwdb_country { 606 + u8 alpha2[2]; 607 + __be16 coll_ptr; 608 + /* this struct cannot be extended */ 609 + } __packed __aligned(4); 610 + 611 + struct fwdb_collection { 612 + u8 len; 613 + u8 n_rules; 614 + u8 dfs_region; 615 + /* no optional data yet */ 616 + /* aligned to 2, then followed by __be16 array of rule pointers */ 617 + } __packed __aligned(4); 618 + 619 + enum fwdb_flags { 620 + FWDB_FLAG_NO_OFDM = BIT(0), 621 + FWDB_FLAG_NO_OUTDOOR = BIT(1), 622 + FWDB_FLAG_DFS = BIT(2), 623 + FWDB_FLAG_NO_IR = BIT(3), 624 + FWDB_FLAG_AUTO_BW = BIT(4), 625 + }; 626 + 627 + struct fwdb_rule { 628 + u8 len; 629 + u8 flags; 630 + __be16 max_eirp; 631 + __be32 start, end, max_bw; 632 + /* start of optional data */ 633 + __be16 cac_timeout; 634 + } __packed __aligned(4); 635 + 636 + #define FWDB_MAGIC 0x52474442 637 + #define FWDB_VERSION 20 638 + 639 + struct fwdb_header { 640 + __be32 magic; 641 + __be32 version; 642 + struct fwdb_country country[]; 643 + } __packed __aligned(4); 644 + 645 + static bool valid_rule(const u8 *data, unsigned int size, u16 rule_ptr) 646 + { 647 + struct fwdb_rule *rule = (void *)(data + (rule_ptr << 2)); 648 + 649 + if ((u8 *)rule + sizeof(rule->len) > data + size) 650 + return false; 651 + 652 + /* mandatory fields */ 653 + if (rule->len < offsetofend(struct fwdb_rule, max_bw)) 654 + return false; 655 + 656 + return true; 657 + } 658 + 659 + static bool valid_country(const u8 *data, unsigned int size, 660 + const struct fwdb_country *country) 661 + { 662 + unsigned int ptr = be16_to_cpu(country->coll_ptr) << 2; 663 + struct fwdb_collection *coll = (void *)(data + ptr); 664 + __be16 *rules_ptr; 665 + unsigned int i; 666 + 667 + /* make sure we can read len/n_rules */ 668 + if ((u8 *)coll + offsetofend(typeof(*coll), n_rules) > data + size) 669 + return false; 670 + 671 + /* make sure base struct and all rules fit */ 672 + if ((u8 *)coll + ALIGN(coll->len, 2) + 673 + (coll->n_rules * 2) > data + size) 674 + return false; 675 + 676 + /* mandatory fields must exist */ 677 + if (coll->len < offsetofend(struct fwdb_collection, dfs_region)) 678 + return false; 679 + 680 + rules_ptr = (void *)((u8 *)coll + ALIGN(coll->len, 2)); 681 + 682 + for (i = 0; i < coll->n_rules; i++) { 683 + u16 rule_ptr = be16_to_cpu(rules_ptr[i]); 684 + 685 + if (!valid_rule(data, size, rule_ptr)) 686 + return false; 687 + } 688 + 689 + return true; 690 + } 691 + 692 + #ifdef CONFIG_CFG80211_REQUIRE_SIGNED_REGDB 693 + static struct key *builtin_regdb_keys; 694 + 695 + static void __init load_keys_from_buffer(const u8 *p, unsigned int buflen) 696 + { 697 + const u8 *end = p + buflen; 698 + size_t plen; 699 + key_ref_t key; 700 + 701 + while (p < end) { 702 + /* Each cert begins with an ASN.1 SEQUENCE tag and must be more 703 + * than 256 bytes in size. 704 + */ 705 + if (end - p < 4) 706 + goto dodgy_cert; 707 + if (p[0] != 0x30 && 708 + p[1] != 0x82) 709 + goto dodgy_cert; 710 + plen = (p[2] << 8) | p[3]; 711 + plen += 4; 712 + if (plen > end - p) 713 + goto dodgy_cert; 714 + 715 + key = key_create_or_update(make_key_ref(builtin_regdb_keys, 1), 716 + "asymmetric", NULL, p, plen, 717 + ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 718 + KEY_USR_VIEW | KEY_USR_READ), 719 + KEY_ALLOC_NOT_IN_QUOTA | 720 + KEY_ALLOC_BUILT_IN | 721 + KEY_ALLOC_BYPASS_RESTRICTION); 722 + if (IS_ERR(key)) { 723 + pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", 724 + PTR_ERR(key)); 725 + } else { 726 + pr_notice("Loaded X.509 cert '%s'\n", 727 + key_ref_to_ptr(key)->description); 728 + key_ref_put(key); 729 + } 730 + p += plen; 731 + } 732 + 733 + return; 734 + 735 + dodgy_cert: 736 + pr_err("Problem parsing in-kernel X.509 certificate list\n"); 737 + } 738 + 739 + static int __init load_builtin_regdb_keys(void) 740 + { 741 + builtin_regdb_keys = 742 + keyring_alloc(".builtin_regdb_keys", 743 + KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), 744 + ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 745 + KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH), 746 + KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); 747 + if (IS_ERR(builtin_regdb_keys)) 748 + return PTR_ERR(builtin_regdb_keys); 749 + 750 + pr_notice("Loading compiled-in X.509 certificates for regulatory database\n"); 751 + 752 + #ifdef CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS 753 + load_keys_from_buffer(shipped_regdb_certs, shipped_regdb_certs_len); 754 + #endif 755 + #ifdef CFG80211_EXTRA_REGDB_KEYDIR 756 + if (CONFIG_CFG80211_EXTRA_REGDB_KEYDIR[0] != '\0') 757 + load_keys_from_buffer(extra_regdb_certs, extra_regdb_certs_len); 758 + #endif 759 + 760 + return 0; 761 + } 762 + 763 + static bool regdb_has_valid_signature(const u8 *data, unsigned int size) 764 + { 765 + const struct firmware *sig; 766 + bool result; 767 + 768 + if (request_firmware(&sig, "regulatory.db.p7s", &reg_pdev->dev)) 769 + return false; 770 + 771 + result = verify_pkcs7_signature(data, size, sig->data, sig->size, 772 + builtin_regdb_keys, 773 + VERIFYING_UNSPECIFIED_SIGNATURE, 774 + NULL, NULL) == 0; 775 + 776 + release_firmware(sig); 777 + 778 + return result; 779 + } 780 + 781 + static void free_regdb_keyring(void) 782 + { 783 + key_put(builtin_regdb_keys); 784 + } 785 + #else 786 + static int load_builtin_regdb_keys(void) 787 + { 788 + return 0; 789 + } 790 + 791 + static bool regdb_has_valid_signature(const u8 *data, unsigned int size) 792 + { 793 + return true; 794 + } 795 + 796 + static void free_regdb_keyring(void) 797 + { 798 + } 799 + #endif /* CONFIG_CFG80211_REQUIRE_SIGNED_REGDB */ 800 + 801 + static bool valid_regdb(const u8 *data, unsigned int size) 802 + { 803 + const struct fwdb_header *hdr = (void *)data; 804 + const struct fwdb_country *country; 805 + 806 + if (size < sizeof(*hdr)) 807 + return false; 808 + 809 + if (hdr->magic != cpu_to_be32(FWDB_MAGIC)) 810 + return false; 811 + 812 + if (hdr->version != cpu_to_be32(FWDB_VERSION)) 813 + return false; 814 + 815 + if (!regdb_has_valid_signature(data, size)) 816 + return false; 817 + 818 + country = &hdr->country[0]; 819 + while ((u8 *)(country + 1) <= data + size) { 820 + if (!country->coll_ptr) 821 + break; 822 + if (!valid_country(data, size, country)) 823 + return false; 824 + country++; 825 + } 826 + 827 + return true; 828 + } 829 + 830 + static int regdb_query_country(const struct fwdb_header *db, 831 + const struct fwdb_country *country) 832 + { 833 + unsigned int ptr = be16_to_cpu(country->coll_ptr) << 2; 834 + struct fwdb_collection *coll = (void *)((u8 *)db + ptr); 835 + struct ieee80211_regdomain *regdom; 836 + unsigned int size_of_regd; 837 + unsigned int i; 838 + 839 + size_of_regd = 840 + sizeof(struct ieee80211_regdomain) + 841 + coll->n_rules * sizeof(struct ieee80211_reg_rule); 842 + 843 + regdom = kzalloc(size_of_regd, GFP_KERNEL); 844 + if (!regdom) 845 + return -ENOMEM; 846 + 847 + regdom->n_reg_rules = coll->n_rules; 848 + regdom->alpha2[0] = country->alpha2[0]; 849 + regdom->alpha2[1] = country->alpha2[1]; 850 + regdom->dfs_region = coll->dfs_region; 851 + 852 + for (i = 0; i < regdom->n_reg_rules; i++) { 853 + __be16 *rules_ptr = (void *)((u8 *)coll + ALIGN(coll->len, 2)); 854 + unsigned int rule_ptr = be16_to_cpu(rules_ptr[i]) << 2; 855 + struct fwdb_rule *rule = (void *)((u8 *)db + rule_ptr); 856 + struct ieee80211_reg_rule *rrule = &regdom->reg_rules[i]; 857 + 858 + rrule->freq_range.start_freq_khz = be32_to_cpu(rule->start); 859 + rrule->freq_range.end_freq_khz = be32_to_cpu(rule->end); 860 + rrule->freq_range.max_bandwidth_khz = be32_to_cpu(rule->max_bw); 861 + 862 + rrule->power_rule.max_antenna_gain = 0; 863 + rrule->power_rule.max_eirp = be16_to_cpu(rule->max_eirp); 864 + 865 + rrule->flags = 0; 866 + if (rule->flags & FWDB_FLAG_NO_OFDM) 867 + rrule->flags |= NL80211_RRF_NO_OFDM; 868 + if (rule->flags & FWDB_FLAG_NO_OUTDOOR) 869 + rrule->flags |= NL80211_RRF_NO_OUTDOOR; 870 + if (rule->flags & FWDB_FLAG_DFS) 871 + rrule->flags |= NL80211_RRF_DFS; 872 + if (rule->flags & FWDB_FLAG_NO_IR) 873 + rrule->flags |= NL80211_RRF_NO_IR; 874 + if (rule->flags & FWDB_FLAG_AUTO_BW) 875 + rrule->flags |= NL80211_RRF_AUTO_BW; 876 + 877 + rrule->dfs_cac_ms = 0; 878 + 879 + /* handle optional data */ 880 + if (rule->len >= offsetofend(struct fwdb_rule, cac_timeout)) 881 + rrule->dfs_cac_ms = 882 + 1000 * be16_to_cpu(rule->cac_timeout); 883 + } 884 + 885 + return reg_schedule_apply(regdom); 886 + } 887 + 888 + static int query_regdb(const char *alpha2) 889 + { 890 + const struct fwdb_header *hdr = regdb; 891 + const struct fwdb_country *country; 892 + 893 + ASSERT_RTNL(); 894 + 895 + if (IS_ERR(regdb)) 896 + return PTR_ERR(regdb); 897 + 898 + country = &hdr->country[0]; 899 + while (country->coll_ptr) { 900 + if (alpha2_equal(alpha2, country->alpha2)) 901 + return regdb_query_country(regdb, country); 902 + country++; 903 + } 904 + 905 + return -ENODATA; 906 + } 907 + 908 + static void regdb_fw_cb(const struct firmware *fw, void *context) 909 + { 910 + int set_error = 0; 911 + bool restore = true; 912 + void *db; 913 + 914 + if (!fw) { 915 + pr_info("failed to load regulatory.db\n"); 916 + set_error = -ENODATA; 917 + } else if (!valid_regdb(fw->data, fw->size)) { 918 + pr_info("loaded regulatory.db is malformed or signature is missing/invalid\n"); 919 + set_error = -EINVAL; 920 + } 921 + 922 + rtnl_lock(); 923 + if (WARN_ON(regdb && !IS_ERR(regdb))) { 924 + /* just restore and free new db */ 925 + } else if (set_error) { 926 + regdb = ERR_PTR(set_error); 927 + } else if (fw) { 928 + db = kmemdup(fw->data, fw->size, GFP_KERNEL); 929 + if (db) { 930 + regdb = db; 931 + restore = context && query_regdb(context); 932 + } else { 933 + restore = true; 934 + } 935 + } 936 + 937 + if (restore) 938 + restore_regulatory_settings(true); 939 + 940 + rtnl_unlock(); 941 + 942 + kfree(context); 943 + 944 + release_firmware(fw); 945 + } 946 + 947 + static int query_regdb_file(const char *alpha2) 948 + { 949 + ASSERT_RTNL(); 950 + 951 + if (regdb) 952 + return query_regdb(alpha2); 953 + 954 + alpha2 = kmemdup(alpha2, 2, GFP_KERNEL); 955 + if (!alpha2) 956 + return -ENOMEM; 957 + 958 + return request_firmware_nowait(THIS_MODULE, true, "regulatory.db", 959 + &reg_pdev->dev, GFP_KERNEL, 960 + (void *)alpha2, regdb_fw_cb); 961 + } 962 + 963 + int reg_reload_regdb(void) 964 + { 965 + const struct firmware *fw; 966 + void *db; 967 + int err; 968 + 969 + err = request_firmware(&fw, "regulatory.db", &reg_pdev->dev); 970 + if (err) 971 + return err; 972 + 973 + if (!valid_regdb(fw->data, fw->size)) { 974 + err = -ENODATA; 975 + goto out; 976 + } 977 + 978 + db = kmemdup(fw->data, fw->size, GFP_KERNEL); 979 + if (!db) { 980 + err = -ENOMEM; 981 + goto out; 982 + } 983 + 984 + rtnl_lock(); 985 + if (!IS_ERR_OR_NULL(regdb)) 986 + kfree(regdb); 987 + regdb = db; 988 + rtnl_unlock(); 989 + 990 + out: 991 + release_firmware(fw); 992 + return err; 993 + } 994 + 573 995 static bool reg_query_database(struct regulatory_request *request) 574 996 { 575 - /* query internal regulatory database (if it exists) */ 576 - if (reg_query_builtin(request->alpha2) == 0) 997 + if (query_regdb_file(request->alpha2) == 0) 577 998 return true; 578 999 579 1000 if (call_crda(request->alpha2) == 0) ··· 3648 3285 { 3649 3286 int err = 0; 3650 3287 3288 + err = load_builtin_regdb_keys(); 3289 + if (err) 3290 + return err; 3291 + 3651 3292 reg_pdev = platform_device_register_simple("regulatory", 0, NULL, 0); 3652 3293 if (IS_ERR(reg_pdev)) 3653 3294 return PTR_ERR(reg_pdev); ··· 3659 3292 spin_lock_init(&reg_requests_lock); 3660 3293 spin_lock_init(&reg_pending_beacons_lock); 3661 3294 spin_lock_init(&reg_indoor_lock); 3662 - 3663 - reg_regdb_size_check(); 3664 3295 3665 3296 rcu_assign_pointer(cfg80211_regdomain, cfg80211_world_regdom); 3666 3297 ··· 3725 3360 list_del(&reg_request->list); 3726 3361 kfree(reg_request); 3727 3362 } 3363 + 3364 + if (!IS_ERR_OR_NULL(regdb)) 3365 + kfree(regdb); 3366 + 3367 + free_regdb_keyring(); 3728 3368 }
+14
net/wireless/reg.h
··· 1 1 #ifndef __NET_WIRELESS_REG_H 2 2 #define __NET_WIRELESS_REG_H 3 + 4 + #include <net/cfg80211.h> 5 + 3 6 /* 4 7 * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com> 5 8 * ··· 182 179 * @wiphy2 - wiphy it's dfs_region to be checked against that of wiphy1 183 180 */ 184 181 bool reg_dfs_domain_same(struct wiphy *wiphy1, struct wiphy *wiphy2); 182 + 183 + /** 184 + * reg_reload_regdb - reload the regulatory.db firmware file 185 + */ 186 + int reg_reload_regdb(void); 187 + 188 + extern const u8 shipped_regdb_certs[]; 189 + extern unsigned int shipped_regdb_certs_len; 190 + extern const u8 extra_regdb_certs[]; 191 + extern unsigned int extra_regdb_certs_len; 192 + 185 193 #endif /* __NET_WIRELESS_REG_H */
-23
net/wireless/regdb.h
··· 1 - #ifndef __REGDB_H__ 2 - #define __REGDB_H__ 3 - 4 - /* 5 - * Copyright 2009 John W. Linville <linville@tuxdriver.com> 6 - * 7 - * Permission to use, copy, modify, and/or distribute this software for any 8 - * purpose with or without fee is hereby granted, provided that the above 9 - * copyright notice and this permission notice appear in all copies. 10 - * 11 - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 - */ 19 - 20 - extern const struct ieee80211_regdomain *reg_regdb[]; 21 - extern int reg_regdb_size; 22 - 23 - #endif /* __REGDB_H__ */
+44 -1
net/wireless/sme.c
··· 960 960 ev->rm.resp_ie_len = info->resp_ie_len; 961 961 memcpy((void *)ev->rm.resp_ie, info->resp_ie, info->resp_ie_len); 962 962 ev->rm.bss = info->bss; 963 - ev->rm.authorized = info->authorized; 964 963 965 964 spin_lock_irqsave(&wdev->event_lock, flags); 966 965 list_add_tail(&ev->list, &wdev->event_list); ··· 967 968 queue_work(cfg80211_wq, &rdev->event_work); 968 969 } 969 970 EXPORT_SYMBOL(cfg80211_roamed); 971 + 972 + void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid) 973 + { 974 + ASSERT_WDEV_LOCK(wdev); 975 + 976 + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) 977 + return; 978 + 979 + if (WARN_ON(!wdev->current_bss) || 980 + WARN_ON(!ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) 981 + return; 982 + 983 + nl80211_send_port_authorized(wiphy_to_rdev(wdev->wiphy), wdev->netdev, 984 + bssid); 985 + } 986 + 987 + void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid, 988 + gfp_t gfp) 989 + { 990 + struct wireless_dev *wdev = dev->ieee80211_ptr; 991 + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 992 + struct cfg80211_event *ev; 993 + unsigned long flags; 994 + 995 + if (WARN_ON(!bssid)) 996 + return; 997 + 998 + ev = kzalloc(sizeof(*ev), gfp); 999 + if (!ev) 1000 + return; 1001 + 1002 + ev->type = EVENT_PORT_AUTHORIZED; 1003 + memcpy(ev->pa.bssid, bssid, ETH_ALEN); 1004 + 1005 + /* 1006 + * Use the wdev event list so that if there are pending 1007 + * connected/roamed events, they will be reported first. 1008 + */ 1009 + spin_lock_irqsave(&wdev->event_lock, flags); 1010 + list_add_tail(&ev->list, &wdev->event_list); 1011 + spin_unlock_irqrestore(&wdev->event_lock, flags); 1012 + queue_work(cfg80211_wq, &rdev->event_work); 1013 + } 1014 + EXPORT_SYMBOL(cfg80211_port_authorized); 970 1015 971 1016 void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, 972 1017 size_t ie_len, u16 reason, bool from_ap)
+63 -139
net/wireless/util.c
··· 157 157 case NL80211_BAND_2GHZ: 158 158 want = 7; 159 159 for (i = 0; i < sband->n_bitrates; i++) { 160 - if (sband->bitrates[i].bitrate == 10) { 160 + switch (sband->bitrates[i].bitrate) { 161 + case 10: 162 + case 20: 163 + case 55: 164 + case 110: 161 165 sband->bitrates[i].flags |= 162 166 IEEE80211_RATE_MANDATORY_B | 163 167 IEEE80211_RATE_MANDATORY_G; 164 168 want--; 165 - } 166 - 167 - if (sband->bitrates[i].bitrate == 20 || 168 - sband->bitrates[i].bitrate == 55 || 169 - sband->bitrates[i].bitrate == 110 || 170 - sband->bitrates[i].bitrate == 60 || 171 - sband->bitrates[i].bitrate == 120 || 172 - sband->bitrates[i].bitrate == 240) { 169 + break; 170 + case 60: 171 + case 120: 172 + case 240: 173 173 sband->bitrates[i].flags |= 174 174 IEEE80211_RATE_MANDATORY_G; 175 175 want--; 176 - } 177 - 178 - if (sband->bitrates[i].bitrate != 10 && 179 - sband->bitrates[i].bitrate != 20 && 180 - sband->bitrates[i].bitrate != 55 && 181 - sband->bitrates[i].bitrate != 110) 176 + /* fall through */ 177 + default: 182 178 sband->bitrates[i].flags |= 183 179 IEEE80211_RATE_ERP_G; 180 + break; 181 + } 184 182 } 185 - WARN_ON(want != 0 && want != 3 && want != 6); 183 + WARN_ON(want != 0 && want != 3); 186 184 break; 187 185 case NL80211_BAND_60GHZ: 188 186 /* check for mandatory HT MCS 1..4 */ ··· 527 529 } 528 530 EXPORT_SYMBOL(ieee80211_data_to_8023_exthdr); 529 531 530 - int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, 531 - enum nl80211_iftype iftype, 532 - const u8 *bssid, bool qos) 533 - { 534 - struct ieee80211_hdr hdr; 535 - u16 hdrlen, ethertype; 536 - __le16 fc; 537 - const u8 *encaps_data; 538 - int encaps_len, skip_header_bytes; 539 - int nh_pos, h_pos; 540 - int head_need; 541 - 542 - if (unlikely(skb->len < ETH_HLEN)) 543 - return -EINVAL; 544 - 545 - nh_pos = skb_network_header(skb) - skb->data; 546 - h_pos = skb_transport_header(skb) - skb->data; 547 - 548 - /* convert Ethernet header to proper 802.11 header (based on 549 - * operation mode) */ 550 - ethertype = (skb->data[12] << 8) | skb->data[13]; 551 - fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); 552 - 553 - switch (iftype) { 554 - case NL80211_IFTYPE_AP: 555 - case NL80211_IFTYPE_AP_VLAN: 556 - case NL80211_IFTYPE_P2P_GO: 557 - fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); 558 - /* DA BSSID SA */ 559 - memcpy(hdr.addr1, skb->data, ETH_ALEN); 560 - memcpy(hdr.addr2, addr, ETH_ALEN); 561 - memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN); 562 - hdrlen = 24; 563 - break; 564 - case NL80211_IFTYPE_STATION: 565 - case NL80211_IFTYPE_P2P_CLIENT: 566 - fc |= cpu_to_le16(IEEE80211_FCTL_TODS); 567 - /* BSSID SA DA */ 568 - memcpy(hdr.addr1, bssid, ETH_ALEN); 569 - memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); 570 - memcpy(hdr.addr3, skb->data, ETH_ALEN); 571 - hdrlen = 24; 572 - break; 573 - case NL80211_IFTYPE_OCB: 574 - case NL80211_IFTYPE_ADHOC: 575 - /* DA SA BSSID */ 576 - memcpy(hdr.addr1, skb->data, ETH_ALEN); 577 - memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); 578 - memcpy(hdr.addr3, bssid, ETH_ALEN); 579 - hdrlen = 24; 580 - break; 581 - default: 582 - return -EOPNOTSUPP; 583 - } 584 - 585 - if (qos) { 586 - fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); 587 - hdrlen += 2; 588 - } 589 - 590 - hdr.frame_control = fc; 591 - hdr.duration_id = 0; 592 - hdr.seq_ctrl = 0; 593 - 594 - skip_header_bytes = ETH_HLEN; 595 - if (ethertype == ETH_P_AARP || ethertype == ETH_P_IPX) { 596 - encaps_data = bridge_tunnel_header; 597 - encaps_len = sizeof(bridge_tunnel_header); 598 - skip_header_bytes -= 2; 599 - } else if (ethertype >= ETH_P_802_3_MIN) { 600 - encaps_data = rfc1042_header; 601 - encaps_len = sizeof(rfc1042_header); 602 - skip_header_bytes -= 2; 603 - } else { 604 - encaps_data = NULL; 605 - encaps_len = 0; 606 - } 607 - 608 - skb_pull(skb, skip_header_bytes); 609 - nh_pos -= skip_header_bytes; 610 - h_pos -= skip_header_bytes; 611 - 612 - head_need = hdrlen + encaps_len - skb_headroom(skb); 613 - 614 - if (head_need > 0 || skb_cloned(skb)) { 615 - head_need = max(head_need, 0); 616 - if (head_need) 617 - skb_orphan(skb); 618 - 619 - if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) 620 - return -ENOMEM; 621 - } 622 - 623 - if (encaps_data) { 624 - memcpy(skb_push(skb, encaps_len), encaps_data, encaps_len); 625 - nh_pos += encaps_len; 626 - h_pos += encaps_len; 627 - } 628 - 629 - memcpy(skb_push(skb, hdrlen), &hdr, hdrlen); 630 - 631 - nh_pos += hdrlen; 632 - h_pos += hdrlen; 633 - 634 - /* Update skb pointers to various headers since this modified frame 635 - * is going to go through Linux networking code that may potentially 636 - * need things like pointer to IP header. */ 637 - skb_reset_mac_header(skb); 638 - skb_set_network_header(skb, nh_pos); 639 - skb_set_transport_header(skb, h_pos); 640 - 641 - return 0; 642 - } 643 - EXPORT_SYMBOL(ieee80211_data_from_8023); 644 - 645 532 static void 646 533 __frame_add_frag(struct sk_buff *skb, struct page *page, 647 534 void *ptr, int len, int size) ··· 845 962 break; 846 963 case EVENT_STOPPED: 847 964 __cfg80211_leave(wiphy_to_rdev(wdev->wiphy), wdev); 965 + break; 966 + case EVENT_PORT_AUTHORIZED: 967 + __cfg80211_port_authorized(wdev, ev->pa.bssid); 848 968 break; 849 969 } 850 970 wdev_unlock(wdev); ··· 1253 1367 } 1254 1368 EXPORT_SYMBOL(cfg80211_get_p2p_attr); 1255 1369 1256 - static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) 1370 + static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id, bool id_ext) 1257 1371 { 1258 1372 int i; 1259 1373 1260 - for (i = 0; i < n_ids; i++) 1261 - if (ids[i] == id) 1374 + /* Make sure array values are legal */ 1375 + if (WARN_ON(ids[n_ids - 1] == WLAN_EID_EXTENSION)) 1376 + return false; 1377 + 1378 + i = 0; 1379 + while (i < n_ids) { 1380 + if (ids[i] == WLAN_EID_EXTENSION) { 1381 + if (id_ext && (ids[i + 1] == id)) 1382 + return true; 1383 + 1384 + i += 2; 1385 + continue; 1386 + } 1387 + 1388 + if (ids[i] == id && !id_ext) 1262 1389 return true; 1390 + 1391 + i++; 1392 + } 1263 1393 return false; 1264 1394 } 1265 1395 ··· 1305 1403 { 1306 1404 size_t pos = offset; 1307 1405 1308 - while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) { 1406 + while (pos < ielen) { 1407 + u8 ext = 0; 1408 + 1409 + if (ies[pos] == WLAN_EID_EXTENSION) 1410 + ext = 2; 1411 + if ((pos + ext) >= ielen) 1412 + break; 1413 + 1414 + if (!ieee80211_id_in_list(ids, n_ids, ies[pos + ext], 1415 + ies[pos] == WLAN_EID_EXTENSION)) 1416 + break; 1417 + 1309 1418 if (ies[pos] == WLAN_EID_RIC_DATA && n_after_ric) { 1310 1419 pos = skip_ie(ies, ielen, pos); 1311 1420 1312 - while (pos < ielen && 1313 - !ieee80211_id_in_list(after_ric, n_after_ric, 1314 - ies[pos])) 1315 - pos = skip_ie(ies, ielen, pos); 1421 + while (pos < ielen) { 1422 + if (ies[pos] == WLAN_EID_EXTENSION) 1423 + ext = 2; 1424 + else 1425 + ext = 0; 1426 + 1427 + if ((pos + ext) >= ielen) 1428 + break; 1429 + 1430 + if (!ieee80211_id_in_list(after_ric, 1431 + n_after_ric, 1432 + ies[pos + ext], 1433 + ext == 2)) 1434 + pos = skip_ie(ies, ielen, pos); 1435 + } 1316 1436 } else { 1317 1437 pos = skip_ie(ies, ielen, pos); 1318 1438 }