reviewed-by: Marianna Carrera <mcarrera@xxxxxxxxxxxxx> > From: Igor Mitsyanko <igor.mitsyanko.os@xxxxxxxxxxxxx> > Sent: Tuesday, October 2, 2018 6:34 PM > To: hostap@xxxxxxxxxxxxxxxxxxx > Cc: Marianna Carrera; Davina (Ying) Lu; arnout@xxxxxxx; wouter@xxxxxxxxx; Igor Mitsyanko OS > Subject: [PATCH] easymesh: add backhaul BSS support for WPS M8 > > > From: Ying Lu <ylu@xxxxxxxxxxxxx> > > This patch adds a feature similar to the existing “Additional > Credential attribute(s)” (extra_cred), relating to the requirements of > Wi-Fi Alliance Multi-AP Specification v1.0 (WFA EasyMesh). These specs > can be found at https://www.wi-fi.org/file/multi-ap-specification-v10. > > They mandate that a “fronthaul” BSS, that is pairing a client that has > bit 7 of the Multi-AP Extension subelement in the Wi-Fi Alliance Vendor > Extension attribute in the WSC M1 message, shall configure such client > with credentials pertaining to the “backhaul” BSS. Therefore we introduce > two new configuration options (wps_cred_processing_easymesh and > easymesh_backhaul_ap_settings) that behave like the existing extra_cred, > except for the additional check on the content of M1. > > Configuring these options will be done by a “MultiAP Agent”, an open-source > implementation of such agent is work in progress at > https://github.com/prplfoundation/prplMesh. > > Signed-off-by: Davina Lu <ylu@xxxxxxxxxxxxx> > Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@xxxxxxxxxxxxx> > --- > hostapd/config_file.c | 12 ++++++++++++ > hostapd/hostapd.conf | 11 +++++++++++ > src/ap/ap_config.c | 1 + > src/ap/ap_config.h | 3 +++ > src/wps/wps.h | 36 ++++++++++++++++++++++++++++++++++++ > src/wps/wps_attr_parse.c | 10 ++++++++++ > src/wps/wps_attr_parse.h | 1 + > src/wps/wps_defs.h | 9 ++++++++- > src/wps/wps_dev_attr.c | 5 +++++ > src/wps/wps_dev_attr.h | 1 + > src/wps/wps_registrar.c | 17 +++++++++++++++++ > 11 files changed, 105 insertions(+), 1 deletion(-) > > diff --git a/hostapd/config_file.c b/hostapd/config_file.c > index b1ab13e..581c634 100644 > --- a/hostapd/config_file.c > +++ b/hostapd/config_file.c > @@ -3457,6 +3457,18 @@ static int hostapd_config_fill(struct hostapd_config *conf, > line, pos); > return 1; > } > + } else if (os_strcmp(buf, "easymesh_backhaul_ap_settings") == 0) { > + os_free(bss->easymesh_backhaul_ap_settings); > + bss->easymesh_backhaul_ap_settings = > + (u8 *) os_readfile(pos, &bss->easymesh_backhaul_ap_settings_len); > + if (bss->easymesh_backhaul_ap_settings == NULL) { > + wpa_printf(MSG_ERROR, > + "Line %d: couldn't read EASYMESH backhaul AP Settings from '%s'", > + line, pos); > + return 1; > + } > + } else if (os_strcmp(buf, "wps_cred_processing_easymesh") == 0) { > + bss->wps_cred_processing_easymesh = atoi(pos); > } else if (os_strcmp(buf, "upnp_iface") == 0) { > os_free(bss->upnp_iface); > bss->upnp_iface = os_strdup(pos); > diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf > index 70f9713..c7946e6 100644 > --- a/hostapd/hostapd.conf > +++ b/hostapd/hostapd.conf > @@ -1845,6 +1845,17 @@ own_ip_addr=127.0.0.1 > # attribute. > #ap_settings=hostapd.ap_settings > > +# Easy mesh AP config > +# when set to 1, hostapd uses the credentials in the file specified by > +# easymesh_backhaul_ap_settings config, only for those STAs that advertise > +# "backhaul STA" in M1's EASYMESH Extension subelement. > +#wps_cred_processing_easymesh=0 > + > +# Easy mesh AP backhaul BSS config > +# Used when wps_cred_processing_easymesh is set. Contains "backhaul BSS" > +# credentials. > +#easymesh_backhaul_ap_settings=hostapd.easymesh_settings > + > # WPS UPnP interface > # If set, support for external Registrars is enabled. > #upnp_iface=br0 > diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c > index 820cba9..197f229 100644 > --- a/src/ap/ap_config.c > +++ b/src/ap/ap_config.c > @@ -582,6 +582,7 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf) > os_free(conf->ap_pin); > os_free(conf->extra_cred); > os_free(conf->ap_settings); > + os_free(conf->easymesh_backhaul_ap_settings); > os_free(conf->upnp_iface); > os_free(conf->friendly_name); > os_free(conf->manufacturer_url); > diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h > index 5b71126..c7b903d 100644 > --- a/src/ap/ap_config.h > +++ b/src/ap/ap_config.h > @@ -455,6 +455,9 @@ struct hostapd_bss_config { > int force_per_enrollee_psk; > u8 *ap_settings; > size_t ap_settings_len; > + u8 *easymesh_backhaul_ap_settings; > + size_t easymesh_backhaul_ap_settings_len; > + int wps_cred_processing_easymesh; > char *upnp_iface; > char *friendly_name; > char *manufacturer_url; > diff --git a/src/wps/wps.h b/src/wps/wps.h > index 2505d2d..2a685b2 100644 > --- a/src/wps/wps.h > +++ b/src/wps/wps.h > @@ -100,6 +100,7 @@ struct wps_device_data { > struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS]; > > int p2p; > + u8 easymesh_ext; > }; > > /** > @@ -395,6 +396,16 @@ struct wps_registrar_config { > * PSK is set for a network. > */ > int force_per_enrollee_psk; > + > + /** > + * wps_cred_processing_easymesh: build credential with backhaul BSS > + * > + * This option can be used to disable internal code that builds > + * Credential attribute into M8 based on the current network > + * configuration and Enrollee capabilities. The extra_cred data will > + * then be used as the Credential(s). > + */ > + int wps_cred_processing_easymesh; > }; > > > @@ -799,6 +810,31 @@ struct wps_context { > struct wpabuf *ap_nfc_dh_pubkey; > struct wpabuf *ap_nfc_dh_privkey; > struct wpabuf *ap_nfc_dev_pw; > + > + /** > + * wps_cred_processing_easymesh: build credential with backhaul BSS > + * > + * This option can be used to disable internal code that builds > + * Credential attribute into M8 based on the current network > + * configuration and Enrollee capabilities. The extra_cred data will > + * then be used as the Credential(s). > + */ > + int wps_cred_processing_easymesh; > + > + /** > + * easymesh_backhaul_ap_settings: EASY mesh backhaul BSS config > + * > + * This optional data (set to NULL to disable) can be used to add > + * Credential attribute(s) for other networks into M8. If > + * wps_cred_processing_easymesh is set, this will also override the automatically > + * generated Credential attribute. > + */ > + const u8 *easymesh_backhaul_ap_settings; > + > + /** > + * easymesh_backhaul_ap_settings_len: Length of easymesh_backhaul_ap_settings in octets > + */ > + size_t easymesh_backhaul_ap_settings_len; > }; > > struct wps_registrar * > diff --git a/src/wps/wps_attr_parse.c b/src/wps/wps_attr_parse.c > index 756d57e..4cb7db6 100644 > --- a/src/wps/wps_attr_parse.c > +++ b/src/wps/wps_attr_parse.c > @@ -67,6 +67,16 @@ static int wps_set_vendor_ext_wfa_subelem(struct wps_parse_attr *attr, > } > attr->registrar_configuration_methods = pos; > break; > + case WFA_ELEM_EASYMESH_EXTENSION: > + if (len != 1) { > + wpa_printf(MSG_DEBUG, "WPS: Invalid EASYMESH Extension length " > + "%u", len); > + return -1; > + } > + attr->easymesh_ext = *pos; > + wpa_printf(MSG_DEBUG, "WPS: EASYMESH Extension " > + "%x", attr->easymesh_ext); > + break; > default: > wpa_printf(MSG_MSGDUMP, "WPS: Skipped unknown WFA Vendor " > "Extension subelement %u", id); > diff --git a/src/wps/wps_attr_parse.h b/src/wps/wps_attr_parse.h > index 8188fe9..a47fd62 100644 > --- a/src/wps/wps_attr_parse.h > +++ b/src/wps/wps_attr_parse.h > @@ -97,6 +97,7 @@ 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 easymesh_ext; > }; > > int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr); > diff --git a/src/wps/wps_defs.h b/src/wps/wps_defs.h > index 301864d..ef76571 100644 > --- a/src/wps/wps_defs.h > +++ b/src/wps/wps_defs.h > @@ -152,9 +152,16 @@ enum { > WFA_ELEM_NETWORK_KEY_SHAREABLE = 0x02, > WFA_ELEM_REQUEST_TO_ENROLL = 0x03, > WFA_ELEM_SETTINGS_DELAY_TIME = 0x04, > - WFA_ELEM_REGISTRAR_CONFIGURATION_METHODS = 0x05 > + WFA_ELEM_REGISTRAR_CONFIGURATION_METHODS = 0x05, > + WFA_ELEM_EASYMESH_EXTENSION = 0x06 > }; > > +/* Multi-AP extension subelement value */ > +#define EASYMESH_TEAR_DOWN 0x10 > +#define EASYMESH_FRONTHAUL_BSS 0x20 > +#define EASYMESH_BACKHAUL_BSS 0x40 > +#define EASYMESH_BACKHAUL_STA 0x80 > + > /* Device Password ID */ > enum wps_dev_password_id { > DEV_PW_DEFAULT = 0x0000, > diff --git a/src/wps/wps_dev_attr.c b/src/wps/wps_dev_attr.c > index 0d01211..ccea68d 100644 > --- a/src/wps/wps_dev_attr.c > +++ b/src/wps/wps_dev_attr.c > @@ -389,6 +389,11 @@ int wps_process_os_version(struct wps_device_data *dev, const u8 *ver) > return 0; > } > > +void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext) > +{ > + dev->easymesh_ext = ext; > + wpa_printf(MSG_DEBUG, "WPS: EASYMESH extension value %02x", dev->easymesh_ext); > +} > > int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands) > { > diff --git a/src/wps/wps_dev_attr.h b/src/wps/wps_dev_attr.h > index c9034ad..a4b4173 100644 > --- a/src/wps/wps_dev_attr.h > +++ b/src/wps/wps_dev_attr.h > @@ -29,6 +29,7 @@ int wps_build_dev_name(struct wps_device_data *dev, struct wpabuf *msg); > int wps_process_device_attrs(struct wps_device_data *dev, > struct wps_parse_attr *attr); > int wps_process_os_version(struct wps_device_data *dev, const u8 *ver); > +void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext); > int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands); > void wps_device_data_free(struct wps_device_data *dev); > int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg); > diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c > index 379925e..93e4b8a 100644 > --- a/src/wps/wps_registrar.c > +++ b/src/wps/wps_registrar.c > @@ -188,6 +188,7 @@ struct wps_registrar { > #ifdef WPS_WORKAROUNDS > struct os_reltime pbc_ignore_start; > #endif /* WPS_WORKAROUNDS */ > + int wps_cred_processing_easymesh; > }; > > > @@ -666,6 +667,7 @@ wps_registrar_init(struct wps_context *wps, > reg->static_wep_only = cfg->static_wep_only; > reg->dualband = cfg->dualband; > reg->force_per_enrollee_psk = cfg->force_per_enrollee_psk; > + reg->wps_cred_processing_easymesh = cfg->wps_cred_processing_easymesh; > > if (wps_set_ie(reg)) { > wps_registrar_deinit(reg); > @@ -1588,6 +1590,15 @@ int wps_build_credential_wrap(struct wpabuf *msg, > return 0; > } > > +static int wps_build_easymesh_backhual_ap_settings(struct wps_data *wps, struct wpabuf *msg) > +{ > + wpabuf_put_data(msg, wps->wps->easymesh_backhaul_ap_settings, > + wps->wps->easymesh_backhaul_ap_settings_len); > + wpa_printf(MSG_DEBUG, "WPS: EASYMESH mesh backhaul BSS config len %lu=%lu\n", > + wpabuf_len(msg), > + wps->wps->easymesh_backhaul_ap_settings_len); > + return 0; > +} > > int wps_build_cred(struct wps_data *wps, struct wpabuf *msg) > { > @@ -1596,6 +1607,11 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg) > if (wps->wps->registrar->skip_cred_build) > goto skip_cred_build; > > + if (wps->wps->registrar->wps_cred_processing_easymesh && > + wps->peer_dev.easymesh_ext == EASYMESH_BACKHAUL_STA && > + wps->wps->easymesh_backhaul_ap_settings) > + return wps_build_easymesh_backhual_ap_settings(wps, msg); > + > wpa_printf(MSG_DEBUG, "WPS: * Credential"); > if (wps->use_cred) { > os_memcpy(&wps->cred, wps->use_cred, sizeof(wps->cred)); > @@ -2705,6 +2721,7 @@ static enum wps_process_res wps_process_m1(struct wps_data *wps, > wps->use_psk_key = 1; > } > #endif /* WPS_WORKAROUNDS */ > + wps_process_vendor_ext_m1(&wps->peer_dev, attr->easymesh_ext); > > wps->state = SEND_M2; > return WPS_CONTINUE; > -- > 2.9.5 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap