nl80211: Update ERP info using NL80211_CMD_UPDATE_CONNECT_PARAMS
authorVidyullatha Kanchanapally <vidyullatha@codeaurora.org>
Tue, 22 May 2018 08:19:08 +0000 (10:19 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 23 May 2018 09:21:35 +0000 (11:21 +0200)
Use NL80211_CMD_UPDATE_CONNECT_PARAMS to update new ERP information,
Association IEs and the Authentication type to driver / firmware which
will be used in subsequent roamings.

Signed-off-by: Vidyullatha Kanchanapally <vidyullatha@codeaurora.org>
[arend: extended fils-sk kernel doc and added check in wiphy_register()]
Reviewed-by: Jithu Jance <jithu.jance@broadcom.com>
Reviewed-by: Eylon Pedinovsky <eylon.pedinovsky@broadcom.com>
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/core.c
net/wireless/nl80211.c

index 1e7c0df4fe333a392c32bcd06b47594d04dd988e..5fbfe61f41c67f19713bf0e307ae0612428d68a6 100644 (file)
@@ -2225,9 +2225,14 @@ struct cfg80211_connect_params {
  * have to be updated as part of update_connect_params() call.
  *
  * @UPDATE_ASSOC_IES: Indicates whether association request IEs are updated
+ * @UPDATE_FILS_ERP_INFO: Indicates that FILS connection parameters (realm,
+ *     username, erp sequence number and rrk) are updated
+ * @UPDATE_AUTH_TYPE: Indicates that authentication type is updated
  */
 enum cfg80211_connect_params_changed {
        UPDATE_ASSOC_IES                = BIT(0),
+       UPDATE_FILS_ERP_INFO            = BIT(1),
+       UPDATE_AUTH_TYPE                = BIT(2),
 };
 
 /**
index 0a412335d56bf0c7475140e8c200ffb924e087e1..06f9af23156b4e19eb58cf616005acdb8b830d06 100644 (file)
  * FILS shared key authentication offload should be able to construct the
  * authentication and association frames for FILS shared key authentication and
  * eventually do a key derivation as per IEEE 802.11ai. The below additional
- * parameters should be given to driver in %NL80211_CMD_CONNECT.
+ * parameters should be given to driver in %NL80211_CMD_CONNECT and/or in
+ * %NL80211_CMD_UPDATE_CONNECT_PARAMS.
  *     %NL80211_ATTR_FILS_ERP_USERNAME - used to construct keyname_nai
  *     %NL80211_ATTR_FILS_ERP_REALM - used to construct keyname_nai
  *     %NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM - used to construct erp message
index c0fd8a85e7f72e59fa8e93be41a4dee1ee0a5104..5fe35aafdd9cf849d78d46f0f7d960356c804987 100644 (file)
@@ -725,6 +725,10 @@ int wiphy_register(struct wiphy *wiphy)
                    (!rdev->ops->set_pmk || !rdev->ops->del_pmk)))
                return -EINVAL;
 
+       if (WARN_ON(!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
+                   rdev->ops->update_connect_params))
+               return -EINVAL;
+
        if (wiphy->addresses)
                memcpy(wiphy->perm_addr, wiphy->addresses[0].addr, ETH_ALEN);
 
index ae57f9712d7d738318032febcfa419ab21d9fe12..bdf73b24cc09e82ed385e57d299b9170621a73d2 100644 (file)
@@ -9429,6 +9429,8 @@ static int nl80211_update_connect_params(struct sk_buff *skb,
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
        struct net_device *dev = info->user_ptr[1];
        struct wireless_dev *wdev = dev->ieee80211_ptr;
+       bool fils_sk_offload;
+       u32 auth_type;
        u32 changed = 0;
        int ret;
 
@@ -9443,6 +9445,56 @@ static int nl80211_update_connect_params(struct sk_buff *skb,
                changed |= UPDATE_ASSOC_IES;
        }
 
+       fils_sk_offload = wiphy_ext_feature_isset(&rdev->wiphy,
+                                                 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD);
+
+       /*
+        * when driver supports fils-sk offload all attributes must be
+        * provided. So the else covers "fils-sk-not-all" and
+        * "no-fils-sk-any".
+        */
+       if (fils_sk_offload &&
+           info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
+           info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
+           info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
+           info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
+               connect.fils_erp_username =
+                       nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
+               connect.fils_erp_username_len =
+                       nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
+               connect.fils_erp_realm =
+                       nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
+               connect.fils_erp_realm_len =
+                       nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
+               connect.fils_erp_next_seq_num =
+                       nla_get_u16(
+                          info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
+               connect.fils_erp_rrk =
+                       nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
+               connect.fils_erp_rrk_len =
+                       nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
+               changed |= UPDATE_FILS_ERP_INFO;
+       } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
+                  info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
+                  info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
+                  info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
+               return -EINVAL;
+       }
+
+       if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
+               auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
+               if (!nl80211_valid_auth_type(rdev, auth_type,
+                                            NL80211_CMD_CONNECT))
+                       return -EINVAL;
+
+               if (auth_type == NL80211_AUTHTYPE_FILS_SK &&
+                   fils_sk_offload && !(changed & UPDATE_FILS_ERP_INFO))
+                       return -EINVAL;
+
+               connect.auth_type = auth_type;
+               changed |= UPDATE_AUTH_TYPE;
+       }
+
        wdev_lock(dev->ieee80211_ptr);
        if (!wdev->current_bss)
                ret = -ENOLINK;