|
@@ -8521,11 +8521,14 @@ static int wpa_supplicant_global_iface_add(struct wpa_global *global,
|
|
|
char *cmd)
|
|
|
{
|
|
|
struct wpa_interface iface;
|
|
|
- char *pos;
|
|
|
+ char *pos, *extra;
|
|
|
+ struct wpa_supplicant *wpa_s;
|
|
|
+ unsigned int create_iface = 0;
|
|
|
+ u8 mac_addr[ETH_ALEN];
|
|
|
|
|
|
/*
|
|
|
* <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
|
|
|
- * TAB<bridge_ifname>
|
|
|
+ * TAB<bridge_ifname>[TAB<create>]
|
|
|
*/
|
|
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd);
|
|
|
|
|
@@ -8585,12 +8588,47 @@ static int wpa_supplicant_global_iface_add(struct wpa_global *global,
|
|
|
iface.bridge_ifname = NULL;
|
|
|
if (pos == NULL)
|
|
|
break;
|
|
|
+
|
|
|
+ extra = pos;
|
|
|
+ pos = os_strchr(pos, '\t');
|
|
|
+ if (pos)
|
|
|
+ *pos++ = '\0';
|
|
|
+ if (os_strcmp(extra, "create") == 0)
|
|
|
+ create_iface = 1;
|
|
|
+ else
|
|
|
+ return -1;
|
|
|
} while (0);
|
|
|
|
|
|
+ if (create_iface) {
|
|
|
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE creating interface '%s'",
|
|
|
+ iface.ifname);
|
|
|
+ if (!global->ifaces)
|
|
|
+ return -1;
|
|
|
+ if (wpa_drv_if_add(global->ifaces, WPA_IF_STATION, iface.ifname,
|
|
|
+ NULL, NULL, NULL, mac_addr, NULL) < 0) {
|
|
|
+ wpa_printf(MSG_ERROR,
|
|
|
+ "CTRL_IFACE interface creation failed");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ wpa_printf(MSG_DEBUG,
|
|
|
+ "CTRL_IFACE interface '%s' created with MAC addr: "
|
|
|
+ MACSTR, iface.ifname, MAC2STR(mac_addr));
|
|
|
+ }
|
|
|
+
|
|
|
if (wpa_supplicant_get_iface(global, iface.ifname))
|
|
|
- return -1;
|
|
|
+ goto fail;
|
|
|
+
|
|
|
+ wpa_s = wpa_supplicant_add_iface(global, &iface, NULL);
|
|
|
+ if (!wpa_s)
|
|
|
+ goto fail;
|
|
|
+ wpa_s->added_vif = create_iface;
|
|
|
+ return 0;
|
|
|
|
|
|
- return wpa_supplicant_add_iface(global, &iface, NULL) ? 0 : -1;
|
|
|
+fail:
|
|
|
+ if (create_iface)
|
|
|
+ wpa_drv_if_remove(global->ifaces, WPA_IF_STATION, iface.ifname);
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -8598,13 +8636,22 @@ static int wpa_supplicant_global_iface_remove(struct wpa_global *global,
|
|
|
char *cmd)
|
|
|
{
|
|
|
struct wpa_supplicant *wpa_s;
|
|
|
+ int ret;
|
|
|
+ unsigned int delete_iface;
|
|
|
|
|
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd);
|
|
|
|
|
|
wpa_s = wpa_supplicant_get_iface(global, cmd);
|
|
|
if (wpa_s == NULL)
|
|
|
return -1;
|
|
|
- return wpa_supplicant_remove_iface(global, wpa_s, 0);
|
|
|
+ delete_iface = wpa_s->added_vif;
|
|
|
+ ret = wpa_supplicant_remove_iface(global, wpa_s, 0);
|
|
|
+ if (!ret && delete_iface) {
|
|
|
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE deleting the interface '%s'",
|
|
|
+ cmd);
|
|
|
+ ret = wpa_drv_if_remove(global->ifaces, WPA_IF_STATION, cmd);
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
|