diff options
Diffstat (limited to 'net/wireless/util.c')
-rw-r--r-- | net/wireless/util.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/net/wireless/util.c b/net/wireless/util.c index 0c8a1e8b769..76120aeda57 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -144,19 +144,25 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy) | |||
144 | 144 | ||
145 | int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, | 145 | int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, |
146 | struct key_params *params, int key_idx, | 146 | struct key_params *params, int key_idx, |
147 | const u8 *mac_addr) | 147 | bool pairwise, const u8 *mac_addr) |
148 | { | 148 | { |
149 | int i; | 149 | int i; |
150 | 150 | ||
151 | if (key_idx > 5) | 151 | if (key_idx > 5) |
152 | return -EINVAL; | 152 | return -EINVAL; |
153 | 153 | ||
154 | if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) | ||
155 | return -EINVAL; | ||
156 | |||
157 | if (pairwise && !mac_addr) | ||
158 | return -EINVAL; | ||
159 | |||
154 | /* | 160 | /* |
155 | * Disallow pairwise keys with non-zero index unless it's WEP | 161 | * Disallow pairwise keys with non-zero index unless it's WEP |
156 | * (because current deployments use pairwise WEP keys with | 162 | * (because current deployments use pairwise WEP keys with |
157 | * non-zero indizes but 802.11i clearly specifies to use zero) | 163 | * non-zero indizes but 802.11i clearly specifies to use zero) |
158 | */ | 164 | */ |
159 | if (mac_addr && key_idx && | 165 | if (pairwise && key_idx && |
160 | params->cipher != WLAN_CIPHER_SUITE_WEP40 && | 166 | params->cipher != WLAN_CIPHER_SUITE_WEP40 && |
161 | params->cipher != WLAN_CIPHER_SUITE_WEP104) | 167 | params->cipher != WLAN_CIPHER_SUITE_WEP104) |
162 | return -EINVAL; | 168 | return -EINVAL; |
@@ -183,7 +189,14 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, | |||
183 | return -EINVAL; | 189 | return -EINVAL; |
184 | break; | 190 | break; |
185 | default: | 191 | default: |
186 | return -EINVAL; | 192 | /* |
193 | * We don't know anything about this algorithm, | ||
194 | * allow using it -- but the driver must check | ||
195 | * all parameters! We still check below whether | ||
196 | * or not the driver supports this algorithm, | ||
197 | * of course. | ||
198 | */ | ||
199 | break; | ||
187 | } | 200 | } |
188 | 201 | ||
189 | if (params->seq) { | 202 | if (params->seq) { |
@@ -221,7 +234,7 @@ const unsigned char bridge_tunnel_header[] __aligned(2) = | |||
221 | { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; | 234 | { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; |
222 | EXPORT_SYMBOL(bridge_tunnel_header); | 235 | EXPORT_SYMBOL(bridge_tunnel_header); |
223 | 236 | ||
224 | unsigned int ieee80211_hdrlen(__le16 fc) | 237 | unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc) |
225 | { | 238 | { |
226 | unsigned int hdrlen = 24; | 239 | unsigned int hdrlen = 24; |
227 | 240 | ||
@@ -319,7 +332,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, | |||
319 | cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { | 332 | cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { |
320 | case cpu_to_le16(IEEE80211_FCTL_TODS): | 333 | case cpu_to_le16(IEEE80211_FCTL_TODS): |
321 | if (unlikely(iftype != NL80211_IFTYPE_AP && | 334 | if (unlikely(iftype != NL80211_IFTYPE_AP && |
322 | iftype != NL80211_IFTYPE_AP_VLAN)) | 335 | iftype != NL80211_IFTYPE_AP_VLAN && |
336 | iftype != NL80211_IFTYPE_P2P_GO)) | ||
323 | return -1; | 337 | return -1; |
324 | break; | 338 | break; |
325 | case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): | 339 | case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): |
@@ -347,7 +361,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, | |||
347 | break; | 361 | break; |
348 | case cpu_to_le16(IEEE80211_FCTL_FROMDS): | 362 | case cpu_to_le16(IEEE80211_FCTL_FROMDS): |
349 | if ((iftype != NL80211_IFTYPE_STATION && | 363 | if ((iftype != NL80211_IFTYPE_STATION && |
350 | iftype != NL80211_IFTYPE_MESH_POINT) || | 364 | iftype != NL80211_IFTYPE_P2P_CLIENT && |
365 | iftype != NL80211_IFTYPE_MESH_POINT) || | ||
351 | (is_multicast_ether_addr(dst) && | 366 | (is_multicast_ether_addr(dst) && |
352 | !compare_ether_addr(src, addr))) | 367 | !compare_ether_addr(src, addr))) |
353 | return -1; | 368 | return -1; |
@@ -424,6 +439,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, | |||
424 | switch (iftype) { | 439 | switch (iftype) { |
425 | case NL80211_IFTYPE_AP: | 440 | case NL80211_IFTYPE_AP: |
426 | case NL80211_IFTYPE_AP_VLAN: | 441 | case NL80211_IFTYPE_AP_VLAN: |
442 | case NL80211_IFTYPE_P2P_GO: | ||
427 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); | 443 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); |
428 | /* DA BSSID SA */ | 444 | /* DA BSSID SA */ |
429 | memcpy(hdr.addr1, skb->data, ETH_ALEN); | 445 | memcpy(hdr.addr1, skb->data, ETH_ALEN); |
@@ -432,6 +448,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, | |||
432 | hdrlen = 24; | 448 | hdrlen = 24; |
433 | break; | 449 | break; |
434 | case NL80211_IFTYPE_STATION: | 450 | case NL80211_IFTYPE_STATION: |
451 | case NL80211_IFTYPE_P2P_CLIENT: | ||
435 | fc |= cpu_to_le16(IEEE80211_FCTL_TODS); | 452 | fc |= cpu_to_le16(IEEE80211_FCTL_TODS); |
436 | /* BSSID SA DA */ | 453 | /* BSSID SA DA */ |
437 | memcpy(hdr.addr1, bssid, ETH_ALEN); | 454 | memcpy(hdr.addr1, bssid, ETH_ALEN); |
@@ -666,7 +683,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev) | |||
666 | for (i = 0; i < 6; i++) { | 683 | for (i = 0; i < 6; i++) { |
667 | if (!wdev->connect_keys->params[i].cipher) | 684 | if (!wdev->connect_keys->params[i].cipher) |
668 | continue; | 685 | continue; |
669 | if (rdev->ops->add_key(wdev->wiphy, dev, i, NULL, | 686 | if (rdev->ops->add_key(wdev->wiphy, dev, i, false, NULL, |
670 | &wdev->connect_keys->params[i])) { | 687 | &wdev->connect_keys->params[i])) { |
671 | printk(KERN_ERR "%s: failed to set key %d\n", | 688 | printk(KERN_ERR "%s: failed to set key %d\n", |
672 | dev->name, i); | 689 | dev->name, i); |
@@ -771,7 +788,9 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
771 | 788 | ||
772 | /* if it's part of a bridge, reject changing type to station/ibss */ | 789 | /* if it's part of a bridge, reject changing type to station/ibss */ |
773 | if ((dev->priv_flags & IFF_BRIDGE_PORT) && | 790 | if ((dev->priv_flags & IFF_BRIDGE_PORT) && |
774 | (ntype == NL80211_IFTYPE_ADHOC || ntype == NL80211_IFTYPE_STATION)) | 791 | (ntype == NL80211_IFTYPE_ADHOC || |
792 | ntype == NL80211_IFTYPE_STATION || | ||
793 | ntype == NL80211_IFTYPE_P2P_CLIENT)) | ||
775 | return -EBUSY; | 794 | return -EBUSY; |
776 | 795 | ||
777 | if (ntype != otype) { | 796 | if (ntype != otype) { |
@@ -782,6 +801,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
782 | cfg80211_leave_ibss(rdev, dev, false); | 801 | cfg80211_leave_ibss(rdev, dev, false); |
783 | break; | 802 | break; |
784 | case NL80211_IFTYPE_STATION: | 803 | case NL80211_IFTYPE_STATION: |
804 | case NL80211_IFTYPE_P2P_CLIENT: | ||
785 | cfg80211_disconnect(rdev, dev, | 805 | cfg80211_disconnect(rdev, dev, |
786 | WLAN_REASON_DEAUTH_LEAVING, true); | 806 | WLAN_REASON_DEAUTH_LEAVING, true); |
787 | break; | 807 | break; |
@@ -810,9 +830,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
810 | if (dev->ieee80211_ptr->use_4addr) | 830 | if (dev->ieee80211_ptr->use_4addr) |
811 | break; | 831 | break; |
812 | /* fall through */ | 832 | /* fall through */ |
833 | case NL80211_IFTYPE_P2P_CLIENT: | ||
813 | case NL80211_IFTYPE_ADHOC: | 834 | case NL80211_IFTYPE_ADHOC: |
814 | dev->priv_flags |= IFF_DONT_BRIDGE; | 835 | dev->priv_flags |= IFF_DONT_BRIDGE; |
815 | break; | 836 | break; |
837 | case NL80211_IFTYPE_P2P_GO: | ||
816 | case NL80211_IFTYPE_AP: | 838 | case NL80211_IFTYPE_AP: |
817 | case NL80211_IFTYPE_AP_VLAN: | 839 | case NL80211_IFTYPE_AP_VLAN: |
818 | case NL80211_IFTYPE_WDS: | 840 | case NL80211_IFTYPE_WDS: |
@@ -823,7 +845,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
823 | /* monitor can't bridge anyway */ | 845 | /* monitor can't bridge anyway */ |
824 | break; | 846 | break; |
825 | case NL80211_IFTYPE_UNSPECIFIED: | 847 | case NL80211_IFTYPE_UNSPECIFIED: |
826 | case __NL80211_IFTYPE_AFTER_LAST: | 848 | case NUM_NL80211_IFTYPES: |
827 | /* not happening */ | 849 | /* not happening */ |
828 | break; | 850 | break; |
829 | } | 851 | } |