[PATCH v2 3/7] wifi: add support for FILS



The FILS(Fast Initial Link Setup) is a specification defined by IEEE 802.11ai to
speed up roaming. This patch adds support of it.

I have tested with these cases.
+-----+-------------------------+----------------+
| STA |            AP           |                |
|FILS |         key-mgmt        |     result     |
+-----+-------------------------+----------------+
|  1  | WPA-EAP                 |       O        |
+-----+-------------------------+----------------+
|  1  | WPA-EAP-SHA256          |       O        |
+-----+-------------------------+----------------+
|  1  | FILS-SHA256             |       X        |
+-----+-------------------------+----------------+
|  1  | FILS-SHA384             |       X        |
+-----+-------------------------+----------------+
|  1  | WPA-EAP WPA-EAP-SHA256  |       O        |
|     | FILS-SHA256 FILS-SHA384 | WPA-EAP-SHA256 |
+-----+-------------------------+----------------+
|  2  | WPA-EAP                 |       O        |
+-----+-------------------------+----------------+
|  2  | WPA-EAP-SHA256          |       O        |
+-----+-------------------------+----------------+
|  2  | FILS-SHA256             |       O        |
+-----+-------------------------+----------------+
|  2  | FILS-SHA384             |       O        |
+-----+-------------------------+----------------+
|  2  | WPA-EAP WPA-EAP-SHA256  |       O        |
|     | FILS-SHA256 FILS-SHA384 | FILS-SHA384    |
+-----+-------------------------+----------------+
|  3  | WPA-EAP                 |       X        |
+-----+-------------------------+----------------+
|  3  | WPA-EAP-SHA256          |       X        |
+-----+-------------------------+----------------+
|  3  | FILS-SHA256             |       O        |
+-----+-------------------------+----------------+
|  3  | FILS-SHA384             |       O        |
+-----+-------------------------+----------------+
|  3  | WPA-EAP WPA-EAP-SHA256  |       O        |
|     | FILS-SHA256 FILS-SHA384 | FILS-SHA384    |
+-----+-------------------------+----------------+

Signed-off-by: Masashi Honma <masashi honma gmail com>
---
 libnm-core/nm-setting-wireless-security.c          | 57 ++++++++++++++++++++++
 libnm-core/nm-setting-wireless-security.h          | 26 ++++++++++
 libnm/libnm.ver                                    |  2 +
 man/NetworkManager.conf.xml                        |  5 ++
 src/devices/wifi/nm-device-wifi.c                  | 18 +++++++
 src/devices/wifi/nm-wifi-ap.c                      |  4 +-
 .../plugins/ifcfg-rh/nms-ifcfg-rh-reader.c         |  7 +++
 .../plugins/ifcfg-rh/nms-ifcfg-rh-writer.c         |  7 +++
 src/supplicant/nm-supplicant-config.c              | 13 ++++-
 src/supplicant/nm-supplicant-config.h              |  1 +
 src/supplicant/nm-supplicant-settings-verify.c     |  1 +
 src/supplicant/tests/test-supplicant-config.c      |  2 +
 12 files changed, 141 insertions(+), 2 deletions(-)

diff --git a/libnm-core/nm-setting-wireless-security.c b/libnm-core/nm-setting-wireless-security.c
index de77a49..31e386f 100644
--- a/libnm-core/nm-setting-wireless-security.c
+++ b/libnm-core/nm-setting-wireless-security.c
@@ -87,6 +87,9 @@ typedef struct {
 
        /* WPS */
        NMSettingWirelessSecurityWpsMethod wps_method;
+
+       /* FILS */
+       NMSettingWirelessSecurityFils fils;
 } NMSettingWirelessSecurityPrivate;
 
 enum {
@@ -110,6 +113,7 @@ enum {
        PROP_LEAP_PASSWORD,
        PROP_LEAP_PASSWORD_FLAGS,
        PROP_WPS_METHOD,
+       PROP_FILS,
 
        LAST_PROP
 };
@@ -814,6 +818,22 @@ nm_setting_wireless_security_get_wps_method (NMSettingWirelessSecurity *setting)
        return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->wps_method;
 }
 
