hostapd: nl80211 retry creating a interface if it fails the first time
authorKarl Hiramoto <karl@hiramoto.org>
Fri, 29 May 2009 18:48:19 +0000 (21:48 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 29 May 2009 18:48:19 +0000 (21:48 +0300)
If hostapd segfaults, or is killed with -9, or the interface already exists,
when the interface is created, it will fail.

Configuration file: /tmp/hostapd/hostapd.conf
Failed to create interface mon.wlan0_0.
Using interface wlan0_0 with hwaddr 00:13:01:01:08:0a and ssid 'IG_0405_LAN'
Failed to set beacon head/tail or DTIM period
Failed to create interface wlan0_1.

Try to remove the interface and re-create it before aborting.

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 */