]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
wext: Filter unexpected interface added/up events
authorJouni Malinen <j@w1.fi>
Sat, 18 Feb 2012 11:28:21 +0000 (13:28 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 18 Feb 2012 11:28:21 +0000 (13:28 +0200)
It looks like a RTM_NEWLINK event claiming the interface to be UP is
delivered just before removing an interface after having first indicated
that the interface was going down/removed. Ignore this event if the
interface is not present anymore at the moment the event is processed.
This fixes issues where an interface that was re-added after being
removed did not get reconfigured properly.

Signed-hostap: Jouni Malinen <j@w1.fi>
intended-for: hostap-1

src/drivers/driver_wext.c

index 9be1665a744ed5d2e014e20288cc5e4f00e61d25..b76ce1d2020e1a180d4422ca6d892c50b978f96b 100644 (file)
@@ -569,10 +569,28 @@ static void wpa_driver_wext_event_link(struct wpa_driver_wext_data *drv,
                   del ? "removed" : "added");
 
        if (os_strcmp(drv->ifname, event.interface_status.ifname) == 0) {
-               if (del)
+               if (del) {
+                       if (drv->if_removed) {
+                               wpa_printf(MSG_DEBUG, "WEXT: if_removed "
+                                          "already set - ignore event");
+                               return;
+                       }
                        drv->if_removed = 1;
-               else
+               } else {
+                       if (if_nametoindex(drv->ifname) == 0) {
+                               wpa_printf(MSG_DEBUG, "WEXT: Interface %s "
+                                          "does not exist - ignore "
+                                          "RTM_NEWLINK",
+                                          drv->ifname);
+                               return;
+                       }
+                       if (!drv->if_removed) {
+                               wpa_printf(MSG_DEBUG, "WEXT: if_removed "
+                                          "already cleared - ignore event");
+                               return;
+                       }
                        drv->if_removed = 0;
+               }
        }
 
        wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
@@ -628,6 +646,7 @@ static void wpa_driver_wext_event_rtm_newlink(void *ctx, struct ifinfomsg *ifi,
        struct wpa_driver_wext_data *drv = ctx;
        int attrlen, rta_len;
        struct rtattr *attr;
+       char namebuf[IFNAMSIZ];
 
        if (!wpa_driver_wext_own_ifindex(drv, ifi->ifi_index, buf, len)) {
                wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d",
@@ -650,9 +669,25 @@ static void wpa_driver_wext_event_rtm_newlink(void *ctx, struct ifinfomsg *ifi,
        }
 
        if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
-               wpa_printf(MSG_DEBUG, "WEXT: Interface up");
-               drv->if_disabled = 0;
-               wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL);
+               if (if_indextoname(ifi->ifi_index, namebuf) &&
+                   linux_iface_up(drv->ioctl_sock, drv->ifname) == 0) {
+                       wpa_printf(MSG_DEBUG, "WEXT: Ignore interface up "
+                                  "event since interface %s is down",
+                                  namebuf);
+               } else if (if_nametoindex(drv->ifname) == 0) {
+                       wpa_printf(MSG_DEBUG, "WEXT: Ignore interface up "
+                                  "event since interface %s does not exist",
+                                  drv->ifname);
+               } else if (drv->if_removed) {
+                       wpa_printf(MSG_DEBUG, "WEXT: Ignore interface up "
+                                  "event since interface %s is marked "
+                                  "removed", drv->ifname);
+               } else {
+                       wpa_printf(MSG_DEBUG, "WEXT: Interface up");
+                       drv->if_disabled = 0;
+                       wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
+                                            NULL);
+               }
        }
 
        /*