Patchwork [03/20] driver: nl80211: hold wdev identification for P2P device

login
register
mail settings
Submitter Arend van Spriel
Date May 16, 2013, 1:28 p.m.
Message ID <1368710915-32176-4-git-send-email-arend@broadcom.com>
Download mbox | patch
Permalink /patch/244317/
State Changes Requested
Headers show

Comments

Arend van Spriel - May 16, 2013, 1:28 p.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.

Signed-off-by: David Spinadel <david.spinadel@intel.com>
---
 src/drivers/driver_nl80211.c |   84 ++++++++++++++++++++++++++++++++----------
 1 file changed, 64 insertions(+), 20 deletions(-)
Ilan Peer - May 19, 2013, 6:13 p.m.
> -----Original Message-----
> From: hostap-bounces@lists.shmoo.com [mailto:hostap-
> bounces@lists.shmoo.com] On Behalf Of Arend van Spriel
> Sent: Thursday, May 16, 2013 16:28
> To: Jouni Malinen
> Cc: hostap@lists.shmoo.com
> Subject: [PATCH 03/20] driver: nl80211: hold wdev identification for P2P device
> 

The title of the patch might be a bit misleading :)

> 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.
> 
> Signed-off-by: David Spinadel <david.spinadel@intel.com>
> ---
>  src/drivers/driver_nl80211.c |   84 ++++++++++++++++++++++++++++++++------
> ----
>  1 file changed, 64 insertions(+), 20 deletions(-)
> 
> diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index
> b304ddd..ec877f2 100644
> --- a/src/drivers/driver_nl80211.c
> +++ b/src/drivers/driver_nl80211.c
> @@ -12,7 +12,7 @@
> 
>  #include "includes.h"
>  #include <sys/ioctl.h>
> -#include <sys/types.h>
> +#include <inttypes.h>
>  #include <sys/stat.h>
>  #include <fcntl.h>
>  #include <net/if.h>
> @@ -183,6 +183,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;
> @@ -464,6 +465,17 @@ struct family_data {
>  	int id;
>  };
> 
> +static int nl80211_set_iface_id(struct nl_msg *msg, struct i802_bss
> +*bss) {

It is possible to always add both attributes (and this can actually be done for all the nl commands ...). The kernel should be able to handle this.

> +	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)  { @@ -2434,23
> +2446,35 @@ 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]);
> 

It might be better to get both IFINDEX and WDEV id, and then have only a single iteration and do similar processing as in process_global_event(). Otherwise, you might miss a case where the ifindex is -1 but a bss with a valid wdev_id is not the first in the list

