devices/wifi: support Mesh mode

This puts together the bits from previous commits and actually allows
for activating a mode=mesh connection.
This commit is contained in:
Lubomir Rintel
2019-01-24 15:33:26 +01:00
parent f1ab27a297
commit 5874f4e4e9
3 changed files with 37 additions and 13 deletions

1
NEWS
View File

@@ -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, 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 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. 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 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: and 1.18.2 are also present in NetworkManager-1.18:

View File

@@ -748,6 +748,20 @@ check_connection_compatible (NMDevice *device, NMConnection *connection, GError
return FALSE; 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 // FIXME: check channel/freq/band against bands the hardware supports
@@ -2436,6 +2450,7 @@ supplicant_connection_timeout_cb (gpointer user_data)
g_assert (connection); g_assert (connection);
if ( priv->mode == NM_802_11_MODE_ADHOC if ( priv->mode == NM_802_11_MODE_ADHOC
|| priv->mode == NM_802_11_MODE_MESH
|| priv->mode == NM_802_11_MODE_AP) { || priv->mode == NM_802_11_MODE_AP) {
/* In Ad-Hoc and AP modes there's nothing to check the encryption key /* 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 * (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 */ /* Scanning not done in AP mode; clear the scan list */
remove_all_aps (self); 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); _notify (self, PROP_MODE);
/* The kernel doesn't support Ad-Hoc WPA connections well at this time, /* 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)) if (!nm_device_hw_addr_set_cloned (device, connection, TRUE))
return NM_ACT_STAGE_RETURN_FAILURE; return NM_ACT_STAGE_RETURN_FAILURE;
/* AP mode never uses a specific object or existing scanned AP */ /* AP and Mesh modes never use a specific object or existing scanned AP */
if (priv->mode != NM_802_11_MODE_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_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; ap = ap_path ? nm_wifi_ap_lookup_for_device (NM_DEVICE (self), ap_path) : NULL;
if (ap) 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 /* 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 * (hidden network or something), starting a Hotspot or joining a Mesh,
* from the security settings in the connection. This "fake" AP gets used * create a fake APfrom the security settings in the connection. This "fake"
* until the real one is found in the scan list (Ad-Hoc or Hidden), or until * AP gets used until the real one is found in the scan list (Ad-Hoc or Hidden),
* the device is deactivated (Hotspot). * or until the device is deactivated (Hotspot).
*/ */
ap = nm_wifi_ap_new_fake_from_connection (connection); ap = nm_wifi_ap_new_fake_from_connection (connection);
g_return_val_if_fail (ap != NULL, NM_ACT_STAGE_RETURN_FAILURE); 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); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
NMSupplicantConfig *config = NULL; NMSupplicantConfig *config = NULL;
NM80211Mode ap_mode;
NMActRequest *req; NMActRequest *req;
NMWifiAP *ap; NMWifiAP *ap;
NMConnection *connection; 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); NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
goto out; goto out;
} }
ap_mode = nm_wifi_ap_get_mode (ap);
connection = nm_act_request_get_applied_connection (req); connection = nm_act_request_get_applied_connection (req);
g_assert (connection); g_assert (connection);
@@ -2862,14 +2880,16 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
priv->ssid_found = FALSE; priv->ssid_found = FALSE;
/* Supplicant requires an initial frequency for Ad-Hoc and Hotspot; if the user /* Supplicant requires an initial frequency for Ad-Hoc, Hotspot and Mesh;
* didn't specify one and we didn't find an AP that matched the connection, * if the user didn't specify one and we didn't find an AP that matched
* just pick a frequency the device supports. * 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); 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); set_powersave (device);
/* Build up the supplicant configuration */ /* Build up the supplicant configuration */

View File

@@ -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 (NM_IS_WIFI_AP (ap), FALSE);
g_return_val_if_fail ( mode == NM_802_11_MODE_ADHOC 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); 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); nm_wifi_ap_set_mode (ap, NM_802_11_MODE_INFRA);
else if (!strcmp (mode, "adhoc")) else if (!strcmp (mode, "adhoc"))
nm_wifi_ap_set_mode (ap, NM_802_11_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")) { else if (!strcmp (mode, "ap")) {
nm_wifi_ap_set_mode (ap, NM_802_11_MODE_INFRA); nm_wifi_ap_set_mode (ap, NM_802_11_MODE_INFRA);
NM_WIFI_AP_GET_PRIVATE (ap)->hotspot = TRUE; NM_WIFI_AP_GET_PRIVATE (ap)->hotspot = TRUE;