Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 21 Sep 2016 19:48:07 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r306139 - head/sys/net80211
Message-ID:  <201609211948.u8LJm7P1015015@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Wed Sep 21 19:48:07 2016
New Revision: 306139
URL: https://svnweb.freebsd.org/changeset/base/306139

Log:
  [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

Modified:
  head/sys/net80211/ieee80211_adhoc.c
  head/sys/net80211/ieee80211_node.c
  head/sys/net80211/ieee80211_node.h

Modified: head/sys/net80211/ieee80211_adhoc.c
==============================================================================
--- head/sys/net80211/ieee80211_adhoc.c	Wed Sep 21 19:30:34 2016	(r306138)
+++ head/sys/net80211/ieee80211_adhoc.c	Wed Sep 21 19:48:07 2016	(r306139)
@@ -747,8 +747,20 @@ adhoc_recv_mgmt(struct ieee80211_node *n
 			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.

Modified: head/sys/net80211/ieee80211_node.c
==============================================================================
--- head/sys/net80211/ieee80211_node.c	Wed Sep 21 19:30:34 2016	(r306138)
+++ head/sys/net80211/ieee80211_node.c	Wed Sep 21 19:48:07 2016	(r306139)
@@ -579,6 +579,62 @@ ieee80211_ibss_merge_check(struct ieee80
 }
 
 /*
+ * 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

Modified: head/sys/net80211/ieee80211_node.h
==============================================================================
--- head/sys/net80211/ieee80211_node.h	Wed Sep 21 19:30:34 2016	(r306138)
+++ head/sys/net80211/ieee80211_node.h	Wed Sep 21 19:48:07 2016	(r306139)
@@ -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 ieee8
 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 *,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609211948.u8LJm7P1015015>