[PATCH 1/6] nl80211: Share a common netlink object.

greearb at candelatech.com greearb
Wed Oct 19 12:20:14 PDT 2011


From: Ben Greear <greearb at candelatech.com>

This decreases load and spurious messages when running
lots of VIFs.

Signed-off-by: Ben Greear <greearb at candelatech.com>
---
:100644 100644 5693f59... 7ebcf37... M	src/drivers/driver_nl80211.c
 src/drivers/driver_nl80211.c |   81 +++++++++++++++++++++++++++++-------------
 1 files changed, 56 insertions(+), 25 deletions(-)

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 5693f59..7ebcf37 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -107,6 +107,7 @@ static void nl80211_handle_destroy(struct nl_handle *handle)
 struct nl80211_global {
 	struct dl_list interfaces;
 	int if_add_ifindex;
+	struct netlink_data *netlink;
 };
 
 struct i802_bss {
@@ -126,7 +127,6 @@ struct wpa_driver_nl80211_data {
 	u8 addr[ETH_ALEN];
 	char phyname[32];
 	void *ctx;
-	struct netlink_data *netlink;
 	int ioctl_sock; /* socket for ioctl() use */
 	int ifindex;
 	int if_removed;
@@ -488,13 +488,23 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
 						 struct ifinfomsg *ifi,
 						 u8 *buf, size_t len)
 {
-	struct wpa_driver_nl80211_data *drv = ctx;
+	struct nl80211_global *global = ctx;
+	struct wpa_driver_nl80211_data *drvtmp;
+	struct wpa_driver_nl80211_data *drv = NULL;
 	int attrlen, rta_len;
 	struct rtattr *attr;
 	u32 brid = 0;
 
-	if (!wpa_driver_nl80211_own_ifindex(drv, ifi->ifi_index, buf, len) &&
-	    !have_ifidx(drv, ifi->ifi_index)) {
+	dl_list_for_each(drvtmp, &global->interfaces,
+			 struct wpa_driver_nl80211_data, list) {
+		if (wpa_driver_nl80211_own_ifindex(drvtmp, ifi->ifi_index, buf, len) ||
+		    have_ifidx(drvtmp, ifi->ifi_index)) {
+			drv = drvtmp;
+			break;
+		}
+	}
+
+	if (!drv) {
 		wpa_printf(MSG_DEBUG, "nl80211: Ignore event for foreign "
 			   "ifindex %d", ifi->ifi_index);
 		return;
@@ -536,7 +546,7 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
 	if (drv->operstate == 1 &&
 	    (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
 	    !(ifi->ifi_flags & IFF_RUNNING))
-		netlink_send_oper_ifla(drv->netlink, drv->ifindex,
+		netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
 				       -1, IF_OPER_UP);
 
 	attrlen = len;
@@ -570,14 +580,31 @@ static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
 						 struct ifinfomsg *ifi,
 						 u8 *buf, size_t len)
 {
-	struct wpa_driver_nl80211_data *drv = ctx;
+	struct nl80211_global *global = ctx;
 	int attrlen, rta_len;
 	struct rtattr *attr;
 	u32 brid = 0;
+	struct wpa_driver_nl80211_data *drvtmp;
+	struct wpa_driver_nl80211_data *drv = NULL;
+
+	dl_list_for_each(drvtmp, &global->interfaces,
+			 struct wpa_driver_nl80211_data, list) {
+		if (wpa_driver_nl80211_own_ifindex(drvtmp, ifi->ifi_index, buf, len) ||
+		    have_ifidx(drvtmp, ifi->ifi_index)) {
+			drv = drvtmp;
+			break;
+		}
+	}
 
 	attrlen = len;
 	attr = (struct rtattr *) buf;
 
+	if (!drv) {
+		wpa_printf(MSG_DEBUG, "nl80211: Ignore dellink event for"
+			   " foreign ifindex %d", ifi->ifi_index);
+		return;
+	}
+
 	rta_len = RTA_ALIGN(sizeof(struct rtattr));
 	while (RTA_OK(attr, attrlen)) {
 		if (attr->rta_type == IFLA_IFNAME) {
@@ -2142,7 +2169,6 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
 				      void *global_priv)
 {
 	struct wpa_driver_nl80211_data *drv;
-	struct netlink_config *cfg;
 	struct rfkill_config *rcfg;
 	struct i802_bss *bss;
 
@@ -2172,18 +2198,6 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
 		goto failed;
 	}
 
-	cfg = os_zalloc(sizeof(*cfg));
-	if (cfg == NULL)
-		goto failed;
-	cfg->ctx = drv;
-	cfg->newlink_cb = wpa_driver_nl80211_event_rtm_newlink;
-	cfg->dellink_cb = wpa_driver_nl80211_event_rtm_dellink;
-	drv->netlink = netlink_init(cfg);
-	if (drv->netlink == NULL) {
-		os_free(cfg);
-		goto failed;
-	}
-
 	rcfg = os_zalloc(sizeof(*rcfg));
 	if (rcfg == NULL)
 		goto failed;
@@ -2212,7 +2226,6 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
 
 failed:
 	rfkill_deinit(drv->rfkill);
-	netlink_deinit(drv->netlink);
 	if (drv->ioctl_sock >= 0)
 		close(drv->ioctl_sock);
 
@@ -2362,7 +2375,7 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
 		}
 	}
 
-	netlink_send_oper_ifla(drv->netlink, drv->ifindex,
+	netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
 			       1, IF_OPER_DORMANT);
 #endif /* HOSTAPD */
 
@@ -2468,8 +2481,7 @@ static void wpa_driver_nl80211_deinit(void *priv)
 	if (drv->disable_11b_rates)
 		nl80211_disable_11b_rates(drv, drv->ifindex, 0);
 
-	netlink_send_oper_ifla(drv->netlink, drv->ifindex, 0, IF_OPER_UP);
-	netlink_deinit(drv->netlink);
+	netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, 0, IF_OPER_UP);
 	rfkill_deinit(drv->rfkill);
 
 	eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
@@ -5781,7 +5793,7 @@ static int wpa_driver_nl80211_set_operstate(void *priv, int state)
 	wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)",
 		   __func__, drv->operstate, state, state ? "UP" : "DORMANT");
 	drv->operstate = state;
-	return netlink_send_oper_ifla(drv->netlink, drv->ifindex, -1,
+	return netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, -1,
 				      state ? IF_OPER_UP : IF_OPER_DORMANT);
 }
 
