hostapd: nl80211 retry creating a interface if it fails the first time
[wpasupplicant] / src / drivers / driver_nl80211.c
index 79c7889..26ee21e 100644 (file)
@@ -2468,9 +2468,10 @@ static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
 }
 
 
-static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
-                               const char *ifname, enum nl80211_iftype iftype,
-                               const u8 *addr)
+static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
+                                    const char *ifname,
+                                    enum nl80211_iftype iftype,
+                                    const u8 *addr)
 {
        struct nl_msg *msg, *flags = NULL;
        int ifidx;
@@ -2506,8 +2507,8 @@ static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
        ret = send_and_recv_msgs(drv, msg, NULL, NULL);
        if (ret) {
  nla_put_failure:
-               wpa_printf(MSG_ERROR, "Failed to create interface %s.",
-                          ifname);
+               wpa_printf(MSG_ERROR, "Failed to create interface %s: %d (%s)",
+                          ifname, ret, strerror(-ret));
                return ret;
        }
 
@@ -2529,6 +2530,27 @@ static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
 
        return ifidx;
 }
+static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
+                               const char *ifname, enum nl80211_iftype iftype,
+                               const u8 *addr)
+{
+       int ret;
+
+       ret = nl80211_create_iface_once(drv, ifname, iftype, addr);
+
+       /* if error occured and interface exists already */
+       if (ret == -ENFILE && if_nametoindex(ifname)) {
+               wpa_printf(MSG_INFO, "Try to remove and re-create %s", ifname);
+
+               /* Try to remove the interface that was already there. */
+               nl80211_remove_iface(drv, if_nametoindex(ifname));
+
+               /* Try to create the interface again */
+               ret = nl80211_create_iface_once(drv, ifname, iftype, addr);
+       }
+
+       return ret;
+}
 
 #endif /* CONFIG_AP || HOSTAPD */