From: Hu Wang Date: Tue, 19 Aug 2025 06:43:40 +0000 (-0700) Subject: wpa_supplicant: Add option to disable 80+80 MHz opclass advertisement X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7bb930d50b5f8b1ab09a5b37ac4bc1f267792e1d;p=thirdparty%2Fhostap.git wpa_supplicant: Add option to disable 80+80 MHz opclass advertisement Introduce a new global configuration parameter, disable_op_classes_80_80_mhz, to wpa_supplicant. When set to 1, this option prevents the advertisement of 80+80 MHz channel capabilities in the Supported Operating Classes element sent in (Re)Association Request frames. This addresses a specific compatibility issue reported with certain legacy or less compliant Soft AP implementations (e.g., on Windows PCs) which may misinterpret or fail to process the specific octet sequence used for 80+80 MHz channel advertisements within this element. Signed-off-by: Hu Wang --- diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index aad4e7508..a0f71cfc6 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -5705,6 +5705,7 @@ static const struct global_parse_data global_fields[] = { { INT_RANGE(wfa_gen_capa, 0, 2), 0}, { BIN(wfa_gen_capa_supp), 0 }, { BIN(wfa_gen_capa_cert), 0 }, + { BOOL(disable_op_classes_80_80_mhz), 0 }, /* NOTE: When adding new parameters here, add_interface() in * wpa_supplicant/dbus_new_introspect.c may need to be modified to * increase the size of the iface->xml buffer. */ diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 83083b509..c187d36ed 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -1899,6 +1899,16 @@ struct wpa_config { * wfa_gen_capa_supp. */ struct wpabuf *wfa_gen_capa_cert; + + /** + * disable_op_classes_80_80_mhz - Disable advertisement of 80+80 MHz + * channel capabilities in the Supported Operating Classes element + * + * By default, %wpa_supplicant tries to advertise 80+80 MHz channel + * capabilities in the Supported Operating Classes element if the driver + * supports this. + */ + bool disable_op_classes_80_80_mhz; }; diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index e9a8fa470..b1ba03ac5 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -1753,6 +1753,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) fprintf(f, "wfa_gen_capa=%d\n", config->wfa_gen_capa); write_global_bin(f, "wfa_gen_capa_supp", config->wfa_gen_capa_supp); write_global_bin(f, "wfa_gen_capa_cert", config->wfa_gen_capa_cert); + if (config->disable_op_classes_80_80_mhz) + fprintf(f, "disable_op_classes_80_80_mhz=%d\n", + config->disable_op_classes_80_80_mhz); } static void wpa_config_write_identity(FILE *f, struct wpa_dev_ik *dev_ik) diff --git a/wpa_supplicant/op_classes.c b/wpa_supplicant/op_classes.c index ec66e8ccd..72ac3e91b 100644 --- a/wpa_supplicant/op_classes.c +++ b/wpa_supplicant/op_classes.c @@ -15,6 +15,7 @@ #include "common/ieee802_11_common.h" #include "wpa_supplicant_i.h" #include "bss.h" +#include "config.h" static enum chan_allowed allow_channel(struct hostapd_hw_modes *mode, @@ -530,6 +531,8 @@ size_t wpas_supp_op_class_ie(struct wpa_supplicant *wpa_s, u8 *ie_len; size_t res; bool op128 = false, op130 = false, op133 = false, op135 = false; + bool disable_op_classes_80_80_mhz = wpa_s->conf ? + wpa_s->conf->disable_op_classes_80_80_mhz : false; /* * Determine the current operating class correct mode based on @@ -586,7 +589,8 @@ size_t wpas_supp_op_class_ie(struct wpa_supplicant *wpa_s, } /* Add the 2-octet operating classes (i.e., 80+80 MHz cases), if any */ - if ((op128 && op130) || (op133 && op135)) { + if (!disable_op_classes_80_80_mhz && + ((op128 && op130) || (op133 && op135))) { /* Operating Class Duple Sequence field */ /* Zero Delimiter */ diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 300e118f3..e62b74d7b 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -2643,6 +2643,7 @@ do { \ d->go_venue_group = s->go_venue_group; d->go_venue_type = s->go_venue_type; d->p2p_add_cli_chan = s->p2p_add_cli_chan; + d->disable_op_classes_80_80_mhz = s->disable_op_classes_80_80_mhz; } diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index b13bf4992..03180a316 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -524,6 +524,7 @@ static char ** wpa_cli_complete_set(const char *str, int pos) #endif /* CONFIG_TESTING_OPTIONS */ "relative_rssi", "relative_band_adjust", "extended_key_id", + "disable_op_classes_80_80_mhz", }; int i, num_fields = ARRAY_SIZE(fields); @@ -624,7 +625,8 @@ static char ** wpa_cli_complete_get(const char *str, int pos) "tdls_external_control", "wowlan_triggers", "p2p_search_delay", "mac_addr", "rand_addr_lifetime", "preassoc_mac_addr", "key_mgmt_offload", "passive_scan", - "reassoc_same_bss_optim", "extended_key_id" + "reassoc_same_bss_optim", "extended_key_id", + "disable_op_classes_80_80_mhz" }; int i, num_fields = ARRAY_SIZE(fields);