Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/bsd/wpa/dist Interface additions/removals are not g...



details:   https://anonhg.NetBSD.org/src/rev/a27394f43ad0
branches:  trunk
changeset: 814482:a27394f43ad0
user:      roy <roy%NetBSD.org@localhost>
date:      Wed Mar 23 08:48:43 2016 +0000

description:
Interface additions/removals are not guaranteed to be for the driver
listening to kernel events. As such, send the events to
wpa_supplicant_event_global() which can then pick the correct interface
registered with wpa_supplicant to send the event to.

diffstat:

 external/bsd/wpa/dist/hostapd/main.c                  |   3 +-
 external/bsd/wpa/dist/src/ap/drv_callbacks.c          |  27 ++++++
 external/bsd/wpa/dist/src/ap/hostapd.c                |  20 +++++
 external/bsd/wpa/dist/src/ap/hostapd.h                |   3 +
 external/bsd/wpa/dist/src/drivers/driver.h            |  24 +++++-
 external/bsd/wpa/dist/src/drivers/driver_bsd.c        |  61 ++++++++++++--
 external/bsd/wpa/dist/wpa_supplicant/events.c         |  26 ++++++
 external/bsd/wpa/dist/wpa_supplicant/wpa_priv.c       |  75 ++++++++++++++++--
 external/bsd/wpa/dist/wpa_supplicant/wpa_supplicant.c |   2 +-
 9 files changed, 218 insertions(+), 23 deletions(-)

diffs (truncated from 472 to 300 lines):

diff -r 5dbda9b2b8f7 -r a27394f43ad0 external/bsd/wpa/dist/hostapd/main.c
--- a/external/bsd/wpa/dist/hostapd/main.c      Wed Mar 23 08:39:01 2016 +0000
+++ b/external/bsd/wpa/dist/hostapd/main.c      Wed Mar 23 08:48:43 2016 +0000
@@ -170,7 +170,8 @@
 
                if (global.drv_priv[i] == NULL &&
                    wpa_drivers[i]->global_init) {
-                       global.drv_priv[i] = wpa_drivers[i]->global_init();
+                       global.drv_priv[i] =
+                               wpa_drivers[i]->global_init(iface->interfaces);
                        if (global.drv_priv[i] == NULL) {
                                wpa_printf(MSG_ERROR, "Failed to initialize "
                                           "driver '%s'",
diff -r 5dbda9b2b8f7 -r a27394f43ad0 external/bsd/wpa/dist/src/ap/drv_callbacks.c
--- a/external/bsd/wpa/dist/src/ap/drv_callbacks.c      Wed Mar 23 08:39:01 2016 +0000
+++ b/external/bsd/wpa/dist/src/ap/drv_callbacks.c      Wed Mar 23 08:48:43 2016 +0000
@@ -1259,4 +1259,31 @@
        }
 }
 
+
+void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
+                                union wpa_event_data *data)
+{
+       struct hapd_interfaces *interfaces = ctx;
+       struct hostapd_data *hapd;
+
+       if (event != EVENT_INTERFACE_STATUS)
+               return;
+
+       hapd = hostapd_get_iface(interfaces, data->interface_status.ifname);
+       if (hapd && hapd->driver && hapd->driver->get_ifindex &&
+           hapd->drv_priv) {
+               unsigned int ifindex;
+
+               ifindex = hapd->driver->get_ifindex(hapd->drv_priv);
+               if (ifindex != data->interface_status.ifindex) {
+                       wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
+                               "interface status ifindex %d mismatch (%d)",
+                               ifindex, data->interface_status.ifindex);
+                       return;
+               }
+       }
+       if (hapd)
+               wpa_supplicant_event(hapd, event, data);
+}
+
 #endif /* HOSTAPD */
diff -r 5dbda9b2b8f7 -r a27394f43ad0 external/bsd/wpa/dist/src/ap/hostapd.c
--- a/external/bsd/wpa/dist/src/ap/hostapd.c    Wed Mar 23 08:39:01 2016 +0000
+++ b/external/bsd/wpa/dist/src/ap/hostapd.c    Wed Mar 23 08:48:43 2016 +0000
@@ -2723,3 +2723,23 @@
 }
 
 #endif /* NEED_AP_MLME */
