History

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. ====================

David S. Miller committed 9 years ago

Commit df2fd382 parents b822696 90a53e447 files · +1277 −898Browse files

Unified · Split

47 files
  1. Documentation/driver-api/80211/cfg80211.rst +0 −3
  2. Documentation/networking/regulatory.txt +10 −20
  3. MAINTAINERS +10 −3
  4. drivers/net/wireless/mac80211_hwsim.c +96 −96
  5. include/linux/ieee80211.h +1 −0
  6. include/net/cfg80211.h +21 −19
  7. include/net/fq.h +7 −0
  8. include/net/fq_impl.h +62 −10
  9. include/net/mac80211.h +7 −1
  10. include/uapi/linux/nl80211.h +65 −17
  11. net/mac80211/Makefile +1 −2
  12. net/mac80211/aead_api.c +20 −20
  13. net/mac80211/aead_api.h +27 −0
  14. net/mac80211/aes_ccm.h +31 −11
  15. net/mac80211/aes_gcm.c +0 −109
  16. net/mac80211/aes_gcm.h +30 −8
  17. net/mac80211/agg-rx.c +2 −2
  18. net/mac80211/ht.c +7 −5
  19. net/mac80211/ieee80211_i.h +2 −0
  20. net/mac80211/iface.c +6 −23
  21. net/mac80211/mesh.c +1 −2
  22. net/mac80211/mesh.h +1 −0
  23. net/mac80211/mesh_hwmp.c +4 −4
  24. net/mac80211/mesh_plink.c +5 −8
  25. net/mac80211/mlme.c +7 −12
  26. net/mac80211/scan.c +28 −9
  27. net/mac80211/sta_info.c +35 −26
  28. net/mac80211/sta_info.h +3 −1
  29. net/mac80211/tx.c +34 −0
  30. net/mac80211/util.c +11 −14
  31. net/mac80211/vht.c +10 −0
  32. net/mac80211/wpa.c +2 −2
  33. net/wireless/.gitignore +2 −1
  34. net/wireless/Kconfig +34 −24
  35. net/wireless/Makefile +20 −4
  36. net/wireless/certs/sforshee.x509 +0 −0
  37. net/wireless/core.c +1 −1
  38. net/wireless/core.h +5 −0
  39. net/wireless/db.txt +0 −17
  40. net/wireless/genregdb.awk +0 −158
  41. net/wireless/nl80211.c +136 −63
  42. net/wireless/nl80211.h +2 −0
  43. net/wireless/reg.c +411 −41
  44. net/wireless/reg.h +14 −0
  45. net/wireless/regdb.h +0 −23
  46. net/wireless/sme.c +44 −1
  47. net/wireless/util.c +63 −139
