Cumulative patch from commit c06c9099f0d0827feae5622097bd8ac946eca5ea

c06c909 Use stronger PRNG for MS-MPPE-Send/Recv-Key salt
9e1f1bd eloop: Clean up coding style for eloop debug prints
f9982b3 Implement kqueue(2) support via CONFIG_ELOOP_KQUEUE
2e69bdd eloop: Add eloop_sock_requeue()
70f4f05 wpa_ctrl: Retry select() on EINTR
df9e2c2 D-Bus: Don't do <deny send_interface="..." /> in dbus service file
9684c75 mesh: Fix peer link counting when a mesh peer reconnects
83fe38b P2P: Fall back to no VHT when starting AP/P2P GO
360a9d5 P2P: Reduce off channel wait time for some P2P Action frames
1fc63fe RADIUS: Share a single function for generating session IDs
2cbc6ff RADIUS: Redesign Request Authenticator generation
b71a64a Send an Acct-Multi-Session-Id attribute in Access-Request packets
4260e1a Add Acct-Session-Id to Accounting-On/Off
d72a005 RADIUS: Use more likely unique accounting Acct-{,Multi-}Session-Id
d689317 EAPOL auth: Move radius_cui/identity freeing to eapol_auth_free()
0ae86f9 wpa_supplicant: Fix couple of C++ compiler errors with header files
9b6177a Add Event-Timestamp to all Accounting-Request packets
d179089 GAS: Calculate response buffer length of ANQP elements
dda091c OpenSSL: Fix server side PKCS#12 processing with extra certificates
443c8e1 OpenSSL: Fix possible null pointer dereference on an OCSP error path
a3cc64f Remove -w support from wpa_supplicant README
e265838 EAP-FAST: Fix an error path in PAC binary format parsing
f91e11f D-Bus: Fix p2p interface capability message
479f46c Do not send Acct-Authentic in Accounting-On/Off
696544e RADIUS: Do not include Acct-Terminate-Cause in Accounting-On/Off
236053e Make fallback from HT40 to HT20 work
cb22e3b BSD: Zero ifindex on interface removal
a8ef133 Android: Support multiple CA certs when connecting to EAP network
80ce804 WNM: Workaround for broken AP operating class behavior
af06093 BSD: Disable interface on down
dc0ad60 BSD: Use correct ifindex from route messages
5f17b2c BSD: __FUNCTION__ -> __func__
2088ecb OSU: Add debug printing of more LogotypeExtn fields
0b905c8 Add the selector suite into wpa_parse_wpa_ie_rsn() "invalid group cipher"
03a72ea VHT: Add an interoperability workaround for 80+80 and 160 MHz channels

Change-Id: Ief9174bdec380e81025e1467c47bf1656eb39cd9
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/accounting.c b/src/ap/accounting.c
index c60b3a6..f3ce121 100644
--- a/src/ap/accounting.c
+++ b/src/ap/accounting.c
@@ -41,6 +41,7 @@
 	size_t len;
 	int i;
 	struct wpabuf *b;
+	struct os_time now;
 
 	msg = radius_msg_new(RADIUS_CODE_ACCOUNTING_REQUEST,
 			     radius_client_get_id(hapd->radius));
@@ -49,25 +50,9 @@
 		return NULL;
 	}
 
-	if (sta) {
-		radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta));
-
-		if ((hapd->conf->wpa & 2) &&
-		    !hapd->conf->disable_pmksa_caching &&
-		    sta->eapol_sm && sta->eapol_sm->acct_multi_session_id_hi) {
-			os_snprintf(buf, sizeof(buf), "%08X+%08X",
-				    sta->eapol_sm->acct_multi_session_id_hi,
-				    sta->eapol_sm->acct_multi_session_id_lo);
-			if (!radius_msg_add_attr(
-				    msg, RADIUS_ATTR_ACCT_MULTI_SESSION_ID,
-				    (u8 *) buf, os_strlen(buf))) {
-				wpa_printf(MSG_INFO,
-					   "Could not add Acct-Multi-Session-Id");
-				goto fail;
-			}
-		}
-	} else {
-		radius_msg_make_authenticator(msg, (u8 *) hapd, sizeof(*hapd));
+	if (radius_msg_make_authenticator(msg) < 0) {
+		wpa_printf(MSG_INFO, "Could not make Request Authenticator");
+		goto fail;
 	}
 
 	if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_STATUS_TYPE,
@@ -76,17 +61,18 @@
 		goto fail;
 	}
 
