Commit 333ba732 authored by Eliad Peller's avatar Eliad Peller Committed by John W. Linville

cfg80211: don't drop p2p probe responses

Commit 0a35d36d ("cfg80211: Use capability info to detect mesh beacons")
assumed that probe response with both ESS and IBSS bits cleared
means that the frame was sent by a mesh sta.

However, these capabilities are also being used in the p2p_find phase,
and the mesh-validation broke it.

Rename the WLAN_CAPABILITY_IS_MBSS macro, and verify that mesh ies
exist before assuming this frame was sent by a mesh sta.
Signed-off-by: default avatarEliad Peller <eliad@wizery.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 1144181c
...@@ -1003,8 +1003,12 @@ struct ieee80211_ht_info { ...@@ -1003,8 +1003,12 @@ struct ieee80211_ht_info {
#define WLAN_CAPABILITY_ESS (1<<0) #define WLAN_CAPABILITY_ESS (1<<0)
#define WLAN_CAPABILITY_IBSS (1<<1) #define WLAN_CAPABILITY_IBSS (1<<1)
/* A mesh STA sets the ESS and IBSS capability bits to zero */ /*
#define WLAN_CAPABILITY_IS_MBSS(cap) \ * A mesh STA sets the ESS and IBSS capability bits to zero.
* however, this holds true for p2p probe responses (in the p2p_find
* phase) as well.
*/
#define WLAN_CAPABILITY_IS_STA_BSS(cap) \
(!((cap) & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS))) (!((cap) & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)))
#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) #define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
......
...@@ -267,13 +267,35 @@ static bool is_bss(struct cfg80211_bss *a, ...@@ -267,13 +267,35 @@ static bool is_bss(struct cfg80211_bss *a,
return memcmp(ssidie + 2, ssid, ssid_len) == 0; return memcmp(ssidie + 2, ssid, ssid_len) == 0;
} }
static bool is_mesh_bss(struct cfg80211_bss *a)
{
const u8 *ie;
if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability))
return false;
ie = cfg80211_find_ie(WLAN_EID_MESH_ID,
a->information_elements,
a->len_information_elements);
if (!ie)
return false;
ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
a->information_elements,
a->len_information_elements);
if (!ie)
return false;
return true;
}
static bool is_mesh(struct cfg80211_bss *a, static bool is_mesh(struct cfg80211_bss *a,
const u8 *meshid, size_t meshidlen, const u8 *meshid, size_t meshidlen,
const u8 *meshcfg) const u8 *meshcfg)
{ {
const u8 *ie; const u8 *ie;
if (!WLAN_CAPABILITY_IS_MBSS(a->capability)) if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability))
return false; return false;
ie = cfg80211_find_ie(WLAN_EID_MESH_ID, ie = cfg80211_find_ie(WLAN_EID_MESH_ID,
...@@ -311,7 +333,7 @@ static int cmp_bss(struct cfg80211_bss *a, ...@@ -311,7 +333,7 @@ static int cmp_bss(struct cfg80211_bss *a,
if (a->channel != b->channel) if (a->channel != b->channel)
return b->channel->center_freq - a->channel->center_freq; return b->channel->center_freq - a->channel->center_freq;
if (WLAN_CAPABILITY_IS_MBSS(a->capability | b->capability)) { if (is_mesh_bss(a) && is_mesh_bss(b)) {
r = cmp_ies(WLAN_EID_MESH_ID, r = cmp_ies(WLAN_EID_MESH_ID,
a->information_elements, a->information_elements,
a->len_information_elements, a->len_information_elements,
...@@ -457,7 +479,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, ...@@ -457,7 +479,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
struct cfg80211_internal_bss *res) struct cfg80211_internal_bss *res)
{ {
struct cfg80211_internal_bss *found = NULL; struct cfg80211_internal_bss *found = NULL;
const u8 *meshid, *meshcfg;
/* /*
* The reference to "res" is donated to this function. * The reference to "res" is donated to this function.
...@@ -470,22 +491,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, ...@@ -470,22 +491,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
res->ts = jiffies; res->ts = jiffies;
if (WLAN_CAPABILITY_IS_MBSS(res->pub.capability)) {
/* must be mesh, verify */
meshid = cfg80211_find_ie(WLAN_EID_MESH_ID,
res->pub.information_elements,
res->pub.len_information_elements);
meshcfg = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
res->pub.information_elements,
res->pub.len_information_elements);
if (!meshid || !meshcfg ||
meshcfg[1] != sizeof(struct ieee80211_meshconf_ie)) {
/* bogus mesh */
kref_put(&res->ref, bss_release);
return NULL;
}
}
spin_lock_bh(&dev->bss_lock); spin_lock_bh(&dev->bss_lock);
found = rb_find_bss(dev, res); found = rb_find_bss(dev, res);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment