diff --git a/NEWS b/NEWS index a51d0cdf6..abda0292a 100644 --- a/NEWS +++ b/NEWS @@ -47,6 +47,7 @@ USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE! properties take effect immediately. The "no-reapply" flag allows suppressing this, so that not changes take effect automatically. The purpose is to really only modify the profile itself without changes to the runtime configuration of the device. +* Added support for Wi-Fi Mesh network. The following changes were backported to 1.18.x releases between 1.18.0 and 1.18.2 are also present in NetworkManager-1.18: diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index d0a8d7823..ef4d443cb 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -748,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 @@ -2436,6 +2450,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 @@ -2675,7 +2690,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, @@ -2695,8 +2711,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) @@ -2712,10 +2728,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); @@ -2803,6 +2819,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; @@ -2823,6 +2840,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); @@ -2862,14 +2880,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 */ diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index 8d60bee34..b94421a63 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -259,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); @@ -1246,6 +1247,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;