[RFC 11/13] nl80211: Use one global ioctl socket.

greearb at candelatech.com greearb
Fri Oct 14 15:34:35 PDT 2011


From: Ben Greear <greearb at candelatech.com>

Saves lots of sockets when using multiple VIFS in a single
wpa_supplicant instance.

Signed-off-by: Ben Greear <greearb at candelatech.com>
---
:100644 100644 1dd7a40... 3266ffc... M	src/drivers/driver_nl80211.c
 src/drivers/driver_nl80211.c |   94 ++++++++++++++++++++++--------------------
 1 files changed, 49 insertions(+), 45 deletions(-)

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 1dd7a40..3266ffc 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -130,7 +130,7 @@ struct nl80211_global {
 	struct nl_cache *nl_cache_preq;
 	struct nl_cb *nl_cb;
 	struct genl_family *nl80211;
-
+	int ioctl_sock; /* socket for ioctl() use */
 };
 
 static struct nl80211_global* global_ptr = NULL;
@@ -155,7 +155,6 @@ struct wpa_driver_nl80211_data {
 	u8 addr[ETH_ALEN];
 	char phyname[32];
 	void *ctx;
-	int ioctl_sock; /* socket for ioctl() use */
 	int ifindex;
 	int if_removed;
 	int if_disabled;
@@ -1995,7 +1994,8 @@ static void wpa_driver_nl80211_rfkill_unblocked(void *ctx)
 {
 	struct wpa_driver_nl80211_data *drv = ctx;
 	wpa_msg(drv->ctx, MSG_DEBUG, "nl80211: RFKILL unblocked");
-	if (linux_set_iface_flags(drv->ioctl_sock, drv->first_bss.ifname, 1)) {
+	if (linux_set_iface_flags(drv->global->ioctl_sock,
+				  drv->first_bss.ifname, 1)) {
 		wpa_msg(drv->ctx, MSG_DEBUG, "nl80211: Could not set interface UP "
 			"after rfkill unblock");
 		return;
@@ -2090,14 +2090,14 @@ static void wpa_driver_nl80211_deinit(void *priv)
 		wpa_driver_nl80211_probe_req_report(bss, 0);
 
 	if (bss->added_if_into_bridge) {
-		if (linux_br_del_if(drv->ioctl_sock, bss->brname, bss->ifname)
+		if (linux_br_del_if(drv->global->ioctl_sock, bss->brname, bss->ifname)
 		    < 0)
 			wpa_msg(drv->ctx, MSG_INFO, "nl80211: Failed to remove "
 				"interface %s from bridge %s: %s",
 				bss->ifname, bss->brname, strerror(errno));
 	}
 	if (bss->added_bridge) {
-		if (linux_br_del(drv->ioctl_sock, bss->brname) < 0)
+		if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
 			wpa_msg(drv->ctx, MSG_INFO, "nl80211: Failed to remove "
 				"bridge %s: %s",
 				bss->brname, strerror(errno));
@@ -2135,12 +2135,9 @@ static void wpa_driver_nl80211_deinit(void *priv)
 
 	eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
 
-	(void) linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0);
+	linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0);
 	wpa_driver_nl80211_set_mode(bss, NL80211_IFTYPE_STATION);
 
-	if (drv->ioctl_sock >= 0)
-		close(drv->ioctl_sock);
-
 	os_free(drv->filter_ssids);
 
 	if (drv->global)
@@ -2177,17 +2174,10 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
 	os_strlcpy(bss->ifname, ifname, sizeof(bss->ifname));
 	drv->monitor_ifidx = -1;
 	drv->monitor_sock = -1;
-	drv->ioctl_sock = -1;
 	drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
 
 	nl80211_get_phy_name(drv);
 
-	drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
-	if (drv->ioctl_sock < 0) {
-		perror("socket(PF_INET,SOCK_DGRAM)");
-		goto failed;
-	}
-
 	rcfg = os_zalloc(sizeof(*rcfg));
 	if (rcfg == NULL)
 		goto failed;
@@ -2336,7 +2326,7 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
 			"use managed mode");
 	}
 
-	if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1)) {
+	if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1)) {
 		if (rfkill_is_blocked(drv->rfkill)) {
 			wpa_msg(drv->ctx, MSG_DEBUG, "nl80211: Could not yet enable "
 				"interface '%s' due to rfkill",
@@ -2357,7 +2347,7 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
 	if (wpa_driver_nl80211_capa(drv))
 		return -1;
 
-	if (linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, drv->addr))
+	if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname, drv->addr))
 		return -1;
 
 	if (nl80211_register_action_frames(drv) < 0) {
@@ -4291,7 +4281,7 @@ static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
 #endif /* HOSTAPD */
 
 	if (addr && iftype != NL80211_IFTYPE_MONITOR &&
-	    linux_set_ifhwaddr(drv->ioctl_sock, ifname, addr)) {
+	    linux_set_ifhwaddr(drv->global->ioctl_sock, ifname, addr)) {
 		nl80211_remove_iface(drv, ifidx);
 		return -1;
 	}
@@ -4647,7 +4637,7 @@ nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv)
 	if (drv->monitor_ifidx < 0)
 		return -1;
 
