[PATCH 5/5] driver_bsd.c: Move route and socket fds to global init

Roy Marples roy at marples.name
Tue May 26 17:25:18 EDT 2009


This allows the driver to raise events for any interface and allows
wpa_supplicant to dynamically add/remove interfaces.

Signed-off-by: Roy Marples <roy at marples.name>
---
 src/drivers/driver_bsd.c |  150 ++++++++++++++++++++++++++++++---------------
 1 files changed, 100 insertions(+), 50 deletions(-)

diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c
index c6f9b9a..f2fac5a 100644
--- a/src/drivers/driver_bsd.c
+++ b/src/drivers/driver_bsd.c
@@ -849,9 +849,14 @@ const struct wpa_driver_ops wpa_driver_bsd_ops = {
 
 #else /* HOSTAPD */
 
-struct wpa_driver_bsd_data {
+struct wpa_driver_bsd_global {
 	int	sock;			/* open socket for 802.11 ioctls */
 	int	route;			/* routing socket for events */
+	void 	*global;
+};
+
+struct wpa_driver_bsd_data {
+	struct wpa_driver_bsd_global *global;
 	char	ifname[IFNAMSIZ+1];	/* interface name */
 	unsigned int ifindex;		/* interface index */
 	void	*ctx;
@@ -863,19 +868,19 @@ struct wpa_driver_bsd_data {
 static int
 set80211var(struct wpa_driver_bsd_data *drv, int op, const void *arg, int arg_len)
 {
-	return bsd_set80211var(drv->sock, drv->ifname, op, arg, arg_len);
+	return bsd_set80211var(drv->global->sock, drv->ifname, op, arg, arg_len);
 }
 
 static int
 get80211var(struct wpa_driver_bsd_data *drv, int op, void *arg, int arg_len)
 {
-	return bsd_get80211var(drv->sock, drv->ifname, op, arg, arg_len);
+	return bsd_get80211var(drv->global->sock, drv->ifname, op, arg, arg_len);
 }
 
 static int
 set80211param(struct wpa_driver_bsd_data *drv, int op, int arg)
 {
-	return bsd_set80211param(drv->sock, drv->ifname, op, arg);
+	return bsd_set80211param(drv->global->sock, drv->ifname, op, arg);
 }
 
 static int
@@ -887,7 +892,7 @@ get80211param(struct wpa_driver_bsd_data *drv, int op)
 	os_strlcpy(ireq.i_name, drv->ifname, sizeof(ireq.i_name));
 	ireq.i_type = op;
 
-	if (ioctl(drv->sock, SIOCG80211, &ireq) < 0) {
+	if (ioctl(drv->global->sock, SIOCG80211, &ireq) < 0) {
 		fprintf(stderr, "ioctl[SIOCG80211, op %u]: %s\n",
 			op, strerror(errno));
 		return -1;
@@ -902,7 +907,7 @@ getifflags(struct wpa_driver_bsd_data *drv, int *flags)
 
 	os_memset(&ifr, 0, sizeof(ifr));
 	os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name));
-	if (ioctl(drv->sock, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
+	if (ioctl(drv->global->sock, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
 		perror("SIOCGIFFLAGS");
 		return errno;
 	}
@@ -918,7 +923,7 @@ setifflags(struct wpa_driver_bsd_data *drv, int flags)
 	os_memset(&ifr, 0, sizeof(ifr));
 	os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name));
 	ifr.ifr_flags = flags & 0xffff;
-	if (ioctl(drv->sock, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) {
+	if (ioctl(drv->global->sock, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) {
 		perror("SIOCSIFFLAGS");
 		return errno;
 	}
@@ -933,7 +938,7 @@ wpa_driver_bsd_get_bssid(void *priv, u8 *bssid)
 	struct ieee80211_bssid bs;
 
 	os_strncpy(bs.i_name, drv->ifname, sizeof(bs.i_name));
-	if (ioctl(drv->sock, SIOCG80211BSSID, &bs) < 0)
+	if (ioctl(drv->global->sock, SIOCG80211BSSID, &bs) < 0)
 		return -1;
 	os_memcpy(bssid, bs.i_bssid, sizeof(bs.i_bssid));
 	return 0;
@@ -959,7 +964,7 @@ wpa_driver_bsd_get_ssid(void *priv, u8 *ssid)
 {
 	struct wpa_driver_bsd_data *drv = priv;
 
-	return bsd_get_ssid(drv->sock, drv->ifname, ssid);
+	return bsd_get_ssid(drv->global->sock, drv->ifname, ssid);
 }
 
 static int
@@ -968,7 +973,7 @@ wpa_driver_bsd_set_ssid(void *priv, const u8 *ssid,
 {
 	struct wpa_driver_bsd_data *drv = priv;
 
-	return bsd_set_ssid(drv->sock, drv->ifname, ssid, ssid_len);
+	return bsd_set_ssid(drv->global->sock, drv->ifname, ssid, ssid_len);
 }
 
 static int
@@ -1237,7 +1242,7 @@ wpa_driver_bsd_scan(void *priv, const u8 *ssid, size_t ssid_len)
 static void
 wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
 {
-	struct wpa_driver_bsd_data *drv = sock_ctx;
+	struct wpa_driver_bsd_global *g = sock_ctx;
 	char buf[2048];
 	struct if_announcemsghdr *ifan;
 	struct if_msghdr *ifm;
@@ -1263,13 +1268,13 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
 	switch (rtm->rtm_type) {
 	case RTM_IFANNOUNCE:
 		ifan = (struct if_announcemsghdr *) rtm;
-		if (ifan->ifan_index != drv->ifindex)
-			break;
-		strlcpy(event.interface_status.ifname, drv->ifname,
-			sizeof(event.interface_status.ifname));
 		switch (ifan->ifan_what) {
+		case IFAN_ARRIVAL:
+			event.interface_status.ievent = EVENT_INTERFACE_ADDED;
+			break;
 		case IFAN_DEPARTURE:
 			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
+			break;
 		default:
 			return;
 		}
@@ -1277,22 +1282,27 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
 			   event.interface_status.ifname,
 			   ifan->ifan_what == IFAN_DEPARTURE ?
 				"removed" : "added");
-		wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
+		strlcpy(event.interface_status.ifname, ifan->ifan_name,
+			sizeof(event.interface_status.ifname));
+		wpa_supplicant_event2(g->global, EVENT_INTERFACE_STATUS,
+		    &event);
 		break;
 	case RTM_IEEE80211:
 		ifan = (struct if_announcemsghdr *) rtm;
-		if (ifan->ifan_index != drv->ifindex)
-			break;
+		strlcpy(event.interface_status.ifname, ifan->ifan_name,
+			sizeof(event.interface_status.ifname));
 		switch (ifan->ifan_what) {
 		case RTM_IEEE80211_ASSOC:
 		case RTM_IEEE80211_REASSOC:
-			wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
+			wpa_supplicant_event2(g->global, EVENT_ASSOC, &event);
 			break;
 		case RTM_IEEE80211_DISASSOC:
-			wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL);
+			wpa_supplicant_event2(g->global, EVENT_DISASSOC,
+			    &event);
 			break;
 		case RTM_IEEE80211_SCAN:
-			wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL);
+			wpa_supplicant_event2(g->global, EVENT_SCAN_RESULTS,
+			    &event);
 			break;
 		case RTM_IEEE80211_REPLAY:
 			/* ignore */
@@ -1307,23 +1317,38 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
 			os_memset(&event, 0, sizeof(event));
 			event.michael_mic_failure.unicast =
 				!IEEE80211_IS_MULTICAST(mic->iev_dst);
-			wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE,
-				&event);
+			wpa_supplicant_event2(g->global,
+			    EVENT_MICHAEL_MIC_FAILURE, &event);
 			break;
 		}
 		break;
 	case RTM_IFINFO:
 		ifm = (struct if_msghdr *) rtm;
-		if (ifm->ifm_index != drv->ifindex)
+		if (if_indextoname(ifm->ifm_index,
+				   event.interface_status.ifname) == NULL)
 			break;
-		if ((rtm->rtm_flags & RTF_UP) == 0) {
-			strlcpy(event.interface_status.ifname, drv->ifname,
-				sizeof(event.interface_status.ifname));
+		if ((ifm->ifm_flags & RTF_UP) == 0)
 			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
-			wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN",
-				   event.interface_status.ifname);
-			wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
-		}
+		else
+			event.interface_status.ievent = EVENT_INTERFACE_ADDED;
+		wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' %s",
+		    event.interface_status.ifname,
+		    event.interface_status.ievent == EVENT_INTERFACE_REMOVED ?
+		    "DOWN" : "UP");
+		wpa_supplicant_event2(g->global, EVENT_INTERFACE_STATUS,
+		    &event);
+		break;
+	case RTM_ADD:           /* FALLTHROUGH */
+	case RTM_DELETE:        /* FALLTHROUGH */
+	case RTM_CHANGE:        /* FALLTHROUGH */
+	case RTM_NEWADDR:       /* FALLTHROUGH */
+	case RTM_DELADDR:       /* FALLTHROUGH */
+	case RTM_LOSING:        /* FALLTHROUGH */
+	case RTM_REDIRECT:      /* FALLTHROUGH */
+	case RTM_MISS:          /* FALLTRHOUGH */
+		break;
+	default:
+		wpa_printf(MSG_DEBUG, "RTM_???: %d", rtm->rtm_type);
 		break;
 	}
 }
@@ -1419,7 +1444,7 @@ wpa_driver_bsd_get_scan_results2(void *priv)
 }
 
 static void *
-wpa_driver_bsd_init(void *ctx, const char *ifname)
+wpa_driver_bsd_init2(void *ctx, const char *ifname, void *global_priv)
 {
 #define	GETPARAM(drv, param, v) \
 	(((v) = get80211param(drv, param)) != -1)
@@ -1437,19 +1462,12 @@ wpa_driver_bsd_init(void *ctx, const char *ifname)
 	drv->ifindex = if_nametoindex(ifname);
 	if (drv->ifindex == 0) {
 		wpa_printf(MSG_DEBUG, "%s: interface %s does not exist",
-			   __func__, ifname);
-		goto fail1;
-	}
-	drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
-	if (drv->sock < 0)
-		goto fail1;
-	drv->route = socket(PF_ROUTE, SOCK_RAW, 0);
-	if (drv->route < 0)
+			__func__, ifname);
 		goto fail;
-	eloop_register_read_sock(drv->route,
-		wpa_driver_bsd_event_receive, ctx, drv);
+	}
 
 	drv->ctx = ctx;
+	drv->global = global_priv;
 	os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
 
 	if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) {
@@ -1481,8 +1499,6 @@ wpa_driver_bsd_init(void *ctx, const char *ifname)
 
 	return drv;
 fail:
-	close(drv->sock);
-fail1:
 	os_free(drv);
 	return NULL;
 #undef GETPARAM
@@ -1494,8 +1510,6 @@ wpa_driver_bsd_deinit(void *priv)
 	struct wpa_driver_bsd_data *drv = priv;
 	int flags;
 
-	eloop_unregister_read_sock(drv->route);
-
 	/* NB: mark interface down */
 	if (getifflags(drv, &flags) == 0)
 		(void) setifflags(drv, flags &~ IFF_UP);
@@ -1503,18 +1517,54 @@ wpa_driver_bsd_deinit(void *priv)
 	wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy);
 	if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0)
 		wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state",
