diff --git a/hostapd/config_file.c b/hostapd/config_file.c index e29ae2fbb..12d627a8a 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2509,6 +2509,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, "wps_state", line); errors++; } + } else if (os_strcmp(buf, "wps_independent") == 0) { + bss->wps_independent = atoi(pos); } else if (os_strcmp(buf, "ap_setup_locked") == 0) { bss->ap_setup_locked = atoi(pos); } else if (os_strcmp(buf, "uuid") == 0) { diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index eca399604..17bb7ed78 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1124,6 +1124,14 @@ own_ip_addr=127.0.0.1 # 2 = WPS enabled, configured #wps_state=2 +# Whether to manage this interface independently from other WPS interfaces +# By default, a single hostapd process applies WPS operations to all configured +# interfaces. This parameter can be used to disable that behavior for a subset +# of interfaces. If this is set to non-zero for an interface, WPS commands +# issued on that interface do not apply to other interfaces and WPS operations +# performed on other interfaces do not affect this interface. +#wps_independent=0 + # AP can be configured into a locked state where new WPS Registrar are not # accepted, but previously authorized Registrars (including the internal one) # can continue to add new Enrollees. diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 6606f72d7..d9ef984df 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -340,6 +340,7 @@ struct hostapd_bss_config { int wps_state; #ifdef CONFIG_WPS + int wps_independent; int ap_setup_locked; u8 uuid[16]; char *wps_pin_requests; diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c index b6d9c20bc..69b34fef3 100644 --- a/src/ap/wps_hostapd.c +++ b/src/ap/wps_hostapd.c @@ -45,6 +45,7 @@ static void hostapd_wps_ap_pin_timeout(void *eloop_data, void *user_ctx); struct wps_for_each_data { int (*func)(struct hostapd_data *h, void *ctx); void *ctx; + struct hostapd_data *calling_hapd; }; @@ -57,7 +58,14 @@ static int wps_for_each(struct hostapd_iface *iface, void *ctx) return 0; for (j = 0; j < iface->num_bss; j++) { struct hostapd_data *hapd = iface->bss[j]; - int ret = data->func(hapd, data->ctx); + int ret; + + if (hapd != data->calling_hapd && + (hapd->conf->wps_independent || + data->calling_hapd->conf->wps_independent)) + continue; + + ret = data->func(hapd, data->ctx); if (ret) return ret; } @@ -74,6 +82,7 @@ static int hostapd_wps_for_each(struct hostapd_data *hapd, struct wps_for_each_data data; data.func = func; data.ctx = ctx; + data.calling_hapd = hapd; if (iface->interfaces == NULL || iface->interfaces->for_each_interface == NULL) return wps_for_each(iface, &data); @@ -814,7 +823,8 @@ static int get_uuid_cb(struct hostapd_iface *iface, void *ctx) return 0; for (j = 0; j < iface->num_bss; j++) { struct hostapd_data *hapd = iface->bss[j]; - if (hapd->wps && !is_nil_uuid(hapd->wps->uuid)) { + if (hapd->wps && !hapd->conf->wps_independent && + !is_nil_uuid(hapd->wps->uuid)) { *uuid = hapd->wps->uuid; return 1; } @@ -907,7 +917,7 @@ int hostapd_init_wps(struct hostapd_data *hapd, if (is_nil_uuid(hapd->conf->uuid)) { const u8 *uuid; uuid = get_own_uuid(hapd->iface); - if (uuid) { + if (uuid && !conf->wps_independent) { os_memcpy(wps->uuid, uuid, UUID_LEN); wpa_hexdump(MSG_DEBUG, "WPS: Clone UUID from another " "interface", wps->uuid, UUID_LEN);