dbus: Add virtual interface create/remove logic to be inline with ctrl_iface
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>
This commit is contained in:
parent
5102d7411f
commit
0ba266d86c
3 changed files with 60 additions and 2 deletions
|
@ -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>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>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>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>
|
</table>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
|
@ -704,6 +704,8 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
|
||||||
char *ifname = NULL;
|
char *ifname = NULL;
|
||||||
char *confname = NULL;
|
char *confname = NULL;
|
||||||
char *bridge_ifname = 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);
|
dbus_message_iter_init(message, &iter);
|
||||||
|
|
||||||
|
@ -740,6 +742,19 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
|
||||||
wpa_dbus_dict_entry_clear(&entry);
|
wpa_dbus_dict_entry_clear(&entry);
|
||||||
if (bridge_ifname == NULL)
|
if (bridge_ifname == NULL)
|
||||||
goto oom;
|
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 {
|
} else {
|
||||||
wpa_dbus_dict_entry_clear(&entry);
|
wpa_dbus_dict_entry_clear(&entry);
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -761,6 +776,23 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
|
||||||
struct wpa_supplicant *wpa_s;
|
struct wpa_supplicant *wpa_s;
|
||||||
struct wpa_interface iface;
|
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));
|
os_memset(&iface, 0, sizeof(iface));
|
||||||
iface.driver = driver;
|
iface.driver = driver;
|
||||||
iface.ifname = ifname;
|
iface.ifname = ifname;
|
||||||
|
@ -771,6 +803,9 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
|
||||||
if (wpa_s && wpa_s->dbus_new_path) {
|
if (wpa_s && wpa_s->dbus_new_path) {
|
||||||
const char *path = 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);
|
reply = dbus_message_new_method_return(message);
|
||||||
dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
|
dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
|
||||||
&path, DBUS_TYPE_INVALID);
|
&path, DBUS_TYPE_INVALID);
|
||||||
|
@ -778,6 +813,9 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
|
||||||
reply = wpas_dbus_error_unknown_error(
|
reply = wpas_dbus_error_unknown_error(
|
||||||
message,
|
message,
|
||||||
"wpa_supplicant couldn't grab this interface.");
|
"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;
|
struct wpa_supplicant *wpa_s;
|
||||||
char *path;
|
char *path;
|
||||||
DBusMessage *reply = NULL;
|
DBusMessage *reply = NULL;
|
||||||
|
bool delete_iface;
|
||||||
|
|
||||||
dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
|
dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
|
||||||
DBUS_TYPE_INVALID);
|
DBUS_TYPE_INVALID);
|
||||||
|
|
||||||
wpa_s = get_iface_by_dbus_path(global, path);
|
wpa_s = get_iface_by_dbus_path(global, path);
|
||||||
if (wpa_s == NULL)
|
if (!wpa_s) {
|
||||||
reply = wpas_dbus_error_iface_unknown(message);
|
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(
|
reply = wpas_dbus_error_unknown_error(
|
||||||
message,
|
message,
|
||||||
"wpa_supplicant couldn't remove this interface.");
|
"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;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -926,6 +926,7 @@ struct wpa_supplicant {
|
||||||
unsigned int connection_he:1;
|
unsigned int connection_he:1;
|
||||||
unsigned int connection_eht:1;
|
unsigned int connection_eht:1;
|
||||||
unsigned int disable_mbo_oce:1;
|
unsigned int disable_mbo_oce:1;
|
||||||
|
enum wpa_driver_if_type added_vif_type;
|
||||||
|
|
||||||
struct os_reltime last_mac_addr_change;
|
struct os_reltime last_mac_addr_change;
|
||||||
int last_mac_addr_style;
|
int last_mac_addr_style;
|
||||||
|
|
Loading…
Reference in a new issue