From 653ea84231d0fc5b2726308401d3e742ff64c7cd Mon Sep 17 00:00:00 2001 From: John Crispin Date: Fri, 13 Mar 2026 15:29:51 +0100 Subject: [PATCH 1/8] rpcd: fix build failure against qca-wifi-7 iwinfo The standard iwinfo added he_chan_info, eht_chan_info and eht_chan_width which rpcd uses unconditionally. The qca-wifi-7 iwinfo lacks these, breaking the rpcd build. Add IWINFO_HAS_EHT_CHAN_INFO to the standard iwinfo header and guard the HE/EHT scan result blocks in rpcd behind it. Signed-off-by: John Crispin --- ...-add-he-eht-scan-info-feature-define.patch | 35 ++++++++++++++ ...0100-rpcd-guard-he-eht-iwinfo-fields.patch | 47 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 patches-25.12/0099-iwinfo-add-he-eht-scan-info-feature-define.patch create mode 100644 patches-25.12/0100-rpcd-guard-he-eht-iwinfo-fields.patch diff --git a/patches-25.12/0099-iwinfo-add-he-eht-scan-info-feature-define.patch b/patches-25.12/0099-iwinfo-add-he-eht-scan-info-feature-define.patch new file mode 100644 index 000000000..705849e3d --- /dev/null +++ b/patches-25.12/0099-iwinfo-add-he-eht-scan-info-feature-define.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Thu, 13 Mar 2026 09:00:00 +0100 +Subject: [PATCH] iwinfo: add HE/EHT scan info feature define + +Add IWINFO_HAS_EHT_CHAN_INFO to the standard iwinfo header so that +consumers can detect at compile time whether HE/EHT channel info +fields are available in struct iwinfo_scanlist_entry. + +This allows rpcd and other packages to conditionally compile HE/EHT +scan result handling, avoiding build failures against older iwinfo +versions (e.g. qca-wifi-7's iwinfo which lacks these fields). + +Signed-off-by: John Crispin +--- + .../utils/iwinfo/patches/200-add-he-eht-feature-define.patch | 11 +++++++++++ + 1 file changed, 11 insertions(+) + create mode 100644 package/network/utils/iwinfo/patches/200-add-he-eht-feature-define.patch + +diff --git a/package/network/utils/iwinfo/patches/200-add-he-eht-feature-define.patch b/package/network/utils/iwinfo/patches/200-add-he-eht-feature-define.patch +new file mode 100644 +--- /dev/null ++++ b/package/network/utils/iwinfo/patches/200-add-he-eht-feature-define.patch +@@ -0,0 +1,11 @@ ++--- a/include/iwinfo.h +++++ b/include/iwinfo.h ++@@ -335,6 +335,8 @@ ++ 2 = 80 MHz ++ 3 = 80+80 or 160 MHz ++ 4 = 160+160 or 320 MHz */ +++ +++#define IWINFO_HAS_EHT_CHAN_INFO ++ extern const uint16_t eht_chan_width[5]; ++ ++ struct iwinfo_scanlist_entry { diff --git a/patches-25.12/0100-rpcd-guard-he-eht-iwinfo-fields.patch b/patches-25.12/0100-rpcd-guard-he-eht-iwinfo-fields.patch new file mode 100644 index 000000000..70883c224 --- /dev/null +++ b/patches-25.12/0100-rpcd-guard-he-eht-iwinfo-fields.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Thu, 13 Mar 2026 09:00:00 +0100 +Subject: [PATCH] rpcd: guard HE/EHT iwinfo scan fields + +Wrap the HE and EHT channel info scan result blocks in rpcd's iwinfo +plugin with an IWINFO_HAS_EHT_CHAN_INFO ifdef guard. The qca-wifi-7 +iwinfo (v2024-10-20) does not provide he_chan_info, eht_chan_info or +eht_chan_width, so building rpcd against it fails. With this guard, +rpcd compiles against both the standard and qca-wifi-7 iwinfo. + +Signed-off-by: John Crispin +--- + .../system/rpcd/patches/100-guard-he-eht-fields.patch | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + create mode 100644 package/system/rpcd/patches/100-guard-he-eht-fields.patch + +diff --git a/package/system/rpcd/patches/100-guard-he-eht-fields.patch b/package/system/rpcd/patches/100-guard-he-eht-fields.patch +new file mode 100644 +--- /dev/null ++++ b/package/system/rpcd/patches/100-guard-he-eht-fields.patch +@@ -0,0 +1,25 @@ ++--- a/iwinfo.c +++++ b/iwinfo.c ++@@ -437,20 +437,22 @@ ++ blobmsg_close_table(&buf, t); ++ } ++ +++#ifdef IWINFO_HAS_EHT_CHAN_INFO ++ if (e->he_chan_info.center_chan_1) { ++ t = blobmsg_open_table(&buf, "he_operation"); ++ blobmsg_add_u32(&buf, "channel_width", eht_chan_width[e->he_chan_info.chan_width]); ++ blobmsg_add_u32(&buf, "center_freq_1", e->he_chan_info.center_chan_1); ++ blobmsg_add_u32(&buf, "center_freq_2", e->he_chan_info.center_chan_2); ++ blobmsg_close_table(&buf, t); ++ } ++ ++ if (e->eht_chan_info.center_chan_1) { ++ t = blobmsg_open_table(&buf, "eht_operation"); ++ blobmsg_add_u32(&buf, "channel_width", eht_chan_width[e->eht_chan_info.chan_width]); ++ blobmsg_add_u32(&buf, "center_freq_1", e->eht_chan_info.center_chan_1); ++ blobmsg_add_u32(&buf, "center_freq_2", e->eht_chan_info.center_chan_2); ++ blobmsg_close_table(&buf, t); ++ } +++#endif ++ ++ rpc_iwinfo_add_encryption("encryption", &e->crypto); From 68c3bd4bbf654e55082fa66cf3016f4bc9527281 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Fri, 13 Mar 2026 17:22:42 +0100 Subject: [PATCH 2/8] mediatek: fix eap111 network config and rebase WAP588M patch Move edgecore,eap111 to the correct switch group in 02_network and adjust the WAP588M patch context to match. Signed-off-by: John Crispin --- .../0044-mediatek-edgecore-eap111-fixes.patch | 25 +++++++++++++++++-- ...iatek-add-support-for-EMPLUS-WAP588M.patch | 8 +++--- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/patches-25.12/0044-mediatek-edgecore-eap111-fixes.patch b/patches-25.12/0044-mediatek-edgecore-eap111-fixes.patch index c884b2ef6..788483770 100644 --- a/patches-25.12/0044-mediatek-edgecore-eap111-fixes.patch +++ b/patches-25.12/0044-mediatek-edgecore-eap111-fixes.patch @@ -1,4 +1,4 @@ -From 3e85d0984d2df4092e518685ae55f745a3eace5f Mon Sep 17 00:00:00 2001 +From a2edd27a8b077a51994f693eac50beafa6cc061f Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sat, 2 Aug 2025 06:47:35 +0200 Subject: [PATCH] mediatek: edgecore eap111 fixes @@ -19,12 +19,13 @@ Signed-off-by: John Crispin .../files-6.12/drivers/net/phy/an8801.c | 1535 +++++++++++++++++ .../files-6.12/drivers/net/phy/an8801.h | 233 +++ .../filogic/base-files/etc/board.d/01_leds | 5 + + .../filogic/base-files/etc/board.d/02_network | 2 +- .../filogic/base-files/etc/init.d/bootcount | 8 + .../base-files/lib/upgrade/platform.sh | 32 +- target/linux/mediatek/filogic/config-6.12 | 1 + ...y-support-an8801-and-mdio-second-phy.patch | 94 + ...net-mtk_eth_soc-add-mdio-reset-delay.patch | 26 + - 11 files changed, 1955 insertions(+), 5 deletions(-) + 12 files changed, 1956 insertions(+), 6 deletions(-) create mode 100644 package/kernel/mt76/edgecore_eap111_eeprom_dbdc.bin create mode 100644 target/linux/mediatek/files-6.12/drivers/net/phy/an8801.c create mode 100644 target/linux/mediatek/files-6.12/drivers/net/phy/an8801.h @@ -1916,6 +1917,26 @@ index 133db38005..0787a12913 100644 elecom,wrc-x3000gs3) ucidef_set_led_netdev "wan" "wan" "green:wan" "wan" ;; +diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network +index 9a41600c32..5b714f9d91 100644 +--- a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network ++++ b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network +@@ -121,7 +121,6 @@ mediatek_setup_interfaces() + ;; + airpi,ap3000m|\ + bananapi,bpi-r3-mini|\ +- edgecore,eap111|\ + huasifei,wh3000|\ + huasifei,wh3000-pro) + ucidef_set_interfaces_lan_wan eth0 eth1 +@@ -131,6 +130,7 @@ mediatek_setup_interfaces() + cudy,tr3000-256mb-v1|\ + cudy,tr3000-v1|\ + cudy,tr3000-v1-ubootmod|\ ++ edgecore,eap111|\ + glinet,gl-mt2500|\ + glinet,gl-mt2500-airoha|\ + glinet,gl-mt3000|\ diff --git a/target/linux/mediatek/filogic/base-files/etc/init.d/bootcount b/target/linux/mediatek/filogic/base-files/etc/init.d/bootcount index 415674322f..947e31c649 100755 --- a/target/linux/mediatek/filogic/base-files/etc/init.d/bootcount diff --git a/patches-25.12/0095-mediatek-add-support-for-EMPLUS-WAP588M.patch b/patches-25.12/0095-mediatek-add-support-for-EMPLUS-WAP588M.patch index bb3945d22..8b13bd3cc 100644 --- a/patches-25.12/0095-mediatek-add-support-for-EMPLUS-WAP588M.patch +++ b/patches-25.12/0095-mediatek-add-support-for-EMPLUS-WAP588M.patch @@ -1,4 +1,4 @@ -From 3dd9325bbae88486e2870b23700b221e78901608 Mon Sep 17 00:00:00 2001 +From 9f1d7ff0ea913a68576eb9f1a69047db72fcc24b Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 3 Mar 2026 07:50:14 +0100 Subject: [PATCH] mediatek: add support for EMPLUS WAP588M @@ -282,13 +282,13 @@ index cbbaa9dfd7..fef7297f19 100644 ucidef_set_led_netdev "wan" "wan" "green:wan" "wan" ;; diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network -index 800c40f93d..86e15d92ab 100644 +index 45649285b4..09a4730d29 100644 --- a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network +++ b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network @@ -121,6 +121,7 @@ mediatek_setup_interfaces() + ;; airpi,ap3000m|\ bananapi,bpi-r3-mini|\ - edgecore,eap111|\ + emplus,wap588m|\ huasifei,wh3000|\ huasifei,wh3000-pro) @@ -324,7 +324,7 @@ index 5603bb6249..e4449abdd0 100644 nand_do_upgrade "$1" ;; diff --git a/target/linux/mediatek/image/filogic.mk b/target/linux/mediatek/image/filogic.mk -index 7807433e22..0b0d81b622 100644 +index b9ed67ff04..a46cff2201 100644 --- a/target/linux/mediatek/image/filogic.mk +++ b/target/linux/mediatek/image/filogic.mk @@ -1426,6 +1426,25 @@ define Device/edgecore_eap115a From 5b64d7845939de8c1f2f42f28855984c34d29d19 Mon Sep 17 00:00:00 2001 From: Arif Alam Date: Fri, 13 Mar 2026 18:16:13 -0400 Subject: [PATCH 3/8] ucentral-client: fix hostname validation - Wire hostname validation enable / disable to hostname_validate flag in gateway.json - Fix hostname validation check when server cert Subject CN has other attributes like Organization in case of Insta server certs: subject=CN=*.example.com, O=ExampleInc. Fix backported to libwebsockets from: https://github.com/warmcat/libwebsockets/commit/5124ffe9d431ca866ef90cb6f5167a837fdc4840 Fixes WIFI-15384 Signed-off-by: Arif Alam --- ...runcate-CN-in-presence-of-other-attr.patch | 49 +++++++++++++++++++ .../ucentral-client/files/etc/init.d/ucentral | 2 + 2 files changed, 51 insertions(+) create mode 100644 feeds/ucentral/libwebsockets/patches/200-openssl-x509-truncate-CN-in-presence-of-other-attr.patch diff --git a/feeds/ucentral/libwebsockets/patches/200-openssl-x509-truncate-CN-in-presence-of-other-attr.patch b/feeds/ucentral/libwebsockets/patches/200-openssl-x509-truncate-CN-in-presence-of-other-attr.patch new file mode 100644 index 000000000..2fe8140fd --- /dev/null +++ b/feeds/ucentral/libwebsockets/patches/200-openssl-x509-truncate-CN-in-presence-of-other-attr.patch @@ -0,0 +1,49 @@ +From 975ef85e3fc478dc96b19d9862a1ade383fe48f8 Mon Sep 17 00:00:00 2001 +From: Arif Alam +Date: Thu, 12 Mar 2026 09:53:21 -0400 +Subject: [PATCH] openssl: x509: truncate CN in presence of other attr + +Backport of upstream commit 5124ffe9d431ca866ef90cb6f5167a837fdc4840. +https://github.com/warmcat/libwebsockets/issues/2542 + +Signed-off-by: Arif Alam +--- + lib/tls/openssl/openssl-x509.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/lib/tls/openssl/openssl-x509.c b/lib/tls/openssl/openssl-x509.c +index 185a84a8..df324aa0 100644 +--- a/lib/tls/openssl/openssl-x509.c ++++ b/lib/tls/openssl/openssl-x509.c +@@ -77,7 +77,8 @@ lws_tls_openssl_cert_info(X509 *x509, enum lws_tls_cert_info type, + { + X509_NAME *xn; + #if !defined(LWS_PLAT_OPTEE) +- char *p; ++ char *p, *p1; ++ size_t rl; + #endif + + if (!x509) +@@ -112,8 +113,16 @@ lws_tls_openssl_cert_info(X509 *x509, enum lws_tls_cert_info type, + return -1; + X509_NAME_oneline(xn, buf->ns.name, (int)len - 2); + p = strstr(buf->ns.name, "/CN="); +- if (p) +- memmove(buf->ns.name, p + 4, strlen(p + 4) + 1); ++ if (p) { ++ p += 4; ++ p1 = strchr(p, '/'); ++ if (p1) ++ rl = (size_t)(p1 - p); ++ else ++ rl = strlen(p); ++ memmove(buf->ns.name, p, rl); ++ buf->ns.name[rl] = '\0'; ++ } + buf->ns.len = (int)strlen(buf->ns.name); + return 0; + #endif +-- +2.53.0 + diff --git a/feeds/ucentral/ucentral-client/files/etc/init.d/ucentral b/feeds/ucentral/ucentral-client/files/etc/init.d/ucentral index 3a139ca1d..253032a3a 100755 --- a/feeds/ucentral/ucentral-client/files/etc/init.d/ucentral +++ b/feeds/ucentral/ucentral-client/files/etc/init.d/ucentral @@ -63,6 +63,8 @@ start_service() { [ "$debug" -eq 0 ] || procd_append_param command -d [ "$insecure" -eq 0 ] || procd_append_param command -i [ -n "$cert" -a -n "$ca" ] && procd_append_param command -c $cert -C $ca + hostname_validate=$(cat /etc/ucentral/gateway.json | jsonfilter -e '@["hostname_validate"]') + [ "$hostname_validate" = "0" ] || procd_append_param command -h [ -z "$(mount | grep 'tmpfs on / type tmpfs')" ] || procd_append_param command -r procd_append_param command -b "$boot_cause" procd_append_param command -f "$(cat /tmp/ucentral.version)" From ac122c7912607e38f4000444222de3abbc0e01ab Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sat, 14 Mar 2026 10:21:59 +0100 Subject: [PATCH 4/8] hostapd: add CUI to ACL RADIUS Access-Request When radius_request_cui=1 is configured, the EAP path includes a Chargeable-User-Identity attribute (RFC 4372) but the ACL path used by psk2-radius / mpsk-radius does not. Add a nul CUI to hostapd_radius_acl_query() so the RADIUS server is solicited for CUI in Access-Accept, matching the EAP initial-request behaviour. Signed-off-by: John Crispin --- .../hostapd/patches/zzz-acl-radius-cui.patch | 17 ++++++++ ...add-CUI-to-ACL-RADIUS-Access-Request.patch | 43 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 feeds/qca-wifi-6/hostapd/patches/zzz-acl-radius-cui.patch create mode 100644 patches-25.12/0101-hostapd-add-CUI-to-ACL-RADIUS-Access-Request.patch diff --git a/feeds/qca-wifi-6/hostapd/patches/zzz-acl-radius-cui.patch b/feeds/qca-wifi-6/hostapd/patches/zzz-acl-radius-cui.patch new file mode 100644 index 000000000..d335722a6 --- /dev/null +++ b/feeds/qca-wifi-6/hostapd/patches/zzz-acl-radius-cui.patch @@ -0,0 +1,17 @@ +--- a/src/ap/ieee802_11_auth.c ++++ b/src/ap/ieee802_11_auth.c +@@ -149,6 +149,14 @@ + if (add_common_radius_attr(hapd, hapd->conf->radius_auth_req_attr, + NULL, msg) < 0) + goto fail; ++ ++ if (hapd->conf->radius_request_cui && ++ !radius_msg_add_attr(msg, ++ RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, ++ (const u8 *) "\0", 1)) { ++ wpa_printf(MSG_DEBUG, "Could not add CUI"); ++ goto fail; ++ } + + os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT, + MAC2STR(addr)); diff --git a/patches-25.12/0101-hostapd-add-CUI-to-ACL-RADIUS-Access-Request.patch b/patches-25.12/0101-hostapd-add-CUI-to-ACL-RADIUS-Access-Request.patch new file mode 100644 index 000000000..94bb0363b --- /dev/null +++ b/patches-25.12/0101-hostapd-add-CUI-to-ACL-RADIUS-Access-Request.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Fri, 14 Mar 2026 09:00:00 +0100 +Subject: [PATCH] hostapd: add CUI to ACL RADIUS Access-Request + +When radius_request_cui=1 is configured, hostapd includes the +Chargeable-User-Identity attribute (RFC 4372) in EAP Access-Request +messages but not in the ACL path used by psk2-radius / mpsk-radius. +RADIUS servers expecting CUI for PSK-RADIUS therefore receive no CUI. + +Add a nul CUI to hostapd_radius_acl_query() so that the RADIUS server +is solicited for a CUI in the Access-Accept, matching the initial-request +behaviour of the EAP path when no prior CUI is known. The response side +already extracts CUI from Access-Accept and stores it. + +Signed-off-by: John Crispin +--- + .../hostapd/patches/zzz-0018-acl-radius-cui.patch | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + create mode 100644 package/network/services/hostapd/patches/zzz-0018-acl-radius-cui.patch + +diff --git a/package/network/services/hostapd/patches/zzz-0018-acl-radius-cui.patch b/package/network/services/hostapd/patches/zzz-0018-acl-radius-cui.patch +new file mode 100644 +--- /dev/null ++++ b/package/network/services/hostapd/patches/zzz-0018-acl-radius-cui.patch +@@ -0,0 +1,17 @@ ++--- a/src/ap/ieee802_11_auth.c +++++ b/src/ap/ieee802_11_auth.c ++@@ -149,6 +149,14 @@ ++ if (add_common_radius_attr(hapd, hapd->conf->radius_auth_req_attr, ++ NULL, msg) < 0) ++ goto fail; +++ +++ if (hapd->conf->radius_request_cui && +++ !radius_msg_add_attr(msg, +++ RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, +++ (const u8 *) "\0", 1)) { +++ wpa_printf(MSG_DEBUG, "Could not add CUI"); +++ goto fail; +++ } ++ ++ os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT, ++ MAC2STR(addr)); From 74261d1e9fd83caa659747e8319c9f7d2d3245d6 Mon Sep 17 00:00:00 2001 From: Arif Alam Date: Thu, 29 Jan 2026 15:51:21 -0500 Subject: [PATCH 5/8] hostapd: fix session-timeout with radius-psk backport hostapd commit e6ec62aa2d68e9436daeb4470260a101a06c9213 fixes WIFI-15317 Signed-off-by: Arif Alam --- ...meout-with-PSK-RADIUS-during-4-way-h.patch | 38 +++++++++++++++++++ ...meout-with-PSK-RADIUS-during-4-way-h.patch | 38 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 feeds/qca-wifi-6/hostapd/patches/t00-013-Allow-Session-Timeout-with-PSK-RADIUS-during-4-way-h.patch create mode 100644 feeds/qca-wifi-7/hostapd/patches/zzz-t03-Allow-Session-Timeout-with-PSK-RADIUS-during-4-way-h.patch diff --git a/feeds/qca-wifi-6/hostapd/patches/t00-013-Allow-Session-Timeout-with-PSK-RADIUS-during-4-way-h.patch b/feeds/qca-wifi-6/hostapd/patches/t00-013-Allow-Session-Timeout-with-PSK-RADIUS-during-4-way-h.patch new file mode 100644 index 000000000..3ddad4372 --- /dev/null +++ b/feeds/qca-wifi-6/hostapd/patches/t00-013-Allow-Session-Timeout-with-PSK-RADIUS-during-4-way-h.patch @@ -0,0 +1,38 @@ +From e6ec62aa2d68e9436daeb4470260a101a06c9213 Mon Sep 17 00:00:00 2001 +From: Lee Harding +Date: Tue, 9 Apr 2024 15:06:38 -0700 +Subject: [PATCH] Allow Session-Timeout with PSK RADIUS during 4-way handshake + +When the RADIUS response included a Session-Timeout attribute, but is +otherwise valid (an Access-Accept with a valid Tunnel-Password), the +association still failed due to the strict comparison of the accepted +value with HOSTAPD_ACL_ACCEPT. Apparently this combination wasn't +previously tested. + +Extend this to allow a packet containing a valid Session-Timeout +attribute to be accepted by extending the "success" comparison to +include HOSTAPD_ACL_ACCEPT_TIMEOUT. + +Fixes: 1c3438fec4ba ("RADIUS ACL/PSK check during 4-way handshake") +Signed-off-by: Lee Harding +--- + src/ap/ieee802_11_auth.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c +index e723ae74b..98a877dec 100644 +--- a/src/ap/ieee802_11_auth.c ++++ b/src/ap/ieee802_11_auth.c +@@ -596,7 +596,8 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req, + + if (query->radius_psk) { + struct sta_info *sta; +- bool success = cache->accepted == HOSTAPD_ACL_ACCEPT; ++ bool success = cache->accepted == HOSTAPD_ACL_ACCEPT || ++ cache->accepted == HOSTAPD_ACL_ACCEPT_TIMEOUT; + + sta = ap_get_sta(hapd, query->addr); + if (!sta || !sta->wpa_sm) { +-- +2.52.0 + diff --git a/feeds/qca-wifi-7/hostapd/patches/zzz-t03-Allow-Session-Timeout-with-PSK-RADIUS-during-4-way-h.patch b/feeds/qca-wifi-7/hostapd/patches/zzz-t03-Allow-Session-Timeout-with-PSK-RADIUS-during-4-way-h.patch new file mode 100644 index 000000000..3ddad4372 --- /dev/null +++ b/feeds/qca-wifi-7/hostapd/patches/zzz-t03-Allow-Session-Timeout-with-PSK-RADIUS-during-4-way-h.patch @@ -0,0 +1,38 @@ +From e6ec62aa2d68e9436daeb4470260a101a06c9213 Mon Sep 17 00:00:00 2001 +From: Lee Harding +Date: Tue, 9 Apr 2024 15:06:38 -0700 +Subject: [PATCH] Allow Session-Timeout with PSK RADIUS during 4-way handshake + +When the RADIUS response included a Session-Timeout attribute, but is +otherwise valid (an Access-Accept with a valid Tunnel-Password), the +association still failed due to the strict comparison of the accepted +value with HOSTAPD_ACL_ACCEPT. Apparently this combination wasn't +previously tested. + +Extend this to allow a packet containing a valid Session-Timeout +attribute to be accepted by extending the "success" comparison to +include HOSTAPD_ACL_ACCEPT_TIMEOUT. + +Fixes: 1c3438fec4ba ("RADIUS ACL/PSK check during 4-way handshake") +Signed-off-by: Lee Harding +--- + src/ap/ieee802_11_auth.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c +index e723ae74b..98a877dec 100644 +--- a/src/ap/ieee802_11_auth.c ++++ b/src/ap/ieee802_11_auth.c +@@ -596,7 +596,8 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req, + + if (query->radius_psk) { + struct sta_info *sta; +- bool success = cache->accepted == HOSTAPD_ACL_ACCEPT; ++ bool success = cache->accepted == HOSTAPD_ACL_ACCEPT || ++ cache->accepted == HOSTAPD_ACL_ACCEPT_TIMEOUT; + + sta = ap_get_sta(hapd, query->addr); + if (!sta || !sta->wpa_sm) { +-- +2.52.0 + From 1013cd92415d0540b5ed420b9f180721a0241271 Mon Sep 17 00:00:00 2001 From: Venkat Chimata Date: Sun, 1 Feb 2026 20:10:32 +0530 Subject: [PATCH 6/8] hostapd: store RADIUS Class per STA instead of EAPOL SM; preserve Class for ACL/MAC auth and accounting Move storage of RADIUS Class attributes from the EAPOL state machine to struct sta_info and update all users accordingly. Previously, Class was kept only in eapol_state_machine->radius_class, which caused Class to be lost for authentication paths where eapol_sm is not created. As a result, Accounting messages and PMKSA cache operations could miss the Class attribute. This change makes sta_info->radius_class the single source of truth for RADIUS Class attributes and ensures they are preserved and echoed in Accounting regardless of whether an EAPOL state machine exists. Fixes WIFI-15318 Signed-off-by: Venkat Chimata --- ...DIUS-Class-per-STA-instead-of-EAPOL-.patch | 361 ++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 feeds/qca-wifi-7/hostapd/patches/zzz-t04-hostapd-store-RADIUS-Class-per-STA-instead-of-EAPOL-.patch diff --git a/feeds/qca-wifi-7/hostapd/patches/zzz-t04-hostapd-store-RADIUS-Class-per-STA-instead-of-EAPOL-.patch b/feeds/qca-wifi-7/hostapd/patches/zzz-t04-hostapd-store-RADIUS-Class-per-STA-instead-of-EAPOL-.patch new file mode 100644 index 000000000..1bf176ab0 --- /dev/null +++ b/feeds/qca-wifi-7/hostapd/patches/zzz-t04-hostapd-store-RADIUS-Class-per-STA-instead-of-EAPOL-.patch @@ -0,0 +1,361 @@ +From b48e9bb427e1b85ca9adaed9895c8b3721600ead Mon Sep 17 00:00:00 2001 +From: Venkat Chimata +Date: Mon, 2 Feb 2026 14:02:24 +0530 +Subject: [PATCH] hostapd: store RADIUS Class per STA instead of EAPOL SM; + preserve Class for ACL/MAC auth and accounting + +Move storage of RADIUS Class attributes from the EAPOL state machine to +struct sta_info and update all users accordingly. Previously, Class was +kept only in eapol_state_machine->radius_class, which caused Class to be +lost for authentication paths where eapol_sm is not created. As a result, +Accounting messages and PMKSA cache operations could miss the +Class attribute. + +This change makes sta_info->radius_class the single source of truth for +RADIUS Class attributes and ensures they are preserved and echoed in +Accounting regardless of whether an EAPOL state machine exists. + +Signed-off-by: Venkat Chimata +--- + src/ap/accounting.c | 3 +- + src/ap/ieee802_11.c | 63 ++++++++++++++++++++++++++++ + src/ap/ieee802_11.h | 5 +++ + src/ap/ieee802_11_auth.c | 4 ++ + src/ap/ieee802_1x.c | 71 +------------------------------- + src/ap/ieee802_1x.h | 2 - + src/ap/pmksa_cache_auth.c | 10 ++--- + src/ap/sta_info.c | 1 + + src/ap/sta_info.h | 2 + + src/eapol_auth/eapol_auth_sm_i.h | 1 - + 10 files changed, 84 insertions(+), 78 deletions(-) + +diff --git a/src/ap/accounting.c b/src/ap/accounting.c +index 9fc1886..99f8ac9 100644 +--- a/src/ap/accounting.c ++++ b/src/ap/accounting.c +@@ -15,6 +15,7 @@ + #include "radius/radius.h" + #include "radius/radius_client.h" + #include "hostapd.h" ++#include "ieee802_11.h" + #include "ieee802_1x.h" + #include "ap_config.h" + #include "sta_info.h" +@@ -102,7 +103,7 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd, + + if (sta) { + for (i = 0; ; i++) { +- val = ieee802_1x_get_radius_class(sta->eapol_sm, &len, ++ val = radius_get_class(sta, &len, + i); + if (val == NULL) + break; +diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c +index 615fb32..fc26caf 100644 +--- a/src/ap/ieee802_11.c ++++ b/src/ap/ieee802_11.c +@@ -10028,4 +10028,67 @@ void punct_update_legacy_bw(u16 bitmap, u8 pri, enum oper_chan_width *width, + } + } + ++void radius_store_class(struct hostapd_data *hapd, ++ struct sta_info *sta, ++ struct radius_msg *msg) ++{ ++ u8 *attr_class; ++ size_t class_len; ++ int count, i; ++ struct radius_attr_data *nclass; ++ size_t nclass_count; ++ ++ if (!hapd->conf->radius->acct_server || !hapd->radius) ++ return; ++ ++ radius_free_class(&sta->radius_class); ++ count = radius_msg_count_attr(msg, RADIUS_ATTR_CLASS, 1); ++ if (count <= 0) ++ return; ++ ++ nclass = os_calloc(count, sizeof(struct radius_attr_data)); ++ if (!nclass) ++ return; ++ ++ nclass_count = 0; ++ ++ attr_class = NULL; ++ for (i = 0; i < count; i++) { ++ do { ++ if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CLASS, ++ &attr_class, &class_len, ++ attr_class) < 0) { ++ i = count; ++ break; ++ } ++ } while (class_len < 1); ++ ++ nclass[nclass_count].data = os_memdup(attr_class, class_len); ++ if (!nclass[nclass_count].data) ++ break; ++ ++ nclass[nclass_count].len = class_len; ++ nclass_count++; ++ } ++ ++ sta->radius_class.attr = nclass; ++ sta->radius_class.count = nclass_count; ++ wpa_printf(MSG_DEBUG, ++ "IEEE 802.1X: Stored %lu RADIUS Class attributes for " ++ MACSTR, ++ (unsigned long) sta->radius_class.count, ++ MAC2STR(sta->addr)); ++} ++ ++u8* radius_get_class(struct sta_info *sta, size_t *len, ++ int idx) ++{ ++ if (!sta || !sta->radius_class.attr || ++ idx >= (int) sta->radius_class.count) ++ return NULL; ++ ++ *len = sta->radius_class.attr[idx].len; ++ return sta->radius_class.attr[idx].data; ++} ++ + #endif /* CONFIG_NATIVE_WINDOWS */ +diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h +index 83f4884..f140fe0 100644 +--- a/src/ap/ieee802_11.h ++++ b/src/ap/ieee802_11.h +@@ -286,5 +286,10 @@ bool hostapd_is_mld_ap(struct hostapd_data *hapd); + void hostapd_eid_update_cu_info(struct hostapd_data *hapd, u16 *elemid_modified, + const u8 *eid_pos, size_t eid_len, + enum elemid_cu eid_cu); ++void radius_store_class(struct hostapd_data *hapd, ++ struct sta_info *sta, ++ struct radius_msg *msg); ++u8* radius_get_class(struct sta_info *sta, size_t *len, ++ int idx); + + #endif /* IEEE802_11_H */ +diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c +index d461d2b..9e8d004 100644 +--- a/src/ap/ieee802_11_auth.c ++++ b/src/ap/ieee802_11_auth.c +@@ -498,6 +498,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req, + struct hostapd_cached_radius_acl *cache; + struct radius_sta *info; + struct radius_hdr *hdr = radius_msg_get_hdr(msg); ++ struct sta_info *sta; + + query = hapd->acl_queries; + prev = NULL; +@@ -537,6 +538,8 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req, + os_get_reltime(&cache->timestamp); + os_memcpy(cache->addr, query->addr, sizeof(cache->addr)); + info = &cache->info; ++ sta = ap_get_sta(hapd, query->addr); ++ + if (hdr->code == RADIUS_CODE_ACCESS_ACCEPT) { + u8 *buf; + size_t len; +@@ -573,6 +576,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req, + if (info->identity) + os_memcpy(info->identity, buf, len); + } ++ radius_store_class(hapd, sta, msg); + if (radius_msg_get_attr_ptr( + msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, + &buf, &len, NULL) == 0) { +diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c +index 91c537f..4b20278 100644 +--- a/src/ap/ieee802_1x.c ++++ b/src/ap/ieee802_1x.c +@@ -1486,7 +1486,7 @@ void ieee802_1x_free_station(struct hostapd_data *hapd, struct sta_info *sta) + + #ifndef CONFIG_NO_RADIUS + radius_msg_free(sm->last_recv_radius); +- radius_free_class(&sm->radius_class); ++ radius_free_class(&sta->radius_class); + #endif /* CONFIG_NO_RADIUS */ + + eapol_auth_free(sm); +@@ -1633,61 +1633,6 @@ static void ieee802_1x_get_keys(struct hostapd_data *hapd, + } + } + +- +-static void ieee802_1x_store_radius_class(struct hostapd_data *hapd, +- struct sta_info *sta, +- struct radius_msg *msg) +-{ +- u8 *attr_class; +- size_t class_len; +- struct eapol_state_machine *sm = sta->eapol_sm; +- int count, i; +- struct radius_attr_data *nclass; +- size_t nclass_count; +- +- if (!hapd->conf->radius->acct_server || !hapd->radius || !sm) +- return; +- +- radius_free_class(&sm->radius_class); +- count = radius_msg_count_attr(msg, RADIUS_ATTR_CLASS, 1); +- if (count <= 0) +- return; +- +- nclass = os_calloc(count, sizeof(struct radius_attr_data)); +- if (!nclass) +- return; +- +- nclass_count = 0; +- +- attr_class = NULL; +- for (i = 0; i < count; i++) { +- do { +- if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CLASS, +- &attr_class, &class_len, +- attr_class) < 0) { +- i = count; +- break; +- } +- } while (class_len < 1); +- +- nclass[nclass_count].data = os_memdup(attr_class, class_len); +- if (!nclass[nclass_count].data) +- break; +- +- nclass[nclass_count].len = class_len; +- nclass_count++; +- } +- +- sm->radius_class.attr = nclass; +- sm->radius_class.count = nclass_count; +- wpa_printf(MSG_DEBUG, +- "IEEE 802.1X: Stored %lu RADIUS Class attributes for " +- MACSTR, +- (unsigned long) sm->radius_class.count, +- MAC2STR(sta->addr)); +-} +- +- + /* Update sta->identity based on User-Name attribute in Access-Accept */ + static void ieee802_1x_update_sta_identity(struct hostapd_data *hapd, + struct sta_info *sta, +@@ -2146,7 +2091,7 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, + override_eapReq = 1; + ieee802_1x_get_keys(hapd, sta, msg, req, shared_secret, + shared_secret_len); +- ieee802_1x_store_radius_class(hapd, sta, msg); ++ radius_store_class(hapd, sta, msg); + ieee802_1x_update_sta_identity(hapd, sta, msg); + ieee802_1x_update_sta_cui(hapd, sta, msg); + ieee802_1x_check_hs20(hapd, sta, msg, +@@ -2792,18 +2737,6 @@ u8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len) + } + + +-u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len, +- int idx) +-{ +- if (!sm || !sm->radius_class.attr || +- idx >= (int) sm->radius_class.count) +- return NULL; +- +- *len = sm->radius_class.attr[idx].len; +- return sm->radius_class.attr[idx].data; +-} +- +- + struct wpabuf * ieee802_1x_get_radius_cui(struct eapol_state_machine *sm) + { + if (!sm) +diff --git a/src/ap/ieee802_1x.h b/src/ap/ieee802_1x.h +index 1469351..60af508 100644 +--- a/src/ap/ieee802_1x.h ++++ b/src/ap/ieee802_1x.h +@@ -35,8 +35,6 @@ int ieee802_1x_tx_status(struct hostapd_data *hapd, struct sta_info *sta, + int ieee802_1x_eapol_tx_status(struct hostapd_data *hapd, struct sta_info *sta, + const u8 *data, int len, int ack); + u8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len); +-u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len, +- int idx); + struct wpabuf * ieee802_1x_get_radius_cui(struct eapol_state_machine *sm); + const u8 * ieee802_1x_get_key(struct eapol_state_machine *sm, size_t *len); + const u8 * ieee802_1x_get_session_id(struct eapol_state_machine *sm, +diff --git a/src/ap/pmksa_cache_auth.c b/src/ap/pmksa_cache_auth.c +index 32d291d..251f668 100644 +--- a/src/ap/pmksa_cache_auth.c ++++ b/src/ap/pmksa_cache_auth.c +@@ -160,7 +160,7 @@ static void pmksa_cache_from_eapol_data(struct rsn_pmksa_cache_entry *entry, + entry->cui = wpabuf_dup(eapol->radius_cui); + + #ifndef CONFIG_NO_RADIUS +- radius_copy_class(&entry->radius_class, &eapol->radius_class); ++ radius_copy_class(&entry->radius_class, &((struct sta_info *) eapol->sta)->radius_class); + #endif /* CONFIG_NO_RADIUS */ + + entry->eap_type_authsrv = eapol->eap_type_authsrv; +@@ -203,12 +203,12 @@ void pmksa_cache_to_eapol_data(struct hostapd_data *hapd, + } + + #ifndef CONFIG_NO_RADIUS +- radius_free_class(&eapol->radius_class); +- radius_copy_class(&eapol->radius_class, &entry->radius_class); ++ radius_free_class(&((struct sta_info *) eapol->sta)->radius_class); ++ radius_copy_class(&((struct sta_info *) eapol->sta)->radius_class, &entry->radius_class); + #endif /* CONFIG_NO_RADIUS */ +- if (eapol->radius_class.attr) { ++ if (((struct sta_info *) eapol->sta)->radius_class.attr) { + wpa_printf(MSG_DEBUG, "Copied %lu Class attribute(s) from " +- "PMKSA", (unsigned long) eapol->radius_class.count); ++ "PMKSA", (unsigned long) ((struct sta_info *) eapol->sta)->radius_class.count); + } + + eapol->eap_type_authsrv = entry->eap_type_authsrv; +diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c +index 6011980..d46cc1f 100644 +--- a/src/ap/sta_info.c ++++ b/src/ap/sta_info.c +@@ -493,6 +493,7 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta) + #ifndef CONFIG_NO_RADIUS + if (hapd->radius) + radius_client_flush_auth(hapd->radius, sta->addr); ++ radius_free_class(&sta->radius_class); + #endif /* CONFIG_NO_RADIUS */ + + #ifndef CONFIG_NO_VLAN +diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h +index e3aab48..23d441b 100644 +--- a/src/ap/sta_info.h ++++ b/src/ap/sta_info.h +@@ -17,6 +17,7 @@ + #include "common/sae.h" + #include "crypto/sha384.h" + #include "pasn/pasn_common.h" ++#include "radius/radius.h" + + #define HOSTAPD_SCS_MAX_SIZE 10 + /* STA flags */ +@@ -365,6 +366,7 @@ struct sta_info { + struct hostapd_scs_resp *scs_resp; + u8 session_cnt; + #endif ++ struct radius_class_data radius_class; + }; + + +diff --git a/src/eapol_auth/eapol_auth_sm_i.h b/src/eapol_auth/eapol_auth_sm_i.h +index a0cef0f..7e1d6bc 100644 +--- a/src/eapol_auth/eapol_auth_sm_i.h ++++ b/src/eapol_auth/eapol_auth_sm_i.h +@@ -156,7 +156,6 @@ struct eapol_state_machine { + u8 eap_type_authsrv; /* EAP type of the last EAP packet from + * Authentication server */ + u8 eap_type_supp; /* EAP type of the last EAP packet from Supplicant */ +- struct radius_class_data radius_class; + struct wpabuf *radius_cui; /* Chargeable-User-Identity */ + + struct eap_sm *eap; +-- +2.34.1 + From f3086d4bb9c7bda7eb75f572218331191336638e Mon Sep 17 00:00:00 2001 From: Venkat Chimata Date: Mon, 2 Feb 2026 11:25:56 +0530 Subject: [PATCH 7/8] ipq807x_v5.4 / hostapd: store RADIUS Class per STA instead of EAPOL SM; preserve Class for ACL/MAC auth and accounting Move storage of RADIUS Class attributes from the EAPOL state machine to struct sta_info and update all users accordingly. Previously, Class was kept only in eapol_state_machine->radius_class, which caused Class to be lost for authentication paths where eapol_sm is not created. As a result, Accounting messages and PMKSA cache operations could miss the Class attribute. This change makes sta_info->radius_class the single source of truth for RADIUS Class attributes and ensures they are preserved and echoed in Accounting regardless of whether an EAPOL state machine exists. Signed-off-by: Venkat Chimata --- ...DIUS-Class-per-STA-instead-of-EAPOL-.patch | 358 ++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 feeds/qca-wifi-6/hostapd/patches/zzz-t001-hostapd-store-RADIUS-Class-per-STA-instead-of-EAPOL-.patch diff --git a/feeds/qca-wifi-6/hostapd/patches/zzz-t001-hostapd-store-RADIUS-Class-per-STA-instead-of-EAPOL-.patch b/feeds/qca-wifi-6/hostapd/patches/zzz-t001-hostapd-store-RADIUS-Class-per-STA-instead-of-EAPOL-.patch new file mode 100644 index 000000000..632347a6a --- /dev/null +++ b/feeds/qca-wifi-6/hostapd/patches/zzz-t001-hostapd-store-RADIUS-Class-per-STA-instead-of-EAPOL-.patch @@ -0,0 +1,358 @@ +From ff647b3a490692e23ec804e123be1f6f945dee14 Mon Sep 17 00:00:00 2001 +From: Venkat Chimata +Date: Mon, 2 Feb 2026 14:42:02 +0530 +Subject: [PATCH] hostapd: store RADIUS Class per STA instead of EAPOL SM; + preserve Class for ACL/MAC auth and accounting + +Move storage of RADIUS Class attributes from the EAPOL state machine to +struct sta_info and update all users accordingly. Previously, Class was +kept only in eapol_state_machine->radius_class, which caused Class to be +lost for authentication paths where eapol_sm is not created. As a result, +Accounting messages and PMKSA cache operations could miss the +Class attribute. + +This change makes sta_info->radius_class the single source of truth for +RADIUS Class attributes and ensures they are preserved and echoed in +Accounting regardless of whether an EAPOL state machine exists. + +Signed-off-by: Venkat Chimata +--- + src/ap/accounting.c | 3 +- + src/ap/ieee802_11.c | 63 ++++++++++++++++++++++++++++ + src/ap/ieee802_11.h | 5 +++ + src/ap/ieee802_11_auth.c | 3 ++ + src/ap/ieee802_1x.c | 70 +------------------------------- + src/ap/ieee802_1x.h | 2 - + src/ap/pmksa_cache_auth.c | 10 ++--- + src/ap/sta_info.c | 1 + + src/ap/sta_info.h | 2 + + src/eapol_auth/eapol_auth_sm_i.h | 1 - + 10 files changed, 83 insertions(+), 77 deletions(-) + +diff --git a/src/ap/accounting.c b/src/ap/accounting.c +index 9fc1886..99f8ac9 100644 +--- a/src/ap/accounting.c ++++ b/src/ap/accounting.c +@@ -15,6 +15,7 @@ + #include "radius/radius.h" + #include "radius/radius_client.h" + #include "hostapd.h" ++#include "ieee802_11.h" + #include "ieee802_1x.h" + #include "ap_config.h" + #include "sta_info.h" +@@ -102,7 +103,7 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd, + + if (sta) { + for (i = 0; ; i++) { +- val = ieee802_1x_get_radius_class(sta->eapol_sm, &len, ++ val = radius_get_class(sta, &len, + i); + if (val == NULL) + break; +diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c +index 1015100..a414248 100644 +--- a/src/ap/ieee802_11.c ++++ b/src/ap/ieee802_11.c +@@ -7996,4 +7996,67 @@ u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type) + return _hostapd_eid_rnr(hapd, eid, type, 1); + } + ++void radius_store_class(struct hostapd_data *hapd, ++ struct sta_info *sta, ++ struct radius_msg *msg) ++{ ++ u8 *attr_class; ++ size_t class_len; ++ int count, i; ++ struct radius_attr_data *nclass; ++ size_t nclass_count; ++ ++ if (!hapd->conf->radius->acct_server || !hapd->radius) ++ return; ++ ++ radius_free_class(&sta->radius_class); ++ count = radius_msg_count_attr(msg, RADIUS_ATTR_CLASS, 1); ++ if (count <= 0) ++ return; ++ ++ nclass = os_calloc(count, sizeof(struct radius_attr_data)); ++ if (!nclass) ++ return; ++ ++ nclass_count = 0; ++ ++ attr_class = NULL; ++ for (i = 0; i < count; i++) { ++ do { ++ if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CLASS, ++ &attr_class, &class_len, ++ attr_class) < 0) { ++ i = count; ++ break; ++ } ++ } while (class_len < 1); ++ ++ nclass[nclass_count].data = os_memdup(attr_class, class_len); ++ if (!nclass[nclass_count].data) ++ break; ++ ++ nclass[nclass_count].len = class_len; ++ nclass_count++; ++ } ++ ++ sta->radius_class.attr = nclass; ++ sta->radius_class.count = nclass_count; ++ wpa_printf(MSG_DEBUG, ++ "IEEE 802.1X: Stored %lu RADIUS Class attributes for " ++ MACSTR, ++ (unsigned long) sta->radius_class.count, ++ MAC2STR(sta->addr)); ++} ++ ++u8 * radius_get_class(struct sta_info *sta, size_t *len, ++ int idx) ++{ ++ if (!sta || !sta->radius_class.attr || ++ idx >= (int) sta->radius_class.count) ++ return NULL; ++ ++ *len = sta->radius_class.attr[idx].len; ++ return sta->radius_class.attr[idx].data; ++} ++ + #endif /* CONFIG_NATIVE_WINDOWS */ +diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h +index 953e8b9..e77b2c9 100644 +--- a/src/ap/ieee802_11.h ++++ b/src/ap/ieee802_11.h +@@ -230,4 +230,9 @@ u8 * hostapd_get_rsne(struct hostapd_data *hapd, u8 *pos, size_t len); + u8 * hostapd_get_rsnxe(struct hostapd_data *hapd, u8 *pos, size_t len); + int ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta, + int res, struct radius_sta *info); ++void radius_store_class(struct hostapd_data *hapd, ++ struct sta_info *sta, ++ struct radius_msg *msg); ++u8 * radius_get_class(struct sta_info *sta, size_t *len, ++ int idx); + #endif /* IEEE802_11_H */ +diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c +index 5a9c138..cf2451b 100644 +--- a/src/ap/ieee802_11_auth.c ++++ b/src/ap/ieee802_11_auth.c +@@ -498,6 +498,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req, + struct hostapd_cached_radius_acl *cache; + struct radius_sta *info; + struct radius_hdr *hdr = radius_msg_get_hdr(msg); ++ struct sta_info *sta; + + query = hapd->acl_queries; + prev = NULL; +@@ -535,6 +536,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req, + os_get_reltime(&cache->timestamp); + os_memcpy(cache->addr, query->addr, sizeof(cache->addr)); + info = &cache->info; ++ sta = ap_get_sta(hapd, query->addr); + if (hdr->code == RADIUS_CODE_ACCESS_ACCEPT) { + u8 *buf; + size_t len; +@@ -570,6 +572,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req, + if (info->identity) + os_memcpy(info->identity, buf, len); + } ++ radius_store_class(hapd, sta, msg); + if (radius_msg_get_attr_ptr( + msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, + &buf, &len, NULL) == 0) { +diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c +index d29df98..295b3ca 100644 +--- a/src/ap/ieee802_1x.c ++++ b/src/ap/ieee802_1x.c +@@ -1399,7 +1399,7 @@ void ieee802_1x_free_station(struct hostapd_data *hapd, struct sta_info *sta) + + #ifndef CONFIG_NO_RADIUS + radius_msg_free(sm->last_recv_radius); +- radius_free_class(&sm->radius_class); ++ radius_free_class(&sta->radius_class); + #endif /* CONFIG_NO_RADIUS */ + + eapol_auth_free(sm); +@@ -1547,60 +1547,6 @@ static void ieee802_1x_get_keys(struct hostapd_data *hapd, + } + + +-static void ieee802_1x_store_radius_class(struct hostapd_data *hapd, +- struct sta_info *sta, +- struct radius_msg *msg) +-{ +- u8 *attr_class; +- size_t class_len; +- struct eapol_state_machine *sm = sta->eapol_sm; +- int count, i; +- struct radius_attr_data *nclass; +- size_t nclass_count; +- +- if (!hapd->conf->radius->acct_server || !hapd->radius || !sm) +- return; +- +- radius_free_class(&sm->radius_class); +- count = radius_msg_count_attr(msg, RADIUS_ATTR_CLASS, 1); +- if (count <= 0) +- return; +- +- nclass = os_calloc(count, sizeof(struct radius_attr_data)); +- if (!nclass) +- return; +- +- nclass_count = 0; +- +- attr_class = NULL; +- for (i = 0; i < count; i++) { +- do { +- if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CLASS, +- &attr_class, &class_len, +- attr_class) < 0) { +- i = count; +- break; +- } +- } while (class_len < 1); +- +- nclass[nclass_count].data = os_memdup(attr_class, class_len); +- if (!nclass[nclass_count].data) +- break; +- +- nclass[nclass_count].len = class_len; +- nclass_count++; +- } +- +- sm->radius_class.attr = nclass; +- sm->radius_class.count = nclass_count; +- wpa_printf(MSG_DEBUG, +- "IEEE 802.1X: Stored %lu RADIUS Class attributes for " +- MACSTR, +- (unsigned long) sm->radius_class.count, +- MAC2STR(sta->addr)); +-} +- +- + /* Update sta->identity based on User-Name attribute in Access-Accept */ + static void ieee802_1x_update_sta_identity(struct hostapd_data *hapd, + struct sta_info *sta, +@@ -2046,7 +1992,7 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, + override_eapReq = 1; + ieee802_1x_get_keys(hapd, sta, msg, req, shared_secret, + shared_secret_len); +- ieee802_1x_store_radius_class(hapd, sta, msg); ++ radius_store_class(hapd, sta, msg); + ieee802_1x_update_sta_identity(hapd, sta, msg); + ieee802_1x_update_sta_cui(hapd, sta, msg); + ieee802_1x_check_hs20(hapd, sta, msg, +@@ -2656,18 +2602,6 @@ u8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len) + } + + +-u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len, +- int idx) +-{ +- if (!sm || !sm->radius_class.attr || +- idx >= (int) sm->radius_class.count) +- return NULL; +- +- *len = sm->radius_class.attr[idx].len; +- return sm->radius_class.attr[idx].data; +-} +- +- + struct wpabuf * ieee802_1x_get_radius_cui(struct eapol_state_machine *sm) + { + if (!sm) +diff --git a/src/ap/ieee802_1x.h b/src/ap/ieee802_1x.h +index 70dc11a..bd6ccf2 100644 +--- a/src/ap/ieee802_1x.h ++++ b/src/ap/ieee802_1x.h +@@ -35,8 +35,6 @@ int ieee802_1x_tx_status(struct hostapd_data *hapd, struct sta_info *sta, + int ieee802_1x_eapol_tx_status(struct hostapd_data *hapd, struct sta_info *sta, + const u8 *data, int len, int ack); + u8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len); +-u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len, +- int idx); + struct wpabuf * ieee802_1x_get_radius_cui(struct eapol_state_machine *sm); + const u8 * ieee802_1x_get_key(struct eapol_state_machine *sm, size_t *len); + const u8 * ieee802_1x_get_session_id(struct eapol_state_machine *sm, +diff --git a/src/ap/pmksa_cache_auth.c b/src/ap/pmksa_cache_auth.c +index fe5f817..1ef0ee1 100644 +--- a/src/ap/pmksa_cache_auth.c ++++ b/src/ap/pmksa_cache_auth.c +@@ -159,7 +159,7 @@ static void pmksa_cache_from_eapol_data(struct rsn_pmksa_cache_entry *entry, + entry->cui = wpabuf_dup(eapol->radius_cui); + + #ifndef CONFIG_NO_RADIUS +- radius_copy_class(&entry->radius_class, &eapol->radius_class); ++ radius_copy_class(&entry->radius_class, &((struct sta_info *) eapol->sta)->radius_class); + #endif /* CONFIG_NO_RADIUS */ + + entry->eap_type_authsrv = eapol->eap_type_authsrv; +@@ -202,12 +202,12 @@ void pmksa_cache_to_eapol_data(struct hostapd_data *hapd, + } + + #ifndef CONFIG_NO_RADIUS +- radius_free_class(&eapol->radius_class); +- radius_copy_class(&eapol->radius_class, &entry->radius_class); ++ radius_free_class(&((struct sta_info *) eapol->sta)->radius_class); ++ radius_copy_class(&((struct sta_info *) eapol->sta)->radius_class, &entry->radius_class); + #endif /* CONFIG_NO_RADIUS */ +- if (eapol->radius_class.attr) { ++ if (((struct sta_info *) eapol->sta)->radius_class.attr) { + wpa_printf(MSG_DEBUG, "Copied %lu Class attribute(s) from " +- "PMKSA", (unsigned long) eapol->radius_class.count); ++ "PMKSA", (unsigned long) ((struct sta_info *) eapol->sta)->radius_class.count); + } + + eapol->eap_type_authsrv = entry->eap_type_authsrv; +diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c +index 235ed89..4d69472 100644 +--- a/src/ap/sta_info.c ++++ b/src/ap/sta_info.c +@@ -303,6 +303,7 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta) + #ifndef CONFIG_NO_RADIUS + if (hapd->radius) + radius_client_flush_auth(hapd->radius, sta->addr); ++ radius_free_class(&sta->radius_class); + #endif /* CONFIG_NO_RADIUS */ + + #ifndef CONFIG_NO_VLAN +diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h +index 942bb3b..c22deac 100644 +--- a/src/ap/sta_info.h ++++ b/src/ap/sta_info.h +@@ -16,6 +16,7 @@ + #include "common/ieee802_11_defs.h" + #include "common/sae.h" + #include "crypto/sha384.h" ++#include "radius/radius.h" + + /* STA flags */ + #define WLAN_STA_AUTH BIT(0) +@@ -337,6 +338,7 @@ struct sta_info { + struct pasn_data *pasn; + #endif /* CONFIG_PASN */ + int signal_mgmt; ++ struct radius_class_data radius_class; + }; + + +diff --git a/src/eapol_auth/eapol_auth_sm_i.h b/src/eapol_auth/eapol_auth_sm_i.h +index 3c68983..1026472 100644 +--- a/src/eapol_auth/eapol_auth_sm_i.h ++++ b/src/eapol_auth/eapol_auth_sm_i.h +@@ -156,7 +156,6 @@ struct eapol_state_machine { + u8 eap_type_authsrv; /* EAP type of the last EAP packet from + * Authentication server */ + u8 eap_type_supp; /* EAP type of the last EAP packet from Supplicant */ +- struct radius_class_data radius_class; + struct wpabuf *radius_cui; /* Chargeable-User-Identity */ + + struct eap_sm *eap; +-- +2.34.1 + From 7f99a4d8eb500a48d9ba67f40421ab995467909d Mon Sep 17 00:00:00 2001 From: Venkat Chimata Date: Tue, 17 Mar 2026 11:27:45 +0530 Subject: [PATCH 8/8] hostapd: store RADIUS Class per STA instead of EAPOL SM; preserve Class for ACL/MAC auth and accounting Move storage of RADIUS Class attributes from the EAPOL state machine to struct sta_info and update all users accordingly. Previously, Class was kept only in eapol_state_machine->radius_class, which caused Class to be lost for authentication paths where eapol_sm is not created. As a result, Accounting messages and PMKSA cache operations could miss the Class attribute. This change makes sta_info->radius_class the single source of truth for RADIUS Class attributes and ensures they are preserved and echoed in Accounting regardless of whether an EAPOL state machine exists. Signed-off-by: Venkat Chimata --- ...lass-store-RADIUS-Class-per-STA-inst.patch | 400 ++++++++++++++++++ 1 file changed, 400 insertions(+) create mode 100644 patches-25.12/0102-hostapd-radius-class-store-RADIUS-Class-per-STA-inst.patch diff --git a/patches-25.12/0102-hostapd-radius-class-store-RADIUS-Class-per-STA-inst.patch b/patches-25.12/0102-hostapd-radius-class-store-RADIUS-Class-per-STA-inst.patch new file mode 100644 index 000000000..5edb98910 --- /dev/null +++ b/patches-25.12/0102-hostapd-radius-class-store-RADIUS-Class-per-STA-inst.patch @@ -0,0 +1,400 @@ +From 22893342533ed81864cf4161bb54001b7eed5366 Mon Sep 17 00:00:00 2001 +From: Venkat Chimata +Date: Tue, 17 Mar 2026 11:02:15 +0530 +Subject: [PATCH] hostapd / radius / class: store RADIUS Class per STA instead + of EAPOL SM; preserve Class for ACL/MAC auth and accounting + +Move storage of RADIUS Class attributes from the EAPOL state machine to +struct sta_info and update all users accordingly. Previously, Class was +kept only in eapol_state_machine->radius_class, which caused Class to be +lost for authentication paths where eapol_sm is not created. As a result, +Accounting messages and PMKSA cache operations could miss the +Class attribute. + +This change makes sta_info->radius_class the single source of truth for +RADIUS Class attributes and ensures they are preserved and echoed in +Accounting regardless of whether an EAPOL state machine exists. + +Signed-off-by: Venkat Chimata +--- + ...tore-RADIUS-Class-per-STA-instead-of.patch | 368 ++++++++++++++++++ + 1 file changed, 368 insertions(+) + create mode 100644 package/network/services/hostapd/patches/zzz-0019-radius-class-store-RADIUS-Class-per-STA-instead-of.patch + +diff --git a/package/network/services/hostapd/patches/zzz-0019-radius-class-store-RADIUS-Class-per-STA-instead-of.patch b/package/network/services/hostapd/patches/zzz-0019-radius-class-store-RADIUS-Class-per-STA-instead-of.patch +new file mode 100644 +index 0000000000..28524066d8 +--- /dev/null ++++ b/package/network/services/hostapd/patches/zzz-0019-radius-class-store-RADIUS-Class-per-STA-instead-of.patch +@@ -0,0 +1,368 @@ ++From f554c855229c9078174e18fa0b71161162b7160b Mon Sep 17 00:00:00 2001 ++From: Venkat Chimata ++Date: Tue, 17 Mar 2026 10:58:41 +0530 ++Subject: [PATCH] radius / class: store RADIUS Class per STA instead of EAPOL ++ SM; preserve Class for ACL/MAC auth and accounting ++ ++Move storage of RADIUS Class attributes from the EAPOL state machine to ++struct sta_info and update all users accordingly. Previously, Class was ++kept only in eapol_state_machine->radius_class, which caused Class to be ++lost for authentication paths where eapol_sm is not created. As a result, ++Accounting messages and PMKSA cache operations could miss the ++Class attribute. ++ ++This change makes sta_info->radius_class the single source of truth for ++RADIUS Class attributes and ensures they are preserved and echoed in ++Accounting regardless of whether an EAPOL state machine exists. ++ ++Signed-off-by: Venkat Chimata ++--- ++ src/ap/accounting.c | 3 +- ++ src/ap/ieee802_11.c | 65 ++++++++++++++++++++++++++++++ ++ src/ap/ieee802_11.h | 5 +++ ++ src/ap/ieee802_11_auth.c | 3 ++ ++ src/ap/ieee802_1x.c | 69 +------------------------------- ++ src/ap/ieee802_1x.h | 2 - ++ src/ap/pmksa_cache_auth.c | 10 ++--- ++ src/ap/sta_info.c | 2 + ++ src/ap/sta_info.h | 3 +- ++ src/eapol_auth/eapol_auth_sm_i.h | 1 - ++ 10 files changed, 86 insertions(+), 77 deletions(-) ++ ++diff --git a/src/ap/accounting.c b/src/ap/accounting.c ++index 9fc1886..99f8ac9 100644 ++--- a/src/ap/accounting.c +++++ b/src/ap/accounting.c ++@@ -15,6 +15,7 @@ ++ #include "radius/radius.h" ++ #include "radius/radius_client.h" ++ #include "hostapd.h" +++#include "ieee802_11.h" ++ #include "ieee802_1x.h" ++ #include "ap_config.h" ++ #include "sta_info.h" ++@@ -102,7 +103,7 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd, ++ ++ if (sta) { ++ for (i = 0; ; i++) { ++- val = ieee802_1x_get_radius_class(sta->eapol_sm, &len, +++ val = radius_get_class(sta, &len, ++ i); ++ if (val == NULL) ++ break; ++diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c ++index 8538670..ed5f1fb 100644 ++--- a/src/ap/ieee802_11.c +++++ b/src/ap/ieee802_11.c ++@@ -10,6 +10,7 @@ ++ ++ #ifndef CONFIG_NATIVE_WINDOWS ++ +++#include ++ #include "utils/common.h" ++ #include "utils/eloop.h" ++ #include "crypto/crypto.h" ++@@ -9001,4 +9002,68 @@ u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end, ++ return eid; ++ } ++ +++void radius_store_class(struct hostapd_data *hapd, +++ struct sta_info *sta, +++ struct radius_msg *msg) +++{ +++ u8 *attr_class; +++ size_t class_len; +++ int count, i; +++ struct radius_attr_data *nclass; +++ size_t nclass_count; +++ +++ if (!hapd->conf->radius->acct_server || !hapd->radius) +++ return; +++ +++ radius_free_class(&sta->radius_class); +++ count = radius_msg_count_attr(msg, RADIUS_ATTR_CLASS, 1); +++ if (count <= 0) +++ return; +++ +++ nclass = os_calloc(count, sizeof(struct radius_attr_data)); +++ if (!nclass) +++ return; +++ +++ nclass_count = 0; +++ +++ attr_class = NULL; +++ for (i = 0; i < count; i++) { +++ do { +++ if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CLASS, +++ &attr_class, &class_len, +++ attr_class) < 0) { +++ i = count; +++ break; +++ } +++ } while (class_len < 1); +++ +++ nclass[nclass_count].data = os_memdup(attr_class, class_len); +++ if (!nclass[nclass_count].data) +++ break; +++ +++ nclass[nclass_count].len = class_len; +++ nclass_count++; +++ } +++ +++ sta->radius_class.attr = nclass; +++ sta->radius_class.count = nclass_count; +++ wpa_printf(MSG_DEBUG, +++ "IEEE 802.1X: Stored %lu RADIUS Class attributes for " +++ MACSTR, +++ (unsigned long) sta->radius_class.count, +++ MAC2STR(sta->addr)); +++} +++ +++u8* radius_get_class(struct sta_info *sta, size_t *len, +++ int idx) +++{ +++ if (!sta || !sta->radius_class.attr || +++ idx >= (int) sta->radius_class.count) +++ return NULL; +++ +++ *len = sta->radius_class.attr[idx].len; +++ return sta->radius_class.attr[idx].data; +++} +++ +++ ++ #endif /* CONFIG_NATIVE_WINDOWS */ ++diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h ++index 930be67..5d45e21 100644 ++--- a/src/ap/ieee802_11.h +++++ b/src/ap/ieee802_11.h ++@@ -324,4 +324,9 @@ void hostapd_link_reconf_resp_tx_status(struct hostapd_data *hapd, ++ const struct ieee80211_mgmt *mgmt, ++ size_t len, int ok); ++ +++void radius_store_class(struct hostapd_data *hapd, +++ struct sta_info *sta, +++ struct radius_msg *msg); +++u8* radius_get_class(struct sta_info *sta, size_t *len, int idx); +++ ++ #endif /* IEEE802_11_H */ ++diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c ++index fa3895a..10fff2e 100644 ++--- a/src/ap/ieee802_11_auth.c +++++ b/src/ap/ieee802_11_auth.c ++@@ -500,6 +500,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req, ++ struct hostapd_cached_radius_acl *cache; ++ struct radius_sta *info; ++ struct radius_hdr *hdr = radius_msg_get_hdr(msg); +++ struct sta_info *sta; ++ ++ query = hapd->acl_queries; ++ prev = NULL; ++@@ -541,6 +542,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req, ++ os_get_reltime(&cache->timestamp); ++ os_memcpy(cache->addr, query->addr, sizeof(cache->addr)); ++ info = &cache->info; +++ sta = ap_get_sta(hapd, query->addr); ++ if (hdr->code == RADIUS_CODE_ACCESS_ACCEPT) { ++ u8 *buf; ++ size_t len; ++@@ -577,6 +579,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req, ++ if (info->identity) ++ os_memcpy(info->identity, buf, len); ++ } +++ radius_store_class(hapd, sta, msg); ++ if (radius_msg_get_attr_ptr( ++ msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, ++ &buf, &len, NULL) == 0) { ++diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c ++index ab20478..73f5e17 100644 ++--- a/src/ap/ieee802_1x.c +++++ b/src/ap/ieee802_1x.c ++@@ -1513,7 +1513,7 @@ void ieee802_1x_free_station(struct hostapd_data *hapd, struct sta_info *sta) ++ ++ #ifndef CONFIG_NO_RADIUS ++ radius_msg_free(sm->last_recv_radius); ++- radius_free_class(&sm->radius_class); +++ radius_free_class(&sta->radius_class); ++ #endif /* CONFIG_NO_RADIUS */ ++ ++ eapol_auth_free(sm); ++@@ -1661,59 +1661,6 @@ static void ieee802_1x_get_keys(struct hostapd_data *hapd, ++ } ++ ++ ++-static void ieee802_1x_store_radius_class(struct hostapd_data *hapd, ++- struct sta_info *sta, ++- struct radius_msg *msg) ++-{ ++- u8 *attr_class; ++- size_t class_len; ++- struct eapol_state_machine *sm = sta->eapol_sm; ++- int count, i; ++- struct radius_attr_data *nclass; ++- size_t nclass_count; ++- ++- if (!hapd->conf->radius->acct_server || !hapd->radius || !sm) ++- return; ++- ++- radius_free_class(&sm->radius_class); ++- count = radius_msg_count_attr(msg, RADIUS_ATTR_CLASS, 1); ++- if (count <= 0) ++- return; ++- ++- nclass = os_calloc(count, sizeof(struct radius_attr_data)); ++- if (!nclass) ++- return; ++- ++- nclass_count = 0; ++- ++- attr_class = NULL; ++- for (i = 0; i < count; i++) { ++- do { ++- if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CLASS, ++- &attr_class, &class_len, ++- attr_class) < 0) { ++- i = count; ++- break; ++- } ++- } while (class_len < 1); ++- ++- nclass[nclass_count].data = os_memdup(attr_class, class_len); ++- if (!nclass[nclass_count].data) ++- break; ++- ++- nclass[nclass_count].len = class_len; ++- nclass_count++; ++- } ++- ++- sm->radius_class.attr = nclass; ++- sm->radius_class.count = nclass_count; ++- wpa_printf(MSG_DEBUG, ++- "IEEE 802.1X: Stored %lu RADIUS Class attributes for " ++- MACSTR, ++- (unsigned long) sm->radius_class.count, ++- MAC2STR(sta->addr)); ++-} ++- ++ ++ /* Update sta->identity based on User-Name attribute in Access-Accept */ ++ static void ieee802_1x_update_sta_identity(struct hostapd_data *hapd, ++@@ -2134,7 +2081,7 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, ++ override_eapReq = 1; ++ ieee802_1x_get_keys(hapd, sta, msg, req, shared_secret, ++ shared_secret_len); ++- ieee802_1x_store_radius_class(hapd, sta, msg); +++ radius_store_class(hapd, sta, msg); ++ ieee802_1x_update_sta_identity(hapd, sta, msg); ++ ieee802_1x_update_sta_cui(hapd, sta, msg); ++ ieee802_1x_check_hs20(hapd, sta, msg, ++@@ -2780,18 +2727,6 @@ u8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len) ++ } ++ ++ ++-u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len, ++- int idx) ++-{ ++- if (!sm || !sm->radius_class.attr || ++- idx >= (int) sm->radius_class.count) ++- return NULL; ++- ++- *len = sm->radius_class.attr[idx].len; ++- return sm->radius_class.attr[idx].data; ++-} ++- ++- ++ struct wpabuf * ieee802_1x_get_radius_cui(struct eapol_state_machine *sm) ++ { ++ if (!sm) ++diff --git a/src/ap/ieee802_1x.h b/src/ap/ieee802_1x.h ++index 1469351..60af508 100644 ++--- a/src/ap/ieee802_1x.h +++++ b/src/ap/ieee802_1x.h ++@@ -35,8 +35,6 @@ int ieee802_1x_tx_status(struct hostapd_data *hapd, struct sta_info *sta, ++ int ieee802_1x_eapol_tx_status(struct hostapd_data *hapd, struct sta_info *sta, ++ const u8 *data, int len, int ack); ++ u8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len); ++-u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len, ++- int idx); ++ struct wpabuf * ieee802_1x_get_radius_cui(struct eapol_state_machine *sm); ++ const u8 * ieee802_1x_get_key(struct eapol_state_machine *sm, size_t *len); ++ const u8 * ieee802_1x_get_session_id(struct eapol_state_machine *sm, ++diff --git a/src/ap/pmksa_cache_auth.c b/src/ap/pmksa_cache_auth.c ++index 0715540..bc8d742 100644 ++--- a/src/ap/pmksa_cache_auth.c +++++ b/src/ap/pmksa_cache_auth.c ++@@ -162,7 +162,7 @@ static void pmksa_cache_from_eapol_data(struct rsn_pmksa_cache_entry *entry, ++ entry->cui = wpabuf_dup(eapol->radius_cui); ++ ++ #ifndef CONFIG_NO_RADIUS ++- radius_copy_class(&entry->radius_class, &eapol->radius_class); +++ radius_copy_class(&entry->radius_class, &((struct sta_info *) eapol->sta)->radius_class); ++ #endif /* CONFIG_NO_RADIUS */ ++ ++ entry->eap_type_authsrv = eapol->eap_type_authsrv; ++@@ -205,12 +205,12 @@ void pmksa_cache_to_eapol_data(struct hostapd_data *hapd, ++ } ++ ++ #ifndef CONFIG_NO_RADIUS ++- radius_free_class(&eapol->radius_class); ++- radius_copy_class(&eapol->radius_class, &entry->radius_class); +++ radius_free_class(&((struct sta_info *) eapol->sta)->radius_class); +++ radius_copy_class(&((struct sta_info *) eapol->sta)->radius_class, &entry->radius_class); ++ #endif /* CONFIG_NO_RADIUS */ ++- if (eapol->radius_class.attr) { +++ if (((struct sta_info *) eapol->sta)->radius_class.attr) { ++ wpa_printf(MSG_DEBUG, "Copied %lu Class attribute(s) from " ++- "PMKSA", (unsigned long) eapol->radius_class.count); +++ "PMKSA", (unsigned long) ((struct sta_info *) eapol->sta)->radius_class.count); ++ } ++ ++ eapol->eap_type_authsrv = entry->eap_type_authsrv; ++diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c ++index d60d8d3..ee76e6e 100644 ++--- a/src/ap/sta_info.c +++++ b/src/ap/sta_info.c ++@@ -361,6 +361,8 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta) ++ #ifndef CONFIG_NO_RADIUS ++ if (hapd->radius) ++ radius_client_flush_auth(hapd->radius, sta->addr); +++ +++ radius_free_class(&sta->radius_class); ++ #endif /* CONFIG_NO_RADIUS */ ++ ++ #ifndef CONFIG_NO_VLAN ++diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h ++index 7df6eb2..ae76212 100644 ++--- a/src/ap/sta_info.h +++++ b/src/ap/sta_info.h ++@@ -18,6 +18,7 @@ ++ #include "crypto/sha384.h" ++ #include "pasn/pasn_common.h" ++ #include "hostapd.h" +++#include "radius/radius.h" ++ ++ /* STA flags */ ++ #define WLAN_STA_AUTH BIT(0) ++@@ -321,7 +322,7 @@ struct sta_info { ++ u8 mld_assoc_link_id; ++ struct link_reconf_req_list *reconf_req; ++ #endif /* CONFIG_IEEE80211BE */ ++- +++ struct radius_class_data radius_class; ++ u16 max_idle_period; /* if nonzero, the granted BSS max idle period in ++ * units of 1000 TUs */ ++ ++diff --git a/src/eapol_auth/eapol_auth_sm_i.h b/src/eapol_auth/eapol_auth_sm_i.h ++index c970e73..65f1f26 100644 ++--- a/src/eapol_auth/eapol_auth_sm_i.h +++++ b/src/eapol_auth/eapol_auth_sm_i.h ++@@ -156,7 +156,6 @@ struct eapol_state_machine { ++ u8 eap_type_authsrv; /* EAP type of the last EAP packet from ++ * Authentication server */ ++ u8 eap_type_supp; /* EAP type of the last EAP packet from Supplicant */ ++- struct radius_class_data radius_class; ++ struct wpabuf *radius_cui; /* Chargeable-User-Identity */ ++ ++ struct eap_sm *eap; ++-- ++2.34.1 ++ +-- +2.34.1 +