Allow more complex BSSID masks to be used for multi-BSSID
authorJouni Malinen <jouni.malinen@atheros.com>
Thu, 12 Mar 2009 20:01:26 +0000 (22:01 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 12 Mar 2009 20:01:26 +0000 (22:01 +0200)
If every secondary BSS is configured with a pre-set BSSID, hostapd does
not enforce the BSSID mask requirements anymore, i.e., they are used
only if hostapd is responsible for generating MAC addresses for virtual
interfaces.

hostapd/hostapd.c
hostapd/hostapd.conf

index 8531d0a..6a04713 100644 (file)
@@ -1012,6 +1012,7 @@ static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
        struct hostapd_data *hapd = iface->bss[0];
        unsigned int i = iface->conf->num_bss, bits = 0, j;
        int res;
+       int auto_addr = 0;
 
        if (hostapd_drv_none(hapd))
                return 0;
@@ -1025,8 +1026,11 @@ static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
        /* 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 (hostapd_mac_comp_empty(iface->conf->bss[j].bssid) == 0) {
+                       if (j)
+                               auto_addr++;
                        continue;
+               }
 
                for (i = 0; i < ETH_ALEN; i++) {
                        mask[i] |=
@@ -1035,6 +1039,9 @@ static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
                }
        }
 
+       if (!auto_addr)
+               goto skip_mask_ext;
+
        for (i = 0; i < ETH_ALEN && mask[i] == 0; i++)
                ;
        j = 0;
@@ -1050,8 +1057,11 @@ static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
        if (bits < j)
                bits = j;
 
-       if (bits > 40)
+       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;
@@ -1061,6 +1071,7 @@ static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
        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);
 
@@ -1075,6 +1086,9 @@ static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
                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
index 0533f19..117e1d5 100644 (file)
@@ -1006,7 +1006,10 @@ own_ip_addr=127.0.0.1
 # hostapd will generate BSSID mask based on the BSSIDs that are
 # configured. hostapd will verify that dev_addr & MASK == dev_addr. If this is
 # not the case, the MAC address of the radio must be changed before starting
-# hostapd (ifconfig wlan0 hw ether <MAC addr>).
+# hostapd (ifconfig wlan0 hw ether <MAC addr>). If a BSSID is configured for
+# every secondary BSS, this limitation is not applied at hostapd and other
+# masks may be used if the driver supports them (e.g., swap the locally
+# administered bit)
 #
 # BSSIDs are assigned in order to each BSS, unless an explicit BSSID is
 # specified using the 'bssid' parameter.