diff options
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/chan.c | 7 | ||||
-rw-r--r-- | net/wireless/core.c | 53 | ||||
-rw-r--r-- | net/wireless/core.h | 2 | ||||
-rw-r--r-- | net/wireless/mlme.c | 37 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 266 | ||||
-rw-r--r-- | net/wireless/nl80211.h | 5 | ||||
-rw-r--r-- | net/wireless/radiotap.c | 2 | ||||
-rw-r--r-- | net/wireless/reg.c | 45 | ||||
-rw-r--r-- | net/wireless/scan.c | 2 | ||||
-rw-r--r-- | net/wireless/util.c | 36 | ||||
-rw-r--r-- | net/wireless/wext-core.c | 8 |
11 files changed, 337 insertions, 126 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c index d355f67d0cdd..2f876b9ee344 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c | |||
@@ -105,7 +105,7 @@ cfg80211_get_chan_state(struct wireless_dev *wdev, | |||
105 | 105 | ||
106 | ASSERT_WDEV_LOCK(wdev); | 106 | ASSERT_WDEV_LOCK(wdev); |
107 | 107 | ||
108 | if (!netif_running(wdev->netdev)) | 108 | if (wdev->netdev && !netif_running(wdev->netdev)) |
109 | return; | 109 | return; |
110 | 110 | ||
111 | switch (wdev->iftype) { | 111 | switch (wdev->iftype) { |
@@ -143,6 +143,11 @@ cfg80211_get_chan_state(struct wireless_dev *wdev, | |||
143 | case NL80211_IFTYPE_WDS: | 143 | case NL80211_IFTYPE_WDS: |
144 | /* these interface types don't really have a channel */ | 144 | /* these interface types don't really have a channel */ |
145 | return; | 145 | return; |
146 | case NL80211_IFTYPE_P2P_DEVICE: | ||
147 | if (wdev->wiphy->features & | ||
148 | NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL) | ||
149 | *chanmode = CHAN_MODE_EXCLUSIVE; | ||
150 | return; | ||
146 | case NL80211_IFTYPE_UNSPECIFIED: | 151 | case NL80211_IFTYPE_UNSPECIFIED: |
147 | case NUM_NL80211_IFTYPES: | 152 | case NUM_NL80211_IFTYPES: |
148 | WARN_ON(1); | 153 | WARN_ON(1); |
diff --git a/net/wireless/core.c b/net/wireless/core.c index dcd64d5b07aa..443d4d7deea2 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -230,9 +230,24 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked) | |||
230 | rtnl_lock(); | 230 | rtnl_lock(); |
231 | mutex_lock(&rdev->devlist_mtx); | 231 | mutex_lock(&rdev->devlist_mtx); |
232 | 232 | ||
233 | list_for_each_entry(wdev, &rdev->wdev_list, list) | 233 | list_for_each_entry(wdev, &rdev->wdev_list, list) { |
234 | if (wdev->netdev) | 234 | if (wdev->netdev) { |
235 | dev_close(wdev->netdev); | 235 | dev_close(wdev->netdev); |
236 | continue; | ||
237 | } | ||
238 | /* otherwise, check iftype */ | ||
239 | switch (wdev->iftype) { | ||
240 | case NL80211_IFTYPE_P2P_DEVICE: | ||
241 | if (!wdev->p2p_started) | ||
242 | break; | ||
243 | rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); | ||
244 | wdev->p2p_started = false; | ||
245 | rdev->opencount--; | ||
246 | break; | ||
247 | default: | ||
248 | break; | ||
249 | } | ||
250 | } | ||
236 | 251 | ||
237 | mutex_unlock(&rdev->devlist_mtx); | 252 | mutex_unlock(&rdev->devlist_mtx); |
238 | rtnl_unlock(); | 253 | rtnl_unlock(); |
@@ -407,6 +422,11 @@ static int wiphy_verify_combinations(struct wiphy *wiphy) | |||
407 | if (WARN_ON(wiphy->software_iftypes & types)) | 422 | if (WARN_ON(wiphy->software_iftypes & types)) |
408 | return -EINVAL; | 423 | return -EINVAL; |
409 | 424 | ||
425 | /* Only a single P2P_DEVICE can be allowed */ | ||
426 | if (WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) && | ||
427 | c->limits[j].max > 1)) | ||
428 | return -EINVAL; | ||
429 | |||
410 | cnt += c->limits[j].max; | 430 | cnt += c->limits[j].max; |
411 | /* | 431 | /* |
412 | * Don't advertise an unsupported type | 432 | * Don't advertise an unsupported type |
@@ -734,6 +754,35 @@ static void wdev_cleanup_work(struct work_struct *work) | |||
734 | dev_put(wdev->netdev); | 754 | dev_put(wdev->netdev); |
735 | } | 755 | } |
736 | 756 | ||
757 | void cfg80211_unregister_wdev(struct wireless_dev *wdev) | ||
758 | { | ||
759 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | ||
760 | |||
761 | ASSERT_RTNL(); | ||
762 | |||
763 | if (WARN_ON(wdev->netdev)) | ||
764 | return; | ||
765 | |||
766 | mutex_lock(&rdev->devlist_mtx); | ||
767 | list_del_rcu(&wdev->list); | ||
768 | rdev->devlist_generation++; | ||
769 | |||
770 | switch (wdev->iftype) { | ||
771 | case NL80211_IFTYPE_P2P_DEVICE: | ||
772 | if (!wdev->p2p_started) | ||
773 | break; | ||
774 | rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); | ||
775 | wdev->p2p_started = false; | ||
776 | rdev->opencount--; | ||
777 | break; | ||
778 | default: | ||
779 | WARN_ON_ONCE(1); | ||
780 | break; | ||
781 | } | ||
782 | mutex_unlock(&rdev->devlist_mtx); | ||
783 | } | ||
784 | EXPORT_SYMBOL(cfg80211_unregister_wdev); | ||
785 | |||
737 | static struct device_type wiphy_type = { | 786 | static struct device_type wiphy_type = { |
738 | .name = "wlan", | 787 | .name = "wlan", |
739 | }; | 788 | }; |
diff --git a/net/wireless/core.h b/net/wireless/core.h index bc7430b54771..a343be4a52bd 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -55,7 +55,7 @@ struct cfg80211_registered_device { | |||
55 | int opencount; /* also protected by devlist_mtx */ | 55 | int opencount; /* also protected by devlist_mtx */ |
56 | wait_queue_head_t dev_wait; | 56 | wait_queue_head_t dev_wait; |
57 | 57 | ||
58 | u32 ap_beacons_nlpid; | 58 | u32 ap_beacons_nlportid; |
59 | 59 | ||
60 | /* protected by RTNL only */ | 60 | /* protected by RTNL only */ |
61 | int num_running_ifaces; | 61 | int num_running_ifaces; |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 1cdb1d5e6b0f..8016fee0752b 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -612,10 +612,21 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp) | |||
612 | } | 612 | } |
613 | EXPORT_SYMBOL(cfg80211_del_sta); | 613 | EXPORT_SYMBOL(cfg80211_del_sta); |
614 | 614 | ||
615 | void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr, | ||
616 | enum nl80211_connect_failed_reason reason, | ||
617 | gfp_t gfp) | ||
618 | { | ||
619 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | ||
620 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
621 | |||
622 | nl80211_send_conn_failed_event(rdev, dev, mac_addr, reason, gfp); | ||
623 | } | ||
624 | EXPORT_SYMBOL(cfg80211_conn_failed); | ||
625 | |||
615 | struct cfg80211_mgmt_registration { | 626 | struct cfg80211_mgmt_registration { |
616 | struct list_head list; | 627 | struct list_head list; |
617 | 628 | ||
618 | u32 nlpid; | 629 | u32 nlportid; |
619 | 630 | ||
620 | int match_len; | 631 | int match_len; |
621 | 632 | ||
@@ -624,7 +635,7 @@ struct cfg80211_mgmt_registration { | |||
624 | u8 match[]; | 635 | u8 match[]; |
625 | }; | 636 | }; |
626 | 637 | ||
627 | int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, | 638 | int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid, |
628 | u16 frame_type, const u8 *match_data, | 639 | u16 frame_type, const u8 *match_data, |
629 | int match_len) | 640 | int match_len) |
630 | { | 641 | { |
@@ -672,7 +683,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, | |||
672 | 683 | ||
673 | memcpy(nreg->match, match_data, match_len); | 684 | memcpy(nreg->match, match_data, match_len); |
674 | nreg->match_len = match_len; | 685 | nreg->match_len = match_len; |
675 | nreg->nlpid = snd_pid; | 686 | nreg->nlportid = snd_portid; |
676 | nreg->frame_type = cpu_to_le16(frame_type); | 687 | nreg->frame_type = cpu_to_le16(frame_type); |
677 | list_add(&nreg->list, &wdev->mgmt_registrations); | 688 | list_add(&nreg->list, &wdev->mgmt_registrations); |
678 | 689 | ||
@@ -685,7 +696,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, | |||
685 | return err; | 696 | return err; |
686 | } | 697 | } |
687 | 698 | ||
688 | void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) | 699 | void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid) |
689 | { | 700 | { |
690 | struct wiphy *wiphy = wdev->wiphy; | 701 | struct wiphy *wiphy = wdev->wiphy; |
691 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 702 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
@@ -694,7 +705,7 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) | |||
694 | spin_lock_bh(&wdev->mgmt_registrations_lock); | 705 | spin_lock_bh(&wdev->mgmt_registrations_lock); |
695 | 706 | ||
696 | list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { | 707 | list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { |
697 | if (reg->nlpid != nlpid) | 708 | if (reg->nlportid != nlportid) |
698 | continue; | 709 | continue; |
699 | 710 | ||
700 | if (rdev->ops->mgmt_frame_register) { | 711 | if (rdev->ops->mgmt_frame_register) { |
@@ -710,8 +721,8 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) | |||
710 | 721 | ||
711 | spin_unlock_bh(&wdev->mgmt_registrations_lock); | 722 | spin_unlock_bh(&wdev->mgmt_registrations_lock); |
712 | 723 | ||
713 | if (nlpid == wdev->ap_unexpected_nlpid) | 724 | if (nlportid == wdev->ap_unexpected_nlportid) |
714 | wdev->ap_unexpected_nlpid = 0; | 725 | wdev->ap_unexpected_nlportid = 0; |
715 | } | 726 | } |
716 | 727 | ||
717 | void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) | 728 | void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) |
@@ -736,7 +747,6 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
736 | const u8 *buf, size_t len, bool no_cck, | 747 | const u8 *buf, size_t len, bool no_cck, |
737 | bool dont_wait_for_ack, u64 *cookie) | 748 | bool dont_wait_for_ack, u64 *cookie) |
738 | { | 749 | { |
739 | struct net_device *dev = wdev->netdev; | ||
740 | const struct ieee80211_mgmt *mgmt; | 750 | const struct ieee80211_mgmt *mgmt; |
741 | u16 stype; | 751 | u16 stype; |
742 | 752 | ||
@@ -796,7 +806,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
796 | case NL80211_IFTYPE_AP: | 806 | case NL80211_IFTYPE_AP: |
797 | case NL80211_IFTYPE_P2P_GO: | 807 | case NL80211_IFTYPE_P2P_GO: |
798 | case NL80211_IFTYPE_AP_VLAN: | 808 | case NL80211_IFTYPE_AP_VLAN: |
799 | if (!ether_addr_equal(mgmt->bssid, dev->dev_addr)) | 809 | if (!ether_addr_equal(mgmt->bssid, wdev_address(wdev))) |
800 | err = -EINVAL; | 810 | err = -EINVAL; |
801 | break; | 811 | break; |
802 | case NL80211_IFTYPE_MESH_POINT: | 812 | case NL80211_IFTYPE_MESH_POINT: |
@@ -809,6 +819,11 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
809 | * cfg80211 doesn't track the stations | 819 | * cfg80211 doesn't track the stations |
810 | */ | 820 | */ |
811 | break; | 821 | break; |
822 | case NL80211_IFTYPE_P2P_DEVICE: | ||
823 | /* | ||
824 | * fall through, P2P device only supports | ||
825 | * public action frames | ||
826 | */ | ||
812 | default: | 827 | default: |
813 | err = -EOPNOTSUPP; | 828 | err = -EOPNOTSUPP; |
814 | break; | 829 | break; |
@@ -819,7 +834,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
819 | return err; | 834 | return err; |
820 | } | 835 | } |
821 | 836 | ||
822 | if (!ether_addr_equal(mgmt->sa, dev->dev_addr)) | 837 | if (!ether_addr_equal(mgmt->sa, wdev_address(wdev))) |
823 | return -EINVAL; | 838 | return -EINVAL; |
824 | 839 | ||
825 | /* Transmit the Action frame as requested by user space */ | 840 | /* Transmit the Action frame as requested by user space */ |
@@ -868,7 +883,7 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, | |||
868 | /* found match! */ | 883 | /* found match! */ |
869 | 884 | ||
870 | /* Indicate the received Action frame to user space */ | 885 | /* Indicate the received Action frame to user space */ |
871 | if (nl80211_send_mgmt(rdev, wdev, reg->nlpid, | 886 | if (nl80211_send_mgmt(rdev, wdev, reg->nlportid, |
872 | freq, sig_mbm, | 887 | freq, sig_mbm, |
873 | buf, len, gfp)) | 888 | buf, len, gfp)) |
874 | continue; | 889 | continue; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 1e37dbf00cb3..0418a6d5c1a6 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -496,11 +496,11 @@ static bool is_valid_ie_attr(const struct nlattr *attr) | |||
496 | } | 496 | } |
497 | 497 | ||
498 | /* message building helper */ | 498 | /* message building helper */ |
499 | static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq, | 499 | static inline void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq, |
500 | int flags, u8 cmd) | 500 | int flags, u8 cmd) |
501 | { | 501 | { |
502 | /* since there is no private header just add the generic one */ | 502 | /* since there is no private header just add the generic one */ |
503 | return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd); | 503 | return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd); |
504 | } | 504 | } |
505 | 505 | ||
506 | static int nl80211_msg_put_channel(struct sk_buff *msg, | 506 | static int nl80211_msg_put_channel(struct sk_buff *msg, |
@@ -851,7 +851,7 @@ nla_put_failure: | |||
851 | return -ENOBUFS; | 851 | return -ENOBUFS; |
852 | } | 852 | } |
853 | 853 | ||
854 | static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | 854 | static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags, |
855 | struct cfg80211_registered_device *dev) | 855 | struct cfg80211_registered_device *dev) |
856 | { | 856 | { |
857 | void *hdr; | 857 | void *hdr; |
@@ -866,7 +866,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
866 | const struct ieee80211_txrx_stypes *mgmt_stypes = | 866 | const struct ieee80211_txrx_stypes *mgmt_stypes = |
867 | dev->wiphy.mgmt_stypes; | 867 | dev->wiphy.mgmt_stypes; |
868 | 868 | ||
869 | hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY); | 869 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_WIPHY); |
870 | if (!hdr) | 870 | if (!hdr) |
871 | return -1; | 871 | return -1; |
872 | 872 | ||
@@ -1100,6 +1100,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
1100 | if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS)) | 1100 | if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS)) |
1101 | goto nla_put_failure; | 1101 | goto nla_put_failure; |
1102 | } | 1102 | } |
1103 | CMD(start_p2p_device, START_P2P_DEVICE); | ||
1103 | 1104 | ||
1104 | #ifdef CONFIG_NL80211_TESTMODE | 1105 | #ifdef CONFIG_NL80211_TESTMODE |
1105 | CMD(testmode_cmd, TESTMODE); | 1106 | CMD(testmode_cmd, TESTMODE); |
@@ -1266,7 +1267,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
1266 | continue; | 1267 | continue; |
1267 | if (++idx <= start) | 1268 | if (++idx <= start) |
1268 | continue; | 1269 | continue; |
1269 | if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid, | 1270 | if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid, |
1270 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 1271 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
1271 | dev) < 0) { | 1272 | dev) < 0) { |
1272 | idx--; | 1273 | idx--; |
@@ -1289,7 +1290,7 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1289 | if (!msg) | 1290 | if (!msg) |
1290 | return -ENOMEM; | 1291 | return -ENOMEM; |
1291 | 1292 | ||
1292 | if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0) { | 1293 | if (nl80211_send_wiphy(msg, info->snd_portid, info->snd_seq, 0, dev) < 0) { |
1293 | nlmsg_free(msg); | 1294 | nlmsg_free(msg); |
1294 | return -ENOBUFS; | 1295 | return -ENOBUFS; |
1295 | } | 1296 | } |
@@ -1735,26 +1736,26 @@ static inline u64 wdev_id(struct wireless_dev *wdev) | |||
1735 | ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32); | 1736 | ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32); |
1736 | } | 1737 | } |
1737 | 1738 | ||
1738 | static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags, | 1739 | static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags, |
1739 | struct cfg80211_registered_device *rdev, | 1740 | struct cfg80211_registered_device *rdev, |
1740 | struct wireless_dev *wdev) | 1741 | struct wireless_dev *wdev) |
1741 | { | 1742 | { |
1742 | struct net_device *dev = wdev->netdev; | 1743 | struct net_device *dev = wdev->netdev; |
1743 | void *hdr; | 1744 | void *hdr; |
1744 | 1745 | ||
1745 | hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE); | 1746 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_INTERFACE); |
1746 | if (!hdr) | 1747 | if (!hdr) |
1747 | return -1; | 1748 | return -1; |
1748 | 1749 | ||
1749 | if (dev && | 1750 | if (dev && |
1750 | (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || | 1751 | (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || |
1751 | nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name) || | 1752 | nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name))) |
1752 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dev->dev_addr))) | ||
1753 | goto nla_put_failure; | 1753 | goto nla_put_failure; |
1754 | 1754 | ||
1755 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 1755 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
1756 | nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) || | 1756 | nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) || |
1757 | nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) || | 1757 | nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) || |
1758 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) || | ||
1758 | nla_put_u32(msg, NL80211_ATTR_GENERATION, | 1759 | nla_put_u32(msg, NL80211_ATTR_GENERATION, |
1759 | rdev->devlist_generation ^ | 1760 | rdev->devlist_generation ^ |
1760 | (cfg80211_rdev_list_generation << 2))) | 1761 | (cfg80211_rdev_list_generation << 2))) |
@@ -1806,7 +1807,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * | |||
1806 | if_idx++; | 1807 | if_idx++; |
1807 | continue; | 1808 | continue; |
1808 | } | 1809 | } |
1809 | if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid, | 1810 | if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid, |
1810 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 1811 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
1811 | rdev, wdev) < 0) { | 1812 | rdev, wdev) < 0) { |
1812 | mutex_unlock(&rdev->devlist_mtx); | 1813 | mutex_unlock(&rdev->devlist_mtx); |
@@ -1837,7 +1838,7 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) | |||
1837 | if (!msg) | 1838 | if (!msg) |
1838 | return -ENOMEM; | 1839 | return -ENOMEM; |
1839 | 1840 | ||
1840 | if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, | 1841 | if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0, |
1841 | dev, wdev) < 0) { | 1842 | dev, wdev) < 0) { |
1842 | nlmsg_free(msg); | 1843 | nlmsg_free(msg); |
1843 | return -ENOBUFS; | 1844 | return -ENOBUFS; |
@@ -2021,8 +2022,10 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
2021 | return PTR_ERR(wdev); | 2022 | return PTR_ERR(wdev); |
2022 | } | 2023 | } |
2023 | 2024 | ||
2024 | if (type == NL80211_IFTYPE_MESH_POINT && | 2025 | switch (type) { |
2025 | info->attrs[NL80211_ATTR_MESH_ID]) { | 2026 | case NL80211_IFTYPE_MESH_POINT: |
2027 | if (!info->attrs[NL80211_ATTR_MESH_ID]) | ||
2028 | break; | ||
2026 | wdev_lock(wdev); | 2029 | wdev_lock(wdev); |
2027 | BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != | 2030 | BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != |
2028 | IEEE80211_MAX_MESH_ID_LEN); | 2031 | IEEE80211_MAX_MESH_ID_LEN); |
@@ -2031,9 +2034,29 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
2031 | memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]), | 2034 | memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]), |
2032 | wdev->mesh_id_up_len); | 2035 | wdev->mesh_id_up_len); |
2033 | wdev_unlock(wdev); | 2036 | wdev_unlock(wdev); |
2037 | break; | ||
2038 | case NL80211_IFTYPE_P2P_DEVICE: | ||
2039 | /* | ||
2040 | * P2P Device doesn't have a netdev, so doesn't go | ||
2041 | * through the netdev notifier and must be added here | ||
2042 | */ | ||
2043 | mutex_init(&wdev->mtx); | ||
2044 | INIT_LIST_HEAD(&wdev->event_list); | ||
2045 | spin_lock_init(&wdev->event_lock); | ||
2046 | INIT_LIST_HEAD(&wdev->mgmt_registrations); | ||
2047 | spin_lock_init(&wdev->mgmt_registrations_lock); | ||
2048 | |||
2049 | mutex_lock(&rdev->devlist_mtx); | ||
2050 | wdev->identifier = ++rdev->wdev_id; | ||
2051 | list_add_rcu(&wdev->list, &rdev->wdev_list); | ||
2052 | rdev->devlist_generation++; | ||
2053 | mutex_unlock(&rdev->devlist_mtx); | ||
2054 | break; | ||
2055 | default: | ||
2056 | break; | ||
2034 | } | 2057 | } |
2035 | 2058 | ||
2036 | if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, | 2059 | if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0, |
2037 | rdev, wdev) < 0) { | 2060 | rdev, wdev) < 0) { |
2038 | nlmsg_free(msg); | 2061 | nlmsg_free(msg); |
2039 | return -ENOBUFS; | 2062 | return -ENOBUFS; |
@@ -2168,7 +2191,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) | |||
2168 | if (!msg) | 2191 | if (!msg) |
2169 | return -ENOMEM; | 2192 | return -ENOMEM; |
2170 | 2193 | ||
2171 | hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, | 2194 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
2172 | NL80211_CMD_NEW_KEY); | 2195 | NL80211_CMD_NEW_KEY); |
2173 | if (IS_ERR(hdr)) | 2196 | if (IS_ERR(hdr)) |
2174 | return PTR_ERR(hdr); | 2197 | return PTR_ERR(hdr); |
@@ -2746,7 +2769,7 @@ nla_put_failure: | |||
2746 | return false; | 2769 | return false; |
2747 | } | 2770 | } |
2748 | 2771 | ||
2749 | static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, | 2772 | static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, |
2750 | int flags, | 2773 | int flags, |
2751 | struct cfg80211_registered_device *rdev, | 2774 | struct cfg80211_registered_device *rdev, |
2752 | struct net_device *dev, | 2775 | struct net_device *dev, |
@@ -2755,7 +2778,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, | |||
2755 | void *hdr; | 2778 | void *hdr; |
2756 | struct nlattr *sinfoattr, *bss_param; | 2779 | struct nlattr *sinfoattr, *bss_param; |
2757 | 2780 | ||
2758 | hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); | 2781 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_STATION); |
2759 | if (!hdr) | 2782 | if (!hdr) |
2760 | return -1; | 2783 | return -1; |
2761 | 2784 | ||
@@ -2908,7 +2931,7 @@ static int nl80211_dump_station(struct sk_buff *skb, | |||
2908 | goto out_err; | 2931 | goto out_err; |
2909 | 2932 | ||
2910 | if (nl80211_send_station(skb, | 2933 | if (nl80211_send_station(skb, |
2911 | NETLINK_CB(cb->skb).pid, | 2934 | NETLINK_CB(cb->skb).portid, |
2912 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 2935 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
2913 | dev, netdev, mac_addr, | 2936 | dev, netdev, mac_addr, |
2914 | &sinfo) < 0) | 2937 | &sinfo) < 0) |
@@ -2954,7 +2977,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) | |||
2954 | if (!msg) | 2977 | if (!msg) |
2955 | return -ENOMEM; | 2978 | return -ENOMEM; |
2956 | 2979 | ||
2957 | if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0, | 2980 | if (nl80211_send_station(msg, info->snd_portid, info->snd_seq, 0, |
2958 | rdev, dev, mac_addr, &sinfo) < 0) { | 2981 | rdev, dev, mac_addr, &sinfo) < 0) { |
2959 | nlmsg_free(msg); | 2982 | nlmsg_free(msg); |
2960 | return -ENOBUFS; | 2983 | return -ENOBUFS; |
@@ -3280,7 +3303,7 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) | |||
3280 | return rdev->ops->del_station(&rdev->wiphy, dev, mac_addr); | 3303 | return rdev->ops->del_station(&rdev->wiphy, dev, mac_addr); |
3281 | } | 3304 | } |
3282 | 3305 | ||
3283 | static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq, | 3306 | static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq, |
3284 | int flags, struct net_device *dev, | 3307 | int flags, struct net_device *dev, |
3285 | u8 *dst, u8 *next_hop, | 3308 | u8 *dst, u8 *next_hop, |
3286 | struct mpath_info *pinfo) | 3309 | struct mpath_info *pinfo) |
@@ -3288,7 +3311,7 @@ static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq, | |||
3288 | void *hdr; | 3311 | void *hdr; |
3289 | struct nlattr *pinfoattr; | 3312 | struct nlattr *pinfoattr; |
3290 | 3313 | ||
3291 | hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); | 3314 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_STATION); |
3292 | if (!hdr) | 3315 | if (!hdr) |
3293 | return -1; | 3316 | return -1; |
3294 | 3317 | ||
@@ -3366,7 +3389,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb, | |||
3366 | if (err) | 3389 | if (err) |
3367 | goto out_err; | 3390 | goto out_err; |
3368 | 3391 | ||
3369 | if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid, | 3392 | if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid, |
3370 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 3393 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
3371 | netdev, dst, next_hop, | 3394 | netdev, dst, next_hop, |
3372 | &pinfo) < 0) | 3395 | &pinfo) < 0) |
@@ -3415,7 +3438,7 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info) | |||
3415 | if (!msg) | 3438 | if (!msg) |
3416 | return -ENOMEM; | 3439 | return -ENOMEM; |
3417 | 3440 | ||
3418 | if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0, | 3441 | if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0, |
3419 | dev, dst, next_hop, &pinfo) < 0) { | 3442 | dev, dst, next_hop, &pinfo) < 0) { |
3420 | nlmsg_free(msg); | 3443 | nlmsg_free(msg); |
3421 | return -ENOBUFS; | 3444 | return -ENOBUFS; |
@@ -3656,7 +3679,7 @@ static int nl80211_get_mesh_config(struct sk_buff *skb, | |||
3656 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 3679 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
3657 | if (!msg) | 3680 | if (!msg) |
3658 | return -ENOMEM; | 3681 | return -ENOMEM; |
3659 | hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, | 3682 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
3660 | NL80211_CMD_GET_MESH_CONFIG); | 3683 | NL80211_CMD_GET_MESH_CONFIG); |
3661 | if (!hdr) | 3684 | if (!hdr) |
3662 | goto out; | 3685 | goto out; |
@@ -3975,7 +3998,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) | |||
3975 | goto out; | 3998 | goto out; |
3976 | } | 3999 | } |
3977 | 4000 | ||
3978 | hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, | 4001 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
3979 | NL80211_CMD_GET_REG); | 4002 | NL80211_CMD_GET_REG); |
3980 | if (!hdr) | 4003 | if (!hdr) |
3981 | goto put_failure; | 4004 | goto put_failure; |
@@ -4593,7 +4616,7 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, | |||
4593 | 4616 | ||
4594 | ASSERT_WDEV_LOCK(wdev); | 4617 | ASSERT_WDEV_LOCK(wdev); |
4595 | 4618 | ||
4596 | hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).pid, seq, flags, | 4619 | hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags, |
4597 | NL80211_CMD_NEW_SCAN_RESULTS); | 4620 | NL80211_CMD_NEW_SCAN_RESULTS); |
4598 | if (!hdr) | 4621 | if (!hdr) |
4599 | return -1; | 4622 | return -1; |
@@ -4712,14 +4735,14 @@ static int nl80211_dump_scan(struct sk_buff *skb, | |||
4712 | return skb->len; | 4735 | return skb->len; |
4713 | } | 4736 | } |
4714 | 4737 | ||
4715 | static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq, | 4738 | static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq, |
4716 | int flags, struct net_device *dev, | 4739 | int flags, struct net_device *dev, |
4717 | struct survey_info *survey) | 4740 | struct survey_info *survey) |
4718 | { | 4741 | { |
4719 | void *hdr; | 4742 | void *hdr; |
4720 | struct nlattr *infoattr; | 4743 | struct nlattr *infoattr; |
4721 | 4744 | ||
4722 | hdr = nl80211hdr_put(msg, pid, seq, flags, | 4745 | hdr = nl80211hdr_put(msg, portid, seq, flags, |
4723 | NL80211_CMD_NEW_SURVEY_RESULTS); | 4746 | NL80211_CMD_NEW_SURVEY_RESULTS); |
4724 | if (!hdr) | 4747 | if (!hdr) |
4725 | return -ENOMEM; | 4748 | return -ENOMEM; |
@@ -4813,7 +4836,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
4813 | } | 4836 | } |
4814 | 4837 | ||
4815 | if (nl80211_send_survey(skb, | 4838 | if (nl80211_send_survey(skb, |
4816 | NETLINK_CB(cb->skb).pid, | 4839 | NETLINK_CB(cb->skb).portid, |
4817 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 4840 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
4818 | netdev, | 4841 | netdev, |
4819 | &survey) < 0) | 4842 | &survey) < 0) |
@@ -5428,7 +5451,7 @@ static int nl80211_testmode_dump(struct sk_buff *skb, | |||
5428 | } | 5451 | } |
5429 | 5452 | ||
5430 | while (1) { | 5453 | while (1) { |
5431 | void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).pid, | 5454 | void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid, |
5432 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 5455 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
5433 | NL80211_CMD_TESTMODE); | 5456 | NL80211_CMD_TESTMODE); |
5434 | struct nlattr *tmdata; | 5457 | struct nlattr *tmdata; |
@@ -5468,7 +5491,7 @@ static int nl80211_testmode_dump(struct sk_buff *skb, | |||
5468 | 5491 | ||
5469 | static struct sk_buff * | 5492 | static struct sk_buff * |
5470 | __cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev, | 5493 | __cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev, |
5471 | int approxlen, u32 pid, u32 seq, gfp_t gfp) | 5494 | int approxlen, u32 portid, u32 seq, gfp_t gfp) |
5472 | { | 5495 | { |
5473 | struct sk_buff *skb; | 5496 | struct sk_buff *skb; |
5474 | void *hdr; | 5497 | void *hdr; |
@@ -5478,7 +5501,7 @@ __cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev, | |||
5478 | if (!skb) | 5501 | if (!skb) |
5479 | return NULL; | 5502 | return NULL; |
5480 | 5503 | ||
5481 | hdr = nl80211hdr_put(skb, pid, seq, 0, NL80211_CMD_TESTMODE); | 5504 | hdr = nl80211hdr_put(skb, portid, seq, 0, NL80211_CMD_TESTMODE); |
5482 | if (!hdr) { | 5505 | if (!hdr) { |
5483 | kfree_skb(skb); | 5506 | kfree_skb(skb); |
5484 | return NULL; | 5507 | return NULL; |
@@ -5508,7 +5531,7 @@ struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy, | |||
5508 | return NULL; | 5531 | return NULL; |
5509 | 5532 | ||
5510 | return __cfg80211_testmode_alloc_skb(rdev, approxlen, | 5533 | return __cfg80211_testmode_alloc_skb(rdev, approxlen, |
5511 | rdev->testmode_info->snd_pid, | 5534 | rdev->testmode_info->snd_portid, |
5512 | rdev->testmode_info->snd_seq, | 5535 | rdev->testmode_info->snd_seq, |
5513 | GFP_KERNEL); | 5536 | GFP_KERNEL); |
5514 | } | 5537 | } |
@@ -5846,7 +5869,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, | |||
5846 | if (!msg) | 5869 | if (!msg) |
5847 | return -ENOMEM; | 5870 | return -ENOMEM; |
5848 | 5871 | ||
5849 | hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, | 5872 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
5850 | NL80211_CMD_REMAIN_ON_CHANNEL); | 5873 | NL80211_CMD_REMAIN_ON_CHANNEL); |
5851 | 5874 | ||
5852 | if (IS_ERR(hdr)) { | 5875 | if (IS_ERR(hdr)) { |
@@ -6055,6 +6078,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
6055 | case NL80211_IFTYPE_AP_VLAN: | 6078 | case NL80211_IFTYPE_AP_VLAN: |
6056 | case NL80211_IFTYPE_MESH_POINT: | 6079 | case NL80211_IFTYPE_MESH_POINT: |
6057 | case NL80211_IFTYPE_P2P_GO: | 6080 | case NL80211_IFTYPE_P2P_GO: |
6081 | case NL80211_IFTYPE_P2P_DEVICE: | ||
6058 | break; | 6082 | break; |
6059 | default: | 6083 | default: |
6060 | return -EOPNOTSUPP; | 6084 | return -EOPNOTSUPP; |
@@ -6064,7 +6088,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
6064 | if (!rdev->ops->mgmt_tx) | 6088 | if (!rdev->ops->mgmt_tx) |
6065 | return -EOPNOTSUPP; | 6089 | return -EOPNOTSUPP; |
6066 | 6090 | ||
6067 | return cfg80211_mlme_register_mgmt(wdev, info->snd_pid, frame_type, | 6091 | return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type, |
6068 | nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]), | 6092 | nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]), |
6069 | nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH])); | 6093 | nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH])); |
6070 | } | 6094 | } |
@@ -6101,6 +6125,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
6101 | case NL80211_IFTYPE_AP_VLAN: | 6125 | case NL80211_IFTYPE_AP_VLAN: |
6102 | case NL80211_IFTYPE_MESH_POINT: | 6126 | case NL80211_IFTYPE_MESH_POINT: |
6103 | case NL80211_IFTYPE_P2P_GO: | 6127 | case NL80211_IFTYPE_P2P_GO: |
6128 | case NL80211_IFTYPE_P2P_DEVICE: | ||
6104 | break; | 6129 | break; |
6105 | default: | 6130 | default: |
6106 | return -EOPNOTSUPP; | 6131 | return -EOPNOTSUPP; |
@@ -6144,7 +6169,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
6144 | if (!msg) | 6169 | if (!msg) |
6145 | return -ENOMEM; | 6170 | return -ENOMEM; |
6146 | 6171 | ||
6147 | hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, | 6172 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
6148 | NL80211_CMD_FRAME); | 6173 | NL80211_CMD_FRAME); |
6149 | 6174 | ||
6150 | if (IS_ERR(hdr)) { | 6175 | if (IS_ERR(hdr)) { |
@@ -6197,6 +6222,7 @@ static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *in | |||
6197 | case NL80211_IFTYPE_AP: | 6222 | case NL80211_IFTYPE_AP: |
6198 | case NL80211_IFTYPE_AP_VLAN: | 6223 | case NL80211_IFTYPE_AP_VLAN: |
6199 | case NL80211_IFTYPE_P2P_GO: | 6224 | case NL80211_IFTYPE_P2P_GO: |
6225 | case NL80211_IFTYPE_P2P_DEVICE: | ||
6200 | break; | 6226 | break; |
6201 | default: | 6227 | default: |
6202 | return -EOPNOTSUPP; | 6228 | return -EOPNOTSUPP; |
@@ -6260,7 +6286,7 @@ static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info) | |||
6260 | if (!msg) | 6286 | if (!msg) |
6261 | return -ENOMEM; | 6287 | return -ENOMEM; |
6262 | 6288 | ||
6263 | hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, | 6289 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
6264 | NL80211_CMD_GET_POWER_SAVE); | 6290 | NL80211_CMD_GET_POWER_SAVE); |
6265 | if (!hdr) { | 6291 | if (!hdr) { |
6266 | err = -ENOBUFS; | 6292 | err = -ENOBUFS; |
@@ -6462,7 +6488,7 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
6462 | if (!msg) | 6488 | if (!msg) |
6463 | return -ENOMEM; | 6489 | return -ENOMEM; |
6464 | 6490 | ||
6465 | hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, | 6491 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
6466 | NL80211_CMD_GET_WOWLAN); | 6492 | NL80211_CMD_GET_WOWLAN); |
6467 | if (!hdr) | 6493 | if (!hdr) |
6468 | goto nla_put_failure; | 6494 | goto nla_put_failure; |
@@ -6736,10 +6762,10 @@ static int nl80211_register_unexpected_frame(struct sk_buff *skb, | |||
6736 | wdev->iftype != NL80211_IFTYPE_P2P_GO) | 6762 | wdev->iftype != NL80211_IFTYPE_P2P_GO) |
6737 | return -EINVAL; | 6763 | return -EINVAL; |
6738 | 6764 | ||
6739 | if (wdev->ap_unexpected_nlpid) | 6765 | if (wdev->ap_unexpected_nlportid) |
6740 | return -EBUSY; | 6766 | return -EBUSY; |
6741 | 6767 | ||
6742 | wdev->ap_unexpected_nlpid = info->snd_pid; | 6768 | wdev->ap_unexpected_nlportid = info->snd_portid; |
6743 | return 0; | 6769 | return 0; |
6744 | } | 6770 | } |
6745 | 6771 | ||
@@ -6769,7 +6795,7 @@ static int nl80211_probe_client(struct sk_buff *skb, | |||
6769 | if (!msg) | 6795 | if (!msg) |
6770 | return -ENOMEM; | 6796 | return -ENOMEM; |
6771 | 6797 | ||
6772 | hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, | 6798 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
6773 | NL80211_CMD_PROBE_CLIENT); | 6799 | NL80211_CMD_PROBE_CLIENT); |
6774 | 6800 | ||
6775 | if (IS_ERR(hdr)) { | 6801 | if (IS_ERR(hdr)) { |
@@ -6804,10 +6830,72 @@ static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info) | |||
6804 | if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS)) | 6830 | if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS)) |
6805 | return -EOPNOTSUPP; | 6831 | return -EOPNOTSUPP; |
6806 | 6832 | ||
6807 | if (rdev->ap_beacons_nlpid) | 6833 | if (rdev->ap_beacons_nlportid) |
6808 | return -EBUSY; | 6834 | return -EBUSY; |
6809 | 6835 | ||
6810 | rdev->ap_beacons_nlpid = info->snd_pid; | 6836 | rdev->ap_beacons_nlportid = info->snd_portid; |
6837 | |||
6838 | return 0; | ||
6839 | } | ||
6840 | |||
6841 | static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info) | ||
6842 | { | ||
6843 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
6844 | struct wireless_dev *wdev = info->user_ptr[1]; | ||
6845 | int err; | ||
6846 | |||
6847 | if (!rdev->ops->start_p2p_device) | ||
6848 | return -EOPNOTSUPP; | ||
6849 | |||
6850 | if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE) | ||
6851 | return -EOPNOTSUPP; | ||
6852 | |||
6853 | if (wdev->p2p_started) | ||
6854 | return 0; | ||
6855 | |||
6856 | mutex_lock(&rdev->devlist_mtx); | ||
6857 | err = cfg80211_can_add_interface(rdev, wdev->iftype); | ||
6858 | mutex_unlock(&rdev->devlist_mtx); | ||
6859 | if (err) | ||
6860 | return err; | ||
6861 | |||
6862 | err = rdev->ops->start_p2p_device(&rdev->wiphy, wdev); | ||
6863 | if (err) | ||
6864 | return err; | ||
6865 | |||
6866 | wdev->p2p_started = true; | ||
6867 | mutex_lock(&rdev->devlist_mtx); | ||
6868 | rdev->opencount++; | ||
6869 | mutex_unlock(&rdev->devlist_mtx); | ||
6870 | |||
6871 | return 0; | ||
6872 | } | ||
6873 | |||
6874 | static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info) | ||
6875 | { | ||
6876 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
6877 | struct wireless_dev *wdev = info->user_ptr[1]; | ||
6878 | |||
6879 | if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE) | ||
6880 | return -EOPNOTSUPP; | ||
6881 | |||
6882 | if (!rdev->ops->stop_p2p_device) | ||
6883 | return -EOPNOTSUPP; | ||
6884 | |||
6885 | if (!wdev->p2p_started) | ||
6886 | return 0; | ||
6887 | |||
6888 | rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); | ||
6889 | wdev->p2p_started = false; | ||
6890 | |||
6891 | mutex_lock(&rdev->devlist_mtx); | ||
6892 | rdev->opencount--; | ||
6893 | mutex_unlock(&rdev->devlist_mtx); | ||
6894 | |||
6895 | if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) { | ||
6896 | rdev->scan_req->aborted = true; | ||
6897 | ___cfg80211_scan_done(rdev, true); | ||
6898 | } | ||
6811 | 6899 | ||
6812 | return 0; | 6900 | return 0; |
6813 | } | 6901 | } |
@@ -6819,7 +6907,7 @@ static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info) | |||
6819 | #define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\ | 6907 | #define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\ |
6820 | NL80211_FLAG_CHECK_NETDEV_UP) | 6908 | NL80211_FLAG_CHECK_NETDEV_UP) |
6821 | #define NL80211_FLAG_NEED_WDEV 0x10 | 6909 | #define NL80211_FLAG_NEED_WDEV 0x10 |
6822 | /* If a netdev is associated, it must be UP */ | 6910 | /* If a netdev is associated, it must be UP, P2P must be started */ |
6823 | #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ | 6911 | #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ |
6824 | NL80211_FLAG_CHECK_NETDEV_UP) | 6912 | NL80211_FLAG_CHECK_NETDEV_UP) |
6825 | 6913 | ||
@@ -6880,6 +6968,13 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, | |||
6880 | } | 6968 | } |
6881 | 6969 | ||
6882 | dev_hold(dev); | 6970 | dev_hold(dev); |
6971 | } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) { | ||
6972 | if (!wdev->p2p_started) { | ||
6973 | mutex_unlock(&cfg80211_mutex); | ||
6974 | if (rtnl) | ||
6975 | rtnl_unlock(); | ||
6976 | return -ENETDOWN; | ||
6977 | } | ||
6883 | } | 6978 | } |
6884 | 6979 | ||
6885 | cfg80211_lock_rdev(rdev); | 6980 | cfg80211_lock_rdev(rdev); |
@@ -7441,7 +7536,22 @@ static struct genl_ops nl80211_ops[] = { | |||
7441 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 7536 | .internal_flags = NL80211_FLAG_NEED_NETDEV | |
7442 | NL80211_FLAG_NEED_RTNL, | 7537 | NL80211_FLAG_NEED_RTNL, |
7443 | }, | 7538 | }, |
7444 | 7539 | { | |
7540 | .cmd = NL80211_CMD_START_P2P_DEVICE, | ||
7541 | .doit = nl80211_start_p2p_device, | ||
7542 | .policy = nl80211_policy, | ||
7543 | .flags = GENL_ADMIN_PERM, | ||
7544 | .internal_flags = NL80211_FLAG_NEED_WDEV | | ||
7545 | NL80211_FLAG_NEED_RTNL, | ||
7546 | }, | ||
7547 | { | ||
7548 | .cmd = NL80211_CMD_STOP_P2P_DEVICE, | ||
7549 | .doit = nl80211_stop_p2p_device, | ||
7550 | .policy = nl80211_policy, | ||
7551 | .flags = GENL_ADMIN_PERM, | ||
7552 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | | ||
7553 | NL80211_FLAG_NEED_RTNL, | ||
7554 | }, | ||
7445 | }; | 7555 | }; |
7446 | 7556 | ||
7447 | static struct genl_multicast_group nl80211_mlme_mcgrp = { | 7557 | static struct genl_multicast_group nl80211_mlme_mcgrp = { |
@@ -7520,12 +7630,12 @@ static int nl80211_add_scan_req(struct sk_buff *msg, | |||
7520 | static int nl80211_send_scan_msg(struct sk_buff *msg, | 7630 | static int nl80211_send_scan_msg(struct sk_buff *msg, |
7521 | struct cfg80211_registered_device *rdev, | 7631 | struct cfg80211_registered_device *rdev, |
7522 | struct wireless_dev *wdev, | 7632 | struct wireless_dev *wdev, |
7523 | u32 pid, u32 seq, int flags, | 7633 | u32 portid, u32 seq, int flags, |
7524 | u32 cmd) | 7634 | u32 cmd) |
7525 | { | 7635 | { |
7526 | void *hdr; | 7636 | void *hdr; |
7527 | 7637 | ||
7528 | hdr = nl80211hdr_put(msg, pid, seq, flags, cmd); | 7638 | hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); |
7529 | if (!hdr) | 7639 | if (!hdr) |
7530 | return -1; | 7640 | return -1; |
7531 | 7641 | ||
@@ -7549,11 +7659,11 @@ static int | |||
7549 | nl80211_send_sched_scan_msg(struct sk_buff *msg, | 7659 | nl80211_send_sched_scan_msg(struct sk_buff *msg, |
7550 | struct cfg80211_registered_device *rdev, | 7660 | struct cfg80211_registered_device *rdev, |
7551 | struct net_device *netdev, | 7661 | struct net_device *netdev, |
7552 | u32 pid, u32 seq, int flags, u32 cmd) | 7662 | u32 portid, u32 seq, int flags, u32 cmd) |
7553 | { | 7663 | { |
7554 | void *hdr; | 7664 | void *hdr; |
7555 | 7665 | ||
7556 | hdr = nl80211hdr_put(msg, pid, seq, flags, cmd); | 7666 | hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); |
7557 | if (!hdr) | 7667 | if (!hdr) |
7558 | return -1; | 7668 | return -1; |
7559 | 7669 | ||
@@ -8254,6 +8364,40 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev, | |||
8254 | nlmsg_free(msg); | 8364 | nlmsg_free(msg); |
8255 | } | 8365 | } |
8256 | 8366 | ||
8367 | void nl80211_send_conn_failed_event(struct cfg80211_registered_device *rdev, | ||
8368 | struct net_device *dev, const u8 *mac_addr, | ||
8369 | enum nl80211_connect_failed_reason reason, | ||
8370 | gfp_t gfp) | ||
8371 | { | ||
8372 | struct sk_buff *msg; | ||
8373 | void *hdr; | ||
8374 | |||
8375 | msg = nlmsg_new(NLMSG_GOODSIZE, gfp); | ||
8376 | if (!msg) | ||
8377 | return; | ||
8378 | |||
8379 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED); | ||
8380 | if (!hdr) { | ||
8381 | nlmsg_free(msg); | ||
8382 | return; | ||
8383 | } | ||
8384 | |||
8385 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || | ||
8386 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) || | ||
8387 | nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason)) | ||
8388 | goto nla_put_failure; | ||
8389 | |||
8390 | genlmsg_end(msg, hdr); | ||
8391 | |||
8392 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | ||
8393 | nl80211_mlme_mcgrp.id, gfp); | ||
8394 | return; | ||
8395 | |||
8396 | nla_put_failure: | ||
8397 | genlmsg_cancel(msg, hdr); | ||
8398 | nlmsg_free(msg); | ||
8399 | } | ||
8400 | |||
8257 | static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd, | 8401 | static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd, |
8258 | const u8 *addr, gfp_t gfp) | 8402 | const u8 *addr, gfp_t gfp) |
8259 | { | 8403 | { |
@@ -8262,9 +8406,9 @@ static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd, | |||
8262 | struct sk_buff *msg; | 8406 | struct sk_buff *msg; |
8263 | void *hdr; | 8407 | void *hdr; |
8264 | int err; | 8408 | int err; |
8265 | u32 nlpid = ACCESS_ONCE(wdev->ap_unexpected_nlpid); | 8409 | u32 nlportid = ACCESS_ONCE(wdev->ap_unexpected_nlportid); |
8266 | 8410 | ||
8267 | if (!nlpid) | 8411 | if (!nlportid) |
8268 | return false; | 8412 | return false; |
8269 | 8413 | ||
8270 | msg = nlmsg_new(100, gfp); | 8414 | msg = nlmsg_new(100, gfp); |
@@ -8288,7 +8432,7 @@ static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd, | |||
8288 | return true; | 8432 | return true; |
8289 | } | 8433 | } |
8290 | 8434 | ||
8291 | genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid); | 8435 | genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid); |
8292 | return true; | 8436 | return true; |
8293 | 8437 | ||
8294 | nla_put_failure: | 8438 | nla_put_failure: |
@@ -8312,7 +8456,7 @@ bool nl80211_unexpected_4addr_frame(struct net_device *dev, | |||
8312 | } | 8456 | } |
8313 | 8457 | ||
8314 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | 8458 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, |
8315 | struct wireless_dev *wdev, u32 nlpid, | 8459 | struct wireless_dev *wdev, u32 nlportid, |
8316 | int freq, int sig_dbm, | 8460 | int freq, int sig_dbm, |
8317 | const u8 *buf, size_t len, gfp_t gfp) | 8461 | const u8 *buf, size_t len, gfp_t gfp) |
8318 | { | 8462 | { |
@@ -8341,7 +8485,7 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | |||
8341 | 8485 | ||
8342 | genlmsg_end(msg, hdr); | 8486 | genlmsg_end(msg, hdr); |
8343 | 8487 | ||
8344 | return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid); | 8488 | return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid); |
8345 | 8489 | ||
8346 | nla_put_failure: | 8490 | nla_put_failure: |
8347 | genlmsg_cancel(msg, hdr); | 8491 | genlmsg_cancel(msg, hdr); |
@@ -8696,9 +8840,9 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy, | |||
8696 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 8840 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
8697 | struct sk_buff *msg; | 8841 | struct sk_buff *msg; |
8698 | void *hdr; | 8842 | void *hdr; |
8699 | u32 nlpid = ACCESS_ONCE(rdev->ap_beacons_nlpid); | 8843 | u32 nlportid = ACCESS_ONCE(rdev->ap_beacons_nlportid); |
8700 | 8844 | ||
8701 | if (!nlpid) | 8845 | if (!nlportid) |
8702 | return; | 8846 | return; |
8703 | 8847 | ||
8704 | msg = nlmsg_new(len + 100, gfp); | 8848 | msg = nlmsg_new(len + 100, gfp); |
@@ -8721,7 +8865,7 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy, | |||
8721 | 8865 | ||
8722 | genlmsg_end(msg, hdr); | 8866 | genlmsg_end(msg, hdr); |
8723 | 8867 | ||
8724 | genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid); | 8868 | genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid); |
8725 | return; | 8869 | return; |
8726 | 8870 | ||
8727 | nla_put_failure: | 8871 | nla_put_failure: |
@@ -8745,9 +8889,9 @@ static int nl80211_netlink_notify(struct notifier_block * nb, | |||
8745 | 8889 | ||
8746 | list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { | 8890 | list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { |
8747 | list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) | 8891 | list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) |
8748 | cfg80211_mlme_unregister_socket(wdev, notify->pid); | 8892 | cfg80211_mlme_unregister_socket(wdev, notify->portid); |
8749 | if (rdev->ap_beacons_nlpid == notify->pid) | 8893 | if (rdev->ap_beacons_nlportid == notify->portid) |
8750 | rdev->ap_beacons_nlpid = 0; | 8894 | rdev->ap_beacons_nlportid = 0; |
8751 | } | 8895 | } |
8752 | 8896 | ||
8753 | rcu_read_unlock(); | 8897 | rcu_read_unlock(); |
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 9f2616fffb40..f6153516068c 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h | |||
@@ -91,6 +91,11 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev, | |||
91 | struct net_device *dev, const u8 *mac_addr, | 91 | struct net_device *dev, const u8 *mac_addr, |
92 | gfp_t gfp); | 92 | gfp_t gfp); |
93 | 93 | ||
94 | void nl80211_send_conn_failed_event(struct cfg80211_registered_device *rdev, | ||
95 | struct net_device *dev, const u8 *mac_addr, | ||
96 | enum nl80211_connect_failed_reason reason, | ||
97 | gfp_t gfp); | ||
98 | |||
94 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | 99 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, |
95 | struct wireless_dev *wdev, u32 nlpid, | 100 | struct wireless_dev *wdev, u32 nlpid, |
96 | int freq, int sig_dbm, | 101 | int freq, int sig_dbm, |
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c index c4ad7958af52..7d604c06c3dc 100644 --- a/net/wireless/radiotap.c +++ b/net/wireless/radiotap.c | |||
@@ -41,6 +41,8 @@ static const struct radiotap_align_size rtap_namespace_sizes[] = { | |||
41 | [IEEE80211_RADIOTAP_TX_FLAGS] = { .align = 2, .size = 2, }, | 41 | [IEEE80211_RADIOTAP_TX_FLAGS] = { .align = 2, .size = 2, }, |
42 | [IEEE80211_RADIOTAP_RTS_RETRIES] = { .align = 1, .size = 1, }, | 42 | [IEEE80211_RADIOTAP_RTS_RETRIES] = { .align = 1, .size = 1, }, |
43 | [IEEE80211_RADIOTAP_DATA_RETRIES] = { .align = 1, .size = 1, }, | 43 | [IEEE80211_RADIOTAP_DATA_RETRIES] = { .align = 1, .size = 1, }, |
44 | [IEEE80211_RADIOTAP_MCS] = { .align = 1, .size = 3, }, | ||
45 | [IEEE80211_RADIOTAP_AMPDU_STATUS] = { .align = 4, .size = 8, }, | ||
44 | /* | 46 | /* |
45 | * add more here as they are defined in radiotap.h | 47 | * add more here as they are defined in radiotap.h |
46 | */ | 48 | */ |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 72d170ca3406..3b8cbbc214db 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -510,9 +510,11 @@ static bool reg_does_bw_fit(const struct ieee80211_freq_range *freq_range, | |||
510 | * | 510 | * |
511 | * This lets us know if a specific frequency rule is or is not relevant to | 511 | * This lets us know if a specific frequency rule is or is not relevant to |
512 | * a specific frequency's band. Bands are device specific and artificial | 512 | * a specific frequency's band. Bands are device specific and artificial |
513 | * definitions (the "2.4 GHz band" and the "5 GHz band"), however it is | 513 | * definitions (the "2.4 GHz band", the "5 GHz band" and the "60GHz band"), |
514 | * safe for now to assume that a frequency rule should not be part of a | 514 | * however it is safe for now to assume that a frequency rule should not be |
515 | * frequency's band if the start freq or end freq are off by more than 2 GHz. | 515 | * part of a frequency's band if the start freq or end freq are off by more |
516 | * than 2 GHz for the 2.4 and 5 GHz bands, and by more than 10 GHz for the | ||
517 | * 60 GHz band. | ||
516 | * This resolution can be lowered and should be considered as we add | 518 | * This resolution can be lowered and should be considered as we add |
517 | * regulatory rule support for other "bands". | 519 | * regulatory rule support for other "bands". |
518 | **/ | 520 | **/ |
@@ -520,9 +522,16 @@ static bool freq_in_rule_band(const struct ieee80211_freq_range *freq_range, | |||
520 | u32 freq_khz) | 522 | u32 freq_khz) |
521 | { | 523 | { |
522 | #define ONE_GHZ_IN_KHZ 1000000 | 524 | #define ONE_GHZ_IN_KHZ 1000000 |
523 | if (abs(freq_khz - freq_range->start_freq_khz) <= (2 * ONE_GHZ_IN_KHZ)) | 525 | /* |
526 | * From 802.11ad: directional multi-gigabit (DMG): | ||
527 | * Pertaining to operation in a frequency band containing a channel | ||
528 | * with the Channel starting frequency above 45 GHz. | ||
529 | */ | ||
530 | u32 limit = freq_khz > 45 * ONE_GHZ_IN_KHZ ? | ||
531 | 10 * ONE_GHZ_IN_KHZ : 2 * ONE_GHZ_IN_KHZ; | ||
532 | if (abs(freq_khz - freq_range->start_freq_khz) <= limit) | ||
524 | return true; | 533 | return true; |
525 | if (abs(freq_khz - freq_range->end_freq_khz) <= (2 * ONE_GHZ_IN_KHZ)) | 534 | if (abs(freq_khz - freq_range->end_freq_khz) <= limit) |
526 | return true; | 535 | return true; |
527 | return false; | 536 | return false; |
528 | #undef ONE_GHZ_IN_KHZ | 537 | #undef ONE_GHZ_IN_KHZ |
@@ -1955,8 +1964,7 @@ static void restore_regulatory_settings(bool reset_user) | |||
1955 | if (reg_request->initiator != | 1964 | if (reg_request->initiator != |
1956 | NL80211_REGDOM_SET_BY_USER) | 1965 | NL80211_REGDOM_SET_BY_USER) |
1957 | continue; | 1966 | continue; |
1958 | list_del(®_request->list); | 1967 | list_move_tail(®_request->list, &tmp_reg_req_list); |
1959 | list_add_tail(®_request->list, &tmp_reg_req_list); | ||
1960 | } | 1968 | } |
1961 | } | 1969 | } |
1962 | spin_unlock(®_requests_lock); | 1970 | spin_unlock(®_requests_lock); |
@@ -2015,8 +2023,7 @@ static void restore_regulatory_settings(bool reset_user) | |||
2015 | "into the queue\n", | 2023 | "into the queue\n", |
2016 | reg_request->alpha2[0], | 2024 | reg_request->alpha2[0], |
2017 | reg_request->alpha2[1]); | 2025 | reg_request->alpha2[1]); |
2018 | list_del(®_request->list); | 2026 | list_move_tail(®_request->list, ®_requests_list); |
2019 | list_add_tail(®_request->list, ®_requests_list); | ||
2020 | } | 2027 | } |
2021 | spin_unlock(®_requests_lock); | 2028 | spin_unlock(®_requests_lock); |
2022 | 2029 | ||
@@ -2201,7 +2208,6 @@ static void print_regdomain_info(const struct ieee80211_regdomain *rd) | |||
2201 | static int __set_regdom(const struct ieee80211_regdomain *rd) | 2208 | static int __set_regdom(const struct ieee80211_regdomain *rd) |
2202 | { | 2209 | { |
2203 | const struct ieee80211_regdomain *intersected_rd = NULL; | 2210 | const struct ieee80211_regdomain *intersected_rd = NULL; |
2204 | struct cfg80211_registered_device *rdev = NULL; | ||
2205 | struct wiphy *request_wiphy; | 2211 | struct wiphy *request_wiphy; |
2206 | /* Some basic sanity checks first */ | 2212 | /* Some basic sanity checks first */ |
2207 | 2213 | ||
@@ -2313,24 +2319,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
2313 | return 0; | 2319 | return 0; |
2314 | } | 2320 | } |
2315 | 2321 | ||
2316 | if (!intersected_rd) | 2322 | return -EINVAL; |
2317 | return -EINVAL; | ||
2318 | |||
2319 | rdev = wiphy_to_dev(request_wiphy); | ||
2320 | |||
2321 | rdev->country_ie_alpha2[0] = rd->alpha2[0]; | ||
2322 | rdev->country_ie_alpha2[1] = rd->alpha2[1]; | ||
2323 | rdev->env = last_request->country_ie_env; | ||
2324 | |||
2325 | BUG_ON(intersected_rd == rd); | ||
2326 | |||
2327 | kfree(rd); | ||
2328 | rd = NULL; | ||
2329 | |||
2330 | reset_regdomains(false); | ||
2331 | cfg80211_regdomain = intersected_rd; | ||
2332 | |||
2333 | return 0; | ||
2334 | } | 2323 | } |
2335 | 2324 | ||
2336 | 2325 | ||
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 848523a2b22f..9730c9862bdc 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -815,7 +815,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, | |||
815 | return NULL; | 815 | return NULL; |
816 | 816 | ||
817 | if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC && | 817 | if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC && |
818 | (signal < 0 || signal > 100))) | 818 | (signal < 0 || signal > 100))) |
819 | return NULL; | 819 | return NULL; |
820 | 820 | ||
821 | if (WARN_ON(len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable))) | 821 | if (WARN_ON(len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable))) |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 994e2f0cc7a8..ef35f4ef2aa6 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -684,22 +684,10 @@ EXPORT_SYMBOL(cfg80211_classify8021d); | |||
684 | 684 | ||
685 | const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie) | 685 | const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie) |
686 | { | 686 | { |
687 | u8 *end, *pos; | 687 | if (bss->information_elements == NULL) |
688 | |||
689 | pos = bss->information_elements; | ||
690 | if (pos == NULL) | ||
691 | return NULL; | 688 | return NULL; |
692 | end = pos + bss->len_information_elements; | 689 | return cfg80211_find_ie(ie, bss->information_elements, |
693 | 690 | bss->len_information_elements); | |
694 | while (pos + 1 < end) { | ||
695 | if (pos + 2 + pos[1] > end) | ||
696 | break; | ||
697 | if (pos[0] == ie) | ||
698 | return pos; | ||
699 | pos += 2 + pos[1]; | ||
700 | } | ||
701 | |||
702 | return NULL; | ||
703 | } | 691 | } |
704 | EXPORT_SYMBOL(ieee80211_bss_get_ie); | 692 | EXPORT_SYMBOL(ieee80211_bss_get_ie); |
705 | 693 | ||
@@ -812,6 +800,10 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
812 | if (otype == NL80211_IFTYPE_AP_VLAN) | 800 | if (otype == NL80211_IFTYPE_AP_VLAN) |
813 | return -EOPNOTSUPP; | 801 | return -EOPNOTSUPP; |
814 | 802 | ||
803 | /* cannot change into P2P device type */ | ||
804 | if (ntype == NL80211_IFTYPE_P2P_DEVICE) | ||
805 | return -EOPNOTSUPP; | ||
806 | |||
815 | if (!rdev->ops->change_virtual_intf || | 807 | if (!rdev->ops->change_virtual_intf || |
816 | !(rdev->wiphy.interface_modes & (1 << ntype))) | 808 | !(rdev->wiphy.interface_modes & (1 << ntype))) |
817 | return -EOPNOTSUPP; | 809 | return -EOPNOTSUPP; |
@@ -889,6 +881,9 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
889 | case NUM_NL80211_IFTYPES: | 881 | case NUM_NL80211_IFTYPES: |
890 | /* not happening */ | 882 | /* not happening */ |
891 | break; | 883 | break; |
884 | case NL80211_IFTYPE_P2P_DEVICE: | ||
885 | WARN_ON(1); | ||
886 | break; | ||
892 | } | 887 | } |
893 | } | 888 | } |
894 | 889 | ||
@@ -1053,8 +1048,15 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, | |||
1053 | list_for_each_entry(wdev_iter, &rdev->wdev_list, list) { | 1048 | list_for_each_entry(wdev_iter, &rdev->wdev_list, list) { |
1054 | if (wdev_iter == wdev) | 1049 | if (wdev_iter == wdev) |
1055 | continue; | 1050 | continue; |
1056 | if (!netif_running(wdev_iter->netdev)) | 1051 | if (wdev_iter->netdev) { |
1057 | continue; | 1052 | if (!netif_running(wdev_iter->netdev)) |
1053 | continue; | ||
1054 | } else if (wdev_iter->iftype == NL80211_IFTYPE_P2P_DEVICE) { | ||
1055 | if (!wdev_iter->p2p_started) | ||
1056 | continue; | ||
1057 | } else { | ||
1058 | WARN_ON(1); | ||
1059 | } | ||
1058 | 1060 | ||
1059 | if (rdev->wiphy.software_iftypes & BIT(wdev_iter->iftype)) | 1061 | if (rdev->wiphy.software_iftypes & BIT(wdev_iter->iftype)) |
1060 | continue; | 1062 | continue; |
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index b0eb7aa49b60..c8717c1d082e 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c | |||
@@ -478,13 +478,13 @@ void wireless_send_event(struct net_device * dev, | |||
478 | if (descr->header_type == IW_HEADER_TYPE_POINT) { | 478 | if (descr->header_type == IW_HEADER_TYPE_POINT) { |
479 | /* Check if number of token fits within bounds */ | 479 | /* Check if number of token fits within bounds */ |
480 | if (wrqu->data.length > descr->max_tokens) { | 480 | if (wrqu->data.length > descr->max_tokens) { |
481 | netdev_err(dev, "(WE) : Wireless Event too big (%d)\n", | 481 | netdev_err(dev, "(WE) : Wireless Event (cmd=0x%04X) too big (%d)\n", |
482 | wrqu->data.length); | 482 | cmd, wrqu->data.length); |
483 | return; | 483 | return; |
484 | } | 484 | } |
485 | if (wrqu->data.length < descr->min_tokens) { | 485 | if (wrqu->data.length < descr->min_tokens) { |
486 | netdev_err(dev, "(WE) : Wireless Event too small (%d)\n", | 486 | netdev_err(dev, "(WE) : Wireless Event (cmd=0x%04X) too small (%d)\n", |
487 | wrqu->data.length); | 487 | cmd, wrqu->data.length); |
488 | return; | 488 | return; |
489 | } | 489 | } |
490 | /* Calculate extra_len - extra is NULL for restricted events */ | 490 | /* Calculate extra_len - extra is NULL for restricted events */ |