[net80211] don't add IBSS node table entries for neighbors from other SSIDs.

The adhoc probe/beacon input path was creating nodes for all SSIDs.
This wasn't a problem when the NICs were configured to only process
frames for the current BSSID, but that didn't allow IBSS merges.
Once avos and I flipped on "beacons from all BSSIDs" to allow for
correct IBSS merging, we found this interesting behaviour.

This adds a check against the current SSID.

* If there's no VAP SSID, allow anything
* If there's a VAP SSID, check if the incoming frame has a suitable
  SSID and if so, allow it.

This prevents nodes being created for other SSIDs in probe and beacon
frames - ie, beacons overlapping IBSSes with different SSIDs, and
probe requests from arbitrary devices.

Tested:

* AR9380, IBSS mode, both local and other IBSSes.

Reviewed by:	avos
Differential Revision:	https://reviews.freebsd.org/D7959
This commit is contained in:
Adrian Chadd 2016-09-21 19:48:07 +00:00
parent 693c825e5e
commit 172b009aef
3 changed files with 72 additions and 1 deletions

View File

@ -747,8 +747,20 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
/*
* Create a new entry in the neighbor table.
*
* XXX TODO:
*
* Here we're not scanning; so if we have an
* SSID then make sure it matches our SSID.
* Otherwise this code will match on all IBSS
* beacons/probe requests for all SSIDs,
* filling the node table with nodes that
* aren't ours.
*/
ni = ieee80211_add_neighbor(vap, wh, &scan);
if (ieee80211_ibss_node_check_new(ni, &scan))
ni = ieee80211_add_neighbor(vap, wh, &scan);
else
ni = NULL;
} else if (ni->ni_capinfo == 0) {
/*
* Update faked node created on transmit.

View File

@ -578,6 +578,62 @@ ieee80211_ibss_merge_check(struct ieee80211_node *ni)
return 1;
}
/*
* Check if the given node should populate the node table.
*
* We need to be in "see all beacons for all ssids" mode in order
* to do IBSS merges, however this means we will populate nodes for
* /all/ IBSS SSIDs, versus just the one we care about.
*
* So this check ensures the node can actually belong to our IBSS
* configuration. For now it simply checks the SSID.
*/
int
ieee80211_ibss_node_check_new(struct ieee80211_node *ni,
const struct ieee80211_scanparams *scan)
{
struct ieee80211vap *vap = ni->ni_vap;
int i;
/*
* If we have no SSID and no scan SSID, return OK.
*/
if (vap->iv_des_nssid == 0 && scan->ssid == NULL)
goto ok;
/*
* If we have one of (SSID, scan SSID) then return error.
*/
if (!! (vap->iv_des_nssid == 0) != !! (scan->ssid == NULL))
goto mismatch;
/*
* Double-check - we need scan SSID.
*/
if (scan->ssid == NULL)
goto mismatch;
/*
* Check if the scan SSID matches the SSID list for the VAP.
*/
for (i = 0; i < vap->iv_des_nssid; i++) {
/* Sanity length check */
if (vap->iv_des_ssid[i].len != scan->ssid[1])
continue;
/* Note: SSID in the scan entry is the IE format */
if (memcmp(vap->iv_des_ssid[i].ssid, scan->ssid + 2,
vap->iv_des_ssid[i].len) == 0)
goto ok;
}
mismatch:
return (0);
ok:
return (1);
}
/*
* Handle 802.11 ad hoc network merge. The
* convention, set by the Wireless Ethernet Compatibility Alliance

View File

@ -65,6 +65,7 @@
struct ieee80211_node_table;
struct ieee80211com;
struct ieee80211vap;
struct ieee80211_scanparams;
/*
* Information element ``blob''. We use this structure
@ -330,6 +331,8 @@ void ieee80211_setupcurchan(struct ieee80211com *,
void ieee80211_setcurchan(struct ieee80211com *, struct ieee80211_channel *);
void ieee80211_update_chw(struct ieee80211com *);
int ieee80211_ibss_merge_check(struct ieee80211_node *);
int ieee80211_ibss_node_check_new(struct ieee80211_node *ni,
const struct ieee80211_scanparams *);
int ieee80211_ibss_merge(struct ieee80211_node *);
struct ieee80211_scan_entry;
int ieee80211_sta_join(struct ieee80211vap *, struct ieee80211_channel *,