Cumulative patch from commit f2d6c17aa0f9107a0e8092238b849461447cdd21
f2d6c17 nl80211: Support network hierarchy of a master interface under bridge
f85399f Reserve QCA vendor specific nl80211 commands 116..118
3bd5886 hostapd: Handle running out of DFS channels
cc1af6f FST: Fix session setup failure with peer without MB IE
dfe0745 P2P: Add optional op_class argument to P2P_SET listen_channel
e4a1469 P2P: Adjust service discovery maximum fragment size for 60 GHz
c7fb678 D-Bus: Add association response status code property for failure cases
2940bf6 hostapd: Use ifname of the current context in debug messages
6448e06 hostapd: Allow use of driver-generated interface addresses
f2accfe AP: Save EAPOL received before Association Response ACK
1307301 wpaspy: Add support for TERMINATE command
a2c88a8 wpaspy: Add support for UDP connection
3e67171 hostapd: Add global TERMINATE command
618f5d0 hostapd: Add INTERFACES ctrl_iface command
180e5b9 hostapd: Update ctrl_interface for UDP to include the selected port
56e2fc2 wpa_supplicant: Add ctrl parameter to INTERFACES command
b9066c6 hostapd: Allow UDP ctrl_iface configuration to set the UDP port
56885ee hostapd: Add UDP support for ctrl_iface
acf57fa ctrl_iface_common: Use sockaddr_storage instead of sockaddr_un
89b781b hostapd: Use common functions for ctrl_iface
1a2124c wpa_supplicant: Use common functions for ctrl_iface
ca974ae Add common ctrl_iface files
d60886c wpa_supplicant: Add monitor support for global UDP ctrl_iface
f0e5d3b wpa_supplicant: Share attach/detach/send UDP ctrl_iface functions
db7fb43 wpa_supplicant: Allow UDP ctrl_iface configuration to set the UDP port
3598695 P2P: Update peer WFD IE from PD Response and GO Negotiation Response
c69ef1d P2P: Respect p2p_ignore_shared_freq on p2p_group_add
4115b05 P2P: Fix shared freq print in wpas_p2p_init_go_params()
Change-Id: Id939064b95210ee1a195f7a9f7c069da520d77ca
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index f19cac6..2d07c67 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -665,6 +665,9 @@
u8 vht_oper_centr_freq_seg0_idx;
u8 vht_oper_centr_freq_seg1_idx;
+ /* Use driver-generated interface addresses when adding multiple BSSs */
+ u8 use_driver_iface_addr;
+
#ifdef CONFIG_FST
struct fst_iface_cfg fst_cfg;
#endif /* CONFIG_FST */
diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index bda23f0..47adba7 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -704,7 +704,8 @@
skip_radar);
if (!channel) {
wpa_printf(MSG_ERROR, "could not get valid channel");
- return -1;
+ hostapd_set_state(iface, HAPD_IFACE_DFS);
+ return 0;
}
iface->freq = channel->freq;
@@ -793,7 +794,6 @@
if (!channel) {
wpa_printf(MSG_ERROR, "No valid channel available");
- hostapd_setup_interface_complete(iface, err);
return err;
}
@@ -858,8 +858,9 @@
&vht_oper_centr_freq_seg1_idx,
skip_radar);
if (!channel) {
- /* FIXME: Wait for channel(s) to become available */
- hostapd_disable_iface(iface);
+ wpa_printf(MSG_INFO,
+ "%s: no DFS channels left, waiting for NOP to finish",
+ __func__);
return err;
}
@@ -982,6 +983,11 @@
/* TODO add correct implementation here */
set_dfs_state(iface, freq, ht_enabled, chan_offset, chan_width,
cf1, cf2, HOSTAPD_CHAN_DFS_USABLE);
+
+ /* Handle cases where all channels were initially unavailable */
+ if (iface->state == HAPD_IFACE_DFS && !iface->cac_started)
+ hostapd_handle_dfs(iface);
+
return 0;
}
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 303786b..55ca9e8 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -512,6 +512,9 @@
if (hostapd_drv_none(hapd))
return 0;
+ if (iface->conf->use_driver_iface_addr)
+ return 0;
+
/* Generate BSSID mask that is large enough to cover the BSSIDs. */
/* Determine the bits necessary to cover the number of BSSIDs. */
@@ -905,12 +908,9 @@
hapd->started = 1;
if (!first || first == -1) {
- if (is_zero_ether_addr(conf->bssid)) {
- /* Allocate the next available BSSID. */
- do {
- inc_byte_array(hapd->own_addr, ETH_ALEN);
- } while (mac_in_conf(hapd->iconf, hapd->own_addr));
- } else {
+ u8 *addr = hapd->own_addr;
+
+ if (!is_zero_ether_addr(conf->bssid)) {
/* Allocate the configured BSSID. */
os_memcpy(hapd->own_addr, conf->bssid, ETH_ALEN);
@@ -922,11 +922,18 @@
"the radio", conf->iface);
return -1;
}
+ } else if (hapd->iconf->use_driver_iface_addr) {
+ addr = NULL;
+ } else {
+ /* Allocate the next available BSSID. */
+ do {
+ inc_byte_array(hapd->own_addr, ETH_ALEN);
+ } while (mac_in_conf(hapd->iconf, hapd->own_addr));
}
hapd->interface_added = 1;
if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS,
- conf->iface, hapd->own_addr, hapd,
+ conf->iface, addr, hapd,
&hapd->drv_priv, force_ifname, if_addr,
conf->bridge[0] ? conf->bridge : NULL,
first == -1)) {
@@ -935,6 +942,9 @@
hapd->interface_added = 0;
return -1;
}
+
+ if (!addr)
+ os_memcpy(hapd->own_addr, if_addr, ETH_ALEN);
}
if (conf->wmm_enabled < 0)
@@ -1859,6 +1869,7 @@
hapd->iface = hapd_iface;
hapd->driver = hapd->iconf->driver;
hapd->ctrl_sock = -1;
+ dl_list_init(&hapd->ctrl_dst);
return hapd;
}
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index d6d96db..60516ae 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -41,7 +41,7 @@
size_t count;
int global_ctrl_sock;
- struct wpa_ctrl_dst *global_ctrl_dst;
+ struct dl_list global_ctrl_dst;
char *global_iface_path;
char *global_iface_name;
#ifndef CONFIG_NATIVE_WINDOWS
@@ -155,7 +155,7 @@
int tkip_countermeasures;
int ctrl_sock;
- struct wpa_ctrl_dst *ctrl_dst;
+ struct dl_list ctrl_dst;
void *ssl_ctx;
void *eap_sim_db_priv;
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index b36e68d..134ae06 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -2782,6 +2782,25 @@
wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
hapd->new_assoc_sta_cb(hapd, sta, !new_assoc);
ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
+
+ if (sta->pending_eapol_rx) {
+ struct os_reltime now, age;
+
+ os_get_reltime(&now);
+ os_reltime_sub(&now, &sta->pending_eapol_rx->rx_time, &age);
+ if (age.sec == 0 && age.usec < 200000) {
+ wpa_printf(MSG_DEBUG,
+ "Process pending EAPOL frame that was received from " MACSTR " just before association notification",
+ MAC2STR(sta->addr));
+ ieee802_1x_receive(
+ hapd, mgmt->da,
+ wpabuf_head(sta->pending_eapol_rx->buf),
+ wpabuf_len(sta->pending_eapol_rx->buf));
+ }
+ wpabuf_free(sta->pending_eapol_rx->buf);
+ os_free(sta->pending_eapol_rx);
+ sta->pending_eapol_rx = NULL;
+ }
}
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index c774d5c..42b0299 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -861,6 +861,29 @@
}
+static void ieee802_1x_save_eapol(struct sta_info *sta, const u8 *buf,
+ size_t len)
+{
+ if (sta->pending_eapol_rx) {
+ wpabuf_free(sta->pending_eapol_rx->buf);
+ } else {
+ sta->pending_eapol_rx =
+ os_malloc(sizeof(*sta->pending_eapol_rx));
+ if (!sta->pending_eapol_rx)
+ return;
+ }
+
+ sta->pending_eapol_rx->buf = wpabuf_alloc_copy(buf, len);
+ if (!sta->pending_eapol_rx->buf) {
+ os_free(sta->pending_eapol_rx);
+ sta->pending_eapol_rx = NULL;
+ return;
+ }
+
+ os_get_reltime(&sta->pending_eapol_rx->rx_time);
+}
+
+
/**
* ieee802_1x_receive - Process the EAPOL frames from the Supplicant
* @hapd: hostapd BSS data
@@ -891,6 +914,13 @@
!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_WIRED))) {
wpa_printf(MSG_DEBUG, "IEEE 802.1X data frame from not "
"associated/Pre-authenticating STA");
+
+ if (sta && (sta->flags & WLAN_STA_AUTH)) {
+ wpa_printf(MSG_DEBUG, "Saving EAPOL frame from " MACSTR
+ " for later use", MAC2STR(sta->addr));
+ ieee802_1x_save_eapol(sta, buf, len);
+ }
+
return;
}
@@ -1183,6 +1213,12 @@
eloop_cancel_timeout(ieee802_1x_wnm_notif_send, hapd, sta);
#endif /* CONFIG_HS20 */
+ if (sta->pending_eapol_rx) {
+ wpabuf_free(sta->pending_eapol_rx->buf);
+ os_free(sta->pending_eapol_rx);
+ sta->pending_eapol_rx = NULL;
+ }
+
if (sm == NULL)
return;
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index cd89e99..70a59cc 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -56,6 +56,11 @@
u8 channels[];
};
+struct pending_eapol_rx {
+ struct wpabuf *buf;
+ struct os_reltime rx_time;
+};
+
struct sta_info {
struct sta_info *next; /* next entry in sta list */
struct sta_info *hnext; /* next entry in hash table list */
@@ -113,6 +118,8 @@
/* IEEE 802.1X related data */
struct eapol_state_machine *eapol_sm;
+ struct pending_eapol_rx *pending_eapol_rx;
+
u64 acct_session_id;
struct os_reltime acct_session_start;
int acct_session_started;