diff options
author | Andrew Zaborowski <andrew.zaborowski@intel.com> | 2021-11-09 03:02:09 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2022-01-21 11:16:24 +0100 |
commit | 4822d1a1d1a0d42445e27b9b605235c875f6a7cc (patch) | |
tree | fc932d5ad9bbb9b47e2b5c78b10b5e3ea03eebac | |
parent | 524675db75c0edcff25932e038fe215d8f03868d (diff) |
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.
-rw-r--r-- | src/core/devices/wifi/nm-device-iwd-p2p.c | 10 | ||||
-rw-r--r-- | src/core/devices/wifi/nm-device-wifi-p2p.c | 9 | ||||
-rw-r--r-- | src/core/devices/wifi/nm-wifi-p2p-peer.c | 12 | ||||
-rw-r--r-- | src/core/devices/wifi/nm-wifi-p2p-peer.h | 7 |
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); |