def _handle_status_lvap(self, wtp, status): """Handle an incoming STATUS_LVAP message. Args: status, a STATUS_LVAP message Returns: None """ if not wtp.connection: LOG.info("Status from disconnected WTP %s", wtp.addr) return sta = EtherAddress(status.sta) set_mask = bool(status.flags.set_mask) lvap = None accum = [] incoming_ssids = [SSID(x.ssid) for x in status.ssids] accum.append("addr ") accum.append(EtherAddress(status.sta).to_str()) accum.append(" net_bssid ") accum.append(EtherAddress(status.net_bssid).to_str()) accum.append(" lvap_bssid ") accum.append(EtherAddress(status.lvap_bssid).to_str()) accum.append(" ssid ") if incoming_ssids[0]: accum.append(incoming_ssids[0].to_str()) else: accum.append("None") accum.append(" ssids [") for ssid in incoming_ssids[1:]: accum.append(" ") accum.append(ssid.to_str()) accum.append(" ]") accum.append(" assoc_id ") accum.append(str(status.assoc_id)) if bool(status.flags.authenticated): accum.append(" AUTH") if bool(status.flags.associated): accum.append(" ASSOC") LOG.info("LVAP status %s", ''.join(accum)) # If the LVAP does not exists, then create a new one if sta not in RUNTIME.lvaps: net_bssid_addr = EtherAddress(status.net_bssid) lvap_bssid_addr = EtherAddress(status.lvap_bssid) lvap = LVAP(sta, net_bssid_addr, lvap_bssid_addr) RUNTIME.lvaps[sta] = lvap lvap = RUNTIME.lvaps[sta] # Check if block is valid incoming = ResourceBlock(wtp, EtherAddress(status.hwaddr), status.channel, status.band) valid = [block for block in wtp.supports if block == incoming] if not valid: LOG.warning("No valid intersection found. Removing block.") wtp.connection.send_del_lvap(lvap) return # received downlink block but a different downlink block is already # present, delete before going any further if set_mask and lvap._downlink and lvap._downlink != valid[0]: lvap._downlink.radio.connection.send_del_lvap(lvap) if set_mask: lvap._downlink = valid[0] else: lvap._uplink.append(valid[0]) # update ports if not lvap.ports: lvap.ports[0] = VirtualPort(virtual_port_id=0) lvap.ports[0].poas.append(wtp.port()) # set supported band lvap._supported_band = status.supported_band # update LVAP params lvap.authentication_state = bool(status.flags.authenticated) lvap.association_state = bool(status.flags.associated) lvap._assoc_id = status.assoc_id lvap._encap = EtherAddress(status.encap) ssids = [SSID(x.ssid) for x in status.ssids] # update ssid if lvap.ssid: # Raise LVAP leave event self.server.send_lvap_leave_message_to_self(lvap) # removing LVAP from tenant, need first to look for right tenant if lvap.addr in lvap.tenant.lvaps: LOG.info("Removing %s from tenant %s", lvap.addr, lvap.ssid) del lvap.tenant.lvaps[lvap.addr] lvap._tenant = None # update remaining ssids lvap._ssids = ssids[1:] if ssids[0]: tenant = RUNTIME.load_tenant(ssids[0]) if not tenant: LOG.info("LVAP %s from unknown tenant %s", lvap.addr, ssids[0]) RUNTIME.remove_lvap(lvap.addr) return # setting tenant without seding out add lvap message lvap._tenant = tenant # adding LVAP to tenant LOG.info("Adding %s to tenant %s", lvap.addr, ssids[0]) lvap.tenant.lvaps[lvap.addr] = lvap # Raise LVAP join event self.server.send_lvap_join_message_to_self(lvap)
def _handle_probe_request(self, wtp, request): """Handle an incoming PROBE_REQUEST message. Args: request, a PROBE_REQUEST message Returns: None """ if not wtp.connection: LOG.info("Probe request from disconnected WTP %s", wtp.addr) self.stream.close() return if not wtp.port(): LOG.info("WTP %s not ready", wtp.addr) return sta = EtherAddress(request.sta) if sta in RUNTIME.lvaps: return if not RUNTIME.is_allowed(sta): return if RUNTIME.is_denied(sta): return ssid = SSID(request.ssid) if request.ssid == b'': LOG.info("Probe request from %s ssid %s", sta, "Broadcast") else: LOG.info("Probe request from %s ssid %s", sta, ssid) # generate list of available SSIDs ssids = set() for tenant in RUNTIME.tenants.values(): if tenant.bssid_type == T_TYPE_SHARED: continue for wtp_in_tenant in tenant.wtps.values(): if wtp.addr == wtp_in_tenant.addr: ssids.add(tenant.tenant_name) if not ssids: LOG.info("No SSIDs available at this WTP") return # spawn new LVAP LOG.info("Spawning new LVAP %s on %s", sta, wtp.addr) net_bssid = generate_bssid(BASE_MAC, sta) lvap = LVAP(sta, net_bssid, net_bssid) lvap._ssids = list(ssids) # set supported band lvap._supported_band = request.supported_band # Check if block is valid incoming = ResourceBlock(wtp, EtherAddress(request.hwaddr), request.channel, request.band) valid = [block for block in wtp.supports if block == incoming] if not valid: LOG.warning("No valid intersection found. Ignoring request.") return # This will trigger an LVAP ADD message (and REMOVE if necessary) lvap.blocks = valid[0] # save LVAP in the runtime RUNTIME.lvaps[sta] = lvap LOG.info("Sending probe response to %s", lvap.addr) self.send_probe_response(lvap, ssid)