]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
rfkill: Use rtnetlink ifup/ifdown events
authorJouni Malinen <j@w1.fi>
Mon, 31 May 2010 15:00:27 +0000 (18:00 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 31 May 2010 15:52:17 +0000 (18:52 +0300)
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.

src/drivers/driver_nl80211.c
src/drivers/driver_wext.c
src/drivers/driver_wext.h

index 2b7462bea7ce702361742d359547c343c19418ae..39c1d2d1cf8df93e90da4725d6ec68785ee8bf18 100644 (file)
@@ -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 "
index 222378378798d06c97e7e7cf32a0a25448a781a7..d3629dd0d31b497161b31110922ee79e88814b10 100644 (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_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 "
index 22d26a6b5b47c228f55e7b47d55c2f844c4e5673..9176dd879c8cfc5ec0d49048d3cd9454bb04fd39 100644 (file)
@@ -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;