> -	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;
> +			}
> +		wpa_printf(MSG_DEBUG,
> +			   "nl80211: Ignored event (cmd=%d) for foreign
> interface (ifindex %d)",
> +			   gnlh->cmd, ifidx);
> +	} 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) {
> +				do_process_drv_event(bss, gnlh->cmd, tb);
> +				return NL_SKIP;
> +			}
> +		wpa_printf(MSG_DEBUG,
> +			   "nl80211: Ignored event (cmd=%d) for foreign
> interface (wdev 0x%"
> +			   PRIx64 ")", gnlh->cmd, wdev_id);
>  	}
> 
> -	wpa_printf(MSG_DEBUG, "nl80211: Ignored event (cmd=%d) for
> foreign "
> -		   "interface (ifindex %d)", gnlh->cmd, ifidx);
> -
>  	return NL_SKIP;
>  }
> 
> @@ -2463,17 +2487,22 @@ 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;
>  			}
> @@ -3349,6 +3378,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;
> @@ -3436,7 +3466,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);
> 
> @@ -3856,7 +3888,7 @@ 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;
>  	size_t i;
> @@ -3867,8 +3899,10 @@ 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)
> +		NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
> +	else
> +		NLA_PUT_U64(msg, NL80211_ATTR_WDEV, wdev_id);
> 
>  	if (params->num_ssids) {
>  		struct nlattr *ssids;
> @@ -3917,6 +3951,7 @@ nl80211_scan_common(struct
> wpa_driver_nl80211_data *drv, u8 cmd,
>  	return msg;
> 
>  fail:
> +nla_put_failure:
>  	nlmsg_free(msg);
>  	return NULL;
>  }
> @@ -3938,7 +3973,8 @@ static int wpa_driver_nl80211_scan(struct i802_bss
> *bss,
>  	wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request");
>  	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;
> 
> @@ -4041,7 +4077,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;
> 
> @@ -8585,6 +8622,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;
> @@ -8696,7 +8734,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); @@ -
> 8818,7 +8858,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);
> 
> @@ -8865,7 +8907,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
> 
> 
> _______________________________________________
> HostAP mailing list
> HostAP@lists.shmoo.com
> http://lists.shmoo.com/mailman/listinfo/hostap
Arend van Spriel - May 19, 2013, 9:13 p.m.
On 05/19/2013 08:13 PM, Peer, Ilan wrote:
>
>
>> -----Original Message-----
>> From: hostap-bounces@lists.shmoo.com [mailto:hostap-
>> bounces@lists.shmoo.com] On Behalf Of Arend van Spriel
>> Sent: Thursday, May 16, 2013 16:28
>> To: Jouni Malinen
>> Cc: hostap@lists.shmoo.com
>> Subject: [PATCH 03/20] driver: nl80211: hold wdev identification for P2P device
>>
>
> The title of the patch might be a bit misleading :)
>
>> 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.
>>
>> Signed-off-by: David Spinadel <david.spinadel@intel.com>
>> ---
>>   src/drivers/driver_nl80211.c |   84 ++++++++++++++++++++++++++++++++------
>> ----
>>   1 file changed, 64 insertions(+), 20 deletions(-)
>>
>> diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index
>> b304ddd..ec877f2 100644
>> --- a/src/drivers/driver_nl80211.c
>> +++ b/src/drivers/driver_nl80211.c
>> @@ -12,7 +12,7 @@
>>
>>   #include "includes.h"
>>   #include <sys/ioctl.h>
>> -#include <sys/types.h>
>> +#include <inttypes.h>
>>   #include <sys/stat.h>
>>   #include <fcntl.h>
>>   #include <net/if.h>
>> @@ -183,6 +183,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;
>> @@ -464,6 +465,17 @@ struct family_data {
>>   	int id;
>>   };
>>
>> +static int nl80211_set_iface_id(struct nl_msg *msg, struct i802_bss
>> +*bss) {
>
> It is possible to always add both attributes (and this can actually be done for all the nl commands ...). The kernel should be able to handle this.

That was my initial take as well, but Johannes pointed out to keep 
wpa_supplicant usable for kernel version with wdev_id.

>> +	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)  { @@ -2434,23
>> +2446,35 @@ 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]);
>>
>
> It might be better to get both IFINDEX and WDEV id, and then have only a single iteration and do similar processing as in process_global_event(). Otherwise, you might miss a case where the ifindex is -1 but a bss with a valid wdev_id is not the first in the list
>
>> -	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;
>> +			}
>> +		wpa_printf(MSG_DEBUG,
>> +			   "nl80211: Ignored event (cmd=%d) for foreign
>> interface (ifindex %d)",
>> +			   gnlh->cmd, ifidx);
>> +	} 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) {
>> +				do_process_drv_event(bss, gnlh->cmd, tb);
>> +				return NL_SKIP;
>> +			}
>> +		wpa_printf(MSG_DEBUG,
>> +			   "nl80211: Ignored event (cmd=%d) for foreign
>> interface (wdev 0x%"
>> +			   PRIx64 ")", gnlh->cmd, wdev_id);
>>   	}
>>
>> -	wpa_printf(MSG_DEBUG, "nl80211: Ignored event (cmd=%d) for
>> foreign "
>> -		   "interface (ifindex %d)", gnlh->cmd, ifidx);
>> -
>>   	return NL_SKIP;
>>   }
>>
>> @@ -2463,17 +2487,22 @@ 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;
>>   			}
>> @@ -3349,6 +3378,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;
>> @@ -3436,7 +3466,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);
>>
>> @@ -3856,7 +3888,7 @@ 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;
>>   	size_t i;
>> @@ -3867,8 +3899,10 @@ 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)
>> +		NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
>> +	else
>> +		NLA_PUT_U64(msg, NL80211_ATTR_WDEV, wdev_id);
>>
>>   	if (params->num_ssids) {
>>   		struct nlattr *ssids;
>> @@ -3917,6 +3951,7 @@ nl80211_scan_common(struct
>> wpa_driver_nl80211_data *drv, u8 cmd,
>>   	return msg;
>>
>>   fail:
>> +nla_put_failure:
>>   	nlmsg_free(msg);
>>   	return NULL;
>>   }
>> @@ -3938,7 +3973,8 @@ static int wpa_driver_nl80211_scan(struct i802_bss
>> *bss,
>>   	wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request");
>>   	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;
>>
>> @@ -4041,7 +4077,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;
>>
>> @@ -8585,6 +8622,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;
>> @@ -8696,7 +8734,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); @@ -
>> 8818,7 +8858,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);
>>
>> @@ -8865,7 +8907,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
>>
>>
>> _______________________________________________
>> HostAP mailing list
>> HostAP@lists.shmoo.com
>> http://lists.shmoo.com/mailman/listinfo/hostap
>
Ilan Peer - May 20, 2013, 7:05 a.m.
> -----Original Message-----
> From: Arend van Spriel [mailto:arend@broadcom.com]
> Sent: Monday, May 20, 2013 00:14
> To: Peer, Ilan
> Cc: Jouni Malinen; hostap@lists.shmoo.com; Johannes Berg
> Subject: Re: [PATCH 03/20] driver: nl80211: hold wdev identification for P2P
> device
> 
> On 05/19/2013 08:13 PM, Peer, Ilan wrote:
> >
> >
> >> -----Original Message-----
> >> From: hostap-bounces@lists.shmoo.com [mailto:hostap-
> >> bounces@lists.shmoo.com] On Behalf Of Arend van Spriel
> >> Sent: Thursday, May 16, 2013 16:28
> >> To: Jouni Malinen
> >> Cc: hostap@lists.shmoo.com
> >> Subject: [PATCH 03/20] driver: nl80211: hold wdev identification for
> >> P2P device
> >>
> >
> > The title of the patch might be a bit misleading :)
> >
> >> 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.
> >>
> >> Signed-off-by: David Spinadel <david.spinadel@intel.com>
> >> ---
> >>   src/drivers/driver_nl80211.c |   84 ++++++++++++++++++++++++++++++++-
> -----
> >> ----
> >>   1 file changed, 64 insertions(+), 20 deletions(-)
> >>
> >> diff --git a/src/drivers/driver_nl80211.c
> >> b/src/drivers/driver_nl80211.c index
> >> b304ddd..ec877f2 100644
> >> --- a/src/drivers/driver_nl80211.c
> >> +++ b/src/drivers/driver_nl80211.c
> >> @@ -12,7 +12,7 @@
> >>
> >>   #include "includes.h"
> >>   #include <sys/ioctl.h>
> >> -#include <sys/types.h>
> >> +#include <inttypes.h>
> >>   #include <sys/stat.h>
> >>   #include <fcntl.h>
> >>   #include <net/if.h>
> >> @@ -183,6 +183,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;
> >> @@ -464,6 +465,17 @@ struct family_data {
> >>   	int id;
> >>   };
> >>
> >> +static int nl80211_set_iface_id(struct nl_msg *msg, struct i802_bss
> >> +*bss) {
> >
> > It is possible to always add both attributes (and this can actually be done for
> all the nl commands ...). The kernel should be able to handle this.
> 
> That was my initial take as well, but Johannes pointed out to keep
> wpa_supplicant usable for kernel version with wdev_id.

I meant put both attributes :) I think that even older kernel versions can handle this.