+/*
+ * nm_setting_wireless_security_get_fils:
+ * @setting: the #NMSettingWirelessSecurity
+ *
+ * Returns: the #NMSettingWirelessSecurity:fils property of the setting
+ *
+ * Since: 1.12
+ **/
+NMSettingWirelessSecurityFils
+nm_setting_wireless_security_get_fils (NMSettingWirelessSecurity *setting)
+{
+       g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), 0);
+
+       return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->fils;
+}
+
 static GPtrArray *
 need_secrets (NMSetting *setting)
 {
@@ -1327,6 +1347,9 @@ set_property (GObject *object, guint prop_id,
        case PROP_WPS_METHOD:
                priv->wps_method = g_value_get_uint (value);
                break;
+       case PROP_FILS:
+               priv->fils = g_value_get_int (value);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -1398,6 +1421,9 @@ get_property (GObject *object, guint prop_id,
        case PROP_WPS_METHOD:
                g_value_set_uint (value, priv->wps_method);
                break;
+       case PROP_FILS:
+               g_value_set_int (value, nm_setting_wireless_security_get_fils (setting));
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -1865,4 +1891,35 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting
                                    G_PARAM_CONSTRUCT |
                                    NM_SETTING_PARAM_FUZZY_IGNORE |
                                    G_PARAM_STATIC_STRINGS));
+
+       /**
+        * NMSettingWirelessSecurity:fils:
+        *
+        * Indicates whether Fast Initial Link Setup (802.11ai) must be enabled for
+        * the connection.  One of %NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT (use
+        * global default value), %NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE
+        * (disable FILS), %NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL (enable FILS
+        * if the supplicant and the access point support it) or
+        * %NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED (enable FILS and fail if not
+        * supported).  When set to %NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT and
+        * no global default is set, FILS will be optionally enabled.
+        *
+        * Since: 1.12
+        **/
+       /* ---ifcfg-rh---
+        * property: fils
+        * variable: FILS(+)
+        * values: default, disable, optional, required
+        * description: Enables or disables FILS (802.11ai)
+        * example: FILS=required
+        * ---end---
+        */
+       g_object_class_install_property
+               (object_class, PROP_FILS,
+                g_param_spec_int (NM_SETTING_WIRELESS_SECURITY_FILS, "", "",
+                                  G_MININT32, G_MAXINT32, 0,
+                                  G_PARAM_READWRITE |
+                                  G_PARAM_CONSTRUCT |
+                                  NM_SETTING_PARAM_FUZZY_IGNORE |
+                                  G_PARAM_STATIC_STRINGS));
 }
diff --git a/libnm-core/nm-setting-wireless-security.h b/libnm-core/nm-setting-wireless-security.h
index e7641b3..5a732ac 100644
--- a/libnm-core/nm-setting-wireless-security.h
+++ b/libnm-core/nm-setting-wireless-security.h
@@ -109,6 +109,28 @@ typedef enum {
        NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PIN         = 0x00000008,
 } NMSettingWirelessSecurityWpsMethod;
 
+/**
+ * NMSettingWirelessSecurityFils:
+ * @NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT: use the default value
+ * @NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE: disable FILS
+ * @NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL: enable FILS if the supplicant and the AP support it
+ * @NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED: require FILS and fail if not available
+ * @_NM_SETTING_WIRELESS_SECURITY_FILS_NUM: placeholder value for bounds-checking
+ * @NM_SETTING_WIRELESS_SECURITY_FILS_LAST: placeholder value for bounds-checking
+ *
+ * These flags indicate whether FILS must be enabled.
+ *
+ * Since: 1.12
+ **/
+typedef enum {
+       NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT       = 0,
+       NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE       = 1,
+       NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL      = 2,
+       NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED      = 3,
+       _NM_SETTING_WIRELESS_SECURITY_FILS_NUM, /*< skip >*/
+       NM_SETTING_WIRELESS_SECURITY_FILS_LAST          =  _NM_SETTING_WIRELESS_SECURITY_FILS_NUM - 1, /*< 
skip >*/
+} NMSettingWirelessSecurityFils;
+
 #define NM_SETTING_WIRELESS_SECURITY_KEY_MGMT "key-mgmt"
 #define NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX "wep-tx-keyidx"
 #define NM_SETTING_WIRELESS_SECURITY_AUTH_ALG "auth-alg"
@@ -128,6 +150,7 @@ typedef enum {
 #define NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD "leap-password"
 #define NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS "leap-password-flags"
 #define NM_SETTING_WIRELESS_SECURITY_WPS_METHOD "wps-method"
+#define NM_SETTING_WIRELESS_SECURITY_FILS "fils"
 
 /**
  * NMSettingWirelessSecurity:
@@ -193,6 +216,9 @@ NMWepKeyType nm_setting_wireless_security_get_wep_key_type (NMSettingWirelessSec
 NM_AVAILABLE_IN_1_10
 NMSettingWirelessSecurityWpsMethod nm_setting_wireless_security_get_wps_method (NMSettingWirelessSecurity 
*setting);
 
+NM_AVAILABLE_IN_1_12
+NMSettingWirelessSecurityFils nm_setting_wireless_security_get_fils (NMSettingWirelessSecurity *setting);
+
 G_END_DECLS
 
 #endif /* __NM_SETTING_WIRELESS_SECURITY_H__ */
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index 29dfba7..179a225 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -1352,4 +1352,6 @@ global:
        nm_setting_ip_tunnel_get_flags;
        nm_setting_vpn_get_data_keys;
        nm_setting_vpn_get_secret_keys;
+       nm_setting_wireless_security_get_fils;
+       nm_setting_wireless_security_fils_get_type;
 } libnm_1_10_0;
diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml
index 4171bfd..074ddc0 100644
--- a/man/NetworkManager.conf.xml
+++ b/man/NetworkManager.conf.xml
@@ -752,6 +752,11 @@ ipv6.ip6-privacy=0
           <listitem><para>If left unspecified, the default value
           "<literal>optional</literal>" will be used.</para></listitem>
         </varlistentry>
+        <varlistentry>
+          <term><varname>wifi-sec.fils</varname></term>
+          <listitem><para>If left unspecified, the default value
+          "<literal>optional</literal>" will be used.</para></listitem>
+        </varlistentry>
       </variablelist>
     </para>
     </refsect2>
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index f9441f8..e3593dc 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -2381,6 +2381,7 @@ build_supplicant_config (NMDeviceWifi *self,
        NMSettingWireless *s_wireless;
        NMSettingWirelessSecurity *s_wireless_sec;
        NMSettingWirelessSecurityPmf pmf;
+       NMSettingWirelessSecurityFils fils;
        gs_free char *value = NULL;
 
        g_return_val_if_fail (priv->sup_iface, NULL);
@@ -2450,6 +2451,22 @@ build_supplicant_config (NMDeviceWifi *self,
                        }
                }
 
+               /* Configure FILS (802.11ai) */
+               fils = nm_setting_wireless_security_get_fils (s_wireless_sec);
+               if (fils == NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT) {
+                       value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
+                                                                      "wifi-sec.fils",
+                                                                      NM_DEVICE (self));
+                       fils = _nm_utils_ascii_str_to_int64 (value, 10,
+                                                           NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE,
+                                                           NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED,
+                                                           NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL);
+               }
+
+               /* Don't try to enable FILS on non-EAP networks */
+               if (!NM_IN_STRSET (nm_setting_wireless_security_get_key_mgmt (s_wireless_sec),  "wpa-eap"))
+                       fils = NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE;
+
                s_8021x = nm_connection_get_setting_802_1x (connection);
                if (!nm_supplicant_config_add_setting_wireless_security (config,
                                                                         s_wireless_sec,
@@ -2457,6 +2474,7 @@ build_supplicant_config (NMDeviceWifi *self,
                                                                         con_uuid,
                                                                         mtu,
                                                                         pmf,
+                                                                        fils,
                                                                         error)) {
                        g_prefix_error (error, "802-11-wireless-security: ");
                        goto error;
diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c
index 603eb57..c3c64e7 100644
--- a/src/devices/wifi/nm-wifi-ap.c
+++ b/src/devices/wifi/nm-wifi-ap.c
@@ -415,7 +415,9 @@ security_from_vardict (GVariant *security)
            && array) {
                if (g_strv_contains (array, "wpa-psk"))
                        flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK;
-               if (g_strv_contains (array, "wpa-eap"))
+               if (g_strv_contains (array, "wpa-eap") ||
+                   g_strv_contains (array, "wpa-fils-sha256") ||
+                   g_strv_contains (array, "wpa-fils-sha384"))
                        flags |= NM_802_11_AP_SEC_KEY_MGMT_802_1X;
                g_free (array);
        }
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c 
b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
index 400a7bd..aed73c3 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
@@ -3542,6 +3542,13 @@ make_wpa_setting (shvarFile *ifcfg,
                return NULL;
        g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PMF, i_val, NULL);
 
+       i_val = NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT;
+       if (!svGetValueEnum (ifcfg, "FILS",
+                            nm_setting_wireless_security_fils_get_type (),
+                            &i_val, error))
+               return NULL;
+       g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_FILS, i_val, NULL);
+
        nm_clear_g_free (&value);
        v = svGetValueStr (ifcfg, "SECURITYMODE", &value);
        if (NM_IN_STRSET (v, NULL, "open"))
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c 
b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
index 32f056f..8fa4e5d 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
@@ -794,6 +794,13 @@ write_wireless_security_setting (NMConnection *connection,
                                nm_setting_wireless_security_get_pmf (s_wsec));
        }
 
