diff options
Diffstat (limited to 'net/wireless/util.c')
-rw-r--r-- | net/wireless/util.c | 50 |
1 files changed, 39 insertions, 11 deletions
diff --git a/net/wireless/util.c b/net/wireless/util.c index 1c39d6a2e850..e74837824cea 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -233,25 +233,30 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, | |||
233 | 233 | ||
234 | switch (params->cipher) { | 234 | switch (params->cipher) { |
235 | case WLAN_CIPHER_SUITE_TKIP: | 235 | case WLAN_CIPHER_SUITE_TKIP: |
236 | /* Extended Key ID can only be used with CCMP/GCMP ciphers */ | ||
237 | if ((pairwise && key_idx) || | ||
238 | params->mode != NL80211_KEY_RX_TX) | ||
239 | return -EINVAL; | ||
240 | break; | ||
236 | case WLAN_CIPHER_SUITE_CCMP: | 241 | case WLAN_CIPHER_SUITE_CCMP: |
237 | case WLAN_CIPHER_SUITE_CCMP_256: | 242 | case WLAN_CIPHER_SUITE_CCMP_256: |
238 | case WLAN_CIPHER_SUITE_GCMP: | 243 | case WLAN_CIPHER_SUITE_GCMP: |
239 | case WLAN_CIPHER_SUITE_GCMP_256: | 244 | case WLAN_CIPHER_SUITE_GCMP_256: |
240 | /* IEEE802.11-2016 allows only 0 and - when using Extended Key | 245 | /* IEEE802.11-2016 allows only 0 and - when supporting |
241 | * ID - 1 as index for pairwise keys. | 246 | * Extended Key ID - 1 as index for pairwise keys. |
242 | * @NL80211_KEY_NO_TX is only allowed for pairwise keys when | 247 | * @NL80211_KEY_NO_TX is only allowed for pairwise keys when |
243 | * the driver supports Extended Key ID. | 248 | * the driver supports Extended Key ID. |
244 | * @NL80211_KEY_SET_TX can't be set when installing and | 249 | * @NL80211_KEY_SET_TX can't be set when installing and |
245 | * validating a key. | 250 | * validating a key. |
246 | */ | 251 | */ |
247 | if (params->mode == NL80211_KEY_NO_TX) { | 252 | if ((params->mode == NL80211_KEY_NO_TX && !pairwise) || |
248 | if (!wiphy_ext_feature_isset(&rdev->wiphy, | 253 | params->mode == NL80211_KEY_SET_TX) |
249 | NL80211_EXT_FEATURE_EXT_KEY_ID)) | 254 | return -EINVAL; |
250 | return -EINVAL; | 255 | if (wiphy_ext_feature_isset(&rdev->wiphy, |
251 | else if (!pairwise || key_idx < 0 || key_idx > 1) | 256 | NL80211_EXT_FEATURE_EXT_KEY_ID)) { |
257 | if (pairwise && (key_idx < 0 || key_idx > 1)) | ||
252 | return -EINVAL; | 258 | return -EINVAL; |
253 | } else if ((pairwise && key_idx) || | 259 | } else if (pairwise && key_idx) { |
254 | params->mode == NL80211_KEY_SET_TX) { | ||
255 | return -EINVAL; | 260 | return -EINVAL; |
256 | } | 261 | } |
257 | break; | 262 | break; |
@@ -1697,7 +1702,7 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, | |||
1697 | for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { | 1702 | for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { |
1698 | num_interfaces += params->iftype_num[iftype]; | 1703 | num_interfaces += params->iftype_num[iftype]; |
1699 | if (params->iftype_num[iftype] > 0 && | 1704 | if (params->iftype_num[iftype] > 0 && |
1700 | !(wiphy->software_iftypes & BIT(iftype))) | 1705 | !cfg80211_iftype_allowed(wiphy, iftype, 0, 1)) |
1701 | used_iftypes |= BIT(iftype); | 1706 | used_iftypes |= BIT(iftype); |
1702 | } | 1707 | } |
1703 | 1708 | ||
@@ -1719,7 +1724,7 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, | |||
1719 | return -ENOMEM; | 1724 | return -ENOMEM; |
1720 | 1725 | ||
1721 | for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { | 1726 | for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { |
1722 | if (wiphy->software_iftypes & BIT(iftype)) | 1727 | if (cfg80211_iftype_allowed(wiphy, iftype, 0, 1)) |
1723 | continue; | 1728 | continue; |
1724 | for (j = 0; j < c->n_limits; j++) { | 1729 | for (j = 0; j < c->n_limits; j++) { |
1725 | all_iftypes |= limits[j].types; | 1730 | all_iftypes |= limits[j].types; |
@@ -2072,3 +2077,26 @@ int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap, | |||
2072 | return max_vht_nss; | 2077 | return max_vht_nss; |
2073 | } | 2078 | } |
2074 | EXPORT_SYMBOL(ieee80211_get_vht_max_nss); | 2079 | EXPORT_SYMBOL(ieee80211_get_vht_max_nss); |
2080 | |||
2081 | bool cfg80211_iftype_allowed(struct wiphy *wiphy, enum nl80211_iftype iftype, | ||
2082 | bool is_4addr, u8 check_swif) | ||
2083 | |||
2084 | { | ||
2085 | bool is_vlan = iftype == NL80211_IFTYPE_AP_VLAN; | ||
2086 | |||
2087 | switch (check_swif) { | ||
2088 | case 0: | ||
2089 | if (is_vlan && is_4addr) | ||
2090 | return wiphy->flags & WIPHY_FLAG_4ADDR_AP; | ||
2091 | return wiphy->interface_modes & BIT(iftype); | ||
2092 | case 1: | ||
2093 | if (!(wiphy->software_iftypes & BIT(iftype)) && is_vlan) | ||
2094 | return wiphy->flags & WIPHY_FLAG_4ADDR_AP; | ||
2095 | return wiphy->software_iftypes & BIT(iftype); | ||
2096 | default: | ||
2097 | break; | ||
2098 | } | ||
2099 | |||
2100 | return false; | ||
2101 | } | ||
2102 | EXPORT_SYMBOL(cfg80211_iftype_allowed); | ||