Index: head/sys/net80211/ieee80211_adhoc.c =================================================================== --- head/sys/net80211/ieee80211_adhoc.c +++ head/sys/net80211/ieee80211_adhoc.c @@ -747,8 +747,20 @@ 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. Index: head/sys/net80211/ieee80211_node.h =================================================================== --- head/sys/net80211/ieee80211_node.h +++ head/sys/net80211/ieee80211_node.h @@ -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_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 *, Index: head/sys/net80211/ieee80211_node.c =================================================================== --- head/sys/net80211/ieee80211_node.c +++ head/sys/net80211/ieee80211_node.c @@ -579,6 +579,62 @@ } /* + * 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 * (WECA), is that an 802.11 station will change its BSSID to match