From b9abe28ab24fbf333960078a9e2255d01cbf408b Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 20 Nov 2023 08:33:42 +0100 Subject: [PATCH] hostapd: sync builtin patches Signed-off-by: John Crispin --- .../network/services/hostapd/files/hostapd.sh | 17 +- .../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, 497 insertions(+), 61 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..958d5a9ac6 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" ;; @@ -746,11 +745,11 @@ hostapd_set_bss_options() { } case "$auth_type" in - sae|owe|eap192|eap256) + sae|owe|eap192|eap2) set_default ieee80211w 2 set_default sae_require_mfp 1 ;; - psk-sae|psk2-radius|eap-eap256) + psk-sae|psk2-radius|eap-eap2) set_default ieee80211w 1 set_default sae_require_mfp 1 ;; @@ -798,7 +797,7 @@ hostapd_set_bss_options() { vlan_possible=1 wps_possible=1 ;; - eap|eap192|eap-eap256|eap256) + eap|eap192|eap-eap2|eap2) append_radius_server # radius can provide VLAN ID for clients vlan_possible=1 @@ -1344,10 +1343,10 @@ wpa_supplicant_add_network() { default_disabled case "$auth_type" in - sae|owe|eap-eap256) + sae|owe|eap-eap2) set_default ieee80211w 2 ;; - psk-sae|eap192|eap256) + psk-sae|eap192|eap2) set_default ieee80211w 1 ;; esac @@ -1425,7 +1424,7 @@ wpa_supplicant_add_network() { fi append network_data "$passphrase" "$N$T" ;; - eap|eap192|eap-eap256|eap256) + eap|eap192|eap-eap2|eap2) hostapd_append_wpa_key_mgmt key_mgmt="$wpa_key_mgmt" 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