+
+
+struct hostapd_data * hostapd_get_iface(struct hapd_interfaces *interfaces,
+                                       const char *ifname)
+{
+       size_t i, j;
+
+       for (i = 0; i < interfaces->count; i++) {
+               struct hostapd_iface *iface = interfaces->iface[i];
+
+               for (j = 0; j < iface->num_bss; j++) {
+                       struct hostapd_data *hapd = iface->bss[j];
+
+                       if (os_strcmp(ifname, hapd->conf->iface) == 0)
+                               return hapd;
+               }
+       }
+
+       return NULL;
+}
diff -r 5dbda9b2b8f7 -r a27394f43ad0 external/bsd/wpa/dist/src/ap/hostapd.h
--- a/external/bsd/wpa/dist/src/ap/hostapd.h    Wed Mar 23 08:39:01 2016 +0000
+++ b/external/bsd/wpa/dist/src/ap/hostapd.h    Wed Mar 23 08:48:43 2016 +0000
@@ -464,4 +464,7 @@
 hostapd_get_eap_user(struct hostapd_data *hapd, const u8 *identity,
                     size_t identity_len, int phase2);
 
+struct hostapd_data * hostapd_get_iface(struct hapd_interfaces *interfaces,
+                                       const char *ifname);
+
 #endif /* HOSTAPD_H */
diff -r 5dbda9b2b8f7 -r a27394f43ad0 external/bsd/wpa/dist/src/drivers/driver.h
--- a/external/bsd/wpa/dist/src/drivers/driver.h        Wed Mar 23 08:39:01 2016 +0000
+++ b/external/bsd/wpa/dist/src/drivers/driver.h        Wed Mar 23 08:48:43 2016 +0000
@@ -1850,6 +1850,14 @@
        void (*poll)(void *priv);
 
        /**
+        * get_ifindex - Get interface index
+        * @priv: private driver interface data
+        *
+        * Returns: Interface index
+        */
+       unsigned int (*get_ifindex)(void *priv);
+
+       /**
         * get_ifname - Get interface name
         * @priv: private driver interface data
         *
@@ -1978,6 +1986,7 @@
 
        /**
         * global_init - Global driver initialization
+        * @ctx: wpa_global pointer
         * Returns: Pointer to private data (global), %NULL on failure
         *
         * This optional function is called to initialize the driver wrapper
@@ -1987,7 +1996,7 @@
         * use init2() function instead of init() to get the pointer to global
         * data available to per-interface initializer.
         */
-       void * (*global_init)(void);
+       void * (*global_init)(void *ctx);
 
        /**
         * global_deinit - Global driver deinitialization
@@ -4116,6 +4125,7 @@
         * struct interface_status - Data for EVENT_INTERFACE_STATUS
         */
        struct interface_status {
+               unsigned int ifindex;
                char ifname[100];
                enum {
                        EVENT_INTERFACE_ADDED, EVENT_INTERFACE_REMOVED
@@ -4577,6 +4587,18 @@
 void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                          union wpa_event_data *data);
 
+/**
+ * wpa_supplicant_event_global - Report a driver event for wpa_supplicant
+ * @ctx: Context pointer (wpa_s); this is the ctx variable registered
+ *     with struct wpa_driver_ops::init()
+ * @event: event type (defined above)
+ * @data: possible extra data for the event
+ *
+ * Same as wpa_supplicant_event(), but we search for the interface in
+ * wpa_global.
+ */
+void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
+                                union wpa_event_data *data);
 
 /*
  * The following inline functions are provided for convenience to simplify
diff -r 5dbda9b2b8f7 -r a27394f43ad0 external/bsd/wpa/dist/src/drivers/driver_bsd.c
--- a/external/bsd/wpa/dist/src/drivers/driver_bsd.c    Wed Mar 23 08:39:01 2016 +0000
+++ b/external/bsd/wpa/dist/src/drivers/driver_bsd.c    Wed Mar 23 08:48:43 2016 +0000
@@ -48,6 +48,7 @@
 #include "l2_packet/l2_packet.h"
 
 struct bsd_driver_global {
+       void            *ctx;
        int             sock;                   /* socket for 802.11 ioctls */
        int             route;                  /* routing socket for events */
        char            *event_buf;
@@ -64,6 +65,7 @@
        char    ifname[IFNAMSIZ+1];     /* interface name */
        int     flags;
        unsigned int ifindex;           /* interface index */
+       int     if_removed;             /* has the interface been removed? */
        void    *ctx;
        struct wpa_driver_capa capa;    /* driver capability */
        int     is_ap;                  /* Access point mode */
@@ -88,13 +90,28 @@
        return NULL;
 }
 