@@ -6484,7 +6496,6 @@ static void *i802_init(struct hostapd_data *hapd,
 failed:
 	nl80211_remove_monitor_interface(drv);
 	rfkill_deinit(drv->rfkill);
-	netlink_deinit(drv->netlink);
 	if (drv->ioctl_sock >= 0)
 		close(drv->ioctl_sock);
 
@@ -7214,11 +7225,29 @@ static int nl80211_set_param(void *priv, const char *param)
 static void * nl80211_global_init(void)
 {
 	struct nl80211_global *global;
+	struct netlink_config *cfg;
+
 	global = os_zalloc(sizeof(*global));
 	if (global == NULL)
 		return NULL;
 	dl_list_init(&global->interfaces);
 	global->if_add_ifindex = -1;
+
+	cfg = os_zalloc(sizeof(*cfg));
+	if (cfg == NULL) {
+		os_free(global);
+		return NULL;
+	}
+	cfg->ctx = global;
+	cfg->newlink_cb = wpa_driver_nl80211_event_rtm_newlink;
+	cfg->dellink_cb = wpa_driver_nl80211_event_rtm_dellink;
+	global->netlink = netlink_init(cfg);
+	if (global->netlink == NULL) {
+		os_free(cfg);
+		os_free(global);
+		return NULL;
+	}
+
 	return global;
 }
 
@@ -7233,6 +7262,8 @@ static void nl80211_global_deinit(void *priv)
 			   "nl80211_global_deinit",
 			   dl_list_len(&global->interfaces));
 	}
+	if (global->netlink)
+		netlink_deinit(global->netlink);
 	os_free(global);
 }
 
-- 
1.7.3.4




More information about the Hostap mailing list