-	if (linux_set_iface_flags(drv->ioctl_sock, buf, 1))
+	if (linux_set_iface_flags(drv->global->ioctl_sock, buf, 1))
 		goto error;
 
 	memset(&ll, 0, sizeof(ll));
@@ -5393,13 +5383,13 @@ static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
 	wpa_msg(drv->ctx, MSG_DEBUG, "nl80211: Try mode change after setting "
 		"interface down");
 	for (i = 0; i < 10; i++) {
-		if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0) ==
-		    0) {
+		if (linux_set_iface_flags(drv->global->ioctl_sock,
+					  bss->ifname, 0) == 0) {
 			/* Try to set the mode again while the interface is
 			 * down */
 			ret = nl80211_set_mode(drv, drv->ifindex, nlmode);
-			if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname,
-						  1))
+			if (linux_set_iface_flags(drv->global->ioctl_sock,
+						  bss->ifname, 1))
 				ret = -1;
 			if (!ret)
 				break;
@@ -6051,11 +6041,11 @@ static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
 						 NULL, 1) < 0)
 				return -1;
 			if (bridge_ifname &&
-			    linux_br_add_if(drv->ioctl_sock, bridge_ifname,
-					    name) < 0)
+			    linux_br_add_if(drv->global->ioctl_sock,
+					    bridge_ifname, name) < 0)
 				return -1;
 		}
-		linux_set_iface_flags(drv->ioctl_sock, name, 1);
+		linux_set_iface_flags(drv->global->ioctl_sock, name, 1);
 		return i802_set_sta_vlan(priv, addr, name, 0);
 	} else {
 		i802_set_sta_vlan(priv, addr, bss->ifname, 0);
@@ -6099,7 +6089,7 @@ static int i802_check_bridge(struct wpa_driver_nl80211_data *drv,
 		 * Bridge was configured, but the bridge device does
 		 * not exist. Try to add it now.
 		 */
-		if (linux_br_add(drv->ioctl_sock, brname) < 0) {
+		if (linux_br_add(drv->global->ioctl_sock, brname) < 0) {
 			wpa_msg(drv->ctx, MSG_ERROR, "nl80211: Failed to add the "
 				"bridge interface %s: %s",
 				brname, strerror(errno));
@@ -6115,7 +6105,8 @@ static int i802_check_bridge(struct wpa_driver_nl80211_data *drv,
 
 		wpa_msg(drv->ctx, MSG_DEBUG, "nl80211: Removing interface %s from "
 			"bridge %s", ifname, in_br);
-		if (linux_br_del_if(drv->ioctl_sock, in_br, ifname) < 0) {
+		if (linux_br_del_if(drv->global->ioctl_sock, in_br,
+				    ifname) < 0) {
 			wpa_msg(drv->ctx, MSG_ERROR, "nl80211: Failed to "
 				"remove interface %s from bridge "
 				"%s: %s",
@@ -6126,7 +6117,7 @@ static int i802_check_bridge(struct wpa_driver_nl80211_data *drv,
 
 	wpa_msg(drv->ctx, MSG_DEBUG, "nl80211: Adding interface %s into bridge %s",
 		ifname, brname);
-	if (linux_br_add_if(drv->ioctl_sock, brname, ifname) < 0) {
+	if (linux_br_add_if(drv->global->ioctl_sock, brname, ifname) < 0) {
 		wpa_msg(drv->ctx, MSG_ERROR, "nl80211: Failed to add interface %s "
 			"into bridge %s: %s",
 			ifname, brname, strerror(errno));
@@ -6183,11 +6174,11 @@ static void *i802_init(struct hostapd_data *hapd,
 	/* start listening for EAPOL on the default AP interface */
 	add_ifidx(drv, drv->ifindex);
 
-	if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0))
+	if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0))
 		goto failed;
 
 	if (params->bssid) {
-		if (linux_set_ifhwaddr(drv->ioctl_sock, bss->ifname,
+		if (linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
 				       params->bssid))
 			goto failed;
 	}
@@ -6203,7 +6194,7 @@ static void *i802_init(struct hostapd_data *hapd,
 	    i802_check_bridge(drv, bss, params->bridge[0], params->ifname) < 0)
 		goto failed;
 
-	if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1))
+	if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1))
 		goto failed;
 
 	drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
@@ -6218,7 +6209,8 @@ static void *i802_init(struct hostapd_data *hapd,
 		goto failed;
 	}
 
-	if (linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, params->own_addr))
+	if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
+			       params->own_addr))
 		goto failed;
 
 	return bss;
@@ -6330,7 +6322,8 @@ static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
 	}
 
 	if (!addr &&
-	    linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, if_addr) < 0) {
+	    linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
+			       if_addr) < 0) {
 		nl80211_remove_iface(drv, ifidx);
 		return -1;
 	}
