Browse Source

hostapd: fix for "Invalid BSSID mask" error message

Phil Sutter 13 years ago
parent
commit
1006235818
1 changed files with 141 additions and 0 deletions
  1. 141 0
      package/hostapd/patches/001-fix-bssid-generation.patch

+ 141 - 0
package/hostapd/patches/001-fix-bssid-generation.patch

@@ -0,0 +1,141 @@
+Modified algorithm for generating BSSIDs. Always set locally
+administered bit. Calculate the mask after calculating the
+BSSIDs. This eliminates the "Invalid BSSID mask" caused when
+addr & mask != addr.
+
+Signed-off-by: Bill Jordan <bjordan <at> rajant.com>
+---
+Taken from http://permalink.gmane.org/gmane.linux.drivers.hostap/22207
+---
+ src/ap/hostapd.c |   74 ++++++------------------------------------------------
+ 1 files changed, 8 insertions(+), 66 deletions(-)
+
+diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
+index f4517f8..1dc6b66 100644
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -360,70 +360,26 @@ static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
+ {
+ 	u8 mask[ETH_ALEN] = { 0 };
+ 	struct hostapd_data *hapd = iface->bss[0];
+-	unsigned int i = iface->conf->num_bss, bits = 0, j;
++	unsigned int i, j;
+ 	int res;
+-	int auto_addr = 0;
+
+ 	if (hostapd_drv_none(hapd))
+ 		return 0;
+
+ 	/* Generate BSSID mask that is large enough to cover the BSSIDs. */
+
+-	/* Determine the bits necessary to cover the number of BSSIDs. */
+-	for (i--; i; i >>= 1)
+-		bits++;
+-
+ 	/* Determine the bits necessary to any configured BSSIDs,
+ 	   if they are higher than the number of BSSIDs. */
+ 	for (j = 0; j < iface->conf->num_bss; j++) {
+-		if (hostapd_mac_comp_empty(iface->conf->bss[j].bssid) == 0) {
+-			if (j)
+-				auto_addr++;
+-			continue;
+-		}
+-
+ 		for (i = 0; i < ETH_ALEN; i++) {
+ 			mask[i] |=
+-				iface->conf->bss[j].bssid[i] ^
++				iface->bss[j]->conf->bssid[i] ^
+ 				hapd->own_addr[i];
+ 		}
+ 	}
+
+-	if (!auto_addr)
+-		goto skip_mask_ext;
+-
+-	for (i = 0; i < ETH_ALEN && mask[i] == 0; i++)
+-		;
+-	j = 0;
+-	if (i < ETH_ALEN) {
+-		j = (5 - i) * 8;
+-
+-		while (mask[i] != 0) {
+-			mask[i] >>= 1;
+-			j++;
+-		}
+-	}
+-
+-	if (bits < j)
+-		bits = j;
+-
+-	if (bits > 40) {
+-		wpa_printf(MSG_ERROR, "Too many bits in the BSSID mask (%u)",
+-			   bits);
+-		return -1;
+-	}
+-
+-	os_memset(mask, 0xff, ETH_ALEN);
+-	j = bits / 8;
+-	for (i = 5; i > 5 - j; i--)
+-		mask[i] = 0;
+-	j = bits % 8;
+-	while (j--)
+-		mask[i] <<= 1;
+-
+-skip_mask_ext:
+-	wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR " (%d bits)",
+-		   (unsigned long) iface->conf->num_bss, MAC2STR(mask), bits);
++	wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR ,
++		   (unsigned long) iface->conf->num_bss, MAC2STR(mask));
+
+ 	res = hostapd_valid_bss_mask(hapd, hapd->own_addr, mask);
+ 	if (res == 0)
+@@ -436,21 +392,6 @@ skip_mask_ext:
+ 		return -1;
+ 	}
+
+-	if (!auto_addr)
+-		return 0;
+-
+-	for (i = 0; i < ETH_ALEN; i++) {
+-		if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) {
+-			wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR
+-				   " for start address " MACSTR ".",
+-				   MAC2STR(mask), MAC2STR(hapd->own_addr));
+-			wpa_printf(MSG_ERROR, "Start address must be the "
+-				   "first address in the block (i.e., addr "
+-				   "AND mask == addr).");
+-			return -1;
+-		}
+-	}
+-
+ 	return 0;
+ }
+
+@@ -492,6 +433,7 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
+ 	if (!first) {
+ 		if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0) {
+ 			/* Allocate the next available BSSID. */
++			hapd->own_addr[0] |= 2; /* locally administered address */
+ 			do {
+ 				inc_byte_array(hapd->own_addr, ETH_ALEN);
+ 			} while (mac_in_conf(hapd->iconf, hapd->own_addr));
+@@ -672,9 +614,6 @@ static int setup_interface(struct hostapd_iface *iface)
+ 		iface->bss[i]->drv_priv = hapd->drv_priv;
+ 	}
+
+-	if (hostapd_validate_bssid_configuration(iface))
+-		return -1;
+-
+ 	if (hapd->iconf->country[0] && hapd->iconf->country[1]) {
+ 		os_memcpy(country, hapd->iconf->country, 3);
+ 		country[3] = '\0';
+@@ -774,6 +713,9 @@ int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
+ 			prev_addr = hapd->own_addr;
+ 	}
+
++	if (hostapd_validate_bssid_configuration(iface))
++		return -1;
++
+ 	hostapd_tx_queue_params(iface);
+
+ 	ap_list_init(iface);