[RFC 03/10] nl80211 driver: hold wdev identification for P2P device

Arend van Spriel arend
Mon Feb 11 03:15:40 PST 2013


From: David Spinadel <david.spinadel at intel.com>

Add wdev_id to i802_bss.
Init wdev_id to -1 by default.
Use wdev_id if assigned, instead of ifindex.
Use wdev_id for events that come from the kernel to identify the
relevant interface.

Change-Id: If9f44f688fec1e11c5eda390961199dfd1135a1f
Signed-hostap: David Spinadel <david.spinadel at intel.com>
---
 src/drivers/driver_nl80211.c |   96 ++++++++++++++++++++++++++++++------------
 1 file changed, 70 insertions(+), 26 deletions(-)

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 75d1f22..670eedc 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -189,6 +189,7 @@ struct i802_bss {
 	struct wpa_driver_nl80211_data *drv;
 	struct i802_bss *next;
 	int ifindex;
+	int64_t wdev_id;
 	char ifname[IFNAMSIZ + 1];
 	char brname[IFNAMSIZ];
 	unsigned int beacon_set:1;
@@ -468,6 +469,17 @@ struct family_data {
 	int id;
 };
 
+static int nl80211_set_iface_id(struct nl_msg *msg, struct i802_bss *bss)
+{
+	if (bss->wdev_id != -1)
+		NLA_PUT_U64(msg, NL80211_ATTR_WDEV, bss->wdev_id);
+	else
+		NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
+	return 0;
+
+nla_put_failure:
+	return -1;
+}
 
 static int family_handler(struct nl_msg *msg, void *arg)
 {
@@ -2345,18 +2357,29 @@ static int process_drv_event(struct nl_msg *msg, void *arg)
 	struct nlattr *tb[NL80211_ATTR_MAX + 1];
 	struct i802_bss *bss;
 	int ifidx = -1;
+	int64_t wdev_id = -1;
 
 	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
 		  genlmsg_attrlen(gnlh, 0), NULL);
 
-	if (tb[NL80211_ATTR_IFINDEX])
+	if (tb[NL80211_ATTR_IFINDEX]) {
 		ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
 
-	for (bss = &drv->first_bss; bss; bss = bss->next) {
-		if (ifidx == -1 || ifidx == bss->ifindex) {
-			do_process_drv_event(bss, gnlh->cmd, tb);
-			return NL_SKIP;
-		}
+		for (bss = &drv->first_bss; bss; bss = bss->next)
+			if (ifidx == -1 || ifidx == bss->ifindex) {
+				do_process_drv_event(bss, gnlh->cmd, tb);
+				return NL_SKIP;
+			}
+	} else if (tb[NL80211_ATTR_WDEV]) {
+		wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
+		wpa_printf(MSG_DEBUG, " process event on p2p device");
+		for (bss = &drv->first_bss; bss; bss = bss->next)
+			if (wdev_id == bss->wdev_id) {
+				wpa_printf(MSG_DEBUG,
+					   "nl80211: Ignored event (cmd=%d) for foreign interface (wdev 0x%llx)",
+					   gnlh->cmd, wdev_id);
+				return NL_SKIP;
+			}
 	}
 
 	wpa_printf(MSG_DEBUG, "nl80211: Ignored event (cmd=%d) for foreign "
@@ -2374,20 +2397,24 @@ static int process_global_event(struct nl_msg *msg, void *arg)
 	struct wpa_driver_nl80211_data *drv, *tmp;
 	int ifidx = -1;
 	struct i802_bss *bss;
+	int64_t wdev_id = -1;
 
 	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
 		  genlmsg_attrlen(gnlh, 0), NULL);
 
 	if (tb[NL80211_ATTR_IFINDEX])
 		ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
+	else if (tb[NL80211_ATTR_WDEV])
+		wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
 
 	dl_list_for_each_safe(drv, tmp, &global->interfaces,
 			      struct wpa_driver_nl80211_data, list) {
 		for (bss = &drv->first_bss; bss; bss = bss->next) {
-			if (ifidx == -1 || ifidx == bss->ifindex) {
+			if ((ifidx == -1 && wdev_id == -1) ||
+			    ifidx == bss->ifindex ||
+			    (wdev_id != -1 && wdev_id == bss->wdev_id))
 				do_process_drv_event(bss, gnlh->cmd, tb);
 				return NL_SKIP;
-			}
 		}
 	}
 
@@ -3131,6 +3158,7 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
 	bss = &drv->first_bss;
 	bss->drv = drv;
 	bss->ctx = ctx;
+	bss->wdev_id = -1;
 
 	os_strlcpy(bss->ifname, ifname, sizeof(bss->ifname));
 	drv->monitor_ifidx = -1;
@@ -3218,7 +3246,9 @@ static int nl80211_register_frame(struct i802_bss *bss,
 
 	nl80211_cmd(drv, msg, 0, NL80211_CMD_REGISTER_ACTION);
 
-	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
+	if (nl80211_set_iface_id(msg, bss))
+		goto nla_put_failure;
+
 	NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE, type);
 	NLA_PUT(msg, NL80211_ATTR_FRAME_MATCH, match_len, match);
 
@@ -3636,10 +3666,10 @@ static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
 
 static struct nl_msg *
 nl80211_scan_common(struct wpa_driver_nl80211_data *drv, u8 cmd,
-		    struct wpa_driver_scan_params *params)
+		    struct wpa_driver_scan_params *params, int64_t wdev_id)
 {
 	struct nl_msg *msg;
-	int err;
+	int err = 0;
 	size_t i;
 
 	msg = nlmsg_alloc();
@@ -3648,13 +3678,18 @@ nl80211_scan_common(struct wpa_driver_nl80211_data *drv, u8 cmd,
 
 	nl80211_cmd(drv, msg, 0, cmd);
 
-	if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, drv->ifindex) < 0)
-		goto fail;
+	if (wdev_id == -1) {
+		err = nla_put_u32(msg, NL80211_ATTR_IFINDEX, drv->ifindex) < 0;
+		if (err)
+			goto nla_put_failure;
+	} else {
+		NLA_PUT_U64(msg, NL80211_ATTR_WDEV, wdev_id);
+	}
 
 	if (params->num_ssids) {
 		struct nl_msg *ssids = nlmsg_alloc();
 		if (ssids == NULL)
-			goto fail;
+			goto nla_put_failure;
 		for (i = 0; i < params->num_ssids; i++) {
 			wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Scan SSID",
 					  params->ssids[i].ssid,
@@ -3662,13 +3697,13 @@ nl80211_scan_common(struct wpa_driver_nl80211_data *drv, u8 cmd,
 			if (nla_put(ssids, i + 1, params->ssids[i].ssid_len,
 				    params->ssids[i].ssid) < 0) {
 				nlmsg_free(ssids);
-				goto fail;
+				goto nla_put_failure;
 			}
 		}
 		err = nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);
 		nlmsg_free(ssids);
 		if (err < 0)
-			goto fail;
+			goto nla_put_failure;
 	}
 
 	if (params->extra_ies) {
@@ -3676,26 +3711,26 @@ nl80211_scan_common(struct wpa_driver_nl80211_data *drv, u8 cmd,
 			    params->extra_ies, params->extra_ies_len);
 		if (nla_put(msg, NL80211_ATTR_IE, params->extra_ies_len,
 			    params->extra_ies) < 0)
-			goto fail;
+			goto nla_put_failure;
 	}
 
 	if (params->freqs) {
 		struct nl_msg *freqs = nlmsg_alloc();
 		if (freqs == NULL)
-			goto fail;
+			goto nla_put_failure;
 		for (i = 0; params->freqs[i]; i++) {
 			wpa_printf(MSG_MSGDUMP, "nl80211: Scan frequency %u "
 				   "MHz", params->freqs[i]);
 			if (nla_put_u32(freqs, i + 1, params->freqs[i]) < 0) {
 				nlmsg_free(freqs);
-				goto fail;
+				goto nla_put_failure;
 			}
 		}
 		err = nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES,
 				     freqs);
 		nlmsg_free(freqs);
 		if (err < 0)
-			goto fail;
+			goto nla_put_failure;
 	}
 
 	os_free(drv->filter_ssids);