-			__func__);
+		    __func__);
 
-	(void) close(drv->route);		/* ioctl socket */
-	(void) close(drv->sock);		/* event socket */
 	os_free(drv);
 }
 
+static void *
+wpa_driver_bsd_global_init(void *priv)
+{
+	struct wpa_driver_bsd_global *global;
+
+	global = os_zalloc(sizeof(*global));
+	global->sock = socket(PF_INET, SOCK_DGRAM, 0);
+	if (global->sock < 0)
+		goto fail1;
+	global->route = socket(PF_ROUTE, SOCK_RAW, 0);
+	if (global->route < 0)
+		goto fail;
+
+	global->global = priv;
+	eloop_register_read_sock(global->route,
+	    wpa_driver_bsd_event_receive, NULL, global);
+	return global;
+
+fail:
+	close(global->sock);
+fail1:
+	os_free(global);
+	return NULL;
+}
+
+static void
+wpa_driver_bsd_global_deinit(void *priv)
+{
+	struct wpa_driver_bsd_global *global = priv;
+
+	eloop_unregister_read_sock(global->route);
+	(void) close(global->route);
+	(void) close(global->sock);
+	os_free(global);
+}
+
 
 const struct wpa_driver_ops wpa_driver_bsd_ops = {
 	.name			= "bsd",
 	.desc			= "BSD 802.11 support",
-	.init			= wpa_driver_bsd_init,
+	.global_init		= wpa_driver_bsd_global_init,
+	.global_deinit		= wpa_driver_bsd_global_deinit,
+	.init2			= wpa_driver_bsd_init2,
 	.deinit			= wpa_driver_bsd_deinit,
 	.get_bssid		= wpa_driver_bsd_get_bssid,
 	.get_ssid		= wpa_driver_bsd_get_ssid,
-- 
1.6.2.5



More information about the HostAP mailing list