From ec223cf7246d3134f92974be2608ffe8ae8e46c2 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 26 May 2021 14:34:46 +0200 Subject: hostapd: add support for specifying the maxassoc parameter as a device option It allows enforcing a limit on associated stations to be enforced for the full device, e.g. in order to deal with hardware/driver limitations Signed-off-by: Felix Fietkau --- package/network/services/hostapd/files/hostapd.sh | 4 +- .../hostapd/patches/720-iface_max_num_sta.patch | 82 ++++++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 package/network/services/hostapd/patches/720-iface_max_num_sta.patch (limited to 'package') diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh index 8d12683a39..9993bc9047 100644 --- a/package/network/services/hostapd/files/hostapd.sh +++ b/package/network/services/hostapd/files/hostapd.sh @@ -103,6 +103,7 @@ hostapd_common_add_device_config() { config_add_int rts_threshold config_add_int rssi_reject_assoc_rssi config_add_int rssi_ignore_probe_request + config_add_int maxassoc config_add_string acs_chan_bias config_add_array hostapd_options @@ -120,7 +121,7 @@ hostapd_prepare_device_config() { json_get_vars country country_ie beacon_int:100 dtim_period:2 doth require_mode legacy_rates \ acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density \ - rts_threshold beacon_rate rssi_reject_assoc_rssi rssi_ignore_probe_request + rts_threshold beacon_rate rssi_reject_assoc_rssi rssi_ignore_probe_request maxassoc hostapd_set_log_options base_cfg @@ -220,6 +221,7 @@ hostapd_prepare_device_config() { [ -n "$rts_threshold" ] && append base_cfg "rts_threshold=$rts_threshold" "$N" append base_cfg "dtim_period=$dtim_period" "$N" [ "$airtime_mode" -gt 0 ] && append base_cfg "airtime_mode=$airtime_mode" "$N" + [ -n "$maxassoc" ] && append base_cfg "iface_max_num_sta=$maxassoc" "$N" json_get_values opts hostapd_options for val in $opts; do diff --git a/package/network/services/hostapd/patches/720-iface_max_num_sta.patch b/package/network/services/hostapd/patches/720-iface_max_num_sta.patch new file mode 100644 index 0000000000..b93a0bcbef --- /dev/null +++ b/package/network/services/hostapd/patches/720-iface_max_num_sta.patch @@ -0,0 +1,82 @@ +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -2873,6 +2873,14 @@ static int hostapd_config_fill(struct ho + line, bss->max_num_sta, MAX_STA_COUNT); + return 1; + } ++ } else if (os_strcmp(buf, "iface_max_num_sta") == 0) { ++ conf->max_num_sta = atoi(pos); ++ if (conf->max_num_sta < 0 || ++ conf->max_num_sta > MAX_STA_COUNT) { ++ wpa_printf(MSG_ERROR, "Line %d: Invalid max_num_sta=%d; allowed range 0..%d", ++ line, conf->max_num_sta, MAX_STA_COUNT); ++ return 1; ++ } + } else if (os_strcmp(buf, "wpa") == 0) { + bss->wpa = atoi(pos); + } else if (os_strcmp(buf, "extended_key_id") == 0) { +--- a/src/ap/hostapd.h ++++ b/src/ap/hostapd.h +@@ -648,6 +648,7 @@ void hostapd_cleanup_cs_params(struct ho + void hostapd_periodic_iface(struct hostapd_iface *iface); + int hostapd_owe_trans_get_info(struct hostapd_data *hapd); + void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx); ++int hostapd_check_max_sta(struct hostapd_data *hapd); + + /* utils.c */ + int hostapd_register_probereq_cb(struct hostapd_data *hapd, +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -236,6 +236,30 @@ static int hostapd_iface_conf_changed(st + } + + ++static inline int hostapd_iface_num_sta(struct hostapd_iface *iface) ++{ ++ int num_sta = 0; ++ int i; ++ ++ for (i = 0; i < iface->num_bss; i++) ++ num_sta += iface->bss[i]->num_sta; ++ ++ return num_sta; ++} ++ ++ ++int hostapd_check_max_sta(struct hostapd_data *hapd) ++{ ++ if (hapd->num_sta >= hapd->conf->max_num_sta) ++ return 1; ++ ++ if (hapd->iconf->max_num_sta && ++ hostapd_iface_num_sta(hapd->iface) >= hapd->iconf->max_num_sta) ++ return 1; ++ ++ return 0; ++} ++ + int hostapd_reload_config(struct hostapd_iface *iface, int reconf) + { + struct hapd_interfaces *interfaces = iface->interfaces; +--- a/src/ap/beacon.c ++++ b/src/ap/beacon.c +@@ -1039,7 +1039,7 @@ void handle_probe_req(struct hostapd_dat + if (hapd->conf->no_probe_resp_if_max_sta && + is_multicast_ether_addr(mgmt->da) && + is_multicast_ether_addr(mgmt->bssid) && +- hapd->num_sta >= hapd->conf->max_num_sta && ++ hostapd_check_max_sta(hapd) && + !ap_get_sta(hapd, mgmt->sa)) { + wpa_printf(MSG_MSGDUMP, "%s: Ignore Probe Request from " MACSTR + " since no room for additional STA", +--- a/src/ap/ap_config.h ++++ b/src/ap/ap_config.h +@@ -976,6 +976,8 @@ struct hostapd_config { + unsigned int track_sta_max_num; + unsigned int track_sta_max_age; + ++ int max_num_sta; ++ + char country[3]; /* first two octets: country code as described in + * ISO/IEC 3166-1. Third octet: + * ' ' (ascii 32): all environments -- cgit v1.2.3