cfg80211: don't drop p2p probe responses
Commit 0a35d36
("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: Eliad Peller <eliad@wizery.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
1144181c1b
commit
333ba73252
@ -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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user