@@ -3705,7 +3740,7 @@ nl80211_scan_common(struct wpa_driver_nl80211_data *drv, u8 cmd,
 
 	return msg;
 
-fail:
+nla_put_failure:
 	nlmsg_free(msg);
 	return NULL;
 }
@@ -3726,7 +3761,8 @@ static int wpa_driver_nl80211_scan(struct i802_bss *bss,
 
 	drv->scan_for_auth = 0;
 
-	msg = nl80211_scan_common(drv, NL80211_CMD_TRIGGER_SCAN, params);
+	msg = nl80211_scan_common(drv, NL80211_CMD_TRIGGER_SCAN, params,
+				  bss->wdev_id);
 	if (!msg)
 		return -1;
 
@@ -3830,7 +3866,8 @@ static int wpa_driver_nl80211_sched_scan(void *priv,
 		return android_pno_start(bss, params);
 #endif /* ANDROID */
 
-	msg = nl80211_scan_common(drv, NL80211_CMD_START_SCHED_SCAN, params);
+	msg = nl80211_scan_common(drv, NL80211_CMD_START_SCHED_SCAN, params,
+				  bss->wdev_id);
 	if (!msg)
 		goto nla_put_failure;
 
@@ -8224,6 +8261,7 @@ static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
 		os_strlcpy(new_bss->ifname, ifname, IFNAMSIZ);
 		os_memcpy(new_bss->addr, if_addr, ETH_ALEN);
 		new_bss->ifindex = ifidx;
+		new_bss->wdev_id = -1;
 		new_bss->drv = drv;
 		new_bss->next = drv->first_bss.next;
 		new_bss->freq = drv->first_bss.freq;
@@ -8335,7 +8373,9 @@ static int nl80211_send_frame_cmd(struct i802_bss *bss,
 		   freq, wait, no_cck, no_ack, offchanok);
 	nl80211_cmd(drv, msg, 0, NL80211_CMD_FRAME);
 
-	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
+	if (nl80211_set_iface_id(msg, bss))
+		goto nla_put_failure;
+
 	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
 	if (wait)
 		NLA_PUT_U32(msg, NL80211_ATTR_DURATION, wait);
@@ -8455,7 +8495,9 @@ static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq,
 
 	nl80211_cmd(drv, msg, 0, NL80211_CMD_REMAIN_ON_CHANNEL);
 
-	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+	if (nl80211_set_iface_id(msg, bss))
+		goto nla_put_failure;
+
 	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
 	NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration);
 
@@ -8502,7 +8544,9 @@ static int wpa_driver_nl80211_cancel_remain_on_channel(void *priv)
 
 	nl80211_cmd(drv, msg, 0, NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL);
 
-	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+	if (nl80211_set_iface_id(msg, bss))
+		goto nla_put_failure;
+
 	NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, drv->remain_on_chan_cookie);
 
 	ret = send_and_recv_msgs(drv, msg, NULL, NULL);
-- 
1.7.10.4





More information about the Hostap mailing list