+       if (nm_setting_wireless_security_get_fils (s_wsec) == NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT)
+               svUnsetValue (ifcfg, "FILS");
+       else {
+               svSetValueEnum (ifcfg, "FILS", nm_setting_wireless_security_fils_get_type (),
+                               nm_setting_wireless_security_get_fils (s_wsec));
+       }
+
        return TRUE;
 }
 
diff --git a/src/supplicant/nm-supplicant-config.c b/src/supplicant/nm-supplicant-config.c
index e51e8ba..a2502bd 100644
--- a/src/supplicant/nm-supplicant-config.c
+++ b/src/supplicant/nm-supplicant-config.c
@@ -733,6 +733,7 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
                                                     const char *con_uuid,
                                                     guint32 mtu,
                                                     NMSettingWirelessSecurityPmf pmf,
+                                                    NMSettingWirelessSecurityFils fils,
                                                     GError **error)
 {
        const char *key_mgmt, *key_mgmt_conf, *auth_alg;
@@ -747,7 +748,17 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
        if (nm_streq (key_mgmt, "wpa-psk"))
                key_mgmt_conf = "wpa-psk wpa-psk-sha256";
        else if (nm_streq (key_mgmt, "wpa-eap"))
-               key_mgmt_conf = "wpa-eap wpa-eap-sha256";
+               switch (fils) {
+               case NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL:
+                       key_mgmt_conf = "wpa-eap wpa-eap-sha256 fils-sha256 fils-sha384";
+                       break;
+               case NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED:
+                       key_mgmt_conf = "fils-sha256 fils-sha384";
+                       break;
+               default:
+                       key_mgmt_conf = "wpa-eap wpa-eap-sha256";
+                       break;
+               }
 
        if (!add_string_val (self, key_mgmt_conf, "key_mgmt", TRUE, NULL, error))
                return FALSE;
diff --git a/src/supplicant/nm-supplicant-config.h b/src/supplicant/nm-supplicant-config.h
index d90d82b..39b8a9f 100644
--- a/src/supplicant/nm-supplicant-config.h
+++ b/src/supplicant/nm-supplicant-config.h
@@ -65,6 +65,7 @@ gboolean nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig
                                                              const char *con_uuid,
                                                              guint32 mtu,
                                                              NMSettingWirelessSecurityPmf pmf,
+                                                             NMSettingWirelessSecurityFils fils,
                                                              GError **error);
 
 gboolean nm_supplicant_config_add_no_security (NMSupplicantConfig *self,
diff --git a/src/supplicant/nm-supplicant-settings-verify.c b/src/supplicant/nm-supplicant-settings-verify.c
index 14daf69..d53a13c 100644
--- a/src/supplicant/nm-supplicant-settings-verify.c
+++ b/src/supplicant/nm-supplicant-settings-verify.c
@@ -73,6 +73,7 @@ const char * group_allowed[] =    { "CCMP", "TKIP", "WEP104", "WEP40", NULL };
 const char * proto_allowed[] =    { "WPA", "RSN", NULL };
 const char * key_mgmt_allowed[] = { "WPA-PSK", "WPA-PSK-SHA256",
                                     "WPA-EAP", "WPA-EAP-SHA256",
+                                    "FILS-SHA256", "FILS-SHA384",
                                     "IEEE8021X", "WPA-NONE",
                                     "NONE", NULL };
 const char * auth_alg_allowed[] = { "OPEN", "SHARED", "LEAP", NULL };
diff --git a/src/supplicant/tests/test-supplicant-config.c b/src/supplicant/tests/test-supplicant-config.c
index f85c137..9420860 100644
--- a/src/supplicant/tests/test-supplicant-config.c
+++ b/src/supplicant/tests/test-supplicant-config.c
@@ -118,6 +118,7 @@ build_supplicant_config (NMConnection *connection, guint mtu, guint fixed_freq)
        s_wsec = nm_connection_get_setting_wireless_security (connection);
        if (s_wsec) {
                NMSettingWirelessSecurityPmf pmf = nm_setting_wireless_security_get_pmf (s_wsec);
+               NMSettingWirelessSecurityFils fils = nm_setting_wireless_security_get_fils (s_wsec);
                s_8021x = nm_connection_get_setting_802_1x (connection);
                success = nm_supplicant_config_add_setting_wireless_security (config,
                                                                                  s_wsec,
@@ -125,6 +126,7 @@ build_supplicant_config (NMConnection *connection, guint mtu, guint fixed_freq)
                                                                                  nm_connection_get_uuid 
(connection),
                                                                                  mtu,
                                                                                  pmf,
+                                                                                 fils,
                                                                                  &error);
        } else {
                success = nm_supplicant_config_add_no_security (config, &error);
-- 
2.7.4



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]