[PATCH] p2p_supplicant: probe reporting should be from listen interface

Johannes Berg johannes
Thu Apr 18 14:41:55 PDT 2013


On Thu, 2013-03-28 at 15:39 +0100, Arend van Spriel wrote:
> P2P listen phase is used to listen for P2P probe request messages
> from peers. The probe reporting call should be done on the same
> interface as the remain_on_channel.

Conceptually, I agree with this patch.


> This patch fixes it for my driver and it kind of makes sense to me that
> the probe request reporting should be done on the same interface as the
> on doing the LISTEN.

Implementation wise, I'm surprised this even worked for you. It
definitely seems to break P2P operation with hwsim with David's patches.

I think we need to do something like this (on top of your patch)

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index b74cf0b..e1d8e48 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -9808,7 +9808,7 @@ static void nl80211_deinit_p2p_dev(void *priv)
 {
 	struct i802_bss *p2p_dev = priv;
 	struct wpa_driver_nl80211_data *drv = p2p_dev->drv;
-	struct i802_bss *last;
+	struct i802_bss *tbss;
 
 	if (p2p_dev->wdev_id == -1)
 		return;
@@ -9821,11 +9821,19 @@ static void nl80211_deinit_p2p_dev(void *priv)
 				    NL80211_CMD_DEL_INTERFACE,
 				    p2p_dev->wdev_id);
 
-	for (last = &drv->first_bss; last->next && last->next != p2p_dev;
-	     last = last->next)
-		;
-	if (last->next && last->next == p2p_dev)
-		last->next = p2p_dev->next;
+	for (tbss = &drv->first_bss; tbss; tbss = tbss->next) {
+		if (tbss->next == p2p_dev) {
+			tbss->next = p2p_dev->next;
+			break;
+		}
+	}
+
+	if (p2p_dev->nl_mgmt) {
+		eloop_unregister_read_sock(nl_socket_get_fd(p2p_dev->nl_mgmt));
+		nl_destroy_handles(&p2p_dev->nl_mgmt);
+	}
+
+	nl80211_destroy_bss(p2p_dev);
 
 	os_free(p2p_dev);
 }
@@ -9833,15 +9841,16 @@ static void nl80211_deinit_p2p_dev(void *priv)
 static void *nl80211_init_p2p_dev(void *priv, const char *ifname, u8 *addr)
 {
 	struct i802_bss *bss = priv;
-	struct i802_bss *last;
 	struct wpa_driver_nl80211_data *drv = bss->drv;
 	int ret;
 	int type;
 	struct i802_bss *p2p_dev = os_zalloc(sizeof(struct i802_bss));
+
 	if (!p2p_dev)
 		return NULL;
 
-	*p2p_dev = *bss;
+	p2p_dev->drv = drv;
+	p2p_dev->ctx = drv->ctx;
 	os_strncpy(p2p_dev->ifname, ifname, IFNAMSIZ);
 
 	p2p_dev->ifindex = nl80211_create_iface(drv, ifname,
@@ -9857,6 +9866,17 @@ static void *nl80211_init_p2p_dev(void *priv, const char *ifname, u8 *addr)
 		return NULL;
 	}
 
+	ret = nl80211_init_bss(p2p_dev);
+	if (ret) {
+		nl80211_deinit_p2p_dev(p2p_dev);
+		return NULL;
+	}
+
+	if (nl80211_alloc_mgmt_handle(p2p_dev)) {
+		nl80211_deinit_p2p_dev(p2p_dev);
+		return NULL;
+	}
+
 	ret = nl80211_p2p_device_exec_cmd(drv, ifname,
 					NL80211_CMD_START_P2P_DEVICE,
 					p2p_dev->wdev_id);
@@ -9868,18 +9888,17 @@ static void *nl80211_init_p2p_dev(void *priv, const char *ifname, u8 *addr)
 		return NULL;
 	}
 
-	for (last = bss; last->next; last = last->next)
-		;
-	last->next = p2p_dev;
-
 	os_memcpy(addr, p2p_dev->addr, ETH_ALEN);
 
+	p2p_dev->next = drv->first_bss.next;
+	drv->first_bss.next = p2p_dev;
+
 	/* Register P2P Public Action frame on the device interface */
 	type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_ACTION << 4);
-	nl80211_register_frame(p2p_dev, bss->nl_mgmt, type,
+	nl80211_register_frame(p2p_dev, p2p_dev->nl_mgmt, type,
 			       (u8 *) "\x04\x09\x50\x6f\x9a\x09", 6);
 	/* Register P2P Action frame on the device interface */
-	nl80211_register_frame(p2p_dev, bss->nl_mgmt, type,
+	nl80211_register_frame(p2p_dev, p2p_dev->nl_mgmt, type,
 			       (u8 *) "\x7f\x50\x6f\x9a\x09", 5);
 
 	return p2p_dev;



This works in hwsim now, with a mac80211 patch:

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 5b4492a..3290ce6 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2681,6 +2681,9 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
 
 	stype = mgmt->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE);
 
+	if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE)
+		return RX_CONTINUE;
+
 	if (!ieee80211_vif_is_mesh(&sdata->vif) &&
 	    sdata->vif.type != NL80211_IFTYPE_ADHOC &&
 	    sdata->vif.type != NL80211_IFTYPE_STATION)
@@ -3030,7 +3033,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
 		    !ieee80211_is_probe_resp(hdr->frame_control) &&
 		    !ieee80211_is_beacon(hdr->frame_control))
 			return 0;
-		if (!ether_addr_equal(sdata->vif.addr, hdr->addr1))
+		if (!ether_addr_equal(sdata->vif.addr, hdr->addr1) &&
+		    !multicast)
 			status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
 		break;
 	default:


johannes




More information about the Hostap mailing list