[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