Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -1003,8 +1003,12 @@ struct ieee80211_ht_info {
#define WLAN_CAPABILITY_ESS		(1<<0)
#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)))

#define WLAN_CAPABILITY_CF_POLLABLE	(1<<2)
+24 −19
Original line number Diff line number Diff line
@@ -267,13 +267,35 @@ static bool is_bss(struct cfg80211_bss *a,
	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,
		    const u8 *meshid, size_t meshidlen,
		    const u8 *meshcfg)
{
	const u8 *ie;

	if (!WLAN_CAPABILITY_IS_MBSS(a->capability))
	if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability))
		return false;

	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)
		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,
			    a->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 *found = NULL;
	const u8 *meshid, *meshcfg;

	/*
	 * The reference to "res" is donated to this function.
@@ -470,22 +491,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,

	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);

	found = rb_find_bss(dev, res);