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/4700d8e73483
branches: trunk
changeset: 344340:4700d8e73483
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 5ddaecf4607c -r 4700d8e73483 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 5ddaecf4607c -r 4700d8e73483 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 5ddaecf4607c -r 4700d8e73483 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 5ddaecf4607c -r 4700d8e73483 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 5ddaecf4607c -r 4700d8e73483 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 5ddaecf4607c -r 4700d8e73483 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 5ddaecf4607c -r 4700d8e73483 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