diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index d962ac988..ed9681cb9 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -601,6 +601,14 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : ""); if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) { + char namebuf[IFNAMSIZ]; + if (if_indextoname(ifi->ifi_index, namebuf) && + linux_iface_up(drv->global->ioctl_sock, + drv->first_bss.ifname) > 0) { + wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down " + "event since interface %s is up", namebuf); + return; + } wpa_printf(MSG_DEBUG, "nl80211: Interface down"); if (drv->ignore_if_down_event) { wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down " diff --git a/src/drivers/linux_ioctl.c b/src/drivers/linux_ioctl.c index 3f7ee291d..d7501cf04 100644 --- a/src/drivers/linux_ioctl.c +++ b/src/drivers/linux_ioctl.c @@ -60,6 +60,28 @@ int linux_set_iface_flags(int sock, const char *ifname, int dev_up) } +int linux_iface_up(int sock, const char *ifname) +{ + struct ifreq ifr; + int ret; + + if (sock < 0) + return -1; + + os_memset(&ifr, 0, sizeof(ifr)); + os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + + if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) { + ret = errno ? -errno : -999; + wpa_printf(MSG_ERROR, "Could not read interface %s flags: %s", + ifname, strerror(errno)); + return ret; + } + + return !!(ifr.ifr_flags & IFF_UP); +} + + int linux_get_ifhwaddr(int sock, const char *ifname, u8 *addr) { struct ifreq ifr; diff --git a/src/drivers/linux_ioctl.h b/src/drivers/linux_ioctl.h index a5557383d..e0bf673bc 100644 --- a/src/drivers/linux_ioctl.h +++ b/src/drivers/linux_ioctl.h @@ -16,6 +16,7 @@ #define LINUX_IOCTL_H int linux_set_iface_flags(int sock, const char *ifname, int dev_up); +int linux_iface_up(int sock, const char *ifname); int linux_get_ifhwaddr(int sock, const char *ifname, u8 *addr); int linux_set_ifhwaddr(int sock, const char *ifname, const u8 *addr); int linux_br_add(int sock, const char *brname);