> 
> >> +	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)  { @@
> >> -2434,23
> >> +2446,35 @@ 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]);
> >>
> >
> > It might be better to get both IFINDEX and WDEV id, and then have only
> > a single iteration and do similar processing as in
> > process_global_event(). Otherwise, you might miss a case where the
> > ifindex is -1 but a bss with a valid wdev_id is not the first in the
> > list
> >
> >> -	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;
> >> +			}
> >> +		wpa_printf(MSG_DEBUG,
> >> +			   "nl80211: Ignored event (cmd=%d) for foreign
> >> interface (ifindex %d)",
> >> +			   gnlh->cmd, ifidx);
> >> +	} 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) {
> >> +				do_process_drv_event(bss, gnlh->cmd, tb);
> >> +				return NL_SKIP;
> >> +			}
> >> +		wpa_printf(MSG_DEBUG,
> >> +			   "nl80211: Ignored event (cmd=%d) for foreign
> >> interface (wdev 0x%"
> >> +			   PRIx64 ")", gnlh->cmd, wdev_id);
> >>   	}
> >>
> >> -	wpa_printf(MSG_DEBUG, "nl80211: Ignored event (cmd=%d) for
> >> foreign "
> >> -		   "interface (ifindex %d)", gnlh->cmd, ifidx);
> >> -
> >>   	return NL_SKIP;
> >>   }
> >>
> >> @@ -2463,17 +2487,22 @@ 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;
> >>   			}
> >> @@ -3349,6 +3378,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;
> >> @@ -3436,7 +3466,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);
> >>
> >> @@ -3856,7 +3888,7 @@ 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;
> >>   	size_t i;
> >> @@ -3867,8 +3899,10 @@ 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)
> >> +		NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
> >> +	else
> >> +		NLA_PUT_U64(msg, NL80211_ATTR_WDEV, wdev_id);
> >>
> >>   	if (params->num_ssids) {
> >>   		struct nlattr *ssids;
> >> @@ -3917,6 +3951,7 @@ nl80211_scan_common(struct
> >> wpa_driver_nl80211_data *drv, u8 cmd,
> >>   	return msg;
> >>
> >>   fail:
> >> +nla_put_failure:
> >>   	nlmsg_free(msg);
> >>   	return NULL;
> >>   }
> >> @@ -3938,7 +3973,8 @@ static int wpa_driver_nl80211_scan(struct
> >> i802_bss *bss,
> >>   	wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request");
> >>   	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;
> >>
> >> @@ -4041,7 +4077,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;
> >>
> >> @@ -8585,6 +8622,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; @@ -8696,7 +8734,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); @@ -
> >> 8818,7 +8858,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);
> >>
> >> @@ -8865,7 +8907,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
> >>
> >>
> >> _______________________________________________
> >> HostAP mailing list
> >> HostAP@lists.shmoo.com
> >> http://lists.shmoo.com/mailman/listinfo/hostap
> >
>
Arend van Spriel - May 21, 2013, 10:18 a.m.
On 05/19/2013 11:13 PM, Arend van Spriel wrote:
> On 05/19/2013 08:13 PM, Peer, Ilan wrote:
>>
>>
>>> -----Original Message-----
>>> From: hostap-bounces@lists.shmoo.com [mailto:hostap-
>>> bounces@lists.shmoo.com] On Behalf Of Arend van Spriel
>>> Sent: Thursday, May 16, 2013 16:28
>>> To: Jouni Malinen
>>> Cc: hostap@lists.shmoo.com
>>> Subject: [PATCH 03/20] driver: nl80211: hold wdev identification for
>>> P2P device
>>>
>>
>> The title of the patch might be a bit misleading :)
>>
>>> 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.
>>>
>>> Signed-off-by: David Spinadel <david.spinadel@intel.com>
>>> ---
>>>   src/drivers/driver_nl80211.c |   84
>>> ++++++++++++++++++++++++++++++++------
>>> ----
>>>   1 file changed, 64 insertions(+), 20 deletions(-)
>>>
>>> diff --git a/src/drivers/driver_nl80211.c
>>> b/src/drivers/driver_nl80211.c index
>>> b304ddd..ec877f2 100644
>>> --- a/src/drivers/driver_nl80211.c
>>> +++ b/src/drivers/driver_nl80211.c
>>> @@ -12,7 +12,7 @@
>>>
>>>   #include "includes.h"
>>>   #include <sys/ioctl.h>
>>> -#include <sys/types.h>
>>> +#include <inttypes.h>
>>>   #include <sys/stat.h>
>>>   #include <fcntl.h>
>>>   #include <net/if.h>
>>> @@ -183,6 +183,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;
>>> @@ -464,6 +465,17 @@ struct family_data {
>>>       int id;
>>>   };
>>>
>>> +static int nl80211_set_iface_id(struct nl_msg *msg, struct i802_bss
>>> +*bss) {
>>
>> It is possible to always add both attributes (and this can actually be
>> done for all the nl commands ...). The kernel should be able to handle
>> this.
>
> That was my initial take as well, but Johannes pointed out to keep
> wpa_supplicant usable for kernel version with wdev_id.

I meant to say: kernel version *without* wdev_id. Sorry for the confusion.

>
Ilan Peer - May 21, 2013, 6:21 p.m.
> -----Original Message-----
> From: Arend van Spriel [mailto:arend@broadcom.com]
> Sent: Tuesday, May 21, 2013 13:18
> To: Peer, Ilan
> Cc: Jouni Malinen; Johannes Berg; hostap@lists.shmoo.com
> Subject: Re: [PATCH 03/20] driver: nl80211: hold wdev identification for P2P
> device
> 
> On 05/19/2013 11:13 PM, Arend van Spriel wrote:
> > On 05/19/2013 08:13 PM, Peer, Ilan wrote:
> >>
> >>
> >>> -----Original Message-----
> >>> From: hostap-bounces@lists.shmoo.com [mailto:hostap-
> >>> bounces@lists.shmoo.com] On Behalf Of Arend van Spriel
> >>> Sent: Thursday, May 16, 2013 16:28
> >>> To: Jouni Malinen
> >>> Cc: hostap@lists.shmoo.com
> >>> Subject: [PATCH 03/20] driver: nl80211: hold wdev identification for
> >>> P2P device
> >>>
> >>
> >> The title of the patch might be a bit misleading :)
> >>
> >>> 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.
> >>>
> >>> Signed-off-by: David Spinadel <david.spinadel@intel.com>
> >>> ---
> >>>   src/drivers/driver_nl80211.c |   84
> >>> ++++++++++++++++++++++++++++++++------
> >>> ----
> >>>   1 file changed, 64 insertions(+), 20 deletions(-)
> >>>
> >>> diff --git a/src/drivers/driver_nl80211.c
> >>> b/src/drivers/driver_nl80211.c index
> >>> b304ddd..ec877f2 100644
> >>> --- a/src/drivers/driver_nl80211.c
> >>> +++ b/src/drivers/driver_nl80211.c
> >>> @@ -12,7 +12,7 @@
> >>>
> >>>   #include "includes.h"
> >>>   #include <sys/ioctl.h>
> >>> -#include <sys/types.h>
> >>> +#include <inttypes.h>
> >>>   #include <sys/stat.h>
> >>>   #include <fcntl.h>
> >>>   #include <net/if.h>
> >>> @@ -183,6 +183,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;
> >>> @@ -464,6 +465,17 @@ struct family_data {
> >>>       int id;
> >>>   };
> >>>
> >>> +static int nl80211_set_iface_id(struct nl_msg *msg, struct i802_bss
> >>> +*bss) {
> >>
> >> It is possible to always add both attributes (and this can actually
> >> be done for all the nl commands ...). The kernel should be able to
> >> handle this.
> >
> > That was my initial take as well, but Johannes pointed out to keep
> > wpa_supplicant usable for kernel version with wdev_id.
> 
> I meant to say: kernel version *without* wdev_id. Sorry for the confusion.

I think that older kernel versions will ignore the WDEV attribute so that should not be an issue. Anyway, I'm also ok with the current approach :) thanks.

> 
> >
>
Arend van Spriel - May 21, 2013, 7:29 p.m.
On 05/20/2013 09:05 AM, Peer, Ilan wrote:
>> That was my initial take as well, but Johannes pointed out to keep
>> >wpa_supplicant usable for kernel version with wdev_id.
> I meant put both attributes:)  I think that even older kernel versions can handle this.

