]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
dbus: Add virtual interface create/remove logic to be inline with ctrl_iface
authorJintao Lin <jintaolin@chromium.org>
Mon, 7 Nov 2022 19:25:26 +0000 (19:25 +0000)
committerJouni Malinen <j@w1.fi>
Fri, 25 Nov 2022 16:57:51 +0000 (18:57 +0200)
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@chromium.org>
doc/dbus.doxygen
wpa_supplicant/dbus/dbus_new_handlers.c
wpa_supplicant/wpa_supplicant_i.h

index f6ab820001086b169d237488dce36304530ba6b9..504db7540459ae19d43201e7625c25040a92c12b 100644 (file)
@@ -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>
index 7b9cf2884c06659aa1f1927826d7f64345054637..e63e2209eda635a02287a53e2a98e72c9d20f9c8 100644 (file)
@@ -704,6 +704,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);
 
@@ -740,6 +742,19 @@ 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;
@@ -761,6 +776,23 @@ 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;
@@ -771,6 +803,9 @@ 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);
@@ -778,6 +813,9 @@ 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, if_type,
+                                                 ifname);
                }
        }
 
@@ -814,19 +852,36 @@ DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
        struct wpa_supplicant *wpa_s;
        char *path;
        DBusMessage *reply = NULL;
+       bool 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) {
                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;
 }
 
index add24f07dfe76551c2947d9c73608c3511dc8351..330b80f4da82b97fa9bf9bdf5e2fdf908d547116 100644 (file)
@@ -926,6 +926,7 @@ struct wpa_supplicant {
        unsigned int connection_he:1;
        unsigned int connection_eht: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;