There is no way to create or remove a virtual interface with wpa_supplicant dbus methods. The platform has to use out-of-band methods to manage the virtual interfaces. This change adds virtual interface create/remove logic to the dbus methods CreateInterface and RemoveInterface to achieve similar functionalities as wpa_cli commands interface_add and interface_remove. Signed-off-by: Jintao Lin <jintaolin@xxxxxxxxxxxx> --- doc/dbus.doxygen | 2 + wpa_supplicant/dbus/dbus_new_handlers.c | 54 ++++++++++++++++++++++++- wpa_supplicant/wpa_supplicant_i.h | 1 + 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen index 075c2d5bf..a23817983 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 (sta or ap)</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..776956059 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -755,6 +755,8 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message, char *ifname = NULL; char *confname = NULL; char *bridge_ifname = NULL; + bool create_iface = false; + enum wpa_driver_if_type if_type = WPA_IF_STATION; dbus_message_iter_init(message, &iter); @@ -791,6 +793,20 @@ 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) { + if (os_strcmp(entry.str_value, "sta") == 0) { + if_type = WPA_IF_STATION; + } else if (os_strcmp(entry.str_value, "ap") == 0) { + if_type = WPA_IF_AP_BSS; + } else { + goto error; + } + wpa_dbus_dict_entry_clear(&entry); } else { wpa_dbus_dict_entry_clear(&entry); goto error; @@ -812,6 +828,20 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message, struct wpa_supplicant *wpa_s; struct wpa_interface iface; + if (create_iface) { + u8 mac_addr[ETH_ALEN]; + + 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; + } + } + os_memset(&iface, 0, sizeof(iface)); iface.driver = driver; iface.ifname = ifname; @@ -822,6 +852,8 @@ 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; + wpa_s->added_vif_type = create_iface? if_type : WPA_IF_MAX; reply = dbus_message_new_method_return(message); dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); @@ -829,6 +861,8 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message, reply = wpas_dbus_error_unknown_error( message, "wpa_supplicant couldn't grab this interface."); + if (create_iface) + wpa_drv_if_remove(global->ifaces, wpa_s->added_vif_type, ifname); } } @@ -865,19 +899,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_s->added_vif_type, wpa_s->ifname)) { + reply = wpas_dbus_error_unknown_error( + message, + "wpa_supplicant couldn't delete this interface."); + } } +out: return reply; } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 858ca23d1..af6cf893e 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -857,6 +857,7 @@ struct wpa_supplicant { unsigned int connection_vht:1; unsigned int connection_he:1; unsigned int disable_mbo_oce:1; + enum wpa_driver_if_type added_vif_type; struct os_reltime last_mac_addr_change; int last_mac_addr_style; -- 2.38.1.431.g37b22c650d-goog _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap