[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