diff options
Diffstat (limited to 'src/devices/wifi')
| -rw-r--r-- | src/devices/wifi/nm-device-iwd.c | 32 | ||||
| -rw-r--r-- | src/devices/wifi/nm-device-iwd.h | 1 | ||||
| -rw-r--r-- | src/devices/wifi/nm-device-olpc-mesh.c | 2 | ||||
| -rw-r--r-- | src/devices/wifi/nm-device-olpc-mesh.h | 2 | ||||
| -rw-r--r-- | src/devices/wifi/nm-device-wifi-p2p.c | 1 | ||||
| -rw-r--r-- | src/devices/wifi/nm-device-wifi.c | 166 | ||||
| -rw-r--r-- | src/devices/wifi/nm-device-wifi.h | 1 | ||||
| -rw-r--r-- | src/devices/wifi/nm-iwd-manager.c | 20 | ||||
| -rw-r--r-- | src/devices/wifi/nm-iwd-manager.h | 1 | ||||
| -rw-r--r-- | src/devices/wifi/nm-wifi-ap.c | 19 | ||||
| -rw-r--r-- | src/devices/wifi/nm-wifi-ap.h | 1 | ||||
| -rw-r--r-- | src/devices/wifi/nm-wifi-common.c | 1 | ||||
| -rw-r--r-- | src/devices/wifi/nm-wifi-common.h | 1 | ||||
| -rw-r--r-- | src/devices/wifi/nm-wifi-factory.c | 1 | ||||
| -rw-r--r-- | src/devices/wifi/nm-wifi-utils.c | 55 | ||||
| -rw-r--r-- | src/devices/wifi/nm-wifi-utils.h | 2 | ||||
| -rw-r--r-- | src/devices/wifi/tests/meson.build | 6 | ||||
| -rw-r--r-- | src/devices/wifi/tests/test-devices-wifi.c (renamed from src/devices/wifi/tests/test-general.c) | 2 |
18 files changed, 204 insertions, 110 deletions
diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c index da7d0685..9cfe5f70 100644 --- a/src/devices/wifi/nm-device-iwd.c +++ b/src/devices/wifi/nm-device-iwd.c @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager -- Network link manager * * This program is free software; you can redistribute it and/or modify @@ -780,12 +779,10 @@ complete_connection (NMDevice *device, NMDeviceIwd *self = NM_DEVICE_IWD (device); NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); NMSettingWireless *s_wifi; - const char *setting_mac; gs_free char *ssid_utf8 = NULL; NMWifiAP *ap; GBytes *ssid; GBytes *setting_ssid = NULL; - const char *perm_hw_addr; const char *mode; s_wifi = nm_connection_get_setting_wireless (connection); @@ -875,36 +872,9 @@ complete_connection (NMDevice *device, ssid_utf8, ssid_utf8, NULL, + nm_setting_wireless_get_mac_address (s_wifi) ? NULL : nm_device_get_iface (device), TRUE); - perm_hw_addr = nm_device_get_permanent_hw_address (device); - if (perm_hw_addr) { - setting_mac = nm_setting_wireless_get_mac_address (s_wifi); - if (setting_mac) { - /* Make sure the setting MAC (if any) matches the device's permanent MAC */ - if (!nm_utils_hwaddr_matches (setting_mac, -1, perm_hw_addr, -1)) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - "connection does not match device"); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS); - return FALSE; - } - } else { - guint8 tmp[ETH_ALEN]; - - /* Lock the connection to this device by default if it uses a - * permanent MAC address (ie not a 'locally administered' one) - */ - nm_utils_hwaddr_aton (perm_hw_addr, tmp, ETH_ALEN); - if (!(tmp[0] & 0x02)) { - g_object_set (G_OBJECT (s_wifi), - NM_SETTING_WIRELESS_MAC_ADDRESS, perm_hw_addr, - NULL); - } - } - } - return TRUE; } diff --git a/src/devices/wifi/nm-device-iwd.h b/src/devices/wifi/nm-device-iwd.h index 4a2bd31e..aab45b7b 100644 --- a/src/devices/wifi/nm-device-iwd.h +++ b/src/devices/wifi/nm-device-iwd.h @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager -- Network link manager * * This program is free software; you can redistribute it and/or modify diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c index 1172a613..3c865c55 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.c +++ b/src/devices/wifi/nm-device-olpc-mesh.c @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager -- Network link manager * * Dan Williams <dcbw@redhat.com> @@ -133,6 +132,7 @@ complete_connection (NMDevice *device, NULL, _("Mesh"), NULL, + NULL, FALSE); /* No IPv6 by default */ return TRUE; diff --git a/src/devices/wifi/nm-device-olpc-mesh.h b/src/devices/wifi/nm-device-olpc-mesh.h index bf0e4da9..619fc46a 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.h +++ b/src/devices/wifi/nm-device-olpc-mesh.h @@ -1,5 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ - /* NetworkManager -- Network link manager * * Dan Williams <dcbw@redhat.com> diff --git a/src/devices/wifi/nm-device-wifi-p2p.c b/src/devices/wifi/nm-device-wifi-p2p.c index 8381ebc7..c5826e24 100644 --- a/src/devices/wifi/nm-device-wifi-p2p.c +++ b/src/devices/wifi/nm-device-wifi-p2p.c @@ -331,6 +331,7 @@ complete_connection (NMDevice *device, setting_name, setting_name, NULL, + NULL, TRUE); return TRUE; diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 3a58c620..2ffba47a 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager -- Network link manager * * This program is free software; you can redistribute it and/or modify @@ -545,6 +544,60 @@ wake_on_wlan_restore (NMDeviceWifi *self) } static void +disconnect_cb (NMSupplicantInterface *iface, GError *error, gpointer user_data) +{ + gs_unref_object NMDeviceWifi *self = NULL; + NMDeviceDeactivateCallback callback; + gpointer callback_user_data; + + nm_utils_user_data_unpack (user_data, &self, &callback, &callback_user_data); + + /* error will be freed by sup_iface */ + callback (NM_DEVICE (self), error, callback_user_data); +} + +static void +disconnect_cb_on_idle (gpointer user_data, + GCancellable *cancellable) +{ + gs_unref_object NMDeviceWifi *self = NULL; + NMDeviceDeactivateCallback callback; + gpointer callback_user_data; + gs_free_error GError *cancelled_error = NULL; + + nm_utils_user_data_unpack (user_data, &self, &callback, &callback_user_data); + + g_cancellable_set_error_if_cancelled (cancellable, &cancelled_error); + callback (NM_DEVICE (self), cancelled_error, callback_user_data); +} + +static void +deactivate_async (NMDevice *device, + GCancellable *cancellable, + NMDeviceDeactivateCallback callback, + gpointer callback_user_data) { + NMDeviceWifi *self = NM_DEVICE_WIFI (device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + gpointer user_data; + + nm_assert (G_IS_CANCELLABLE (cancellable)); + nm_assert (callback); + + user_data = nm_utils_user_data_pack (g_object_ref (self), callback, callback_user_data); + if (!priv->sup_iface) { + nm_utils_invoke_on_idle (disconnect_cb_on_idle, user_data, cancellable); + return; + } + + cleanup_association_attempt (self, FALSE); + + nm_supplicant_interface_disconnect_async (priv->sup_iface, + cancellable, + disconnect_cb, + user_data); +} + +static void deactivate (NMDevice *device) { NMDeviceWifi *self = NM_DEVICE_WIFI (device); @@ -695,6 +748,20 @@ check_connection_compatible (NMDevice *device, NMConnection *connection, GError return FALSE; } } + } else if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_MESH) == 0) { + if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_MESH)) { + nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "the device does not support Mesh mode"); + return FALSE; + } + + if (priv->sup_iface) { + if (nm_supplicant_interface_get_mesh_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_NO) { + nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "wpa_supplicant does not support Mesh mode"); + return FALSE; + } + } } // FIXME: check channel/freq/band against bands the hardware supports @@ -739,12 +806,13 @@ check_connection_available (NMDevice *device, return TRUE; } - /* Ad-Hoc and AP connections are always available because they may be + /* Ad-Hoc, AP and Mesh connections are always available because they may be * started at any time. */ mode = nm_setting_wireless_get_mode (s_wifi); if ( g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0 - || g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_AP) == 0) + || g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_AP) == 0 + || g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_MESH) == 0) return TRUE; /* Hidden SSIDs obviously don't always appear in the scan list either. @@ -778,13 +846,11 @@ complete_connection (NMDevice *device, NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMSettingWireless *s_wifi; - const char *setting_mac; gs_free char *ssid_utf8 = NULL; NMWifiAP *ap; GBytes *ssid = NULL; GBytes *setting_ssid = NULL; gboolean hidden = FALSE; - const char *perm_hw_addr; const char *mode; s_wifi = nm_connection_get_setting_wireless (connection); @@ -908,27 +974,12 @@ complete_connection (NMDevice *device, ssid_utf8, ssid_utf8, NULL, + nm_setting_wireless_get_mac_address (s_wifi) ? NULL : nm_device_get_iface (device), TRUE); if (hidden) g_object_set (s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); - perm_hw_addr = nm_device_get_permanent_hw_address (device); - if (perm_hw_addr) { - setting_mac = nm_setting_wireless_get_mac_address (s_wifi); - if (setting_mac) { - /* Make sure the setting MAC (if any) matches the device's permanent MAC */ - if (!nm_utils_hwaddr_matches (setting_mac, -1, perm_hw_addr, -1)) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("connection does not match device")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS); - return FALSE; - } - } - } - return TRUE; } @@ -972,7 +1023,8 @@ can_auto_connect (NMDevice *device, NMConnection *connection; NMSettingWireless *s_wifi; NMWifiAP *ap; - const char *method, *mode; + const char *method6, *mode; + gboolean auto4, auto6; guint64 timestamp = 0; nm_assert (!specific_object || !*specific_object); @@ -985,13 +1037,20 @@ can_auto_connect (NMDevice *device, s_wifi = nm_connection_get_setting_wireless (connection); g_return_val_if_fail (s_wifi, FALSE); - /* Always allow autoconnect for AP and non-autoconf Ad-Hoc */ - method = nm_utils_get_ip_config_method (connection, AF_INET); + /* Always allow autoconnect for AP and non-autoconf Ad-Hoc or Mesh */ + auto4 = nm_streq0 (nm_utils_get_ip_config_method (connection, AF_INET), + NM_SETTING_IP4_CONFIG_METHOD_AUTO); + method6 = nm_utils_get_ip_config_method (connection, AF_INET6); + auto6 = nm_streq0 (method6, NM_SETTING_IP6_CONFIG_METHOD_AUTO) + || nm_streq0 (method6, NM_SETTING_IP6_CONFIG_METHOD_DHCP); + mode = nm_setting_wireless_get_mode (s_wifi); + if (nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_AP)) return TRUE; - else if ( nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) - && !nm_streq0 (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) + else if (!auto4 && nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC)) + return TRUE; + else if (!auto4 && !auto6 && nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_MESH)) return TRUE; /* Don't autoconnect to networks that have been tried at least once @@ -1531,13 +1590,14 @@ try_fill_ssid_for_hidden_ap (NMDeviceWifi *self, NMSettingsConnection *sett_conn = connections[i]; NMSettingWireless *s_wifi; + if (!nm_settings_connection_has_seen_bssid (sett_conn, bssid)) + continue; s_wifi = nm_connection_get_setting_wireless (nm_settings_connection_get_connection (sett_conn)); - if (s_wifi) { - if (nm_settings_connection_has_seen_bssid (sett_conn, bssid)) { - nm_wifi_ap_set_ssid (ap, nm_setting_wireless_get_ssid (s_wifi)); - break; - } - } + if (!s_wifi) + continue; + + nm_wifi_ap_set_ssid (ap, nm_setting_wireless_get_ssid (s_wifi)); + break; } } @@ -1777,9 +1837,10 @@ supplicant_iface_wps_credentials_cb (NMSupplicantInterface *iface, } if (secrets) { if (nm_settings_connection_new_secrets (nm_act_request_get_settings_connection (req), - nm_act_request_get_applied_connection (req), - NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - secrets, &error)) { + nm_act_request_get_applied_connection (req), + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + secrets, + &error)) { wifi_secrets_cancel (self); nm_device_activate_schedule_stage1_device_prepare (NM_DEVICE (self)); } else { @@ -2398,6 +2459,7 @@ supplicant_connection_timeout_cb (gpointer user_data) g_assert (connection); if ( priv->mode == NM_802_11_MODE_ADHOC + || priv->mode == NM_802_11_MODE_MESH || priv->mode == NM_802_11_MODE_AP) { /* In Ad-Hoc and AP modes there's nothing to check the encryption key * (if any), so supplicant timeouts here are almost certainly the wifi @@ -2468,7 +2530,9 @@ build_supplicant_config (NMDeviceWifi *self, config = nm_supplicant_config_new ( nm_supplicant_interface_get_pmf_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_YES, - nm_supplicant_interface_get_fils_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_YES); + nm_supplicant_interface_get_fils_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_YES, + nm_supplicant_interface_get_ft_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_YES, + nm_supplicant_interface_get_sha384_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_YES); /* Warn if AP mode may not be supported */ if ( g_strcmp0 (nm_setting_wireless_get_mode (s_wireless), NM_SETTING_WIRELESS_MODE_AP) == 0 @@ -2635,7 +2699,8 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) /* Scanning not done in AP mode; clear the scan list */ remove_all_aps (self); - } + } else if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_MESH) == 0) + priv->mode = NM_802_11_MODE_MESH; _notify (self, PROP_MODE); /* The kernel doesn't support Ad-Hoc WPA connections well at this time, @@ -2655,8 +2720,8 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) if (!nm_device_hw_addr_set_cloned (device, connection, TRUE)) return NM_ACT_STAGE_RETURN_FAILURE; - /* AP mode never uses a specific object or existing scanned AP */ - if (priv->mode != NM_802_11_MODE_AP) { + /* AP and Mesh modes never use a specific object or existing scanned AP */ + if (priv->mode != NM_802_11_MODE_AP && priv->mode != NM_802_11_MODE_MESH) { ap_path = nm_active_connection_get_specific_object (NM_ACTIVE_CONNECTION (req)); ap = ap_path ? nm_wifi_ap_lookup_for_device (NM_DEVICE (self), ap_path) : NULL; if (ap) @@ -2672,10 +2737,10 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) } /* If the user is trying to connect to an AP that NM doesn't yet know about - * (hidden network or something) or starting a Hotspot, create an fake AP - * from the security settings in the connection. This "fake" AP gets used - * until the real one is found in the scan list (Ad-Hoc or Hidden), or until - * the device is deactivated (Hotspot). + * (hidden network or something), starting a Hotspot or joining a Mesh, + * create a fake APfrom the security settings in the connection. This "fake" + * AP gets used until the real one is found in the scan list (Ad-Hoc or Hidden), + * or until the device is deactivated (Hotspot). */ ap = nm_wifi_ap_new_fake_from_connection (connection); g_return_val_if_fail (ap != NULL, NM_ACT_STAGE_RETURN_FAILURE); @@ -2763,6 +2828,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMSupplicantConfig *config = NULL; + NM80211Mode ap_mode; NMActRequest *req; NMWifiAP *ap; NMConnection *connection; @@ -2783,6 +2849,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); goto out; } + ap_mode = nm_wifi_ap_get_mode (ap); connection = nm_act_request_get_applied_connection (req); g_assert (connection); @@ -2822,14 +2889,16 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) priv->ssid_found = FALSE; - /* Supplicant requires an initial frequency for Ad-Hoc and Hotspot; if the user - * didn't specify one and we didn't find an AP that matched the connection, - * just pick a frequency the device supports. + /* Supplicant requires an initial frequency for Ad-Hoc, Hotspot and Mesh; + * if the user didn't specify one and we didn't find an AP that matched + * the connection, just pick a frequency the device supports. */ - if ((nm_wifi_ap_get_mode (ap) == NM_802_11_MODE_ADHOC) || nm_wifi_ap_is_hotspot (ap)) + if ( ap_mode == NM_802_11_MODE_ADHOC + || ap_mode == NM_802_11_MODE_MESH + || nm_wifi_ap_is_hotspot (ap)) ensure_hotspot_frequency (self, s_wireless, ap); - if (nm_wifi_ap_get_mode (ap) == NM_802_11_MODE_INFRA) + if (ap_mode == NM_802_11_MODE_INFRA) set_powersave (device); /* Build up the supplicant configuration */ @@ -3386,6 +3455,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) device_class->get_configured_mtu = get_configured_mtu; device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; device_class->act_stage4_ip_config_timeout = act_stage4_ip_config_timeout; + device_class->deactivate_async = deactivate_async; device_class->deactivate = deactivate; device_class->deactivate_reset_hw_addr = deactivate_reset_hw_addr; device_class->unmanaged_on_quit = unmanaged_on_quit; diff --git a/src/devices/wifi/nm-device-wifi.h b/src/devices/wifi/nm-device-wifi.h index 116ad11e..82f62be6 100644 --- a/src/devices/wifi/nm-device-wifi.h +++ b/src/devices/wifi/nm-device-wifi.h @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager -- Network link manager * * This program is free software; you can redistribute it and/or modify diff --git a/src/devices/wifi/nm-iwd-manager.c b/src/devices/wifi/nm-iwd-manager.c index 494fca32..5b550ea4 100644 --- a/src/devices/wifi/nm-iwd-manager.c +++ b/src/devices/wifi/nm-iwd-manager.c @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager -- Network link manager * * This program is free software; you can redistribute it and/or modify @@ -437,7 +436,6 @@ mirror_8021x_connection (NMIwdManager *self, NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_CONNECTION_ID, name, NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_buf (uuid), - NM_SETTING_CONNECTION_READ_ONLY, TRUE, NULL)); nm_connection_add_setting (connection, setting); @@ -470,19 +468,19 @@ mirror_8021x_connection (NMIwdManager *self, if (!nm_connection_normalize (connection, NULL, NULL, NULL)) return NULL; - settings_connection = nm_settings_add_connection (priv->settings, connection, - FALSE, &error); - if (!settings_connection) { + if (!nm_settings_add_connection (priv->settings, + connection, + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY, + NM_SETTINGS_CONNECTION_ADD_REASON_NONE, + NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED, + &settings_connection, + &error)) { _LOGW ("failed to add a mirror NMConnection for IWD's Known Network '%s': %s", name, error->message); g_error_free (error); return NULL; } - nm_settings_connection_set_flags (settings_connection, - NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED | - NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED, - TRUE); return settings_connection; } @@ -499,7 +497,7 @@ mirror_8021x_connection_take_and_delete (NMSettingsConnection *sett_conn) /* If connection has not been saved since we created it * in interface_added it too can be removed now. */ if (NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) - nm_settings_connection_delete (sett_conn, NULL); + nm_settings_connection_delete (sett_conn, FALSE); g_object_unref (sett_conn); } @@ -900,7 +898,7 @@ nm_iwd_manager_init (NMIwdManager *self) g_signal_connect (priv->manager, NM_MANAGER_DEVICE_ADDED, G_CALLBACK (device_added), self); - priv->settings = g_object_ref (nm_settings_get ()); + priv->settings = g_object_ref (NM_SETTINGS_GET); g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, G_CALLBACK (connection_removed), self); diff --git a/src/devices/wifi/nm-iwd-manager.h b/src/devices/wifi/nm-iwd-manager.h index 57b7007a..b410e4ce 100644 --- a/src/devices/wifi/nm-iwd-manager.h +++ b/src/devices/wifi/nm-iwd-manager.h @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager -- Network link manager * * This program is free software; you can redistribute it and/or modify diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index 87daff59..c7ab7f04 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager -- Network link manager * * This program is free software; you can redistribute it and/or modify @@ -260,7 +259,8 @@ nm_wifi_ap_set_mode (NMWifiAP *ap, const NM80211Mode mode) g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE); g_return_val_if_fail ( mode == NM_802_11_MODE_ADHOC - || mode == NM_802_11_MODE_INFRA, FALSE); + || mode == NM_802_11_MODE_INFRA + || mode == NM_802_11_MODE_MESH, FALSE); priv = NM_WIFI_AP_GET_PRIVATE (ap); @@ -418,9 +418,11 @@ security_from_vardict (GVariant *security) if ( g_variant_lookup (security, "KeyMgmt", "^a&s", &array) && array) { - if (g_strv_contains (array, "wpa-psk")) + if (g_strv_contains (array, "wpa-psk") || + g_strv_contains (array, "wpa-ft-psk")) flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK; if (g_strv_contains (array, "wpa-eap") || + g_strv_contains (array, "wpa-ft-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; @@ -815,6 +817,8 @@ nm_wifi_ap_update_from_properties (NMWifiAP *ap, changed |= nm_wifi_ap_set_mode (ap, NM_802_11_MODE_INFRA); else if (!g_strcmp0 (s, "ad-hoc")) changed |= nm_wifi_ap_set_mode (ap, NM_802_11_MODE_ADHOC); + else if (!g_strcmp0 (s, "mesh")) + changed |= nm_wifi_ap_set_mode (ap, NM_802_11_MODE_MESH); } if (g_variant_lookup (properties, "Signal", "n", &i16)) @@ -1007,7 +1011,9 @@ nm_wifi_ap_to_string (const NMWifiAP *self, ? '#' : (priv->fake ? 'f' - : 'a'))), + : (priv->mode == NM_802_11_MODE_MESH + ? 'm' + : 'a')))), chan, priv->strength, priv->flags & NM_802_11_AP_FLAGS_PRIVACY ? 'P' : '_', @@ -1072,6 +1078,8 @@ nm_wifi_ap_check_compatible (NMWifiAP *self, if ( !strcmp (mode, "ap") && (priv->mode != NM_802_11_MODE_INFRA || priv->hotspot != TRUE)) return FALSE; + if (!strcmp (mode, "mesh") && (priv->mode != NM_802_11_MODE_MESH)) + return FALSE; } band = nm_setting_wireless_get_band (s_wireless); @@ -1115,6 +1123,7 @@ nm_wifi_ap_complete_connection (NMWifiAP *self, return nm_wifi_utils_complete_connection (priv->ssid, priv->address, priv->mode, + priv->freq, priv->flags, priv->wpa_flags, priv->rsn_flags, @@ -1245,6 +1254,8 @@ nm_wifi_ap_new_fake_from_connection (NMConnection *connection) nm_wifi_ap_set_mode (ap, NM_802_11_MODE_INFRA); else if (!strcmp (mode, "adhoc")) nm_wifi_ap_set_mode (ap, NM_802_11_MODE_ADHOC); + else if (!strcmp (mode, "mesh")) + nm_wifi_ap_set_mode (ap, NM_802_11_MODE_MESH); else if (!strcmp (mode, "ap")) { nm_wifi_ap_set_mode (ap, NM_802_11_MODE_INFRA); NM_WIFI_AP_GET_PRIVATE (ap)->hotspot = TRUE; diff --git a/src/devices/wifi/nm-wifi-ap.h b/src/devices/wifi/nm-wifi-ap.h index 7462e9d1..755e722c 100644 --- a/src/devices/wifi/nm-wifi-ap.h +++ b/src/devices/wifi/nm-wifi-ap.h @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager -- Network link manager * * This program is free software; you can redistribute it and/or modify diff --git a/src/devices/wifi/nm-wifi-common.c b/src/devices/wifi/nm-wifi-common.c index c95620e7..96828d59 100644 --- a/src/devices/wifi/nm-wifi-common.c +++ b/src/devices/wifi/nm-wifi-common.c @@ -1,4 +1,3 @@ -/*-*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/devices/wifi/nm-wifi-common.h b/src/devices/wifi/nm-wifi-common.h index 91cbeb55..81d657ec 100644 --- a/src/devices/wifi/nm-wifi-common.h +++ b/src/devices/wifi/nm-wifi-common.h @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/devices/wifi/nm-wifi-factory.c b/src/devices/wifi/nm-wifi-factory.c index 9a89bbe9..2f069882 100644 --- a/src/devices/wifi/nm-wifi-factory.c +++ b/src/devices/wifi/nm-wifi-factory.c @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager -- Network link manager * * This program is free software; you can redistribute it and/or modify diff --git a/src/devices/wifi/nm-wifi-utils.c b/src/devices/wifi/nm-wifi-utils.c index c6e8b3e0..426eeea8 100644 --- a/src/devices/wifi/nm-wifi-utils.c +++ b/src/devices/wifi/nm-wifi-utils.c @@ -1,4 +1,3 @@ -/*-*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,6 +24,7 @@ #include <stdlib.h> #include "nm-utils.h" +#include "nm-core-internal.h" static gboolean verify_no_wep (NMSettingWirelessSecurity *s_wsec, const char *tag, GError **error) @@ -527,6 +527,7 @@ gboolean nm_wifi_utils_complete_connection (GBytes *ap_ssid, const char *bssid, NM80211Mode ap_mode, + guint32 ap_freq, guint32 ap_flags, guint32 ap_wpa_flags, guint32 ap_rsn_flags, @@ -540,6 +541,7 @@ nm_wifi_utils_complete_connection (GBytes *ap_ssid, GBytes *ssid; const char *mode, *key_mgmt, *auth_alg, *leap_username; gboolean adhoc = FALSE; + gboolean mesh = FALSE; s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); @@ -576,6 +578,10 @@ nm_wifi_utils_complete_connection (GBytes *ap_ssid, if (ap_mode == NM_802_11_MODE_ADHOC) valid = TRUE; adhoc = TRUE; + } else if (!strcmp (mode, NM_SETTING_WIRELESS_MODE_MESH)) { + if (ap_mode == NM_802_11_MODE_MESH) + valid = TRUE; + mesh = TRUE; } if (valid == FALSE) { @@ -591,10 +597,57 @@ nm_wifi_utils_complete_connection (GBytes *ap_ssid, if (ap_mode == NM_802_11_MODE_ADHOC) { mode = NM_SETTING_WIRELESS_MODE_ADHOC; adhoc = TRUE; + } else if (ap_mode == NM_802_11_MODE_MESH) { + mode = NM_SETTING_WIRELESS_MODE_MESH; + mesh = TRUE; } g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MODE, mode, NULL); } + /* For now mesh requires channel and band, fill them only if both not present. + * Do not check existing values against an existing ap/mesh point, + * mesh join will start a new network if required */ + if (mesh) { + const char *band; + guint32 channel; + gboolean band_valid = TRUE; + gboolean chan_valid = TRUE; + gboolean valid; + + band = nm_setting_wireless_get_band (s_wifi); + channel = nm_setting_wireless_get_channel (s_wifi); + + valid = ((band == NULL) && (channel == 0)) + || ((band != NULL) && (channel != 0)); + + if ((band == NULL) && (channel == 0)) { + channel = nm_utils_wifi_freq_to_channel (ap_freq); + if (channel) { + g_object_set (s_wifi, + NM_SETTING_WIRELESS_CHANNEL, channel, + NULL); + } else { + chan_valid = FALSE; + } + + band = nm_utils_wifi_freq_to_band (ap_freq); + if (band) { + g_object_set (s_wifi, NM_SETTING_WIRELESS_BAND, band, NULL); + } else { + band_valid = FALSE; + } + } + + if (!valid || !chan_valid || !band_valid) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match mesh point")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MODE); + return FALSE; + } + } + /* Security */ /* Open */ diff --git a/src/devices/wifi/nm-wifi-utils.h b/src/devices/wifi/nm-wifi-utils.h index 03238c24..251d122f 100644 --- a/src/devices/wifi/nm-wifi-utils.h +++ b/src/devices/wifi/nm-wifi-utils.h @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,6 +36,7 @@ typedef enum { gboolean nm_wifi_utils_complete_connection (GBytes *ssid, const char *bssid, NM80211Mode mode, + guint32 ap_freq, guint32 flags, guint32 wpa_flags, guint32 rsn_flags, diff --git a/src/devices/wifi/tests/meson.build b/src/devices/wifi/tests/meson.build index 895853c4..ba756d53 100644 --- a/src/devices/wifi/tests/meson.build +++ b/src/devices/wifi/tests/meson.build @@ -1,13 +1,13 @@ -test_unit = 'test-general' +test_unit = 'test-devices-wifi' exe = executable( - 'wifi-' + test_unit, + test_unit, [test_unit + '.c'] + common_sources, dependencies: test_nm_dep, ) test( - 'devices/wifi/' + test_unit, + test_unit, test_script, args: test_args + [exe.full_path()], timeout: default_test_timeout, diff --git a/src/devices/wifi/tests/test-general.c b/src/devices/wifi/tests/test-devices-wifi.c index e0899837..a0b3e17f 100644 --- a/src/devices/wifi/tests/test-general.c +++ b/src/devices/wifi/tests/test-devices-wifi.c @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -86,6 +85,7 @@ complete_connection (const char *ssid, return nm_wifi_utils_complete_connection (ssid_b, bssid, mode, + 0, flags, wpa_flags, rsn_flags, |