aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/cfg80211.h8
-rw-r--r--include/uapi/linux/nl80211.h20
-rw-r--r--net/wireless/nl80211.c13
3 files changed, 39 insertions, 2 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b1f84b05c67e..572005981366 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1701,8 +1701,14 @@ struct cfg80211_ibss_params {
1701 * 1701 *
1702 * @channel: The channel to use or %NULL if not specified (auto-select based 1702 * @channel: The channel to use or %NULL if not specified (auto-select based
1703 * on scan results) 1703 * on scan results)
1704 * @channel_hint: The channel of the recommended BSS for initial connection or
1705 * %NULL if not specified
1704 * @bssid: The AP BSSID or %NULL if not specified (auto-select based on scan 1706 * @bssid: The AP BSSID or %NULL if not specified (auto-select based on scan
1705 * results) 1707 * results)
1708 * @bssid_hint: The recommended AP BSSID for initial connection to the BSS or
1709 * %NULL if not specified. Unlike the @bssid parameter, the driver is
1710 * allowed to ignore this @bssid_hint if it has knowledge of a better BSS
1711 * to use.
1706 * @ssid: SSID 1712 * @ssid: SSID
1707 * @ssid_len: Length of ssid in octets 1713 * @ssid_len: Length of ssid in octets
1708 * @auth_type: Authentication type (algorithm) 1714 * @auth_type: Authentication type (algorithm)
@@ -1725,7 +1731,9 @@ struct cfg80211_ibss_params {
1725 */ 1731 */
1726struct cfg80211_connect_params { 1732struct cfg80211_connect_params {
1727 struct ieee80211_channel *channel; 1733 struct ieee80211_channel *channel;
1734 struct ieee80211_channel *channel_hint;
1728 u8 *bssid; 1735 u8 *bssid;
1736 const u8 *bssid_hint;
1729 u8 *ssid; 1737 u8 *ssid;
1730 size_t ssid_len; 1738 size_t ssid_len;
1731 enum nl80211_auth_type auth_type; 1739 enum nl80211_auth_type auth_type;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 91054fd660e0..e57de3318068 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -418,8 +418,18 @@
418 * %NL80211_ATTR_SSID attribute, and can optionally specify the association 418 * %NL80211_ATTR_SSID attribute, and can optionally specify the association
419 * IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_USE_MFP, 419 * IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_USE_MFP,
420 * %NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, 420 * %NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT,
421 * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and 421 * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
422 * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT. 422 * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, %NL80211_ATTR_MAC_HINT, and
423 * %NL80211_ATTR_WIPHY_FREQ_HINT.
424 * If included, %NL80211_ATTR_MAC and %NL80211_ATTR_WIPHY_FREQ are
425 * restrictions on BSS selection, i.e., they effectively prevent roaming
426 * within the ESS. %NL80211_ATTR_MAC_HINT and %NL80211_ATTR_WIPHY_FREQ_HINT
427 * can be included to provide a recommendation of the initial BSS while
428 * allowing the driver to roam to other BSSes within the ESS and also to
429 * ignore this recommendation if the indicated BSS is not ideal. Only one
430 * set of BSSID,frequency parameters is used (i.e., either the enforcing
431 * %NL80211_ATTR_MAC,%NL80211_ATTR_WIPHY_FREQ or the less strict
432 * %NL80211_ATTR_MAC_HINT and %NL80211_ATTR_WIPHY_FREQ_HINT).
423 * Background scan period can optionally be 433 * Background scan period can optionally be
424 * specified in %NL80211_ATTR_BG_SCAN_PERIOD, 434 * specified in %NL80211_ATTR_BG_SCAN_PERIOD,
425 * if not specified default background scan configuration 435 * if not specified default background scan configuration
@@ -1555,6 +1565,9 @@ enum nl80211_commands {
1555 * data is in the format defined for the payload of the QoS Map Set element 1565 * data is in the format defined for the payload of the QoS Map Set element
1556 * in IEEE Std 802.11-2012, 8.4.2.97. 1566 * in IEEE Std 802.11-2012, 8.4.2.97.
1557 * 1567 *
1568 * @NL80211_ATTR_MAC_HINT: MAC address recommendation as initial BSS
1569 * @NL80211_ATTR_WIPHY_FREQ_HINT: frequency of the recommended initial BSS
1570 *
1558 * @NL80211_ATTR_MAX: highest attribute number currently defined 1571 * @NL80211_ATTR_MAX: highest attribute number currently defined
1559 * @__NL80211_ATTR_AFTER_LAST: internal use 1572 * @__NL80211_ATTR_AFTER_LAST: internal use
1560 */ 1573 */
@@ -1883,6 +1896,9 @@ enum nl80211_attrs {
1883 1896
1884 NL80211_ATTR_QOS_MAP, 1897 NL80211_ATTR_QOS_MAP,
1885 1898
1899 NL80211_ATTR_MAC_HINT,
1900 NL80211_ATTR_WIPHY_FREQ_HINT,
1901
1886 /* add attributes here, update the policy in nl80211.c */ 1902 /* add attributes here, update the policy in nl80211.c */
1887 1903
1888 __NL80211_ATTR_AFTER_LAST, 1904 __NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 7a742594916e..6e7d580ec645 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -382,6 +382,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
382 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY }, 382 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
383 [NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY, 383 [NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY,
384 .len = IEEE80211_QOS_MAP_LEN_MAX }, 384 .len = IEEE80211_QOS_MAP_LEN_MAX },
385 [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN },
386 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
385}; 387};
386 388
387/* policy for the key attributes */ 389/* policy for the key attributes */
@@ -6984,6 +6986,9 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
6984 6986
6985 if (info->attrs[NL80211_ATTR_MAC]) 6987 if (info->attrs[NL80211_ATTR_MAC])
6986 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 6988 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
6989 else if (info->attrs[NL80211_ATTR_MAC_HINT])
6990 connect.bssid_hint =
6991 nla_data(info->attrs[NL80211_ATTR_MAC_HINT]);
6987 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); 6992 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
6988 connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); 6993 connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
6989 6994
@@ -7008,6 +7013,14 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
7008 if (!connect.channel || 7013 if (!connect.channel ||
7009 connect.channel->flags & IEEE80211_CHAN_DISABLED) 7014 connect.channel->flags & IEEE80211_CHAN_DISABLED)
7010 return -EINVAL; 7015 return -EINVAL;
7016 } else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) {
7017 connect.channel_hint =
7018 ieee80211_get_channel(wiphy,
7019 nla_get_u32(
7020 info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]));
7021 if (!connect.channel_hint ||
7022 connect.channel_hint->flags & IEEE80211_CHAN_DISABLED)
7023 return -EINVAL;
7011 } 7024 }
7012 7025
7013 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) { 7026 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {