@@ -4551,6 +4551,26 @@ static int hostapd_config_fill(struct hostapd_config *conf,
}
bss->multi_ap = val;
+ } else if (os_strcmp(buf, "multi_ap_profile") == 0) {
+ int val = atoi(pos);
+
+ if (val < 1 || val > 2) {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid multi_ap_profile '%s'",
+ line, buf);
+ return -1;
+ }
+
+ bss->multi_ap_profile = val;
+ } else if (os_strcmp(buf, "multi_ap_primary_vlan_id") == 0) {
+ int val = atoi(pos);
+
+ if (val < 0 || val > MAX_VLAN_ID) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid multi_ap_primary_vlan_id %d (expected 0..%d)",
+ line, val, MAX_VLAN_ID);
+ return 1;
+ }
+ bss->multi_ap_primary_vlan_id = val;
} else if (os_strcmp(buf, "rssi_reject_assoc_rssi") == 0) {
conf->rssi_reject_assoc_rssi = atoi(pos);
} else if (os_strcmp(buf, "rssi_reject_assoc_timeout") == 0) {
@@ -774,6 +774,8 @@ struct hostapd_bss_config {
#define BACKHAUL_BSS 1
#define FRONTHAUL_BSS 2
int multi_ap; /* bitmap of BACKHAUL_BSS, FRONTHAUL_BSS */
+ int multi_ap_profile;
+ int multi_ap_primary_vlan_id;
#ifdef CONFIG_AIRTIME_POLICY
unsigned int airtime_weight;
@@ -1290,6 +1290,10 @@ int hostapd_init_wps(struct hostapd_data *hapd,
cfg.multi_ap_backhaul_network_key_len = 2 * PMK_LEN;
}
}
+ if (conf->multi_ap) {
+ cfg.multi_ap_profile = conf->multi_ap_profile;
+ cfg.multi_ap_primary_vlan_id = conf->multi_ap_primary_vlan_id;
+ }
wps->ap_settings = conf->ap_settings;
wps->ap_settings_len = conf->ap_settings_len;
@@ -1418,7 +1422,9 @@ static int hostapd_wps_update_multi_ap(struct hostapd_data *hapd,
reg, conf->multi_ap_backhaul_ssid.ssid,
conf->multi_ap_backhaul_ssid.ssid_len,
multi_ap_backhaul_network_key,
- multi_ap_backhaul_network_key_len);
+ multi_ap_backhaul_network_key_len,
+ conf->multi_ap_profile,
+ conf->multi_ap_primary_vlan_id);
os_free(multi_ap_backhaul_network_key);
return ret;
@@ -437,6 +437,18 @@ struct wps_registrar_config {
* multi_ap_backhaul_network_key in octets
*/
size_t multi_ap_backhaul_network_key_len;
+
+ /**
+ * multi_ap_prorifle - This is parameter for
+ * Multi-AP Profile subelement
+ */
+ int multi_ap_profile;
+
+ /**
+ * multi_ap_primary_vlan_id - This is parameter for
+ * Default 8021Q Settings Subelement
+ */
+ int multi_ap_primary_vlan_id;
};
@@ -881,7 +893,9 @@ int wps_registrar_update_multi_ap(struct wps_registrar *reg,
const u8 *multi_ap_backhaul_ssid,
size_t multi_ap_backhaul_ssid_len,
const u8 *multi_ap_backhaul_network_key,
- size_t multi_ap_backhaul_network_key_len);
+ size_t multi_ap_backhaul_network_key_len,
+ u8 multi_ap_profile,
+ u16 multi_ap_primary_vlan_id);
int wps_build_credential_wrap(struct wpabuf *msg,
const struct wps_credential *cred);
@@ -248,6 +248,48 @@ int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
MAC2STR(&auth_macs[i * ETH_ALEN]));
}
+ WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2);
+
+#ifdef CONFIG_WPS_TESTING
+ if (WPS_VERSION > 0x20) {
+ if (wpabuf_tailroom(msg) < 5)
+ return -1;
+ wpa_printf(MSG_DEBUG, "WPS: * Extensibility Testing - extra "
+ "attribute");
+ wpabuf_put_be16(msg, ATTR_EXTENSIBILITY_TEST);
+ wpabuf_put_be16(msg, 1);
+ wpabuf_put_u8(msg, 42);
+ }
+#endif /* CONFIG_WPS_TESTING */
+ return 0;
+}
+
+
+int wps_build_wfa_ext_multi_ap(struct wpabuf *msg, u8 multi_ap_subelem,
+ u8 profile, u16 vlan_id)
+{
+ u8 *len;
+
+#ifdef CONFIG_WPS_TESTING
+ if (WPS_VERSION == 0x10)
+ return 0;
+#endif /* CONFIG_WPS_TESTING */
+
+ if (wpabuf_tailroom(msg) <
+ 7 + 3 +
+ (multi_ap_subelem ? 3 : 0) +
+ (profile ? 7 : 0))
+ return -1;
+
+ wpabuf_put_be16(msg, ATTR_VENDOR_EXT);
+ len = wpabuf_put(msg, 2); /* to be filled */
+ wpabuf_put_be24(msg, WPS_VENDOR_ID_WFA);
+
+ wpa_printf(MSG_INFO, "WPS: * Version2 (0x%x)", WPS_VERSION);
+ wpabuf_put_u8(msg, WFA_ELEM_VERSION2);
+ wpabuf_put_u8(msg, 1);
+ wpabuf_put_u8(msg, WPS_VERSION);
+
if (multi_ap_subelem) {
wpa_printf(MSG_DEBUG, "WPS: * Multi-AP (0x%x)",
multi_ap_subelem);
@@ -256,6 +298,21 @@ int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
wpabuf_put_u8(msg, multi_ap_subelem);
}
+ if (profile) {
+ wpa_printf(MSG_DEBUG, "WPS: * Multi-AP profile (%d)", profile);
+ wpabuf_put_u8(msg, WFA_ELEM_MULTI_AP_PROFILE);
+ wpabuf_put_u8(msg, 1); /* length */
+ wpabuf_put_u8(msg, profile);
+
+ if (vlan_id) {
+ wpa_printf(MSG_DEBUG, "WPS: * Multi-AP vlan_id (%d)",
+ vlan_id);
+ wpabuf_put_u8(msg, WFA_ELEM_MULTI_AP_8021Q);
+ wpabuf_put_u8(msg, 2); /* length */
+ wpabuf_put_le16(msg, vlan_id);
+ }
+ }
+
WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2);
#ifdef CONFIG_WPS_TESTING
@@ -78,6 +78,28 @@ static int wps_set_vendor_ext_wfa_subelem(struct wps_parse_attr *attr,
wpa_printf(MSG_DEBUG, "WPS: Multi-AP Extension 0x%02x",
attr->multi_ap_ext);
break;
+ case WFA_ELEM_MULTI_AP_PROFILE:
+ if (len != 1) {
+ wpa_printf(MSG_DEBUG,
+ "WPS: Invalid Multi-AP Profile length %u",
+ len);
+ return -1;
+ }
+ attr->multi_ap_profile = *pos;
+ wpa_printf(MSG_DEBUG, "WPS: Multi-AP Profile %u",
+ attr->multi_ap_profile);
+ break;
+ case WFA_ELEM_MULTI_AP_8021Q:
+ if (len != 2) {
+ wpa_printf(MSG_DEBUG,
+ "WPS: Invalid Multi-AP Default 8021Q Settings length %u",
+ len);
+ return -1;
+ }
+ attr->multi_ap_primary_vlan_id = WPA_GET_LE16(pos);
+ wpa_printf(MSG_DEBUG, "WPS: Multi-AP vlan_id %u",
+ attr->multi_ap_primary_vlan_id);
+ break;
default:
wpa_printf(MSG_MSGDUMP, "WPS: Skipped unknown WFA Vendor "
"Extension subelement %u", id);
@@ -97,7 +97,10 @@ struct wps_parse_attr {
const u8 *cred[MAX_CRED_COUNT];
const u8 *req_dev_type[MAX_REQ_DEV_TYPE_COUNT];
const u8 *vendor_ext[MAX_WPS_PARSE_VENDOR_EXT];
+
u8 multi_ap_ext;
+ u8 multi_ap_profile;
+ u16 multi_ap_primary_vlan_id;
};
int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);
@@ -153,7 +153,9 @@ enum {
WFA_ELEM_REQUEST_TO_ENROLL = 0x03,
WFA_ELEM_SETTINGS_DELAY_TIME = 0x04,
WFA_ELEM_REGISTRAR_CONFIGURATION_METHODS = 0x05,
- WFA_ELEM_MULTI_AP = 0x06
+ WFA_ELEM_MULTI_AP = 0x06,
+ WFA_ELEM_MULTI_AP_PROFILE = 0x07,
+ WFA_ELEM_MULTI_AP_8021Q = 0x08
};
/* Device Password ID */
@@ -156,7 +156,9 @@ static struct wpabuf * wps_build_m1(struct wps_data *wps)
wps_build_dev_password_id(msg, wps->dev_pw_id) ||
wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
wps_build_os_version(&wps->wps->dev, msg) ||
- wps_build_wfa_ext(msg, 0, NULL, 0, multi_ap_backhaul_sta) ||
+ (multi_ap_backhaul_sta ?
+ wps_build_wfa_ext_multi_ap(msg, multi_ap_backhaul_sta, 0, 0) :
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) ||
wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
wpabuf_free(msg);
return NULL;
@@ -167,6 +167,8 @@ int wps_build_version(struct wpabuf *msg);
int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
const u8 *auth_macs, size_t auth_macs_count,
u8 multi_ap_subelem);
+int wps_build_wfa_ext_multi_ap(struct wpabuf *msg, u8 multi_ap_subelem,
+ u8 profile, u16 vlan_id);
int wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type);
int wps_build_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg);
int wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg);
@@ -220,6 +220,18 @@ struct wps_registrar {
* multi_ap_backhaul_network_key in octets
*/
size_t multi_ap_backhaul_network_key_len;
+
+ /**
+ * multi_ap_primary - This is parameter for
+ * Multi-AP Profile subelement
+ */
+ int multi_ap_profile;
+
+ /**
+ * multi_ap_primary_vlan_id - This is parameter for
+ * Default 8021Q Settings Subelement
+ */
+ int multi_ap_primary_vlan_id;
};
@@ -714,6 +726,8 @@ wps_registrar_init(struct wps_context *wps,
reg->multi_ap_backhaul_network_key_len =
cfg->multi_ap_backhaul_network_key_len;
}
+ reg->multi_ap_profile = cfg->multi_ap_profile;
+ reg->multi_ap_primary_vlan_id = cfg->multi_ap_primary_vlan_id;
if (wps_set_ie(reg)) {
wps_registrar_deinit(reg);
@@ -2064,7 +2078,11 @@ static struct wpabuf * wps_build_m6(struct wps_data *wps)
static struct wpabuf * wps_build_m8(struct wps_data *wps)
{
+ struct wps_registrar *reg = wps->wps->registrar;
struct wpabuf *msg, *plain;
+ u8 multi_ap_ext = 0;
+ u8 profile = 0;
+ u16 vlan_id = 0;
wpa_printf(MSG_DEBUG, "WPS: Building Message M8");
@@ -2078,6 +2096,14 @@ static struct wpabuf * wps_build_m8(struct wps_data *wps)
return NULL;
}
+
+ if (wps->peer_dev.multi_ap_ext == MULTI_AP_BACKHAUL_STA) {
+ multi_ap_ext = MULTI_AP_BACKHAUL_BSS |
+ MULTI_AP_FRONTHAUL_BSS;
+ profile = reg->multi_ap_profile;
+ vlan_id = reg->multi_ap_primary_vlan_id;
+ }
+
if (wps_build_version(msg) ||
wps_build_msg_type(msg, WPS_M8) ||
wps_build_enrollee_nonce(wps, msg) ||
@@ -2085,7 +2111,9 @@ static struct wpabuf * wps_build_m8(struct wps_data *wps)
(!wps->wps->ap && !wps->er && wps_build_ap_settings(wps, plain)) ||
wps_build_key_wrap_auth(wps, plain) ||
wps_build_encr_settings(wps, msg, plain) ||
- wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
+ (multi_ap_ext ?
+ wps_build_wfa_ext_multi_ap(msg, multi_ap_ext, profile, vlan_id) :
+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) ||
wps_build_authenticator(wps, msg)) {
wpabuf_clear_free(plain);
wpabuf_clear_free(msg);
@@ -3663,7 +3691,9 @@ int wps_registrar_update_multi_ap(struct wps_registrar *reg,
const u8 *multi_ap_backhaul_ssid,
size_t multi_ap_backhaul_ssid_len,
const u8 *multi_ap_backhaul_network_key,
- size_t multi_ap_backhaul_network_key_len)
+ size_t multi_ap_backhaul_network_key_len,
+ u8 multi_ap_profile,
+ u16 multi_ap_primary_vlan_id)
{
if (multi_ap_backhaul_ssid) {
os_memcpy(reg->multi_ap_backhaul_ssid,
@@ -3683,6 +3713,8 @@ int wps_registrar_update_multi_ap(struct wps_registrar *reg,
reg->multi_ap_backhaul_network_key_len =
multi_ap_backhaul_network_key_len;
}
+ reg->multi_ap_profile = multi_ap_profile;
+ reg->multi_ap_primary_vlan_id = multi_ap_primary_vlan_id;
return 0;
}
Patch adds hostapd config option to allow to configure Multi-AP profile and primary vlan_id. It then use those values to send Multi-AP Profile and Multi-AP Default 802.1Q subelements via WPS WFA Vendor Extensions. This is can be used Multi-AP onbaording with Traffic Separation feature. Some important parts are missed i.e. passing values from supplicant and needs to be added. We infernally use ubus event when get WPS credentials and pass vlan_id value there. It's needed further to allow authentication be done via vlan when Traffic Separation feature is enababled. Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl> --- hostapd/config_file.c | 20 ++++++++++++++ src/ap/ap_config.h | 2 ++ src/ap/wps_hostapd.c | 8 +++++- src/wps/wps.h | 16 ++++++++++- src/wps/wps_attr_build.c | 57 ++++++++++++++++++++++++++++++++++++++++ src/wps/wps_attr_parse.c | 22 ++++++++++++++++ src/wps/wps_attr_parse.h | 3 +++ src/wps/wps_defs.h | 4 ++- src/wps/wps_enrollee.c | 4 ++- src/wps/wps_i.h | 2 ++ src/wps/wps_registrar.c | 36 +++++++++++++++++++++++-- 11 files changed, 168 insertions(+), 6 deletions(-)