Good point. Although obviously for the P2P device interface we would 
only put the wdev_id as it does not have a valid ifindex.

Gr. AvS

Patch

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index b304ddd..ec877f2 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -12,7 +12,7 @@ 
 
 #include "includes.h"
 #include <sys/ioctl.h>
-#include <sys/types.h>
+#include <inttypes.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <net/if.h>
@@ -183,6 +183,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;
@@ -464,6 +465,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)
 {
@@ -2434,23 +2446,35 @@  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;
+			}
+		wpa_printf(MSG_DEBUG,
+			   "nl80211: Ignored event (cmd=%d) for foreign interface (ifindex %d)",
+			   gnlh->cmd, ifidx);
+	} 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) {
+				do_process_drv_event(bss, gnlh->cmd, tb);
+				return NL_SKIP;
+			}
+		wpa_printf(MSG_DEBUG,
+			   "nl80211: Ignored event (cmd=%d) for foreign interface (wdev 0x%"
+			   PRIx64 ")", gnlh->cmd, wdev_id);
 	}
 
-	wpa_printf(MSG_DEBUG, "nl80211: Ignored event (cmd=%d) for foreign "
-		   "interface (ifindex %d)", gnlh->cmd, ifidx);
-
 	return NL_SKIP;
 }
 
@@ -2463,17 +2487,22 @@  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;
 			}
@@ -3349,6 +3378,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;
@@ -3436,7 +3466,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);
 
@@ -3856,7 +3888,7 @@  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;
 	size_t i;
@@ -3867,8 +3899,10 @@  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)
+		NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+	else
+		NLA_PUT_U64(msg, NL80211_ATTR_WDEV, wdev_id);
 
 	if (params->num_ssids) {
 		struct nlattr *ssids;
@@ -3917,6 +3951,7 @@  nl80211_scan_common(struct wpa_driver_nl80211_data *drv, u8 cmd,
 	return msg;
 
 fail:
+nla_put_failure:
 	nlmsg_free(msg);
 	return NULL;
 }
@@ -3938,7 +3973,8 @@  static int wpa_driver_nl80211_scan(struct i802_bss *bss,
 	wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request");
 	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;
 
@@ -4041,7 +4077,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;
 
@@ -8585,6 +8622,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;
@@ -8696,7 +8734,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);
@@ -8818,7 +8858,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);
 
@@ -8865,7 +8907,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);