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

login
register
mail settings
Submitter Arend van Spriel
Date Feb. 11, 2013, 11:15 a.m.
Message ID <1360581347-26766-4-git-send-email-arend@broadcom.com>
Download mbox | patch
Permalink /patch/219582/
State Superseded
Headers show

Comments

Arend van Spriel - Feb. 11, 2013, 11:15 a.m.
From: David Spinadel <david.spinadel@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@intel.com>
---
 src/drivers/driver_nl80211.c |   96 ++++++++++++++++++++++++++++++------------
 1 file changed, 70 insertions(+), 26 deletions(-)
Arend van Spriel - Feb. 11, 2013, 11:32 a.m.
On 02/11/2013 12:15 PM, Arend van Spriel wrote:
> From: David Spinadel <david.spinadel@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@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
> @@ -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);

This one causes a warning on 64-bit machines:

../src/drivers/driver_nl80211.c: In function ‘process_drv_event’:
../src/drivers/driver_nl80211.c:2381:9: warning: format ‘%llx’ expects
argument of type ‘long long unsigned int’, but argument 4 has type
‘int64_t’ [-Wformat]

> +				return NL_SKIP;
> +			}
>  	}
>  
>  	wpa_printf(MSG_DEBUG, "nl80211: Ignored event (cmd=%d) for foreign "
> @@ -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);
> +	}

Seems like you could use nl80211_set_iface_id() here as well. Maybe I am
overlooking something.

>  
>  	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,
Spinadel, David - Feb. 13, 2013, 6:15 a.m.
> 
> This one causes a warning on 64-bit machines:
> 
> ../src/drivers/driver_nl80211.c: In function 'process_drv_event':
> ../src/drivers/driver_nl80211.c:2381:9: warning: format '%llx' expects
> argument of type 'long long unsigned int', but argument 4 has type 'int64_t'
> [-Wformat]
> 
Well, I'll change the include to inttypes.h instead of /sys/types.h, and use PRIx64.
Thanks.
David 

---------------------------------------------------------------------
A member of the Intel Corporation group of companies

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
Spinadel, David - Feb. 14, 2013, 8:30 a.m.
> > +	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);
> > +	}
> 
> Seems like you could use nl80211_set_iface_id() here as well. Maybe I am
> overlooking something.
> 
I cannot use it here since we have no i802_bss here. This wdev_id is coming from wpa_driver_nl8021_scan(). Common scan is done here on the driver, not on the interface. Maybe it worth to fix?
David  

---------------------------------------------------------------------
A member of the Intel Corporation group of companies

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
Arend van Spriel - Feb. 14, 2013, 9:50 a.m.
Sent: Thursday, February 14, 2013 9:30 AM

> > +   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);
> > +   }
>
> Seems like you could use nl80211_set_iface_id() here as well. Maybe I am
> overlooking something.
>
I cannot use it here since we have no i802_bss here. This wdev_id is coming from wpa_driver_nl8021_scan(). Common scan is done here on the driver, not on the interface. Maybe it worth to fix?
David

A: I overlooked that. Does fixing it mean other drivers need to be modified as well?

Regards,
Arend

Patch

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);