-	if (!hostapd_config_get_radius_attr(hapd->conf->radius_acct_req_attr,
-					    RADIUS_ATTR_ACCT_AUTHENTIC) &&
-	    !radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_AUTHENTIC,
-				       hapd->conf->ieee802_1x ?
-				       RADIUS_ACCT_AUTHENTIC_RADIUS :
-				       RADIUS_ACCT_AUTHENTIC_LOCAL)) {
-		wpa_printf(MSG_INFO, "Could not add Acct-Authentic");
-		goto fail;
-	}
-
 	if (sta) {
+		if (!hostapd_config_get_radius_attr(
+			    hapd->conf->radius_acct_req_attr,
+			    RADIUS_ATTR_ACCT_AUTHENTIC) &&
+		    !radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_AUTHENTIC,
+					       hapd->conf->ieee802_1x ?
+					       RADIUS_ACCT_AUTHENTIC_RADIUS :
+					       RADIUS_ACCT_AUTHENTIC_LOCAL)) {
+			wpa_printf(MSG_INFO, "Could not add Acct-Authentic");
+			goto fail;
+		}
+
 		/* Use 802.1X identity if available */
 		val = ieee802_1x_get_identity(sta->eapol_sm, &len);
 
@@ -158,6 +144,14 @@
 		}
 	}
 
+	os_get_time(&now);
+	if (now.sec > 1000000000 &&
+	    !radius_msg_add_attr_int32(msg, RADIUS_ATTR_EVENT_TIMESTAMP,
+				       now.sec)) {
+		wpa_printf(MSG_INFO, "Could not add Event-Timestamp");
+		goto fail;
+	}
+
 	return msg;
 
  fail:
@@ -226,8 +220,8 @@
 
 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
 		       HOSTAPD_LEVEL_INFO,
-		       "starting accounting session %08X-%08X",
-		       sta->acct_session_id_hi, sta->acct_session_id_lo);
+		       "starting accounting session %016lX",
+		       (long unsigned int) sta->acct_session_id);
 
 	os_get_reltime(&sta->acct_session_start);
 	sta->last_rx_bytes = sta->last_tx_bytes = 0;
@@ -260,7 +254,6 @@
 	int cause = sta->acct_terminate_cause;
 	struct hostap_sta_driver_data data;
 	struct os_reltime now_r, diff;
-	struct os_time now;
 	u32 gigawords;
 
 	if (!hapd->conf->radius->acct_server)
@@ -275,7 +268,6 @@
 	}
 
 	os_get_reltime(&now_r);
-	os_get_time(&now);
 	os_reltime_sub(&now_r, &sta->acct_session_start, &diff);
 	if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_SESSION_TIME,
 				       diff.sec)) {
@@ -332,12 +324,6 @@
 		}
 	}
 
-	if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_EVENT_TIMESTAMP,
-				       now.sec)) {
-		wpa_printf(MSG_INFO, "Could not add Event-Timestamp");
-		goto fail;
-	}
-
 	if (eloop_terminated())
 		cause = RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_REBOOT;
 
@@ -384,22 +370,17 @@
 		eloop_cancel_timeout(accounting_interim_update, hapd, sta);
 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
 			       HOSTAPD_LEVEL_INFO,
-			       "stopped accounting session %08X-%08X",
-			       sta->acct_session_id_hi,
-			       sta->acct_session_id_lo);
+			       "stopped accounting session %016lX",
+			       (long unsigned int) sta->acct_session_id);
 		sta->acct_session_started = 0;
 	}
 }
 
 
-void accounting_sta_get_id(struct hostapd_data *hapd,
-				  struct sta_info *sta)
+int accounting_sta_get_id(struct hostapd_data *hapd, struct sta_info *sta)
 {
-	sta->acct_session_id_lo = hapd->acct_session_id_lo++;
-	if (hapd->acct_session_id_lo == 0) {
-		hapd->acct_session_id_hi++;
-	}
-	sta->acct_session_id_hi = hapd->acct_session_id_hi;
+	return radius_gen_session_id((u8 *) &sta->acct_session_id,
+				     sizeof(sta->acct_session_id));
 }
 
 
@@ -446,12 +427,14 @@
 	if (!msg)
 		return;
 
