[PATCH] CHROMIUM: dbus: Add virtual interface create/remove logic to be inline with ctrl_iface

Jintao Lin jintaolin at chromium.org
Wed Nov 2 18:03:36 PDT 2022


Signed-off-by: Jintao Lin <jintaolin at chromium.org>

BUG=b:254714993
TEST=on device, check the interface creation and removal by using dbus
command,
> gdbus call --system --dest fi.w1.wpa_supplicant1 --object-path /fi/w1/wpa_supplicant1 --method fi.w1.wpa_supplicant1.CreateInterface "{'Ifname':<'wlan1'>, 'Driver':<'nl80211'>, 'ConfigFile':<'/usr/lib64/shill/shims/wpa_supplicant.conf'>, 'Create':<true>, 'Type':<'ap'>}"
> iwconfig wlan1
> gdbus call --system --dest fi.w1.wpa_supplicant1 --object-path /fi/w1/wpa_supplicant1 --method fi.w1.wpa_supplicant1.RemoveInterface '/fi/w1/wpa_supplicant1/Interfaces/1'
> ifconfig -a

Change-Id: Idc987db638cdc68fc13fe34d430e212f6ce37e13
---
 doc/dbus.doxygen                        |  2 +
 wpa_supplicant/dbus/dbus_new_handlers.c | 63 ++++++++++++++++++++++++-
 2 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen
index 075c2d5bf..b2e267605 100644
--- a/doc/dbus.doxygen
+++ b/doc/dbus.doxygen
@@ -41,6 +41,8 @@ registered in the bus with fi.w1.wpa_supplicant1 name.
 	      <tr><td>BridgeIfname</td><td>s</td><td>Name of the bridge interface to control, e.g., br0</td><td>No</td>
 	      <tr><td>Driver</td><td>s</td><td>Driver name which the interface uses, e.g., nl80211</td><td>No</td>
 	      <tr><td>ConfigFile</td><td>s</td><td>Configuration file path</td><td>No</td>
+	      <tr><td>Create</td><td>b</td><td>Whether to create a new interface in the kernel</td><td>No</td>
+	      <tr><td>Type</td><td>s</td><td>Interface type to create</td><td>No</td>
 	    </table>
 	  </dd>
 	</dl>
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index c1f147398..ed27d5d64 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -755,6 +755,10 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
 	char *ifname = NULL;
 	char *confname = NULL;
 	char *bridge_ifname = NULL;
+	char *type = NULL;
+	bool create_iface = false;
+	enum wpa_driver_if_type if_type = WPA_IF_STATION;
+	u8 mac_addr[ETH_ALEN];
 
 	dbus_message_iter_init(message, &iter);
 
@@ -791,6 +795,17 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
 			wpa_dbus_dict_entry_clear(&entry);
 			if (bridge_ifname == NULL)
 				goto oom;
+		} else if (os_strcmp(entry.key, "Create") == 0 &&
+			   entry.type == DBUS_TYPE_BOOLEAN) {
+			create_iface = entry.bool_value;
+			wpa_dbus_dict_entry_clear(&entry);
+		} else if (os_strcmp(entry.key, "Type") == 0 &&
+			   entry.type == DBUS_TYPE_STRING) {
+			os_free(type);
+			type = os_strdup(entry.str_value);
+			wpa_dbus_dict_entry_clear(&entry);
+			if (type == NULL)
+				goto oom;
 		} else {
 			wpa_dbus_dict_entry_clear(&entry);
 			goto error;
@@ -800,6 +815,26 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
 	if (ifname == NULL)
 		goto error; /* Required Ifname argument missing */
 
+	if (create_iface) {
+		if (os_strcmp(type, "sta") == 0) {
+			if_type = WPA_IF_STATION;
+		} else if (os_strcmp(type, "ap") == 0) {
+			if_type = WPA_IF_AP_BSS;
+		} else {
+			goto error;
+		}
+
+		wpa_printf(MSG_DEBUG, "%s[dbus]: creating an interface '%s'",
+			   __func__, ifname);
+		if (!global->ifaces || wpa_drv_if_add(global->ifaces, if_type, ifname,
+				   NULL, NULL, NULL, mac_addr, NULL) < 0) {
+			reply = wpas_dbus_error_unknown_error(
+				message,
+				"interface creation failed.");
+			goto out;
+		}
+	}
+
 	/*
 	 * Try to get the wpa_supplicant record for this iface, return
 	 * an error if we already control it.
@@ -808,6 +843,7 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
 		reply = dbus_message_new_error(
 			message, WPAS_DBUS_ERROR_IFACE_EXISTS,
 			"wpa_supplicant already controls this interface.");
+		goto fail;
 	} else {
 		struct wpa_supplicant *wpa_s;
 		struct wpa_interface iface;
@@ -822,6 +858,7 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
 		if (wpa_s && wpa_s->dbus_new_path) {
 			const char *path = wpa_s->dbus_new_path;
 
+			wpa_s->added_vif = create_iface;
 			reply = dbus_message_new_method_return(message);
 			dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
 						 &path, DBUS_TYPE_INVALID);
@@ -829,6 +866,7 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
 			reply = wpas_dbus_error_unknown_error(
 				message,
 				"wpa_supplicant couldn't grab this interface.");
+			goto fail;
 		}
 	}
 
@@ -837,6 +875,7 @@ out:
 	os_free(ifname);
 	os_free(confname);
 	os_free(bridge_ifname);
+	os_free(type);
 	return reply;
 
 error:
@@ -845,6 +884,10 @@ error:
 oom:
 	reply = wpas_dbus_error_no_memory(message);
 	goto out;
+fail:
+	if (create_iface)
+		wpa_drv_if_remove(global->ifaces, WPA_IF_STATION, ifname);
+	goto out;
 }
 
 
@@ -865,19 +908,35 @@ DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
 	struct wpa_supplicant *wpa_s;
 	char *path;
 	DBusMessage *reply = NULL;
+	unsigned int delete_iface;
 
 	dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
 			      DBUS_TYPE_INVALID);
 
 	wpa_s = get_iface_by_dbus_path(global, path);
-	if (wpa_s == NULL)
+	if (wpa_s == NULL) {
 		reply = wpas_dbus_error_iface_unknown(message);
-	else if (wpa_supplicant_remove_iface(global, wpa_s, 0)) {
+		goto out;
+	}
+	delete_iface = wpa_s->added_vif;
+	if (wpa_supplicant_remove_iface(global, wpa_s, 0)) {
 		reply = wpas_dbus_error_unknown_error(
 			message,
 			"wpa_supplicant couldn't remove this interface.");
+		goto out;
 	}
 
+	if (delete_iface) {
+		wpa_printf(MSG_DEBUG, "%s[dbus]: deleting the interface '%s'",
+			   __func__, wpa_s->ifname);
+		if (wpa_drv_if_remove(global->ifaces, WPA_IF_STATION, wpa_s->ifname)) {
+			reply = wpas_dbus_error_unknown_error(
+			message,
+			"wpa_supplicant couldn't delete this interface.");
+		}
+	}
+
+out:
 	return reply;
 }
 
-- 
2.38.1.273.g43a17bfeac-goog




More information about the Hostap mailing list