summaryrefslogtreecommitdiff
path: root/src/core/devices
diff options
context:
space:
mode:
authorAndrew Zaborowski <andrew.zaborowski@intel.com>2021-11-09 03:02:09 +0100
committerThomas Haller <thaller@redhat.com>2022-01-21 11:16:24 +0100
commit4822d1a1d1a0d42445e27b9b605235c875f6a7cc (patch)
treefc932d5ad9bbb9b47e2b5c78b10b5e3ea03eebac /src/core/devices
parent524675db75c0edcff25932e038fe215d8f03868d (diff)
downloadNetworkManager-4822d1a1d1a0d42445e27b9b605235c875f6a7cc.tar.gz
iwd: Ensure WFD IE is present during activation
If the connection has wfd_ies set, we want to ensure that a WFD connection is being established so we want to check that the target peer also supports WFD. For now this in the IWD backend only. However, WFD peers will send us their WFD IEs in their Probe Responses only if our own Probe Request contained a WFD IE, or at least that's when the spec mandates that they include the WFD IE. This implies that the discovery phase (NM.Device.WifiP2P.StartFind(options) / .StopFind()) needs to know the value of the local WFD IE and include it in the Probe Requests, which existing clients (gnome-network-displays) doesn't do and in fact can't do because there's no API for the client to pass the WFD IE -- that is easy to add in the options parameter though (a dictionary). The current situation is that with the wpa_supplicant backend we'll sometimes see the WFD IE (when the peer is discovered from a Probe Request that it has sent, rather than from a Probe Response) and sometimes not, while with the IWD backend we'll never see the WFD information because IWD assumes that the client (NM) is not interested in seeing it if it hasn't registered the local WFD information before starting discovery. So, for compatibility with this existing situation and with the wpa_supplicant backend, ignore whether the peer is a WFD peer except in the PREPARE stage. In PREPARE, if we have a peer compatible with the connection being activated -- except for the WFD information -- force a new discovery, this time passing the WFD information from the NMSettingConnection's wfd_ies, and only progress to CONFIG if the target peer is re-discovered as a WFD peer within 10 seconds. We don't actually check the contents of the WFD IEs to match, e.g. we don't check the sink/source/dual role compatibility between our and the peer's properties, but IWD will do some of these checks later during activation.
Diffstat (limited to 'src/core/devices')
-rw-r--r--src/core/devices/wifi/nm-device-iwd-p2p.c10
-rw-r--r--src/core/devices/wifi/nm-device-wifi-p2p.c9
-rw-r--r--src/core/devices/wifi/nm-wifi-p2p-peer.c12
-rw-r--r--src/core/devices/wifi/nm-wifi-p2p-peer.h7
4 files changed, 24 insertions, 14 deletions
diff --git a/src/core/devices/wifi/nm-device-iwd-p2p.c b/src/core/devices/wifi/nm-device-iwd-p2p.c
index 2525db355f..01774b12f7 100644
--- a/src/core/devices/wifi/nm-device-iwd-p2p.c
+++ b/src/core/devices/wifi/nm-device-iwd-p2p.c
@@ -194,14 +194,14 @@ check_connection_available(NMDevice *device,
return FALSE;
}
- if (!nm_wifi_p2p_peer_check_compatible(peer, connection)) {
+ if (!nm_wifi_p2p_peer_check_compatible(peer, connection, FALSE)) {
nm_utils_error_set_literal(error,
NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
"Requested P2P peer is not compatible with profile");
return FALSE;
}
} else {
- peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, connection);
+ peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, connection, FALSE);
if (!peer) {
nm_utils_error_set_literal(error,
NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
@@ -596,7 +596,7 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
priv->wfd_registered = TRUE;
}
- peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, connection);
+ peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, connection, TRUE);
if (!peer) {
iwd_request_discovery(self, 10);
return NM_ACT_STAGE_RETURN_POSTPONE;
@@ -674,7 +674,7 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
NM_IS_SETTING_WIFI_P2P(nm_connection_get_setting(connection, NM_TYPE_SETTING_WIFI_P2P)));
/* The prepare stage ensures that the peer has been found */
- peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, connection);
+ peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, connection, TRUE);
if (!peer) {
cleanup_connect_attempt(self);
NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_PEER_NOT_FOUND);
@@ -742,7 +742,7 @@ act_check_new_peer_compatible(NMDeviceIwdP2P *self, NMWifiP2PPeer *peer)
connection = nm_device_get_applied_connection(device);
nm_assert(NM_IS_CONNECTION(connection));
- if (nm_wifi_p2p_peer_check_compatible(peer, connection)) {
+ if (nm_wifi_p2p_peer_check_compatible(peer, connection, TRUE)) {
/* A peer for the connection was found, cancel the timeout and go to configure state. */
iwd_release_discovery(self);
nm_device_activate_schedule_stage2_device_config(device, FALSE);
diff --git a/src/core/devices/wifi/nm-device-wifi-p2p.c b/src/core/devices/wifi/nm-device-wifi-p2p.c
index 4cb76e45e7..dfbf89785c 100644
--- a/src/core/devices/wifi/nm-device-wifi-p2p.c
+++ b/src/core/devices/wifi/nm-device-wifi-p2p.c
@@ -168,7 +168,7 @@ check_connection_peer_joined(NMDeviceWifiP2P *device)
return FALSE;
/* NOTE: We currently only support connections to a specific peer */
- peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, conn);
+ peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, conn, FALSE);
if (!peer)
return FALSE;
@@ -369,7 +369,7 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
NM_SETTING_WIFI_P2P(nm_connection_get_setting(connection, NM_TYPE_SETTING_WIFI_P2P));
g_return_val_if_fail(s_wifi_p2p, NM_ACT_STAGE_RETURN_FAILURE);
- peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, connection);
+ peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, connection, FALSE);
if (!peer) {
/* Set up a timeout on the find attempt and run a find for the same period of time */
if (priv->find_peer_timeout_id == 0) {
@@ -436,7 +436,7 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
NM_IS_SETTING_WIFI_P2P(nm_connection_get_setting(connection, NM_TYPE_SETTING_WIFI_P2P)));
/* The prepare stage ensures that the peer has been found */
- peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, connection);
+ peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, connection, FALSE);
if (!peer) {
NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_PEER_NOT_FOUND);
return NM_ACT_STAGE_RETURN_FAILURE;
@@ -521,7 +521,8 @@ peer_add_remove(NMDeviceWifiP2P *self,
connection = nm_device_get_applied_connection(device);
nm_assert(NM_IS_CONNECTION(connection));
- peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, connection);
+ peer =
+ nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, connection, FALSE);
if (peer) {
/* A peer for the connection was found, cancel the timeout and go to configure state. */
nm_clear_g_source(&priv->find_peer_timeout_id);
diff --git a/src/core/devices/wifi/nm-wifi-p2p-peer.c b/src/core/devices/wifi/nm-wifi-p2p-peer.c
index 5d2f7c5547..0a17427067 100644
--- a/src/core/devices/wifi/nm-wifi-p2p-peer.c
+++ b/src/core/devices/wifi/nm-wifi-p2p-peer.c
@@ -101,14 +101,16 @@ nm_wifi_p2p_peers_get_paths(const CList *peers_lst_head)
}
NMWifiP2PPeer *
-nm_wifi_p2p_peers_find_first_compatible(const CList *peers_lst_head, NMConnection *connection)
+nm_wifi_p2p_peers_find_first_compatible(const CList *peers_lst_head,
+ NMConnection *connection,
+ gboolean check_wfd)
{
NMWifiP2PPeer *peer;
g_return_val_if_fail(connection, NULL);
c_list_for_each_entry (peer, peers_lst_head, peers_lst) {
- if (nm_wifi_p2p_peer_check_compatible(peer, connection))
+ if (nm_wifi_p2p_peer_check_compatible(peer, connection, check_wfd))
return peer;
}
return NULL;
@@ -543,7 +545,7 @@ nm_wifi_p2p_peer_to_string(const NMWifiP2PPeer *self, char *str_buf, gsize buf_l
}
gboolean
-nm_wifi_p2p_peer_check_compatible(NMWifiP2PPeer *self, NMConnection *connection)
+nm_wifi_p2p_peer_check_compatible(NMWifiP2PPeer *self, NMConnection *connection, gboolean check_wfd)
{
NMWifiP2PPeerPrivate *priv;
NMSettingWifiP2P *s_wifi_p2p;
@@ -563,6 +565,10 @@ nm_wifi_p2p_peer_check_compatible(NMWifiP2PPeer *self, NMConnection *connection)
if (hwaddr && (!priv->address || !nm_utils_hwaddr_matches(hwaddr, -1, priv->address, -1)))
return FALSE;
+ if (check_wfd && nm_setting_wifi_p2p_get_wfd_ies(s_wifi_p2p)
+ && !nm_wifi_p2p_peer_get_wfd_ies(self))
+ return FALSE;
+
return TRUE;
}
diff --git a/src/core/devices/wifi/nm-wifi-p2p-peer.h b/src/core/devices/wifi/nm-wifi-p2p-peer.h
index f7ffbf385d..5124d1dea4 100644
--- a/src/core/devices/wifi/nm-wifi-p2p-peer.h
+++ b/src/core/devices/wifi/nm-wifi-p2p-peer.h
@@ -51,7 +51,9 @@ gboolean nm_wifi_p2p_peer_update_from_properties(NMWifiP2PPeer
const struct _NMSupplicantPeerInfo *peer_info);
gboolean nm_wifi_p2p_peer_update_from_iwd_object(NMWifiP2PPeer *peer, GDBusObject *obj);
-gboolean nm_wifi_p2p_peer_check_compatible(NMWifiP2PPeer *self, NMConnection *connection);
+gboolean nm_wifi_p2p_peer_check_compatible(NMWifiP2PPeer *self,
+ NMConnection *connection,
+ gboolean check_wfd);
const char *nm_wifi_p2p_peer_get_supplicant_path(NMWifiP2PPeer *peer);
@@ -83,7 +85,8 @@ nm_wifi_p2p_peer_to_string(const NMWifiP2PPeer *self, char *str_buf, gsize buf_l
const char **nm_wifi_p2p_peers_get_paths(const CList *peers_lst_head);
NMWifiP2PPeer *nm_wifi_p2p_peers_find_first_compatible(const CList *peers_lst_head,
- NMConnection *connection);
+ NMConnection *connection,
+ gboolean check_wfd);
NMWifiP2PPeer *nm_wifi_p2p_peers_find_by_supplicant_path(const CList *peers_lst_head,
const char *path);