@@ -6342,10 +6335,10 @@ static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
 		/* Enforce unique P2P Interface Address */
 		u8 new_addr[ETH_ALEN], own_addr[ETH_ALEN];
 
-		if (linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, own_addr)
-		    < 0 ||
-		    linux_get_ifhwaddr(drv->ioctl_sock, ifname, new_addr) < 0)
-		{
+		if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
+				       own_addr) < 0 ||
+		    linux_get_ifhwaddr(drv->global->ioctl_sock, ifname,
+				       new_addr) < 0) {
 			nl80211_remove_iface(drv, ifidx);
 			return -1;
 		}
@@ -6356,7 +6349,7 @@ static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
 				nl80211_remove_iface(drv, ifidx);
 				return -1;
 			}
-			if (linux_set_ifhwaddr(drv->ioctl_sock, ifname,
+			if (linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
 					       new_addr) < 0) {
 				nl80211_remove_iface(drv, ifidx);
 				return -1;
@@ -6378,7 +6371,7 @@ static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
 	}
 
 	if (type == WPA_IF_AP_BSS) {
-		if (linux_set_iface_flags(drv->ioctl_sock, ifname, 1)) {
+		if (linux_set_iface_flags(drv->global->ioctl_sock, ifname, 1)) {
 			nl80211_remove_iface(drv, ifidx);
 			os_free(new_bss);
 			return -1;
@@ -6415,14 +6408,14 @@ static int wpa_driver_nl80211_if_remove(void *priv,
 
 #ifdef HOSTAPD
 	if (bss->added_if_into_bridge) {
-		if (linux_br_del_if(drv->ioctl_sock, bss->brname, bss->ifname)
+		if (linux_br_del_if(drv->global->ioctl_sock, bss->brname, bss->ifname)
 		    < 0)
 			wpa_msg(drv->ctx, MSG_INFO, "nl80211: Failed to remove "
 				"interface %s from bridge %s: %s",
 				bss->ifname, bss->brname, strerror(errno));
 	}
 	if (bss->added_bridge) {
-		if (linux_br_del(drv->ioctl_sock, bss->brname) < 0)
+		if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
 			wpa_msg(drv->ctx, MSG_INFO, "nl80211: Failed to remove "
 				"bridge %s: %s",
 				bss->brname, strerror(errno));
@@ -6823,7 +6816,7 @@ static void wpa_driver_nl80211_resume(void *priv)
 {
 	struct i802_bss *bss = priv;
 	struct wpa_driver_nl80211_data *drv = bss->drv;
-	if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1)) {
+	if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1)) {
 		wpa_msg(drv->ctx, MSG_DEBUG, "nl80211: Failed to set interface up on "
 			"resume event");
 	}
@@ -6840,7 +6833,8 @@ static int nl80211_send_ft_action(void *priv, u8 action, const u8 *target_ap,
 	size_t data_len;
 	u8 own_addr[ETH_ALEN];
 
-	if (linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, own_addr) < 0)
+	if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
+			       own_addr) < 0)
 		return -1;
 
 	if (action != 1) {
@@ -7015,6 +7009,9 @@ static void nl80211_global_deinit(void *priv)
 	if (global->nl80211)
 		genl_family_put(global->nl80211);
 
+	if (global->ioctl_sock >= 0)
+		close(global->ioctl_sock);
+
 	if (global == global_ptr)
 		global_ptr = NULL;
 
@@ -7036,6 +7033,7 @@ static void * nl80211_global_init(void)
 	if (global == NULL)
 		return NULL;
 	global->struct_id = HAP_DRV_NL80211_GLOBAL;
+	global->ioctl_sock = -1;
 	dl_list_init(&global->interfaces);
 	global->if_add_ifindex = -1;
 
@@ -7149,6 +7147,12 @@ static void * nl80211_global_init(void)
 		/* Continue without regulatory events */
 	}
 
+	global->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
+	if (global->ioctl_sock < 0) {
+		perror("socket(PF_INET,SOCK_DGRAM)");
+		goto err;
+	}
+
 	eloop_register_read_sock(nl_socket_get_fd(global->nl_handle_event),
 				 wpa_driver_nl80211_event_receive, global,
 				 global->nl_handle_event);
-- 
1.7.3.4




More information about the Hostap mailing list