-	if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_TERMINATE_CAUSE,
-				       RADIUS_ACCT_TERMINATE_CAUSE_NAS_REBOOT))
-	{
-		wpa_printf(MSG_INFO, "Could not add Acct-Terminate-Cause");
-		radius_msg_free(msg);
-		return;
+	if (hapd->acct_session_id) {
+		char buf[20];
+
+		os_snprintf(buf, sizeof(buf), "%016lX",
+			    (long unsigned int) hapd->acct_session_id);
+		if (!radius_msg_add_attr(msg, RADIUS_ATTR_ACCT_SESSION_ID,
+					 (u8 *) buf, os_strlen(buf)))
+			wpa_printf(MSG_ERROR, "Could not add Acct-Session-Id");
 	}
 
 	if (radius_client_send(hapd->radius, msg, RADIUS_ACCT, NULL) < 0)
@@ -466,16 +449,9 @@
  */
 int accounting_init(struct hostapd_data *hapd)
 {
-	struct os_time now;
-
-	/* Acct-Session-Id should be unique over reboots. Using a random number
-	 * is preferred. If that is not available, take the current time. Mix
-	 * in microseconds to make this more likely to be unique. */
-	os_get_time(&now);
-	if (os_get_random((u8 *) &hapd->acct_session_id_hi,
-			  sizeof(hapd->acct_session_id_hi)) < 0)
-		hapd->acct_session_id_hi = now.sec;
-	hapd->acct_session_id_hi ^= now.usec;
+	if (radius_gen_session_id((u8 *) &hapd->acct_session_id,
+				  sizeof(hapd->acct_session_id)) < 0)
+		return -1;
 
 	if (radius_client_register(hapd->radius, RADIUS_ACCT,
 				   accounting_receive, hapd))
diff --git a/src/ap/accounting.h b/src/ap/accounting.h
index dcc54ee..de5a33f 100644
--- a/src/ap/accounting.h
+++ b/src/ap/accounting.h
@@ -10,9 +10,10 @@
 #define ACCOUNTING_H
 
 #ifdef CONFIG_NO_ACCOUNTING
-static inline void accounting_sta_get_id(struct hostapd_data *hapd,
-					 struct sta_info *sta)
+static inline int accounting_sta_get_id(struct hostapd_data *hapd,
+					struct sta_info *sta)
 {
+	return 0;
 }
 
 static inline void accounting_sta_start(struct hostapd_data *hapd,
@@ -34,7 +35,7 @@
 {
 }
 #else /* CONFIG_NO_ACCOUNTING */
-void accounting_sta_get_id(struct hostapd_data *hapd, struct sta_info *sta);
+int accounting_sta_get_id(struct hostapd_data *hapd, struct sta_info *sta);
 void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta);
 void accounting_sta_stop(struct hostapd_data *hapd, struct sta_info *sta);
 int accounting_init(struct hostapd_data *hapd);
diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c
index b9d6176..179dc7a 100644
--- a/src/ap/gas_serv.c
+++ b/src/ap/gas_serv.c
@@ -786,6 +786,24 @@
 #endif /* CONFIG_HS20 */
 
 
+static size_t anqp_get_required_len(struct hostapd_data *hapd,
+				    const u16 *infoid,
+				    unsigned int num_infoid)
+{
+	size_t len = 0;
+	unsigned int i;
+
+	for (i = 0; i < num_infoid; i++) {
+		struct anqp_element *elem = get_anqp_elem(hapd, infoid[i]);
+
+		if (elem)
+			len += 2 + 2 + wpabuf_len(elem->payload);
+	}
+
+	return len;
+}
+
+
 static struct wpabuf *
 gas_serv_build_gas_resp_payload(struct hostapd_data *hapd,
 				unsigned int request,
@@ -803,7 +821,7 @@
 		len += 1000;
 	if (request & ANQP_REQ_ICON_REQUEST)
 		len += 65536;
-	len += num_extra_req * 1000;
+	len += anqp_get_required_len(hapd, extra_req, num_extra_req);
 
 	buf = wpabuf_alloc(len);
 	if (buf == NULL)
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 2aa4f8c..a848f35 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -673,7 +673,7 @@
 
 	if (attr->acct_session_id) {
 		num_attr++;
-		if (attr->acct_session_id_len != 17) {
+		if (attr->acct_session_id_len != 16) {
 			wpa_printf(MSG_DEBUG,
 				   "RADIUS DAS: Acct-Session-Id cannot match");
 			return NULL;
@@ -683,10 +683,9 @@
 		for (sta = hapd->sta_list; sta; sta = sta->next) {
 			if (!sta->radius_das_match)
 				continue;
-			os_snprintf(buf, sizeof(buf), "%08X-%08X",
-				    sta->acct_session_id_hi,
-				    sta->acct_session_id_lo);
-			if (os_memcmp(attr->acct_session_id, buf, 17) != 0)
+			os_snprintf(buf, sizeof(buf), "%016lX",
+				    (long unsigned int) sta->acct_session_id);
+			if (os_memcmp(attr->acct_session_id, buf, 16) != 0)
 				sta->radius_das_match = 0;
 			else
 				count++;
@@ -702,7 +701,7 @@
 
 	if (attr->acct_multi_session_id) {
 		num_attr++;
-		if (attr->acct_multi_session_id_len != 17) {
+		if (attr->acct_multi_session_id_len != 16) {
 			wpa_printf(MSG_DEBUG,
 				   "RADIUS DAS: Acct-Multi-Session-Id cannot match");
 			return NULL;
@@ -713,14 +712,14 @@
 			if (!sta->radius_das_match)
 				continue;
 			if (!sta->eapol_sm ||
-			    !sta->eapol_sm->acct_multi_session_id_hi) {
+			    !sta->eapol_sm->acct_multi_session_id) {
 				sta->radius_das_match = 0;
 				continue;
 			}
-			os_snprintf(buf, sizeof(buf), "%08X+%08X",
-				    sta->eapol_sm->acct_multi_session_id_hi,
-				    sta->eapol_sm->acct_multi_session_id_lo);
-			if (os_memcmp(attr->acct_multi_session_id, buf, 17) !=
+			os_snprintf(buf, sizeof(buf), "%016lX",
+				    (long unsigned int)
+				    sta->eapol_sm->acct_multi_session_id);
+			if (os_memcmp(attr->acct_multi_session_id, buf, 16) !=
 			    0)
 				sta->radius_das_match = 0;
 			else
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index 7b59f80..0f31dd4 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -138,7 +138,7 @@
 	void *msg_ctx_parent; /* parent interface ctx for wpa_msg() calls */
 
 	struct radius_client_data *radius;
-	u32 acct_session_id_hi, acct_session_id_lo;
+	u64 acct_session_id;
 	struct radius_das_data *radius_das;
 
 	struct iapp_data *iapp;
@@ -258,7 +258,8 @@
 #ifdef CONFIG_MESH
 	int num_plinks;
 	int max_plinks;
-	void (*mesh_sta_free_cb)(struct sta_info *sta);
+	void (*mesh_sta_free_cb)(struct hostapd_data *hapd,
+				 struct sta_info *sta);
 	struct wpabuf *mesh_pending_auth;
 	struct os_reltime mesh_pending_auth_time;
 #endif /* CONFIG_MESH */
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index 3607066..16887ac 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -329,6 +329,7 @@
 	res = ieee80211n_allowed_ht40_channel_pair(iface);
 	if (!res) {
 		iface->conf->secondary_channel = 0;
+		res = 1;
 		wpa_printf(MSG_INFO, "Fallback to 20 MHz");
 	}
 
diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c
index b7e7ce3..ec0037a 100644
--- a/src/ap/ieee802_11_auth.c
+++ b/src/ap/ieee802_11_auth.c
@@ -165,7 +165,10 @@
 	if (msg == NULL)
 		return -1;
 
-	radius_msg_make_authenticator(msg, addr, ETH_ALEN);
+	if (radius_msg_make_authenticator(msg) < 0) {
+		wpa_printf(MSG_INFO, "Could not make Request Authenticator");
+		goto fail;
+	}
 
 	os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT, MAC2STR(addr));
 	if (!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, (u8 *) buf,
diff --git a/src/ap/ieee802_11_vht.c b/src/ap/ieee802_11_vht.c
index 3236016..0841898 100644
--- a/src/ap/ieee802_11_vht.c
+++ b/src/ap/ieee802_11_vht.c
@@ -81,6 +81,26 @@
 		hapd->iconf->vht_oper_centr_freq_seg1_idx;
 
 	oper->vht_op_info_chwidth = hapd->iconf->vht_oper_chwidth;
+	if (hapd->iconf->vht_oper_chwidth == 2) {
+		/*
+		 * Convert 160 MHz channel width to new style as interop
+		 * workaround.
+		 */
+		oper->vht_op_info_chwidth = 1;
+		oper->vht_op_info_chan_center_freq_seg1_idx =
+			oper->vht_op_info_chan_center_freq_seg0_idx;
+		if (hapd->iconf->channel <
+		    hapd->iconf->vht_oper_centr_freq_seg0_idx)
+			oper->vht_op_info_chan_center_freq_seg0_idx -= 8;
+		else
+			oper->vht_op_info_chan_center_freq_seg0_idx += 8;
+	} else if (hapd->iconf->vht_oper_chwidth == 3) {
+		/*
+		 * Convert 80+80 MHz channel width to new style as interop
+		 * workaround.
+		 */
+		oper->vht_op_info_chwidth = 1;
+	}
 
 	/* VHT Basic MCS set comes from hw */
 	/* Hard code 1 stream, MCS0-7 is a min Basic VHT MCS rates */
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 607f941..d399b1e 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -438,9 +438,9 @@
 		return -1;
 	}
 
-	if (sta->acct_session_id_hi || sta->acct_session_id_lo) {
-		os_snprintf(buf, sizeof(buf), "%08X-%08X",
-			    sta->acct_session_id_hi, sta->acct_session_id_lo);
+	if (sta->acct_session_id) {
+		os_snprintf(buf, sizeof(buf), "%016lX",
+			    (long unsigned int) sta->acct_session_id);
 		if (!radius_msg_add_attr(msg, RADIUS_ATTR_ACCT_SESSION_ID,
 					 (u8 *) buf, os_strlen(buf))) {
 			wpa_printf(MSG_ERROR, "Could not add Acct-Session-Id");
@@ -448,6 +448,21 @@
 		}
 	}
 
+	if ((hapd->conf->wpa & 2) &&
+	    !hapd->conf->disable_pmksa_caching &&
+	    sta->eapol_sm && sta->eapol_sm->acct_multi_session_id) {
+		os_snprintf(buf, sizeof(buf), "%016lX",
+			    (long unsigned int)
+			    sta->eapol_sm->acct_multi_session_id);
+		if (!radius_msg_add_attr(
+			    msg, RADIUS_ATTR_ACCT_MULTI_SESSION_ID,
+			    (u8 *) buf, os_strlen(buf))) {
+			wpa_printf(MSG_INFO,
+				   "Could not add Acct-Multi-Session-Id");
+			return -1;
+		}
+	}
+
 #ifdef CONFIG_IEEE80211R
 	if (hapd->conf->wpa && wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt) &&
 	    sta->wpa_sm &&
@@ -587,7 +602,10 @@
 		return;
 	}
 
-	radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta));
+	if (radius_msg_make_authenticator(msg) < 0) {
+		wpa_printf(MSG_INFO, "Could not make Request Authenticator");
+		goto fail;
+	}
 
 	if (sm->identity &&
 	    !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME,
@@ -1165,10 +1183,8 @@
 #ifndef CONFIG_NO_RADIUS
 	radius_msg_free(sm->last_recv_radius);
 	radius_free_class(&sm->radius_class);
-	wpabuf_free(sm->radius_cui);
 #endif /* CONFIG_NO_RADIUS */
 
-	os_free(sm->identity);
 	eapol_auth_free(sm);
 }
 
@@ -2495,12 +2511,12 @@
 			  /* TODO: dot1xAuthSessionOctetsTx */
 			  /* TODO: dot1xAuthSessionFramesRx */
 			  /* TODO: dot1xAuthSessionFramesTx */
-			  "dot1xAuthSessionId=%08X-%08X\n"
+			  "dot1xAuthSessionId=%016lX\n"
 			  "dot1xAuthSessionAuthenticMethod=%d\n"
 			  "dot1xAuthSessionTime=%u\n"
 			  "dot1xAuthSessionTerminateCause=999\n"
 			  "dot1xAuthSessionUserName=%s\n",
-			  sta->acct_session_id_hi, sta->acct_session_id_lo,
+			  (long unsigned int) sta->acct_session_id,
 			  (wpa_key_mgmt_wpa_ieee8021x(
 				   wpa_auth_sta_key_mgmt(sta->wpa_sm))) ?
 			  1 : 2,
@@ -2510,11 +2526,11 @@
 		return len;
 	len += ret;
 
-	if (sm->acct_multi_session_id_hi) {
+	if (sm->acct_multi_session_id) {
 		ret = os_snprintf(buf + len, buflen - len,
-				  "authMultiSessionId=%08X+%08X\n",
-				  sm->acct_multi_session_id_hi,
-				  sm->acct_multi_session_id_lo);
+				  "authMultiSessionId=%016lX\n",
+				  (long unsigned int)
+				  sm->acct_multi_session_id);
 		if (os_snprintf_error(buflen - len, ret))
 			return len;
 		len += ret;
diff --git a/src/ap/pmksa_cache_auth.c b/src/ap/pmksa_cache_auth.c
index 83e4bda..eb37c78 100644
--- a/src/ap/pmksa_cache_auth.c
+++ b/src/ap/pmksa_cache_auth.c
@@ -148,8 +148,7 @@
 	entry->eap_type_authsrv = eapol->eap_type_authsrv;
 	entry->vlan_id = ((struct sta_info *) eapol->sta)->vlan_id;
 
-	entry->acct_multi_session_id_hi = eapol->acct_multi_session_id_hi;
-	entry->acct_multi_session_id_lo = eapol->acct_multi_session_id_lo;
+	entry->acct_multi_session_id = eapol->acct_multi_session_id;
 }
 
 
@@ -188,8 +187,7 @@
 	eapol->eap_type_authsrv = entry->eap_type_authsrv;
 	((struct sta_info *) eapol->sta)->vlan_id = entry->vlan_id;
 
-	eapol->acct_multi_session_id_hi = entry->acct_multi_session_id_hi;
-	eapol->acct_multi_session_id_lo = entry->acct_multi_session_id_lo;
+	eapol->acct_multi_session_id = entry->acct_multi_session_id;
 }
 
 
@@ -471,12 +469,11 @@
 	if (attr->acct_multi_session_id) {
 		char buf[20];
 
-		if (attr->acct_multi_session_id_len != 17)
+		if (attr->acct_multi_session_id_len != 16)
 			return 0;
-		os_snprintf(buf, sizeof(buf), "%08X+%08X",
-			    entry->acct_multi_session_id_hi,
-			    entry->acct_multi_session_id_lo);
-		if (os_memcmp(attr->acct_multi_session_id, buf, 17) != 0)
+		os_snprintf(buf, sizeof(buf), "%016lX",
+			    (long unsigned int) entry->acct_multi_session_id);
+		if (os_memcmp(attr->acct_multi_session_id, buf, 16) != 0)
 			return 0;
 		match++;
 	}
diff --git a/src/ap/pmksa_cache_auth.h b/src/ap/pmksa_cache_auth.h
index b2da379..4dc841f 100644
--- a/src/ap/pmksa_cache_auth.h
+++ b/src/ap/pmksa_cache_auth.h
@@ -31,8 +31,7 @@
 	int vlan_id;
 	int opportunistic;
 
-	u32 acct_multi_session_id_hi;
-	u32 acct_multi_session_id_lo;
+	u64 acct_multi_session_id;
 };
 
 struct rsn_pmksa_cache;
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index 8bba73c..3d7c839 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -238,7 +238,7 @@
 
 #ifdef CONFIG_MESH
 	if (hapd->mesh_sta_free_cb)
-		hapd->mesh_sta_free_cb(sta);
+		hapd->mesh_sta_free_cb(hapd, sta);
 #endif /* CONFIG_MESH */
 
 	if (set_beacon)
@@ -625,7 +625,10 @@
 		return NULL;
 	}
 	sta->acct_interim_interval = hapd->conf->acct_interim_interval;
-	accounting_sta_get_id(hapd, sta);
+	if (accounting_sta_get_id(hapd, sta) < 0) {
+		os_free(sta);
+		return NULL;
+	}
 
 	if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) {
 		wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout "
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index e3b4915..359f480 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -101,8 +101,7 @@
 	/* IEEE 802.1X related data */
 	struct eapol_state_machine *eapol_sm;
 
-	u32 acct_session_id_hi;
-	u32 acct_session_id_lo;
+	u64 acct_session_id;
 	struct os_reltime acct_session_start;
 	int acct_session_started;
 	int acct_terminate_cause; /* Acct-Terminate-Cause */