mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-29 17:42:41 +00:00 
			
		
		
		
	hostapd: sync built-in version
Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
		
							
								
								
									
										781
									
								
								patches/0069-hostapd-sync-builtin-patches.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										781
									
								
								patches/0069-hostapd-sync-builtin-patches.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,781 @@ | ||||
| From b09c1180c1ba4a30b70530b90748e7682931b91a Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Mon, 20 Nov 2023 08:33:42 +0100 | ||||
| Subject: [PATCH] hostapd: sync builtin patches | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  .../network/services/hostapd/files/hostapd.sh |   5 +- | ||||
|  .../hostapd/patches/760-acs_exclude_dfs.patch |   8 +- | ||||
|  .../hostapd/patches/780-maxassoc.patch        |   6 +- | ||||
|  .../patches/790-wired-dynamic-vlan.patch      |  33 +++ | ||||
|  .../services/hostapd/patches/900-coa.patch    |  22 ++ | ||||
|  .../hostapd/patches/901-cfg-section.patch     |  38 +-- | ||||
|  .../hostapd/patches/901-coa-ubus.patch        |  28 +++ | ||||
|  .../hostapd/patches/999-das-proxy-state.patch |  95 ++++++++ | ||||
|  .../hostapd/patches/999-ssi_signal.patch      |  81 +++++++ | ||||
|  .../services/hostapd/src/src/ap/ubus.c        | 229 ++++++++++++++++-- | ||||
|  .../services/hostapd/src/src/ap/ubus.h        |   1 + | ||||
|  11 files changed, 491 insertions(+), 55 deletions(-) | ||||
|  create mode 100644 package/network/services/hostapd/patches/790-wired-dynamic-vlan.patch | ||||
|  create mode 100644 package/network/services/hostapd/patches/900-coa.patch | ||||
|  create mode 100644 package/network/services/hostapd/patches/901-coa-ubus.patch | ||||
|  create mode 100644 package/network/services/hostapd/patches/999-das-proxy-state.patch | ||||
|  create mode 100644 package/network/services/hostapd/patches/999-ssi_signal.patch | ||||
|  | ||||
| diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh | ||||
| index 145848189d..19d5138510 100644 | ||||
| --- a/package/network/services/hostapd/files/hostapd.sh | ||||
| +++ b/package/network/services/hostapd/files/hostapd.sh | ||||
| @@ -48,15 +48,14 @@ hostapd_append_wpa_key_mgmt() { | ||||
|  		;; | ||||
|  		eap192) | ||||
|  			append wpa_key_mgmt "WPA-EAP-SUITE-B-192" | ||||
| -			append wpa_key_mgmt "WPA-EAP-SHA256" | ||||
|  			[ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP" | ||||
|  		;; | ||||
| -		eap-eap256) | ||||
| +		eap-eap2) | ||||
|  			append wpa_key_mgmt "WPA-EAP" | ||||
|  			append wpa_key_mgmt "WPA-EAP-SHA256" | ||||
|  			[ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP" | ||||
|  		;; | ||||
| -		eap256) | ||||
| +		eap2) | ||||
|  			append wpa_key_mgmt "WPA-EAP-SHA256" | ||||
|  			[ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP" | ||||
|  		;; | ||||
| diff --git a/package/network/services/hostapd/patches/760-acs_exclude_dfs.patch b/package/network/services/hostapd/patches/760-acs_exclude_dfs.patch | ||||
| index 52d63c5ff9..27b3a6161a 100644 | ||||
| --- a/package/network/services/hostapd/patches/760-acs_exclude_dfs.patch | ||||
| +++ b/package/network/services/hostapd/patches/760-acs_exclude_dfs.patch | ||||
| @@ -1,8 +1,6 @@ | ||||
| -Index: hostapd-2021-02-20-59e9794c/src/ap/acs.c | ||||
| -=================================================================== | ||||
| ---- hostapd-2021-02-20-59e9794c.orig/src/ap/acs.c | ||||
| -+++ hostapd-2021-02-20-59e9794c/src/ap/acs.c | ||||
| -@@ -672,6 +672,10 @@ acs_find_ideal_chan_mode(struct hostapd_ | ||||
| +--- a/src/ap/acs.c | ||||
| ++++ b/src/ap/acs.c | ||||
| +@@ -668,6 +668,10 @@ acs_find_ideal_chan_mode(struct hostapd_ | ||||
|   			continue; | ||||
|   		} | ||||
|    | ||||
| diff --git a/package/network/services/hostapd/patches/780-maxassoc.patch b/package/network/services/hostapd/patches/780-maxassoc.patch | ||||
| index 98840f382a..07fc54e142 100644 | ||||
| --- a/package/network/services/hostapd/patches/780-maxassoc.patch | ||||
| +++ b/package/network/services/hostapd/patches/780-maxassoc.patch | ||||
| @@ -1,7 +1,5 @@ | ||||
| -Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c | ||||
| -=================================================================== | ||||
| ---- hostapd-2021-02-20-59e9794c.orig/src/ap/sta_info.c | ||||
| -+++ hostapd-2021-02-20-59e9794c/src/ap/sta_info.c | ||||
| +--- a/src/ap/sta_info.c | ||||
| ++++ b/src/ap/sta_info.c | ||||
|  @@ -717,7 +717,7 @@ struct sta_info * ap_sta_add(struct host | ||||
|   		return sta; | ||||
|    | ||||
| diff --git a/package/network/services/hostapd/patches/790-wired-dynamic-vlan.patch b/package/network/services/hostapd/patches/790-wired-dynamic-vlan.patch | ||||
| new file mode 100644 | ||||
| index 0000000000..f673c3e34f | ||||
| --- /dev/null | ||||
| +++ b/package/network/services/hostapd/patches/790-wired-dynamic-vlan.patch | ||||
| @@ -0,0 +1,33 @@ | ||||
| +Index: hostapd-2021-02-20-59e9794c/src/ap/vlan_init.c | ||||
| +=================================================================== | ||||
| +--- hostapd-2021-02-20-59e9794c.orig/src/ap/vlan_init.c | ||||
| ++++ hostapd-2021-02-20-59e9794c/src/ap/vlan_init.c | ||||
| +@@ -37,7 +37,14 @@ static int vlan_if_add(struct hostapd_da | ||||
| + 	} | ||||
| + #endif /* CONFIG_WEP */ | ||||
| +  | ||||
| +-	if (!vlan_exists) | ||||
| ++	if (!hapd->driver || !hapd->driver->if_add) { | ||||
| ++		char *dot = strstr(vlan->ifname, "."); | ||||
| ++		if (dot) | ||||
| ++			*dot = '\0'; | ||||
| ++		ret = 0; | ||||
| ++	} | ||||
| ++	 | ||||
| ++	else if (!vlan_exists) | ||||
| + 		ret = hostapd_vlan_if_add(hapd, vlan->ifname); | ||||
| + 	else if (!existsok) | ||||
| + 		return -1; | ||||
| +Index: hostapd-2021-02-20-59e9794c/src/ap/vlan_init.c | ||||
| +=================================================================== | ||||
| +--- hostapd-2021-02-20-59e9794c.orig/src/ap/vlan_init.c | ||||
| ++++ hostapd-2021-02-20-59e9794c/src/ap/vlan_init.c | ||||
| +@@ -59,7 +59,7 @@ static int vlan_if_add(struct hostapd_da | ||||
| + 	if (hapd->wpa_auth) | ||||
| + 		ret = wpa_auth_ensure_group(hapd->wpa_auth, vlan->vlan_id); | ||||
| +  | ||||
| +-	if (!ret && !vlan_exists) | ||||
| ++	if (!ret && !vlan_exists && hapd->driver->if_add) | ||||
| + 		hostapd_ubus_add_vlan(hapd, vlan); | ||||
| +  | ||||
| + 	if (ret == 0) | ||||
| diff --git a/package/network/services/hostapd/patches/900-coa.patch b/package/network/services/hostapd/patches/900-coa.patch | ||||
| new file mode 100644 | ||||
| index 0000000000..3e1213a4dd | ||||
| --- /dev/null | ||||
| +++ b/package/network/services/hostapd/patches/900-coa.patch | ||||
| @@ -0,0 +1,22 @@ | ||||
| +--- a/src/radius/radius_das.c | ||||
| ++++ b/src/radius/radius_das.c | ||||
| +@@ -48,6 +48,8 @@ static struct radius_msg * radius_das_di | ||||
| + 		RADIUS_ATTR_EVENT_TIMESTAMP, | ||||
| + 		RADIUS_ATTR_MESSAGE_AUTHENTICATOR, | ||||
| + 		RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, | ||||
| ++		RADIUS_ATTR_VENDOR_SPECIFIC, | ||||
| ++		RADIUS_ATTR_CALLED_STATION_ID, | ||||
| + #ifdef CONFIG_IPV6 | ||||
| + 		RADIUS_ATTR_NAS_IPV6_ADDRESS, | ||||
| + #endif /* CONFIG_IPV6 */ | ||||
| +@@ -205,9 +207,8 @@ static struct radius_msg * radius_das_co | ||||
| + 		RADIUS_ATTR_EVENT_TIMESTAMP, | ||||
| + 		RADIUS_ATTR_MESSAGE_AUTHENTICATOR, | ||||
| + 		RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, | ||||
| +-#ifdef CONFIG_HS20 | ||||
| + 		RADIUS_ATTR_VENDOR_SPECIFIC, | ||||
| +-#endif /* CONFIG_HS20 */ | ||||
| ++		RADIUS_ATTR_CALLED_STATION_ID, | ||||
| + #ifdef CONFIG_IPV6 | ||||
| + 		RADIUS_ATTR_NAS_IPV6_ADDRESS, | ||||
| + #endif /* CONFIG_IPV6 */ | ||||
| diff --git a/package/network/services/hostapd/patches/901-cfg-section.patch b/package/network/services/hostapd/patches/901-cfg-section.patch | ||||
| index 657c5054f6..05fd6a6512 100644 | ||||
| --- a/package/network/services/hostapd/patches/901-cfg-section.patch | ||||
| +++ b/package/network/services/hostapd/patches/901-cfg-section.patch | ||||
| @@ -1,7 +1,7 @@ | ||||
| -Index: hostapd-2023-06-22-599d00be/hostapd/config_file.c | ||||
| +Index: hostapd-2023-09-08-e5ccbfc6/hostapd/config_file.c | ||||
|  =================================================================== | ||||
| ---- hostapd-2023-06-22-599d00be.orig/hostapd/config_file.c | ||||
| -+++ hostapd-2023-06-22-599d00be/hostapd/config_file.c | ||||
| +--- hostapd-2023-09-08-e5ccbfc6.orig/hostapd/config_file.c | ||||
| ++++ hostapd-2023-09-08-e5ccbfc6/hostapd/config_file.c | ||||
|  @@ -2345,6 +2345,8 @@ static int hostapd_config_fill(struct ho | ||||
|   			return 1; | ||||
|   		} | ||||
| @@ -11,36 +11,22 @@ Index: hostapd-2023-06-22-599d00be/hostapd/config_file.c | ||||
|   	} else if (os_strcmp(buf, "driver_params") == 0) { | ||||
|   		os_free(conf->driver_params); | ||||
|   		conf->driver_params = os_strdup(pos); | ||||
| -Index: hostapd-2023-06-22-599d00be/src/ap/ap_config.h | ||||
| +Index: hostapd-2023-09-08-e5ccbfc6/src/ap/ap_config.h | ||||
|  =================================================================== | ||||
| ---- hostapd-2023-06-22-599d00be.orig/src/ap/ap_config.h | ||||
| -+++ hostapd-2023-06-22-599d00be/src/ap/ap_config.h | ||||
| -@@ -288,6 +288,7 @@ struct hostapd_bss_config { | ||||
| +--- hostapd-2023-09-08-e5ccbfc6.orig/src/ap/ap_config.h | ||||
| ++++ hostapd-2023-09-08-e5ccbfc6/src/ap/ap_config.h | ||||
| +@@ -287,6 +287,7 @@ struct hostapd_bss_config { | ||||
| + 	char snoop_iface[IFNAMSIZ + 1]; | ||||
|   	char vlan_bridge[IFNAMSIZ + 1]; | ||||
|   	char wds_bridge[IFNAMSIZ + 1]; | ||||
| - 	int bridge_hairpin; /* hairpin_mode on bridge members */ | ||||
|  +	char *uci_section; | ||||
| + 	int bridge_hairpin; /* hairpin_mode on bridge members */ | ||||
|    | ||||
|   	enum hostapd_logger_level logger_syslog_level, logger_stdout_level; | ||||
| -  | ||||
| -Index: hostapd-2023-06-22-599d00be/src/ap/ubus.c | ||||
| -=================================================================== | ||||
| ---- hostapd-2023-06-22-599d00be.orig/src/ap/ubus.c | ||||
| -+++ hostapd-2023-06-22-599d00be/src/ap/ubus.c | ||||
| -@@ -418,6 +418,9 @@ hostapd_bss_get_status(struct ubus_conte | ||||
| - 			hapd->iface->cac_started ? hapd->iface->dfs_cac_ms / 1000 - now.sec : 0); | ||||
| - 	blobmsg_close_table(&b, dfs_table); | ||||
| -  | ||||
| -+	if (hapd->conf->uci_section) | ||||
| -+		blobmsg_add_string(&b, "uci_section", hapd->conf->uci_section); | ||||
| -+ | ||||
| - 	ubus_send_reply(ctx, req, b.head); | ||||
| -  | ||||
| - 	return 0; | ||||
| -Index: hostapd-2023-06-22-599d00be/src/ap/ap_config.c | ||||
| +Index: hostapd-2023-09-08-e5ccbfc6/src/ap/ap_config.c | ||||
|  =================================================================== | ||||
| ---- hostapd-2023-06-22-599d00be.orig/src/ap/ap_config.c | ||||
| -+++ hostapd-2023-06-22-599d00be/src/ap/ap_config.c | ||||
| +--- hostapd-2023-09-08-e5ccbfc6.orig/src/ap/ap_config.c | ||||
| ++++ hostapd-2023-09-08-e5ccbfc6/src/ap/ap_config.c | ||||
|  @@ -798,6 +798,7 @@ void hostapd_config_free_bss(struct host | ||||
|   	os_free(conf->radius_req_attr_sqlite); | ||||
|   	os_free(conf->rsn_preauth_interfaces); | ||||
| diff --git a/package/network/services/hostapd/patches/901-coa-ubus.patch b/package/network/services/hostapd/patches/901-coa-ubus.patch | ||||
| new file mode 100644 | ||||
| index 0000000000..d525c79460 | ||||
| --- /dev/null | ||||
| +++ b/package/network/services/hostapd/patches/901-coa-ubus.patch | ||||
| @@ -0,0 +1,28 @@ | ||||
| +Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c | ||||
| +=================================================================== | ||||
| +--- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.c | ||||
| ++++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.c | ||||
| +@@ -1034,6 +1034,23 @@ hostapd_das_disconnect(void *ctx, struct | ||||
| + 	struct hostapd_data *hapd = ctx; | ||||
| + 	struct sta_info *sta; | ||||
| + 	int multi; | ||||
| ++	int ubus_resp; | ||||
| ++	struct hostapd_ubus_request req = { | ||||
| ++		.type = HOSTAPD_UBUS_COA, | ||||
| ++		.mgmt_frame = 0, | ||||
| ++		.ssi_signal = 0, | ||||
| ++		.addr = attr->sta_addr, | ||||
| ++	}; | ||||
| ++ | ||||
| ++	if (hostapd_ubus_handle_event(hapd, &req)) { | ||||
| ++		wpa_printf(MSG_INFO, "DAS: disconnect due approved via ubus"); | ||||
| ++		sta = ap_get_sta(hapd, attr->sta_addr); | ||||
| ++		if (sta) { | ||||
| ++			hostapd_drv_sta_deauth(hapd, attr->sta_addr, 2); | ||||
| ++			ap_sta_deauthenticate(hapd, sta, 2); | ||||
| ++		} | ||||
| ++		return RADIUS_DAS_SUCCESS; | ||||
| ++	} | ||||
| +  | ||||
| + 	if (hostapd_das_nas_mismatch(hapd, attr)) | ||||
| + 		return RADIUS_DAS_NAS_MISMATCH; | ||||
| diff --git a/package/network/services/hostapd/patches/999-das-proxy-state.patch b/package/network/services/hostapd/patches/999-das-proxy-state.patch | ||||
| new file mode 100644 | ||||
| index 0000000000..64b7aa4c07 | ||||
| --- /dev/null | ||||
| +++ b/package/network/services/hostapd/patches/999-das-proxy-state.patch | ||||
| @@ -0,0 +1,95 @@ | ||||
| +Index: hostapd-2021-02-20-59e9794c/src/radius/radius_das.c | ||||
| +=================================================================== | ||||
| +--- hostapd-2021-02-20-59e9794c.orig/src/radius/radius_das.c | ||||
| ++++ hostapd-2021-02-20-59e9794c/src/radius/radius_das.c | ||||
| +@@ -63,6 +63,7 @@ static struct radius_msg * radius_das_di | ||||
| + 		RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, | ||||
| + 		RADIUS_ATTR_VENDOR_SPECIFIC, | ||||
| + 		RADIUS_ATTR_CALLED_STATION_ID, | ||||
| ++		RADIUS_ATTR_PROXY_STATE, | ||||
| + #ifdef CONFIG_IPV6 | ||||
| + 		RADIUS_ATTR_NAS_IPV6_ADDRESS, | ||||
| + #endif /* CONFIG_IPV6 */ | ||||
| +@@ -159,6 +160,12 @@ static struct radius_msg * radius_das_di | ||||
| + 		attrs.cui_len = len; | ||||
| + 	} | ||||
| +  | ||||
| ++	if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_PROXY_STATE, | ||||
| ++				    &buf, &len, NULL) == 0) { | ||||
| ++		attrs.proxy = buf; | ||||
| ++		attrs.proxy_len = len; | ||||
| ++	} | ||||
| ++ | ||||
| + 	res = das->disconnect(das->ctx, &attrs); | ||||
| + 	switch (res) { | ||||
| + 	case RADIUS_DAS_NAS_MISMATCH: | ||||
| +@@ -167,10 +174,11 @@ static struct radius_msg * radius_das_di | ||||
| + 		error = 403; | ||||
| + 		break; | ||||
| + 	case RADIUS_DAS_SESSION_NOT_FOUND: | ||||
| +-		wpa_printf(MSG_INFO, "DAS: Session not found for request from " | ||||
| +-			   "%s:%d", abuf, from_port); | ||||
| +-		error = 503; | ||||
| +-		break; | ||||
| ++		return NULL; | ||||
| ++//		wpa_printf(MSG_INFO, "DAS: Session not found for request from " | ||||
| ++//			   "%s:%d", abuf, from_port); | ||||
| ++//		error = 503; | ||||
| ++//		break; | ||||
| + 	case RADIUS_DAS_MULTI_SESSION_MATCH: | ||||
| + 		wpa_printf(MSG_INFO, | ||||
| + 			   "DAS: Multiple sessions match for request from %s:%d", | ||||
| +@@ -192,6 +200,9 @@ fail: | ||||
| + 	if (reply == NULL) | ||||
| + 		return NULL; | ||||
| +  | ||||
| ++	if (attrs.proxy) | ||||
| ++		radius_msg_add_attr(reply, RADIUS_ATTR_PROXY_STATE, attrs.proxy, attrs.proxy_len); | ||||
| ++ | ||||
| + 	if (error) { | ||||
| + 		if (!radius_msg_add_attr_int32(reply, RADIUS_ATTR_ERROR_CAUSE, | ||||
| + 					       error)) { | ||||
| +@@ -222,6 +233,7 @@ static struct radius_msg * radius_das_co | ||||
| + 		RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, | ||||
| + 		RADIUS_ATTR_VENDOR_SPECIFIC, | ||||
| + 		RADIUS_ATTR_CALLED_STATION_ID, | ||||
| ++		RADIUS_ATTR_PROXY_STATE, | ||||
| + #ifdef CONFIG_IPV6 | ||||
| + 		RADIUS_ATTR_NAS_IPV6_ADDRESS, | ||||
| + #endif /* CONFIG_IPV6 */ | ||||
| +@@ -347,6 +359,12 @@ static struct radius_msg * radius_das_co | ||||
| + 	} | ||||
| + #endif /* CONFIG_HS20 */ | ||||
| +  | ||||
| ++	if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_PROXY_STATE, | ||||
| ++				    &buf, &len, NULL) == 0) { | ||||
| ++		attrs.proxy = buf; | ||||
| ++		attrs.proxy_len = len; | ||||
| ++	} | ||||
| ++ | ||||
| + 	res = das->coa(das->ctx, &attrs); | ||||
| + 	switch (res) { | ||||
| + 	case RADIUS_DAS_NAS_MISMATCH: | ||||
| +@@ -382,6 +400,9 @@ fail: | ||||
| + 	if (!reply) | ||||
| + 		return NULL; | ||||
| +  | ||||
| ++	if (attrs.proxy) | ||||
| ++		radius_msg_add_attr(reply, RADIUS_ATTR_PROXY_STATE, attrs.proxy, attrs.proxy_len); | ||||
| ++ | ||||
| + 	if (error && | ||||
| + 	    !radius_msg_add_attr_int32(reply, RADIUS_ATTR_ERROR_CAUSE, error)) { | ||||
| + 		radius_msg_free(reply); | ||||
| +Index: hostapd-2021-02-20-59e9794c/src/radius/radius_das.h | ||||
| +=================================================================== | ||||
| +--- hostapd-2021-02-20-59e9794c.orig/src/radius/radius_das.h | ||||
| ++++ hostapd-2021-02-20-59e9794c/src/radius/radius_das.h | ||||
| +@@ -36,6 +36,8 @@ struct radius_das_attrs { | ||||
| + 	size_t acct_multi_session_id_len; | ||||
| + 	const u8 *cui; | ||||
| + 	size_t cui_len; | ||||
| ++	const u8 *proxy; | ||||
| ++	size_t proxy_len; | ||||
| +  | ||||
| + 	/* Authorization changes */ | ||||
| + 	const u8 *hs20_t_c_filtering; | ||||
| diff --git a/package/network/services/hostapd/patches/999-ssi_signal.patch b/package/network/services/hostapd/patches/999-ssi_signal.patch | ||||
| new file mode 100644 | ||||
| index 0000000000..17eac6d4cb | ||||
| --- /dev/null | ||||
| +++ b/package/network/services/hostapd/patches/999-ssi_signal.patch | ||||
| @@ -0,0 +1,81 @@ | ||||
| +Index: hostapd-2023-09-08-e5ccbfc6/src/ap/ieee802_11.c | ||||
| +=================================================================== | ||||
| +--- hostapd-2023-09-08-e5ccbfc6.orig/src/ap/ieee802_11.c | ||||
| ++++ hostapd-2023-09-08-e5ccbfc6/src/ap/ieee802_11.c | ||||
| +@@ -59,6 +59,17 @@ | ||||
| + #include "pasn/pasn_common.h" | ||||
| +  | ||||
| +  | ||||
| ++static int | ||||
| ++ewma(int new, int old) | ||||
| ++{ | ||||
| ++	#define ALPHA	10 | ||||
| ++	if (!old) | ||||
| ++		return new; | ||||
| ++	if (new >= 0) | ||||
| ++		return old; | ||||
| ++	return ((ALPHA * new) + ((100 - ALPHA) * old)) / 100; | ||||
| ++} | ||||
| ++ | ||||
| + #ifdef CONFIG_FILS | ||||
| + static struct wpabuf * | ||||
| + prepare_auth_resp_fils(struct hostapd_data *hapd, | ||||
| +@@ -5856,7 +5867,7 @@ static int robust_action_frame(u8 catego | ||||
| +  | ||||
| + static int handle_action(struct hostapd_data *hapd, | ||||
| + 			 const struct ieee80211_mgmt *mgmt, size_t len, | ||||
| +-			 unsigned int freq) | ||||
| ++			 unsigned int freq, int ssi_signal) | ||||
| + { | ||||
| + 	struct sta_info *sta; | ||||
| + 	u8 *action __maybe_unused; | ||||
| +@@ -5913,6 +5924,7 @@ static int handle_action(struct hostapd_ | ||||
| +  | ||||
| + 		sta->last_seq_ctrl = seq_ctrl; | ||||
| + 		sta->last_subtype = WLAN_FC_STYPE_ACTION; | ||||
| ++		sta->signal_mgmt = ewma(ssi_signal, sta->signal_mgmt);; | ||||
| + 	} | ||||
| +  | ||||
| + 	switch (mgmt->u.action.category) { | ||||
| +@@ -6089,6 +6101,8 @@ int ieee802_11_mgmt(struct hostapd_data | ||||
| + 	unsigned int freq; | ||||
| + 	int ssi_signal = fi ? fi->ssi_signal : 0; | ||||
| +  | ||||
| ++	hapd->signal_mgmt = ewma(ssi_signal, hapd->signal_mgmt);; | ||||
| ++ | ||||
| + 	if (len < 24) | ||||
| + 		return 0; | ||||
| +  | ||||
| +@@ -6196,7 +6210,7 @@ int ieee802_11_mgmt(struct hostapd_data | ||||
| + 		break; | ||||
| + 	case WLAN_FC_STYPE_ACTION: | ||||
| + 		wpa_printf(MSG_DEBUG, "mgmt::action"); | ||||
| +-		ret = handle_action(hapd, mgmt, len, freq); | ||||
| ++		ret = handle_action(hapd, mgmt, len, freq, ssi_signal); | ||||
| + 		break; | ||||
| + 	default: | ||||
| + 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, | ||||
| +Index: hostapd-2023-09-08-e5ccbfc6/src/ap/sta_info.h | ||||
| +=================================================================== | ||||
| +--- hostapd-2023-09-08-e5ccbfc6.orig/src/ap/sta_info.h | ||||
| ++++ hostapd-2023-09-08-e5ccbfc6/src/ap/sta_info.h | ||||
| +@@ -330,6 +330,7 @@ struct sta_info { | ||||
| + #ifdef CONFIG_PASN | ||||
| + 	struct pasn_data *pasn; | ||||
| + #endif /* CONFIG_PASN */ | ||||
| ++	int signal_mgmt; | ||||
| +  | ||||
| + #ifdef CONFIG_IEEE80211BE | ||||
| + 	struct mld_info mld_info; | ||||
| +Index: hostapd-2023-09-08-e5ccbfc6/src/ap/hostapd.h | ||||
| +=================================================================== | ||||
| +--- hostapd-2023-09-08-e5ccbfc6.orig/src/ap/hostapd.h | ||||
| ++++ hostapd-2023-09-08-e5ccbfc6/src/ap/hostapd.h | ||||
| +@@ -494,6 +494,7 @@ struct hostapd_data { | ||||
| + #ifdef CONFIG_CTRL_IFACE_UDP | ||||
| +        unsigned char ctrl_iface_cookie[CTRL_IFACE_COOKIE_LEN]; | ||||
| + #endif /* CONFIG_CTRL_IFACE_UDP */ | ||||
| ++       int signal_mgmt; | ||||
| + }; | ||||
| +  | ||||
| +  | ||||
| diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c | ||||
| index 114141e088..52f83c50f7 100644 | ||||
| --- a/package/network/services/hostapd/src/src/ap/ubus.c | ||||
| +++ b/package/network/services/hostapd/src/src/ap/ubus.c | ||||
| @@ -24,6 +24,7 @@ | ||||
|  #include "taxonomy.h" | ||||
|  #include "airtime_policy.h" | ||||
|  #include "hw_features.h" | ||||
| +#include "ieee802_11_auth.h" | ||||
|   | ||||
|  static struct ubus_context *ctx; | ||||
|  static struct blob_buf b; | ||||
| @@ -153,7 +154,7 @@ hostapd_bss_ban_client(struct hostapd_data *hapd, u8 *addr, int time) | ||||
|  		} | ||||
|  	} | ||||
|   | ||||
| -	eloop_register_timeout(0, time * 1000, hostapd_bss_del_ban, ban, hapd); | ||||
| +	eloop_register_timeout(time, 0, hostapd_bss_del_ban, ban, hapd); | ||||
|  } | ||||
|   | ||||
|  static int | ||||
| @@ -319,7 +320,42 @@ hostapd_bss_get_clients(struct ubus_context *ctx, struct ubus_object *obj, | ||||
|  			blobmsg_add_u32(&b, "rx", sta_driver_data.current_rx_rate * 100); | ||||
|  			blobmsg_add_u32(&b, "tx", sta_driver_data.current_tx_rate * 100); | ||||
|  			blobmsg_close_table(&b, r); | ||||
| +			blobmsg_add_u32(&b, "retries", sta_driver_data.tx_retry_count); | ||||
| +			blobmsg_add_u32(&b, "failed", sta_driver_data.tx_retry_failed); | ||||
|  			blobmsg_add_u32(&b, "signal", sta_driver_data.signal); | ||||
| + | ||||
| +			r = blobmsg_open_table(&b, "mcs"); | ||||
| +			if (sta_driver_data.rx_hemcs) { | ||||
| +				blobmsg_add_u32(&b, "he", 1); | ||||
| +				blobmsg_add_u32(&b, "rx", sta_driver_data.rx_hemcs); | ||||
| +				blobmsg_add_u32(&b, "tx", sta_driver_data.tx_hemcs); | ||||
| +			} else if (sta_driver_data.rx_vhtmcs) { | ||||
| +				blobmsg_add_u32(&b, "vht", 1); | ||||
| +				blobmsg_add_u32(&b, "rx", sta_driver_data.rx_vhtmcs); | ||||
| +				blobmsg_add_u32(&b, "tx", sta_driver_data.tx_vhtmcs); | ||||
| +			} else { | ||||
| +				blobmsg_add_u32(&b, "rx", sta_driver_data.rx_mcs); | ||||
| +				blobmsg_add_u32(&b, "tx", sta_driver_data.tx_mcs); | ||||
| +			} | ||||
| +			blobmsg_close_table(&b, r); | ||||
| + | ||||
| +			r = blobmsg_open_table(&b, "nss"); | ||||
| +			if (sta_driver_data.rx_he_nss) { | ||||
| +				blobmsg_add_u32(&b, "he", 1); | ||||
| +				blobmsg_add_u32(&b, "rx", sta_driver_data.rx_he_nss); | ||||
| +				blobmsg_add_u32(&b, "tx", sta_driver_data.tx_he_nss); | ||||
| +			} else if (sta_driver_data.rx_vht_nss) { | ||||
| +				blobmsg_add_u32(&b, "vht", 1); | ||||
| +				blobmsg_add_u32(&b, "rx", sta_driver_data.rx_vht_nss); | ||||
| +				blobmsg_add_u32(&b, "tx", sta_driver_data.tx_vht_nss); | ||||
| +			} else { | ||||
| +				blobmsg_add_u32(&b, "rx", sta_driver_data.rx_mcs); | ||||
| +				blobmsg_add_u32(&b, "tx", sta_driver_data.tx_mcs); | ||||
| +			} | ||||
| +			blobmsg_close_table(&b, r); | ||||
| + | ||||
| +			if (sta->signal_mgmt) | ||||
| +				blobmsg_add_u32(&b, "signal_mgmt", sta->signal_mgmt); | ||||
|  		} | ||||
|   | ||||
|  		hostapd_parse_capab_blobmsg(sta); | ||||
| @@ -369,6 +405,7 @@ hostapd_bss_get_status(struct ubus_context *ctx, struct ubus_object *obj, | ||||
|  				      &op_class, &channel); | ||||
|   | ||||
|  	blob_buf_init(&b, 0); | ||||
| +	blobmsg_add_string(&b, "driver", hapd->driver->name); | ||||
|  	blobmsg_add_string(&b, "status", hostapd_state_text(hapd->iface->state)); | ||||
|  	blobmsg_printf(&b, "bssid", MACSTR, MAC2STR(hapd->conf->bssid)); | ||||
|   | ||||
| @@ -418,6 +455,12 @@ hostapd_bss_get_status(struct ubus_context *ctx, struct ubus_object *obj, | ||||
|  			hapd->iface->cac_started ? hapd->iface->dfs_cac_ms / 1000 - now.sec : 0); | ||||
|  	blobmsg_close_table(&b, dfs_table); | ||||
|   | ||||
| +	if (hapd->conf->uci_section) | ||||
| +		blobmsg_add_string(&b, "uci_section", hapd->conf->uci_section); | ||||
| + | ||||
| +	if (hapd->signal_mgmt) | ||||
| +		blobmsg_add_u32(&b, "signal_mgmt", hapd->signal_mgmt); | ||||
| + | ||||
|  	ubus_send_reply(ctx, req, b.head); | ||||
|   | ||||
|  	return 0; | ||||
| @@ -471,6 +514,23 @@ static const struct blobmsg_policy del_policy[__DEL_CLIENT_MAX] = { | ||||
|  	[DEL_CLIENT_GLOBAL_BAN] = { "global_ban", BLOBMSG_TYPE_INT8 }, | ||||
|  }; | ||||
|   | ||||
| +static int | ||||
| +hostapd_bss_del_client_cb(struct hostapd_iface *iface, void *ctx) | ||||
| +{ | ||||
| +	struct blob_attr **tb = ctx; | ||||
| +	u8 addr[ETH_ALEN]; | ||||
| +	int i; | ||||
| + | ||||
| +	hwaddr_aton(blobmsg_data(tb[DEL_CLIENT_ADDR]), addr); | ||||
| + | ||||
| +	for (i = 0; i < iface->num_bss; i++) { | ||||
| +		struct hostapd_data *bss = iface->bss[i]; | ||||
| + | ||||
| +		hostapd_bss_ban_client(bss, addr, blobmsg_get_u32(tb[DEL_CLIENT_BAN_TIME])); | ||||
| +	} | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
|  static int | ||||
|  hostapd_bss_del_client(struct ubus_context *ctx, struct ubus_object *obj, | ||||
|  			struct ubus_request_data *req, const char *method, | ||||
| @@ -479,8 +539,8 @@ hostapd_bss_del_client(struct ubus_context *ctx, struct ubus_object *obj, | ||||
|  	struct blob_attr *tb[__DEL_CLIENT_MAX]; | ||||
|  	struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); | ||||
|  	struct sta_info *sta; | ||||
| -	bool deauth = false,  global = false; | ||||
| -	int reason; | ||||
| +	bool deauth = false, global = false; | ||||
| +	int reason, ban_time = 0; | ||||
|  	u8 addr[ETH_ALEN]; | ||||
|   | ||||
|  	blobmsg_parse(del_policy, __DEL_CLIENT_MAX, tb, blob_data(msg), blob_len(msg)); | ||||
| @@ -500,6 +560,9 @@ hostapd_bss_del_client(struct ubus_context *ctx, struct ubus_object *obj, | ||||
|  	if (tb[DEL_CLIENT_GLOBAL_BAN]) | ||||
|  		global = blobmsg_get_bool(tb[DEL_CLIENT_GLOBAL_BAN]); | ||||
|   | ||||
| +	if (tb[DEL_CLIENT_GLOBAL_BAN]) | ||||
| +		global = blobmsg_get_bool(tb[DEL_CLIENT_GLOBAL_BAN]); | ||||
| + | ||||
|  	sta = ap_get_sta(hapd, addr); | ||||
|  	if (sta) { | ||||
|  		if (deauth) { | ||||
| @@ -512,16 +575,11 @@ hostapd_bss_del_client(struct ubus_context *ctx, struct ubus_object *obj, | ||||
|  	} | ||||
|   | ||||
|  	if (tb[DEL_CLIENT_BAN_TIME]) { | ||||
| -		int i; | ||||
| - | ||||
| -                for (i = 0; i < hapd->iface->num_bss; i++) { | ||||
| -                        struct hostapd_data *bss = hapd->iface->bss[i]; | ||||
| - | ||||
| -                        if (!global && bss != hapd) | ||||
| -                                continue; | ||||
| - | ||||
| -                        hostapd_bss_ban_client(bss, addr, blobmsg_get_u32(tb[DEL_CLIENT_BAN_TIME])); | ||||
| -                } | ||||
| +		ban_time = blobmsg_get_u32(tb[DEL_CLIENT_BAN_TIME]); | ||||
| +		if (global) | ||||
| +			hapd->iface->interfaces->for_each_interface(hapd->iface->interfaces, hostapd_bss_del_client_cb, tb); | ||||
| +		else | ||||
| +			hostapd_bss_ban_client(hapd, addr, ban_time); | ||||
|  	} | ||||
|   | ||||
|  	return 0; | ||||
| @@ -1671,6 +1729,121 @@ static int avl_compare_macaddr(const void *k1, const void *k2, void *ptr) | ||||
|  	return memcmp(k1, k2, ETH_ALEN); | ||||
|  } | ||||
|   | ||||
| +static int | ||||
| +hostapd_wired_get_clients(struct ubus_context *ctx, struct ubus_object *obj, | ||||
| +			  struct ubus_request_data *req, const char *method, | ||||
| +			  struct blob_attr *msg) | ||||
| +{ | ||||
| +	struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); | ||||
| +	struct hostap_sta_driver_data sta_driver_data; | ||||
| +	struct sta_info *sta; | ||||
| +	void *list, *c; | ||||
| +	char mac_buf[20]; | ||||
| +	static const struct { | ||||
| +		const char *name; | ||||
| +		uint32_t flag; | ||||
| +	} sta_flags[] = { | ||||
| +		{ "authorized", WLAN_STA_AUTHORIZED }, | ||||
| +	}; | ||||
| + | ||||
| +	blob_buf_init(&b, 0); | ||||
| +	list = blobmsg_open_table(&b, "clients"); | ||||
| +	for (sta = hapd->sta_list; sta; sta = sta->next) { | ||||
| +		void *r; | ||||
| +		int i; | ||||
| + | ||||
| +		sprintf(mac_buf, MACSTR, MAC2STR(sta->addr)); | ||||
| +		c = blobmsg_open_table(&b, mac_buf); | ||||
| +		for (i = 0; i < ARRAY_SIZE(sta_flags); i++) | ||||
| +			blobmsg_add_u8(&b, sta_flags[i].name, | ||||
| +				       !!(sta->flags & sta_flags[i].flag)); | ||||
| + | ||||
| +			blobmsg_close_table(&b, c); | ||||
| +	} | ||||
| +	blobmsg_close_array(&b, list); | ||||
| +	ubus_send_reply(ctx, req, b.head); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int | ||||
| +hostapd_wired_get_status(struct ubus_context *ctx, struct ubus_object *obj, | ||||
| +			 struct ubus_request_data *req, const char *method, | ||||
| +			 struct blob_attr *msg) | ||||
| +{ | ||||
| +	struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); | ||||
| +	char iface_name[17]; | ||||
| + | ||||
| +	blob_buf_init(&b, 0); | ||||
| +	blobmsg_add_string(&b, "driver", hapd->driver->name); | ||||
| +	blobmsg_add_string(&b, "status", hostapd_state_text(hapd->iface->state)); | ||||
| + | ||||
| +	snprintf(iface_name, 17, "%s", hapd->iface->phy); | ||||
| +	blobmsg_add_string(&b, "iface", iface_name); | ||||
| + | ||||
| +	ubus_send_reply(ctx, req, b.head); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int | ||||
| +hostapd_wired_del_clients(struct ubus_context *ctx, struct ubus_object *obj, | ||||
| +			  struct ubus_request_data *req, const char *method, | ||||
| +			  struct blob_attr *msg) | ||||
| +{ | ||||
| +	struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); | ||||
| + | ||||
| +	hostapd_free_stas(hapd); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +enum { | ||||
| +	MAC_AUTH_ADDR, | ||||
| +	__MAC_AUTH_MAX | ||||
| +}; | ||||
| + | ||||
| +static const struct blobmsg_policy mac_auth_policy[__MAC_AUTH_MAX] = { | ||||
| +	[MAC_AUTH_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, | ||||
| +}; | ||||
| + | ||||
| +static int | ||||
| +hostapd_wired_mac_auth(struct ubus_context *ctx, struct ubus_object *obj, | ||||
| +		       struct ubus_request_data *req, const char *method, | ||||
| +		       struct blob_attr *msg) | ||||
| +{ | ||||
| +	struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); | ||||
| +	struct blob_attr *tb[__MAC_AUTH_MAX]; | ||||
| +	struct radius_sta rad_info; | ||||
| +	struct sta_info *sta; | ||||
| +	u8 addr[ETH_ALEN]; | ||||
| +	int acl_res; | ||||
| + | ||||
| +	blobmsg_parse(mac_auth_policy, __MAC_AUTH_MAX, tb, blob_data(msg), blob_len(msg)); | ||||
| + | ||||
| +	if (hwaddr_aton(blobmsg_data(tb[MAC_AUTH_ADDR]), addr)) | ||||
| +		return UBUS_STATUS_INVALID_ARGUMENT; | ||||
| + | ||||
| +	acl_res = hostapd_allowed_address(hapd, addr, NULL, 0, &rad_info, 0); | ||||
| +	if (acl_res == HOSTAPD_ACL_REJECT) { | ||||
| +		wpa_printf(MSG_ERROR, "Ignore new peer notification\n"); | ||||
| +		return UBUS_STATUS_INVALID_ARGUMENT; | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static const struct ubus_method wired_methods[] = { | ||||
| +	UBUS_METHOD_NOARG("reload", hostapd_bss_reload), | ||||
| +	UBUS_METHOD_NOARG("get_clients", hostapd_wired_get_clients), | ||||
| +	UBUS_METHOD_NOARG("del_clients", hostapd_wired_del_clients), | ||||
| +	UBUS_METHOD_NOARG("get_status", hostapd_wired_get_status), | ||||
| +	UBUS_METHOD("mac_auth", hostapd_wired_mac_auth, mac_auth_policy), | ||||
| +}; | ||||
| + | ||||
| +static struct ubus_object_type wired_object_type = | ||||
| +	UBUS_OBJECT_TYPE("hostapd_wired", wired_methods); | ||||
| + | ||||
|  void hostapd_ubus_add_bss(struct hostapd_data *hapd) | ||||
|  { | ||||
|  	struct ubus_object *obj = &hapd->ubus.obj; | ||||
| @@ -1690,9 +1863,15 @@ void hostapd_ubus_add_bss(struct hostapd_data *hapd) | ||||
|   | ||||
|  	avl_init(&hapd->ubus.banned, avl_compare_macaddr, false, NULL); | ||||
|  	obj->name = name; | ||||
| -	obj->type = &bss_object_type; | ||||
| -	obj->methods = bss_object_type.methods; | ||||
| -	obj->n_methods = bss_object_type.n_methods; | ||||
| +	if (!strcmp(hapd->driver->name, "wired")) { | ||||
| +		obj->type = &wired_object_type; | ||||
| +		obj->methods = wired_object_type.methods; | ||||
| +		obj->n_methods = wired_object_type.n_methods; | ||||
| +	} else { | ||||
| +		obj->type = &bss_object_type; | ||||
| +		obj->methods = bss_object_type.methods; | ||||
| +		obj->n_methods = bss_object_type.n_methods; | ||||
| +	} | ||||
|  	ret = ubus_add_object(ctx, obj); | ||||
|  	hostapd_ubus_ref_inc(); | ||||
|  } | ||||
| @@ -1775,6 +1954,7 @@ int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_req | ||||
|  		[HOSTAPD_UBUS_PROBE_REQ] = "probe", | ||||
|  		[HOSTAPD_UBUS_AUTH_REQ] = "auth", | ||||
|  		[HOSTAPD_UBUS_ASSOC_REQ] = "assoc", | ||||
| +		[HOSTAPD_UBUS_COA] = "coa", | ||||
|  	}; | ||||
|  	const char *type = "mgmt"; | ||||
|  	struct ubus_event_req ureq = {}; | ||||
| @@ -1844,7 +2024,7 @@ int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_req | ||||
|  		} | ||||
|  	} | ||||
|   | ||||
| -	if (!hapd->ubus.notify_response) { | ||||
| +	if (!hapd->ubus.notify_response && req->type != HOSTAPD_UBUS_COA) { | ||||
|  		ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); | ||||
|  		return WLAN_STATUS_SUCCESS; | ||||
|  	} | ||||
| @@ -1876,6 +2056,19 @@ void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 * | ||||
|  	ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); | ||||
|  } | ||||
|   | ||||
| +void hostapd_ubus_notify_csa(struct hostapd_data *hapd, int freq) | ||||
| +{ | ||||
| +	if (!hapd->ubus.obj.has_subscribers) | ||||
| +		return; | ||||
| + | ||||
| +	blob_buf_init(&b, 0); | ||||
| +	blobmsg_add_string(&b, "ifname", hapd->conf->iface); | ||||
| +	blobmsg_add_u32(&b, "freq", freq); | ||||
| +	blobmsg_printf(&b, "bssid", MACSTR, MAC2STR(hapd->conf->bssid)); | ||||
| + | ||||
| +	ubus_notify(ctx, &hapd->ubus.obj, "channel-switch", b.head, -1); | ||||
| +} | ||||
| + | ||||
|  void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta, | ||||
|  				    const char *auth_alg) | ||||
|  { | ||||
| @@ -1884,6 +2077,8 @@ void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info * | ||||
|   | ||||
|  	blob_buf_init(&b, 0); | ||||
|  	blobmsg_add_macaddr(&b, "address", sta->addr); | ||||
| +	if (sta->vlan_id) | ||||
| +		blobmsg_add_u32(&b, "vlan", sta->vlan_id);	 | ||||
|  	blobmsg_add_string(&b, "ifname", hapd->conf->iface); | ||||
|  	if (auth_alg) | ||||
|  		blobmsg_add_string(&b, "auth-alg", auth_alg); | ||||
| diff --git a/package/network/services/hostapd/src/src/ap/ubus.h b/package/network/services/hostapd/src/src/ap/ubus.h | ||||
| index b0f7c44ab5..b294f981a8 100644 | ||||
| --- a/package/network/services/hostapd/src/src/ap/ubus.h | ||||
| +++ b/package/network/services/hostapd/src/src/ap/ubus.h | ||||
| @@ -12,6 +12,7 @@ enum hostapd_ubus_event_type { | ||||
|  	HOSTAPD_UBUS_PROBE_REQ, | ||||
|  	HOSTAPD_UBUS_AUTH_REQ, | ||||
|  	HOSTAPD_UBUS_ASSOC_REQ, | ||||
| +	HOSTAPD_UBUS_COA, | ||||
|  	HOSTAPD_UBUS_TYPE_MAX | ||||
|  }; | ||||
|   | ||||
| --  | ||||
| 2.34.1 | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 John Crispin
					John Crispin