+#ifndef HOSTAPD
+static struct bsd_driver_data *
+bsd_get_drvname(void *priv, const char *ifname)
+{
+       struct bsd_driver_global *global = priv;
+       struct bsd_driver_data *drv;
+
+       dl_list_for_each(drv, &global->ifaces, struct bsd_driver_data, list) {
+               if (os_strcmp(drv->ifname, ifname) == 0)
+                       return drv;
+       }
+       return NULL;
+}
+#endif /* HOSTAPD */
+
 static int
 bsd_set80211(void *priv, int op, int val, const void *arg, int arg_len)
 {
        struct bsd_driver_data *drv = priv;
        struct ieee80211req ireq;
 
-       if (drv->ifindex == 0)
+       if (drv->ifindex == 0 || drv->if_removed)
                return -1;
 
        os_memset(&ireq, 0, sizeof(ireq));
@@ -1221,24 +1238,45 @@
        switch (rtm->rtm_type) {
        case RTM_IFANNOUNCE:
                ifan = (struct if_announcemsghdr *) rtm;
-               drv = bsd_get_drvindex(global, ifan->ifan_index);
-               if (drv == NULL)
-                       return;
-               os_strlcpy(event.interface_status.ifname, drv->ifname,
-                          sizeof(event.interface_status.ifname));
                switch (ifan->ifan_what) {
                case IFAN_DEPARTURE:
+                       drv = bsd_get_drvindex(global, ifan->ifan_index);
+                       if (drv)
+                               drv->if_removed = 1;
                        event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
-                       drv->ifindex = 0;
+                       break;
+               case IFAN_ARRIVAL:
+                       drv = bsd_get_drvname(global, ifan->ifan_name);
+                       if (drv) {
+                               drv->ifindex = ifan->ifan_index;
+                               drv->if_removed = 0;
+                       }
+                       event.interface_status.ievent = EVENT_INTERFACE_ADDED;
                        break;
                default:
+                       wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: unknown action");
                        return;
                }
                wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s",
-                          event.interface_status.ifname,
+                          ifan->ifan_name,
                           ifan->ifan_what == IFAN_DEPARTURE ?
                                "removed" : "added");
-               wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
+               os_strlcpy(event.interface_status.ifname, ifan->ifan_name,
+                          sizeof(event.interface_status.ifname));
+               if (drv) {
+                       wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS,
+                                            &event);
+                       /*
+                        * Set ifindex to zero after sending the event as the
+                        * event might query the driver to ensure a match.
+                        */
+                       if (ifan->ifan_what == IFAN_DEPARTURE)
+                               drv->ifindex = 0;
+               } else {
+                       wpa_supplicant_event_global(global->ctx,
+                                                   EVENT_INTERFACE_STATUS,
+                                                   &event);
+               }
                break;
        case RTM_IEEE80211:
                ifan = (struct if_announcemsghdr *) rtm;
@@ -1580,7 +1618,7 @@
 {
        struct bsd_driver_data *drv = priv;
 
-       if (drv->ifindex != 0) {
+       if (drv->ifindex != 0 && !drv->if_removed) {
                wpa_driver_bsd_set_wpa(drv, 0);
 
                /* NB: mark interface down */
@@ -1613,7 +1651,7 @@
 #endif /* HOSTAPD */
 
 static void *
-bsd_global_init(void)
+bsd_global_init(void *ctx)
 {
        struct bsd_driver_global *global;
 
@@ -1621,6 +1659,7 @@
        if (global == NULL)
                return NULL;
 
+       global->ctx = ctx;
        dl_list_init(&global->ifaces);
 
        global->sock = socket(PF_INET, SOCK_DGRAM, 0);
diff -r 5dbda9b2b8f7 -r a27394f43ad0 external/bsd/wpa/dist/wpa_supplicant/events.c
--- a/external/bsd/wpa/dist/wpa_supplicant/events.c     Wed Mar 23 08:39:01 2016 +0000
+++ b/external/bsd/wpa/dist/wpa_supplicant/events.c     Wed Mar 23 08:48:43 2016 +0000
@@ -3662,3 +3662,29 @@
                break;
        }
 }
+
+
+void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
+                                union wpa_event_data *data)
+{
+       struct wpa_supplicant *wpa_s;
+
+       if (event != EVENT_INTERFACE_STATUS)
+               return;
+
+       wpa_s = wpa_supplicant_get_iface(ctx, data->interface_status.ifname);
+       if (wpa_s && wpa_s->driver->get_ifindex) {
+               unsigned int ifindex;
+
+               ifindex = wpa_s->driver->get_ifindex(wpa_s->drv_priv);
+               if (ifindex != data->interface_status.ifindex) {



Home | Main Index | Thread Index | Old Index