[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