summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2020-09-30 13:35:49 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2020-10-12 22:13:23 +0200
commit90bbc540b36a8c60d41be6fd41533d1ffd438e7b (patch)
treefaa67f7a7b815096d8000de10d62f381fe01a73b
parentdc54a946acb968c73f8d55e01c61efedb4ae6cc1 (diff)
downloadNetworkManager-bg/wifi-bridge.tar.gz
wifi: set the BridgeIfname supplicant property when neededbg/wifi-bridge
When a wifi device is in a bridge, the supplicant must be aware of it, as a socket must be opened on the bridge to receive packets. Set the BridgeIfname property of the supplicant Interface object before starting the association. Note that the property was read-only in the past and recently [1] became read-write. When using a supplicant version without the patch, writing the property will return an InvalidArgs error and NetworkManager will print a warning. [1] https://w1.fi/cgit/hostap/commit/?id=1c58317f56e312576b6872440f125f794e45f991 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/83
-rw-r--r--src/devices/wifi/nm-device-wifi.c12
-rw-r--r--src/supplicant/nm-supplicant-interface.c48
-rw-r--r--src/supplicant/nm-supplicant-interface.h2
3 files changed, 62 insertions, 0 deletions
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index 5506264479..7c749f1e3c 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -3136,6 +3136,9 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
NMSettingWireless * s_wireless;
GError * error = NULL;
guint timeout;
+ NMActRequest * request;
+ NMActiveConnection * master_ac;
+ NMDevice * master;
nm_clear_g_source(&priv->sup_timeout_id);
nm_clear_g_source(&priv->link_timeout_id);
@@ -3209,6 +3212,15 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
goto out_fail;
}
+ /* Tell the supplicant in which bridge the interface is */
+ if ((request = nm_device_get_act_request(device))
+ && (master_ac = nm_active_connection_get_master(NM_ACTIVE_CONNECTION(request)))
+ && (master = nm_active_connection_get_device(master_ac))
+ && nm_device_get_device_type(master) == NM_DEVICE_TYPE_BRIDGE) {
+ nm_supplicant_interface_set_bridge(priv->sup_iface, nm_device_get_iface(master));
+ } else
+ nm_supplicant_interface_set_bridge(priv->sup_iface, NULL);
+
nm_supplicant_interface_assoc(priv->sup_iface, config, supplicant_iface_assoc_cb, self);
/* Set up a timeout on the association attempt */
diff --git a/src/supplicant/nm-supplicant-interface.c b/src/supplicant/nm-supplicant-interface.c
index 77254c7ebc..5021f3f60b 100644
--- a/src/supplicant/nm-supplicant-interface.c
+++ b/src/supplicant/nm-supplicant-interface.c
@@ -1322,6 +1322,54 @@ nm_supplicant_interface_get_capabilities(NMSupplicantInterface *self)
return caps;
}
+static void
+set_bridge_cb(GVariant *ret, GError *error, gpointer user_data)
+{
+ NMSupplicantInterface *self;
+ NMLogLevel level;
+ gs_free const char * bridge = NULL;
+
+ nm_utils_user_data_unpack(user_data, &self, &bridge);
+
+ if (nm_utils_error_is_cancelled(error))
+ return;
+
+ /* The supplicant supports writing the bridge property since
+ * version 2.10. Before that version, trying to set the property
+ * results in a InvalidArgs error. Don't log a warning unless we
+ * are trying to set a non-NULL bridge. */
+ if (!error)
+ level = LOGL_DEBUG;
+ else if (bridge == NULL && g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS)) {
+ level = LOGL_DEBUG;
+ } else
+ level = LOGL_WARN;
+
+ _NMLOG(level,
+ "set bridge %s%s%s result: %s",
+ NM_PRINT_FMT_QUOTE_STRING(bridge),
+ error ? error->message : "success");
+}
+
+void
+nm_supplicant_interface_set_bridge(NMSupplicantInterface *self, const char *bridge)
+{
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE(self);
+
+ _LOGT("set bridge %s%s%s", NM_PRINT_FMT_QUOTE_STRING(bridge));
+
+ nm_dbus_connection_call_set(priv->dbus_connection,
+ priv->name_owner->str,
+ priv->object_path->str,
+ NM_WPAS_DBUS_IFACE_INTERFACE,
+ "BridgeIfname",
+ g_variant_new_string(bridge ?: ""),
+ DBUS_TIMEOUT_MSEC,
+ priv->main_cancellable,
+ set_bridge_cb,
+ nm_utils_user_data_pack(self, g_strdup(bridge)));
+}
+
void
nm_supplicant_interface_set_global_capabilities(NMSupplicantInterface *self, NMSupplCapMask value)
{
diff --git a/src/supplicant/nm-supplicant-interface.h b/src/supplicant/nm-supplicant-interface.h
index 812ea193fb..97ff0a95b0 100644
--- a/src/supplicant/nm-supplicant-interface.h
+++ b/src/supplicant/nm-supplicant-interface.h
@@ -190,4 +190,6 @@ void nm_supplicant_interface_cancel_wps(NMSupplicantInterface *self);
NMSupplicantAuthState nm_supplicant_interface_get_auth_state(NMSupplicantInterface *self);
+void nm_supplicant_interface_set_bridge(NMSupplicantInterface *self, const char *bridge);
+
#endif /* __NM_SUPPLICANT_INTERFACE_H__ */