aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/util.c')
-rw-r--r--net/wireless/util.c230
1 files changed, 186 insertions, 44 deletions
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 0c8a1e8b7690..4d7b83fbc32f 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -29,29 +29,37 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
29} 29}
30EXPORT_SYMBOL(ieee80211_get_response_rate); 30EXPORT_SYMBOL(ieee80211_get_response_rate);
31 31
32int ieee80211_channel_to_frequency(int chan) 32int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band)
33{ 33{
34 if (chan < 14) 34 /* see 802.11 17.3.8.3.2 and Annex J
35 return 2407 + chan * 5; 35 * there are overlapping channel numbers in 5GHz and 2GHz bands */
36 36 if (band == IEEE80211_BAND_5GHZ) {
37 if (chan == 14) 37 if (chan >= 182 && chan <= 196)
38 return 2484; 38 return 4000 + chan * 5;
39 39 else
40 /* FIXME: 802.11j 17.3.8.3.2 */ 40 return 5000 + chan * 5;
41 return (chan + 1000) * 5; 41 } else { /* IEEE80211_BAND_2GHZ */
42 if (chan == 14)
43 return 2484;
44 else if (chan < 14)
45 return 2407 + chan * 5;
46 else
47 return 0; /* not supported */
48 }
42} 49}
43EXPORT_SYMBOL(ieee80211_channel_to_frequency); 50EXPORT_SYMBOL(ieee80211_channel_to_frequency);
44 51
45int ieee80211_frequency_to_channel(int freq) 52int ieee80211_frequency_to_channel(int freq)
46{ 53{
54 /* see 802.11 17.3.8.3.2 and Annex J */
47 if (freq == 2484) 55 if (freq == 2484)
48 return 14; 56 return 14;
49 57 else if (freq < 2484)
50 if (freq < 2484)
51 return (freq - 2407) / 5; 58 return (freq - 2407) / 5;
52 59 else if (freq >= 4910 && freq <= 4980)
53 /* FIXME: 802.11j 17.3.8.3.2 */ 60 return (freq - 4000) / 5;
54 return freq/5 - 1000; 61 else
62 return (freq - 5000) / 5;
55} 63}
56EXPORT_SYMBOL(ieee80211_frequency_to_channel); 64EXPORT_SYMBOL(ieee80211_frequency_to_channel);
57 65
@@ -144,21 +152,30 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
144 152
145int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, 153int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
146 struct key_params *params, int key_idx, 154 struct key_params *params, int key_idx,
147 const u8 *mac_addr) 155 bool pairwise, const u8 *mac_addr)
148{ 156{
149 int i; 157 int i;
150 158
151 if (key_idx > 5) 159 if (key_idx > 5)
152 return -EINVAL; 160 return -EINVAL;
153 161
162 if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
163 return -EINVAL;
164
165 if (pairwise && !mac_addr)
166 return -EINVAL;
167
154 /* 168 /*
155 * Disallow pairwise keys with non-zero index unless it's WEP 169 * Disallow pairwise keys with non-zero index unless it's WEP
156 * (because current deployments use pairwise WEP keys with 170 * or a vendor specific cipher (because current deployments use
157 * non-zero indizes but 802.11i clearly specifies to use zero) 171 * pairwise WEP keys with non-zero indices and for vendor specific
172 * ciphers this should be validated in the driver or hardware level
173 * - but 802.11i clearly specifies to use zero)
158 */ 174 */
159 if (mac_addr && key_idx && 175 if (pairwise && key_idx &&
160 params->cipher != WLAN_CIPHER_SUITE_WEP40 && 176 ((params->cipher == WLAN_CIPHER_SUITE_TKIP) ||
161 params->cipher != WLAN_CIPHER_SUITE_WEP104) 177 (params->cipher == WLAN_CIPHER_SUITE_CCMP) ||
178 (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC)))
162 return -EINVAL; 179 return -EINVAL;
163 180
164 switch (params->cipher) { 181 switch (params->cipher) {
@@ -183,7 +200,14 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
183 return -EINVAL; 200 return -EINVAL;
184 break; 201 break;
185 default: 202 default:
186 return -EINVAL; 203 /*
204 * We don't know anything about this algorithm,
205 * allow using it -- but the driver must check
206 * all parameters! We still check below whether
207 * or not the driver supports this algorithm,
208 * of course.
209 */
210 break;
187 } 211 }
188 212
189 if (params->seq) { 213 if (params->seq) {
@@ -221,7 +245,7 @@ const unsigned char bridge_tunnel_header[] __aligned(2) =
221 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; 245 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
222EXPORT_SYMBOL(bridge_tunnel_header); 246EXPORT_SYMBOL(bridge_tunnel_header);
223 247
224unsigned int ieee80211_hdrlen(__le16 fc) 248unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc)
225{ 249{
226 unsigned int hdrlen = 24; 250 unsigned int hdrlen = 24;
227 251
@@ -319,7 +343,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
319 cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { 343 cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
320 case cpu_to_le16(IEEE80211_FCTL_TODS): 344 case cpu_to_le16(IEEE80211_FCTL_TODS):
321 if (unlikely(iftype != NL80211_IFTYPE_AP && 345 if (unlikely(iftype != NL80211_IFTYPE_AP &&
322 iftype != NL80211_IFTYPE_AP_VLAN)) 346 iftype != NL80211_IFTYPE_AP_VLAN &&
347 iftype != NL80211_IFTYPE_P2P_GO))
323 return -1; 348 return -1;
324 break; 349 break;
325 case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): 350 case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):
@@ -347,7 +372,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
347 break; 372 break;
348 case cpu_to_le16(IEEE80211_FCTL_FROMDS): 373 case cpu_to_le16(IEEE80211_FCTL_FROMDS):
349 if ((iftype != NL80211_IFTYPE_STATION && 374 if ((iftype != NL80211_IFTYPE_STATION &&
350 iftype != NL80211_IFTYPE_MESH_POINT) || 375 iftype != NL80211_IFTYPE_P2P_CLIENT &&
376 iftype != NL80211_IFTYPE_MESH_POINT) ||
351 (is_multicast_ether_addr(dst) && 377 (is_multicast_ether_addr(dst) &&
352 !compare_ether_addr(src, addr))) 378 !compare_ether_addr(src, addr)))
353 return -1; 379 return -1;
@@ -424,6 +450,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
424 switch (iftype) { 450 switch (iftype) {
425 case NL80211_IFTYPE_AP: 451 case NL80211_IFTYPE_AP:
426 case NL80211_IFTYPE_AP_VLAN: 452 case NL80211_IFTYPE_AP_VLAN:
453 case NL80211_IFTYPE_P2P_GO:
427 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); 454 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
428 /* DA BSSID SA */ 455 /* DA BSSID SA */
429 memcpy(hdr.addr1, skb->data, ETH_ALEN); 456 memcpy(hdr.addr1, skb->data, ETH_ALEN);
@@ -432,6 +459,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
432 hdrlen = 24; 459 hdrlen = 24;
433 break; 460 break;
434 case NL80211_IFTYPE_STATION: 461 case NL80211_IFTYPE_STATION:
462 case NL80211_IFTYPE_P2P_CLIENT:
435 fc |= cpu_to_le16(IEEE80211_FCTL_TODS); 463 fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
436 /* BSSID SA DA */ 464 /* BSSID SA DA */
437 memcpy(hdr.addr1, bssid, ETH_ALEN); 465 memcpy(hdr.addr1, bssid, ETH_ALEN);
@@ -485,7 +513,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
485 skb_orphan(skb); 513 skb_orphan(skb);
486 514
487 if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) { 515 if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) {
488 printk(KERN_ERR "failed to reallocate Tx buffer\n"); 516 pr_err("failed to reallocate Tx buffer\n");
489 return -ENOMEM; 517 return -ENOMEM;
490 } 518 }
491 skb->truesize += head_need; 519 skb->truesize += head_need;
@@ -516,7 +544,8 @@ EXPORT_SYMBOL(ieee80211_data_from_8023);
516 544
517void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, 545void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
518 const u8 *addr, enum nl80211_iftype iftype, 546 const u8 *addr, enum nl80211_iftype iftype,
519 const unsigned int extra_headroom) 547 const unsigned int extra_headroom,
548 bool has_80211_header)
520{ 549{
521 struct sk_buff *frame = NULL; 550 struct sk_buff *frame = NULL;
522 u16 ethertype; 551 u16 ethertype;
@@ -525,14 +554,18 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
525 int remaining, err; 554 int remaining, err;
526 u8 dst[ETH_ALEN], src[ETH_ALEN]; 555 u8 dst[ETH_ALEN], src[ETH_ALEN];
527 556
528 err = ieee80211_data_to_8023(skb, addr, iftype); 557 if (has_80211_header) {
529 if (err) 558 err = ieee80211_data_to_8023(skb, addr, iftype);
530 goto out; 559 if (err)
560 goto out;
531 561
532 /* skip the wrapping header */ 562 /* skip the wrapping header */
533 eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr)); 563 eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr));
534 if (!eth) 564 if (!eth)
535 goto out; 565 goto out;
566 } else {
567 eth = (struct ethhdr *) skb->data;
568 }
536 569
537 while (skb != frame) { 570 while (skb != frame) {
538 u8 padding; 571 u8 padding;
@@ -666,22 +699,20 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
666 for (i = 0; i < 6; i++) { 699 for (i = 0; i < 6; i++) {
667 if (!wdev->connect_keys->params[i].cipher) 700 if (!wdev->connect_keys->params[i].cipher)
668 continue; 701 continue;
669 if (rdev->ops->add_key(wdev->wiphy, dev, i, NULL, 702 if (rdev->ops->add_key(wdev->wiphy, dev, i, false, NULL,
670 &wdev->connect_keys->params[i])) { 703 &wdev->connect_keys->params[i])) {
671 printk(KERN_ERR "%s: failed to set key %d\n", 704 netdev_err(dev, "failed to set key %d\n", i);
672 dev->name, i);
673 continue; 705 continue;
674 } 706 }
675 if (wdev->connect_keys->def == i) 707 if (wdev->connect_keys->def == i)
676 if (rdev->ops->set_default_key(wdev->wiphy, dev, i)) { 708 if (rdev->ops->set_default_key(wdev->wiphy, dev,
677 printk(KERN_ERR "%s: failed to set defkey %d\n", 709 i, true, true)) {
678 dev->name, i); 710 netdev_err(dev, "failed to set defkey %d\n", i);
679 continue; 711 continue;
680 } 712 }
681 if (wdev->connect_keys->defmgmt == i) 713 if (wdev->connect_keys->defmgmt == i)
682 if (rdev->ops->set_default_mgmt_key(wdev->wiphy, dev, i)) 714 if (rdev->ops->set_default_mgmt_key(wdev->wiphy, dev, i))
683 printk(KERN_ERR "%s: failed to set mgtdef %d\n", 715 netdev_err(dev, "failed to set mgtdef %d\n", i);
684 dev->name, i);
685 } 716 }
686 717
687 kfree(wdev->connect_keys); 718 kfree(wdev->connect_keys);
@@ -715,7 +746,7 @@ static void cfg80211_process_wdev_events(struct wireless_dev *wdev)
715 NULL); 746 NULL);
716 break; 747 break;
717 case EVENT_ROAMED: 748 case EVENT_ROAMED:
718 __cfg80211_roamed(wdev, ev->rm.bssid, 749 __cfg80211_roamed(wdev, ev->rm.channel, ev->rm.bssid,
719 ev->rm.req_ie, ev->rm.req_ie_len, 750 ev->rm.req_ie, ev->rm.req_ie_len,
720 ev->rm.resp_ie, ev->rm.resp_ie_len); 751 ev->rm.resp_ie, ev->rm.resp_ie_len);
721 break; 752 break;
@@ -771,17 +802,26 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
771 802
772 /* if it's part of a bridge, reject changing type to station/ibss */ 803 /* if it's part of a bridge, reject changing type to station/ibss */
773 if ((dev->priv_flags & IFF_BRIDGE_PORT) && 804 if ((dev->priv_flags & IFF_BRIDGE_PORT) &&
774 (ntype == NL80211_IFTYPE_ADHOC || ntype == NL80211_IFTYPE_STATION)) 805 (ntype == NL80211_IFTYPE_ADHOC ||
806 ntype == NL80211_IFTYPE_STATION ||
807 ntype == NL80211_IFTYPE_P2P_CLIENT))
775 return -EBUSY; 808 return -EBUSY;
776 809
777 if (ntype != otype) { 810 if (ntype != otype) {
811 err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr,
812 ntype);
813 if (err)
814 return err;
815
778 dev->ieee80211_ptr->use_4addr = false; 816 dev->ieee80211_ptr->use_4addr = false;
817 dev->ieee80211_ptr->mesh_id_up_len = 0;
779 818
780 switch (otype) { 819 switch (otype) {
781 case NL80211_IFTYPE_ADHOC: 820 case NL80211_IFTYPE_ADHOC:
782 cfg80211_leave_ibss(rdev, dev, false); 821 cfg80211_leave_ibss(rdev, dev, false);
783 break; 822 break;
784 case NL80211_IFTYPE_STATION: 823 case NL80211_IFTYPE_STATION:
824 case NL80211_IFTYPE_P2P_CLIENT:
785 cfg80211_disconnect(rdev, dev, 825 cfg80211_disconnect(rdev, dev,
786 WLAN_REASON_DEAUTH_LEAVING, true); 826 WLAN_REASON_DEAUTH_LEAVING, true);
787 break; 827 break;
@@ -810,9 +850,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
810 if (dev->ieee80211_ptr->use_4addr) 850 if (dev->ieee80211_ptr->use_4addr)
811 break; 851 break;
812 /* fall through */ 852 /* fall through */
853 case NL80211_IFTYPE_P2P_CLIENT:
813 case NL80211_IFTYPE_ADHOC: 854 case NL80211_IFTYPE_ADHOC:
814 dev->priv_flags |= IFF_DONT_BRIDGE; 855 dev->priv_flags |= IFF_DONT_BRIDGE;
815 break; 856 break;
857 case NL80211_IFTYPE_P2P_GO:
816 case NL80211_IFTYPE_AP: 858 case NL80211_IFTYPE_AP:
817 case NL80211_IFTYPE_AP_VLAN: 859 case NL80211_IFTYPE_AP_VLAN:
818 case NL80211_IFTYPE_WDS: 860 case NL80211_IFTYPE_WDS:
@@ -823,7 +865,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
823 /* monitor can't bridge anyway */ 865 /* monitor can't bridge anyway */
824 break; 866 break;
825 case NL80211_IFTYPE_UNSPECIFIED: 867 case NL80211_IFTYPE_UNSPECIFIED:
826 case __NL80211_IFTYPE_AFTER_LAST: 868 case NUM_NL80211_IFTYPES:
827 /* not happening */ 869 /* not happening */
828 break; 870 break;
829 } 871 }
@@ -864,3 +906,103 @@ u16 cfg80211_calculate_bitrate(struct rate_info *rate)
864 /* do NOT round down here */ 906 /* do NOT round down here */
865 return (bitrate + 50000) / 100000; 907 return (bitrate + 50000) / 100000;
866} 908}
909
910int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
911 u32 beacon_int)
912{
913 struct wireless_dev *wdev;
914 int res = 0;
915
916 if (!beacon_int)
917 return -EINVAL;
918
919 mutex_lock(&rdev->devlist_mtx);
920
921 list_for_each_entry(wdev, &rdev->netdev_list, list) {
922 if (!wdev->beacon_interval)
923 continue;
924 if (wdev->beacon_interval != beacon_int) {
925 res = -EINVAL;
926 break;
927 }
928 }
929
930 mutex_unlock(&rdev->devlist_mtx);
931
932 return res;
933}
934
935int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
936 struct wireless_dev *wdev,
937 enum nl80211_iftype iftype)
938{
939 struct wireless_dev *wdev_iter;
940 int num[NUM_NL80211_IFTYPES];
941 int total = 1;
942 int i, j;
943
944 ASSERT_RTNL();
945
946 /* Always allow software iftypes */
947 if (rdev->wiphy.software_iftypes & BIT(iftype))
948 return 0;
949
950 /*
951 * Drivers will gradually all set this flag, until all
952 * have it we only enforce for those that set it.
953 */
954 if (!(rdev->wiphy.flags & WIPHY_FLAG_ENFORCE_COMBINATIONS))
955 return 0;
956
957 memset(num, 0, sizeof(num));
958
959 num[iftype] = 1;
960
961 mutex_lock(&rdev->devlist_mtx);
962 list_for_each_entry(wdev_iter, &rdev->netdev_list, list) {
963 if (wdev_iter == wdev)
964 continue;
965 if (!netif_running(wdev_iter->netdev))
966 continue;
967
968 if (rdev->wiphy.software_iftypes & BIT(wdev_iter->iftype))
969 continue;
970
971 num[wdev_iter->iftype]++;
972 total++;
973 }
974 mutex_unlock(&rdev->devlist_mtx);
975
976 for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) {
977 const struct ieee80211_iface_combination *c;
978 struct ieee80211_iface_limit *limits;
979
980 c = &rdev->wiphy.iface_combinations[i];
981
982 limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits,
983 GFP_KERNEL);
984 if (!limits)
985 return -ENOMEM;
986 if (total > c->max_interfaces)
987 goto cont;
988
989 for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) {
990 if (rdev->wiphy.software_iftypes & BIT(iftype))
991 continue;
992 for (j = 0; j < c->n_limits; j++) {
993 if (!(limits[j].types & iftype))
994 continue;
995 if (limits[j].max < num[iftype])
996 goto cont;
997 limits[j].max -= num[iftype];
998 }
999 }
1000 /* yay, it fits */
1001 kfree(limits);
1002 return 0;
1003 cont:
1004 kfree(limits);
1005 }
1006
1007 return -EBUSY;
1008}