Documentation/driver-api/80211/cfg80211.rst+0−3
@@ -299,9 +299,6 @@ Data path helpers · 298 unmodified lines
299.. kernel-doc:: include/net/cfg80211.h299.. kernel-doc:: include/net/cfg80211.h
300 :functions: ieee80211_data_to_8023300 :functions: ieee80211_data_to_8023
301 301
302.. kernel-doc:: include/net/cfg80211.h
303 :functions: ieee80211_data_from_8023
304
305.. kernel-doc:: include/net/cfg80211.h302.. kernel-doc:: include/net/cfg80211.h
306 :functions: ieee80211_amsdu_to_8023s303 :functions: ieee80211_amsdu_to_8023s
307 304
Documentation/networking/regulatory.txt+10−20
@@ -19,6 +19,14 @@ core regulatory domain all wireless devices should adhere to. · 18 unmodified lines
19How to get regulatory domains to the kernel19How to get regulatory domains to the kernel
20-------------------------------------------20-------------------------------------------
21 21
22When the regulatory domain is first set up, the kernel will request a
23database file (regulatory.db) containing all the regulatory rules. It
24will then use that database when it needs to look up the rules for a
25given country.
26
27How to get regulatory domains to the kernel (old CRDA solution)
28---------------------------------------------------------------
29
22Userspace gets a regulatory domain in the kernel by having30Userspace gets a regulatory domain in the kernel by having
23a userspace agent build it and send it via nl80211. Only31a userspace agent build it and send it via nl80211. Only
24expected regulatory domains will be respected by the kernel.32expected regulatory domains will be respected by the kernel.
@@ -192,23 +200,5 @@ Then in some part of your code after your wiphy has been registered: · 167 unmodified lines
192Statically compiled regulatory database200Statically compiled regulatory database
193---------------------------------------201---------------------------------------
194 202
195In most situations the userland solution using CRDA as described203When a database should be fixed into the kernel, it can be provided as a
196above is the preferred solution. However in some cases a set of204firmware file at build time that is then linked into the kernel.
197rules built into the kernel itself may be desirable. To account
198for this situation, a configuration option has been provided
199(i.e. CONFIG_CFG80211_INTERNAL_REGDB). With this option enabled,
200the wireless database information contained in net/wireless/db.txt is
201used to generate a data structure encoded in net/wireless/regdb.c.
202That option also enables code in net/wireless/reg.c which queries
203the data in regdb.c as an alternative to using CRDA.
204
205The file net/wireless/db.txt should be kept up-to-date with the db.txt
206file available in the git repository here:
207
208 git://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git
209
210Again, most users in most situations should be using the CRDA package
211provided with their distribution, and in most other situations users
212should be building and using CRDA on their own rather than using
213this option. If you are not absolutely sure that you should be using
214CONFIG_CFG80211_INTERNAL_REGDB then _DO_NOT_USE_IT_.
MAINTAINERS+10−3
@@ -3329,17 +3329,22 @@ S: Maintained · 3328 unmodified lines
3329F: drivers/auxdisplay/cfag12864bfb.c3329F: drivers/auxdisplay/cfag12864bfb.c
3330F: include/linux/cfag12864b.h3330F: include/linux/cfag12864b.h
3331 3331
3332CFG80211 and NL802113332802.11 (including CFG80211/NL80211)
3333M: Johannes Berg <johannes@sipsolutions.net>3333M: Johannes Berg <johannes@sipsolutions.net>
3334L: linux-wireless@vger.kernel.org3334L: linux-wireless@vger.kernel.org
3335W: http://wireless.kernel.org/3335W: http://wireless.kernel.org/
3336T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git3336T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
3337T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git3337T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
3338S: Maintained3338S: Maintained
3339F: net/wireless/
3339F: include/uapi/linux/nl80211.h3340F: include/uapi/linux/nl80211.h
3341F: include/linux/ieee80211.h
3342F: include/net/wext.h
3340F: include/net/cfg80211.h3343F: include/net/cfg80211.h
3341F: net/wireless/*3344F: include/net/iw_handler.h
3342X: net/wireless/wext*3345F: include/net/ieee80211_radiotap.h
3346F: Documentation/driver-api/80211/cfg80211.rst
3347F: Documentation/networking/regulatory.txt
3343 3348
3344CHAR and MISC DRIVERS3349CHAR and MISC DRIVERS
3345M: Arnd Bergmann <arnd@arndb.de>3350M: Arnd Bergmann <arnd@arndb.de>
@@ -8208,6 +8213,7 @@ F: Documentation/networking/mac80211-injection.txt · 4862 unmodified lines
8208F: include/net/mac80211.h8213F: include/net/mac80211.h
8209F: net/mac80211/8214F: net/mac80211/
8210F: drivers/net/wireless/mac80211_hwsim.[ch]8215F: drivers/net/wireless/mac80211_hwsim.[ch]
8216F: Documentation/networking/mac80211_hwsim/README
8211 8217
8212MAILBOX API8218MAILBOX API
8213M: Jassi Brar <jassisinghbrar@gmail.com>8219M: Jassi Brar <jassisinghbrar@gmail.com>
@@ -11492,6 +11498,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git · 3278 unmodified lines
11492T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git11498T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
11493S: Maintained11499S: Maintained
11494F: Documentation/rfkill.txt11500F: Documentation/rfkill.txt
11501F: Documentation/ABI/stable/sysfs-class-rfkill
11495F: net/rfkill/11502F: net/rfkill/
11496 11503
11497RHASHTABLE11504RHASHTABLE
drivers/net/wireless/mac80211_hwsim.c+96−96
@@ -396,7 +396,7 @@ static int mac80211_hwsim_vendor_cmd_test(struct wiphy *wiphy, · 395 unmodified lines
396 if (!tb[QCA_WLAN_VENDOR_ATTR_TEST])396 if (!tb[QCA_WLAN_VENDOR_ATTR_TEST])
397 return -EINVAL;397 return -EINVAL;
398 val = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_TEST]);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 /* Send a vendor event as a test. Note that this would not normally be401 /* Send a vendor event as a test. Note that this would not normally be
402 * done within a command handler, but rather, based on some other402 * done within a command handler, but rather, based on some other
@@ -643,9 +643,9 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif) · 240 unmodified lines
643 if (!vp->assoc)643 if (!vp->assoc)
644 return;644 return;
645 645
646 wiphy_debug(data->hw->wiphy,646 wiphy_dbg(data->hw->wiphy,
647 "%s: send PS-Poll to %pM for aid %d\n",647 "%s: send PS-Poll to %pM for aid %d\n",
648 __func__, vp->bssid, vp->aid);648 __func__, vp->bssid, vp->aid);
649 649
650 skb = dev_alloc_skb(sizeof(*pspoll));650 skb = dev_alloc_skb(sizeof(*pspoll));
651 if (!skb)651 if (!skb)
@@ -674,9 +674,9 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, · 22 unmodified lines
674 if (!vp->assoc)674 if (!vp->assoc)
675 return;675 return;
676 676
677 wiphy_debug(data->hw->wiphy,677 wiphy_dbg(data->hw->wiphy,
678 "%s: send data::nullfunc to %pM ps=%d\n",678 "%s: send data::nullfunc to %pM ps=%d\n",
679 __func__, vp->bssid, ps);679 __func__, vp->bssid, ps);
680 680
681 skb = dev_alloc_skb(sizeof(*hdr));681 skb = dev_alloc_skb(sizeof(*hdr));
682 if (!skb)682 if (!skb)
@@ -1034,7 +1034,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, · 351 unmodified lines
1034 msg_head = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0,1034 msg_head = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0,
1035 HWSIM_CMD_FRAME);1035 HWSIM_CMD_FRAME);
1036 if (msg_head == NULL) {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 goto nla_put_failure;1038 goto nla_put_failure;
1039 }1039 }
1040 1040
@@ -1093,7 +1093,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, · 52 unmodified lines
1093nla_put_failure:1093nla_put_failure:
1094 nlmsg_free(skb);1094 nlmsg_free(skb);
1095err_free_txskb:1095err_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 ieee80211_free_txskb(hw, my_skb);1097 ieee80211_free_txskb(hw, my_skb);
1098 data->tx_failed++;1098 data->tx_failed++;
1099}1099}
@@ -1347,7 +1347,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, · 247 unmodified lines
1347 }1347 }
1348 1348
1349 if (data->idle && !data->tmp_chan) {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 ieee80211_free_txskb(hw, skb);1351 ieee80211_free_txskb(hw, skb);
1352 return;1352 return;
1353 }1353 }
@@ -1408,7 +1408,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, · 54 unmodified lines
1408static int mac80211_hwsim_start(struct ieee80211_hw *hw)1408static int mac80211_hwsim_start(struct ieee80211_hw *hw)
1409{1409{
1410 struct mac80211_hwsim_data *data = hw->priv;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 data->started = true;1412 data->started = true;
1413 return 0;1413 return 0;
1414}1414}
@@ -1419,16 +1419,16 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw) · 4 unmodified lines
1419 struct mac80211_hwsim_data *data = hw->priv;1419 struct mac80211_hwsim_data *data = hw->priv;
1420 data->started = false;1420 data->started = false;
1421 tasklet_hrtimer_cancel(&data->beacon_timer);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
1426static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,1426static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
1427 struct ieee80211_vif *vif)1427 struct ieee80211_vif *vif)
1428{1428{
1429 wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n",1429 wiphy_dbg(hw->wiphy, "%s (type=%d mac_addr=%pM)\n",
1430 __func__, ieee80211_vif_type_p2p(vif),1430 __func__, ieee80211_vif_type_p2p(vif),
1431 vif->addr);1431 vif->addr);
1432 hwsim_set_magic(vif);1432 hwsim_set_magic(vif);
1433 1433
1434 vif->cab_queue = 0;1434 vif->cab_queue = 0;
@@ -1447,9 +1447,9 @@ static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw, · 12 unmodified lines
1447 bool newp2p)1447 bool newp2p)
1448{1448{
1449 newtype = ieee80211_iftype_p2p(newtype, newp2p);1449 newtype = ieee80211_iftype_p2p(newtype, newp2p);
1450 wiphy_debug(hw->wiphy,1450 wiphy_dbg(hw->wiphy,
1451 "%s (old type=%d, new type=%d, mac_addr=%pM)\n",1451 "%s (old type=%d, new type=%d, mac_addr=%pM)\n",
1452 __func__, ieee80211_vif_type_p2p(vif),1452 __func__, ieee80211_vif_type_p2p(vif),
1453 newtype, vif->addr);1453 newtype, vif->addr);
1454 hwsim_check_magic(vif);1454 hwsim_check_magic(vif);
1455 1455
@@ -1465,9 +1465,9 @@ static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw, · 9 unmodified lines
1465static void mac80211_hwsim_remove_interface(1465static void mac80211_hwsim_remove_interface(
1466 struct ieee80211_hw *hw, struct ieee80211_vif *vif)1466 struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1467{1467{
1468 wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n",1468 wiphy_dbg(hw->wiphy, "%s (type=%d mac_addr=%pM)\n",
1469 __func__, ieee80211_vif_type_p2p(vif),1469 __func__, ieee80211_vif_type_p2p(vif),
1470 vif->addr);1470 vif->addr);
1471 hwsim_check_magic(vif);1471 hwsim_check_magic(vif);
1472 hwsim_clear_magic(vif);1472 hwsim_clear_magic(vif);
1473}1473}
@@ -1589,23 +1589,23 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) · 115 unmodified lines
1589 int idx;1589 int idx;
1590 1590
1591 if (conf->chandef.chan)1591 if (conf->chandef.chan)
1592 wiphy_debug(hw->wiphy,1592 wiphy_dbg(hw->wiphy,
1593 "%s (freq=%d(%d - %d)/%s idle=%d ps=%d smps=%s)\n",1593 "%s (freq=%d(%d - %d)/%s idle=%d ps=%d smps=%s)\n",
1594 __func__,1594 __func__,
1595 conf->chandef.chan->center_freq,1595 conf->chandef.chan->center_freq,
1596 conf->chandef.center_freq1,1596 conf->chandef.center_freq1,
1597 conf->chandef.center_freq2,1597 conf->chandef.center_freq2,
1598 hwsim_chanwidths[conf->chandef.width],1598 hwsim_chanwidths[conf->chandef.width],
1599 !!(conf->flags & IEEE80211_CONF_IDLE),1599 !!(conf->flags & IEEE80211_CONF_IDLE),
1600 !!(conf->flags & IEEE80211_CONF_PS),1600 !!(conf->flags & IEEE80211_CONF_PS),
1601 smps_modes[conf->smps_mode]);1601 smps_modes[conf->smps_mode]);
1602 else1602 else
1603 wiphy_debug(hw->wiphy,1603 wiphy_dbg(hw->wiphy,
1604 "%s (freq=0 idle=%d ps=%d smps=%s)\n",1604 "%s (freq=0 idle=%d ps=%d smps=%s)\n",
1605 __func__,1605 __func__,
1606 !!(conf->flags & IEEE80211_CONF_IDLE),1606 !!(conf->flags & IEEE80211_CONF_IDLE),
1607 !!(conf->flags & IEEE80211_CONF_PS),1607 !!(conf->flags & IEEE80211_CONF_PS),
1608 smps_modes[conf->smps_mode]);1608 smps_modes[conf->smps_mode]);
1609 1609
1610 data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);1610 data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1611 1611
@@ -1659,7 +1659,7 @@ static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw, · 47 unmodified lines
1659{1659{
1660 struct mac80211_hwsim_data *data = hw->priv;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 data->rx_filter = 0;1664 data->rx_filter = 0;
1665 if (*total_flags & FIF_ALLMULTI)1665 if (*total_flags & FIF_ALLMULTI)
@@ -1688,25 +1688,25 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, · 22 unmodified lines
1688 1688
1689 hwsim_check_magic(vif);1689 hwsim_check_magic(vif);
1690 1690
1691 wiphy_debug(hw->wiphy, "%s(changed=0x%x vif->addr=%pM)\n",1691 wiphy_dbg(hw->wiphy, "%s(changed=0x%x vif->addr=%pM)\n",
1692 __func__, changed, vif->addr);1692 __func__, changed, vif->addr);
1693 1693
1694 if (changed & BSS_CHANGED_BSSID) {1694 if (changed & BSS_CHANGED_BSSID) {
1695 wiphy_debug(hw->wiphy, "%s: BSSID changed: %pM\n",1695 wiphy_dbg(hw->wiphy, "%s: BSSID changed: %pM\n",
1696 __func__, info->bssid);1696 __func__, info->bssid);
1697 memcpy(vp->bssid, info->bssid, ETH_ALEN);1697 memcpy(vp->bssid, info->bssid, ETH_ALEN);
1698 }1698 }
1699 1699
1700 if (changed & BSS_CHANGED_ASSOC) {1700 if (changed & BSS_CHANGED_ASSOC) {
1701 wiphy_debug(hw->wiphy, " ASSOC: assoc=%d aid=%d\n",1701 wiphy_dbg(hw->wiphy, " ASSOC: assoc=%d aid=%d\n",
1702 info->assoc, info->aid);1702 info->assoc, info->aid);
1703 vp->assoc = info->assoc;1703 vp->assoc = info->assoc;
1704 vp->aid = info->aid;1704 vp->aid = info->aid;
1705 }1705 }
1706 1706
1707 if (changed & BSS_CHANGED_BEACON_ENABLED) {1707 if (changed & BSS_CHANGED_BEACON_ENABLED) {
1708 wiphy_debug(hw->wiphy, " BCN EN: %d (BI=%u)\n",1708 wiphy_dbg(hw->wiphy, " BCN EN: %d (BI=%u)\n",
1709 info->enable_beacon, info->beacon_int);1709 info->enable_beacon, info->beacon_int);
1710 vp->bcn_en = info->enable_beacon;1710 vp->bcn_en = info->enable_beacon;
1711 if (data->started &&1711 if (data->started &&
1712 !hrtimer_is_queued(&data->beacon_timer.timer) &&1712 !hrtimer_is_queued(&data->beacon_timer.timer) &&
@@ -1725,8 +1725,8 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, · 12 unmodified lines
1725 ieee80211_iterate_active_interfaces_atomic(1725 ieee80211_iterate_active_interfaces_atomic(
1726 data->hw, IEEE80211_IFACE_ITER_NORMAL,1726 data->hw, IEEE80211_IFACE_ITER_NORMAL,
1727 mac80211_hwsim_bcn_en_iter, &count);1727 mac80211_hwsim_bcn_en_iter, &count);
1728 wiphy_debug(hw->wiphy, " beaconing vifs remaining: %u",1728 wiphy_dbg(hw->wiphy, " beaconing vifs remaining: %u",
1729 count);1729 count);
1730 if (count == 0) {1730 if (count == 0) {
1731 tasklet_hrtimer_cancel(&data->beacon_timer);1731 tasklet_hrtimer_cancel(&data->beacon_timer);
1732 data->beacon_int = 0;1732 data->beacon_int = 0;
@@ -1735,31 +1735,31 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, · 2 unmodified lines
1735 }1735 }
1736 1736
1737 if (changed & BSS_CHANGED_ERP_CTS_PROT) {1737 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
1738 wiphy_debug(hw->wiphy, " ERP_CTS_PROT: %d\n",1738 wiphy_dbg(hw->wiphy, " ERP_CTS_PROT: %d\n",
1739 info->use_cts_prot);1739 info->use_cts_prot);
1740 }1740 }
1741 1741
1742 if (changed & BSS_CHANGED_ERP_PREAMBLE) {1742 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
1743 wiphy_debug(hw->wiphy, " ERP_PREAMBLE: %d\n",1743 wiphy_dbg(hw->wiphy, " ERP_PREAMBLE: %d\n",
1744 info->use_short_preamble);1744 info->use_short_preamble);
1745 }1745 }
1746 1746
1747 if (changed & BSS_CHANGED_ERP_SLOT) {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 if (changed & BSS_CHANGED_HT) {1751 if (changed & BSS_CHANGED_HT) {
1752 wiphy_debug(hw->wiphy, " HT: op_mode=0x%x\n",1752 wiphy_dbg(hw->wiphy, " HT: op_mode=0x%x\n",
1753 info->ht_operation_mode);1753 info->ht_operation_mode);
1754 }1754 }
1755 1755
1756 if (changed & BSS_CHANGED_BASIC_RATES) {1756 if (changed & BSS_CHANGED_BASIC_RATES) {
1757 wiphy_debug(hw->wiphy, " BASIC_RATES: 0x%llx\n",1757 wiphy_dbg(hw->wiphy, " BASIC_RATES: 0x%llx\n",
1758 (unsigned long long) info->basic_rates);1758 (unsigned long long) info->basic_rates);
1759 }1759 }
1760 1760
1761 if (changed & BSS_CHANGED_TXPOWER)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
1765static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw,1765static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw,
@@ -1813,11 +1813,11 @@ static int mac80211_hwsim_conf_tx( · 47 unmodified lines
1813 struct ieee80211_vif *vif, u16 queue,1813 struct ieee80211_vif *vif, u16 queue,
1814 const struct ieee80211_tx_queue_params *params)1814 const struct ieee80211_tx_queue_params *params)
1815{1815{
1816 wiphy_debug(hw->wiphy,1816 wiphy_dbg(hw->wiphy,
1817 "%s (queue=%d txop=%d cw_min=%d cw_max=%d aifs=%d)\n",1817 "%s (queue=%d txop=%d cw_min=%d cw_max=%d aifs=%d)\n",
1818 __func__, queue,1818 __func__, queue,
1819 params->txop, params->cw_min,1819 params->txop, params->cw_min,
1820 params->cw_max, params->aifs);1820 params->cw_max, params->aifs);
1821 return 0;1821 return 0;
1822}1822}
1823 1823
@@ -1981,7 +1981,7 @@ static void hw_scan_work(struct work_struct *work) · 157 unmodified lines
1981 .aborted = false,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 ieee80211_scan_completed(hwsim->hw, &info);1985 ieee80211_scan_completed(hwsim->hw, &info);
1986 hwsim->hw_scan_request = NULL;1986 hwsim->hw_scan_request = NULL;
1987 hwsim->hw_scan_vif = NULL;1987 hwsim->hw_scan_vif = NULL;
@@ -1990,8 +1990,8 @@ static void hw_scan_work(struct work_struct *work) · 2 unmodified lines
1990 return;1990 return;
1991 }1991 }
1992 1992
1993 wiphy_debug(hwsim->hw->wiphy, "hw scan %d MHz\n",1993 wiphy_dbg(hwsim->hw->wiphy, "hw scan %d MHz\n",
1994 req->channels[hwsim->scan_chan_idx]->center_freq);1994 req->channels[hwsim->scan_chan_idx]->center_freq);
1995 1995
1996 hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx];1996 hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx];
1997 if (hwsim->tmp_chan->flags & (IEEE80211_CHAN_NO_IR |1997 if (hwsim->tmp_chan->flags & (IEEE80211_CHAN_NO_IR |
@@ -2060,7 +2060,7 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, · 62 unmodified lines
2060 memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));2060 memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
2061 mutex_unlock(&hwsim->mutex);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 ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, 0);2065 ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, 0);
2066 2066
@@ -2075,7 +2075,7 @@ static void mac80211_hwsim_cancel_hw_scan(struct ieee80211_hw *hw, · 8 unmodified lines
2075 .aborted = true,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 cancel_delayed_work_sync(&hwsim->hw_scan);2080 cancel_delayed_work_sync(&hwsim->hw_scan);
2081 2081
@@ -2096,11 +2096,11 @@ static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw, · 14 unmodified lines
2096 mutex_lock(&hwsim->mutex);2096 mutex_lock(&hwsim->mutex);
2097 2097
2098 if (hwsim->scanning) {2098 if (hwsim->scanning) {
2099 printk(KERN_DEBUG "two hwsim sw_scans detected!\n");2099 pr_debug("two hwsim sw_scans detected!\n");
2100 goto out;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 memcpy(hwsim->scan_addr, mac_addr, ETH_ALEN);2105 memcpy(hwsim->scan_addr, mac_addr, ETH_ALEN);
2106 hwsim->scanning = true;2106 hwsim->scanning = true;
@@ -2117,7 +2117,7 @@ static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw, · 10 unmodified lines
2117 2117
2118 mutex_lock(&hwsim->mutex);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 hwsim->scanning = false;2121 hwsim->scanning = false;
2122 eth_zero_addr(hwsim->scan_addr);2122 eth_zero_addr(hwsim->scan_addr);
2123 2123
@@ -2131,7 +2131,7 @@ static void hw_roc_start(struct work_struct *work) · 7 unmodified lines
2131 2131
2132 mutex_lock(&hwsim->mutex);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 hwsim->tmp_chan = hwsim->roc_chan;2135 hwsim->tmp_chan = hwsim->roc_chan;
2136 ieee80211_ready_on_channel(hwsim->hw);2136 ieee80211_ready_on_channel(hwsim->hw);
2137 2137
@@ -2151,7 +2151,7 @@ static void hw_roc_done(struct work_struct *work) · 13 unmodified lines
2151 hwsim->tmp_chan = NULL;2151 hwsim->tmp_chan = NULL;
2152 mutex_unlock(&hwsim->mutex);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
2157static int mac80211_hwsim_roc(struct ieee80211_hw *hw,2157static int mac80211_hwsim_roc(struct ieee80211_hw *hw,
@@ -2172,8 +2172,8 @@ static int mac80211_hwsim_roc(struct ieee80211_hw *hw, · 14 unmodified lines
2172 hwsim->roc_duration = duration;2172 hwsim->roc_duration = duration;
2173 mutex_unlock(&hwsim->mutex);2173 mutex_unlock(&hwsim->mutex);
2174 2174
2175 wiphy_debug(hw->wiphy, "hwsim ROC (%d MHz, %d ms)\n",2175 wiphy_dbg(hw->wiphy, "hwsim ROC (%d MHz, %d ms)\n",
2176 chan->center_freq, duration);2176 chan->center_freq, duration);
2177 ieee80211_queue_delayed_work(hw, &hwsim->roc_start, HZ/50);2177 ieee80211_queue_delayed_work(hw, &hwsim->roc_start, HZ/50);
2178 2178
2179 return 0;2179 return 0;
@@ -2190,7 +2190,7 @@ static int mac80211_hwsim_croc(struct ieee80211_hw *hw) · 10 unmodified lines
2190 hwsim->tmp_chan = NULL;2190 hwsim->tmp_chan = NULL;
2191 mutex_unlock(&hwsim->mutex);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 return 0;2195 return 0;
2196}2196}
@@ -2199,20 +2199,20 @@ static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw, · 2 unmodified lines
2199 struct ieee80211_chanctx_conf *ctx)2199 struct ieee80211_chanctx_conf *ctx)
2200{2200{
2201 hwsim_set_chanctx_magic(ctx);2201 hwsim_set_chanctx_magic(ctx);
2202 wiphy_debug(hw->wiphy,2202 wiphy_dbg(hw->wiphy,
2203 "add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",2203 "add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
2204 ctx->def.chan->center_freq, ctx->def.width,2204 ctx->def.chan->center_freq, ctx->def.width,
2205 ctx->def.center_freq1, ctx->def.center_freq2);2205 ctx->def.center_freq1, ctx->def.center_freq2);
2206 return 0;2206 return 0;
2207}2207}
2208 2208
2209static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw,2209static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw,
2210 struct ieee80211_chanctx_conf *ctx)2210 struct ieee80211_chanctx_conf *ctx)
2211{2211{
2212 wiphy_debug(hw->wiphy,2212 wiphy_dbg(hw->wiphy,
2213 "remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",2213 "remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
2214 ctx->def.chan->center_freq, ctx->def.width,2214 ctx->def.chan->center_freq, ctx->def.width,
2215 ctx->def.center_freq1, ctx->def.center_freq2);2215 ctx->def.center_freq1, ctx->def.center_freq2);
2216 hwsim_check_chanctx_magic(ctx);2216 hwsim_check_chanctx_magic(ctx);
2217 hwsim_clear_chanctx_magic(ctx);2217 hwsim_clear_chanctx_magic(ctx);
2218}2218}
@@ -2222,10 +2222,10 @@ static void mac80211_hwsim_change_chanctx(struct ieee80211_hw *hw, · 3 unmodified lines
2222 u32 changed)2222 u32 changed)
2223{2223{
2224 hwsim_check_chanctx_magic(ctx);2224 hwsim_check_chanctx_magic(ctx);
2225 wiphy_debug(hw->wiphy,2225 wiphy_dbg(hw->wiphy,
2226 "change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",2226 "change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
2227 ctx->def.chan->center_freq, ctx->def.width,2227 ctx->def.chan->center_freq, ctx->def.width,
2228 ctx->def.center_freq1, ctx->def.center_freq2);2228 ctx->def.center_freq1, ctx->def.center_freq2);
2229}2229}
2230 2230
2231static int mac80211_hwsim_assign_vif_chanctx(struct ieee80211_hw *hw,2231static int mac80211_hwsim_assign_vif_chanctx(struct ieee80211_hw *hw,
@@ -2479,7 +2479,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, · 247 unmodified lines
2479 ops = &mac80211_hwsim_mchan_ops;2479 ops = &mac80211_hwsim_mchan_ops;
2480 hw = ieee80211_alloc_hw_nm(sizeof(*data), ops, param->hwname);2480 hw = ieee80211_alloc_hw_nm(sizeof(*data), ops, param->hwname);
2481 if (!hw) {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 err = -ENOMEM;2483 err = -ENOMEM;
2484 goto failed;2484 goto failed;
2485 }2485 }
@@ -2507,7 +2507,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, · 21 unmodified lines
2507 data->dev->driver = &mac80211_hwsim_driver.driver;2507 data->dev->driver = &mac80211_hwsim_driver.driver;
2508 err = device_bind_driver(data->dev);2508 err = device_bind_driver(data->dev);
2509 if (err != 0) {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 err);2511 err);
2512 goto failed_bind;2512 goto failed_bind;
2513 }2513 }
@@ -2698,12 +2698,12 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, · 184 unmodified lines
2698 2698
2699 err = ieee80211_register_hw(hw);2699 err = ieee80211_register_hw(hw);
2700 if (err < 0) {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 err);2702 err);
2703 goto failed_hw;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 if (param->reg_alpha2) {2708 if (param->reg_alpha2) {
2709 data->alpha2[0] = param->reg_alpha2[0];2709 data->alpha2[0] = param->reg_alpha2[0];
@@ -3067,7 +3067,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, · 357 unmodified lines
3067 3067
3068 return 0;3068 return 0;
3069err:3069err:
3070 printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__);3070 pr_debug("mac80211_hwsim: error occurred in %s\n", __func__);
3071out:3071out:
3072 dev_kfree_skb(skb);3072 dev_kfree_skb(skb);
3073 return -EINVAL;3073 return -EINVAL;
@@ -3098,7 +3098,7 @@ static int hwsim_register_received_nl(struct sk_buff *skb_2, · 24 unmodified lines
3098 3098
3099 hwsim_register_wmediumd(net, info->snd_portid);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 "switching to wmediumd mode with pid %d\n", info->snd_portid);3102 "switching to wmediumd mode with pid %d\n", info->snd_portid);
3103 3103
3104 return 0;3104 return 0;
@@ -3387,7 +3387,7 @@ static int __init hwsim_init_netlink(void) · 282 unmodified lines
3387 return 0;3387 return 0;
3388 3388
3389failure:3389failure:
3390 printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__);3390 pr_debug("mac80211_hwsim: error occurred in %s\n", __func__);
3391 return -EINVAL;3391 return -EINVAL;
3392}3392}
3393 3393
@@ -3578,7 +3578,7 @@ module_init(init_mac80211_hwsim); · 184 unmodified lines
3578 3578
3579static void __exit exit_mac80211_hwsim(void)3579static 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 hwsim_exit_netlink();3583 hwsim_exit_netlink();
3584 3584
include/linux/ieee80211.h+1−0
@@ -2445,6 +2445,7 @@ enum ieee80211_sa_query_action { · 2444 unmodified lines
2445#define WLAN_OUI_TYPE_MICROSOFT_WPA 12445#define WLAN_OUI_TYPE_MICROSOFT_WPA 1
2446#define WLAN_OUI_TYPE_MICROSOFT_WMM 22446#define WLAN_OUI_TYPE_MICROSOFT_WMM 2
2447#define WLAN_OUI_TYPE_MICROSOFT_WPS 42447#define WLAN_OUI_TYPE_MICROSOFT_WPS 4
2448#define WLAN_OUI_TYPE_MICROSOFT_TPC 8
2448 2449
2449/*2450/*
2450 * WMM/802.11e Tspec Element2451 * WMM/802.11e Tspec Element
include/net/cfg80211.h+21−19
@@ -4346,19 +4346,6 @@ static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, · 4345 unmodified lines
4346 return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype);4346 return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype);
4347}4347}
4348 4348
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 */
4358int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
4359 enum nl80211_iftype iftype, const u8 *bssid,
4360 bool qos);
4361
4362/**4349/**
4363 * ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame4350 * ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame
4364 *4351 *
@@ -5441,9 +5428,6 @@ cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid, · 1076 unmodified lines
5441 * @req_ie_len: association request IEs length5428 * @req_ie_len: association request IEs length
5442 * @resp_ie: association response IEs (may be %NULL)5429 * @resp_ie: association response IEs (may be %NULL)
5443 * @resp_ie_len: assoc response IEs length5430 * @resp_ie_len: assoc response IEs length
5444 * @authorized: true if the 802.1X authentication was done by the driver or is
5445 * not needed (e.g., when Fast Transition protocol was used), false
5446 * otherwise. Ignored for networks that don't use 802.1X authentication.
5447 */5431 */
5448struct cfg80211_roam_info {5432struct cfg80211_roam_info {
5449 struct ieee80211_channel *channel;5433 struct ieee80211_channel *channel;
@@ -5453,7 +5437,6 @@ struct cfg80211_roam_info { · 3 unmodified lines
5453 size_t req_ie_len;5437 size_t req_ie_len;
5454 const u8 *resp_ie;5438 const u8 *resp_ie;
5455 size_t resp_ie_len;5439 size_t resp_ie_len;
5456 bool authorized;
5457};5440};
5458 5441
5459/**5442/**
@@ -5477,6 +5460,23 @@ struct cfg80211_roam_info { · 17 unmodified lines
5477void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info,5460void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info,
5478 gfp_t gfp);5461 gfp_t gfp);
5479 5462
5463/**
5464 * cfg80211_port_authorized - notify cfg80211 of successful security association
5465 *
5466 * @dev: network device
5467 * @bssid: the BSSID of the AP
5468 * @gfp: allocation flags
5469 *
5470 * This function should be called by a driver that supports 4 way handshake
5471 * offload after a security association was successfully established (i.e.,
5472 * the 4 way handshake was completed successfully). The call to this function
5473 * should be preceded with a call to cfg80211_connect_result(),
5474 * cfg80211_connect_done(), cfg80211_connect_bss() or cfg80211_roamed() to
5475 * indicate the 802.11 association.
5476 */
5477void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid,
5478 gfp_t gfp);
5479
5480/**5480/**
5481 * cfg80211_disconnected - notify cfg80211 that connection was dropped5481 * cfg80211_disconnected - notify cfg80211 that connection was dropped
5482 *5482 *
@@ -5934,7 +5934,8 @@ int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len, · 451 unmodified lines
5934 * @ies: the IE buffer5934 * @ies: the IE buffer
5935 * @ielen: the length of the IE buffer5935 * @ielen: the length of the IE buffer
5936 * @ids: an array with element IDs that are allowed before5936 * @ids: an array with element IDs that are allowed before
5937 * the split5937 * 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 * @n_ids: the size of the element ID array5939 * @n_ids: the size of the element ID array
5939 * @after_ric: array IE types that come after the RIC element5940 * @after_ric: array IE types that come after the RIC element
5940 * @n_after_ric: size of the @after_ric array5941 * @n_after_ric: size of the @after_ric array
@@ -5965,7 +5966,8 @@ size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen, · 24 unmodified lines
5965 * @ies: the IE buffer5966 * @ies: the IE buffer
5966 * @ielen: the length of the IE buffer5967 * @ielen: the length of the IE buffer
5967 * @ids: an array with element IDs that are allowed before5968 * @ids: an array with element IDs that are allowed before
5968 * the split5969 * the split. A WLAN_EID_EXTENSION value means that the next
5970 * EID in the list is a sub-element of the EXTENSION IE.
5969 * @n_ids: the size of the element ID array5971 * @n_ids: the size of the element ID array
5970 * @offset: offset where to start splitting in the buffer5972 * @offset: offset where to start splitting in the buffer
5971 *5973 *
include/net/fq.h+7−0
@@ -90,6 +90,13 @@ typedef void fq_skb_free_t(struct fq *, · 89 unmodified lines
90 struct fq_flow *,90 struct fq_flow *,
91 struct sk_buff *);91 struct sk_buff *);
92 92
93/* Return %true to filter (drop) the frame. */
94typedef bool fq_skb_filter_t(struct fq *,
95 struct fq_tin *,
96 struct fq_flow *,
97 struct sk_buff *,
98 void *);
99
93typedef struct fq_flow *fq_flow_get_default_t(struct fq *,100typedef struct fq_flow *fq_flow_get_default_t(struct fq *,
94 struct fq_tin *,101 struct fq_tin *,
95 int idx,102 int idx,
include/net/fq_impl.h+62−10
@@ -12,24 +12,22 @@ · 11 unmodified lines
12 12
13/* functions that are embedded into includer */13/* functions that are embedded into includer */
14 14
15static struct sk_buff *fq_flow_dequeue(struct fq *fq,15static void fq_adjust_removal(struct fq *fq,
16 struct fq_flow *flow)16 struct fq_flow *flow,
17 struct sk_buff *skb)
17{18{
18 struct fq_tin *tin = flow->tin;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 tin->backlog_bytes -= skb->len;21 tin->backlog_bytes -= skb->len;
29 tin->backlog_packets--;22 tin->backlog_packets--;
30 flow->backlog -= skb->len;23 flow->backlog -= skb->len;
31 fq->backlog--;24 fq->backlog--;
32 fq->memory_usage -= skb->truesize;25 fq->memory_usage -= skb->truesize;
26}
27
28static void fq_rejigger_backlog(struct fq *fq, struct fq_flow *flow)
29{
30 struct fq_flow *i;
33 31
34 if (flow->backlog == 0) {32 if (flow->backlog == 0) {
35 list_del_init(&flow->backlogchain);33 list_del_init(&flow->backlogchain);
@@ -43,6 +41,21 @@ static struct sk_buff *fq_flow_dequeue(struct fq *fq, · 7 unmodified lines
43 list_move_tail(&flow->backlogchain,41 list_move_tail(&flow->backlogchain,
44 &i->backlogchain);42 &i->backlogchain);
45 }43 }
44}
45
46static struct sk_buff *fq_flow_dequeue(struct fq *fq,
47 struct fq_flow *flow)
48{
49 struct sk_buff *skb;
50
51 lockdep_assert_held(&fq->lock);
52
53 skb = __skb_dequeue(&flow->queue);
54 if (!skb)
55 return NULL;
56
57 fq_adjust_removal(fq, flow, skb);
58 fq_rejigger_backlog(fq, flow);
46 59
47 return skb;60 return skb;
48}61}
@@ -188,6 +201,45 @@ static void fq_tin_enqueue(struct fq *fq, · 139 unmodified lines
188 }201 }
189}202}
190 203
204static void fq_flow_filter(struct fq *fq,
205 struct fq_flow *flow,
206 fq_skb_filter_t filter_func,
207 void *filter_data,
208 fq_skb_free_t free_func)
209{
210 struct fq_tin *tin = flow->tin;
211 struct sk_buff *skb, *tmp;
212
213 lockdep_assert_held(&fq->lock);
214
215 skb_queue_walk_safe(&flow->queue, skb, tmp) {
216 if (!filter_func(fq, tin, flow, skb, filter_data))
217 continue;
218
219 __skb_unlink(skb, &flow->queue);
220 fq_adjust_removal(fq, flow, skb);
221 free_func(fq, tin, flow, skb);
222 }
223
224 fq_rejigger_backlog(fq, flow);
225}
226
227static void fq_tin_filter(struct fq *fq,
228 struct fq_tin *tin,
229 fq_skb_filter_t filter_func,
230 void *filter_data,
231 fq_skb_free_t free_func)
232{
233 struct fq_flow *flow;
234
235 lockdep_assert_held(&fq->lock);
236
237 list_for_each_entry(flow, &tin->new_flows, flowchain)
238 fq_flow_filter(fq, flow, filter_func, filter_data, free_func);
239 list_for_each_entry(flow, &tin->old_flows, flowchain)
240 fq_flow_filter(fq, flow, filter_func, filter_data, free_func);
241}
242
191static void fq_flow_reset(struct fq *fq,243static void fq_flow_reset(struct fq *fq,
192 struct fq_flow *flow,244 struct fq_flow *flow,
193 fq_skb_free_t free_func)245 fq_skb_free_t free_func)
include/net/mac80211.h+7−1
@@ -5441,8 +5441,14 @@ void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid, · 5440 unmodified lines
5441 */5441 */
5442void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn);5442void 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 */
5444void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif, const u8 *addr,5450void 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 * ieee80211_start_rx_ba_session_offl - start a Rx BA session5454 * ieee80211_start_rx_ba_session_offl - start a Rx BA session
include/uapi/linux/nl80211.h+65−17
@@ -569,13 +569,14 @@ · 568 unmodified lines
569 * authentication/association or not receiving a response from the AP.569 * authentication/association or not receiving a response from the AP.
570 * Non-zero %NL80211_ATTR_STATUS_CODE value is indicated in that case as570 * Non-zero %NL80211_ATTR_STATUS_CODE value is indicated in that case as
571 * well to remain backwards compatible.571 * well to remain backwards compatible.
572 * @NL80211_CMD_ROAM: notifcation indicating the card/driver roamed by itself.572 * When establishing a security association, drivers that support 4 way
573 * When the driver roamed in a network that requires 802.1X authentication,573 * handshake offload should send %NL80211_CMD_PORT_AUTHORIZED event when
574 * %NL80211_ATTR_PORT_AUTHORIZED should be set if the 802.1X authentication574 * the 4 way handshake is completed successfully.
575 * was done by the driver or if roaming was done using Fast Transition575 * @NL80211_CMD_ROAM: Notification indicating the card/driver roamed by itself.
576 * protocol (in which case 802.1X authentication is not needed). If576 * When a security association was established with the new AP (e.g. if
577 * %NL80211_ATTR_PORT_AUTHORIZED is not set, user space is responsible for577 * the FT protocol was used for roaming or the driver completed the 4 way
578 * the 802.1X authentication.578 * handshake), this event should be followed by an
579 * %NL80211_CMD_PORT_AUTHORIZED event.
579 * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify580 * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify
580 * userspace that a connection was dropped by the AP or due to other581 * userspace that a connection was dropped by the AP or due to other
581 * reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and582 * reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and
@@ -982,6 +983,14 @@ · 400 unmodified lines
982 * @NL80211_CMD_DEL_PMK: For offloaded 4-Way handshake, delete the previously983 * @NL80211_CMD_DEL_PMK: For offloaded 4-Way handshake, delete the previously
983 * configured PMK for the authenticator address identified by984 * configured PMK for the authenticator address identified by
984 * &NL80211_ATTR_MAC.985 * &NL80211_ATTR_MAC.
986 * @NL80211_CMD_PORT_AUTHORIZED: An event that indicates that the 4 way
987 * handshake was completed successfully by the driver. The BSSID is
988 * specified with &NL80211_ATTR_MAC. Drivers that support 4 way handshake
989 * offload should send this event after indicating 802.11 association with
990 * &NL80211_CMD_CONNECT or &NL80211_CMD_ROAM. If the 4 way handshake failed
991 * &NL80211_CMD_DISCONNECT should be indicated instead.
992 *
993 * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded.
985 *994 *
986 * @NL80211_CMD_MAX: highest used command number995 * @NL80211_CMD_MAX: highest used command number
987 * @__NL80211_CMD_AFTER_LAST: internal use996 * @__NL80211_CMD_AFTER_LAST: internal use
@@ -1185,6 +1194,10 @@ enum nl80211_commands { · 197 unmodified lines
1185 NL80211_CMD_SET_PMK,1194 NL80211_CMD_SET_PMK,
1186 NL80211_CMD_DEL_PMK,1195 NL80211_CMD_DEL_PMK,
1187 1196
1197 NL80211_CMD_PORT_AUTHORIZED,
1198
1199 NL80211_CMD_RELOAD_REGDB,
1200
1188 /* add new commands above here */1201 /* add new commands above here */
1189 1202
1190 /* used to define NL80211_CMD_MAX below */1203 /* used to define NL80211_CMD_MAX below */
@@ -1407,8 +1420,12 @@ enum nl80211_commands { · 216 unmodified lines
1407 *1420 *
1408 * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is1421 * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
1409 * used for the association (&enum nl80211_mfp, represented as a u32);1422 * used for the association (&enum nl80211_mfp, represented as a u32);
1410 * this attribute can be used1423 * this attribute can be used with %NL80211_CMD_ASSOCIATE and
1411 * with %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests1424 * %NL80211_CMD_CONNECT requests. %NL80211_MFP_OPTIONAL is not allowed for
1425 * %NL80211_CMD_ASSOCIATE since user space SME is expected and hence, it
1426 * must have decided whether to use management frame protection or not.
1427 * Setting %NL80211_MFP_OPTIONAL with a %NL80211_CMD_CONNECT request will
1428 * let the driver (or the firmware) decide whether to use MFP or not.
1412 *1429 *
1413 * @NL80211_ATTR_STA_FLAGS2: Attribute containing a1430 * @NL80211_ATTR_STA_FLAGS2: Attribute containing a
1414 * &struct nl80211_sta_flag_update.1431 * &struct nl80211_sta_flag_update.
@@ -2134,10 +2151,7 @@ enum nl80211_commands { · 719 unmodified lines
2134 * in %NL80211_CMD_CONNECT to indicate that for 802.1X authentication it2151 * in %NL80211_CMD_CONNECT to indicate that for 802.1X authentication it
2135 * wants to use the supported offload of the 4-way handshake.2152 * wants to use the supported offload of the 4-way handshake.
2136 * @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT.2153 * @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT.
2137 * @NL80211_ATTR_PORT_AUTHORIZED: flag attribute used in %NL80211_CMD_ROAMED2154 * @NL80211_ATTR_PORT_AUTHORIZED: (reserved)
2138 * notification indicating that that 802.1X authentication was done by
2139 * the driver or is not needed (because roaming used the Fast Transition
2140 * protocol).
2141 *2155 *
2142 * @NUM_NL80211_ATTR: total number of nl80211_attrs available2156 * @NUM_NL80211_ATTR: total number of nl80211_attrs available
2143 * @NL80211_ATTR_MAX: highest attribute number currently defined2157 * @NL80211_ATTR_MAX: highest attribute number currently defined
@@ -3947,10 +3961,12 @@ enum nl80211_key_type { · 1803 unmodified lines
3947 * enum nl80211_mfp - Management frame protection state3961 * enum nl80211_mfp - Management frame protection state
3948 * @NL80211_MFP_NO: Management frame protection not used3962 * @NL80211_MFP_NO: Management frame protection not used
3949 * @NL80211_MFP_REQUIRED: Management frame protection required3963 * @NL80211_MFP_REQUIRED: Management frame protection required
3964 * @NL80211_MFP_OPTIONAL: Management frame protection is optional
3950 */3965 */
3951enum nl80211_mfp {3966enum nl80211_mfp {
3952 NL80211_MFP_NO,3967 NL80211_MFP_NO,
3953 NL80211_MFP_REQUIRED,3968 NL80211_MFP_REQUIRED,
3969 NL80211_MFP_OPTIONAL,
3954};3970};
3955 3971
3956enum nl80211_wpa_versions {3972enum nl80211_wpa_versions {
@@ -4914,6 +4930,17 @@ enum nl80211_feature_flags { · 957 unmodified lines
4914 * handshake with 802.1X in station mode (will pass EAP frames to the host4930 * handshake with 802.1X in station mode (will pass EAP frames to the host
4915 * and accept the set_pmk/del_pmk commands), doing it in the host might not4931 * and accept the set_pmk/del_pmk commands), doing it in the host might not
4916 * be supported.4932 * be supported.
4933 * @NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME: Driver is capable of overriding
4934 * the max channel attribute in the FILS request params IE with the
4935 * actual dwell time.
4936 * @NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP: Driver accepts broadcast probe
4937 * response
4938 * @NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE: Driver supports sending
4939 * the first probe request in each channel at rate of at least 5.5Mbps.
4940 * @NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION: Driver supports
4941 * probe request tx deferral and suppression
4942 * @NL80211_EXT_FEATURE_MFP_OPTIONAL: Driver supports the %NL80211_MFP_OPTIONAL
4943 * value in %NL80211_ATTR_USE_MFP.
4917 *4944 *
4918 * @NUM_NL80211_EXT_FEATURES: number of extended features.4945 * @NUM_NL80211_EXT_FEATURES: number of extended features.
4919 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.4946 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4936,6 +4963,11 @@ enum nl80211_ext_feature_index { · 16 unmodified lines
4936 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD,4963 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD,
4937 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK,4964 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK,
4938 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X,4965 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X,
4966 NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME,
4967 NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP,
4968 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE,
4969 NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
4970 NL80211_EXT_FEATURE_MFP_OPTIONAL,
4939 4971
4940 /* add new features before the definition below */4972 /* add new features before the definition below */
4941 NUM_NL80211_EXT_FEATURES,4973 NUM_NL80211_EXT_FEATURES,
@@ -5012,12 +5044,28 @@ enum nl80211_timeout_reason { · 70 unmodified lines
5012 * locally administered 1, multicast 0) is assumed.5044 * locally administered 1, multicast 0) is assumed.
5013 * This flag must not be requested when the feature isn't supported, check5045 * This flag must not be requested when the feature isn't supported, check
5014 * the nl80211 feature flags for the device.5046 * the nl80211 feature flags for the device.
5047 * @NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME: fill the dwell time in the FILS
5048 * request parameters IE in the probe request
5049 * @NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP: accept broadcast probe responses
5050 * @NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE: send probe request frames at
5051 * rate of at least 5.5M. In case non OCE AP is dicovered in the channel,
5052 * only the first probe req in the channel will be sent in high rate.
5053 * @NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION: allow probe request
5054 * tx deferral (dot11FILSProbeDelay shall be set to 15ms)
5055 * and suppression (if it has received a broadcast Probe Response frame,
5056 * Beacon frame or FILS Discovery frame from an AP that the STA considers
5057 * a suitable candidate for (re-)association - suitable in terms of
5058 * SSID and/or RSSI
5015 */5059 */
5016enum nl80211_scan_flags {5060enum nl80211_scan_flags {
5017 NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0,5061 NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0,
5018 NL80211_SCAN_FLAG_FLUSH = 1<<1,5062 NL80211_SCAN_FLAG_FLUSH = 1<<1,
5019 NL80211_SCAN_FLAG_AP = 1<<2,5063 NL80211_SCAN_FLAG_AP = 1<<2,
5020 NL80211_SCAN_FLAG_RANDOM_ADDR = 1<<3,5064 NL80211_SCAN_FLAG_RANDOM_ADDR = 1<<3,
5065 NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME = 1<<4,
5066 NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP = 1<<5,
5067 NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE = 1<<6,
5068 NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 1<<7,
5021};5069};
5022 5070
5023/**5071/**
net/mac80211/Makefile+1−2
@@ -6,6 +6,7 @@ mac80211-y := \ · 5 unmodified lines
6 driver-ops.o \6 driver-ops.o \
7 sta_info.o \7 sta_info.o \
8 wep.o \8 wep.o \
9 aead_api.o \
9 wpa.o \10 wpa.o \
10 scan.o offchannel.o \11 scan.o offchannel.o \
11 ht.o agg-tx.o agg-rx.o \12 ht.o agg-tx.o agg-rx.o \
@@ -15,8 +16,6 @@ mac80211-y := \ · 3 unmodified lines
15 rate.o \16 rate.o \
16 michael.o \17 michael.o \
17 tkip.o \18 tkip.o \
18 aes_ccm.o \
19 aes_gcm.o \
20 aes_cmac.o \19 aes_cmac.o \
21 aes_gmac.o \20 aes_gmac.o \
22 fils_aead.o \21 fils_aead.o \
net/mac80211/aead_api.crenamed from net/mac80211/aes_ccm.c+20−20
@@ -1,6 +1,7 @@
1/*1/*
2 * Copyright 2003-2004, Instant802 Networks, Inc.2 * Copyright 2003-2004, Instant802 Networks, Inc.
3 * Copyright 2005-2006, Devicescape Software, Inc.3 * Copyright 2005-2006, Devicescape Software, Inc.
4 * Copyright 2014-2015, Qualcomm Atheros, Inc.
4 *5 *
5 * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>6 * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
6 *7 *
@@ -12,30 +13,29 @@ · 5 unmodified lines
12#include <linux/kernel.h>13#include <linux/kernel.h>
13#include <linux/types.h>14#include <linux/types.h>
14#include <linux/err.h>15#include <linux/err.h>
16#include <linux/scatterlist.h>
15#include <crypto/aead.h>17#include <crypto/aead.h>
16 18
17#include <net/mac80211.h>19#include "aead_api.h"
18#include "key.h"
19#include "aes_ccm.h"
20 20
21int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,21int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
22 u8 *data, size_t data_len, u8 *mic,22 u8 *data, size_t data_len, u8 *mic)
23 size_t mic_len)
24{23{
24 size_t mic_len = tfm->authsize;
25 struct scatterlist sg[3];25 struct scatterlist sg[3];
26 struct aead_request *aead_req;26 struct aead_request *aead_req;
27 int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);27 int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
28 u8 *__aad;28 u8 *__aad;
29 29
30 aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC);30 aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
31 if (!aead_req)31 if (!aead_req)
32 return -ENOMEM;32 return -ENOMEM;
33 33
34 __aad = (u8 *)aead_req + reqsize;34 __aad = (u8 *)aead_req + reqsize;
35 memcpy(__aad, aad, CCM_AAD_LEN);35 memcpy(__aad, aad, aad_len);
36 36
37 sg_init_table(sg, 3);37 sg_init_table(sg, 3);
38 sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));38 sg_set_buf(&sg[0], __aad, aad_len);
39 sg_set_buf(&sg[1], data, data_len);39 sg_set_buf(&sg[1], data, data_len);
40 sg_set_buf(&sg[2], mic, mic_len);40 sg_set_buf(&sg[2], mic, mic_len);
41 41
@@ -49,10 +49,10 @@ int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, · 7 unmodified lines
49 return 0;49 return 0;
50}50}
51 51
52int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,52int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
53 u8 *data, size_t data_len, u8 *mic,53 u8 *data, size_t data_len, u8 *mic)
54 size_t mic_len)
55{54{
55 size_t mic_len = tfm->authsize;
56 struct scatterlist sg[3];56 struct scatterlist sg[3];
57 struct aead_request *aead_req;57 struct aead_request *aead_req;
58 int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);58 int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
@@ -62,15 +62,15 @@ int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, · 3 unmodified lines
62 if (data_len == 0)62 if (data_len == 0)
63 return -EINVAL;63 return -EINVAL;
64 64
65 aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC);65 aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
66 if (!aead_req)66 if (!aead_req)
67 return -ENOMEM;67 return -ENOMEM;
68 68
69 __aad = (u8 *)aead_req + reqsize;69 __aad = (u8 *)aead_req + reqsize;
70 memcpy(__aad, aad, CCM_AAD_LEN);70 memcpy(__aad, aad, aad_len);
71 71
72 sg_init_table(sg, 3);72 sg_init_table(sg, 3);
73 sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));73 sg_set_buf(&sg[0], __aad, aad_len);
74 sg_set_buf(&sg[1], data, data_len);74 sg_set_buf(&sg[1], data, data_len);
75 sg_set_buf(&sg[2], mic, mic_len);75 sg_set_buf(&sg[2], mic, mic_len);
76 76
@@ -84,14 +84,14 @@ int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, · 7 unmodified lines
84 return err;84 return err;
85}85}
86 86
87struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],87struct crypto_aead *
88 size_t key_len,88aead_key_setup_encrypt(const char *alg, const u8 key[],
89 size_t mic_len)89 size_t key_len, size_t mic_len)
90{90{
91 struct crypto_aead *tfm;91 struct crypto_aead *tfm;
92 int err;92 int err;
93 93
94 tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC);94 tfm = crypto_alloc_aead(alg, 0, CRYPTO_ALG_ASYNC);
95 if (IS_ERR(tfm))95 if (IS_ERR(tfm))
96 return tfm;96 return tfm;
97 97
@@ -109,7 +109,7 @@ free_aead: · 11 unmodified lines
109 return ERR_PTR(err);109 return ERR_PTR(err);
110}110}
111 111
112void ieee80211_aes_key_free(struct crypto_aead *tfm)112void aead_key_free(struct crypto_aead *tfm)
113{113{
114 crypto_free_aead(tfm);114 crypto_free_aead(tfm);
115}115}
net/mac80211/aead_api.h+27−0
@@ -0,0 +1,27 @@
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
13struct crypto_aead *
14aead_key_setup_encrypt(const char *alg, const u8 key[],
15 size_t key_len, size_t mic_len);
16
17int 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
21int 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
25void aead_key_free(struct crypto_aead *tfm);
26
27#endif /* _AEAD_API_H */
net/mac80211/aes_ccm.h+31−11
@@ -10,19 +10,39 @@ · 9 unmodified lines
10#ifndef AES_CCM_H10#ifndef AES_CCM_H
11#define AES_CCM_H11#define AES_CCM_H
12 12
13#include <linux/crypto.h>13#include "aead_api.h"
14 14
15#define CCM_AAD_LEN 3215#define CCM_AAD_LEN 32
16 16
17struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],17static inline struct crypto_aead *
18 size_t key_len,18ieee80211_aes_key_setup_encrypt(const u8 key[], size_t key_len, size_t mic_len)
19 size_t mic_len);19{
20int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,20 return aead_key_setup_encrypt("ccm(aes)", key, key_len, mic_len);
21 u8 *data, size_t data_len, u8 *mic,21}
22 size_t mic_len);22
23int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,23static inline int
24 u8 *data, size_t data_len, u8 *mic,24ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm,
25 size_t mic_len);25 u8 *b_0, u8 *aad, u8 *data,
26void ieee80211_aes_key_free(struct crypto_aead *tfm);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
33static inline int
34ieee80211_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
43static inline void ieee80211_aes_key_free(struct crypto_aead *tfm)
44{
45 return aead_key_free(tfm);
46}
27 47
28#endif /* AES_CCM_H */48#endif /* AES_CCM_H */
net/mac80211/aes_gcm.c+0−109
@@ -1,109 +0,0 @@
1/*
2 * Copyright 2014-2015, Qualcomm Atheros, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/kernel.h>
10#include <linux/types.h>
11#include <linux/err.h>
12#include <crypto/aead.h>
13
14#include <net/mac80211.h>
15#include "key.h"
16#include "aes_gcm.h"
17
18int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
19 u8 *data, size_t data_len, u8 *mic)
20{
21 struct scatterlist sg[3];
22 struct aead_request *aead_req;
23 int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
24 u8 *__aad;
25
26 aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC);
27 if (!aead_req)
28 return -ENOMEM;
29
30 __aad = (u8 *)aead_req + reqsize;
31 memcpy(__aad, aad, GCM_AAD_LEN);
32
33 sg_init_table(sg, 3);
34 sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
35 sg_set_buf(&sg[1], data, data_len);
36 sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN);
37
38 aead_request_set_tfm(aead_req, tfm);
39 aead_request_set_crypt(aead_req, sg, sg, data_len, j_0);
40 aead_request_set_ad(aead_req, sg[0].length);
41
42 crypto_aead_encrypt(aead_req);
43 kzfree(aead_req);
44 return 0;
45}
46
47int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
48 u8 *data, size_t data_len, u8 *mic)
49{
50 struct scatterlist sg[3];
51 struct aead_request *aead_req;
52 int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
53 u8 *__aad;
54 int err;
55
56 if (data_len == 0)
57 return -EINVAL;
58
59 aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC);
60 if (!aead_req)
61 return -ENOMEM;
62
63 __aad = (u8 *)aead_req + reqsize;
64 memcpy(__aad, aad, GCM_AAD_LEN);
65
66 sg_init_table(sg, 3);
67 sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
68 sg_set_buf(&sg[1], data, data_len);
69 sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN);
70
71 aead_request_set_tfm(aead_req, tfm);
72 aead_request_set_crypt(aead_req, sg, sg,
73 data_len + IEEE80211_GCMP_MIC_LEN, j_0);
74 aead_request_set_ad(aead_req, sg[0].length);
75
76 err = crypto_aead_decrypt(aead_req);
77 kzfree(aead_req);
78
79 return err;
80}
81
82struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
83 size_t key_len)
84{
85 struct crypto_aead *tfm;
86 int err;
87
88 tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
89 if (IS_ERR(tfm))
90 return tfm;
91
92 err = crypto_aead_setkey(tfm, key, key_len);
93 if (err)
94 goto free_aead;
95 err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN);
96 if (err)
97 goto free_aead;
98
99 return tfm;
100
101free_aead:
102 crypto_free_aead(tfm);
103 return ERR_PTR(err);
104}
105
106void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
107{
108 crypto_free_aead(tfm);
109}
net/mac80211/aes_gcm.h+30−8
@@ -9,16 +9,38 @@ · 8 unmodified lines
9#ifndef AES_GCM_H9#ifndef AES_GCM_H
10#define AES_GCM_H10#define AES_GCM_H
11 11
12#include <linux/crypto.h>12#include "aead_api.h"
13 13
14#define GCM_AAD_LEN 3214#define GCM_AAD_LEN 32
15 15
16int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,16static inline int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm,
17 u8 *data, size_t data_len, u8 *mic);17 u8 *j_0, u8 *aad, u8 *data,
18int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,18 size_t data_len, u8 *mic)
19 u8 *data, size_t data_len, u8 *mic);19{
20struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],20 return aead_encrypt(tfm, j_0, aad + 2,
21 size_t key_len);21 be16_to_cpup((__be16 *)aad),
22void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm);22 data, data_len, mic);
23}
24
25static 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
34static inline struct crypto_aead *
35ieee80211_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
41static inline void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
42{
43 return aead_key_free(tfm);
44}
23 45
24#endif /* AES_GCM_H */46#endif /* AES_GCM_H */
net/mac80211/agg-rx.c+2−2
@@ -459,7 +459,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, · 458 unmodified lines
459}459}
460 460
461void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif,461void 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 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);464 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
465 struct ieee80211_local *local = sdata->local;465 struct ieee80211_local *local = sdata->local;
@@ -470,7 +470,7 @@ void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif, · 4 unmodified lines
470 if (!sta)470 if (!sta)
471 goto unlock;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 ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work);474 ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work);
475 unlock:475 unlock:
476 rcu_read_unlock();476 rcu_read_unlock();
net/mac80211/ht.c+7−5
@@ -290,13 +290,15 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, · 289 unmodified lines
290{290{
291 int i;291 int i;
292 292
293 mutex_lock(&sta->ampdu_mlme.mtx);
293 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {294 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
294 __ieee80211_stop_tx_ba_session(sta, i, reason);295 ___ieee80211_stop_tx_ba_session(sta, i, reason);
295 __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,296 ___ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
296 WLAN_REASON_QSTA_LEAVE_QBSS,297 WLAN_REASON_QSTA_LEAVE_QBSS,
297 reason != AGG_STOP_DESTROY_STA &&298 reason != AGG_STOP_DESTROY_STA &&
298 reason != AGG_STOP_PEER_REQUEST);299 reason != AGG_STOP_PEER_REQUEST);
299 }300 }
301 mutex_unlock(&sta->ampdu_mlme.mtx);
300 302
301 /* stopping might queue the work again - so cancel only afterwards */303 /* stopping might queue the work again - so cancel only afterwards */
302 cancel_work_sync(&sta->ampdu_mlme.work);304 cancel_work_sync(&sta->ampdu_mlme.work);
net/mac80211/ieee80211_i.h+2−0
@@ -2009,6 +2009,8 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata, · 2008 unmodified lines
2009 struct txq_info *txq, int tid);2009 struct txq_info *txq, int tid);
2010void ieee80211_txq_purge(struct ieee80211_local *local,2010void ieee80211_txq_purge(struct ieee80211_local *local,
2011 struct txq_info *txqi);2011 struct txq_info *txqi);
2012void ieee80211_txq_remove_vlan(struct ieee80211_local *local,
2013 struct ieee80211_sub_if_data *sdata);
2012void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,2014void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
2013 u16 transaction, u16 auth_alg, u16 status,2015 u16 transaction, u16 auth_alg, u16 status,
2014 const u8 *extra, size_t extra_len, const u8 *bssid,2016 const u8 *extra, size_t extra_len, const u8 *bssid,
net/mac80211/iface.c+6−23
@@ -793,9 +793,7 @@ static int ieee80211_open(struct net_device *dev) · 792 unmodified lines
793static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,793static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
794 bool going_down)794 bool going_down)
795{795{
796 struct ieee80211_sub_if_data *txq_sdata = sdata;
797 struct ieee80211_local *local = sdata->local;796 struct ieee80211_local *local = sdata->local;
798 struct fq *fq = &local->fq;
799 unsigned long flags;797 unsigned long flags;
800 struct sk_buff *skb, *tmp;798 struct sk_buff *skb, *tmp;
801 u32 hw_reconf_flags = 0;799 u32 hw_reconf_flags = 0;
@@ -939,9 +937,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, · 137 unmodified lines
939 937
940 switch (sdata->vif.type) {938 switch (sdata->vif.type) {
941 case NL80211_IFTYPE_AP_VLAN:939 case NL80211_IFTYPE_AP_VLAN:
942 txq_sdata = container_of(sdata->bss,
943 struct ieee80211_sub_if_data, u.ap);
944
945 mutex_lock(&local->mtx);940 mutex_lock(&local->mtx);
946 list_del(&sdata->u.vlan.list);941 list_del(&sdata->u.vlan.list);
947 mutex_unlock(&local->mtx);942 mutex_unlock(&local->mtx);
@@ -998,8 +993,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, · 50 unmodified lines
998 skb_queue_purge(&sdata->skb_queue);993 skb_queue_purge(&sdata->skb_queue);
999 }994 }
1000 995
1001 sdata->bss = NULL;
1002
1003 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);996 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
1004 for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {997 for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
1005 skb_queue_walk_safe(&local->pending[i], skb, tmp) {998 skb_queue_walk_safe(&local->pending[i], skb, tmp) {
@@ -1012,22 +1005,10 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, · 6 unmodified lines
1012 }1005 }
1013 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);1006 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
1014 1007
1015 if (txq_sdata->vif.txq) {1008 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1016 struct txq_info *txqi = to_txq_info(txq_sdata->vif.txq);1009 ieee80211_txq_remove_vlan(local, sdata);
1017
1018 /*
1019 * FIXME FIXME
1020 *
1021 * We really shouldn't purge the *entire* txqi since that
1022 * contains frames for the other AP_VLANs (and possibly
1023 * the AP itself) as well, but there's no API in FQ now
1024 * to be able to filter.
1025 */
1026 1010
1027 spin_lock_bh(&fq->lock);1011 sdata->bss = NULL;
1028 ieee80211_txq_purge(local, txqi);
1029 spin_unlock_bh(&fq->lock);
1030 }
1031 1012
1032 if (local->open_count == 0)1013 if (local->open_count == 0)
1033 ieee80211_clear_tx_pending(local);1014 ieee80211_clear_tx_pending(local);
@@ -1772,7 +1753,9 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, · 738 unmodified lines
1772 sizeof(void *));1753 sizeof(void *));
1773 int txq_size = 0;1754 int txq_size = 0;
1774 1755
1775 if (local->ops->wake_tx_queue)1756 if (local->ops->wake_tx_queue &&
1757 type != NL80211_IFTYPE_AP_VLAN &&
1758 type != NL80211_IFTYPE_MONITOR)
1776 txq_size += sizeof(struct txq_info) +1759 txq_size += sizeof(struct txq_info) +
1777 local->hw.txq_data_size;1760 local->hw.txq_data_size;
1778 1761
net/mac80211/mesh.c+1−2
@@ -675,8 +675,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh) · 674 unmodified lines
675 enum nl80211_band band;675 enum nl80211_band band;
676 u8 *pos;676 u8 *pos;
677 struct ieee80211_sub_if_data *sdata;677 struct ieee80211_sub_if_data *sdata;
678 int hdr_len = offsetof(struct ieee80211_mgmt, u.beacon) +678 int hdr_len = offsetofend(struct ieee80211_mgmt, u.beacon);
679 sizeof(mgmt->u.beacon);
680 679
681 sdata = container_of(ifmsh, struct ieee80211_sub_if_data, u.mesh);680 sdata = container_of(ifmsh, struct ieee80211_sub_if_data, u.mesh);
682 rcu_read_lock();681 rcu_read_lock();
net/mac80211/mesh.h+1−0
@@ -275,6 +275,7 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, · 274 unmodified lines
275 u8 *hw_addr, struct ieee802_11_elems *ie);275 u8 *hw_addr, struct ieee802_11_elems *ie);
276bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);276bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
277u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);277u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
278void mesh_plink_timer(struct timer_list *t);
278void mesh_plink_broken(struct sta_info *sta);279void mesh_plink_broken(struct sta_info *sta);
279u32 mesh_plink_deactivate(struct sta_info *sta);280u32 mesh_plink_deactivate(struct sta_info *sta);
280u32 mesh_plink_open(struct sta_info *sta);281u32 mesh_plink_open(struct sta_info *sta);
net/mac80211/mesh_hwmp.c+4−4
@@ -111,8 +111,8 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, · 110 unmodified lines
111 struct sk_buff *skb;111 struct sk_buff *skb;
112 struct ieee80211_mgmt *mgmt;112 struct ieee80211_mgmt *mgmt;
113 u8 *pos, ie_len;113 u8 *pos, ie_len;
114 int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) +114 int hdr_len = offsetofend(struct ieee80211_mgmt,
115 sizeof(mgmt->u.action.u.mesh_action);115 u.action.u.mesh_action);
116 116
117 skb = dev_alloc_skb(local->tx_headroom +117 skb = dev_alloc_skb(local->tx_headroom +
118 hdr_len +118 hdr_len +
@@ -242,8 +242,8 @@ int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata, · 123 unmodified lines
242 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;242 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
243 struct ieee80211_mgmt *mgmt;243 struct ieee80211_mgmt *mgmt;
244 u8 *pos, ie_len;244 u8 *pos, ie_len;
245 int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) +245 int hdr_len = offsetofend(struct ieee80211_mgmt,
246 sizeof(mgmt->u.action.u.mesh_action);246 u.action.u.mesh_action);
247 247
248 if (time_before(jiffies, ifmsh->next_perr))248 if (time_before(jiffies, ifmsh->next_perr))
249 return -EAGAIN;249 return -EAGAIN;
net/mac80211/mesh_plink.c+5−8
@@ -220,8 +220,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, · 219 unmodified lines
220 bool include_plid = false;220 bool include_plid = false;
221 u16 peering_proto = 0;221 u16 peering_proto = 0;
222 u8 *pos, ie_len = 4;222 u8 *pos, ie_len = 4;
223 int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) +223 int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.self_prot);
224 sizeof(mgmt->u.action.u.self_prot);
225 int err = -ENOMEM;224 int err = -ENOMEM;
226 225
227 skb = dev_alloc_skb(local->tx_headroom +226 skb = dev_alloc_skb(local->tx_headroom +
@@ -604,8 +603,9 @@ out: · 376 unmodified lines
604 ieee80211_mbss_info_change_notify(sdata, changed);603 ieee80211_mbss_info_change_notify(sdata, changed);
605}604}
606 605
607static void mesh_plink_timer(unsigned long data)606void mesh_plink_timer(struct timer_list *t)
608{607{
608 struct mesh_sta *mesh = from_timer(mesh, t, plink_timer);
609 struct sta_info *sta;609 struct sta_info *sta;
610 u16 reason = 0;610 u16 reason = 0;
611 struct ieee80211_sub_if_data *sdata;611 struct ieee80211_sub_if_data *sdata;
@@ -617,7 +617,7 @@ static void mesh_plink_timer(unsigned long data) · 5 unmodified lines
617 * del_timer_sync() this timer after having made sure617 * del_timer_sync() this timer after having made sure
618 * it cannot be readded (by deleting the plink.)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 if (sta->sdata->local->quiescing)622 if (sta->sdata->local->quiescing)
623 return;623 return;
@@ -697,11 +697,8 @@ static void mesh_plink_timer(unsigned long data) · 73 unmodified lines
697 697
698static inline void mesh_plink_timer_set(struct sta_info *sta, u32 timeout)698static 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 sta->mesh->plink_timeout = timeout;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
707static bool llid_in_use(struct ieee80211_sub_if_data *sdata,704static bool llid_in_use(struct ieee80211_sub_if_data *sdata,
net/mac80211/mlme.c+7−12
@@ -780,11 +780,12 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) · 779 unmodified lines
780 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,780 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
781 WLAN_EID_HT_CAPABILITY,781 WLAN_EID_HT_CAPABILITY,
782 WLAN_EID_BSS_COEX_2040,782 WLAN_EID_BSS_COEX_2040,
783 /* luckily this is almost always there */
783 WLAN_EID_EXT_CAPABILITY,784 WLAN_EID_EXT_CAPABILITY,
784 WLAN_EID_QOS_TRAFFIC_CAPA,785 WLAN_EID_QOS_TRAFFIC_CAPA,
785 WLAN_EID_TIM_BCAST_REQ,786 WLAN_EID_TIM_BCAST_REQ,
786 WLAN_EID_INTERWORKING,787 WLAN_EID_INTERWORKING,
787 /* 60GHz doesn't happen right now */788 /* 60 GHz (Multi-band, DMG, MMS) can't happen */
788 WLAN_EID_VHT_CAPABILITY,789 WLAN_EID_VHT_CAPABILITY,
789 WLAN_EID_OPMODE_NOTIF,790 WLAN_EID_OPMODE_NOTIF,
790 };791 };
@@ -811,22 +812,16 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) · 20 unmodified lines
811 /* if present, add any custom IEs that go before VHT */812 /* if present, add any custom IEs that go before VHT */
812 if (assoc_data->ie_len) {813 if (assoc_data->ie_len) {
813 static const u8 before_vht[] = {814 static const u8 before_vht[] = {
814 WLAN_EID_SSID,815 /*
815 WLAN_EID_SUPP_RATES,816 * no need to list the ones split off before HT
816 WLAN_EID_EXT_SUPP_RATES,817 * or generated here
817 WLAN_EID_PWR_CAPABILITY,818 */
818 WLAN_EID_SUPPORTED_CHANNELS,
819 WLAN_EID_RSN,
820 WLAN_EID_QOS_CAPA,
821 WLAN_EID_RRM_ENABLED_CAPABILITIES,
822 WLAN_EID_MOBILITY_DOMAIN,
823 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
824 WLAN_EID_HT_CAPABILITY,
825 WLAN_EID_BSS_COEX_2040,819 WLAN_EID_BSS_COEX_2040,
826 WLAN_EID_EXT_CAPABILITY,820 WLAN_EID_EXT_CAPABILITY,
827 WLAN_EID_QOS_TRAFFIC_CAPA,821 WLAN_EID_QOS_TRAFFIC_CAPA,
828 WLAN_EID_TIM_BCAST_REQ,822 WLAN_EID_TIM_BCAST_REQ,
829 WLAN_EID_INTERWORKING,823 WLAN_EID_INTERWORKING,
824 /* 60 GHz (Multi-band, DMG, MMS) can't happen */
830 };825 };
831 826
832 /* RIC already taken above, so no need to handle here anymore */827 /* RIC already taken above, so no need to handle here anymore */
net/mac80211/scan.c+28−9
@@ -7,7 +7,7 @@ · 6 unmodified lines
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
9 * Copyright 2013-2015 Intel Mobile Communications GmbH9 * Copyright 2013-2015 Intel Mobile Communications GmbH
10 * Copyright 2016 Intel Deutschland GmbH10 * Copyright 2016-2017 Intel Deutschland GmbH
11 *11 *
12 * This program is free software; you can redistribute it and/or modify12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as13 * it under the terms of the GNU General Public License version 2 as
@@ -183,6 +183,20 @@ ieee80211_bss_info_update(struct ieee80211_local *local, · 169 unmodified lines
183 return bss;183 return bss;
184}184}
185 185
186static 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
186void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)200void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
187{201{
188 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);202 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
@@ -208,19 +222,24 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb) · 19 unmodified lines
208 if (ieee80211_is_probe_resp(mgmt->frame_control)) {222 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
209 struct cfg80211_scan_request *scan_req;223 struct cfg80211_scan_request *scan_req;
210 struct cfg80211_sched_scan_request *sched_scan_req;224 struct cfg80211_sched_scan_request *sched_scan_req;
225 u32 scan_req_flags = 0, sched_scan_req_flags = 0;
211 226
212 scan_req = rcu_dereference(local->scan_req);227 scan_req = rcu_dereference(local->scan_req);
213 sched_scan_req = rcu_dereference(local->sched_scan_req);228 sched_scan_req = rcu_dereference(local->sched_scan_req);
214 229
215 /* ignore ProbeResp to foreign address unless scanning230 if (scan_req)
216 * with randomised address231 scan_req_flags = scan_req->flags;
232
233 if (sched_scan_req)
234 sched_scan_req_flags = sched_scan_req->flags;
235
236 /* ignore ProbeResp to foreign address or non-bcast (OCE)
237 * unless scanning with randomised address
217 */238 */
218 if (!(sdata1 &&239 if (!ieee80211_scan_accept_presp(sdata1, scan_req_flags,
219 (ether_addr_equal(mgmt->da, sdata1->vif.addr) ||240 mgmt->da) &&
220 scan_req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) &&241 !ieee80211_scan_accept_presp(sdata2, sched_scan_req_flags,
221 !(sdata2 &&242 mgmt->da))
222 (ether_addr_equal(mgmt->da, sdata2->vif.addr) ||
223 sched_scan_req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)))
224 return;243 return;
225 244
226 elements = mgmt->u.probe_resp.variable;245 elements = mgmt->u.probe_resp.variable;
net/mac80211/sta_info.c+35−26
@@ -329,10 +329,12 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, · 328 unmodified lines
329 sta->mesh = kzalloc(sizeof(*sta->mesh), gfp);329 sta->mesh = kzalloc(sizeof(*sta->mesh), gfp);
330 if (!sta->mesh)330 if (!sta->mesh)
331 goto free;331 goto free;
332 sta->mesh->plink_sta = sta;
332 spin_lock_init(&sta->mesh->plink_lock);333 spin_lock_init(&sta->mesh->plink_lock);
333 if (ieee80211_vif_is_mesh(&sdata->vif) &&334 if (ieee80211_vif_is_mesh(&sdata->vif) &&
334 !sdata->u.mesh.user_mpm)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 sta->mesh->nonpeer_pm = NL80211_MESH_POWER_ACTIVE;338 sta->mesh->nonpeer_pm = NL80211_MESH_POWER_ACTIVE;
337 }339 }
338#endif340#endif
@@ -515,6 +517,31 @@ static int sta_info_insert_drv_state(struct ieee80211_local *local, · 176 unmodified lines
515 return err;517 return err;
516}518}
517 519
520static void
521ieee80211_recalc_p2p_go_ps_allowed(struct ieee80211_sub_if_data *sdata)
522{
523 struct ieee80211_local *local = sdata->local;
524 bool allow_p2p_go_ps = sdata->vif.p2p;
525 struct sta_info *sta;
526
527 rcu_read_lock();
528 list_for_each_entry_rcu(sta, &local->sta_list, list) {
529 if (sdata != sta->sdata ||
530 !test_sta_flag(sta, WLAN_STA_ASSOC))
531 continue;
532 if (!sta->sta.support_p2p_ps) {
533 allow_p2p_go_ps = false;
534 break;
535 }
536 }
537 rcu_read_unlock();
538
539 if (allow_p2p_go_ps != sdata->vif.bss_conf.allow_p2p_go_ps) {
540 sdata->vif.bss_conf.allow_p2p_go_ps = allow_p2p_go_ps;
541 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_P2P_PS);
542 }
543}
544
518/*545/*
519 * should be called with sta_mtx locked546 * should be called with sta_mtx locked
520 * this function replaces the mutex lock547 * this function replaces the mutex lock
@@ -561,6 +588,13 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) · 40 unmodified lines
561 goto out_remove;588 goto out_remove;
562 589
563 set_sta_flag(sta, WLAN_STA_INSERTED);590 set_sta_flag(sta, WLAN_STA_INSERTED);
591
592 if (sta->sta_state >= IEEE80211_STA_ASSOC) {
593 ieee80211_recalc_min_chandef(sta->sdata);
594 if (!sta->sta.support_p2p_ps)
595 ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
596 }
597
564 /* accept BA sessions now */598 /* accept BA sessions now */
565 clear_sta_flag(sta, WLAN_STA_BLOCK_BA);599 clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
566 600
@@ -1788,31 +1822,6 @@ void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta, · 1221 unmodified lines
1788}1822}
1789EXPORT_SYMBOL(ieee80211_sta_set_buffered);1823EXPORT_SYMBOL(ieee80211_sta_set_buffered);
1790 1824
1791static void
1792ieee80211_recalc_p2p_go_ps_allowed(struct ieee80211_sub_if_data *sdata)
1793{
1794 struct ieee80211_local *local = sdata->local;
1795 bool allow_p2p_go_ps = sdata->vif.p2p;
1796 struct sta_info *sta;
1797
1798 rcu_read_lock();
1799 list_for_each_entry_rcu(sta, &local->sta_list, list) {
1800 if (sdata != sta->sdata ||
1801 !test_sta_flag(sta, WLAN_STA_ASSOC))
1802 continue;
1803 if (!sta->sta.support_p2p_ps) {
1804 allow_p2p_go_ps = false;
1805 break;
1806 }
1807 }
1808 rcu_read_unlock();
1809
1810 if (allow_p2p_go_ps != sdata->vif.bss_conf.allow_p2p_go_ps) {
1811 sdata->vif.bss_conf.allow_p2p_go_ps = allow_p2p_go_ps;
1812 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_P2P_PS);
1813 }
1814}
1815
1816int sta_info_move_state(struct sta_info *sta,1825int sta_info_move_state(struct sta_info *sta,
1817 enum ieee80211_sta_state new_state)1826 enum ieee80211_sta_state new_state)
1818{1827{
net/mac80211/sta_info.h+3−1
@@ -344,6 +344,7 @@ DECLARE_EWMA(mesh_fail_avg, 20, 8) · 343 unmodified lines
344 * @plink_state: peer link state344 * @plink_state: peer link state
345 * @plink_timeout: timeout of peer link345 * @plink_timeout: timeout of peer link
346 * @plink_timer: peer link watch timer346 * @plink_timer: peer link watch timer
347 * @plink_sta: peer link watch timer's sta_info
347 * @t_offset: timing offset relative to this host348 * @t_offset: timing offset relative to this host
348 * @t_offset_setpoint: reference timing offset of this sta to be used when349 * @t_offset_setpoint: reference timing offset of this sta to be used when
349 * calculating clockdrift350 * calculating clockdrift
@@ -356,6 +357,7 @@ DECLARE_EWMA(mesh_fail_avg, 20, 8) · 6 unmodified lines
356 */357 */
357struct mesh_sta {358struct mesh_sta {
358 struct timer_list plink_timer;359 struct timer_list plink_timer;
360 struct sta_info *plink_sta;
359 361
360 s64 t_offset;362 s64 t_offset;
361 s64 t_offset_setpoint;363 s64 t_offset_setpoint;
@@ -398,7 +400,7 @@ struct ieee80211_sta_rx_stats { · 36 unmodified lines
398 u64 msdu[IEEE80211_NUM_TIDS + 1];400 u64 msdu[IEEE80211_NUM_TIDS + 1];
399};401};
400 402
401/**403/*
402 * The bandwidth threshold below which the per-station CoDel parameters will be404 * The bandwidth threshold below which the per-station CoDel parameters will be
403 * scaled to be more lenient (to prevent starvation of slow stations). This405 * scaled to be more lenient (to prevent starvation of slow stations). This
404 * value will be scaled by the number of active stations when it is being406 * value will be scaled by the number of active stations when it is being
net/mac80211/tx.c+34−0
@@ -1396,6 +1396,40 @@ static void ieee80211_txq_enqueue(struct ieee80211_local *local, · 1395 unmodified lines
1396 fq_flow_get_default_func);1396 fq_flow_get_default_func);
1397}1397}
1398 1398
1399static 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
1408void 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
1399void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata,1433void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata,
1400 struct sta_info *sta,1434 struct sta_info *sta,
1401 struct txq_info *txqi, int tid)1435 struct txq_info *txqi, int tid)
net/mac80211/util.c+11−14
@@ -1392,10 +1392,10 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local, · 1391 unmodified lines
1392 /* insert custom IEs that go before HT */1392 /* insert custom IEs that go before HT */
1393 if (ie && ie_len) {1393 if (ie && ie_len) {
1394 static const u8 before_ht[] = {1394 static const u8 before_ht[] = {
1395 WLAN_EID_SSID,1395 /*
1396 WLAN_EID_SUPP_RATES,1396 * no need to list the ones split off already
1397 WLAN_EID_REQUEST,1397 * (or generated here)
1398 WLAN_EID_EXT_SUPP_RATES,1398 */
1399 WLAN_EID_DS_PARAMS,1399 WLAN_EID_DS_PARAMS,
1400 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,1400 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
1401 };1401 };
@@ -1424,20 +1424,17 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local, · 22 unmodified lines
1424 /* insert custom IEs that go before VHT */1424 /* insert custom IEs that go before VHT */
1425 if (ie && ie_len) {1425 if (ie && ie_len) {
1426 static const u8 before_vht[] = {1426 static const u8 before_vht[] = {
1427 WLAN_EID_SSID,1427 /*
1428 WLAN_EID_SUPP_RATES,1428 * no need to list the ones split off already
1429 WLAN_EID_REQUEST,1429 * (or generated here)
1430 WLAN_EID_EXT_SUPP_RATES,1430 */
1431 WLAN_EID_DS_PARAMS,
1432 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
1433 WLAN_EID_HT_CAPABILITY,
1434 WLAN_EID_BSS_COEX_2040,1431 WLAN_EID_BSS_COEX_2040,
1435 WLAN_EID_EXT_CAPABILITY,1432 WLAN_EID_EXT_CAPABILITY,
1436 WLAN_EID_SSID_LIST,1433 WLAN_EID_SSID_LIST,
1437 WLAN_EID_CHANNEL_USAGE,1434 WLAN_EID_CHANNEL_USAGE,
1438 WLAN_EID_INTERWORKING,1435 WLAN_EID_INTERWORKING,
1439 WLAN_EID_MESH_ID,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 noffset = ieee80211_ie_split(ie, ie_len,1439 noffset = ieee80211_ie_split(ie, ie_len,
1443 before_vht, ARRAY_SIZE(before_vht),1440 before_vht, ARRAY_SIZE(before_vht),
@@ -2980,8 +2977,8 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, · 1536 unmodified lines
2980 struct ieee80211_mgmt *mgmt;2977 struct ieee80211_mgmt *mgmt;
2981 struct ieee80211_local *local = sdata->local;2978 struct ieee80211_local *local = sdata->local;
2982 int freq;2979 int freq;
2983 int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.chan_switch) +2980 int hdr_len = offsetofend(struct ieee80211_mgmt,
2984 sizeof(mgmt->u.action.u.chan_switch);2981 u.action.u.chan_switch);
2985 u8 *pos;2982 u8 *pos;
2986 2983
2987 if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&2984 if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
net/mac80211/vht.c+10−0
@@ -386,6 +386,16 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta) · 385 unmodified lines
386 386
387 bw = ieee80211_sta_cap_rx_bw(sta);387 bw = ieee80211_sta_cap_rx_bw(sta);
388 bw = min(bw, sta->cur_max_bandwidth);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 bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width));399 bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width));
390 400
391 return bw;401 return bw;
net/mac80211/wpa.c+2−2
@@ -464,7 +464,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb, · 463 unmodified lines
464 pos += IEEE80211_CCMP_HDR_LEN;464 pos += IEEE80211_CCMP_HDR_LEN;
465 ccmp_special_blocks(skb, pn, b_0, aad);465 ccmp_special_blocks(skb, pn, b_0, aad);
466 return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,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,7 +543,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx, · 72 unmodified lines
543 key->u.ccmp.tfm, b_0, aad,543 key->u.ccmp.tfm, b_0, aad,
544 skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,544 skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
545 data_len,545 data_len,
546 skb->data + skb->len - mic_len, mic_len))546 skb->data + skb->len - mic_len))
547 return RX_DROP_UNUSABLE;547 return RX_DROP_UNUSABLE;
548 }548 }
549 549
net/wireless/.gitignore+2−1
@@ -1 +1,2 @@
1regdb.c1shipped-certs.c
2extra-certs.c
net/wireless/Kconfig+34−24
@@ -19,6 +19,7 @@ config WEXT_PRIV · 18 unmodified lines
19config CFG8021119config CFG80211
20 tristate "cfg80211 - wireless configuration API"20 tristate "cfg80211 - wireless configuration API"
21 depends on RFKILL || !RFKILL21 depends on RFKILL || !RFKILL
22 select FW_LOADER
22 ---help---23 ---help---
23 cfg80211 is the Linux wireless LAN (802.11) configuration API.24 cfg80211 is the Linux wireless LAN (802.11) configuration API.
24 Enable this if you have a wireless device.25 Enable this if you have a wireless device.
@@ -82,6 +83,36 @@ config CFG80211_CERTIFICATION_ONUS · 57 unmodified lines
82 you are a wireless researcher and are working in a controlled83 you are a wireless researcher and are working in a controlled
83 and approved environment by your local regulatory agency.84 and approved environment by your local regulatory agency.
84 85
86config CFG80211_REQUIRE_SIGNED_REGDB
87 bool "require regdb signature" if CFG80211_CERTIFICATION_ONUS
88 default y
89 select SYSTEM_DATA_VERIFICATION
90 help
91 Require that in addition to the "regulatory.db" file a
92 "regulatory.db.p7s" can be loaded with a valid PKCS#7
93 signature for the regulatory.db file made by one of the
94 keys in the certs/ directory.
95
96config CFG80211_USE_KERNEL_REGDB_KEYS
97 bool "allow regdb keys shipped with the kernel" if CFG80211_CERTIFICATION_ONUS
98 default y
99 depends on CFG80211_REQUIRE_SIGNED_REGDB
100 help
101 Allow the regulatory database to be signed by one of the keys for
102 which certificates are part of the kernel sources
103 (in net/wireless/certs/).
104
105 This is currently only Seth Forshee's key, who is the regulatory
106 database maintainer.
107
108config CFG80211_EXTRA_REGDB_KEYDIR
109 string "additional regdb key directory" if CFG80211_CERTIFICATION_ONUS
110 depends on CFG80211_REQUIRE_SIGNED_REGDB
111 help
112 If selected, point to a directory with DER-encoded X.509
113 certificates like in the kernel sources (net/wireless/certs/)
114 that shall be accepted for a signed regulatory database.
115
85config CFG80211_REG_CELLULAR_HINTS116config CFG80211_REG_CELLULAR_HINTS
86 bool "cfg80211 regulatory support for cellular base station hints"117 bool "cfg80211 regulatory support for cellular base station hints"
87 depends on CFG80211_CERTIFICATION_ONUS118 depends on CFG80211_CERTIFICATION_ONUS
@@ -139,35 +170,14 @@ config CFG80211_DEBUGFS · 51 unmodified lines
139 170
140 If unsure, say N.171 If unsure, say N.
141 172
142config CFG80211_INTERNAL_REGDB
143 bool "use statically compiled regulatory rules database" if EXPERT
144 default n
145 depends on CFG80211
146 ---help---
147 This option generates an internal data structure representing
148 the wireless regulatory rules described in net/wireless/db.txt
149 and includes code to query that database. This is an alternative
150 to using CRDA for defining regulatory rules for the kernel.
151
152 Using this option requires some parsing of the db.txt at build time,
153 the parser will be upkept with the latest wireless-regdb updates but
154 older wireless-regdb formats will be ignored. The parser may later
155 be replaced to avoid issues with conflicts on versions of
156 wireless-regdb.
157
158 For details see:
159
160 http://wireless.kernel.org/en/developers/Regulatory
161
162 Most distributions have a CRDA package. So if unsure, say N.
163
164config CFG80211_CRDA_SUPPORT173config CFG80211_CRDA_SUPPORT
165 bool "support CRDA" if CFG80211_INTERNAL_REGDB174 bool "support CRDA" if EXPERT
166 default y175 default y
167 depends on CFG80211176 depends on CFG80211
168 help177 help
169 You should enable this option unless you know for sure you have no178 You should enable this option unless you know for sure you have no
170 need for it, for example when using internal regdb (above.)179 need for it, for example when using internal regdb (above) or the
180 database loaded as a firmware file.
171 181
172 If unsure, say Y.182 If unsure, say Y.
173 183
net/wireless/Makefile+20−4
@@ -14,11 +14,27 @@ cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o ocb.o · 13 unmodified lines
14cfg80211-$(CONFIG_OF) += of.o14cfg80211-$(CONFIG_OF) += of.o
15cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o15cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o
16cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o16cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o
17cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o
18 17
19CFLAGS_trace.o := -I$(src)18CFLAGS_trace.o := -I$(src)
20 19
21$(obj)/regdb.c: $(src)/db.txt $(src)/genregdb.awk20cfg80211-$(CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS) += shipped-certs.o
22 @$(AWK) -f $(srctree)/$(src)/genregdb.awk < $< > $@21ifneq ($(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR),)
22cfg80211-y += extra-certs.o
23endif
23 24
24clean-files := regdb.c25$(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+0−0

Binary file not shown.

net/wireless/core.c+1−1
@@ -1384,7 +1384,7 @@ out_fail_sysfs: · 1383 unmodified lines
1384out_fail_pernet:1384out_fail_pernet:
1385 return err;1385 return err;
1386}1386}
1387subsys_initcall(cfg80211_init);1387fs_initcall(cfg80211_init);
1388 1388
1389static void __exit cfg80211_exit(void)1389static void __exit cfg80211_exit(void)
1390{1390{
net/wireless/core.h+5−0
@@ -216,6 +216,7 @@ enum cfg80211_event_type { · 215 unmodified lines
216 EVENT_DISCONNECTED,216 EVENT_DISCONNECTED,
217 EVENT_IBSS_JOINED,217 EVENT_IBSS_JOINED,
218 EVENT_STOPPED,218 EVENT_STOPPED,
219 EVENT_PORT_AUTHORIZED,
219};220};
220 221
221struct cfg80211_event {222struct cfg80211_event {
@@ -235,6 +236,9 @@ struct cfg80211_event { · 13 unmodified lines
235 u8 bssid[ETH_ALEN];236 u8 bssid[ETH_ALEN];
236 struct ieee80211_channel *channel;237 struct ieee80211_channel *channel;
237 } ij;238 } ij;
239 struct {
240 u8 bssid[ETH_ALEN];
241 } pa;
238 };242 };
239};243};
240 244
@@ -385,6 +389,7 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev, · 144 unmodified lines
385 bool wextev);389 bool wextev);
386void __cfg80211_roamed(struct wireless_dev *wdev,390void __cfg80211_roamed(struct wireless_dev *wdev,
387 struct cfg80211_roam_info *info);391 struct cfg80211_roam_info *info);
392void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid);
388int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,393int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
389 struct wireless_dev *wdev);394 struct wireless_dev *wdev);
390void cfg80211_autodisconnect_wk(struct work_struct *work);395void cfg80211_autodisconnect_wk(struct work_struct *work);
net/wireless/db.txt+0−17
@@ -1,17 +0,0 @@
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#
net/wireless/genregdb.awk+0−158
@@ -1,158 +0,0 @@
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
22BEGIN {
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
36function 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
52function 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
123function 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
144active && /^[ \t]*\(/ {
145 parse_reg_rule()
146}
147
148active && /^[ \t]*$/ {
149 print_tail_country()
150}
151
152END {
153 if (active)
154 print_tail_country()
155 print regdb "};"
156 print ""
157 print "int reg_regdb_size = ARRAY_SIZE(reg_regdb);"
158}
net/wireless/nl80211.c+136−63
@@ -2130,6 +2130,15 @@ static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, · 2129 unmodified lines
2130 case NL80211_CHAN_HT40MINUS:2130 case NL80211_CHAN_HT40MINUS:
2131 cfg80211_chandef_create(chandef, chandef->chan,2131 cfg80211_chandef_create(chandef, chandef->chan,
2132 chantype);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 break;2142 break;
2134 default:2143 default:
2135 return -EINVAL;2144 return -EINVAL;
@@ -5677,6 +5686,11 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) · 3541 unmodified lines
5677 }5686 }
5678}5687}
5679 5688
5689static int nl80211_reload_regdb(struct sk_buff *skb, struct genl_info *info)
5690{
5691 return reg_reload_regdb();
5692}
5693
5680static int nl80211_get_mesh_config(struct sk_buff *skb,5694static int nl80211_get_mesh_config(struct sk_buff *skb,
5681 struct genl_info *info)5695 struct genl_info *info)
5682{5696{
@@ -6618,6 +6632,77 @@ static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev) · 935 unmodified lines
6618 return regulatory_pre_cac_allowed(wdev->wiphy);6632 return regulatory_pre_cac_allowed(wdev->wiphy);
6619}6633}
6620 6634
6635static int
6636nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
6637 void *request, struct nlattr **attrs,
6638 bool is_sched_scan)
6639{
6640 u8 *mac_addr, *mac_addr_mask;
6641 u32 *flags;
6642 enum nl80211_feature_flags randomness_flag;
6643
6644 if (!attrs[NL80211_ATTR_SCAN_FLAGS])
6645 return 0;
6646
6647 if (is_sched_scan) {
6648 struct cfg80211_sched_scan_request *req = request;
6649
6650 randomness_flag = wdev ?
6651 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR :
6652 NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
6653 flags = &req->flags;
6654 mac_addr = req->mac_addr;
6655 mac_addr_mask = req->mac_addr_mask;
6656 } else {
6657 struct cfg80211_scan_request *req = request;
6658
6659 randomness_flag = NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
6660 flags = &req->flags;
6661 mac_addr = req->mac_addr;
6662 mac_addr_mask = req->mac_addr_mask;
6663 }
6664
6665 *flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
6666
6667 if ((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
6668 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN))
6669 return -EOPNOTSUPP;
6670
6671 if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
6672 int err;
6673
6674 if (!(wiphy->features & randomness_flag) ||
6675 (wdev && wdev->current_bss))
6676 return -EOPNOTSUPP;
6677
6678 err = nl80211_parse_random_mac(attrs, mac_addr, mac_addr_mask);
6679 if (err)
6680 return err;
6681 }
6682
6683 if ((*flags & NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME) &&
6684 !wiphy_ext_feature_isset(wiphy,
6685 NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME))
6686 return -EOPNOTSUPP;
6687
6688 if ((*flags & NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP) &&
6689 !wiphy_ext_feature_isset(wiphy,
6690 NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP))
6691 return -EOPNOTSUPP;
6692
6693 if ((*flags & NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) &&
6694 !wiphy_ext_feature_isset(wiphy,
6695 NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION))
6696 return -EOPNOTSUPP;
6697
6698 if ((*flags & NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE) &&
6699 !wiphy_ext_feature_isset(wiphy,
6700 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE))
6701 return -EOPNOTSUPP;
6702
6703 return 0;
6704}
6705
6621static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)6706static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
6622{6707{
6623 struct cfg80211_registered_device *rdev = info->user_ptr[0];6708 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -6823,34 +6908,10 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) · 199 unmodified lines
6823 nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);6908 nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
6824 }6909 }
6825 6910
6826 if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) {6911 err = nl80211_check_scan_flags(wiphy, wdev, request, info->attrs,
6827 request->flags = nla_get_u32(6912 false);
6828 info->attrs[NL80211_ATTR_SCAN_FLAGS]);6913 if (err)
6829 if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&6914 goto out_free;
6830 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
6831 err = -EOPNOTSUPP;
6832 goto out_free;
6833 }
6834
6835 if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
6836 if (!(wiphy->features &
6837 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR)) {
6838 err = -EOPNOTSUPP;
6839 goto out_free;
6840 }
6841
6842 if (wdev->current_bss) {
6843 err = -EOPNOTSUPP;
6844 goto out_free;
6845 }
6846
6847 err = nl80211_parse_random_mac(info->attrs,
6848 request->mac_addr,
6849 request->mac_addr_mask);
6850 if (err)
6851 goto out_free;
6852 }
6853 }
6854 6915
6855 request->no_cck =6916 request->no_cck =
6856 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);6917 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
@@ -7298,37 +7359,9 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev, · 441 unmodified lines
7298 request->ie_len);7359 request->ie_len);
7299 }7360 }
7300 7361
7301 if (attrs[NL80211_ATTR_SCAN_FLAGS]) {7362 err = nl80211_check_scan_flags(wiphy, wdev, request, attrs, true);
7302 request->flags = nla_get_u32(7363 if (err)
7303 attrs[NL80211_ATTR_SCAN_FLAGS]);7364 goto out_free;
7304 if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
7305 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
7306 err = -EOPNOTSUPP;
7307 goto out_free;
7308 }
7309
7310 if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
7311 u32 flg = NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
7312
7313 if (!wdev) /* must be net-detect */
7314 flg = NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
7315
7316 if (!(wiphy->features & flg)) {
7317 err = -EOPNOTSUPP;
7318 goto out_free;
7319 }
7320
7321 if (wdev && wdev->current_bss) {
7322 err = -EOPNOTSUPP;
7323 goto out_free;
7324 }
7325
7326 err = nl80211_parse_random_mac(attrs, request->mac_addr,
7327 request->mac_addr_mask);
7328 if (err)
7329 goto out_free;
7330 }
7331 }
7332 7365
7333 if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])7366 if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])
7334 request->delay =7367 request->delay =
@@ -8932,8 +8965,14 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) · 1597 unmodified lines
8932 8965
8933 if (info->attrs[NL80211_ATTR_USE_MFP]) {8966 if (info->attrs[NL80211_ATTR_USE_MFP]) {
8934 connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);8967 connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
8968 if (connect.mfp == NL80211_MFP_OPTIONAL &&
8969 !wiphy_ext_feature_isset(&rdev->wiphy,
8970 NL80211_EXT_FEATURE_MFP_OPTIONAL))
8971 return -EOPNOTSUPP;
8972
8935 if (connect.mfp != NL80211_MFP_REQUIRED &&8973 if (connect.mfp != NL80211_MFP_REQUIRED &&
8936 connect.mfp != NL80211_MFP_NO)8974 connect.mfp != NL80211_MFP_NO &&
8975 connect.mfp != NL80211_MFP_OPTIONAL)
8937 return -EINVAL;8976 return -EINVAL;
8938 } else {8977 } else {
8939 connect.mfp = NL80211_MFP_NO;8978 connect.mfp = NL80211_MFP_NO;
@@ -12684,6 +12723,12 @@ static const struct genl_ops nl80211_ops[] = { · 3744 unmodified lines
12684 .policy = nl80211_policy,12723 .policy = nl80211_policy,
12685 .flags = GENL_ADMIN_PERM,12724 .flags = GENL_ADMIN_PERM,
12686 },12725 },
12726 {
12727 .cmd = NL80211_CMD_RELOAD_REGDB,
12728 .doit = nl80211_reload_regdb,
12729 .policy = nl80211_policy,
12730 .flags = GENL_ADMIN_PERM,
12731 },
12687 {12732 {
12688 .cmd = NL80211_CMD_GET_MESH_CONFIG,12733 .cmd = NL80211_CMD_GET_MESH_CONFIG,
12689 .doit = nl80211_get_mesh_config,12734 .doit = nl80211_get_mesh_config,
@@ -13812,9 +13857,7 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev, · 1122 unmodified lines
13812 info->req_ie)) ||13857 info->req_ie)) ||
13813 (info->resp_ie &&13858 (info->resp_ie &&
13814 nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len,13859 nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len,
13815 info->resp_ie)) ||13860 info->resp_ie)))
13816 (info->authorized &&
13817 nla_put_flag(msg, NL80211_ATTR_PORT_AUTHORIZED)))
13818 goto nla_put_failure;13861 goto nla_put_failure;
13819 13862
13820 genlmsg_end(msg, hdr);13863 genlmsg_end(msg, hdr);
@@ -13828,6 +13871,36 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev, · 7 unmodified lines
13828 nlmsg_free(msg);13871 nlmsg_free(msg);
13829}13872}
13830 13873
13874void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
13875 struct net_device *netdev, const u8 *bssid)
13876{
13877 struct sk_buff *msg;
13878 void *hdr;
13879
13880 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13881 if (!msg)
13882 return;
13883
13884 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PORT_AUTHORIZED);
13885 if (!hdr) {
13886 nlmsg_free(msg);
13887 return;
13888 }
13889
13890 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
13891 goto nla_put_failure;
13892
13893 genlmsg_end(msg, hdr);
13894
13895 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
13896 NL80211_MCGRP_MLME, GFP_KERNEL);
13897 return;
13898
13899 nla_put_failure:
13900 genlmsg_cancel(msg, hdr);
13901 nlmsg_free(msg);
13902}
13903
13831void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,13904void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
13832 struct net_device *netdev, u16 reason,13905 struct net_device *netdev, u16 reason,
13833 const u8 *ie, size_t ie_len, bool from_ap)13906 const u8 *ie, size_t ie_len, bool from_ap)
net/wireless/nl80211.h+2−0
@@ -58,6 +58,8 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev, · 57 unmodified lines
58void nl80211_send_roamed(struct cfg80211_registered_device *rdev,58void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
59 struct net_device *netdev,59 struct net_device *netdev,
60 struct cfg80211_roam_info *info, gfp_t gfp);60 struct cfg80211_roam_info *info, gfp_t gfp);
61void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
62 struct net_device *netdev, const u8 *bssid);
61void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,63void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
62 struct net_device *netdev, u16 reason,64 struct net_device *netdev, u16 reason,
63 const u8 *ie, size_t ie_len, bool from_ap);65 const u8 *ie, size_t ie_len, bool from_ap);
net/wireless/reg.c+411−41
@@ -53,12 +53,13 @@ · 52 unmodified lines
53#include <linux/ctype.h>53#include <linux/ctype.h>
54#include <linux/nl80211.h>54#include <linux/nl80211.h>
55#include <linux/platform_device.h>55#include <linux/platform_device.h>
56#include <linux/verification.h>
56#include <linux/moduleparam.h>57#include <linux/moduleparam.h>
58#include <linux/firmware.h>
57#include <net/cfg80211.h>59#include <net/cfg80211.h>
58#include "core.h"60#include "core.h"
59#include "reg.h"61#include "reg.h"
60#include "rdev-ops.h"62#include "rdev-ops.h"
61#include "regdb.h"
62#include "nl80211.h"63#include "nl80211.h"
63 64
64/*65/*
@@ -100,7 +101,7 @@ static struct regulatory_request core_request_world = { · 35 unmodified lines
100static struct regulatory_request __rcu *last_request =101static struct regulatory_request __rcu *last_request =
101 (void __force __rcu *)&core_request_world;102 (void __force __rcu *)&core_request_world;
102 103
103/* To trigger userspace events */104/* To trigger userspace events and load firmware */
104static struct platform_device *reg_pdev;105static struct platform_device *reg_pdev;
105 106
106/*107/*
@@ -443,7 +444,6 @@ reg_copy_regd(const struct ieee80211_regdomain *src_regd) · 336 unmodified lines
443 return regd;444 return regd;
444}445}
445 446
446#ifdef CONFIG_CFG80211_INTERNAL_REGDB
447struct reg_regdb_apply_request {447struct reg_regdb_apply_request {
448 struct list_head list;448 struct list_head list;
449 const struct ieee80211_regdomain *regdom;449 const struct ieee80211_regdomain *regdom;
@@ -475,55 +475,26 @@ static void reg_regdb_apply(struct work_struct *work) · 25 unmodified lines
475 475
476static DECLARE_WORK(reg_regdb_work, reg_regdb_apply);476static DECLARE_WORK(reg_regdb_work, reg_regdb_apply);
477 477
478static int reg_query_builtin(const char *alpha2)478static int reg_schedule_apply(const struct ieee80211_regdomain *regdom)
479{479{
480 const struct ieee80211_regdomain *regdom = NULL;
481 struct reg_regdb_apply_request *request;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 request = kzalloc(sizeof(struct reg_regdb_apply_request), GFP_KERNEL);482 request = kzalloc(sizeof(struct reg_regdb_apply_request), GFP_KERNEL);
495 if (!request)483 if (!request) {
496 return -ENOMEM;484 kfree(regdom);
497
498 request->regdom = reg_copy_regd(regdom);
499 if (IS_ERR_OR_NULL(request->regdom)) {
500 kfree(request);
501 return -ENOMEM;485 return -ENOMEM;
502 }486 }
503 487
488 request->regdom = regdom;
489
504 mutex_lock(&reg_regdb_apply_mutex);490 mutex_lock(&reg_regdb_apply_mutex);
505 list_add_tail(&request->list, &reg_regdb_apply_list);491 list_add_tail(&request->list, &reg_regdb_apply_list);
506 mutex_unlock(&reg_regdb_apply_mutex);492 mutex_unlock(&reg_regdb_apply_mutex);
507 493
508 schedule_work(&reg_regdb_work);494 schedule_work(&reg_regdb_work);
509
510 return 0;495 return 0;
511}496}
512 497
513/* Feel free to add any other sanity checks here */
514static 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
520static inline void reg_regdb_size_check(void) {}
521static inline int reg_query_builtin(const char *alpha2)
522{
523 return -ENODATA;
524}
525#endif /* CONFIG_CFG80211_INTERNAL_REGDB */
526
527#ifdef CONFIG_CFG80211_CRDA_SUPPORT498#ifdef CONFIG_CFG80211_CRDA_SUPPORT
528/* Max number of consecutive attempts to communicate with CRDA */499/* Max number of consecutive attempts to communicate with CRDA */
529#define REG_MAX_CRDA_TIMEOUTS 10500#define REG_MAX_CRDA_TIMEOUTS 10
@@ -599,10 +570,402 @@ static inline int call_crda(const char *alpha2) · 69 unmodified lines
599}570}
600#endif /* CONFIG_CFG80211_CRDA_SUPPORT */571#endif /* CONFIG_CFG80211_CRDA_SUPPORT */
601 572
573/* code to directly load a firmware database through request_firmware */
574static const struct fwdb_header *regdb;
575
576struct fwdb_country {
577 u8 alpha2[2];
578 __be16 coll_ptr;
579 /* this struct cannot be extended */
580} __packed __aligned(4);
581
582struct fwdb_collection {
583 u8 len;
584 u8 n_rules;
585 u8 dfs_region;
586 /* no optional data yet */
587 /* aligned to 2, then followed by __be16 array of rule pointers */
588} __packed __aligned(4);
589
590enum fwdb_flags {
591 FWDB_FLAG_NO_OFDM = BIT(0),
592 FWDB_FLAG_NO_OUTDOOR = BIT(1),
593 FWDB_FLAG_DFS = BIT(2),
594 FWDB_FLAG_NO_IR = BIT(3),
595 FWDB_FLAG_AUTO_BW = BIT(4),
596};
597
598struct fwdb_rule {
599 u8 len;
600 u8 flags;
601 __be16 max_eirp;
602 __be32 start, end, max_bw;
603 /* start of optional data */
604 __be16 cac_timeout;
605} __packed __aligned(4);
606
607#define FWDB_MAGIC 0x52474442
608#define FWDB_VERSION 20
609
610struct fwdb_header {
611 __be32 magic;
612 __be32 version;
613 struct fwdb_country country[];
614} __packed __aligned(4);
615
616static bool valid_rule(const u8 *data, unsigned int size, u16 rule_ptr)
617{
618 struct fwdb_rule *rule = (void *)(data + (rule_ptr << 2));
619
620 if ((u8 *)rule + sizeof(rule->len) > data + size)
621 return false;
622
623 /* mandatory fields */
624 if (rule->len < offsetofend(struct fwdb_rule, max_bw))
625 return false;
626
627 return true;
628}
629
630static bool valid_country(const u8 *data, unsigned int size,
631 const struct fwdb_country *country)
632{
633 unsigned int ptr = be16_to_cpu(country->coll_ptr) << 2;
634 struct fwdb_collection *coll = (void *)(data + ptr);
635 __be16 *rules_ptr;
636 unsigned int i;
637
638 /* make sure we can read len/n_rules */
639 if ((u8 *)coll + offsetofend(typeof(*coll), n_rules) > data + size)
640 return false;
641
642 /* make sure base struct and all rules fit */
643 if ((u8 *)coll + ALIGN(coll->len, 2) +
644 (coll->n_rules * 2) > data + size)
645 return false;
646
647 /* mandatory fields must exist */
648 if (coll->len < offsetofend(struct fwdb_collection, dfs_region))
649 return false;
650
651 rules_ptr = (void *)((u8 *)coll + ALIGN(coll->len, 2));
652
653 for (i = 0; i < coll->n_rules; i++) {
654 u16 rule_ptr = be16_to_cpu(rules_ptr[i]);
655
656 if (!valid_rule(data, size, rule_ptr))
657 return false;
658 }
659
660 return true;
661}
662
663#ifdef CONFIG_CFG80211_REQUIRE_SIGNED_REGDB
664static struct key *builtin_regdb_keys;
665
666static void __init load_keys_from_buffer(const u8 *p, unsigned int buflen)
667{
668 const u8 *end = p + buflen;
669 size_t plen;
670 key_ref_t key;
671
672 while (p < end) {
673 /* Each cert begins with an ASN.1 SEQUENCE tag and must be more
674 * than 256 bytes in size.
675 */
676 if (end - p < 4)
677 goto dodgy_cert;
678 if (p[0] != 0x30 &&
679 p[1] != 0x82)
680 goto dodgy_cert;
681 plen = (p[2] << 8) | p[3];
682 plen += 4;
683 if (plen > end - p)
684 goto dodgy_cert;
685
686 key = key_create_or_update(make_key_ref(builtin_regdb_keys, 1),
687 "asymmetric", NULL, p, plen,
688 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
689 KEY_USR_VIEW | KEY_USR_READ),
690 KEY_ALLOC_NOT_IN_QUOTA |
691 KEY_ALLOC_BUILT_IN |
692 KEY_ALLOC_BYPASS_RESTRICTION);
693 if (IS_ERR(key)) {
694 pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
695 PTR_ERR(key));
696 } else {
697 pr_notice("Loaded X.509 cert '%s'\n",
698 key_ref_to_ptr(key)->description);
699 key_ref_put(key);
700 }
701 p += plen;
702 }
703
704 return;
705
706dodgy_cert:
707 pr_err("Problem parsing in-kernel X.509 certificate list\n");
708}
709
710static int __init load_builtin_regdb_keys(void)
711{
712 builtin_regdb_keys =
713 keyring_alloc(".builtin_regdb_keys",
714 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
715 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
716 KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),
717 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
718 if (IS_ERR(builtin_regdb_keys))
719 return PTR_ERR(builtin_regdb_keys);
720
721 pr_notice("Loading compiled-in X.509 certificates for regulatory database\n");
722
723#ifdef CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS
724 load_keys_from_buffer(shipped_regdb_certs, shipped_regdb_certs_len);
725#endif
726#ifdef CFG80211_EXTRA_REGDB_KEYDIR
727 if (CONFIG_CFG80211_EXTRA_REGDB_KEYDIR[0] != '\0')
728 load_keys_from_buffer(extra_regdb_certs, extra_regdb_certs_len);
729#endif
730
731 return 0;
732}
733
734static bool regdb_has_valid_signature(const u8 *data, unsigned int size)
735{
736 const struct firmware *sig;
737 bool result;
738
739 if (request_firmware(&sig, "regulatory.db.p7s", &reg_pdev->dev))
740 return false;
741
742 result = verify_pkcs7_signature(data, size, sig->data, sig->size,
743 builtin_regdb_keys,
744 VERIFYING_UNSPECIFIED_SIGNATURE,
745 NULL, NULL) == 0;
746
747 release_firmware(sig);
748
749 return result;
750}
751
752static void free_regdb_keyring(void)
753{
754 key_put(builtin_regdb_keys);
755}
756#else
757static int load_builtin_regdb_keys(void)
758{
759 return 0;
760}
761
762static bool regdb_has_valid_signature(const u8 *data, unsigned int size)
763{
764 return true;
765}
766
767static void free_regdb_keyring(void)
768{
769}
770#endif /* CONFIG_CFG80211_REQUIRE_SIGNED_REGDB */
771
772static bool valid_regdb(const u8 *data, unsigned int size)
773{
774 const struct fwdb_header *hdr = (void *)data;
775 const struct fwdb_country *country;
776
777 if (size < sizeof(*hdr))
778 return false;
779
780 if (hdr->magic != cpu_to_be32(FWDB_MAGIC))
781 return false;
782
783 if (hdr->version != cpu_to_be32(FWDB_VERSION))
784 return false;
785
786 if (!regdb_has_valid_signature(data, size))
787 return false;
788
789 country = &hdr->country[0];
790 while ((u8 *)(country + 1) <= data + size) {
791 if (!country->coll_ptr)
792 break;
793 if (!valid_country(data, size, country))
794 return false;
795 country++;
796 }
797
798 return true;
799}
800
801static int regdb_query_country(const struct fwdb_header *db,
802 const struct fwdb_country *country)
803{
804 unsigned int ptr = be16_to_cpu(country->coll_ptr) << 2;
805 struct fwdb_collection *coll = (void *)((u8 *)db + ptr);
806 struct ieee80211_regdomain *regdom;
807 unsigned int size_of_regd;
808 unsigned int i;
809
810 size_of_regd =
811 sizeof(struct ieee80211_regdomain) +
812 coll->n_rules * sizeof(struct ieee80211_reg_rule);
813
814 regdom = kzalloc(size_of_regd, GFP_KERNEL);
815 if (!regdom)
816 return -ENOMEM;
817
818 regdom->n_reg_rules = coll->n_rules;
819 regdom->alpha2[0] = country->alpha2[0];
820 regdom->alpha2[1] = country->alpha2[1];
821 regdom->dfs_region = coll->dfs_region;
822
823 for (i = 0; i < regdom->n_reg_rules; i++) {
824 __be16 *rules_ptr = (void *)((u8 *)coll + ALIGN(coll->len, 2));
825 unsigned int rule_ptr = be16_to_cpu(rules_ptr[i]) << 2;
826 struct fwdb_rule *rule = (void *)((u8 *)db + rule_ptr);
827 struct ieee80211_reg_rule *rrule = &regdom->reg_rules[i];
828
829 rrule->freq_range.start_freq_khz = be32_to_cpu(rule->start);
830 rrule->freq_range.end_freq_khz = be32_to_cpu(rule->end);
831 rrule->freq_range.max_bandwidth_khz = be32_to_cpu(rule->max_bw);
832
833 rrule->power_rule.max_antenna_gain = 0;
834 rrule->power_rule.max_eirp = be16_to_cpu(rule->max_eirp);
835
836 rrule->flags = 0;
837 if (rule->flags & FWDB_FLAG_NO_OFDM)
838 rrule->flags |= NL80211_RRF_NO_OFDM;
839 if (rule->flags & FWDB_FLAG_NO_OUTDOOR)
840 rrule->flags |= NL80211_RRF_NO_OUTDOOR;
841 if (rule->flags & FWDB_FLAG_DFS)
842 rrule->flags |= NL80211_RRF_DFS;
843 if (rule->flags & FWDB_FLAG_NO_IR)
844 rrule->flags |= NL80211_RRF_NO_IR;
845 if (rule->flags & FWDB_FLAG_AUTO_BW)
846 rrule->flags |= NL80211_RRF_AUTO_BW;
847
848 rrule->dfs_cac_ms = 0;
849
850 /* handle optional data */
851 if (rule->len >= offsetofend(struct fwdb_rule, cac_timeout))
852 rrule->dfs_cac_ms =
853 1000 * be16_to_cpu(rule->cac_timeout);
854 }
855
856 return reg_schedule_apply(regdom);
857}
858
859static int query_regdb(const char *alpha2)
860{
861 const struct fwdb_header *hdr = regdb;
862 const struct fwdb_country *country;
863
864 ASSERT_RTNL();
865
866 if (IS_ERR(regdb))
867 return PTR_ERR(regdb);
868
869 country = &hdr->country[0];
870 while (country->coll_ptr) {
871 if (alpha2_equal(alpha2, country->alpha2))
872 return regdb_query_country(regdb, country);
873 country++;
874 }
875
876 return -ENODATA;
877}
878
879static void regdb_fw_cb(const struct firmware *fw, void *context)
880{
881 int set_error = 0;
882 bool restore = true;
883 void *db;
884
885 if (!fw) {
886 pr_info("failed to load regulatory.db\n");
887 set_error = -ENODATA;
888 } else if (!valid_regdb(fw->data, fw->size)) {
889 pr_info("loaded regulatory.db is malformed or signature is missing/invalid\n");
890 set_error = -EINVAL;
891 }
892
893 rtnl_lock();
894 if (WARN_ON(regdb && !IS_ERR(regdb))) {
895 /* just restore and free new db */
896 } else if (set_error) {
897 regdb = ERR_PTR(set_error);
898 } else if (fw) {
899 db = kmemdup(fw->data, fw->size, GFP_KERNEL);
900 if (db) {
901 regdb = db;
902 restore = context && query_regdb(context);
903 } else {
904 restore = true;
905 }
906 }
907
908 if (restore)
909 restore_regulatory_settings(true);
910
911 rtnl_unlock();
912
913 kfree(context);
914
915 release_firmware(fw);
916}
917
918static int query_regdb_file(const char *alpha2)
919{
920 ASSERT_RTNL();
921
922 if (regdb)
923 return query_regdb(alpha2);
924
925 alpha2 = kmemdup(alpha2, 2, GFP_KERNEL);
926 if (!alpha2)
927 return -ENOMEM;
928
929 return request_firmware_nowait(THIS_MODULE, true, "regulatory.db",
930 &reg_pdev->dev, GFP_KERNEL,
931 (void *)alpha2, regdb_fw_cb);
932}
933
934int reg_reload_regdb(void)
935{
936 const struct firmware *fw;
937 void *db;
938 int err;
939
940 err = request_firmware(&fw, "regulatory.db", &reg_pdev->dev);
941 if (err)
942 return err;
943
944 if (!valid_regdb(fw->data, fw->size)) {
945 err = -ENODATA;
946 goto out;
947 }
948
949 db = kmemdup(fw->data, fw->size, GFP_KERNEL);
950 if (!db) {
951 err = -ENOMEM;
952 goto out;
953 }
954
955 rtnl_lock();
956 if (!IS_ERR_OR_NULL(regdb))
957 kfree(regdb);
958 regdb = db;
959 rtnl_unlock();
960
961 out:
962 release_firmware(fw);
963 return err;
964}
965
602static bool reg_query_database(struct regulatory_request *request)966static bool reg_query_database(struct regulatory_request *request)
603{967{
604 /* query internal regulatory database (if it exists) */968 if (query_regdb_file(request->alpha2) == 0)
605 if (reg_query_builtin(request->alpha2) == 0)
606 return true;969 return true;
607 970
608 if (call_crda(request->alpha2) == 0)971 if (call_crda(request->alpha2) == 0)
@@ -3285,6 +3648,10 @@ int __init regulatory_init(void) · 2676 unmodified lines
3285{3648{
3286 int err = 0;3649 int err = 0;
3287 3650
3651 err = load_builtin_regdb_keys();
3652 if (err)
3653 return err;
3654
3288 reg_pdev = platform_device_register_simple("regulatory", 0, NULL, 0);3655 reg_pdev = platform_device_register_simple("regulatory", 0, NULL, 0);
3289 if (IS_ERR(reg_pdev))3656 if (IS_ERR(reg_pdev))
3290 return PTR_ERR(reg_pdev);3657 return PTR_ERR(reg_pdev);
@@ -3293,8 +3660,6 @@ int __init regulatory_init(void) · 2 unmodified lines
3293 spin_lock_init(&reg_pending_beacons_lock);3660 spin_lock_init(&reg_pending_beacons_lock);
3294 spin_lock_init(&reg_indoor_lock);3661 spin_lock_init(&reg_indoor_lock);
3295 3662
3296 reg_regdb_size_check();
3297
3298 rcu_assign_pointer(cfg80211_regdomain, cfg80211_world_regdom);3663 rcu_assign_pointer(cfg80211_regdomain, cfg80211_world_regdom);
3299 3664
3300 user_alpha2[0] = '9';3665 user_alpha2[0] = '9';
@@ -3360,4 +3725,9 @@ void regulatory_exit(void) · 59 unmodified lines
3360 list_del(&reg_request->list);3725 list_del(&reg_request->list);
3361 kfree(reg_request);3726 kfree(reg_request);
3362 }3727 }
3728
3729 if (!IS_ERR_OR_NULL(regdb))
3730 kfree(regdb);
3731
3732 free_regdb_keyring();
3363}3733}
net/wireless/reg.h+14−0
@@ -1,5 +1,8 @@
1#ifndef __NET_WIRELESS_REG_H1#ifndef __NET_WIRELESS_REG_H
2#define __NET_WIRELESS_REG_H2#define __NET_WIRELESS_REG_H
3
4#include <net/cfg80211.h>
5
3/*6/*
4 * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com>7 * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
5 *8 *
@@ -179,4 +182,15 @@ void regulatory_propagate_dfs_state(struct wiphy *wiphy, · 173 unmodified lines
179 * @wiphy2 - wiphy it's dfs_region to be checked against that of wiphy1182 * @wiphy2 - wiphy it's dfs_region to be checked against that of wiphy1
180 */183 */
181bool reg_dfs_domain_same(struct wiphy *wiphy1, struct wiphy *wiphy2);184bool reg_dfs_domain_same(struct wiphy *wiphy1, struct wiphy *wiphy2);
185
186/**
187 * reg_reload_regdb - reload the regulatory.db firmware file
188 */
189int reg_reload_regdb(void);
190
191extern const u8 shipped_regdb_certs[];
192extern unsigned int shipped_regdb_certs_len;
193extern const u8 extra_regdb_certs[];
194extern unsigned int extra_regdb_certs_len;
195
182#endif /* __NET_WIRELESS_REG_H */196#endif /* __NET_WIRELESS_REG_H */
net/wireless/regdb.h+0−23
@@ -1,23 +0,0 @@
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
20extern const struct ieee80211_regdomain *reg_regdb[];
21extern int reg_regdb_size;
22
23#endif /* __REGDB_H__ */
net/wireless/sme.c+44−1
@@ -960,7 +960,6 @@ void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info, · 959 unmodified lines
960 ev->rm.resp_ie_len = info->resp_ie_len;960 ev->rm.resp_ie_len = info->resp_ie_len;
961 memcpy((void *)ev->rm.resp_ie, info->resp_ie, info->resp_ie_len);961 memcpy((void *)ev->rm.resp_ie, info->resp_ie, info->resp_ie_len);
962 ev->rm.bss = info->bss;962 ev->rm.bss = info->bss;
963 ev->rm.authorized = info->authorized;
964 963
965 spin_lock_irqsave(&wdev->event_lock, flags);964 spin_lock_irqsave(&wdev->event_lock, flags);
966 list_add_tail(&ev->list, &wdev->event_list);965 list_add_tail(&ev->list, &wdev->event_list);
@@ -969,6 +968,50 @@ void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info, · 2 unmodified lines
969}968}
970EXPORT_SYMBOL(cfg80211_roamed);969EXPORT_SYMBOL(cfg80211_roamed);
971 970
971void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid)
972{
973 ASSERT_WDEV_LOCK(wdev);
974
975 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
976 return;
977
978 if (WARN_ON(!wdev->current_bss) ||
979 WARN_ON(!ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
980 return;
981
982 nl80211_send_port_authorized(wiphy_to_rdev(wdev->wiphy), wdev->netdev,
983 bssid);
984}
985
986void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid,
987 gfp_t gfp)
988{
989 struct wireless_dev *wdev = dev->ieee80211_ptr;
990 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
991 struct cfg80211_event *ev;
992 unsigned long flags;
993
994 if (WARN_ON(!bssid))
995 return;
996
997 ev = kzalloc(sizeof(*ev), gfp);
998 if (!ev)
999 return;
1000
1001 ev->type = EVENT_PORT_AUTHORIZED;
1002 memcpy(ev->pa.bssid, bssid, ETH_ALEN);
1003
1004 /*
1005 * Use the wdev event list so that if there are pending
1006 * connected/roamed events, they will be reported first.
1007 */
1008 spin_lock_irqsave(&wdev->event_lock, flags);
1009 list_add_tail(&ev->list, &wdev->event_list);
1010 spin_unlock_irqrestore(&wdev->event_lock, flags);
1011 queue_work(cfg80211_wq, &rdev->event_work);
1012}
1013EXPORT_SYMBOL(cfg80211_port_authorized);
1014
972void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,1015void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
973 size_t ie_len, u16 reason, bool from_ap)1016 size_t ie_len, u16 reason, bool from_ap)
974{1017{
net/wireless/util.c+63−139
@@ -157,32 +157,30 @@ static void set_mandatory_flags_band(struct ieee80211_supported_band *sband) · 156 unmodified lines
157 case NL80211_BAND_2GHZ:157 case NL80211_BAND_2GHZ:
158 want = 7;158 want = 7;
159 for (i = 0; i < sband->n_bitrates; i++) {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 sband->bitrates[i].flags |=165 sband->bitrates[i].flags |=
162 IEEE80211_RATE_MANDATORY_B |166 IEEE80211_RATE_MANDATORY_B |
163 IEEE80211_RATE_MANDATORY_G;167 IEEE80211_RATE_MANDATORY_G;
164 want--;168 want--;
165 }169 break;
166 170 case 60:
167 if (sband->bitrates[i].bitrate == 20 ||171 case 120:
168 sband->bitrates[i].bitrate == 55 ||172 case 240:
169 sband->bitrates[i].bitrate == 110 ||
170 sband->bitrates[i].bitrate == 60 ||
171 sband->bitrates[i].bitrate == 120 ||
172 sband->bitrates[i].bitrate == 240) {
173 sband->bitrates[i].flags |=173 sband->bitrates[i].flags |=
174 IEEE80211_RATE_MANDATORY_G;174 IEEE80211_RATE_MANDATORY_G;
175 want--;175 want--;
176 }176 /* fall through */
177 177 default:
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)
182 sband->bitrates[i].flags |=178 sband->bitrates[i].flags |=
183 IEEE80211_RATE_ERP_G;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 break;184 break;
187 case NL80211_BAND_60GHZ:185 case NL80211_BAND_60GHZ:
188 /* check for mandatory HT MCS 1..4 */186 /* check for mandatory HT MCS 1..4 */
@@ -529,121 +527,6 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, · 340 unmodified lines
529}527}
530EXPORT_SYMBOL(ieee80211_data_to_8023_exthdr);528EXPORT_SYMBOL(ieee80211_data_to_8023_exthdr);
531 529
532int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
533 enum nl80211_iftype iftype,
534 const u8 *bssid, bool qos)
535{
536 struct ieee80211_hdr hdr;
537 u16 hdrlen, ethertype;
538 __le16 fc;
539 const u8 *encaps_data;
540 int encaps_len, skip_header_bytes;
541 int nh_pos, h_pos;
542 int head_need;
543
544 if (unlikely(skb->len < ETH_HLEN))
545 return -EINVAL;
546
547 nh_pos = skb_network_header(skb) - skb->data;
548 h_pos = skb_transport_header(skb) - skb->data;
549
550 /* convert Ethernet header to proper 802.11 header (based on
551 * operation mode) */
552 ethertype = (skb->data[12] << 8) | skb->data[13];
553 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
554
555 switch (iftype) {
556 case NL80211_IFTYPE_AP:
557 case NL80211_IFTYPE_AP_VLAN:
558 case NL80211_IFTYPE_P2P_GO:
559 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
560 /* DA BSSID SA */
561 memcpy(hdr.addr1, skb->data, ETH_ALEN);
562 memcpy(hdr.addr2, addr, ETH_ALEN);
563 memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN);
564 hdrlen = 24;
565 break;
566 case NL80211_IFTYPE_STATION:
567 case NL80211_IFTYPE_P2P_CLIENT:
568 fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
569 /* BSSID SA DA */
570 memcpy(hdr.addr1, bssid, ETH_ALEN);
571 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
572 memcpy(hdr.addr3, skb->data, ETH_ALEN);
573 hdrlen = 24;
574 break;
575 case NL80211_IFTYPE_OCB:
576 case NL80211_IFTYPE_ADHOC:
577 /* DA SA BSSID */
578 memcpy(hdr.addr1, skb->data, ETH_ALEN);
579 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
580 memcpy(hdr.addr3, bssid, ETH_ALEN);
581 hdrlen = 24;
582 break;
583 default:
584 return -EOPNOTSUPP;
585 }
586
587 if (qos) {
588 fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
589 hdrlen += 2;
590 }
591
592 hdr.frame_control = fc;
593 hdr.duration_id = 0;
594 hdr.seq_ctrl = 0;
595
596 skip_header_bytes = ETH_HLEN;
597 if (ethertype == ETH_P_AARP || ethertype == ETH_P_IPX) {
598 encaps_data = bridge_tunnel_header;
599 encaps_len = sizeof(bridge_tunnel_header);
600 skip_header_bytes -= 2;
601 } else if (ethertype >= ETH_P_802_3_MIN) {
602 encaps_data = rfc1042_header;
603 encaps_len = sizeof(rfc1042_header);
604 skip_header_bytes -= 2;
605 } else {
606 encaps_data = NULL;
607 encaps_len = 0;
608 }
609
610 skb_pull(skb, skip_header_bytes);
611 nh_pos -= skip_header_bytes;
612 h_pos -= skip_header_bytes;
613
614 head_need = hdrlen + encaps_len - skb_headroom(skb);
615
616 if (head_need > 0 || skb_cloned(skb)) {
617 head_need = max(head_need, 0);
618 if (head_need)
619 skb_orphan(skb);
620
621 if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC))
622 return -ENOMEM;
623 }
624
625 if (encaps_data) {
626 memcpy(skb_push(skb, encaps_len), encaps_data, encaps_len);
627 nh_pos += encaps_len;
628 h_pos += encaps_len;
629 }
630
631 memcpy(skb_push(skb, hdrlen), &hdr, hdrlen);
632
633 nh_pos += hdrlen;
634 h_pos += hdrlen;
635
636 /* Update skb pointers to various headers since this modified frame
637 * is going to go through Linux networking code that may potentially
638 * need things like pointer to IP header. */
639 skb_reset_mac_header(skb);
640 skb_set_network_header(skb, nh_pos);
641 skb_set_transport_header(skb, h_pos);
642
643 return 0;
644}
645EXPORT_SYMBOL(ieee80211_data_from_8023);
646
647static void530static void
648__frame_add_frag(struct sk_buff *skb, struct page *page,531__frame_add_frag(struct sk_buff *skb, struct page *page,
649 void *ptr, int len, int size)532 void *ptr, int len, int size)
@@ -963,6 +846,9 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev) · 313 unmodified lines
963 case EVENT_STOPPED:846 case EVENT_STOPPED:
964 __cfg80211_leave(wiphy_to_rdev(wdev->wiphy), wdev);847 __cfg80211_leave(wiphy_to_rdev(wdev->wiphy), wdev);
965 break;848 break;
849 case EVENT_PORT_AUTHORIZED:
850 __cfg80211_port_authorized(wdev, ev->pa.bssid);
851 break;
966 }852 }
967 wdev_unlock(wdev);853 wdev_unlock(wdev);
968 854
@@ -1367,13 +1253,29 @@ int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len, · 398 unmodified lines
1367}1253}
1368EXPORT_SYMBOL(cfg80211_get_p2p_attr);1254EXPORT_SYMBOL(cfg80211_get_p2p_attr);
1369 1255
1370static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id)1256static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id, bool id_ext)
1371{1257{
1372 int i;1258 int i;
1373 1259
1374 for (i = 0; i < n_ids; i++)1260 /* Make sure array values are legal */
1375 if (ids[i] == id)1261 if (WARN_ON(ids[n_ids - 1] == WLAN_EID_EXTENSION))
1262 return false;
1263
1264 i = 0;
1265 while (i < n_ids) {
1266 if (ids[i] == WLAN_EID_EXTENSION) {
1267 if (id_ext && (ids[i + 1] == id))
1268 return true;
1269
1270 i += 2;
1271 continue;
1272 }
1273
1274 if (ids[i] == id && !id_ext)
1376 return true;1275 return true;
1276
1277 i++;
1278 }
1377 return false;1279 return false;
1378}1280}
1379 1281
@@ -1403,14 +1305,36 @@ size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen, · 23 unmodified lines
1403{1305{
1404 size_t pos = offset;1306 size_t pos = offset;
1405 1307
1406 while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) {1308 while (pos < ielen) {
1309 u8 ext = 0;
1310
1311 if (ies[pos] == WLAN_EID_EXTENSION)
1312 ext = 2;
1313 if ((pos + ext) >= ielen)
1314 break;
1315
1316 if (!ieee80211_id_in_list(ids, n_ids, ies[pos + ext],
1317 ies[pos] == WLAN_EID_EXTENSION))
1318 break;
1319
1407 if (ies[pos] == WLAN_EID_RIC_DATA && n_after_ric) {1320 if (ies[pos] == WLAN_EID_RIC_DATA && n_after_ric) {
1408 pos = skip_ie(ies, ielen, pos);1321 pos = skip_ie(ies, ielen, pos);
1409 1322
1410 while (pos < ielen &&1323 while (pos < ielen) {
1411 !ieee80211_id_in_list(after_ric, n_after_ric,1324 if (ies[pos] == WLAN_EID_EXTENSION)
1412 ies[pos]))1325 ext = 2;
1413 pos = skip_ie(ies, ielen, pos);1326 else
1327 ext = 0;
1328
1329 if ((pos + ext) >= ielen)
1330 break;
1331
1332 if (!ieee80211_id_in_list(after_ric,
1333 n_after_ric,
1334 ies[pos + ext],
1335 ext == 2))
1336 pos = skip_ie(ies, ielen, pos);
1337 }
1414 } else {1338 } else {
1415 pos = skip_ie(ies, ielen, pos);1339 pos = skip_ie(ies, ielen, pos);
1416 }1340 }