aboutsummaryrefslogtreecommitdiffstats
path: root/src/drivers
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2010-05-31 15:00:27 (GMT)
committerJouni Malinen <j@w1.fi>2010-05-31 15:52:17 (GMT)
commita63063b4f6a06d110e7168560131ea52882f0474 (patch)
tree01d3457e0e93343c2187349e87f3b2be431aeef0 /src/drivers
parent84b2f9909fa1b92b2d3eb45278799ca3ecd2392e (diff)
downloadhostap-a63063b4f6a06d110e7168560131ea52882f0474.zip
hostap-a63063b4f6a06d110e7168560131ea52882f0474.tar.gz
hostap-a63063b4f6a06d110e7168560131ea52882f0474.tar.bz2
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.
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/driver_nl80211.c23
-rw-r--r--src/drivers/driver_wext.c22
-rw-r--r--src/drivers/driver_wext.h1
3 files changed, 40 insertions, 6 deletions
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 2b7462b..39c1d2d 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 2223783..d3629dd 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 22d26a6..9176dd8 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;