rfkill: Use rtnetlink ifup/ifdown events

Replace use of rfkill block event with rtnetlink ifdown. This makes
the design more robust since the rfkill event could have been for
another interface while the rtnetlink events are already filtered
based of ifindex. In addition, the new design handles other than
rfkill-triggered ifdown/ifup events, too. rfkill unblocked event
is still needed to try to set the interface back up. If the unblock
was for another interface, ifup will fail and the driver state is
not changed.
This commit is contained in:
Jouni Malinen 2010-05-31 18:00:27 +03:00
parent 84b2f9909f
commit a63063b4f6
3 changed files with 40 additions and 6 deletions

View file

@ -73,6 +73,7 @@ struct wpa_driver_nl80211_data {
char brname[IFNAMSIZ]; char brname[IFNAMSIZ];
int ifindex; int ifindex;
int if_removed; int if_removed;
int if_disabled;
struct rfkill_data *rfkill; struct rfkill_data *rfkill;
struct wpa_driver_capa capa; struct wpa_driver_capa capa;
int has_capability; 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_RUNNING) ? "[RUNNING]" : "",
(ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "", (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
(ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : ""); (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 * Some drivers send the association event before the operup event--in
* this case, lifting operstate in wpa_driver_nl80211_set_operstate() * this case, lifting operstate in wpa_driver_nl80211_set_operstate()
@ -1351,9 +1365,11 @@ err1:
static void wpa_driver_nl80211_rfkill_blocked(void *ctx) static void wpa_driver_nl80211_rfkill_blocked(void *ctx)
{ {
struct wpa_driver_nl80211_data *drv = ctx;
wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked"); 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"); "after rfkill unblock");
return; 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 " wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable "
"interface '%s' due to rfkill", "interface '%s' due to rfkill",
bss->ifname); bss->ifname);
drv->if_disabled = 1;
send_rfkill_event = 1; send_rfkill_event = 1;
} else { } else {
wpa_printf(MSG_ERROR, "nl80211: Could not set " wpa_printf(MSG_ERROR, "nl80211: Could not set "

View file

@ -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_RUNNING) ? "[RUNNING]" : "",
(ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "", (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
(ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : ""); (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 * Some drivers send the association event before the operup event--in
* this case, lifting operstate in wpa_driver_wext_set_operstate() * 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) static void wpa_driver_wext_rfkill_blocked(void *ctx)
{ {
struct wpa_driver_wext_data *drv = ctx;
wpa_printf(MSG_DEBUG, "WEXT: RFKILL blocked"); 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"); "after rfkill unblock");
return; 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 " wpa_printf(MSG_DEBUG, "WEXT: Could not yet enable "
"interface '%s' due to rfkill", "interface '%s' due to rfkill",
drv->ifname); drv->ifname);
drv->if_disabled = 1;
send_rfkill_event = 1; send_rfkill_event = 1;
} else { } else {
wpa_printf(MSG_ERROR, "WEXT: Could not set " wpa_printf(MSG_ERROR, "WEXT: Could not set "

View file

@ -26,6 +26,7 @@ struct wpa_driver_wext_data {
int ifindex; int ifindex;
int ifindex2; int ifindex2;
int if_removed; int if_removed;
int if_disabled;
struct rfkill_data *rfkill; struct rfkill_data *rfkill;
u8 *assoc_req_ies; u8 *assoc_req_ies;
size_t assoc_req_ies_len; size_t assoc_req_ies_len;