From: Felix Fietkau Date: Wed, 26 May 2021 14:34:46 +0200 Subject: [PATCH] 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 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -3041,6 +3041,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/ap_config.h +++ b/src/ap/ap_config.h @@ -1057,6 +1057,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 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -1567,7 +1567,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/hostapd.c +++ b/src/ap/hostapd.c @@ -247,6 +247,29 @@ static int hostapd_iface_conf_changed(st return 0; } +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) { --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -754,6 +754,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); void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap); void hostapd_cleanup_cca_params(struct hostapd_data *hapd);