diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 2b7462bea..39c1d2d1c 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -73,6 +73,7 @@ struct wpa_driver_nl80211_data { char brname[IFNAMSIZ]; int ifindex; int if_removed; + int if_disabled; struct rfkill_data *rfkill; struct wpa_driver_capa capa; int has_capability; @@ -413,6 +414,19 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "", (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "", (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : ""); + + if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) { + wpa_printf(MSG_DEBUG, "nl80211: Interface down"); + drv->if_disabled = 1; + wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED, NULL); + } + + if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) { + wpa_printf(MSG_DEBUG, "nl80211: Interface up"); + drv->if_disabled = 0; + wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL); + } + /* * Some drivers send the association event before the operup event--in * this case, lifting operstate in wpa_driver_nl80211_set_operstate() @@ -1351,9 +1365,11 @@ err1: static void wpa_driver_nl80211_rfkill_blocked(void *ctx) { - struct wpa_driver_nl80211_data *drv = ctx; wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked"); - wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED, NULL); + /* + * This may be for any interface; use ifdown event to disable + * interface. + */ } @@ -1366,7 +1382,7 @@ static void wpa_driver_nl80211_rfkill_unblocked(void *ctx) "after rfkill unblock"); return; } - wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL); + /* rtnetlink ifup handler will report interface as enabled */ } @@ -1524,6 +1540,7 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv) wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable " "interface '%s' due to rfkill", bss->ifname); + drv->if_disabled = 1; send_rfkill_event = 1; } else { wpa_printf(MSG_ERROR, "nl80211: Could not set " diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c index 222378378..d3629dd0d 100644 --- a/src/drivers/driver_wext.c +++ b/src/drivers/driver_wext.c @@ -635,6 +635,19 @@ static void wpa_driver_wext_event_rtm_newlink(void *ctx, struct ifinfomsg *ifi, (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "", (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "", (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : ""); + + if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) { + wpa_printf(MSG_DEBUG, "WEXT: Interface down"); + drv->if_disabled = 1; + wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED, NULL); + } + + 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); + } + /* * Some drivers send the association event before the operup event--in * this case, lifting operstate in wpa_driver_wext_set_operstate() @@ -690,9 +703,11 @@ static void wpa_driver_wext_event_rtm_dellink(void *ctx, struct ifinfomsg *ifi, static void wpa_driver_wext_rfkill_blocked(void *ctx) { - struct wpa_driver_wext_data *drv = ctx; wpa_printf(MSG_DEBUG, "WEXT: RFKILL blocked"); - wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED, NULL); + /* + * This may be for any interface; use ifdown event to disable + * interface. + */ } @@ -705,7 +720,7 @@ static void wpa_driver_wext_rfkill_unblocked(void *ctx) "after rfkill unblock"); return; } - wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL); + /* rtnetlink ifup handler will report interface as enabled */ } @@ -802,6 +817,7 @@ static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv) wpa_printf(MSG_DEBUG, "WEXT: Could not yet enable " "interface '%s' due to rfkill", drv->ifname); + drv->if_disabled = 1; send_rfkill_event = 1; } else { wpa_printf(MSG_ERROR, "WEXT: Could not set " diff --git a/src/drivers/driver_wext.h b/src/drivers/driver_wext.h index 22d26a6b5..9176dd879 100644 --- a/src/drivers/driver_wext.h +++ b/src/drivers/driver_wext.h @@ -26,6 +26,7 @@ struct wpa_driver_wext_data { int ifindex; int ifindex2; int if_removed; + int if_disabled; struct rfkill_data *rfkill; u8 *assoc_req_ies; size_t assoc_req_ies_len;