diff --git a/recipes-connectivity/hostapd/files/0001-Add-build-artifact-build_features.h-to-gitignore.patch b/recipes-connectivity/hostapd/files/0001-Add-build-artifact-build_features.h-to-gitignore.patch new file mode 100644 index 0000000..100bb9f --- /dev/null +++ b/recipes-connectivity/hostapd/files/0001-Add-build-artifact-build_features.h-to-gitignore.patch @@ -0,0 +1,18 @@ +From 1410d96b1ffefbf4ba3dfb3d432db7c9558a8386 Mon Sep 17 00:00:00 2001 +From: Moritz Rosenthal +Date: Sat, 29 Feb 2020 21:13:42 +0100 +Subject: [PATCH] Add build artifact build_features.h to gitignore + +--- + .gitignore | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.gitignore b/.gitignore +index 6a985a75d..dd6bf9291 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -33,3 +33,4 @@ wlantest/test_vectors + wlantest/wlantest + wlantest/wlantest_cli + **/parallel-vm.log ++src/utils/build_features.h diff --git a/recipes-connectivity/hostapd/files/0002-Use-environment-variable-EXTRA_CFLAGS.patch b/recipes-connectivity/hostapd/files/0002-Use-environment-variable-EXTRA_CFLAGS.patch new file mode 100644 index 0000000..f97c4f0 --- /dev/null +++ b/recipes-connectivity/hostapd/files/0002-Use-environment-variable-EXTRA_CFLAGS.patch @@ -0,0 +1,22 @@ +From 919318e4abd51df15dd4d5769ed2d0ad6981e87b Mon Sep 17 00:00:00 2001 +From: Moritz Rosenthal +Date: Sat, 29 Feb 2020 21:17:05 +0100 +Subject: [PATCH] Use environment variable EXTRA_CFLAGS + +--- + src/lib.rules | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lib.rules b/src/lib.rules +index a46315442..3eb721a6d 100644 +--- a/src/lib.rules ++++ b/src/lib.rules +@@ -3,7 +3,7 @@ CC=gcc + endif + + ifndef CFLAGS +-CFLAGS = -MMD -O2 -Wall -g ++CFLAGS = -MMD -O2 -Wall -g $(EXTRA_CFLAGS) + endif + + ifdef TEST_FUZZ diff --git a/recipes-connectivity/hostapd/files/004-mesh-use-setup-completion-callback-to-complete-mesh-.patch b/recipes-connectivity/hostapd/files/004-mesh-use-setup-completion-callback-to-complete-mesh-.patch new file mode 100644 index 0000000..b630f40 --- /dev/null +++ b/recipes-connectivity/hostapd/files/004-mesh-use-setup-completion-callback-to-complete-mesh-.patch @@ -0,0 +1,129 @@ +From be22439f78de79cfbaa12c56f28d1f46bfe46eb3 Mon Sep 17 00:00:00 2001 +From: Peter Oh +Date: Mon, 27 Aug 2018 14:28:38 -0700 +Subject: [PATCH] mesh: use setup completion callback to complete mesh join + +mesh join function is the last function to be called during +mesh join process, but it's been called a bit earlier than +it's supposed to be, so that some mesh parameter values +such as VHT capabilities not applied correct when mesh join +is in process. +Moreover current design of mesh join that is called directly +after mesh initialization isn't suitable for DFS channels to use, +since mesh join process should be paused until DFS CAC is +done and resumed after it's done. +The callback will be called by hostapd_setup_interface_complete_sync. +There is possiblity that completing mesh init fails, so add error +handle codes. + +Signed-off-by: Peter Oh +Signed-off-by: Peter Oh + +--- + src/ap/hostapd.c | 11 ++++++++++- + wpa_supplicant/mesh.c | 13 +++++++------ + 2 files changed, 17 insertions(+), 7 deletions(-) + +diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c +index bf1975fbd..c85563353 100644 +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -423,6 +423,8 @@ static void hostapd_free_hapd_data(struct hostapd_data *hapd) + #ifdef CONFIG_MESH + wpabuf_free(hapd->mesh_pending_auth); + hapd->mesh_pending_auth = NULL; ++ /* handling setup failure is already done */ ++ hapd->setup_complete_cb = NULL; + #endif /* CONFIG_MESH */ + + hostapd_clean_rrm(hapd); +@@ -2049,6 +2051,13 @@ dfs_offload: + if (hapd->setup_complete_cb) + hapd->setup_complete_cb(hapd->setup_complete_cb_ctx); + ++#ifdef CONFIG_MESH ++ if (delay_apply_cfg && !iface->mconf) { ++ wpa_printf(MSG_ERROR, "Error while completing mesh init"); ++ goto fail; ++ } ++#endif /* CONFIG_MESH */ ++ + wpa_printf(MSG_DEBUG, "%s: Setup of interface done.", + iface->bss[0]->conf->iface); + if (iface->interfaces && iface->interfaces->terminate_on_error > 0) +@@ -2192,7 +2201,7 @@ int hostapd_setup_interface(struct hostapd_iface *iface) + ret = setup_interface(iface); + if (ret) { + wpa_printf(MSG_ERROR, "%s: Unable to setup interface.", +- iface->bss[0]->conf->iface); ++ iface->conf ? iface->conf->bss[0]->iface : "N/A"); + return -1; + } + +diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c +index 7354c1b79..4099cbe29 100644 +--- a/wpa_supplicant/mesh.c ++++ b/wpa_supplicant/mesh.c +@@ -190,8 +190,9 @@ static int wpas_mesh_init_rsn(struct wpa_supplicant *wpa_s) + } + + +-static int wpas_mesh_complete(struct wpa_supplicant *wpa_s) ++static void wpas_mesh_complete_cb(void *ctx) + { ++ struct wpa_supplicant *wpa_s = ctx; + struct hostapd_iface *ifmsh = wpa_s->ifmsh; + struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params; + struct wpa_ssid *ssid = wpa_s->current_ssid; +@@ -200,7 +201,7 @@ static int wpas_mesh_complete(struct wpa_supplicant *wpa_s) + if (!params || !ssid || !ifmsh) { + wpa_printf(MSG_ERROR, "mesh: %s called without active mesh", + __func__); +- return -1; ++ return; + } + + if (ifmsh->mconf->security != MESH_CONF_SEC_NONE && +@@ -209,7 +210,7 @@ static int wpas_mesh_complete(struct wpa_supplicant *wpa_s) + "mesh: RSN initialization failed - deinit mesh"); + wpa_supplicant_mesh_deinit(wpa_s); + wpa_drv_leave_mesh(wpa_s); +- return -1; ++ return; + } + + if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) { +@@ -235,8 +236,6 @@ static int wpas_mesh_complete(struct wpa_supplicant *wpa_s) + + if (!ret) + wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); +- +- return ret; + } + + +@@ -263,6 +262,7 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, + if (!ifmsh) + return -ENOMEM; + ++ ifmsh->owner = wpa_s; + ifmsh->drv_flags = wpa_s->drv_flags; + ifmsh->num_bss = 1; + ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss, +@@ -280,6 +280,8 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, + bss->drv_priv = wpa_s->drv_priv; + bss->iface = ifmsh; + bss->mesh_sta_free_cb = mesh_mpm_free_sta; ++ bss->setup_complete_cb = wpas_mesh_complete_cb; ++ bss->setup_complete_cb_ctx = wpa_s; + frequency = ssid->frequency; + if (frequency != freq->freq && + frequency == freq->freq + freq->sec_channel_offset * 20) { +@@ -521,7 +523,6 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, + goto out; + } + +- ret = wpas_mesh_complete(wpa_s); + out: + return ret; + } diff --git a/recipes-connectivity/hostapd/files/005-mesh-update-ssid-frequency-as-pri-sec-channel-switch.patch b/recipes-connectivity/hostapd/files/005-mesh-update-ssid-frequency-as-pri-sec-channel-switch.patch new file mode 100644 index 0000000..0e29f76 --- /dev/null +++ b/recipes-connectivity/hostapd/files/005-mesh-update-ssid-frequency-as-pri-sec-channel-switch.patch @@ -0,0 +1,29 @@ +From ca681f3655d80bd3cc3a2876847992bd6c6ddf35 Mon Sep 17 00:00:00 2001 +From: Peter Oh +Date: Mon, 27 Aug 2018 14:28:41 -0700 +Subject: [PATCH] mesh: update ssid->frequency as pri/sec channel switch + +ssid->frequency is one of variables used to gets channel +number from given frequency. Leave it as unchanged when +pri/sec channel switched will cause picking up wrong +channel number after applying secondary channel offset +for HT40 and leads failing interface bring-up. + +Signed-off-by: Peter Oh + +--- + wpa_supplicant/mesh.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c +index 4099cbe29..3cb2b2c38 100644 +--- a/wpa_supplicant/mesh.c ++++ b/wpa_supplicant/mesh.c +@@ -287,6 +287,7 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, + frequency == freq->freq + freq->sec_channel_offset * 20) { + wpa_printf(MSG_DEBUG, "mesh: pri/sec channels switched"); + frequency = freq->freq; ++ ssid->frequency = frequency; + } + wpa_s->assoc_freq = frequency; + wpa_s->current_ssid = ssid; diff --git a/recipes-connectivity/hostapd/files/006-mesh-inform-kernel-driver-DFS-handler-in-userspace.patch b/recipes-connectivity/hostapd/files/006-mesh-inform-kernel-driver-DFS-handler-in-userspace.patch new file mode 100644 index 0000000..cf5fbb7 --- /dev/null +++ b/recipes-connectivity/hostapd/files/006-mesh-inform-kernel-driver-DFS-handler-in-userspace.patch @@ -0,0 +1,55 @@ +From 8db674b0500f4e7daa2771fceac8fdff162ae0b6 Mon Sep 17 00:00:00 2001 +From: Peter Oh +Date: Mon, 27 Aug 2018 14:28:49 -0700 +Subject: [PATCH] mesh: inform kernel driver DFS handler in userspace + +NL80211_ATTR_HANDLE_DFS is required by kerenel space +to enable DFS channels that indicates DFS handler +resides in userspace. + +Signed-off-by: Peter Oh + +--- + src/drivers/driver.h | 1 + + src/drivers/driver_nl80211.c | 3 +++ + wpa_supplicant/mesh.c | 1 + + 3 files changed, 5 insertions(+) + +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index 2a8459ae3..3c92fb76c 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -1477,6 +1477,7 @@ struct wpa_driver_mesh_join_params { + #define WPA_DRIVER_MESH_FLAG_SAE_AUTH 0x00000004 + #define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008 + unsigned int flags; ++ u8 handle_dfs; + }; + + /** +diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c +index 0a356eefd..6764ba9df 100644 +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -9624,6 +9624,9 @@ static int nl80211_join_mesh(struct i802_bss *bss, + + wpa_printf(MSG_DEBUG, " * flags=%08X", params->flags); + ++ if (params->handle_dfs) ++ if (nla_put_flag(msg, NL80211_ATTR_HANDLE_DFS)) ++ goto fail; + container = nla_nest_start(msg, NL80211_ATTR_MESH_SETUP); + if (!container) + goto fail; +diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c +index 3cb2b2c38..36ff2df89 100644 +--- a/wpa_supplicant/mesh.c ++++ b/wpa_supplicant/mesh.c +@@ -309,6 +309,7 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, + conf->country[0] = wpa_s->conf->country[0]; + conf->country[1] = wpa_s->conf->country[1]; + conf->country[2] = ' '; ++ wpa_s->mesh_params->handle_dfs = 1; + } + + bss->iconf = conf; diff --git a/recipes-connectivity/hostapd/files/007-mesh-apply-channel-attributes-before-running-Mesh.patch b/recipes-connectivity/hostapd/files/007-mesh-apply-channel-attributes-before-running-Mesh.patch new file mode 100644 index 0000000..acebb3d --- /dev/null +++ b/recipes-connectivity/hostapd/files/007-mesh-apply-channel-attributes-before-running-Mesh.patch @@ -0,0 +1,50 @@ +From 912990afa5f72947d5e2cfc21e88e5288a1116d6 Mon Sep 17 00:00:00 2001 +From: Peter Oh +Date: Mon, 27 Aug 2018 14:28:40 -0700 +Subject: [PATCH] mesh: Apply channel attributes before setup interface + +This helps mesh interface initialization with correct channel +parameters. + +Signed-off-by: Peter Oh + +--- + wpa_supplicant/mesh.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c +index 36ff2df89..98b041380 100644 +--- a/wpa_supplicant/mesh.c ++++ b/wpa_supplicant/mesh.c +@@ -249,7 +249,7 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, + struct mesh_conf *mconf; + int basic_rates_erp[] = { 10, 20, 55, 60, 110, 120, 240, -1 }; + int rate_len; +- int frequency; ++ int frequency, saved_freq; + + if (!wpa_s->conf->user_mpm) { + /* not much for us to do here */ +@@ -386,6 +386,13 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, + conf->basic_rates[rate_len] = -1; + } + ++ /* Handle pri/sec switch frequency within AP configuration parameter ++ * generation without changing the stored network profile in the end. */ ++ saved_freq = ssid->frequency; ++ ssid->frequency = frequency; ++ wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf); ++ ssid->frequency = saved_freq; ++ + if (wpa_drv_init_mesh(wpa_s)) { + wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver"); + return -1; +@@ -397,8 +404,6 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, + return -1; + } + +- wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf); +- + return 0; + out_free: + wpa_supplicant_mesh_deinit(wpa_s); diff --git a/recipes-connectivity/hostapd/files/011-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch b/recipes-connectivity/hostapd/files/011-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch new file mode 100644 index 0000000..f6e72f0 --- /dev/null +++ b/recipes-connectivity/hostapd/files/011-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch @@ -0,0 +1,81 @@ +From 6d8777f93943b633580ce25b4ce46cab9f226e41 Mon Sep 17 00:00:00 2001 +From: Peter Oh +Date: Mon, 27 Aug 2018 14:28:45 -0700 +Subject: [PATCH] mesh: Allow DFS channels to be selected if dfs is enabled + +Note: DFS is assumed to be usable if a country code has been set + +Signed-off-by: Benjamin Berg +Signed-off-by: Peter Oh + +--- + wpa_supplicant/wpa_supplicant.c | 24 ++++++++++++++++++------ + 1 file changed, 18 insertions(+), 6 deletions(-) + +diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c +index 911d79d17..578f274a9 100644 +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -2153,6 +2153,8 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, + struct hostapd_freq_params vht_freq; + int chwidth, seg0, seg1; + u32 vht_caps = 0; ++ int dfs_enabled = wpa_s->conf->country[0] && ++ (wpa_s->drv_flags & WPA_DRIVER_FLAGS_RADAR); + + freq->freq = ssid->frequency; + +@@ -2232,8 +2234,11 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, + return; + + /* Check primary channel flags */ +- if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) ++ if (pri_chan->flag & HOSTAPD_CHAN_DISABLED) + return; ++ if (pri_chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR)) ++ if (!dfs_enabled) ++ return; + + freq->channel = pri_chan->chan; + +@@ -2264,8 +2269,11 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, + return; + + /* Check secondary channel flags */ +- if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) ++ if (sec_chan->flag & HOSTAPD_CHAN_DISABLED) + return; ++ if (sec_chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR)) ++ if (!dfs_enabled) ++ return; + + if (ht40 == -1) { + if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS)) +@@ -2356,8 +2364,11 @@ skip_ht40: + return; + + /* Back to HT configuration if channel not usable */ +- if (chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) ++ if (chan->flag & HOSTAPD_CHAN_DISABLED) + return; ++ if (chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR)) ++ if (!dfs_enabled) ++ return; + } + + chwidth = CHANWIDTH_80MHZ; +@@ -2377,10 +2388,11 @@ skip_ht40: + if (!chan) + continue; + +- if (chan->flag & (HOSTAPD_CHAN_DISABLED | +- HOSTAPD_CHAN_NO_IR | +- HOSTAPD_CHAN_RADAR)) ++ if (chan->flag & HOSTAPD_CHAN_DISABLED) + continue; ++ if (chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR)) ++ if (!dfs_enabled) ++ continue; + + /* Found a suitable second segment for 80+80 */ + chwidth = CHANWIDTH_80P80MHZ; diff --git a/recipes-connectivity/hostapd/files/013-mesh-do-not-allow-pri-sec-channel-switch.patch b/recipes-connectivity/hostapd/files/013-mesh-do-not-allow-pri-sec-channel-switch.patch new file mode 100644 index 0000000..04169ad --- /dev/null +++ b/recipes-connectivity/hostapd/files/013-mesh-do-not-allow-pri-sec-channel-switch.patch @@ -0,0 +1,32 @@ +From d9b002241024bcbfeb4d5adf413ff712bc0aa978 Mon Sep 17 00:00:00 2001 +From: Peter Oh +Date: Mon, 27 Aug 2018 14:28:48 -0700 +Subject: [PATCH] mesh: don't allow pri/sec channel switch + +This limitation isn't backed by standard, but it is known that +mesh doesn't have capability to handle 20/40 coex change in +current implementation and it will not able to establish +PLINK when channel switch between primary and secondary happens. + +Since it's unknown when we will have the implementation of handling +20/40 coex change for mesh, it'd better to avoid them from happening +until standard based implementation is introduced. + +Signed-off-by: Peter Oh + +--- + wpa_supplicant/mesh.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c +index 98b041380..f4b62a8fd 100644 +--- a/wpa_supplicant/mesh.c ++++ b/wpa_supplicant/mesh.c +@@ -386,6 +386,7 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, + conf->basic_rates[rate_len] = -1; + } + ++ conf->no_pri_sec_switch = 1; + /* Handle pri/sec switch frequency within AP configuration parameter + * generation without changing the stored network profile in the end. */ + saved_freq = ssid->frequency; diff --git a/recipes-connectivity/hostapd/files/015-mesh-do-not-use-offchan-mgmt-tx-on-DFS.patch b/recipes-connectivity/hostapd/files/015-mesh-do-not-use-offchan-mgmt-tx-on-DFS.patch new file mode 100644 index 0000000..2ac7040 --- /dev/null +++ b/recipes-connectivity/hostapd/files/015-mesh-do-not-use-offchan-mgmt-tx-on-DFS.patch @@ -0,0 +1,64 @@ +From 548e8ebd050dfc96c43315c0b5ed82225ea9ebf4 Mon Sep 17 00:00:00 2001 +From: Peter Oh +Date: Mon, 27 Aug 2018 14:28:46 -0700 +Subject: [PATCH] mesh: do not set offchanok on DFS channels in non-ETSI + +mac80211 does not allow mgmt tx to use off channel on +DFS channels in non-ETSI domain, because it will invalidate +CAC result on current operating channel. +(mac80211 commit: 34373d12f3cbb74960a73431138ef619d857996f) +Hence don't set offchanok for mgmt tx in case of DFS channels +in non-ETSI. + +Signed-off-by: Peter Oh + +--- + src/drivers/driver_nl80211.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c +index 6764ba9df..858cf599a 100644 +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -7462,6 +7462,10 @@ static int wpa_driver_nl80211_send_action(struct i802_bss *bss, + int ret = -1; + u8 *buf; + struct ieee80211_hdr *hdr; ++ struct hostapd_hw_modes *modes; ++ int i, offchanok = 1; ++ u16 num_modes, flags; ++ u8 dfs_domain; + + wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, " + "freq=%u MHz wait=%d ms no_cck=%d)", +@@ -7486,6 +7490,21 @@ static int wpa_driver_nl80211_send_action(struct i802_bss *bss, + os_memset(bss->rand_addr, 0, ETH_ALEN); + } + ++ if (is_mesh_interface(drv->nlmode)) { ++ modes = nl80211_get_hw_feature_data(bss, &num_modes, ++ &flags, &dfs_domain); ++ if (dfs_domain != HOSTAPD_DFS_REGION_ETSI && ++ ieee80211_is_dfs(bss->freq, modes, num_modes)) ++ offchanok = 0; ++ if (modes) { ++ for (i = 0; i < num_modes; i++) { ++ os_free(modes[i].channels); ++ os_free(modes[i].rates); ++ } ++ os_free(modes); ++ } ++ } ++ + if (is_ap_interface(drv->nlmode) && + (!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) || + (int) freq == bss->freq || drv->device_ap_sme || +@@ -7497,7 +7516,7 @@ static int wpa_driver_nl80211_send_action(struct i802_bss *bss, + ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf, + 24 + data_len, + &drv->send_action_cookie, +- no_cck, 0, 1, NULL, 0); ++ no_cck, 0, offchanok, NULL, 0); + + os_free(buf); + return ret; diff --git a/recipes-connectivity/hostapd/files/016-mesh-fix-channel-switch-error-during-CAC.patch b/recipes-connectivity/hostapd/files/016-mesh-fix-channel-switch-error-during-CAC.patch new file mode 100644 index 0000000..571f922 --- /dev/null +++ b/recipes-connectivity/hostapd/files/016-mesh-fix-channel-switch-error-during-CAC.patch @@ -0,0 +1,62 @@ +From f3a877c8961ba1e8955fa0323fdc209d630563db Mon Sep 17 00:00:00 2001 +From: Peter Oh +Date: Mon, 27 Aug 2018 14:28:47 -0700 +Subject: [PATCH] mesh: fix channel switch error during CAC + +Mesh interface has used its channel parameters that configured +during its initialization even after channel switched due to +DFS radar detection during CAC which caused channel switch error. +This change fixes the error by updating its channel parameters +when channel's been changed from initial one. + +Signed-off-by: Peter Oh + +--- + wpa_supplicant/mesh.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c +index f4b62a8fd..bfc7c7a39 100644 +--- a/wpa_supplicant/mesh.c ++++ b/wpa_supplicant/mesh.c +@@ -13,6 +13,7 @@ + #include "utils/uuid.h" + #include "common/ieee802_11_defs.h" + #include "common/wpa_ctrl.h" ++#include "common/hw_features_common.h" + #include "ap/sta_info.h" + #include "ap/hostapd.h" + #include "ap/ieee802_11.h" +@@ -204,6 +205,32 @@ static void wpas_mesh_complete_cb(void *ctx) + return; + } + ++ /* ++ * inspect if channel's been changed since initialized. ++ * i.e. DFS radar detection ++ */ ++ if (ifmsh->freq != params->freq.freq) { ++ wpa_s->assoc_freq = ifmsh->freq; ++ ssid->frequency = ifmsh->freq; ++ if (hostapd_set_freq_params(¶ms->freq, ++ ifmsh->conf->hw_mode, ++ ifmsh->freq, ++ ifmsh->conf->channel, ++ ifmsh->conf->ieee80211n, ++ ifmsh->conf->ieee80211ac, ++ ifmsh->conf->ieee80211ax, ++ ifmsh->conf->secondary_channel, ++ hostapd_get_oper_chwidth(ifmsh->conf), ++ hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf), ++ hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf), ++ ifmsh->current_mode->vht_capab, ++ &ifmsh->current_mode->he_capab[IEEE80211_MODE_AP])) { ++ wpa_printf(MSG_ERROR, "Error updating mesh frequency params."); ++ wpa_supplicant_mesh_deinit(wpa_s); ++ return; ++ } ++ } ++ + if (ifmsh->mconf->security != MESH_CONF_SEC_NONE && + wpas_mesh_init_rsn(wpa_s)) { + wpa_printf(MSG_ERROR, diff --git a/recipes-connectivity/hostapd/files/018-mesh-make-forwarding-configurable.patch b/recipes-connectivity/hostapd/files/018-mesh-make-forwarding-configurable.patch new file mode 100644 index 0000000..304572c --- /dev/null +++ b/recipes-connectivity/hostapd/files/018-mesh-make-forwarding-configurable.patch @@ -0,0 +1,240 @@ +From f3e8469b1fdbf953191a90100d8da18355caf7cb Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Wed, 18 Apr 2018 19:24:31 +0200 +Subject: [PATCH] mesh: make forwarding configurable + +Allow mesh_fwding to be specified in a mesh bss config, pass that +to the driver (only nl80211 implemented for now) and announce +forwarding capability accordingly. + +Signed-off-by: Daniel Golle + +--- + src/ap/ap_config.h | 2 ++ + src/drivers/driver.h | 2 ++ + src/drivers/driver_nl80211.c | 3 +++ + wpa_supplicant/config.c | 4 ++++ + wpa_supplicant/config.h | 9 +++++++++ + wpa_supplicant/config_file.c | 4 ++++ + wpa_supplicant/config_ssid.h | 5 +++++ + wpa_supplicant/mesh.c | 6 ++++++ + wpa_supplicant/mesh_mpm.c | 4 ++-- + wpa_supplicant/wpa_supplicant.conf | 3 +++ + 10 files changed, 40 insertions(+), 2 deletions(-) + +diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h +index ea581a822..cfe59d4b4 100644 +--- a/src/ap/ap_config.h ++++ b/src/ap/ap_config.h +@@ -51,6 +51,7 @@ struct mesh_conf { + int dot11MeshRetryTimeout; /* msec */ + int dot11MeshConfirmTimeout; /* msec */ + int dot11MeshHoldingTimeout; /* msec */ ++ int mesh_fwding; + }; + + #define MAX_STA_COUNT 2007 +@@ -666,6 +667,7 @@ struct hostapd_bss_config { + + #define MESH_ENABLED BIT(0) + int mesh; ++ int mesh_fwding; + + u8 radio_measurements[RRM_CAPABILITIES_IE_LEN]; + +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index 3c92fb76c..d73ff62c0 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -1450,6 +1450,7 @@ struct wpa_driver_mesh_bss_params { + #define WPA_DRIVER_MESH_CONF_FLAG_MAX_PEER_LINKS 0x00000004 + #define WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE 0x00000008 + #define WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD 0x00000010 ++#define WPA_DRIVER_MESH_CONF_FLAG_FORWARDING 0x00000020 + /* + * TODO: Other mesh configuration parameters would go here. + * See NL80211_MESHCONF_* for all the mesh config parameters. +@@ -1459,6 +1460,7 @@ struct wpa_driver_mesh_bss_params { + int peer_link_timeout; + int max_peer_links; + int rssi_threshold; ++ int forwarding; + u16 ht_opmode; + }; + +diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c +index 858cf599a..2930b01b4 100644 +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -9592,6 +9592,9 @@ static int nl80211_put_mesh_config(struct nl_msg *msg, + if (((params->flags & WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS) && + nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS, + params->auto_plinks)) || ++ ((params->flags & WPA_DRIVER_MESH_CONF_FLAG_FORWARDING) && ++ nla_put_u8(msg, NL80211_MESHCONF_FORWARDING, ++ params->forwarding)) || + ((params->flags & WPA_DRIVER_MESH_CONF_FLAG_MAX_PEER_LINKS) && + nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS, + params->max_peer_links)) || +diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c +index 7a62f96d6..07ed344e4 100644 +--- a/wpa_supplicant/config.c ++++ b/wpa_supplicant/config.c +@@ -2307,6 +2307,7 @@ static const struct parse_data ssid_fields[] = { + #ifdef CONFIG_MESH + { INT_RANGE(mode, 0, 5) }, + { INT_RANGE(no_auto_peer, 0, 1) }, ++ { INT_RANGE(mesh_fwding, 0, 1) }, + { INT_RANGE(mesh_rssi_threshold, -255, 1) }, + #else /* CONFIG_MESH */ + { INT_RANGE(mode, 0, 4) }, +@@ -2869,6 +2870,7 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid) + ssid->dot11MeshRetryTimeout = DEFAULT_MESH_RETRY_TIMEOUT; + ssid->dot11MeshConfirmTimeout = DEFAULT_MESH_CONFIRM_TIMEOUT; + ssid->dot11MeshHoldingTimeout = DEFAULT_MESH_HOLDING_TIMEOUT; ++ ssid->mesh_fwding = DEFAULT_MESH_FWDING; + ssid->mesh_rssi_threshold = DEFAULT_MESH_RSSI_THRESHOLD; + #endif /* CONFIG_MESH */ + #ifdef CONFIG_HT_OVERRIDES +@@ -4089,6 +4091,7 @@ struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface, + config->user_mpm = DEFAULT_USER_MPM; + config->max_peer_links = DEFAULT_MAX_PEER_LINKS; + config->mesh_max_inactivity = DEFAULT_MESH_MAX_INACTIVITY; ++ config->mesh_fwding = DEFAULT_MESH_FWDING; + config->dot11RSNASAERetransPeriod = + DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD; + config->fast_reauth = DEFAULT_FAST_REAUTH; +@@ -4726,6 +4729,7 @@ static const struct global_parse_data global_fields[] = { + { INT(user_mpm), 0 }, + { INT_RANGE(max_peer_links, 0, 255), 0 }, + { INT(mesh_max_inactivity), 0 }, ++ { INT_RANGE(mesh_fwding, 0, 1), 0 }, + { INT(dot11RSNASAERetransPeriod), 0 }, + #endif /* CONFIG_MESH */ + { INT(disable_scan_offload), 0 }, +diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h +index 6a297ecfe..11e3fc62a 100644 +--- a/wpa_supplicant/config.h ++++ b/wpa_supplicant/config.h +@@ -18,6 +18,7 @@ + #define DEFAULT_USER_MPM 1 + #define DEFAULT_MAX_PEER_LINKS 99 + #define DEFAULT_MESH_MAX_INACTIVITY 300 ++#define DEFAULT_MESH_FWDING 1 + /* + * The default dot11RSNASAERetransPeriod is defined as 40 ms in the standard, + * but use 1000 ms in practice to avoid issues on low power CPUs. +@@ -1327,6 +1328,14 @@ struct wpa_config { + int mesh_max_inactivity; + + /** ++ * mesh_fwding - Mesh network layer-2 forwarding ++ * ++ * This controls whether to enable layer-2 forwarding. ++ * By default: 1: enabled ++ */ ++ int mesh_fwding; ++ ++ /** + * dot11RSNASAERetransPeriod - Timeout to retransmit SAE Auth frame + * + * This timeout value is used in mesh STA to retransmit +diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c +index 77c326df5..7050a1ae6 100644 +--- a/wpa_supplicant/config_file.c ++++ b/wpa_supplicant/config_file.c +@@ -829,6 +829,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) + #endif /* IEEE8021X_EAPOL */ + INT(mode); + INT(no_auto_peer); ++ INT(mesh_fwding); + INT(frequency); + INT(fixed_freq); + #ifdef CONFIG_ACS +@@ -1472,6 +1473,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) + fprintf(f, "mesh_max_inactivity=%d\n", + config->mesh_max_inactivity); + ++ if (config->mesh_fwding != DEFAULT_MESH_FWDING) ++ fprintf(f, "mesh_fwding=%d\n", config->mesh_fwding); ++ + if (config->dot11RSNASAERetransPeriod != + DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD) + fprintf(f, "dot11RSNASAERetransPeriod=%d\n", +diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h +index d5c5c00a9..a052390ad 100644 +--- a/wpa_supplicant/config_ssid.h ++++ b/wpa_supplicant/config_ssid.h +@@ -516,6 +516,11 @@ struct wpa_ssid { + int dot11MeshConfirmTimeout; /* msec */ + int dot11MeshHoldingTimeout; /* msec */ + ++ /** ++ * Mesh network layer-2 forwarding ++ */ ++ int mesh_fwding; ++ + int ht; + int ht40; + +diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c +index bfc7c7a39..fa39e60bb 100644 +--- a/wpa_supplicant/mesh.c ++++ b/wpa_supplicant/mesh.c +@@ -126,6 +126,7 @@ static struct mesh_conf * mesh_config_create(struct wpa_supplicant *wpa_s, + conf->mesh_cc_id = 0; + conf->mesh_sp_id = MESH_SYNC_METHOD_NEIGHBOR_OFFSET; + conf->mesh_auth_id = (conf->security & MESH_CONF_SEC_AUTH) ? 1 : 0; ++ conf->mesh_fwding = ssid->mesh_fwding; + conf->dot11MeshMaxRetries = ssid->dot11MeshMaxRetries; + conf->dot11MeshRetryTimeout = ssid->dot11MeshRetryTimeout; + conf->dot11MeshConfirmTimeout = ssid->dot11MeshConfirmTimeout; +@@ -328,6 +329,7 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, + bss->conf->start_disabled = 1; + bss->conf->mesh = MESH_ENABLED; + bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity; ++ bss->conf->mesh_fwding = wpa_s->conf->mesh_fwding; + + if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes, + wpa_s->hw.num_modes) && wpa_s->conf->country[0]) { +@@ -549,6 +551,10 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, + } + params->conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity; + ++ /* always explicitely set forwarding to on or off for now */ ++ params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_FORWARDING; ++ params->conf.forwarding = ssid->mesh_fwding; ++ + os_free(wpa_s->mesh_params); + wpa_s->mesh_params = params; + if (wpa_supplicant_mesh_init(wpa_s, ssid, ¶ms->freq)) { +diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c +index 4a163b6eb..0b65b84a8 100644 +--- a/wpa_supplicant/mesh_mpm.c ++++ b/wpa_supplicant/mesh_mpm.c +@@ -305,9 +305,9 @@ static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s, + info = (bss->num_plinks > 63 ? 63 : bss->num_plinks) << 1; + /* TODO: Add Connected to Mesh Gate/AS subfields */ + wpabuf_put_u8(buf, info); +- /* always forwarding & accepting plinks for now */ ++ /* set forwarding & always accepting plinks for now */ + wpabuf_put_u8(buf, MESH_CAP_ACCEPT_ADDITIONAL_PEER | +- MESH_CAP_FORWARDING); ++ (conf->mesh_fwding ? MESH_CAP_FORWARDING : 0)); + } else { /* Peer closing frame */ + /* IE: Mesh ID */ + wpabuf_put_u8(buf, WLAN_EID_MESH_ID); +diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf +index 1159bdcdc..6dc6ef89b 100644 +--- a/wpa_supplicant/wpa_supplicant.conf ++++ b/wpa_supplicant/wpa_supplicant.conf +@@ -153,6 +153,9 @@ ap_scan=1 + # This timeout value is used in mesh STA to clean up inactive stations. + #mesh_max_inactivity=300 + ++# Enable 802.11s layer-2 routing and forwarding ++#mesh_fwding=1 ++ + # cert_in_cb - Whether to include a peer certificate dump in events + # This controls whether peer certificates for authentication server and + # its certificate chain are included in EAP peer certificate events. This is diff --git a/recipes-connectivity/hostapd/files/051-wpa_supplicant-fix-race-condition-in-mesh-mpm-new-pe.patch b/recipes-connectivity/hostapd/files/051-wpa_supplicant-fix-race-condition-in-mesh-mpm-new-pe.patch new file mode 100644 index 0000000..871b9a6 --- /dev/null +++ b/recipes-connectivity/hostapd/files/051-wpa_supplicant-fix-race-condition-in-mesh-mpm-new-pe.patch @@ -0,0 +1,40 @@ +From 72c752918b70221382c73a7b152b1515ac500543 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Tue, 12 Feb 2019 14:22:43 +0100 +Subject: [PATCH] wpa_supplicant: fix race condition in mesh mpm new peer + handling + +When wpa_supplicant receives another new peer event before the first one +has been processed, it tries to add a station to the driver a second time +(which fails) and then tears down the station entry until another event +comes in. +Fix this by only adding a station to the driver if it didn't exist already. + +Signed-off-by: Felix Fietkau + +--- + wpa_supplicant/mesh_mpm.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c +index 0b65b84a8..46144df09 100644 +--- a/wpa_supplicant/mesh_mpm.c ++++ b/wpa_supplicant/mesh_mpm.c +@@ -710,11 +710,12 @@ static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s, + } + + sta = ap_get_sta(data, addr); +- if (!sta) { +- sta = ap_sta_add(data, addr); +- if (!sta) +- return NULL; +- } ++ if (sta) ++ return NULL; ++ ++ sta = ap_sta_add(data, addr); ++ if (!sta) ++ return NULL; + + /* Set WMM by default since Mesh STAs are QoS STAs */ + sta->flags |= WLAN_STA_WMM; diff --git a/recipes-connectivity/hostapd/files/067-0001-AP-Silently-ignore-management-frame-from-unexpected-.patch b/recipes-connectivity/hostapd/files/067-0001-AP-Silently-ignore-management-frame-from-unexpected-.patch new file mode 100644 index 0000000..96153de --- /dev/null +++ b/recipes-connectivity/hostapd/files/067-0001-AP-Silently-ignore-management-frame-from-unexpected-.patch @@ -0,0 +1,71 @@ +From 992ca79a51cc0f300a100795a124b8263fea7852 Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Thu, 29 Aug 2019 11:52:04 +0300 +Subject: [PATCH] AP: Silently ignore management frame from unexpected source + address + +Do not process any received Management frames with unexpected/invalid SA +so that we do not add any state for unexpected STA addresses or end up +sending out frames to unexpected destination. This prevents unexpected +sequences where an unprotected frame might end up causing the AP to send +out a response to another device and that other device processing the +unexpected response. + +In particular, this prevents some potential denial of service cases +where the unexpected response frame from the AP might result in a +connected station dropping its association. + +Signed-off-by: Jouni Malinen + +--- + src/ap/drv_callbacks.c | 13 +++++++++++++ + src/ap/ieee802_11.c | 12 ++++++++++++ + 2 files changed, 25 insertions(+) + +diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c +index 31587685f..34ca379ed 100644 +--- a/src/ap/drv_callbacks.c ++++ b/src/ap/drv_callbacks.c +@@ -131,6 +131,19 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, + "hostapd_notif_assoc: Skip event with no address"); + return -1; + } ++ ++ if (is_multicast_ether_addr(addr) || ++ is_zero_ether_addr(addr) || ++ os_memcmp(addr, hapd->own_addr, ETH_ALEN) == 0) { ++ /* Do not process any frames with unexpected/invalid SA so that ++ * we do not add any state for unexpected STA addresses or end ++ * up sending out frames to unexpected destination. */ ++ wpa_printf(MSG_DEBUG, "%s: Invalid SA=" MACSTR ++ " in received indication - ignore this indication silently", ++ __func__, MAC2STR(addr)); ++ return 0; ++ } ++ + random_add_randomness(addr, ETH_ALEN); + + hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, +diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c +index c85a28db4..e7065372e 100644 +--- a/src/ap/ieee802_11.c ++++ b/src/ap/ieee802_11.c +@@ -4626,6 +4626,18 @@ int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len, + fc = le_to_host16(mgmt->frame_control); + stype = WLAN_FC_GET_STYPE(fc); + ++ if (is_multicast_ether_addr(mgmt->sa) || ++ is_zero_ether_addr(mgmt->sa) || ++ os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) { ++ /* Do not process any frames with unexpected/invalid SA so that ++ * we do not add any state for unexpected STA addresses or end ++ * up sending out frames to unexpected destination. */ ++ wpa_printf(MSG_DEBUG, "MGMT: Invalid SA=" MACSTR ++ " in received frame - ignore this frame silently", ++ MAC2STR(mgmt->sa)); ++ return 0; ++ } ++ + if (stype == WLAN_FC_STYPE_BEACON) { + handle_beacon(hapd, mgmt, len, fi); + return 1; diff --git a/recipes-connectivity/hostapd/files/070-driver_nl80211-fix-WMM-queue-mapping-for-regulatory-.patch b/recipes-connectivity/hostapd/files/070-driver_nl80211-fix-WMM-queue-mapping-for-regulatory-.patch new file mode 100644 index 0000000..02c3809 --- /dev/null +++ b/recipes-connectivity/hostapd/files/070-driver_nl80211-fix-WMM-queue-mapping-for-regulatory-.patch @@ -0,0 +1,46 @@ +From 2e1c4caa71155fdf53ed8acb18d5b3e3cfd69660 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Thu, 23 Jan 2020 13:50:47 +0100 +Subject: [PATCH] driver_nl80211: fix WMM queue mapping for regulatory limit + +nl80211 uses a different queue mapping from hostap, so AC indexes need to +be converted. + +Signed-off-by: Felix Fietkau + +--- + src/drivers/driver_nl80211_capa.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c +index 8318b10ab..0d35b13b5 100644 +--- a/src/drivers/driver_nl80211_capa.c ++++ b/src/drivers/driver_nl80211_capa.c +@@ -1403,6 +1403,12 @@ static void phy_info_freq(struct hostapd_hw_modes *mode, + [NL80211_WMMR_AIFSN] = { .type = NLA_U8 }, + [NL80211_WMMR_TXOP] = { .type = NLA_U16 }, + }; ++ static const u8 wmm_map[4] = { ++ [NL80211_AC_BE] = WMM_AC_BE, ++ [NL80211_AC_BK] = WMM_AC_BK, ++ [NL80211_AC_VI] = WMM_AC_VI, ++ [NL80211_AC_VO] = WMM_AC_VO, ++ }; + struct nlattr *nl_wmm; + struct nlattr *tb_wmm[NL80211_WMMR_MAX + 1]; + int rem_wmm, ac, count = 0; +@@ -1424,12 +1430,13 @@ static void phy_info_freq(struct hostapd_hw_modes *mode, + return; + } + ac = nl_wmm->nla_type; +- if (ac < 0 || ac >= WMM_AC_NUM) { ++ if (ac >= ARRAY_SIZE(wmm_map)) { + wpa_printf(MSG_DEBUG, + "nl80211: Invalid AC value %d", ac); + return; + } + ++ ac = wmm_map[ac]; + chan->wmm_rules[ac].min_cwmin = + nla_get_u16(tb_wmm[NL80211_WMMR_CW_MIN]); + chan->wmm_rules[ac].min_cwmax = diff --git a/recipes-connectivity/hostapd/files/071-driver_nl80211-fix-regulatory-limits-for-wmm-cwmin-c.patch b/recipes-connectivity/hostapd/files/071-driver_nl80211-fix-regulatory-limits-for-wmm-cwmin-c.patch new file mode 100644 index 0000000..11c7391 --- /dev/null +++ b/recipes-connectivity/hostapd/files/071-driver_nl80211-fix-regulatory-limits-for-wmm-cwmin-c.patch @@ -0,0 +1,53 @@ +From 55835a231c505b049b83977e8023eb8d7ea9d4e1 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Thu, 23 Jan 2020 14:10:20 +0100 +Subject: [PATCH] driver_nl80211: fix regulatory limits for wmm cwmin/cwmax + values + +The internal WMM AC parameters use just the exponent of the CW value, while +nl80211 reports the full CW value. +This led to completely bogus CWmin/CWmax values in the WMM IE when a regulatory +limit was present. Fix this by converting the value to the exponent before +passing it on + +Signed-off-by: Felix Fietkau + +--- + src/drivers/driver_nl80211_capa.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c +index 0d35b13b5..0defd6c7b 100644 +--- a/src/drivers/driver_nl80211_capa.c ++++ b/src/drivers/driver_nl80211_capa.c +@@ -1336,6 +1336,18 @@ static void phy_info_vht_capa(struct hostapd_hw_modes *mode, + } + } + ++static inline int cw2ecw(unsigned int cw) ++{ ++ int bit; ++ ++ if (cw == 0) ++ return 0; ++ ++ for (bit = 1; cw != 1; bit++) ++ cw >>= 1; ++ ++ return bit; ++} + + static void phy_info_freq(struct hostapd_hw_modes *mode, + struct hostapd_channel_data *chan, +@@ -1438,9 +1450,9 @@ static void phy_info_freq(struct hostapd_hw_modes *mode, + + ac = wmm_map[ac]; + chan->wmm_rules[ac].min_cwmin = +- nla_get_u16(tb_wmm[NL80211_WMMR_CW_MIN]); ++ cw2ecw(nla_get_u16(tb_wmm[NL80211_WMMR_CW_MIN])); + chan->wmm_rules[ac].min_cwmax = +- nla_get_u16(tb_wmm[NL80211_WMMR_CW_MAX]); ++ cw2ecw(nla_get_u16(tb_wmm[NL80211_WMMR_CW_MAX])); + chan->wmm_rules[ac].min_aifs = + nla_get_u8(tb_wmm[NL80211_WMMR_AIFSN]); + chan->wmm_rules[ac].max_txop = diff --git a/recipes-connectivity/hostapd/files/090-wolfssl-fix-crypto_bignum_sum.patch b/recipes-connectivity/hostapd/files/090-wolfssl-fix-crypto_bignum_sum.patch new file mode 100644 index 0000000..55816ff --- /dev/null +++ b/recipes-connectivity/hostapd/files/090-wolfssl-fix-crypto_bignum_sum.patch @@ -0,0 +1,29 @@ +From de5ea86978634ecc7d936a170dd1d368fd4ed31b Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Mon, 14 Oct 2019 19:27:47 +0300 +Subject: [PATCH] wolfSSL: Fix crypto_bignum_sub() + +The initial crypto wrapper implementation for wolfSSL seems to have +included a copy-paste error in crypto_bignum_sub() implementation that +was identical to crypto_bignum_add() while mp_sub() should have been +used instead of mp_add(). + +Signed-off-by: Jouni Malinen + +--- + src/crypto/crypto_wolfssl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c +index 4cedab436..960caf32a 100644 +--- a/src/crypto/crypto_wolfssl.c ++++ b/src/crypto/crypto_wolfssl.c +@@ -1151,7 +1151,7 @@ int crypto_bignum_sub(const struct crypto_bignum *a, + if (TEST_FAIL()) + return -1; + +- return mp_add((mp_int *) a, (mp_int *) b, ++ return mp_sub((mp_int *) a, (mp_int *) b, + (mp_int *) r) == MP_OKAY ? 0 : -1; + } + diff --git a/recipes-connectivity/hostapd/files/100-daemonize_fix.patch b/recipes-connectivity/hostapd/files/100-daemonize_fix.patch new file mode 100644 index 0000000..7ab6fee --- /dev/null +++ b/recipes-connectivity/hostapd/files/100-daemonize_fix.patch @@ -0,0 +1,107 @@ +From 344ed019cfedec05e6fdb4b6059354b090155f6f Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + src/utils/os_unix.c | 68 ++++++++++++++++++++++------------------------------- + 1 file changed, 28 insertions(+), 40 deletions(-) + +diff --git a/src/utils/os_unix.c b/src/utils/os_unix.c +index 800c50772..6231974cf 100644 +--- a/src/utils/os_unix.c ++++ b/src/utils/os_unix.c +@@ -10,6 +10,7 @@ + + #include + #include ++#include + + #ifdef ANDROID + #include +@@ -182,59 +183,46 @@ int os_gmtime(os_time_t t, struct os_tm *tm) + return 0; + } + +- +-#ifdef __APPLE__ +-#include +-static int os_daemon(int nochdir, int noclose) ++int os_daemonize(const char *pid_file) + { +- int devnull; ++ int pid = 0, i, devnull; + +- if (chdir("/") < 0) +- return -1; ++#if defined(__uClinux__) || defined(__sun__) ++ return -1; ++#else /* defined(__uClinux__) || defined(__sun__) */ + +- devnull = open("/dev/null", O_RDWR); +- if (devnull < 0) ++#ifndef __APPLE__ ++ pid = fork(); ++ if (pid < 0) + return -1; ++#endif + +- if (dup2(devnull, STDIN_FILENO) < 0) { +- close(devnull); +- return -1; ++ if (pid > 0) { ++ if (pid_file) { ++ FILE *f = fopen(pid_file, "w"); ++ if (f) { ++ fprintf(f, "%u\n", pid); ++ fclose(f); ++ } ++ } ++ _exit(0); + } + +- if (dup2(devnull, STDOUT_FILENO) < 0) { +- close(devnull); ++ if (setsid() < 0) + return -1; +- } + +- if (dup2(devnull, STDERR_FILENO) < 0) { +- close(devnull); ++ if (chdir("/") < 0) + return -1; +- } +- +- return 0; +-} +-#else /* __APPLE__ */ +-#define os_daemon daemon +-#endif /* __APPLE__ */ +- + +-int os_daemonize(const char *pid_file) +-{ +-#if defined(__uClinux__) || defined(__sun__) +- return -1; +-#else /* defined(__uClinux__) || defined(__sun__) */ +- if (os_daemon(0, 0)) { +- perror("daemon"); ++ devnull = open("/dev/null", O_RDWR); ++ if (devnull < 0) + return -1; +- } + +- if (pid_file) { +- FILE *f = fopen(pid_file, "w"); +- if (f) { +- fprintf(f, "%u\n", getpid()); +- fclose(f); +- } +- } ++ for (i = 0; i <= STDERR_FILENO; i++) ++ dup2(devnull, i); ++ ++ if (devnull > 2) ++ close(devnull); + + return -0; + #endif /* defined(__uClinux__) || defined(__sun__) */ diff --git a/recipes-connectivity/hostapd/files/200-multicall.patch b/recipes-connectivity/hostapd/files/200-multicall.patch new file mode 100644 index 0000000..4137ab9 --- /dev/null +++ b/recipes-connectivity/hostapd/files/200-multicall.patch @@ -0,0 +1,392 @@ +From 424e215228221cd61f574b4b40cb77e0666d9d37 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + hostapd/Makefile | 26 ++++++++++++++++++++++---- + hostapd/main.c | 7 +++++++ + src/ap/drv_callbacks.c | 6 +++--- + src/drivers/driver.h | 6 +++--- + src/drivers/drivers.c | 4 ++++ + wpa_supplicant/Makefile | 29 +++++++++++++++++++++++++++++ + wpa_supplicant/eapol_test.c | 11 +++++++++++ + wpa_supplicant/events.c | 6 +++--- + wpa_supplicant/wpa_priv.c | 8 +++++--- + wpa_supplicant/wpa_supplicant.c | 8 +++++++- + 10 files changed, 94 insertions(+), 17 deletions(-) + +diff --git a/hostapd/Makefile b/hostapd/Makefile +index 2a6bd7ac8..da8f9bc9b 100644 +--- a/hostapd/Makefile ++++ b/hostapd/Makefile +@@ -28,6 +28,7 @@ CFLAGS += -I$(abspath ../src/utils) + export BINDIR ?= /usr/local/bin/ + + -include .config ++-include $(if $(MULTICALL), ../wpa_supplicant/.config) + + ifndef CONFIG_NO_GITVER + # Add VERSION_STR postfix for builds from a git repository +@@ -198,7 +199,8 @@ endif + + ifdef CONFIG_NO_VLAN + CFLAGS += -DCONFIG_NO_VLAN +-else ++endif ++ifneq ($(findstring CONFIG_NO_VLAN,$(CFLAGS)), CONFIG_NO_VLAN) + OBJS += ../src/ap/vlan_init.o + OBJS += ../src/ap/vlan_ifconfig.o + OBJS += ../src/ap/vlan.o +@@ -366,10 +368,14 @@ CFLAGS += -DCONFIG_MBO + OBJS += ../src/ap/mbo_ap.o + endif + ++ifndef MULTICALL ++CFLAGS += -DNO_SUPPLICANT ++endif ++ + include ../src/drivers/drivers.mak +-OBJS += $(DRV_AP_OBJS) +-CFLAGS += $(DRV_AP_CFLAGS) +-LDFLAGS += $(DRV_AP_LDFLAGS) ++OBJS += $(sort $(DRV_AP_OBJS) $(if $(MULTICALL),$(DRV_WPA_OBJS))) ++CFLAGS += $(DRV_AP_CFLAGS) $(if $(MULTICALL),$(DRV_WPA_CFLAGS)) ++LDFLAGS += $(DRV_AP_LDFLAGS) $(if $(MULTICALL),$(DRV_WPA_LDFLAGS)) + LIBS += $(DRV_AP_LIBS) + + ifdef CONFIG_L2_PACKET +@@ -1316,6 +1322,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR)/,$(ALL)) + + BCHECK=../src/drivers/build.hostapd + ++hostapd_multi.a: $(BCHECK) $(OBJS) ++ $(Q)$(CC) -c -o hostapd_multi.o -Dmain=hostapd_main $(CFLAGS) main.c ++ @$(E) " CC " $< ++ @rm -f $@ ++ @$(AR) cr $@ hostapd_multi.o $(OBJS) ++ + hostapd: $(BCHECK) $(OBJS) + $(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS) + @$(E) " LD " $@ +@@ -1358,6 +1370,12 @@ ifeq ($(CONFIG_TLS), linux) + HOBJS += ../src/crypto/crypto_linux.o + endif + ++dump_cflags: ++ @printf "%s " "$(CFLAGS)" ++ ++dump_ldflags: ++ @printf "%s " "$(LDFLAGS) $(LIBS) $(EXTRALIBS)" ++ + nt_password_hash: $(NOBJS) + $(Q)$(CC) $(LDFLAGS) -o nt_password_hash $(NOBJS) $(LIBS_n) + @$(E) " LD " $@ +diff --git a/hostapd/main.c b/hostapd/main.c +index 08896ffe2..90424d5bd 100644 +--- a/hostapd/main.c ++++ b/hostapd/main.c +@@ -592,6 +592,11 @@ fail: + return -1; + } + ++void hostapd_wpa_event(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); ++ ++void hostapd_wpa_event_global(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); + + #ifdef CONFIG_WPS + static int gen_uuid(const char *txt_addr) +@@ -682,6 +687,8 @@ int main(int argc, char *argv[]) + return -1; + #endif /* CONFIG_DPP */ + ++ wpa_supplicant_event = hostapd_wpa_event; ++ wpa_supplicant_event_global = hostapd_wpa_event_global; + for (;;) { + c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:vg:G:"); + if (c < 0) +diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c +index 34ca379ed..366cfc08a 100644 +--- a/src/ap/drv_callbacks.c ++++ b/src/ap/drv_callbacks.c +@@ -1669,8 +1669,8 @@ err: + #endif /* CONFIG_OWE */ + + +-void wpa_supplicant_event(void *ctx, enum wpa_event_type event, +- union wpa_event_data *data) ++void hostapd_wpa_event(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data) + { + struct hostapd_data *hapd = ctx; + #ifndef CONFIG_NO_STDOUT_DEBUG +@@ -1915,7 +1915,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, + } + + +-void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, ++void hostapd_wpa_event_global(void *ctx, enum wpa_event_type event, + union wpa_event_data *data) + { + struct hapd_interfaces *interfaces = ctx; +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index d73ff62c0..f35e3fdad 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -5657,8 +5657,8 @@ union wpa_event_data { + * Driver wrapper code should call this function whenever an event is received + * from the driver. + */ +-void wpa_supplicant_event(void *ctx, enum wpa_event_type event, +- union wpa_event_data *data); ++extern void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); + + /** + * wpa_supplicant_event_global - Report a driver event for wpa_supplicant +@@ -5670,7 +5670,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, + * Same as wpa_supplicant_event(), but we search for the interface in + * wpa_global. + */ +-void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, ++extern void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event, + union wpa_event_data *data); + + /* +diff --git a/src/drivers/drivers.c b/src/drivers/drivers.c +index e95df6ddb..9071da3cf 100644 +--- a/src/drivers/drivers.c ++++ b/src/drivers/drivers.c +@@ -10,6 +10,10 @@ + #include "utils/common.h" + #include "driver.h" + ++void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); ++void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); + + const struct wpa_driver_ops *const wpa_drivers[] = + { +diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile +index f1384d5fa..3d05870bd 100644 +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -27,6 +27,7 @@ CFLAGS += -I$(abspath ../src) + CFLAGS += -I$(abspath ../src/utils) + + -include .config ++-include $(if $(MULTICALL),../hostapd/.config) + + ifndef CONFIG_NO_GITVER + # Add VERSION_STR postfix for builds from a git repository +@@ -363,7 +364,9 @@ endif + ifdef CONFIG_IBSS_RSN + NEED_RSN_AUTHENTICATOR=y + CFLAGS += -DCONFIG_IBSS_RSN ++ifndef MULTICALL + CFLAGS += -DCONFIG_NO_VLAN ++endif + OBJS += ibss_rsn.o + endif + +@@ -892,6 +895,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS + CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS + LIBS += -ldl -rdynamic + endif ++else ++ ifdef MULTICALL ++ OBJS += ../src/eap_common/eap_common.o ++ endif + endif + + ifdef CONFIG_AP +@@ -899,9 +906,11 @@ NEED_EAP_COMMON=y + NEED_RSN_AUTHENTICATOR=y + CFLAGS += -DCONFIG_AP + OBJS += ap.o ++ifndef MULTICALL + CFLAGS += -DCONFIG_NO_RADIUS + CFLAGS += -DCONFIG_NO_ACCOUNTING + CFLAGS += -DCONFIG_NO_VLAN ++endif + OBJS += ../src/ap/hostapd.o + OBJS += ../src/ap/wpa_auth_glue.o + OBJS += ../src/ap/utils.o +@@ -983,6 +992,12 @@ endif + ifdef CONFIG_HS20 + OBJS += ../src/ap/hs20.o + endif ++else ++ ifdef MULTICALL ++ OBJS += ../src/eap_server/eap_server.o ++ OBJS += ../src/eap_server/eap_server_identity.o ++ OBJS += ../src/eap_server/eap_server_methods.o ++ endif + endif + + ifdef CONFIG_MBO +@@ -991,7 +1006,9 @@ CFLAGS += -DCONFIG_MBO + endif + + ifdef NEED_RSN_AUTHENTICATOR ++ifndef MULTICALL + CFLAGS += -DCONFIG_NO_RADIUS ++endif + NEED_AES_WRAP=y + OBJS += ../src/ap/wpa_auth.o + OBJS += ../src/ap/wpa_auth_ie.o +@@ -1899,6 +1916,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv) + + $(OBJS_c) $(OBJS_t) $(OBJS_t2) $(OBJS) $(BCHECK) $(EXTRA_progs): .config + ++wpa_supplicant_multi.a: .config $(BCHECK) $(OBJS) $(EXTRA_progs) ++ $(Q)$(CC) -c -o wpa_supplicant_multi.o -Dmain=wpa_supplicant_main $(CFLAGS) main.c ++ @$(E) " CC " $< ++ @rm -f $@ ++ @$(AR) cr $@ wpa_supplicant_multi.o $(OBJS) ++ + wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) + $(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) + @$(E) " LD " $@ +@@ -1999,6 +2022,12 @@ endif + $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@ + @$(E) " sed" $< + ++dump_cflags: ++ @printf "%s " "$(CFLAGS)" ++ ++dump_ldflags: ++ @printf "%s " "$(LDFLAGS) $(LIBS) $(EXTRALIBS)" ++ + wpa_supplicant.exe: wpa_supplicant + mv -f $< $@ + wpa_cli.exe: wpa_cli +diff --git a/wpa_supplicant/eapol_test.c b/wpa_supplicant/eapol_test.c +index 524724f19..fe18dfd73 100644 +--- a/wpa_supplicant/eapol_test.c ++++ b/wpa_supplicant/eapol_test.c +@@ -30,7 +30,12 @@ + #include "ctrl_iface.h" + #include "pcsc_funcs.h" + #include "wpas_glue.h" ++#include "drivers/driver.h" + ++void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); ++void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); + + const struct wpa_driver_ops *const wpa_drivers[] = { NULL }; + +@@ -1292,6 +1297,10 @@ static void usage(void) + "option several times.\n"); + } + ++extern void supplicant_event(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); ++extern void supplicant_event_global(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); + + int main(int argc, char *argv[]) + { +@@ -1312,6 +1321,8 @@ int main(int argc, char *argv[]) + if (os_program_init()) + return -1; + ++ wpa_supplicant_event = supplicant_event; ++ wpa_supplicant_event_global = supplicant_event_global; + hostapd_logger_register_cb(hostapd_logger_cb); + + os_memset(&eapol_test, 0, sizeof(eapol_test)); +diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c +index 87dad0811..067f76b48 100644 +--- a/wpa_supplicant/events.c ++++ b/wpa_supplicant/events.c +@@ -4184,8 +4184,8 @@ static void wpas_event_assoc_reject(struct wpa_supplicant *wpa_s, + } + + +-void wpa_supplicant_event(void *ctx, enum wpa_event_type event, +- union wpa_event_data *data) ++void supplicant_event(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data) + { + struct wpa_supplicant *wpa_s = ctx; + int resched; +@@ -4967,7 +4967,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, + } + + +-void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, ++void supplicant_event_global(void *ctx, enum wpa_event_type event, + union wpa_event_data *data) + { + struct wpa_supplicant *wpa_s; +diff --git a/wpa_supplicant/wpa_priv.c b/wpa_supplicant/wpa_priv.c +index b3ad45eca..55630a5c7 100644 +--- a/wpa_supplicant/wpa_priv.c ++++ b/wpa_supplicant/wpa_priv.c +@@ -1031,8 +1031,8 @@ static void wpa_priv_send_ft_response(struct wpa_priv_interface *iface, + } + + +-void wpa_supplicant_event(void *ctx, enum wpa_event_type event, +- union wpa_event_data *data) ++static void supplicant_event(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data) + { + struct wpa_priv_interface *iface = ctx; + +@@ -1095,7 +1095,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, + } + + +-void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, ++void supplicant_event_global(void *ctx, enum wpa_event_type event, + union wpa_event_data *data) + { + struct wpa_priv_global *global = ctx; +@@ -1207,6 +1207,8 @@ int main(int argc, char *argv[]) + if (os_program_init()) + return -1; + ++ wpa_supplicant_event = supplicant_event; ++ wpa_supplicant_event_global = supplicant_event_global; + wpa_priv_fd_workaround(); + + os_memset(&global, 0, sizeof(global)); +diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c +index 578f274a9..4f95917c6 100644 +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -6096,7 +6096,6 @@ struct wpa_interface * wpa_supplicant_match_iface(struct wpa_global *global, + return NULL; + } + +- + /** + * wpa_supplicant_match_existing - Match existing interfaces + * @global: Pointer to global data from wpa_supplicant_init() +@@ -6133,6 +6132,11 @@ static int wpa_supplicant_match_existing(struct wpa_global *global) + + #endif /* CONFIG_MATCH_IFACE */ + ++extern void supplicant_event(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); ++ ++extern void supplicant_event_global(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); + + /** + * wpa_supplicant_add_iface - Add a new network interface +@@ -6389,6 +6393,8 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params) + #ifndef CONFIG_NO_WPA_MSG + wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb); + #endif /* CONFIG_NO_WPA_MSG */ ++ wpa_supplicant_event = supplicant_event; ++ wpa_supplicant_event_global = supplicant_event_global; + + if (params->wpa_debug_file_path) + wpa_debug_open_file(params->wpa_debug_file_path); diff --git a/recipes-connectivity/hostapd/files/300-noscan.patch b/recipes-connectivity/hostapd/files/300-noscan.patch new file mode 100644 index 0000000..d46c781 --- /dev/null +++ b/recipes-connectivity/hostapd/files/300-noscan.patch @@ -0,0 +1,77 @@ +From e8bf6ea2fbcbcff612b6adf93cb5fcdf86f0c4a0 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + hostapd/config_file.c | 4 ++++ + src/ap/ap_config.h | 2 ++ + src/ap/hw_features.c | 3 ++- + src/ap/ieee802_11_ht.c | 6 ++++++ + 4 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/hostapd/config_file.c b/hostapd/config_file.c +index e09e6e141..625104831 100644 +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -3411,6 +3411,10 @@ static int hostapd_config_fill(struct hostapd_config *conf, + bss->ieee80211w = 1; + #endif /* CONFIG_OCV */ + #ifdef CONFIG_IEEE80211N ++ } else if (os_strcmp(buf, "noscan") == 0) { ++ conf->noscan = atoi(pos); ++ } else if (os_strcmp(buf, "ht_coex") == 0) { ++ conf->no_ht_coex = !atoi(pos); + } else if (os_strcmp(buf, "ieee80211n") == 0) { + conf->ieee80211n = atoi(pos); + } else if (os_strcmp(buf, "ht_capab") == 0) { +diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h +index cfe59d4b4..826030666 100644 +--- a/src/ap/ap_config.h ++++ b/src/ap/ap_config.h +@@ -934,6 +934,8 @@ struct hostapd_config { + + int ht_op_mode_fixed; + u16 ht_capab; ++ int noscan; ++ int no_ht_coex; + int ieee80211n; + int secondary_channel; + int no_pri_sec_switch; +diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c +index c1f19e26b..993f0d035 100644 +--- a/src/ap/hw_features.c ++++ b/src/ap/hw_features.c +@@ -477,7 +477,8 @@ static int ieee80211n_check_40mhz(struct hostapd_iface *iface) + int ret; + + /* Check that HT40 is used and PRI / SEC switch is allowed */ +- if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch) ++ if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch || ++ iface->conf->noscan) + return 0; + + hostapd_set_state(iface, HAPD_IFACE_HT_SCAN); +diff --git a/src/ap/ieee802_11_ht.c b/src/ap/ieee802_11_ht.c +index 214855dcc..3697ca331 100644 +--- a/src/ap/ieee802_11_ht.c ++++ b/src/ap/ieee802_11_ht.c +@@ -252,6 +252,9 @@ void hostapd_2040_coex_action(struct hostapd_data *hapd, + return; + } + ++ if (iface->conf->noscan || iface->conf->no_ht_coex) ++ return; ++ + if (len < IEEE80211_HDRLEN + 2 + sizeof(*bc_ie)) { + wpa_printf(MSG_DEBUG, + "Ignore too short 20/40 BSS Coexistence Management frame"); +@@ -412,6 +415,9 @@ void ht40_intolerant_add(struct hostapd_iface *iface, struct sta_info *sta) + if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G) + return; + ++ if (iface->conf->noscan || iface->conf->no_ht_coex) ++ return; ++ + wpa_printf(MSG_INFO, "HT: Forty MHz Intolerant is set by STA " MACSTR + " in Association Request", MAC2STR(sta->addr)); + diff --git a/recipes-connectivity/hostapd/files/301-mesh-noscan.patch b/recipes-connectivity/hostapd/files/301-mesh-noscan.patch new file mode 100644 index 0000000..08f89f2 --- /dev/null +++ b/recipes-connectivity/hostapd/files/301-mesh-noscan.patch @@ -0,0 +1,90 @@ +From e22b3c8a6ed6f4dec3700fd5bb6b719888d91d91 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + wpa_supplicant/config.c | 1 + + wpa_supplicant/config_file.c | 1 + + wpa_supplicant/config_ssid.h | 2 ++ + wpa_supplicant/mesh.c | 2 ++ + wpa_supplicant/wpa_supplicant.c | 6 +++--- + 5 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c +index 07ed344e4..eaabaa88d 100644 +--- a/wpa_supplicant/config.c ++++ b/wpa_supplicant/config.c +@@ -2312,6 +2312,7 @@ static const struct parse_data ssid_fields[] = { + #else /* CONFIG_MESH */ + { INT_RANGE(mode, 0, 4) }, + #endif /* CONFIG_MESH */ ++ { INT_RANGE(noscan, 0, 1) }, + { INT_RANGE(proactive_key_caching, 0, 1) }, + { INT_RANGE(disabled, 0, 2) }, + { STR(id_str) }, +diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c +index 7050a1ae6..f4a397fe3 100644 +--- a/wpa_supplicant/config_file.c ++++ b/wpa_supplicant/config_file.c +@@ -829,6 +829,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) + #endif /* IEEE8021X_EAPOL */ + INT(mode); + INT(no_auto_peer); ++ INT(noscan); + INT(mesh_fwding); + INT(frequency); + INT(fixed_freq); +diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h +index a052390ad..401c22cec 100644 +--- a/wpa_supplicant/config_ssid.h ++++ b/wpa_supplicant/config_ssid.h +@@ -918,6 +918,8 @@ struct wpa_ssid { + */ + int no_auto_peer; + ++ int noscan; ++ + /** + * mesh_rssi_threshold - Set mesh parameter mesh_rssi_threshold (dBm) + * +diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c +index fa39e60bb..6f54ff764 100644 +--- a/wpa_supplicant/mesh.c ++++ b/wpa_supplicant/mesh.c +@@ -361,6 +361,8 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, + frequency); + goto out_free; + } ++ if (ssid->noscan) ++ conf->noscan = 1; + if (ssid->ht40) + conf->secondary_channel = ssid->ht40; + if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A && ssid->vht) { +diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c +index 4f95917c6..70161d272 100644 +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -2143,12 +2143,12 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, + int ieee80211_mode = wpas_mode_to_ieee80211_mode(ssid->mode); + enum hostapd_hw_mode hw_mode; + struct hostapd_hw_modes *mode = NULL; +- int ht40plus[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, ++ int ht40plus[] = { 1, 2, 3, 4, 5, 6, 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, + 184, 192 }; + int vht80[] = { 36, 52, 100, 116, 132, 149 }; + struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL; + u8 channel; +- int i, chan_idx, ht40 = -1, res, obss_scan = 1; ++ int i, chan_idx, ht40 = -1, res, obss_scan = !(ssid->noscan); + unsigned int j, k; + struct hostapd_freq_params vht_freq; + int chwidth, seg0, seg1; +@@ -2221,7 +2221,7 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, + return; + + /* Setup higher BW only for 5 GHz */ +- if (mode->mode != HOSTAPD_MODE_IEEE80211A) ++ if (mode->mode != HOSTAPD_MODE_IEEE80211A && !(ssid->noscan)) + return; + + for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) { diff --git a/recipes-connectivity/hostapd/files/310-rescan_immediately.patch b/recipes-connectivity/hostapd/files/310-rescan_immediately.patch new file mode 100644 index 0000000..c5e3071 --- /dev/null +++ b/recipes-connectivity/hostapd/files/310-rescan_immediately.patch @@ -0,0 +1,21 @@ +From 9836c7637ca362ab893b3f5f12ec123daf36ef37 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + wpa_supplicant/wpa_supplicant.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c +index 70161d272..92ddbe458 100644 +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -4474,7 +4474,7 @@ wpa_supplicant_alloc(struct wpa_supplicant *parent) + if (wpa_s == NULL) + return NULL; + wpa_s->scan_req = INITIAL_SCAN_REQ; +- wpa_s->scan_interval = 5; ++ wpa_s->scan_interval = 1; + wpa_s->new_connection = 1; + wpa_s->parent = parent ? parent : wpa_s; + wpa_s->p2pdev = wpa_s->parent; diff --git a/recipes-connectivity/hostapd/files/320-optional_rfkill.patch b/recipes-connectivity/hostapd/files/320-optional_rfkill.patch new file mode 100644 index 0000000..ced574a --- /dev/null +++ b/recipes-connectivity/hostapd/files/320-optional_rfkill.patch @@ -0,0 +1,74 @@ +From c029de2c61fbc74f39362bdcfe46bf39cde33b17 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + src/drivers/drivers.mak | 4 +--- + src/drivers/rfkill.h | 16 ++++++++++++++++ + 2 files changed, 17 insertions(+), 3 deletions(-) + +diff --git a/src/drivers/drivers.mak b/src/drivers/drivers.mak +index 442c59cf4..da17ccc51 100644 +--- a/src/drivers/drivers.mak ++++ b/src/drivers/drivers.mak +@@ -50,7 +50,6 @@ NEED_SME=y + NEED_AP_MLME=y + NEED_NETLINK=y + NEED_LINUX_IOCTL=y +-NEED_RFKILL=y + NEED_RADIOTAP=y + NEED_LIBNL=y + endif +@@ -107,7 +106,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT + CONFIG_WIRELESS_EXTENSION=y + NEED_NETLINK=y + NEED_LINUX_IOCTL=y +-NEED_RFKILL=y + endif + + ifdef CONFIG_DRIVER_NDIS +@@ -133,7 +131,6 @@ endif + ifdef CONFIG_WIRELESS_EXTENSION + DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION + DRV_WPA_OBJS += ../src/drivers/driver_wext.o +-NEED_RFKILL=y + endif + + ifdef NEED_NETLINK +@@ -146,6 +143,7 @@ endif + + ifdef NEED_RFKILL + DRV_OBJS += ../src/drivers/rfkill.o ++DRV_WPA_CFLAGS += -DCONFIG_RFKILL + endif + + ifdef NEED_RADIOTAP +diff --git a/src/drivers/rfkill.h b/src/drivers/rfkill.h +index 0412ac330..e27565375 100644 +--- a/src/drivers/rfkill.h ++++ b/src/drivers/rfkill.h +@@ -18,8 +18,24 @@ struct rfkill_config { + void (*unblocked_cb)(void *ctx); + }; + ++#ifdef CONFIG_RFKILL + struct rfkill_data * rfkill_init(struct rfkill_config *cfg); + void rfkill_deinit(struct rfkill_data *rfkill); + int rfkill_is_blocked(struct rfkill_data *rfkill); ++#else ++static inline struct rfkill_data * rfkill_init(struct rfkill_config *cfg) ++{ ++ return (void *) 1; ++} ++ ++static inline void rfkill_deinit(struct rfkill_data *rfkill) ++{ ++} ++ ++static inline int rfkill_is_blocked(struct rfkill_data *rfkill) ++{ ++ return 0; ++} ++#endif + + #endif /* RFKILL_H */ diff --git a/recipes-connectivity/hostapd/files/330-nl80211_fix_set_freq.patch b/recipes-connectivity/hostapd/files/330-nl80211_fix_set_freq.patch new file mode 100644 index 0000000..2813fe8 --- /dev/null +++ b/recipes-connectivity/hostapd/files/330-nl80211_fix_set_freq.patch @@ -0,0 +1,21 @@ +From ea5e8082aadcdbf23397cdb3dbd1b1f8aeff78d2 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + src/drivers/driver_nl80211.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c +index 2930b01b4..d0f79ca4b 100644 +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -4431,7 +4431,7 @@ static int nl80211_set_channel(struct i802_bss *bss, + freq->freq, freq->ht_enabled, freq->vht_enabled, freq->he_enabled, + freq->bandwidth, freq->center_freq1, freq->center_freq2); + +- msg = nl80211_drv_msg(drv, 0, set_chan ? NL80211_CMD_SET_CHANNEL : ++ msg = nl80211_bss_msg(bss, 0, set_chan ? NL80211_CMD_SET_CHANNEL : + NL80211_CMD_SET_WIPHY); + if (!msg || nl80211_put_freq_params(msg, freq) < 0) { + nlmsg_free(msg); diff --git a/recipes-connectivity/hostapd/files/340-reload_freq_change.patch b/recipes-connectivity/hostapd/files/340-reload_freq_change.patch new file mode 100644 index 0000000..6e33d1d --- /dev/null +++ b/recipes-connectivity/hostapd/files/340-reload_freq_change.patch @@ -0,0 +1,83 @@ +From ad010c95defeaded858c4d37004911a7cb31f199 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + src/ap/hostapd.c | 47 ++++++++++++++++++++++++++++++++--------------- + 1 file changed, 32 insertions(+), 15 deletions(-) + +diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c +index c85563353..9227a1f01 100644 +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -108,6 +108,26 @@ static void hostapd_reload_bss(struct hostapd_data *hapd) + #endif /* CONFIG_NO_RADIUS */ + + ssid = &hapd->conf->ssid; ++ ++ hostapd_set_freq(hapd, hapd->iconf->hw_mode, hapd->iface->freq, ++ hapd->iconf->channel, ++ hapd->iconf->ieee80211n, ++ hapd->iconf->ieee80211ac, ++ hapd->iconf->ieee80211ax, ++ hapd->iconf->secondary_channel, ++ hostapd_get_oper_chwidth(hapd->iconf), ++ hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf), ++ hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf)); ++ ++ if (hapd->iface->current_mode) { ++ if (hostapd_prepare_rates(hapd->iface, hapd->iface->current_mode)) { ++ wpa_printf(MSG_ERROR, "Failed to prepare rates table."); ++ hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, ++ HOSTAPD_LEVEL_WARNING, ++ "Failed to prepare rates table."); ++ } ++ } ++ + if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next && + ssid->wpa_passphrase_set && ssid->wpa_passphrase) { + /* +@@ -205,6 +225,7 @@ int hostapd_reload_config(struct hostapd_iface *iface) + struct hostapd_data *hapd = iface->bss[0]; + struct hostapd_config *newconf, *oldconf; + size_t j; ++ int i; + + if (iface->config_fname == NULL) { + /* Only in-memory config in use - assume it has been updated */ +@@ -255,24 +276,20 @@ int hostapd_reload_config(struct hostapd_iface *iface) + } + iface->conf = newconf; + ++ for (i = 0; i < iface->num_hw_features; i++) { ++ struct hostapd_hw_modes *mode = &iface->hw_features[i]; ++ if (mode->mode == iface->conf->hw_mode) { ++ iface->current_mode = mode; ++ break; ++ } ++ } ++ ++ if (iface->conf->channel) ++ iface->freq = hostapd_hw_get_freq(hapd, iface->conf->channel); ++ + for (j = 0; j < iface->num_bss; j++) { + hapd = iface->bss[j]; + hapd->iconf = newconf; +- hapd->iconf->channel = oldconf->channel; +- hapd->iconf->acs = oldconf->acs; +- hapd->iconf->secondary_channel = oldconf->secondary_channel; +- hapd->iconf->ieee80211n = oldconf->ieee80211n; +- hapd->iconf->ieee80211ac = oldconf->ieee80211ac; +- hapd->iconf->ht_capab = oldconf->ht_capab; +- hapd->iconf->vht_capab = oldconf->vht_capab; +- hostapd_set_oper_chwidth(hapd->iconf, +- hostapd_get_oper_chwidth(oldconf)); +- hostapd_set_oper_centr_freq_seg0_idx( +- hapd->iconf, +- hostapd_get_oper_centr_freq_seg0_idx(oldconf)); +- hostapd_set_oper_centr_freq_seg1_idx( +- hapd->iconf, +- hostapd_get_oper_centr_freq_seg1_idx(oldconf)); + hapd->conf = newconf->bss[j]; + hostapd_reload_bss(hapd); + } diff --git a/recipes-connectivity/hostapd/files/341-mesh-ctrl-iface-channel-switch.patch b/recipes-connectivity/hostapd/files/341-mesh-ctrl-iface-channel-switch.patch new file mode 100644 index 0000000..b95c70d --- /dev/null +++ b/recipes-connectivity/hostapd/files/341-mesh-ctrl-iface-channel-switch.patch @@ -0,0 +1,49 @@ +From 24c05db1628be8bfbdb0caf70acf3e86e943becc Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + wpa_supplicant/ap.c | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c +index 4e3c2814d..5af4be230 100644 +--- a/wpa_supplicant/ap.c ++++ b/wpa_supplicant/ap.c +@@ -1378,15 +1378,35 @@ int ap_switch_channel(struct wpa_supplicant *wpa_s, + + + #ifdef CONFIG_CTRL_IFACE ++ ++static int __ap_ctrl_iface_chanswitch(struct hostapd_iface *iface, ++ struct csa_settings *settings) ++{ ++#ifdef NEED_AP_MLME ++ if (!iface || !iface->bss[0]) ++ return 0; ++ ++ return hostapd_switch_channel(iface->bss[0], settings); ++#else ++ return -1; ++#endif ++} ++ ++ + int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos) + { + struct csa_settings settings; + int ret = hostapd_parse_csa_settings(pos, &settings); + ++ if (!(wpa_s->ap_iface && wpa_s->ap_iface->bss[0]) && ++ !(wpa_s->ifmsh && wpa_s->ifmsh->bss[0])) ++ return -1; ++ ++ ret = __ap_ctrl_iface_chanswitch(wpa_s->ap_iface, &settings); + if (ret) + return ret; + +- return ap_switch_channel(wpa_s, &settings); ++ return __ap_ctrl_iface_chanswitch(wpa_s->ifmsh, &settings); + } + #endif /* CONFIG_CTRL_IFACE */ + diff --git a/recipes-connectivity/hostapd/files/350-nl80211_del_beacon_bss.patch b/recipes-connectivity/hostapd/files/350-nl80211_del_beacon_bss.patch new file mode 100644 index 0000000..998b2c8 --- /dev/null +++ b/recipes-connectivity/hostapd/files/350-nl80211_del_beacon_bss.patch @@ -0,0 +1,64 @@ +From c2031863a036db040f11a21b7093afb4e2322b91 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + src/drivers/driver_nl80211.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c +index d0f79ca4b..0cdcca66f 100644 +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -2721,10 +2721,15 @@ static int wpa_driver_nl80211_del_beacon(struct i802_bss *bss) + struct nl_msg *msg; + struct wpa_driver_nl80211_data *drv = bss->drv; + ++ if (!bss->beacon_set) ++ return 0; ++ ++ bss->beacon_set = 0; ++ + wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)", +- drv->ifindex); ++ bss->ifindex); + nl80211_put_wiphy_data_ap(bss); +- msg = nl80211_drv_msg(drv, 0, NL80211_CMD_DEL_BEACON); ++ msg = nl80211_bss_msg(bss, 0, NL80211_CMD_DEL_BEACON); + return send_and_recv_msgs(drv, msg, NULL, NULL); + } + +@@ -5042,7 +5047,7 @@ static void nl80211_teardown_ap(struct i802_bss *bss) + nl80211_mgmt_unsubscribe(bss, "AP teardown"); + + nl80211_put_wiphy_data_ap(bss); +- bss->beacon_set = 0; ++ wpa_driver_nl80211_del_beacon(bss); + } + + +@@ -7353,8 +7358,6 @@ static int wpa_driver_nl80211_if_remove(struct i802_bss *bss, + } else { + wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context"); + nl80211_teardown_ap(bss); +- if (!bss->added_if && !drv->first_bss->next) +- wpa_driver_nl80211_del_beacon(bss); + nl80211_destroy_bss(bss); + if (!bss->added_if) + i802_set_iface_flags(bss, 0); +@@ -7744,7 +7747,6 @@ static int wpa_driver_nl80211_deinit_ap(void *priv) + if (!is_ap_interface(drv->nlmode)) + return -1; + wpa_driver_nl80211_del_beacon(bss); +- bss->beacon_set = 0; + + /* + * If the P2P GO interface was dynamically added, then it is +@@ -7764,7 +7766,6 @@ static int wpa_driver_nl80211_stop_ap(void *priv) + if (!is_ap_interface(drv->nlmode)) + return -1; + wpa_driver_nl80211_del_beacon(bss); +- bss->beacon_set = 0; + return 0; + } + diff --git a/recipes-connectivity/hostapd/files/360-ctrl_iface_reload.patch b/recipes-connectivity/hostapd/files/360-ctrl_iface_reload.patch new file mode 100644 index 0000000..9a330ed --- /dev/null +++ b/recipes-connectivity/hostapd/files/360-ctrl_iface_reload.patch @@ -0,0 +1,119 @@ +From 4301f343aad50fc07a271d1bca6ec265089c607e Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + hostapd/ctrl_iface.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++ + src/ap/ctrl_iface_ap.c | 8 ++++++- + 2 files changed, 66 insertions(+), 1 deletion(-) + +diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c +index 0f6dfa13d..35c00bd0d 100644 +--- a/hostapd/ctrl_iface.c ++++ b/hostapd/ctrl_iface.c +@@ -60,6 +60,7 @@ + #include "fst/fst_ctrl_iface.h" + #include "config_file.h" + #include "ctrl_iface.h" ++#include "config_file.h" + + + #define HOSTAPD_CLI_DUP_VALUE_MAX_LEN 256 +@@ -78,6 +79,7 @@ static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level, + enum wpa_msg_type type, + const char *buf, size_t len); + ++static char *reload_opts = NULL; + + static int hostapd_ctrl_iface_attach(struct hostapd_data *hapd, + struct sockaddr_storage *from, +@@ -129,6 +131,61 @@ static int hostapd_ctrl_iface_new_sta(struct hostapd_data *hapd, + return 0; + } + ++static char *get_option(char *opt, char *str) ++{ ++ int len = strlen(str); ++ ++ if (!strncmp(opt, str, len)) ++ return opt + len; ++ else ++ return NULL; ++} ++ ++static struct hostapd_config *hostapd_ctrl_iface_config_read(const char *fname) ++{ ++ struct hostapd_config *conf; ++ char *opt, *val; ++ ++ conf = hostapd_config_read(fname); ++ if (!conf) ++ return NULL; ++ ++ for (opt = strtok(reload_opts, " "); ++ opt; ++ opt = strtok(NULL, " ")) { ++ ++ if ((val = get_option(opt, "channel="))) ++ conf->channel = atoi(val); ++ else if ((val = get_option(opt, "ht_capab="))) ++ conf->ht_capab = atoi(val); ++ else if ((val = get_option(opt, "ht_capab_mask="))) ++ conf->ht_capab &= atoi(val); ++ else if ((val = get_option(opt, "sec_chan="))) ++ conf->secondary_channel = atoi(val); ++ else if ((val = get_option(opt, "hw_mode="))) ++ conf->hw_mode = atoi(val); ++ else if ((val = get_option(opt, "ieee80211n="))) ++ conf->ieee80211n = atoi(val); ++ else ++ break; ++ } ++ ++ return conf; ++} ++ ++static int hostapd_ctrl_iface_update(struct hostapd_data *hapd, char *txt) ++{ ++ struct hostapd_config * (*config_read_cb)(const char *config_fname); ++ struct hostapd_iface *iface = hapd->iface; ++ ++ config_read_cb = iface->interfaces->config_read_cb; ++ iface->interfaces->config_read_cb = hostapd_ctrl_iface_config_read; ++ reload_opts = txt; ++ ++ hostapd_reload_config(iface); ++ ++ iface->interfaces->config_read_cb = config_read_cb; ++} + + #ifdef CONFIG_IEEE80211W + #ifdef NEED_AP_MLME +@@ -3195,6 +3252,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, + } else if (os_strncmp(buf, "VENDOR ", 7) == 0) { + reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply, + reply_size); ++ } else if (os_strncmp(buf, "UPDATE ", 7) == 0) { ++ hostapd_ctrl_iface_update(hapd, buf + 7); + } else if (os_strcmp(buf, "ERP_FLUSH") == 0) { + ieee802_1x_erp_flush(hapd); + #ifdef RADIUS_SERVER +diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c +index 2c4953d8b..1135e8151 100644 +--- a/src/ap/ctrl_iface_ap.c ++++ b/src/ap/ctrl_iface_ap.c +@@ -874,7 +874,13 @@ int hostapd_parse_csa_settings(const char *pos, + + int hostapd_ctrl_iface_stop_ap(struct hostapd_data *hapd) + { +- return hostapd_drv_stop_ap(hapd); ++ struct hostapd_iface *iface = hapd->iface; ++ int i; ++ ++ for (i = 0; i < iface->num_bss; i++) ++ hostapd_drv_stop_ap(iface->bss[i]); ++ ++ return 0; + } + + diff --git a/recipes-connectivity/hostapd/files/370-ap_sta_support.patch b/recipes-connectivity/hostapd/files/370-ap_sta_support.patch new file mode 100644 index 0000000..e4b2aaf --- /dev/null +++ b/recipes-connectivity/hostapd/files/370-ap_sta_support.patch @@ -0,0 +1,443 @@ +From 58cace2f15271782798fa574d27fd4a57b64729b Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + hostapd/ctrl_iface.c | 5 +++ + src/ap/beacon.c | 5 --- + src/drivers/driver.h | 2 ++ + src/drivers/driver_nl80211_event.c | 6 +++- + wpa_supplicant/Makefile | 6 ++++ + wpa_supplicant/bss.c | 14 ++++++++ + wpa_supplicant/bss.h | 4 +++ + wpa_supplicant/events.c | 58 ++++++++++++++++++++++++++++++- + wpa_supplicant/main.c | 8 +++-- + wpa_supplicant/wpa_supplicant.c | 70 ++++++++++++++++++++++++++++++++++++++ + wpa_supplicant/wpa_supplicant_i.h | 7 ++++ + 11 files changed, 176 insertions(+), 9 deletions(-) + +diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c +index 35c00bd0d..cc4f64226 100644 +--- a/hostapd/ctrl_iface.c ++++ b/hostapd/ctrl_iface.c +@@ -2408,6 +2408,11 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface, + if (ret) + return ret; + ++ if (os_strstr(pos, " auto-ht")) { ++ settings.freq_params.ht_enabled = iface->conf->ieee80211n; ++ settings.freq_params.vht_enabled = iface->conf->ieee80211ac; ++ } ++ + for (i = 0; i < iface->num_bss; i++) { + + /* Save CHAN_SWITCH VHT config */ +diff --git a/src/ap/beacon.c b/src/ap/beacon.c +index a51b94960..5039fc0e7 100644 +--- a/src/ap/beacon.c ++++ b/src/ap/beacon.c +@@ -1403,11 +1403,6 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd) + struct wpabuf *beacon, *proberesp, *assocresp; + int res, ret = -1; + +- if (hapd->csa_in_progress) { +- wpa_printf(MSG_ERROR, "Cannot set beacons during CSA period"); +- return -1; +- } +- + hapd->beacon_set_done = 1; + + if (ieee802_11_build_ap_params(hapd, ¶ms) < 0) +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index f35e3fdad..a383af19f 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -5478,6 +5478,7 @@ union wpa_event_data { + + /** + * struct ch_switch ++ * @count: Count until channel switch activates + * @freq: Frequency of new channel in MHz + * @ht_enabled: Whether this is an HT channel + * @ch_offset: Secondary channel offset +@@ -5486,6 +5487,7 @@ union wpa_event_data { + * @cf2: Center frequency 2 + */ + struct ch_switch { ++ int count; + int freq; + int ht_enabled; + int ch_offset; +diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c +index 7c1633066..f074e7ba5 100644 +--- a/src/drivers/driver_nl80211_event.c ++++ b/src/drivers/driver_nl80211_event.c +@@ -536,7 +536,7 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv, + struct nlattr *ifindex, struct nlattr *freq, + struct nlattr *type, struct nlattr *bw, + struct nlattr *cf1, struct nlattr *cf2, +- int finished) ++ struct nlattr *count, int finished) + { + struct i802_bss *bss; + union wpa_event_data data; +@@ -595,6 +595,8 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv, + data.ch_switch.cf1 = nla_get_u32(cf1); + if (cf2) + data.ch_switch.cf2 = nla_get_u32(cf2); ++ if (count) ++ data.ch_switch.count = nla_get_u32(count); + + if (finished) + bss->freq = data.ch_switch.freq; +@@ -2544,6 +2546,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, + tb[NL80211_ATTR_CHANNEL_WIDTH], + tb[NL80211_ATTR_CENTER_FREQ1], + tb[NL80211_ATTR_CENTER_FREQ2], ++ tb[NL80211_ATTR_CH_SWITCH_COUNT], + 0); + break; + case NL80211_CMD_CH_SWITCH_NOTIFY: +@@ -2554,6 +2557,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, + tb[NL80211_ATTR_CHANNEL_WIDTH], + tb[NL80211_ATTR_CENTER_FREQ1], + tb[NL80211_ATTR_CENTER_FREQ2], ++ NULL, + 1); + break; + case NL80211_CMD_DISCONNECT: +diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile +index 3d05870bd..d8e42fe2f 100644 +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -26,6 +26,10 @@ CFLAGS += $(EXTRA_CFLAGS) + CFLAGS += -I$(abspath ../src) + CFLAGS += -I$(abspath ../src/utils) + ++ifdef MULTICALL ++CFLAGS += -DMULTICALL ++endif ++ + -include .config + -include $(if $(MULTICALL),../hostapd/.config) + +@@ -116,6 +120,8 @@ OBJS_c += ../src/utils/common.o + OBJS_c += ../src/common/cli.o + OBJS += wmm_ac.o + ++OBJS += ../src/common/wpa_ctrl.o ++ + ifndef CONFIG_OS + ifdef CONFIG_NATIVE_WINDOWS + CONFIG_OS=win32 +diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c +index 441529cb0..e5dd06a80 100644 +--- a/wpa_supplicant/bss.c ++++ b/wpa_supplicant/bss.c +@@ -11,6 +11,7 @@ + #include "utils/common.h" + #include "utils/eloop.h" + #include "common/ieee802_11_defs.h" ++#include "common/ieee802_11_common.h" + #include "drivers/driver.h" + #include "eap_peer/eap.h" + #include "wpa_supplicant_i.h" +@@ -294,6 +295,10 @@ void calculate_update_time(const struct os_reltime *fetch_time, + static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src, + struct os_reltime *fetch_time) + { ++ struct ieee80211_ht_capabilities *capab; ++ struct ieee80211_ht_operation *oper; ++ struct ieee802_11_elems elems; ++ + dst->flags = src->flags; + os_memcpy(dst->bssid, src->bssid, ETH_ALEN); + dst->freq = src->freq; +@@ -306,6 +311,15 @@ static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src, + dst->est_throughput = src->est_throughput; + dst->snr = src->snr; + ++ memset(&elems, 0, sizeof(elems)); ++ ieee802_11_parse_elems((u8 *) (src + 1), src->ie_len, &elems, 0); ++ capab = (struct ieee80211_ht_capabilities *) elems.ht_capabilities; ++ oper = (struct ieee80211_ht_operation *) elems.ht_operation; ++ if (capab) ++ dst->ht_capab = le_to_host16(capab->ht_capabilities_info); ++ if (oper) ++ dst->ht_param = oper->ht_param; ++ + calculate_update_time(fetch_time, src->age, &dst->last_update); + } + +diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h +index 3ce8cd3f4..50c498612 100644 +--- a/wpa_supplicant/bss.h ++++ b/wpa_supplicant/bss.h +@@ -82,6 +82,10 @@ struct wpa_bss { + u8 ssid[SSID_MAX_LEN]; + /** Length of SSID */ + size_t ssid_len; ++ /** HT capabilities */ ++ u16 ht_capab; ++ /* Five octets of HT Operation Information */ ++ u8 ht_param; + /** Frequency of the channel in MHz (e.g., 2412 = channel 1) */ + int freq; + /** Beacon interval in TUs (host byte order) */ +diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c +index 067f76b48..7891f1ba1 100644 +--- a/wpa_supplicant/events.c ++++ b/wpa_supplicant/events.c +@@ -4184,6 +4184,60 @@ static void wpas_event_assoc_reject(struct wpa_supplicant *wpa_s, + } + + ++static void ++supplicant_ch_switch_started(struct wpa_supplicant *wpa_s, ++ union wpa_event_data *data) ++{ ++ char buf[256]; ++ size_t len = sizeof(buf); ++ char *cmd = NULL; ++ int width = 20; ++ int ret; ++ ++ if (!wpa_s->hostapd) ++ return; ++ ++ wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CHANNEL_SWITCH ++ "count=%d freq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d", ++ data->ch_switch.count, ++ data->ch_switch.freq, ++ data->ch_switch.ht_enabled, ++ data->ch_switch.ch_offset, ++ channel_width_to_string(data->ch_switch.ch_width), ++ data->ch_switch.cf1, ++ data->ch_switch.cf2); ++ ++ switch (data->ch_switch.ch_width) { ++ case CHAN_WIDTH_20_NOHT: ++ case CHAN_WIDTH_20: ++ width = 20; ++ break; ++ case CHAN_WIDTH_40: ++ width = 40; ++ break; ++ case CHAN_WIDTH_80: ++ width = 80; ++ break; ++ case CHAN_WIDTH_160: ++ case CHAN_WIDTH_80P80: ++ width = 160; ++ break; ++ } ++ ++ asprintf(&cmd, "CHAN_SWITCH %d %d sec_channel_offset=%d center_freq1=%d center_freq2=%d, bandwidth=%d auto-ht\n", ++ data->ch_switch.count - 1, ++ data->ch_switch.freq, ++ data->ch_switch.ch_offset, ++ data->ch_switch.cf1, ++ data->ch_switch.cf2, ++ width); ++ ret = wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL); ++ free(cmd); ++ ++ if (ret < 0) ++ wpa_printf(MSG_ERROR, "\nFailed to reload hostapd AP interfaces\n"); ++} ++ + void supplicant_event(void *ctx, enum wpa_event_type event, + union wpa_event_data *data) + { +@@ -4485,8 +4539,10 @@ void supplicant_event(void *ctx, enum wpa_event_type event, + channel_width_to_string(data->ch_switch.ch_width), + data->ch_switch.cf1, + data->ch_switch.cf2); +- if (event == EVENT_CH_SWITCH_STARTED) ++ if (event == EVENT_CH_SWITCH_STARTED) { ++ supplicant_ch_switch_started(wpa_s, data); + break; ++ } + + wpa_s->assoc_freq = data->ch_switch.freq; + wpa_s->current_ssid->frequency = data->ch_switch.freq; +diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c +index 51a8a0298..669f5b0b6 100644 +--- a/wpa_supplicant/main.c ++++ b/wpa_supplicant/main.c +@@ -34,7 +34,7 @@ static void usage(void) + "vW] [-P] " + "[-g] \\\n" + " [-G] \\\n" +- " -i -c [-C] [-D] " ++ " -i -c [-C] [-D] [-H] " + "[-p] \\\n" + " [-b] [-e]" + #ifdef CONFIG_DEBUG_FILE +@@ -74,6 +74,7 @@ static void usage(void) + " -g = global ctrl_interface\n" + " -G = global ctrl_interface group\n" + " -h = show this help text\n" ++ " -H = connect to a hostapd instance to manage state changes\n" + " -i = interface name\n" + " -I = additional configuration file\n" + " -K = include keys (passwords, etc.) in debug output\n" +@@ -201,7 +202,7 @@ int main(int argc, char *argv[]) + + for (;;) { + c = getopt(argc, argv, +- "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuvW"); ++ "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuvW"); + if (c < 0) + break; + switch (c) { +@@ -248,6 +249,9 @@ int main(int argc, char *argv[]) + usage(); + exitcode = 0; + goto out; ++ case 'H': ++ iface->hostapd_ctrl = optarg; ++ break; + case 'i': + iface->ifname = optarg; + break; +diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c +index 92ddbe458..c91a5ab10 100644 +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -127,6 +127,55 @@ static void wpas_update_fils_connect_params(struct wpa_supplicant *wpa_s); + #endif /* CONFIG_FILS && IEEE8021X_EAPOL */ + + ++static int hostapd_stop(struct wpa_supplicant *wpa_s) ++{ ++ const char *cmd = "STOP_AP"; ++ char buf[256]; ++ size_t len = sizeof(buf); ++ ++ if (wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL) < 0) { ++ wpa_printf(MSG_ERROR, "\nFailed to stop hostapd AP interfaces\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int hostapd_reload(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) ++{ ++ char *cmd = NULL; ++ char buf[256]; ++ size_t len = sizeof(buf); ++ enum hostapd_hw_mode hw_mode; ++ u8 channel; ++ int sec_chan = 0; ++ int ret; ++ ++ if (!bss) ++ return -1; ++ ++ if (bss->ht_param & HT_INFO_HT_PARAM_STA_CHNL_WIDTH) { ++ int sec = bss->ht_param & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK; ++ if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE) ++ sec_chan = 1; ++ else if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW) ++ sec_chan = -1; ++ } ++ ++ hw_mode = ieee80211_freq_to_chan(bss->freq, &channel); ++ if (asprintf(&cmd, "UPDATE channel=%d sec_chan=%d hw_mode=%d", ++ channel, sec_chan, hw_mode) < 0) ++ return -1; ++ ++ ret = wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL); ++ free(cmd); ++ ++ if (ret < 0) { ++ wpa_printf(MSG_ERROR, "\nFailed to reload hostapd AP interfaces\n"); ++ return -1; ++ } ++ return 0; ++} ++ + /* Configure default/group WEP keys for static WEP */ + int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) + { +@@ -940,12 +989,16 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, + + sme_sched_obss_scan(wpa_s, 1); + ++ if (wpa_s->hostapd) ++ hostapd_reload(wpa_s, wpa_s->current_bss); + #if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL) + if (!fils_hlp_sent && ssid && ssid->eap.erp) + wpas_update_fils_connect_params(wpa_s); + #endif /* CONFIG_FILS && IEEE8021X_EAPOL */ + } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING || + state == WPA_ASSOCIATED) { ++ if (wpa_s->hostapd) ++ hostapd_stop(wpa_s); + wpa_s->new_connection = 1; + wpa_drv_set_operstate(wpa_s, 0); + #ifndef IEEE8021X_EAPOL +@@ -2038,6 +2091,8 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, + wpa_ssid_txt(ssid->ssid, ssid->ssid_len), + ssid->id); + wpas_notify_mesh_group_started(wpa_s, ssid); ++ if (wpa_s->hostapd) ++ hostapd_reload(wpa_s, wpa_s->current_bss); + #else /* CONFIG_MESH */ + wpa_msg(wpa_s, MSG_ERROR, + "mesh mode support not included in the build"); +@@ -5716,6 +5771,16 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, + sizeof(wpa_s->bridge_ifname)); + } + ++ if (iface->hostapd_ctrl) { ++ wpa_s->hostapd = wpa_ctrl_open(iface->hostapd_ctrl); ++ if (!wpa_s->hostapd) { ++ wpa_printf(MSG_ERROR, "\nFailed to connect to hostapd\n"); ++ return -1; ++ } ++ if (hostapd_stop(wpa_s) < 0) ++ return -1; ++ } ++ + /* RSNA Supplicant Key Management - INITIALIZE */ + eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE); + eapol_sm_notify_portValid(wpa_s->eapol, FALSE); +@@ -6043,6 +6108,11 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s, + if (terminate) + wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING); + ++ if (wpa_s->hostapd) { ++ wpa_ctrl_close(wpa_s->hostapd); ++ wpa_s->hostapd = NULL; ++ } ++ + if (wpa_s->ctrl_iface) { + wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface); + wpa_s->ctrl_iface = NULL; +diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h +index 8a4bdf8cb..f89dd6059 100644 +--- a/wpa_supplicant/wpa_supplicant_i.h ++++ b/wpa_supplicant/wpa_supplicant_i.h +@@ -101,6 +101,11 @@ struct wpa_interface { + const char *ifname; + + /** ++ * hostapd_ctrl - path to hostapd control socket for notification ++ */ ++ const char *hostapd_ctrl; ++ ++ /** + * bridge_ifname - Optional bridge interface name + * + * If the driver interface (ifname) is included in a Linux bridge +@@ -516,6 +521,8 @@ struct wpa_supplicant { + #endif /* CONFIG_CTRL_IFACE_BINDER */ + char bridge_ifname[16]; + ++ struct wpa_ctrl *hostapd; ++ + char *confname; + char *confanother; + diff --git a/recipes-connectivity/hostapd/files/380-disable_ctrl_iface_mib.patch b/recipes-connectivity/hostapd/files/380-disable_ctrl_iface_mib.patch new file mode 100644 index 0000000..b1f70e7 --- /dev/null +++ b/recipes-connectivity/hostapd/files/380-disable_ctrl_iface_mib.patch @@ -0,0 +1,227 @@ +From f890ab993069f8737125bcf24d99f441759e7b63 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + hostapd/Makefile | 3 +++ + hostapd/ctrl_iface.c | 2 ++ + src/ap/ctrl_iface_ap.c | 6 ++++-- + src/ap/ieee802_1x.c | 2 ++ + src/ap/wpa_auth.c | 3 ++- + src/rsn_supp/wpa.c | 3 +++ + wpa_supplicant/Makefile | 3 +++ + wpa_supplicant/ap.c | 2 +- + wpa_supplicant/ctrl_iface.c | 8 +++++++- + 9 files changed, 27 insertions(+), 5 deletions(-) + +diff --git a/hostapd/Makefile b/hostapd/Makefile +index da8f9bc9b..94ffc1a66 100644 +--- a/hostapd/Makefile ++++ b/hostapd/Makefile +@@ -220,6 +220,9 @@ endif + ifdef CONFIG_NO_CTRL_IFACE + CFLAGS += -DCONFIG_NO_CTRL_IFACE + else ++ifdef CONFIG_CTRL_IFACE_MIB ++CFLAGS += -DCONFIG_CTRL_IFACE_MIB ++endif + ifeq ($(CONFIG_CTRL_IFACE), udp) + CFLAGS += -DCONFIG_CTRL_IFACE_UDP + else +diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c +index cc4f64226..ef24ebb74 100644 +--- a/hostapd/ctrl_iface.c ++++ b/hostapd/ctrl_iface.c +@@ -3020,6 +3020,7 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, + reply_size); + } else if (os_strcmp(buf, "STATUS-DRIVER") == 0) { + reply_len = hostapd_drv_status(hapd, reply, reply_size); ++#ifdef CONFIG_CTRL_IFACE_MIB + } else if (os_strcmp(buf, "MIB") == 0) { + reply_len = ieee802_11_get_mib(hapd, reply, reply_size); + if (reply_len >= 0) { +@@ -3061,6 +3062,7 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, + } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { + reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply, + reply_size); ++#endif + } else if (os_strcmp(buf, "ATTACH") == 0) { + if (hostapd_ctrl_iface_attach(hapd, from, fromlen, NULL)) + reply_len = -1; +diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c +index 1135e8151..a1000e34a 100644 +--- a/src/ap/ctrl_iface_ap.c ++++ b/src/ap/ctrl_iface_ap.c +@@ -25,6 +25,7 @@ + #include "mbo_ap.h" + #include "taxonomy.h" + ++#ifdef CONFIG_CTRL_IFACE_MIB + + static size_t hostapd_write_ht_mcs_bitmask(char *buf, size_t buflen, + size_t curr_len, const u8 *mcs_set) +@@ -423,6 +424,7 @@ int hostapd_ctrl_iface_sta_next(struct hostapd_data *hapd, const char *txtaddr, + return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen); + } + ++#endif + + #ifdef CONFIG_P2P_MANAGER + static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype, +@@ -763,12 +765,12 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf, + return len; + len += ret; + } +- ++#ifdef CONFIG_CTRL_IFACE_MIB + if (iface->conf->ieee80211n && !hapd->conf->disable_11n && mode) { + len = hostapd_write_ht_mcs_bitmask(buf, buflen, len, + mode->mcs_set); + } +- ++#endif /* CONFIG_CTRL_IFACE_MIB */ + if (iface->current_rates && iface->num_rates) { + ret = os_snprintf(buf + len, buflen - len, "supported_rates="); + if (os_snprintf_error(buflen - len, ret)) +diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c +index e0614710f..292cd4bc8 100644 +--- a/src/ap/ieee802_1x.c ++++ b/src/ap/ieee802_1x.c +@@ -2706,6 +2706,7 @@ static const char * bool_txt(Boolean val) + return val ? "TRUE" : "FALSE"; + } + ++#ifdef CONFIG_CTRL_IFACE_MIB + + int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen) + { +@@ -2892,6 +2893,7 @@ int ieee802_1x_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta, + return len; + } + ++#endif + + #ifdef CONFIG_HS20 + static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx) +diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c +index c56077001..cb6595f2c 100644 +--- a/src/ap/wpa_auth.c ++++ b/src/ap/wpa_auth.c +@@ -4116,6 +4116,7 @@ static const char * wpa_bool_txt(int val) + return val ? "TRUE" : "FALSE"; + } + ++#ifdef CONFIG_CTRL_IFACE_MIB + + #define RSN_SUITE "%02x-%02x-%02x-%d" + #define RSN_SUITE_ARG(s) \ +@@ -4264,7 +4265,7 @@ int wpa_get_mib_sta(struct wpa_state_machine *sm, char *buf, size_t buflen) + + return len; + } +- ++#endif + + void wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth) + { +diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c +index c929e8194..39dcecd17 100644 +--- a/src/rsn_supp/wpa.c ++++ b/src/rsn_supp/wpa.c +@@ -2502,6 +2502,8 @@ static u32 wpa_key_mgmt_suite(struct wpa_sm *sm) + } + + ++#ifdef CONFIG_CTRL_IFACE_MIB ++ + #define RSN_SUITE "%02x-%02x-%02x-%d" + #define RSN_SUITE_ARG(s) \ + ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff +@@ -2585,6 +2587,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen) + + return (int) len; + } ++#endif + #endif /* CONFIG_CTRL_IFACE */ + + +diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile +index d8e42fe2f..3ee2d6eff 100644 +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -957,6 +957,9 @@ ifdef CONFIG_FILS + OBJS += ../src/ap/fils_hlp.o + endif + ifdef CONFIG_CTRL_IFACE ++ifdef CONFIG_CTRL_IFACE_MIB ++CFLAGS += -DCONFIG_CTRL_IFACE_MIB ++endif + OBJS += ../src/ap/ctrl_iface_ap.o + endif + +diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c +index 5af4be230..5b30c3e3d 100644 +--- a/wpa_supplicant/ap.c ++++ b/wpa_supplicant/ap.c +@@ -1236,7 +1236,7 @@ int wpas_ap_wps_nfc_report_handover(struct wpa_supplicant *wpa_s, + #endif /* CONFIG_WPS */ + + +-#ifdef CONFIG_CTRL_IFACE ++#if defined(CONFIG_CTRL_IFACE) && defined(CONFIG_CTRL_IFACE_MIB) + + int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s, + char *buf, size_t buflen) +diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c +index 8efc08d4d..a328b877b 100644 +--- a/wpa_supplicant/ctrl_iface.c ++++ b/wpa_supplicant/ctrl_iface.c +@@ -2144,7 +2144,7 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, + pos += ret; + } + +-#ifdef CONFIG_AP ++#if defined(CONFIG_AP) && defined(CONFIG_CTRL_IFACE_MIB) + if (wpa_s->ap_iface) { + pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos, + end - pos, +@@ -9962,6 +9962,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, + reply_len = -1; + } else if (os_strncmp(buf, "NOTE ", 5) == 0) { + wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); ++#ifdef CONFIG_CTRL_IFACE_MIB + } else if (os_strcmp(buf, "MIB") == 0) { + reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); + if (reply_len >= 0) { +@@ -9974,6 +9975,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, + reply_size - reply_len); + #endif /* CONFIG_MACSEC */ + } ++#endif + } else if (os_strncmp(buf, "STATUS", 6) == 0) { + reply_len = wpa_supplicant_ctrl_iface_status( + wpa_s, buf + 6, reply, reply_size); +@@ -10458,6 +10460,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, + reply_len = wpa_supplicant_ctrl_iface_bss( + wpa_s, buf + 4, reply, reply_size); + #ifdef CONFIG_AP ++#ifdef CONFIG_CTRL_IFACE_MIB + } else if (os_strcmp(buf, "STA-FIRST") == 0) { + reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); + } else if (os_strncmp(buf, "STA ", 4) == 0) { +@@ -10466,12 +10469,15 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, + } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { + reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, + reply_size); ++#endif ++#ifdef CONFIG_CTRL_IFACE_MIB + } else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) { + if (ap_ctrl_iface_sta_deauthenticate(wpa_s, buf + 15)) + reply_len = -1; + } else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) { + if (ap_ctrl_iface_sta_disassociate(wpa_s, buf + 13)) + reply_len = -1; ++#endif + } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) { + if (ap_ctrl_iface_chanswitch(wpa_s, buf + 12)) + reply_len = -1; diff --git a/recipes-connectivity/hostapd/files/381-hostapd_cli_UNKNOWN-COMMAND.patch b/recipes-connectivity/hostapd/files/381-hostapd_cli_UNKNOWN-COMMAND.patch new file mode 100644 index 0000000..4872a20 --- /dev/null +++ b/recipes-connectivity/hostapd/files/381-hostapd_cli_UNKNOWN-COMMAND.patch @@ -0,0 +1,21 @@ +From c4df803ed65c86cd50fb462ed81d58bd57ae781e Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + hostapd/hostapd_cli.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c +index 046024390..14d3fd9f0 100644 +--- a/hostapd/hostapd_cli.c ++++ b/hostapd/hostapd_cli.c +@@ -743,7 +743,7 @@ static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, const char *cmd, + } + + buf[len] = '\0'; +- if (memcmp(buf, "FAIL", 4) == 0) ++ if (memcmp(buf, "FAIL", 4) == 0 || memcmp(buf, "UNKNOWN COMMAND", 15) == 0) + return -1; + if (print) + printf("%s", buf); diff --git a/recipes-connectivity/hostapd/files/390-wpa_ie_cap_workaround.patch b/recipes-connectivity/hostapd/files/390-wpa_ie_cap_workaround.patch new file mode 100644 index 0000000..ba769db --- /dev/null +++ b/recipes-connectivity/hostapd/files/390-wpa_ie_cap_workaround.patch @@ -0,0 +1,66 @@ +From 8dd311e8023bbceda50d21698f795f2e654bd038 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + src/common/wpa_common.c | 40 ++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 38 insertions(+), 2 deletions(-) + +diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c +index 64e5c5f4c..da1a148b9 100644 +--- a/src/common/wpa_common.c ++++ b/src/common/wpa_common.c +@@ -2089,6 +2089,31 @@ u32 wpa_akm_to_suite(int akm) + } + + ++static void wpa_fixup_wpa_ie_rsn(u8 *assoc_ie, const u8 *wpa_msg_ie, ++ size_t rsn_ie_len) ++{ ++ int pos, count; ++ ++ pos = sizeof(struct rsn_ie_hdr) + RSN_SELECTOR_LEN; ++ if (rsn_ie_len < pos + 2) ++ return; ++ ++ count = WPA_GET_LE16(wpa_msg_ie + pos); ++ pos += 2 + count * RSN_SELECTOR_LEN; ++ if (rsn_ie_len < pos + 2) ++ return; ++ ++ count = WPA_GET_LE16(wpa_msg_ie + pos); ++ pos += 2 + count * RSN_SELECTOR_LEN; ++ if (rsn_ie_len < pos + 2) ++ return; ++ ++ if (!assoc_ie[pos] && !assoc_ie[pos + 1] && ++ (wpa_msg_ie[pos] || wpa_msg_ie[pos + 1])) ++ memcpy(&assoc_ie[pos], &wpa_msg_ie[pos], 2); ++} ++ ++ + int wpa_compare_rsn_ie(int ft_initial_assoc, + const u8 *ie1, size_t ie1len, + const u8 *ie2, size_t ie2len) +@@ -2096,8 +2121,19 @@ int wpa_compare_rsn_ie(int ft_initial_assoc, + if (ie1 == NULL || ie2 == NULL) + return -1; + +- if (ie1len == ie2len && os_memcmp(ie1, ie2, ie1len) == 0) +- return 0; /* identical IEs */ ++ if (ie1len == ie2len) { ++ u8 *ie_tmp; ++ ++ if (os_memcmp(ie1, ie2, ie1len) == 0) ++ return 0; /* identical IEs */ ++ ++ ie_tmp = alloca(ie1len); ++ memcpy(ie_tmp, ie1, ie1len); ++ wpa_fixup_wpa_ie_rsn(ie_tmp, ie2, ie1len); ++ ++ if (os_memcmp(ie_tmp, ie2, ie1len) == 0) ++ return 0; /* only mismatch in RSN capabilties */ ++ } + + #ifdef CONFIG_IEEE80211R + if (ft_initial_assoc) { diff --git a/recipes-connectivity/hostapd/files/400-wps_single_auth_enc_type.patch b/recipes-connectivity/hostapd/files/400-wps_single_auth_enc_type.patch new file mode 100644 index 0000000..3ce4bb3 --- /dev/null +++ b/recipes-connectivity/hostapd/files/400-wps_single_auth_enc_type.patch @@ -0,0 +1,32 @@ +From aa9509512105dc95a3091696d7305900d701be03 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + src/ap/wps_hostapd.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c +index 6161cdbdb..4a0302043 100644 +--- a/src/ap/wps_hostapd.c ++++ b/src/ap/wps_hostapd.c +@@ -346,8 +346,7 @@ static int hapd_wps_reconfig_in_memory(struct hostapd_data *hapd, + bss->wpa_pairwise |= WPA_CIPHER_GCMP; + else + bss->wpa_pairwise |= WPA_CIPHER_CCMP; +- } +- if (cred->encr_type & WPS_ENCR_TKIP) ++ } else if (cred->encr_type & WPS_ENCR_TKIP) + bss->wpa_pairwise |= WPA_CIPHER_TKIP; + bss->rsn_pairwise = bss->wpa_pairwise; + bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa, +@@ -1108,8 +1107,7 @@ int hostapd_init_wps(struct hostapd_data *hapd, + WPA_CIPHER_GCMP_256)) { + wps->encr_types |= WPS_ENCR_AES; + wps->encr_types_rsn |= WPS_ENCR_AES; +- } +- if (conf->rsn_pairwise & WPA_CIPHER_TKIP) { ++ } else if (conf->rsn_pairwise & WPA_CIPHER_TKIP) { + wps->encr_types |= WPS_ENCR_TKIP; + wps->encr_types_rsn |= WPS_ENCR_TKIP; + } diff --git a/recipes-connectivity/hostapd/files/410-limit_debug_messages.patch b/recipes-connectivity/hostapd/files/410-limit_debug_messages.patch new file mode 100644 index 0000000..a9e9c9a --- /dev/null +++ b/recipes-connectivity/hostapd/files/410-limit_debug_messages.patch @@ -0,0 +1,227 @@ +From 7b5795055ae75d37753933b2cc7b5b10185fc70a Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + src/utils/wpa_debug.c | 40 ++++++----------------------- + src/utils/wpa_debug.h | 69 ++++++++++++++++++++++++++++++++++++++++++++------- + 2 files changed, 67 insertions(+), 42 deletions(-) + +diff --git a/src/utils/wpa_debug.c b/src/utils/wpa_debug.c +index c336e5389..334f22d72 100644 +--- a/src/utils/wpa_debug.c ++++ b/src/utils/wpa_debug.c +@@ -206,7 +206,7 @@ void wpa_debug_close_linux_tracing(void) + * + * Note: New line '\n' is added to the end of the text when printing to stdout. + */ +-void wpa_printf(int level, const char *fmt, ...) ++void _wpa_printf(int level, const char *fmt, ...) + { + va_list ap; + +@@ -253,8 +253,8 @@ void wpa_printf(int level, const char *fmt, ...) + } + + +-static void _wpa_hexdump(int level, const char *title, const u8 *buf, +- size_t len, int show) ++void _wpa_hexdump(int level, const char *title, const u8 *buf, ++ size_t len, int show) + { + size_t i; + +@@ -380,20 +380,8 @@ static void _wpa_hexdump(int level, const char *title, const u8 *buf, + #endif /* CONFIG_ANDROID_LOG */ + } + +-void wpa_hexdump(int level, const char *title, const void *buf, size_t len) +-{ +- _wpa_hexdump(level, title, buf, len, 1); +-} +- +- +-void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len) +-{ +- _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys); +-} +- +- +-static void _wpa_hexdump_ascii(int level, const char *title, const void *buf, +- size_t len, int show) ++void _wpa_hexdump_ascii(int level, const char *title, const void *buf, ++ size_t len, int show) + { + size_t i, llen; + const u8 *pos = buf; +@@ -506,20 +494,6 @@ static void _wpa_hexdump_ascii(int level, const char *title, const void *buf, + } + + +-void wpa_hexdump_ascii(int level, const char *title, const void *buf, +- size_t len) +-{ +- _wpa_hexdump_ascii(level, title, buf, len, 1); +-} +- +- +-void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, +- size_t len) +-{ +- _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); +-} +- +- + #ifdef CONFIG_DEBUG_FILE + static char *last_path = NULL; + #endif /* CONFIG_DEBUG_FILE */ +@@ -635,7 +609,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func) + } + + +-void wpa_msg(void *ctx, int level, const char *fmt, ...) ++void _wpa_msg(void *ctx, int level, const char *fmt, ...) + { + va_list ap; + char *buf; +@@ -673,7 +647,7 @@ void wpa_msg(void *ctx, int level, const char *fmt, ...) + } + + +-void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) ++void _wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) + { + va_list ap; + char *buf; +diff --git a/src/utils/wpa_debug.h b/src/utils/wpa_debug.h +index 1fe0b7db7..8a685a164 100644 +--- a/src/utils/wpa_debug.h ++++ b/src/utils/wpa_debug.h +@@ -52,6 +52,17 @@ int wpa_debug_reopen_file(void); + void wpa_debug_close_file(void); + void wpa_debug_setup_stdout(void); + ++/* internal */ ++void _wpa_hexdump(int level, const char *title, const u8 *buf, ++ size_t len, int show); ++void _wpa_hexdump_ascii(int level, const char *title, const void *buf, ++ size_t len, int show); ++extern int wpa_debug_show_keys; ++ ++#ifndef CONFIG_MSG_MIN_PRIORITY ++#define CONFIG_MSG_MIN_PRIORITY 0 ++#endif ++ + /** + * wpa_debug_printf_timestamp - Print timestamp for debug output + * +@@ -72,9 +83,15 @@ void wpa_debug_print_timestamp(void); + * + * Note: New line '\n' is added to the end of the text when printing to stdout. + */ +-void wpa_printf(int level, const char *fmt, ...) ++void _wpa_printf(int level, const char *fmt, ...) + PRINTF_FORMAT(2, 3); + ++#define wpa_printf(level, ...) \ ++ do { \ ++ if (level >= CONFIG_MSG_MIN_PRIORITY) \ ++ _wpa_printf(level, __VA_ARGS__); \ ++ } while(0) ++ + /** + * wpa_hexdump - conditional hex dump + * @level: priority level (MSG_*) of the message +@@ -86,7 +103,13 @@ PRINTF_FORMAT(2, 3); + * output may be directed to stdout, stderr, and/or syslog based on + * configuration. The contents of buf is printed out has hex dump. + */ +-void wpa_hexdump(int level, const char *title, const void *buf, size_t len); ++static inline void wpa_hexdump(int level, const char *title, const void *buf, size_t len) ++{ ++ if (level < CONFIG_MSG_MIN_PRIORITY) ++ return; ++ ++ _wpa_hexdump(level, title, buf, len, 1); ++} + + static inline void wpa_hexdump_buf(int level, const char *title, + const struct wpabuf *buf) +@@ -108,7 +131,13 @@ static inline void wpa_hexdump_buf(int level, const char *title, + * like wpa_hexdump(), but by default, does not include secret keys (passwords, + * etc.) in debug output. + */ +-void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len); ++static inline void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len) ++{ ++ if (level < CONFIG_MSG_MIN_PRIORITY) ++ return; ++ ++ _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys); ++} + + static inline void wpa_hexdump_buf_key(int level, const char *title, + const struct wpabuf *buf) +@@ -130,8 +159,14 @@ static inline void wpa_hexdump_buf_key(int level, const char *title, + * the hex numbers and ASCII characters (for printable range) are shown. 16 + * bytes per line will be shown. + */ +-void wpa_hexdump_ascii(int level, const char *title, const void *buf, +- size_t len); ++static inline void wpa_hexdump_ascii(int level, const char *title, ++ const u8 *buf, size_t len) ++{ ++ if (level < CONFIG_MSG_MIN_PRIORITY) ++ return; ++ ++ _wpa_hexdump_ascii(level, title, buf, len, 1); ++} + + /** + * wpa_hexdump_ascii_key - conditional hex dump, hide keys +@@ -147,8 +182,14 @@ void wpa_hexdump_ascii(int level, const char *title, const void *buf, + * bytes per line will be shown. This works like wpa_hexdump_ascii(), but by + * default, does not include secret keys (passwords, etc.) in debug output. + */ +-void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, +- size_t len); ++static inline void wpa_hexdump_ascii_key(int level, const char *title, ++ const u8 *buf, size_t len) ++{ ++ if (level < CONFIG_MSG_MIN_PRIORITY) ++ return; ++ ++ _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); ++} + + /* + * wpa_dbg() behaves like wpa_msg(), but it can be removed from build to reduce +@@ -185,7 +226,12 @@ void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, + * + * Note: New line '\n' is added to the end of the text when printing to stdout. + */ +-void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); ++void _wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); ++#define wpa_msg(ctx, level, ...) \ ++ do { \ ++ if (level >= CONFIG_MSG_MIN_PRIORITY) \ ++ _wpa_msg(ctx, level, __VA_ARGS__); \ ++ } while(0) + + /** + * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors +@@ -199,8 +245,13 @@ void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); + * attached ctrl_iface monitors. In other words, it can be used for frequent + * events that do not need to be sent to syslog. + */ +-void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) ++void _wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) + PRINTF_FORMAT(3, 4); ++#define wpa_msg_ctrl(ctx, level, ...) \ ++ do { \ ++ if (level >= CONFIG_MSG_MIN_PRIORITY) \ ++ _wpa_msg_ctrl(ctx, level, __VA_ARGS__); \ ++ } while(0) + + /** + * wpa_msg_global - Global printf for ctrl_iface monitors diff --git a/recipes-connectivity/hostapd/files/420-indicate-features.patch b/recipes-connectivity/hostapd/files/420-indicate-features.patch new file mode 100644 index 0000000..cd0963f --- /dev/null +++ b/recipes-connectivity/hostapd/files/420-indicate-features.patch @@ -0,0 +1,75 @@ +From d2c20f1a0dd228fcfaa36bb9fdd1e38148e7b145 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + hostapd/main.c | 5 ++++- + wpa_supplicant/main.c | 11 ++++++++--- + 2 files changed, 12 insertions(+), 4 deletions(-) + +diff --git a/hostapd/main.c b/hostapd/main.c +index 90424d5bd..4b537f35a 100644 +--- a/hostapd/main.c ++++ b/hostapd/main.c +@@ -15,6 +15,7 @@ + #include "utils/common.h" + #include "utils/eloop.h" + #include "utils/uuid.h" ++#include "utils/build_features.h" + #include "crypto/random.h" + #include "crypto/tls.h" + #include "common/version.h" +@@ -690,7 +691,7 @@ int main(int argc, char *argv[]) + wpa_supplicant_event = hostapd_wpa_event; + wpa_supplicant_event_global = hostapd_wpa_event_global; + for (;;) { +- c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:vg:G:"); ++ c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:g:G:v::"); + if (c < 0) + break; + switch (c) { +@@ -727,6 +728,8 @@ int main(int argc, char *argv[]) + break; + #endif /* CONFIG_DEBUG_LINUX_TRACING */ + case 'v': ++ if (optarg) ++ exit(!has_feature(optarg)); + show_version(); + exit(1); + break; +diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c +index 669f5b0b6..3d7f1ba6e 100644 +--- a/wpa_supplicant/main.c ++++ b/wpa_supplicant/main.c +@@ -12,6 +12,7 @@ + #endif /* __linux__ */ + + #include "common.h" ++#include "build_features.h" + #include "fst/fst.h" + #include "wpa_supplicant_i.h" + #include "driver_i.h" +@@ -202,7 +203,7 @@ int main(int argc, char *argv[]) + + for (;;) { + c = getopt(argc, argv, +- "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuvW"); ++ "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuv::W"); + if (c < 0) + break; + switch (c) { +@@ -305,8 +306,12 @@ int main(int argc, char *argv[]) + break; + #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ + case 'v': +- printf("%s\n", wpa_supplicant_version); +- exitcode = 0; ++ if (optarg) { ++ exitcode = !has_feature(optarg); ++ } else { ++ printf("%s\n", wpa_supplicant_version); ++ exitcode = 0; ++ } + goto out; + case 'W': + params.wait_for_monitor++; diff --git a/recipes-connectivity/hostapd/files/430-hostapd_cli_ifdef.patch b/recipes-connectivity/hostapd/files/430-hostapd_cli_ifdef.patch new file mode 100644 index 0000000..f266864 --- /dev/null +++ b/recipes-connectivity/hostapd/files/430-hostapd_cli_ifdef.patch @@ -0,0 +1,68 @@ +From 0c14b6a7fc8ebce22da7e09d9e2761ccabcc58b8 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + hostapd/hostapd_cli.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c +index 14d3fd9f0..7ede2bdb7 100644 +--- a/hostapd/hostapd_cli.c ++++ b/hostapd/hostapd_cli.c +@@ -385,7 +385,6 @@ static int hostapd_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc, + } + + +-#ifdef CONFIG_TAXONOMY + static int hostapd_cli_cmd_signature(struct wpa_ctrl *ctrl, int argc, + char *argv[]) + { +@@ -398,7 +397,6 @@ static int hostapd_cli_cmd_signature(struct wpa_ctrl *ctrl, int argc, + os_snprintf(buf, sizeof(buf), "SIGNATURE %s", argv[0]); + return wpa_ctrl_command(ctrl, buf); + } +-#endif /* CONFIG_TAXONOMY */ + + + #ifdef CONFIG_IEEE80211W +@@ -417,7 +415,6 @@ static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc, + #endif /* CONFIG_IEEE80211W */ + + +-#ifdef CONFIG_WPS + static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, + char *argv[]) + { +@@ -643,7 +640,6 @@ static int hostapd_cli_cmd_wps_config(struct wpa_ctrl *ctrl, int argc, + ssid_hex, argv[1]); + return wpa_ctrl_command(ctrl, buf); + } +-#endif /* CONFIG_WPS */ + + + static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc, +@@ -1538,15 +1534,12 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = { + { "disassociate", hostapd_cli_cmd_disassociate, + hostapd_complete_stations, + " = disassociate a station" }, +-#ifdef CONFIG_TAXONOMY + { "signature", hostapd_cli_cmd_signature, hostapd_complete_stations, + " = get taxonomy signature for a station" }, +-#endif /* CONFIG_TAXONOMY */ + #ifdef CONFIG_IEEE80211W + { "sa_query", hostapd_cli_cmd_sa_query, hostapd_complete_stations, + " = send SA Query to a station" }, + #endif /* CONFIG_IEEE80211W */ +-#ifdef CONFIG_WPS + { "wps_pin", hostapd_cli_cmd_wps_pin, NULL, + " [timeout] [addr] = add WPS Enrollee PIN" }, + { "wps_check_pin", hostapd_cli_cmd_wps_check_pin, NULL, +@@ -1571,7 +1564,6 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = { + " = configure AP" }, + { "wps_get_status", hostapd_cli_cmd_wps_get_status, NULL, + "= show current WPS status" }, +-#endif /* CONFIG_WPS */ + { "disassoc_imminent", hostapd_cli_cmd_disassoc_imminent, NULL, + "= send Disassociation Imminent notification" }, + { "ess_disassoc", hostapd_cli_cmd_ess_disassoc, NULL, diff --git a/recipes-connectivity/hostapd/files/431-wpa_cli_ifdef.patch b/recipes-connectivity/hostapd/files/431-wpa_cli_ifdef.patch new file mode 100644 index 0000000..46eb1d6 --- /dev/null +++ b/recipes-connectivity/hostapd/files/431-wpa_cli_ifdef.patch @@ -0,0 +1,28 @@ +From 263d0dc826ac847d2bea23d0c13ebf7ffdf81e87 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + wpa_supplicant/wpa_cli.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c +index 43ac42720..5e134b0e0 100644 +--- a/wpa_supplicant/wpa_cli.c ++++ b/wpa_supplicant/wpa_cli.c +@@ -26,6 +26,15 @@ + #include + #endif /* ANDROID */ + ++#ifndef CONFIG_P2P ++#define CONFIG_P2P ++#endif ++#ifndef CONFIG_AP ++#define CONFIG_AP ++#endif ++#ifndef CONFIG_MESH ++#define CONFIG_MESH ++#endif + + static const char *const wpa_cli_version = + "wpa_cli v" VERSION_STR "\n" diff --git a/recipes-connectivity/hostapd/files/432-missing-typedef.patch b/recipes-connectivity/hostapd/files/432-missing-typedef.patch new file mode 100644 index 0000000..3981d49 --- /dev/null +++ b/recipes-connectivity/hostapd/files/432-missing-typedef.patch @@ -0,0 +1,20 @@ +From 17a3b7768255699d9fe7d3099d0ed83dc8dc9089 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + src/drivers/linux_wext.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/drivers/linux_wext.h b/src/drivers/linux_wext.h +index e7c7001e1..1cb890974 100644 +--- a/src/drivers/linux_wext.h ++++ b/src/drivers/linux_wext.h +@@ -26,6 +26,7 @@ typedef int32_t __s32; + typedef uint16_t __u16; + typedef int16_t __s16; + typedef uint8_t __u8; ++typedef int8_t __s8; + #ifndef __user + #define __user + #endif /* __user */ diff --git a/recipes-connectivity/hostapd/files/450-scan_wait.patch b/recipes-connectivity/hostapd/files/450-scan_wait.patch new file mode 100644 index 0000000..8f9e0cc --- /dev/null +++ b/recipes-connectivity/hostapd/files/450-scan_wait.patch @@ -0,0 +1,83 @@ +From d32de242fcf209a7de6aa4cd29fcf8f838e0c520 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + hostapd/main.c | 29 +++++++++++++---------------- + 1 file changed, 13 insertions(+), 16 deletions(-) + +diff --git a/hostapd/main.c b/hostapd/main.c +index 4b537f35a..f9b29aa88 100644 +--- a/hostapd/main.c ++++ b/hostapd/main.c +@@ -39,6 +39,8 @@ struct hapd_global { + }; + + static struct hapd_global global; ++static int daemonize = 0; ++static char *pid_file = NULL; + + + #ifndef CONFIG_NO_HOSTAPD_LOGGER +@@ -149,6 +151,14 @@ static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module, + } + #endif /* CONFIG_NO_HOSTAPD_LOGGER */ + ++static void hostapd_setup_complete_cb(void *ctx) ++{ ++ if (daemonize && os_daemonize(pid_file)) { ++ perror("daemon"); ++ return; ++ } ++ daemonize = 0; ++} + + /** + * hostapd_driver_init - Preparate driver interface +@@ -167,6 +177,8 @@ static int hostapd_driver_init(struct hostapd_iface *iface) + return -1; + } + ++ hapd->setup_complete_cb = hostapd_setup_complete_cb; ++ + /* Initialize the driver interface */ + if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5])) + b = NULL; +@@ -407,8 +419,6 @@ static void hostapd_global_deinit(const char *pid_file, int eloop_initialized) + #endif /* CONFIG_NATIVE_WINDOWS */ + + eap_server_unregister_methods(); +- +- os_daemonize_terminate(pid_file); + } + + +@@ -434,18 +444,6 @@ static int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize, + } + #endif /* EAP_SERVER_TNC */ + +- if (daemonize) { +- if (os_daemonize(pid_file)) { +- wpa_printf(MSG_ERROR, "daemon: %s", strerror(errno)); +- return -1; +- } +- if (eloop_sock_requeue()) { +- wpa_printf(MSG_ERROR, "eloop_sock_requeue: %s", +- strerror(errno)); +- return -1; +- } +- } +- + eloop_run(); + + return 0; +@@ -647,8 +645,7 @@ int main(int argc, char *argv[]) + struct hapd_interfaces interfaces; + int ret = 1; + size_t i, j; +- int c, debug = 0, daemonize = 0; +- char *pid_file = NULL; ++ int c, debug = 0; + const char *log_file = NULL; + const char *entropy_file = NULL; + char **bss_config = NULL, **tmp_bss; diff --git a/recipes-connectivity/hostapd/files/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch b/recipes-connectivity/hostapd/files/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch new file mode 100644 index 0000000..725d9ee --- /dev/null +++ b/recipes-connectivity/hostapd/files/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch @@ -0,0 +1,198 @@ +From 10040581346e2465c4f446c9dd006d29ff9cbd7a Mon Sep 17 00:00:00 2001 +From: Antonio Quartulli +Date: Sun, 3 Jun 2012 18:22:56 +0200 +Subject: [PATCH] wpa_supplicant: add new config params to be used with the + ibss join command + +Signed-hostap: Antonio Quartulli + +--- + src/drivers/driver.h | 4 ++ + wpa_supplicant/config.c | 94 +++++++++++++++++++++++++++++++++++++++++ + wpa_supplicant/config_ssid.h | 5 +++ + wpa_supplicant/wpa_supplicant.c | 6 +++ + 4 files changed, 109 insertions(+) + +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index a383af19f..e7a2d8b64 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -19,6 +19,7 @@ + + #define WPA_SUPPLICANT_DRIVER_VERSION 4 + ++#include "ap/sta_info.h" + #include "common/defs.h" + #include "common/ieee802_11_defs.h" + #include "common/wpa_common.h" +@@ -819,6 +820,9 @@ struct wpa_driver_associate_params { + * responsible for selecting with which BSS to associate. */ + const u8 *bssid; + ++ unsigned char rates[WLAN_SUPP_RATES_MAX]; ++ int mcast_rate; ++ + /** + * bssid_hint - BSSID of a proposed AP + * +diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c +index eaabaa88d..2bb91280c 100644 +--- a/wpa_supplicant/config.c ++++ b/wpa_supplicant/config.c +@@ -17,6 +17,7 @@ + #include "eap_peer/eap.h" + #include "p2p/p2p.h" + #include "fst/fst.h" ++#include "ap/sta_info.h" + #include "config.h" + + +@@ -2130,6 +2131,97 @@ static char * wpa_config_write_peerkey(const struct parse_data *data, + #endif /* NO_CONFIG_WRITE */ + + ++static int wpa_config_parse_mcast_rate(const struct parse_data *data, ++ struct wpa_ssid *ssid, int line, ++ const char *value) ++{ ++ ssid->mcast_rate = (int)(strtod(value, NULL) * 10); ++ ++ return 0; ++} ++ ++#ifndef NO_CONFIG_WRITE ++static char * wpa_config_write_mcast_rate(const struct parse_data *data, ++ struct wpa_ssid *ssid) ++{ ++ char *value; ++ int res; ++ ++ if (!ssid->mcast_rate == 0) ++ return NULL; ++ ++ value = os_malloc(6); /* longest: 300.0 */ ++ if (value == NULL) ++ return NULL; ++ res = os_snprintf(value, 5, "%.1f", (double)ssid->mcast_rate / 10); ++ if (res < 0) { ++ os_free(value); ++ return NULL; ++ } ++ return value; ++} ++#endif /* NO_CONFIG_WRITE */ ++ ++static int wpa_config_parse_rates(const struct parse_data *data, ++ struct wpa_ssid *ssid, int line, ++ const char *value) ++{ ++ int i; ++ char *pos, *r, *sptr, *end; ++ double rate; ++ ++ pos = (char *)value; ++ r = strtok_r(pos, ",", &sptr); ++ i = 0; ++ while (pos && i < WLAN_SUPP_RATES_MAX) { ++ rate = 0.0; ++ if (r) ++ rate = strtod(r, &end); ++ ssid->rates[i] = rate * 2; ++ if (*end != '\0' || rate * 2 != ssid->rates[i]) ++ return 1; ++ ++ i++; ++ r = strtok_r(NULL, ",", &sptr); ++ } ++ ++ return 0; ++} ++ ++#ifndef NO_CONFIG_WRITE ++static char * wpa_config_write_rates(const struct parse_data *data, ++ struct wpa_ssid *ssid) ++{ ++ char *value, *pos; ++ int res, i; ++ ++ if (ssid->rates[0] <= 0) ++ return NULL; ++ ++ value = os_malloc(6 * WLAN_SUPP_RATES_MAX + 1); ++ if (value == NULL) ++ return NULL; ++ pos = value; ++ for (i = 0; i < WLAN_SUPP_RATES_MAX - 1; i++) { ++ res = os_snprintf(pos, 6, "%.1f,", (double)ssid->rates[i] / 2); ++ if (res < 0) { ++ os_free(value); ++ return NULL; ++ } ++ pos += res; ++ } ++ res = os_snprintf(pos, 6, "%.1f", ++ (double)ssid->rates[WLAN_SUPP_RATES_MAX - 1] / 2); ++ if (res < 0) { ++ os_free(value); ++ return NULL; ++ } ++ ++ value[6 * WLAN_SUPP_RATES_MAX] = '\0'; ++ return value; ++} ++#endif /* NO_CONFIG_WRITE */ ++ + /* Helper macros for network block parser */ + + #ifdef OFFSET +@@ -2382,6 +2474,8 @@ static const struct parse_data ssid_fields[] = { + { INT(ap_max_inactivity) }, + { INT(dtim_period) }, + { INT(beacon_int) }, ++ { FUNC(rates) }, ++ { FUNC(mcast_rate) }, + #ifdef CONFIG_MACSEC + { INT_RANGE(macsec_policy, 0, 1) }, + { INT_RANGE(macsec_integ_only, 0, 1) }, +diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h +index 401c22cec..ce2aeb5bf 100644 +--- a/wpa_supplicant/config_ssid.h ++++ b/wpa_supplicant/config_ssid.h +@@ -10,8 +10,10 @@ + #define CONFIG_SSID_H + + #include "common/defs.h" ++#include "ap/sta_info.h" + #include "utils/list.h" + #include "eap_peer/eap_config.h" ++#include "drivers/nl80211_copy.h" + + + #define DEFAULT_EAP_WORKAROUND ((unsigned int) -1) +@@ -790,6 +792,9 @@ struct wpa_ssid { + */ + void *parent_cred; + ++ unsigned char rates[WLAN_SUPP_RATES_MAX]; ++ double mcast_rate; ++ + #ifdef CONFIG_MACSEC + /** + * macsec_policy - Determines the policy for MACsec secure session +diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c +index c91a5ab10..a2d0dbcc2 100644 +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -3266,6 +3266,12 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) + params.beacon_int = ssid->beacon_int; + else + params.beacon_int = wpa_s->conf->beacon_int; ++ i = 0; ++ while (i < WLAN_SUPP_RATES_MAX) { ++ params.rates[i] = ssid->rates[i]; ++ i++; ++ } ++ params.mcast_rate = ssid->mcast_rate; + } + + params.pairwise_suite = cipher_pairwise; diff --git a/recipes-connectivity/hostapd/files/461-driver_nl80211-use-new-parameters-during-ibss-join.patch b/recipes-connectivity/hostapd/files/461-driver_nl80211-use-new-parameters-during-ibss-join.patch new file mode 100644 index 0000000..fdc8f38 --- /dev/null +++ b/recipes-connectivity/hostapd/files/461-driver_nl80211-use-new-parameters-during-ibss-join.patch @@ -0,0 +1,62 @@ +From 6ff2943d91e4c6ed209284eb02d5d8dbe258070e Mon Sep 17 00:00:00 2001 +From: Antonio Quartulli +Date: Sun, 3 Jun 2012 18:42:25 +0200 +Subject: [PATCH] driver_nl80211: use new parameters during ibss join + +Signed-hostap: Antonio Quartulli + +--- + src/drivers/driver_nl80211.c | 33 ++++++++++++++++++++++++++++++++- + 1 file changed, 32 insertions(+), 1 deletion(-) + +diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c +index 0cdcca66f..b0c71d242 100644 +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -5323,7 +5323,7 @@ static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv, + struct wpa_driver_associate_params *params) + { + struct nl_msg *msg; +- int ret = -1; ++ int ret = -1, i; + int count = 0; + + wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex); +@@ -5350,6 +5350,37 @@ retry: + nl80211_put_beacon_int(msg, params->beacon_int)) + goto fail; + ++ if (params->fixed_freq) { ++ wpa_printf(MSG_DEBUG, " * fixed_freq"); ++ nla_put_flag(msg, NL80211_ATTR_FREQ_FIXED); ++ } ++ ++ if (params->beacon_int > 0) { ++ wpa_printf(MSG_DEBUG, " * beacon_int=%d", ++ params->beacon_int); ++ nla_put_u32(msg, NL80211_ATTR_BEACON_INTERVAL, ++ params->beacon_int); ++ } ++ ++ if (params->rates[0] > 0) { ++ wpa_printf(MSG_DEBUG, " * basic_rates:"); ++ i = 0; ++ while (i < NL80211_MAX_SUPP_RATES && ++ params->rates[i] > 0) { ++ wpa_printf(MSG_DEBUG, " %.1f", ++ (double)params->rates[i] / 2); ++ i++; ++ } ++ nla_put(msg, NL80211_ATTR_BSS_BASIC_RATES, i, ++ params->rates); ++ } ++ ++ if (params->mcast_rate > 0) { ++ wpa_printf(MSG_DEBUG, " * mcast_rate=%.1f", ++ (double)params->mcast_rate / 10); ++ nla_put_u32(msg, NL80211_ATTR_MCAST_RATE, params->mcast_rate); ++ } ++ + ret = nl80211_set_conn_keys(params, msg); + if (ret) + goto fail; diff --git a/recipes-connectivity/hostapd/files/463-add-mcast_rate-to-11s.patch b/recipes-connectivity/hostapd/files/463-add-mcast_rate-to-11s.patch new file mode 100644 index 0000000..9db8670 --- /dev/null +++ b/recipes-connectivity/hostapd/files/463-add-mcast_rate-to-11s.patch @@ -0,0 +1,81 @@ +From ea7e69a3eece261a1a74797e340fd366006fb1d2 Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Thu, 11 May 2017 08:21:45 +0200 +Subject: [PATCH] set mcast_rate in mesh mode + +The wpa_supplicant code for IBSS allows to set the mcast rate. It is +recommended to increase this value from 1 or 6 Mbit/s to something higher +when using a mesh protocol on top which uses the multicast packet loss as +indicator for the link quality. + +This setting was unfortunately not applied for mesh mode. But it would be +beneficial when wpa_supplicant would behave similar to IBSS mode and set +this argument during mesh join like authsae already does. At least it is +helpful for companies/projects which are currently switching to 802.11s +(without mesh_fwding and with mesh_ttl set to 1) as replacement for IBSS +because newer drivers seem to support 802.11s but not IBSS anymore. + +Signed-off-by: Sven Eckelmann +Tested-by: Simon Wunderlich + +--- + src/drivers/driver.h | 1 + + src/drivers/driver_nl80211.c | 13 +++++++++++++ + wpa_supplicant/mesh.c | 1 + + 3 files changed, 15 insertions(+) + +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index e7a2d8b64..32f093f0f 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -1484,6 +1484,7 @@ struct wpa_driver_mesh_join_params { + #define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008 + unsigned int flags; + u8 handle_dfs; ++ int mcast_rate; + }; + + /** +diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c +index b0c71d242..9b28a398e 100644 +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -9612,6 +9612,18 @@ static int nl80211_put_mesh_id(struct nl_msg *msg, const u8 *mesh_id, + } + + ++static int nl80211_put_mcast_rate(struct nl_msg *msg, int mcast_rate) ++{ ++ if (mcast_rate > 0) { ++ wpa_printf(MSG_DEBUG, " * mcast_rate=%.1f", ++ (double)mcast_rate / 10); ++ return nla_put_u32(msg, NL80211_ATTR_MCAST_RATE, mcast_rate); ++ } ++ ++ return 0; ++} ++ ++ + static int nl80211_put_mesh_config(struct nl_msg *msg, + struct wpa_driver_mesh_bss_params *params) + { +@@ -9673,6 +9685,7 @@ static int nl80211_join_mesh(struct i802_bss *bss, + nl80211_put_basic_rates(msg, params->basic_rates) || + nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) || + nl80211_put_beacon_int(msg, params->beacon_int) || ++ nl80211_put_mcast_rate(msg, params->mcast_rate) || + nl80211_put_dtim_period(msg, params->dtim_period)) + goto fail; + +diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c +index 6f54ff764..8b98f040c 100644 +--- a/wpa_supplicant/mesh.c ++++ b/wpa_supplicant/mesh.c +@@ -494,6 +494,7 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, + + params->meshid = ssid->ssid; + params->meshid_len = ssid->ssid_len; ++ params->mcast_rate = ssid->mcast_rate; + ibss_mesh_setup_freq(wpa_s, ssid, ¶ms->freq); + wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled; + wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled; diff --git a/recipes-connectivity/hostapd/files/464-fix-mesh-obss-check.patch b/recipes-connectivity/hostapd/files/464-fix-mesh-obss-check.patch new file mode 100644 index 0000000..d2e77d9 --- /dev/null +++ b/recipes-connectivity/hostapd/files/464-fix-mesh-obss-check.patch @@ -0,0 +1,29 @@ +From 090886c1b5dab18114042b8e40bfdb95c3ec1bb6 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + wpa_supplicant/wpa_supplicant.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c +index a2d0dbcc2..09313bc94 100644 +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -2216,11 +2216,13 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, + for (j = 0; j < wpa_s->last_scan_res_used; j++) { + struct wpa_bss *bss = wpa_s->last_scan_res[j]; + +- if (ssid->mode != WPAS_MODE_IBSS) ++ /* Don't adjust control freq in case of fixed_freq */ ++ if (ssid->fixed_freq) { ++ obss_scan = 0; + break; ++ } + +- /* Don't adjust control freq in case of fixed_freq */ +- if (ssid->fixed_freq) ++ if (ssid->mode != WPAS_MODE_IBSS) + break; + + if (!bss_is_ibss(bss)) diff --git a/recipes-connectivity/hostapd/files/470-survey_data_fallback.patch b/recipes-connectivity/hostapd/files/470-survey_data_fallback.patch new file mode 100644 index 0000000..44f731e --- /dev/null +++ b/recipes-connectivity/hostapd/files/470-survey_data_fallback.patch @@ -0,0 +1,55 @@ +From d0f0639468a04677e537a0bba481cebb46fc419c Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + src/ap/acs.c | 13 +++---------- + 1 file changed, 3 insertions(+), 10 deletions(-) + +diff --git a/src/ap/acs.c b/src/ap/acs.c +index 11178a1f0..05b280459 100644 +--- a/src/ap/acs.c ++++ b/src/ap/acs.c +@@ -293,18 +293,12 @@ static void acs_fail(struct hostapd_iface *iface) + static long double + acs_survey_interference_factor(struct freq_survey *survey, s8 min_nf) + { +- long double factor, busy, total; ++ long double factor, busy = 0, total; + + if (survey->filled & SURVEY_HAS_CHAN_TIME_BUSY) + busy = survey->channel_time_busy; + else if (survey->filled & SURVEY_HAS_CHAN_TIME_RX) + busy = survey->channel_time_rx; +- else { +- /* This shouldn't really happen as survey data is checked in +- * acs_sanity_check() */ +- wpa_printf(MSG_ERROR, "ACS: Survey data missing"); +- return 0; +- } + + total = survey->channel_time; + +@@ -406,20 +400,19 @@ static int acs_usable_vht160_chan(const struct hostapd_channel_data *chan) + static int acs_survey_is_sufficient(struct freq_survey *survey) + { + if (!(survey->filled & SURVEY_HAS_NF)) { ++ survey->nf = -95; + wpa_printf(MSG_INFO, "ACS: Survey is missing noise floor"); +- return 0; + } + + if (!(survey->filled & SURVEY_HAS_CHAN_TIME)) { ++ survey->channel_time = 0; + wpa_printf(MSG_INFO, "ACS: Survey is missing channel time"); +- return 0; + } + + if (!(survey->filled & SURVEY_HAS_CHAN_TIME_BUSY) && + !(survey->filled & SURVEY_HAS_CHAN_TIME_RX)) { + wpa_printf(MSG_INFO, + "ACS: Survey is missing RX and busy time (at least one is required)"); +- return 0; + } + + return 1; diff --git a/recipes-connectivity/hostapd/files/500-lto-jobserver-support.patch b/recipes-connectivity/hostapd/files/500-lto-jobserver-support.patch new file mode 100644 index 0000000..301c488 --- /dev/null +++ b/recipes-connectivity/hostapd/files/500-lto-jobserver-support.patch @@ -0,0 +1,63 @@ +From 860424f37dbbb730f6f086ec3bfe0245b335be47 Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + hostapd/Makefile | 4 ++-- + wpa_supplicant/Makefile | 10 +++++----- + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/hostapd/Makefile b/hostapd/Makefile +index 94ffc1a66..637af7e4b 100644 +--- a/hostapd/Makefile ++++ b/hostapd/Makefile +@@ -1332,14 +1332,14 @@ hostapd_multi.a: $(BCHECK) $(OBJS) + @$(AR) cr $@ hostapd_multi.o $(OBJS) + + hostapd: $(BCHECK) $(OBJS) +- $(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS) ++ +$(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS) + @$(E) " LD " $@ + + ifdef CONFIG_WPA_TRACE + OBJS_c += ../src/utils/trace.o + endif + hostapd_cli: $(OBJS_c) +- $(Q)$(CC) $(LDFLAGS) -o hostapd_cli $(OBJS_c) $(LIBS_c) ++ +$(Q)$(CC) $(LDFLAGS) -o hostapd_cli $(OBJS_c) $(LIBS_c) + @$(E) " LD " $@ + + NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS) +diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile +index 3ee2d6eff..c4a66a0ad 100644 +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -1932,23 +1932,23 @@ wpa_supplicant_multi.a: .config $(BCHECK) $(OBJS) $(EXTRA_progs) + @$(AR) cr $@ wpa_supplicant_multi.o $(OBJS) + + wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) +- $(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) ++ +$(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) + @$(E) " LD " $@ + + eapol_test: $(OBJS_t) +- $(Q)$(LDO) $(LDFLAGS) -o eapol_test $(OBJS_t) $(LIBS) ++ +$(Q)$(LDO) $(LDFLAGS) -o eapol_test $(OBJS_t) $(LIBS) + @$(E) " LD " $@ + + preauth_test: $(OBJS_t2) +- $(Q)$(LDO) $(LDFLAGS) -o preauth_test $(OBJS_t2) $(LIBS) ++ +$(Q)$(LDO) $(LDFLAGS) -o preauth_test $(OBJS_t2) $(LIBS) + @$(E) " LD " $@ + + wpa_passphrase: $(OBJS_p) +- $(Q)$(LDO) $(LDFLAGS) -o wpa_passphrase $(OBJS_p) $(LIBS_p) $(LIBS) ++ +$(Q)$(LDO) $(LDFLAGS) -o wpa_passphrase $(OBJS_p) $(LIBS_p) $(LIBS) + @$(E) " LD " $@ + + wpa_cli: $(OBJS_c) +- $(Q)$(LDO) $(LDFLAGS) -o wpa_cli $(OBJS_c) $(LIBS_c) ++ +$(Q)$(LDO) $(LDFLAGS) -o wpa_cli $(OBJS_c) $(LIBS_c) + @$(E) " LD " $@ + + LIBCTRL += ../src/common/wpa_ctrl.o diff --git a/recipes-connectivity/hostapd/files/599-wpa_supplicant-fix-warnings.patch b/recipes-connectivity/hostapd/files/599-wpa_supplicant-fix-warnings.patch new file mode 100644 index 0000000..d8efc9a --- /dev/null +++ b/recipes-connectivity/hostapd/files/599-wpa_supplicant-fix-warnings.patch @@ -0,0 +1,29 @@ +From 12642c366d7043664153440940e2ed649150342f Mon Sep 17 00:00:00 2001 +From: OpenEmbedded +Date: Thu, 14 May 2020 19:48:53 +0000 + +--- + wpa_supplicant/wps_supplicant.h | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/wpa_supplicant/wps_supplicant.h b/wpa_supplicant/wps_supplicant.h +index 0fbc85174..b7affc103 100644 +--- a/wpa_supplicant/wps_supplicant.h ++++ b/wpa_supplicant/wps_supplicant.h +@@ -9,6 +9,7 @@ + #ifndef WPS_SUPPLICANT_H + #define WPS_SUPPLICANT_H + ++struct wpa_bss; + struct wpa_scan_results; + + #ifdef CONFIG_WPS +@@ -16,8 +17,6 @@ struct wpa_scan_results; + #include "wps/wps.h" + #include "wps/wps_defs.h" + +-struct wpa_bss; +- + struct wps_new_ap_settings { + const char *ssid_hex; + const char *auth; diff --git a/recipes-connectivity/hostapd/files/700-wifi-reload.patch b/recipes-connectivity/hostapd/files/700-wifi-reload.patch new file mode 100644 index 0000000..3e85e2b --- /dev/null +++ b/recipes-connectivity/hostapd/files/700-wifi-reload.patch @@ -0,0 +1,251 @@ +From 8e5a25f2c0bdda989ac910a209b13b583d84e7a4 Mon Sep 17 00:00:00 2001 +From: OpenEmbedded +Date: Thu, 14 May 2020 19:48:53 +0000 + +--- + hostapd/config_file.c | 4 ++++ + hostapd/ctrl_iface.c | 2 +- + hostapd/main.c | 2 +- + src/ap/ap_config.c | 2 ++ + src/ap/ap_config.h | 2 ++ + src/ap/hostapd.c | 39 ++++++++++++++++++++++++++++++++++++--- + src/ap/hostapd.h | 5 +++-- + src/ap/wps_hostapd.c | 2 +- + src/drivers/driver_nl80211.c | 3 +++ + 9 files changed, 53 insertions(+), 8 deletions(-) + +diff --git a/hostapd/config_file.c b/hostapd/config_file.c +index 625104831..7ca790402 100644 +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -2470,6 +2470,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, + bss->isolate = atoi(pos); + } else if (os_strcmp(buf, "ap_max_inactivity") == 0) { + bss->ap_max_inactivity = atoi(pos); ++ } else if (os_strcmp(buf, "config_id") == 0) { ++ bss->config_id = os_strdup(pos); + } else if (os_strcmp(buf, "skip_inactivity_poll") == 0) { + bss->skip_inactivity_poll = atoi(pos); + } else if (os_strcmp(buf, "country_code") == 0) { +@@ -3131,6 +3133,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, + } + } else if (os_strcmp(buf, "acs_exclude_dfs") == 0) { + conf->acs_exclude_dfs = atoi(pos); ++ } else if (os_strcmp(buf, "radio_config_id") == 0) { ++ conf->config_id = os_strdup(pos); + } else if (os_strcmp(buf, "channel") == 0) { + if (os_strcmp(pos, "acs_survey") == 0) { + #ifndef CONFIG_ACS +diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c +index ef24ebb74..880dec290 100644 +--- a/hostapd/ctrl_iface.c ++++ b/hostapd/ctrl_iface.c +@@ -182,7 +182,7 @@ static int hostapd_ctrl_iface_update(struct hostapd_data *hapd, char *txt) + iface->interfaces->config_read_cb = hostapd_ctrl_iface_config_read; + reload_opts = txt; + +- hostapd_reload_config(iface); ++ hostapd_reload_config(iface, 0); + + iface->interfaces->config_read_cb = config_read_cb; + } +diff --git a/hostapd/main.c b/hostapd/main.c +index f9b29aa88..6295cd258 100644 +--- a/hostapd/main.c ++++ b/hostapd/main.c +@@ -320,7 +320,7 @@ static void handle_term(int sig, void *signal_ctx) + + static int handle_reload_iface(struct hostapd_iface *iface, void *ctx) + { +- if (hostapd_reload_config(iface) < 0) { ++ if (hostapd_reload_config(iface, 0) < 0) { + wpa_printf(MSG_WARNING, "Failed to read new configuration " + "file - continuing with old."); + } +diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c +index 90348e1dd..d732095be 100644 +--- a/src/ap/ap_config.c ++++ b/src/ap/ap_config.c +@@ -698,6 +698,7 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf) + os_free(conf->radius_req_attr_sqlite); + os_free(conf->rsn_preauth_interfaces); + os_free(conf->ctrl_interface); ++ os_free(conf->config_id); + os_free(conf->ca_cert); + os_free(conf->server_cert); + os_free(conf->server_cert2); +@@ -881,6 +882,7 @@ void hostapd_config_free(struct hostapd_config *conf) + + for (i = 0; i < conf->num_bss; i++) + hostapd_config_free_bss(conf->bss[i]); ++ os_free(conf->config_id); + os_free(conf->bss); + os_free(conf->supported_rates); + os_free(conf->basic_rates); +diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h +index 826030666..f27c51e80 100644 +--- a/src/ap/ap_config.h ++++ b/src/ap/ap_config.h +@@ -829,6 +829,7 @@ struct hostapd_bss_config { + */ + u8 mka_psk_set; + #endif /* CONFIG_MACSEC */ ++ char *config_id; + }; + + /** +@@ -1012,6 +1013,7 @@ struct hostapd_config { + unsigned int airtime_update_interval; + #define AIRTIME_MODE_MAX (__AIRTIME_MODE_MAX - 1) + #endif /* CONFIG_AIRTIME_POLICY */ ++ char *config_id; + }; + + +diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c +index 9227a1f01..847f7058b 100644 +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -206,6 +206,10 @@ static int hostapd_iface_conf_changed(struct hostapd_config *newconf, + { + size_t i; + ++ if (newconf->config_id != oldconf->config_id) ++ if (strcmp(newconf->config_id, oldconf->config_id)) ++ return 1; ++ + if (newconf->num_bss != oldconf->num_bss) + return 1; + +@@ -219,7 +223,7 @@ static int hostapd_iface_conf_changed(struct hostapd_config *newconf, + } + + +-int hostapd_reload_config(struct hostapd_iface *iface) ++int hostapd_reload_config(struct hostapd_iface *iface, int reconf) + { + struct hapd_interfaces *interfaces = iface->interfaces; + struct hostapd_data *hapd = iface->bss[0]; +@@ -242,13 +246,16 @@ int hostapd_reload_config(struct hostapd_iface *iface) + if (newconf == NULL) + return -1; + +- hostapd_clear_old(iface); +- + oldconf = hapd->iconf; + if (hostapd_iface_conf_changed(newconf, oldconf)) { + char *fname; + int res; + ++ if (reconf) ++ return -1; ++ ++ hostapd_clear_old(iface); ++ + wpa_printf(MSG_DEBUG, + "Configuration changes include interface/BSS modification - force full disable+enable sequence"); + fname = os_strdup(iface->config_fname); +@@ -273,6 +280,22 @@ int hostapd_reload_config(struct hostapd_iface *iface) + wpa_printf(MSG_ERROR, + "Failed to enable interface on config reload"); + return res; ++ } else { ++ for (j = 0; j < iface->num_bss; j++) { ++ hapd = iface->bss[j]; ++ if (!hapd->config_id || strcmp(hapd->config_id, newconf->bss[j]->config_id)) { ++ hostapd_flush_old_stations(iface->bss[j], ++ WLAN_REASON_PREV_AUTH_NOT_VALID); ++ hostapd_broadcast_wep_clear(iface->bss[j]); ++ ++#ifndef CONFIG_NO_RADIUS ++ /* TODO: update dynamic data based on changed configuration ++ * items (e.g., open/close sockets, etc.) */ ++ radius_client_flush(iface->bss[j]->radius, 0); ++#endif /* CONFIG_NO_RADIUS */ ++ wpa_printf(MSG_INFO, "bss %d changed", j); ++ } ++ } + } + iface->conf = newconf; + +@@ -289,6 +312,12 @@ int hostapd_reload_config(struct hostapd_iface *iface) + + for (j = 0; j < iface->num_bss; j++) { + hapd = iface->bss[j]; ++ if (hapd->config_id) { ++ os_free(hapd->config_id); ++ hapd->config_id = NULL; ++ } ++ if (newconf->bss[j]->config_id) ++ hapd->config_id = strdup(newconf->bss[j]->config_id); + hapd->iconf = newconf; + hapd->conf = newconf->bss[j]; + hostapd_reload_bss(hapd); +@@ -2252,6 +2281,10 @@ hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, + hapd->iconf = conf; + hapd->conf = bss; + hapd->iface = hapd_iface; ++ if (bss && bss->config_id) ++ hapd->config_id = strdup(bss->config_id); ++ else ++ hapd->config_id = NULL; + if (conf) + hapd->driver = conf->driver; + hapd->ctrl_sock = -1; +diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h +index 518c7f10b..7cbd5fd46 100644 +--- a/src/ap/hostapd.h ++++ b/src/ap/hostapd.h +@@ -41,7 +41,7 @@ struct mesh_conf; + struct hostapd_iface; + + struct hapd_interfaces { +- int (*reload_config)(struct hostapd_iface *iface); ++ int (*reload_config)(struct hostapd_iface *iface, int reconf); + struct hostapd_config * (*config_read_cb)(const char *config_fname); + int (*ctrl_iface_init)(struct hostapd_data *hapd); + void (*ctrl_iface_deinit)(struct hostapd_data *hapd); +@@ -145,6 +145,7 @@ struct hostapd_data { + struct hostapd_iface *iface; + struct hostapd_config *iconf; + struct hostapd_bss_config *conf; ++ char *config_id; + int interface_added; /* virtual interface added for this BSS */ + unsigned int started:1; + unsigned int disabled:1; +@@ -572,7 +573,7 @@ struct hostapd_iface { + int hostapd_for_each_interface(struct hapd_interfaces *interfaces, + int (*cb)(struct hostapd_iface *iface, + void *ctx), void *ctx); +-int hostapd_reload_config(struct hostapd_iface *iface); ++int hostapd_reload_config(struct hostapd_iface *iface, int reconf); + void hostapd_reconfig_encryption(struct hostapd_data *hapd); + struct hostapd_data * + hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, +diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c +index 4a0302043..2c0038c1a 100644 +--- a/src/ap/wps_hostapd.c ++++ b/src/ap/wps_hostapd.c +@@ -275,7 +275,7 @@ static void wps_reload_config(void *eloop_data, void *user_ctx) + + wpa_printf(MSG_DEBUG, "WPS: Reload configuration data"); + if (iface->interfaces == NULL || +- iface->interfaces->reload_config(iface) < 0) { ++ iface->interfaces->reload_config(iface, 1) < 0) { + wpa_printf(MSG_WARNING, "WPS: Failed to reload the updated " + "configuration"); + } +diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c +index 9b28a398e..bef4ed32d 100644 +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -4295,6 +4295,9 @@ static int wpa_driver_nl80211_set_ap(void *priv, + if (ret) { + wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)", + ret, strerror(-ret)); ++ if (!bss->beacon_set) ++ ret = 0; ++ bss->beacon_set = 0; + } else { + bss->beacon_set = 1; + nl80211_set_bss(bss, params->cts_protect, params->preamble, diff --git a/recipes-connectivity/hostapd/files/800-usleep.patch b/recipes-connectivity/hostapd/files/800-usleep.patch new file mode 100644 index 0000000..0b35da6 --- /dev/null +++ b/recipes-connectivity/hostapd/files/800-usleep.patch @@ -0,0 +1,58 @@ +From 52f53957d41082597fbdfc5b8d79ee72d85cea36 Mon Sep 17 00:00:00 2001 +From: Rosen Penev +Date: Sat, 24 Aug 2019 15:01:16 -0700 +Subject: [PATCH] os_sleep: Use nanosleep for POSIX versions 2008 and higher + +uClibc-ng optionally disabled deprecated POSIX functions like usleep, +causing compilation failures. This switches to nanosleep while retaining +support for older libcs that do not support nanosleep. + +Signed-off-by: Rosen Penev + +--- + src/utils/os_internal.c | 6 ++++++ + src/utils/os_unix.c | 6 ++++++ + 2 files changed, 12 insertions(+) + +diff --git a/src/utils/os_internal.c b/src/utils/os_internal.c +index 474c8a372..feade6ee6 100644 +--- a/src/utils/os_internal.c ++++ b/src/utils/os_internal.c +@@ -25,10 +25,16 @@ + + void os_sleep(os_time_t sec, os_time_t usec) + { ++#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200809L) ++ const struct timespec req = { sec, usec * 1000 }; ++ ++ nanosleep(&req, NULL); ++#else + if (sec) + sleep(sec); + if (usec) + usleep(usec); ++#endif + } + + +diff --git a/src/utils/os_unix.c b/src/utils/os_unix.c +index 6231974cf..c0a1cceb1 100644 +--- a/src/utils/os_unix.c ++++ b/src/utils/os_unix.c +@@ -50,10 +50,16 @@ struct os_alloc_trace { + + void os_sleep(os_time_t sec, os_time_t usec) + { ++#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200809L) ++ const struct timespec req = { sec, usec * 1000 }; ++ ++ nanosleep(&req, NULL); ++#else + if (sec) + sleep(sec); + if (usec) + usleep(usec); ++#endif + } + + diff --git a/recipes-connectivity/hostapd/files/913-iapp-improvements.patch b/recipes-connectivity/hostapd/files/913-iapp-improvements.patch new file mode 100644 index 0000000..23e50d3 --- /dev/null +++ b/recipes-connectivity/hostapd/files/913-iapp-improvements.patch @@ -0,0 +1,47 @@ +From b1f03e0b2257ce0e32a0a55a75b1e89e121550ce Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + src/ap/hostapd.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c +index ca282aad3..096e9751e 100644 +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -1347,10 +1347,9 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first) + } + + if (conf->ieee802_11f && +- (hapd->iapp = iapp_init(hapd, conf->iapp_iface)) == NULL) { +- wpa_printf(MSG_ERROR, "IEEE 802.11F (IAPP) initialization " +- "failed."); +- return -1; ++ (hapd->iapp = iapp_init(hapd, hapd->conf->iapp_iface)) == NULL) { ++ hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, ++ HOSTAPD_LEVEL_DEBUG, "IEEE 802.11F (IAPP) initialization failed. Try again later"); + } + + #ifdef CONFIG_INTERWORKING +@@ -3141,8 +3140,19 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, + ap_sta_clear_disconnect_timeouts(hapd, sta); + + /* IEEE 802.11F (IAPP) */ +- if (hapd->conf->ieee802_11f) ++ if (hapd->conf->ieee802_11f) { ++ if (!hapd->iapp) { ++ hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, ++ HOSTAPD_LEVEL_DEBUG, "IEEE 802.11F (IAPP) initialization try again"); ++ hapd->iapp = iapp_init(hapd, hapd->conf->iapp_iface); ++ } ++ if (hapd->iapp) { ++ hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, ++ HOSTAPD_LEVEL_DEBUG, "IEEE 802.11F (IAPP) initialization add new station"); + iapp_new_station(hapd->iapp, sta); ++ } ++ } ++ + + #ifdef CONFIG_P2P + if (sta->p2p_ie == NULL && !sta->no_p2p_set) { diff --git a/recipes-connectivity/hostapd/files/914-wlan-acs-srd-channels.patch b/recipes-connectivity/hostapd/files/914-wlan-acs-srd-channels.patch new file mode 100644 index 0000000..a17204c --- /dev/null +++ b/recipes-connectivity/hostapd/files/914-wlan-acs-srd-channels.patch @@ -0,0 +1,34 @@ +From ca3bd0e9ecb1b84a629a7aa4d58026f4642aebbd Mon Sep 17 00:00:00 2001 +From: Patrick Walther +Date: Tue, 28 Jan 2020 15:14:35 +0100 + +--- + src/drivers/driver_nl80211_capa.c | 2 ++ + src/drivers/nl80211_copy.h | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c +index 0defd6c7b..698b7f329 100644 +--- a/src/drivers/driver_nl80211_capa.c ++++ b/src/drivers/driver_nl80211_capa.c +@@ -1371,6 +1371,8 @@ static void phy_info_freq(struct hostapd_hw_modes *mode, + chan->flag |= HOSTAPD_CHAN_INDOOR_ONLY; + if (tb_freq[NL80211_FREQUENCY_ATTR_GO_CONCURRENT]) + chan->flag |= HOSTAPD_CHAN_GO_CONCURRENT; ++ if (tb_freq[NL80211_FREQUENCY_ATTR_SRD_CHANNEL]) ++ chan->flag |= HOSTAPD_CHAN_DISABLED; + + if (tb_freq[NL80211_FREQUENCY_ATTR_NO_10MHZ]) + chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_10; +diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h +index 6f09d1500..52413aabb 100644 +--- a/src/drivers/nl80211_copy.h ++++ b/src/drivers/nl80211_copy.h +@@ -3530,6 +3530,7 @@ enum nl80211_frequency_attr { + NL80211_FREQUENCY_ATTR_NO_20MHZ, + NL80211_FREQUENCY_ATTR_NO_10MHZ, + NL80211_FREQUENCY_ATTR_WMM, ++ NL80211_FREQUENCY_ATTR_SRD_CHANNEL, + + /* keep last */ + __NL80211_FREQUENCY_ATTR_AFTER_LAST, diff --git a/recipes-connectivity/hostapd/files/hostapd-full.config b/recipes-connectivity/hostapd/files/hostapd-full.config new file mode 100644 index 0000000..7e7da25 --- /dev/null +++ b/recipes-connectivity/hostapd/files/hostapd-full.config @@ -0,0 +1,407 @@ +# Example hostapd build time configuration +# +# This file lists the configuration options that are used when building the +# hostapd binary. All lines starting with # are ignored. Configuration option +# lines must be commented out complete, if they are not to be included, i.e., +# just setting VARIABLE=n is not disabling that variable. +# +# This file is included in Makefile, so variables like CFLAGS and LIBS can also +# be modified from here. In most cass, these lines should use += in order not +# to override previous values of the variables. + +# Driver interface for Host AP driver +CONFIG_DRIVER_HOSTAP=y + +# Driver interface for wired authenticator +CONFIG_DRIVER_WIRED=y + +# Driver interface for drivers using the nl80211 kernel interface +CONFIG_DRIVER_NL80211=y + +# QCA vendor extensions to nl80211 +#CONFIG_DRIVER_NL80211_QCA=y + +# driver_nl80211.c requires libnl. If you are compiling it yourself +# you may need to point hostapd to your version of libnl. +# +#CFLAGS += -I$ +#LIBS += -L$ + +# Use libnl v2.0 (or 3.0) libraries. +# CONFIG_LIBNL20=y + +# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) +# CONFIG_LIBNL32=y + +# Use libnl-tiny +CONFIG_LIBNL_TINY=y + +# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) +#CONFIG_DRIVER_BSD=y +#CFLAGS += -I/usr/local/include +#LIBS += -L/usr/local/lib +#LIBS_p += -L/usr/local/lib +#LIBS_c += -L/usr/local/lib + +# Driver interface for no driver (e.g., RADIUS server only) +#CONFIG_DRIVER_NONE=y + +# IEEE 802.11F/IAPP +CONFIG_IAPP=y + +# WPA2/IEEE 802.11i RSN pre-authentication +CONFIG_RSN_PREAUTH=y + +# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS) +CONFIG_PEERKEY=y + +# IEEE 802.11w (management frame protection) +# Driver support is also needed for IEEE 802.11w. +#CONFIG_IEEE80211W=y + +# Support Operating Channel Validation +#CONFIG_OCV=y + +# Integrated EAP server +CONFIG_EAP=y + +# EAP Re-authentication Protocol (ERP) in integrated EAP server +#CONFIG_ERP=y + +# EAP-MD5 for the integrated EAP server +CONFIG_EAP_MD5=y + +# EAP-TLS for the integrated EAP server +CONFIG_EAP_TLS=y + +# EAP-MSCHAPv2 for the integrated EAP server +CONFIG_EAP_MSCHAPV2=y + +# EAP-PEAP for the integrated EAP server +CONFIG_EAP_PEAP=y + +# EAP-GTC for the integrated EAP server +CONFIG_EAP_GTC=y + +# EAP-TTLS for the integrated EAP server +CONFIG_EAP_TTLS=y + +# EAP-SIM for the integrated EAP server +#CONFIG_EAP_SIM=y + +# EAP-AKA for the integrated EAP server +#CONFIG_EAP_AKA=y + +# EAP-AKA' for the integrated EAP server +# This requires CONFIG_EAP_AKA to be enabled, too. +#CONFIG_EAP_AKA_PRIME=y + +# EAP-PAX for the integrated EAP server +#CONFIG_EAP_PAX=y + +# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK) +#CONFIG_EAP_PSK=y + +# EAP-pwd for the integrated EAP server (secure authentication with a password) +#CONFIG_EAP_PWD=y + +# EAP-SAKE for the integrated EAP server +#CONFIG_EAP_SAKE=y + +# EAP-GPSK for the integrated EAP server +#CONFIG_EAP_GPSK=y +# Include support for optional SHA256 cipher suite in EAP-GPSK +#CONFIG_EAP_GPSK_SHA256=y + +# EAP-FAST for the integrated EAP server +CONFIG_EAP_FAST=y + +# EAP-TEAP for the integrated EAP server +# Note: The current EAP-TEAP implementation is experimental and should not be +# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number +# of conflicting statements and missing details and the implementation has +# vendor specific workarounds for those and as such, may not interoperate with +# any other implementation. This should not be used for anything else than +# experimentation and interoperability testing until those issues has been +# resolved. +#CONFIG_EAP_TEAP=y + +# Wi-Fi Protected Setup (WPS) +# CONFIG_WPS=y +# Enable UPnP support for external WPS Registrars +#CONFIG_WPS_UPNP=y +# Enable WPS support with NFC config method +#CONFIG_WPS_NFC=y + +# EAP-IKEv2 +#CONFIG_EAP_IKEV2=y + +# Trusted Network Connect (EAP-TNC) +#CONFIG_EAP_TNC=y + +# EAP-EKE for the integrated EAP server +#CONFIG_EAP_EKE=y + +# PKCS#12 (PFX) support (used to read private key and certificate file from +# a file that usually has extension .p12 or .pfx) +CONFIG_PKCS12=y + +# RADIUS authentication server. This provides access to the integrated EAP +# server from external hosts using RADIUS. +#CONFIG_RADIUS_SERVER=y + +# Build IPv6 support for RADIUS operations +CONFIG_IPV6=y + +# IEEE Std 802.11r-2008 (Fast BSS Transition) +CONFIG_IEEE80211R=y + +# Use the hostapd's IEEE 802.11 authentication (ACL), but without +# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211) +#CONFIG_DRIVER_RADIUS_ACL=y + +# IEEE 802.11n (High Throughput) support +CONFIG_IEEE80211N=y + +# Wireless Network Management (IEEE Std 802.11v-2011) +# Note: This is experimental and not complete implementation. +#CONFIG_WNM=y + +# IEEE 802.11ac (Very High Throughput) support +CONFIG_IEEE80211AC=y + +# IEEE 802.11ax HE support +# Note: This is experimental and work in progress. The definitions are still +# subject to change and this should not be expected to interoperate with the +# final IEEE 802.11ax version. +#CONFIG_IEEE80211AX=y + +# Remove debugging code that is printing out debug messages to stdout. +# This can be used to reduce the size of the hostapd considerably if debugging +# code is not needed. +#CONFIG_NO_STDOUT_DEBUG=y + +# Add support for writing debug log to a file: -f /tmp/hostapd.log +# Disabled by default. +#CONFIG_DEBUG_FILE=y + +# Send debug messages to syslog instead of stdout +# CONFIG_DEBUG_SYSLOG=y + +# Add support for sending all debug messages (regardless of debug verbosity) +# to the Linux kernel tracing facility. This helps debug the entire stack by +# making it easy to record everything happening from the driver up into the +# same file, e.g., using trace-cmd. +#CONFIG_DEBUG_LINUX_TRACING=y + +# Remove support for RADIUS accounting +#CONFIG_NO_ACCOUNTING=y + +# Remove support for RADIUS +#CONFIG_NO_RADIUS=y + +# Remove support for VLANs +#CONFIG_NO_VLAN=y + +# Enable support for fully dynamic VLANs. This enables hostapd to +# automatically create bridge and VLAN interfaces if necessary. +CONFIG_FULL_DYNAMIC_VLAN=y + +# Use netlink-based kernel API for VLAN operations instead of ioctl() +# Note: This requires libnl 3.1 or newer. +#CONFIG_VLAN_NETLINK=y + +# Remove support for dumping internal state through control interface commands +# This can be used to reduce binary size at the cost of disabling a debugging +# option. +CONFIG_NO_DUMP_STATE=y + +# Enable tracing code for developer debugging +# This tracks use of memory allocations and other registrations and reports +# incorrect use with a backtrace of call (or allocation) location. +#CONFIG_WPA_TRACE=y +# For BSD, comment out these. +#LIBS += -lexecinfo +#LIBS_p += -lexecinfo +#LIBS_c += -lexecinfo + +# Use libbfd to get more details for developer debugging +# This enables use of libbfd to get more detailed symbols for the backtraces +# generated by CONFIG_WPA_TRACE=y. +#CONFIG_WPA_TRACE_BFD=y +# For BSD, comment out these. +#LIBS += -lbfd -liberty -lz +#LIBS_p += -lbfd -liberty -lz +#LIBS_c += -lbfd -liberty -lz + +# hostapd depends on strong random number generation being available from the +# operating system. os_get_random() function is used to fetch random data when +# needed, e.g., for key generation. On Linux and BSD systems, this works by +# reading /dev/urandom. It should be noted that the OS entropy pool needs to be +# properly initialized before hostapd is started. This is important especially +# on embedded devices that do not have a hardware random number generator and +# may by default start up with minimal entropy available for random number +# generation. +# +# As a safety net, hostapd is by default trying to internally collect +# additional entropy for generating random data to mix in with the data +# fetched from the OS. This by itself is not considered to be very strong, but +# it may help in cases where the system pool is not initialized properly. +# However, it is very strongly recommended that the system pool is initialized +# with enough entropy either by using hardware assisted random number +# generator or by storing state over device reboots. +# +# hostapd can be configured to maintain its own entropy store over restarts to +# enhance random number generation. This is not perfect, but it is much more +# secure than using the same sequence of random numbers after every reboot. +# This can be enabled with -e command line option. The specified +# file needs to be readable and writable by hostapd. +# +# If the os_get_random() is known to provide strong random data (e.g., on +# Linux/BSD, the board in question is known to have reliable source of random +# data from /dev/urandom), the internal hostapd random pool can be disabled. +# This will save some in binary size and CPU use. However, this should only be +# considered for builds that are known to be used on devices that meet the +# requirements described above. +CONFIG_NO_RANDOM_POOL=y + +# Should we attempt to use the getrandom(2) call that provides more reliable +# yet secure randomness source than /dev/random on Linux 3.17 and newer. +# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. +CONFIG_GETRANDOM=y + +# Should we use poll instead of select? Select is used by default. +#CONFIG_ELOOP_POLL=y + +# Should we use epoll instead of select? Select is used by default. +#CONFIG_ELOOP_EPOLL=y + +# Should we use kqueue instead of select? Select is used by default. +#CONFIG_ELOOP_KQUEUE=y + +# Select TLS implementation +# openssl = OpenSSL (default) +# gnutls = GnuTLS +# internal = Internal TLSv1 implementation (experimental) +# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) +# none = Empty template +CONFIG_TLS=openssl + +# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) +# can be enabled to get a stronger construction of messages when block ciphers +# are used. +#CONFIG_TLSV11=y + +# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) +# can be enabled to enable use of stronger crypto algorithms. +#CONFIG_TLSV12=y + +# Select which ciphers to use by default with OpenSSL if the user does not +# specify them. +#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" + +# If CONFIG_TLS=internal is used, additional library and include paths are +# needed for LibTomMath. Alternatively, an integrated, minimal version of +# LibTomMath can be used. See beginning of libtommath.c for details on benefits +# and drawbacks of this option. +CONFIG_INTERNAL_LIBTOMMATH=y +#ifndef CONFIG_INTERNAL_LIBTOMMATH +#LTM_PATH=/usr/src/libtommath-0.39 +#CFLAGS += -I$(LTM_PATH) +#LIBS += -L$(LTM_PATH) +#LIBS_p += -L$(LTM_PATH) +#endif +# At the cost of about 4 kB of additional binary size, the internal LibTomMath +# can be configured to include faster routines for exptmod, sqr, and div to +# speed up DH and RSA calculation considerably +#CONFIG_INTERNAL_LIBTOMMATH_FAST=y + +# Interworking (IEEE 802.11u) +# This can be used to enable functionality to improve interworking with +# external networks. +#CONFIG_INTERWORKING=y + +# Hotspot 2.0 +#CONFIG_HS20=y + +# Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file +#CONFIG_SQLITE=y + +# Enable Fast Session Transfer (FST) +#CONFIG_FST=y + +# Enable CLI commands for FST testing +#CONFIG_FST_TEST=y + +# Testing options +# This can be used to enable some testing options (see also the example +# configuration file) that are really useful only for testing clients that +# connect to this hostapd. These options allow, for example, to drop a +# certain percentage of probe requests or auth/(re)assoc frames. +# +#CONFIG_TESTING_OPTIONS=y + +# Automatic Channel Selection +# This will allow hostapd to pick the channel automatically when channel is set +# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in +# similar way. +# +# Automatic selection is currently only done through initialization, later on +# we hope to do background checks to keep us moving to more ideal channels as +# time goes by. ACS is currently only supported through the nl80211 driver and +# your driver must have survey dump capability that is filled by the driver +# during scanning. +# +# You can customize the ACS survey algorithm with the hostapd.conf variable +# acs_num_scans. +# +# Supported ACS drivers: +# * ath9k +# * ath5k +# * ath10k +# +# For more details refer to: +# http://wireless.kernel.org/en/users/Documentation/acs +# +CONFIG_ACS=y + +# Multiband Operation support +# These extentions facilitate efficient use of multiple frequency bands +# available to the AP and the devices that may associate with it. +#CONFIG_MBO=y + +# Client Taxonomy +# Has the AP retain the Probe Request and (Re)Association Request frames from +# a client, from which a signature can be produced which can identify the model +# of client device like "Nexus 6P" or "iPhone 5s". +#CONFIG_TAXONOMY=y + +# Fast Initial Link Setup (FILS) (IEEE 802.11ai) +#CONFIG_FILS=y +# FILS shared key authentication with PFS +#CONFIG_FILS_SK_PFS=y + +# Include internal line edit mode in hostapd_cli. This can be used to provide +# limited command line editing and history support. +#CONFIG_WPA_CLI_EDIT=y + +# Opportunistic Wireless Encryption (OWE) +# Experimental implementation of draft-harkins-owe-07.txt +#CONFIG_OWE=y + +# Airtime policy support +#CONFIG_AIRTIME_POLICY=y + +# Override default value for the wpa_disable_eapol_key_retries configuration +# parameter. See that parameter in hostapd.conf for more details. +#CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1 + +# uBus IPC/RPC System +# Services can connect to the bus and provide methods +# that can be called by other services or clients. +# CONFIG_UBUS=y + +# OpenWrt patch 380-disable-ctrl-iface-mib.patch +# leads to the MIB only being compiled in if +# CONFIG_CTRL_IFACE_MIB is enabled. +# CONFIG_CTRL_IFACE_MIB=y diff --git a/recipes-connectivity/hostapd/files/src/ap/ubus.c b/recipes-connectivity/hostapd/files/src/ap/ubus.c new file mode 100644 index 0000000..3375ac4 --- /dev/null +++ b/recipes-connectivity/hostapd/files/src/ap/ubus.c @@ -0,0 +1,1142 @@ +/* + * hostapd / ubus support + * Copyright (c) 2013, Felix Fietkau + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "utils/includes.h" +#include "utils/common.h" +#include "utils/eloop.h" +#include "utils/wpabuf.h" +#include "common/ieee802_11_defs.h" +#include "hostapd.h" +#include "neighbor_db.h" +#include "wps_hostapd.h" +#include "sta_info.h" +#include "ubus.h" +#include "ap_drv_ops.h" +#include "beacon.h" +#include "rrm.h" +#include "wnm_ap.h" +#include "taxonomy.h" + +static struct ubus_context *ctx; +static struct blob_buf b; +static int ctx_ref; + +static inline struct hostapd_data *get_hapd_from_object(struct ubus_object *obj) +{ + return container_of(obj, struct hostapd_data, ubus.obj); +} + + +struct ubus_banned_client { + struct avl_node avl; + u8 addr[ETH_ALEN]; +}; + +static void ubus_receive(int sock, void *eloop_ctx, void *sock_ctx) +{ + struct ubus_context *ctx = eloop_ctx; + ubus_handle_event(ctx); +} + +static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) +{ + if (ubus_reconnect(ctx, NULL)) { + eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); + return; + } + + eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); +} + +static void hostapd_ubus_connection_lost(struct ubus_context *ctx) +{ + eloop_unregister_read_sock(ctx->sock.fd); + eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); +} + +static bool hostapd_ubus_init(void) +{ + if (ctx) + return true; + + ctx = ubus_connect(NULL); + if (!ctx) + return false; + + ctx->connection_lost = hostapd_ubus_connection_lost; + eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); + return true; +} + +static void hostapd_ubus_ref_inc(void) +{ + ctx_ref++; +} + +static void hostapd_ubus_ref_dec(void) +{ + ctx_ref--; + if (!ctx) + return; + + if (ctx_ref) + return; + + eloop_unregister_read_sock(ctx->sock.fd); + ubus_free(ctx); + ctx = NULL; +} + +void hostapd_ubus_add_iface(struct hostapd_iface *iface) +{ + if (!hostapd_ubus_init()) + return; +} + +void hostapd_ubus_free_iface(struct hostapd_iface *iface) +{ + if (!ctx) + return; +} + +static void +hostapd_bss_del_ban(void *eloop_data, void *user_ctx) +{ + struct ubus_banned_client *ban = eloop_data; + struct hostapd_data *hapd = user_ctx; + + avl_delete(&hapd->ubus.banned, &ban->avl); + free(ban); +} + +static void +hostapd_bss_ban_client(struct hostapd_data *hapd, u8 *addr, int time) +{ + struct ubus_banned_client *ban; + + if (time < 0) + time = 0; + + ban = avl_find_element(&hapd->ubus.banned, addr, ban, avl); + if (!ban) { + if (!time) + return; + + ban = os_zalloc(sizeof(*ban)); + memcpy(ban->addr, addr, sizeof(ban->addr)); + ban->avl.key = ban->addr; + avl_insert(&hapd->ubus.banned, &ban->avl); + } else { + eloop_cancel_timeout(hostapd_bss_del_ban, ban, hapd); + if (!time) { + hostapd_bss_del_ban(ban, hapd); + return; + } + } + + eloop_register_timeout(0, time * 1000, hostapd_bss_del_ban, ban, hapd); +} + +static int +hostapd_bss_get_clients(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); + struct sta_info *sta; + void *list, *c; + char mac_buf[20]; + static const struct { + const char *name; + uint32_t flag; + } sta_flags[] = { + { "auth", WLAN_STA_AUTH }, + { "assoc", WLAN_STA_ASSOC }, + { "authorized", WLAN_STA_AUTHORIZED }, + { "preauth", WLAN_STA_PREAUTH }, + { "wds", WLAN_STA_WDS }, + { "wmm", WLAN_STA_WMM }, + { "ht", WLAN_STA_HT }, + { "vht", WLAN_STA_VHT }, + { "wps", WLAN_STA_WPS }, + { "mfp", WLAN_STA_MFP }, + }; + + blob_buf_init(&b, 0); + blobmsg_add_u32(&b, "freq", hapd->iface->freq); + list = blobmsg_open_table(&b, "clients"); + for (sta = hapd->sta_list; sta; sta = sta->next) { + void *r; + int i; + + sprintf(mac_buf, MACSTR, MAC2STR(sta->addr)); + c = blobmsg_open_table(&b, mac_buf); + for (i = 0; i < ARRAY_SIZE(sta_flags); i++) + blobmsg_add_u8(&b, sta_flags[i].name, + !!(sta->flags & sta_flags[i].flag)); + + r = blobmsg_open_array(&b, "rrm"); + for (i = 0; i < ARRAY_SIZE(sta->rrm_enabled_capa); i++) + blobmsg_add_u32(&b, "", sta->rrm_enabled_capa[i]); + blobmsg_close_array(&b, r); + blobmsg_add_u32(&b, "aid", sta->aid); +#ifdef CONFIG_TAXONOMY + r = blobmsg_alloc_string_buffer(&b, "signature", 1024); + if (retrieve_sta_taxonomy(hapd, sta, r, 1024) > 0) + blobmsg_add_string_buffer(&b); +#endif + blobmsg_close_table(&b, c); + } + blobmsg_close_array(&b, list); + ubus_send_reply(ctx, req, b.head); + + return 0; +} + +static int +hostapd_bss_get_features(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); + + blob_buf_init(&b, 0); + blobmsg_add_u8(&b, "ht_supported", ht_supported(hapd->iface->hw_features)); + blobmsg_add_u8(&b, "vht_supported", vht_supported(hapd->iface->hw_features)); + ubus_send_reply(ctx, req, b.head); + + return 0; +} + +enum { + NOTIFY_RESPONSE, + __NOTIFY_MAX +}; + +static const struct blobmsg_policy notify_policy[__NOTIFY_MAX] = { + [NOTIFY_RESPONSE] = { "notify_response", BLOBMSG_TYPE_INT32 }, +}; + +static int +hostapd_notify_response(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__NOTIFY_MAX]; + struct hostapd_data *hapd = get_hapd_from_object(obj); + struct wpabuf *elems; + const char *pos; + size_t len; + + blobmsg_parse(notify_policy, __NOTIFY_MAX, tb, + blob_data(msg), blob_len(msg)); + + if (!tb[NOTIFY_RESPONSE]) + return UBUS_STATUS_INVALID_ARGUMENT; + + hapd->ubus.notify_response = blobmsg_get_u32(tb[NOTIFY_RESPONSE]); + + return UBUS_STATUS_OK; +} + +enum { + DEL_CLIENT_ADDR, + DEL_CLIENT_REASON, + DEL_CLIENT_DEAUTH, + DEL_CLIENT_BAN_TIME, + __DEL_CLIENT_MAX +}; + +static const struct blobmsg_policy del_policy[__DEL_CLIENT_MAX] = { + [DEL_CLIENT_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, + [DEL_CLIENT_REASON] = { "reason", BLOBMSG_TYPE_INT32 }, + [DEL_CLIENT_DEAUTH] = { "deauth", BLOBMSG_TYPE_INT8 }, + [DEL_CLIENT_BAN_TIME] = { "ban_time", BLOBMSG_TYPE_INT32 }, +}; + +static int +hostapd_bss_del_client(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__DEL_CLIENT_MAX]; + struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); + struct sta_info *sta; + bool deauth = false; + int reason; + u8 addr[ETH_ALEN]; + + blobmsg_parse(del_policy, __DEL_CLIENT_MAX, tb, blob_data(msg), blob_len(msg)); + + if (!tb[DEL_CLIENT_ADDR]) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (hwaddr_aton(blobmsg_data(tb[DEL_CLIENT_ADDR]), addr)) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (tb[DEL_CLIENT_REASON]) + reason = blobmsg_get_u32(tb[DEL_CLIENT_REASON]); + + if (tb[DEL_CLIENT_DEAUTH]) + deauth = blobmsg_get_bool(tb[DEL_CLIENT_DEAUTH]); + + sta = ap_get_sta(hapd, addr); + if (sta) { + if (deauth) { + hostapd_drv_sta_deauth(hapd, addr, reason); + ap_sta_deauthenticate(hapd, sta, reason); + } else { + hostapd_drv_sta_disassoc(hapd, addr, reason); + ap_sta_disassociate(hapd, sta, reason); + } + } + + if (tb[DEL_CLIENT_BAN_TIME]) + hostapd_bss_ban_client(hapd, addr, blobmsg_get_u32(tb[DEL_CLIENT_BAN_TIME])); + + return 0; +} + +static void +blobmsg_add_macaddr(struct blob_buf *buf, const char *name, const u8 *addr) +{ + char *s; + + s = blobmsg_alloc_string_buffer(buf, name, 20); + sprintf(s, MACSTR, MAC2STR(addr)); + blobmsg_add_string_buffer(buf); +} + +static int +hostapd_bss_list_bans(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); + struct ubus_banned_client *ban; + void *c; + + blob_buf_init(&b, 0); + c = blobmsg_open_array(&b, "clients"); + avl_for_each_element(&hapd->ubus.banned, ban, avl) + blobmsg_add_macaddr(&b, NULL, ban->addr); + blobmsg_close_array(&b, c); + ubus_send_reply(ctx, req, b.head); + + return 0; +} + +static int +hostapd_bss_wps_start(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + int rc; + struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); + + rc = hostapd_wps_button_pushed(hapd, NULL); + + if (rc != 0) + return UBUS_STATUS_NOT_SUPPORTED; + + return 0; +} + +static int +hostapd_bss_wps_cancel(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + int rc; + struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); + + rc = hostapd_wps_cancel(hapd); + + if (rc != 0) + return UBUS_STATUS_NOT_SUPPORTED; + + return 0; +} + +static int +hostapd_bss_update_beacon(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + int rc; + struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); + + rc = ieee802_11_set_beacon(hapd); + + if (rc != 0) + return UBUS_STATUS_NOT_SUPPORTED; + + return 0; +} + +enum { + CSA_FREQ, + CSA_BCN_COUNT, + CSA_CENTER_FREQ1, + CSA_CENTER_FREQ2, + CSA_BANDWIDTH, + CSA_SEC_CHANNEL_OFFSET, + CSA_HT, + CSA_VHT, + CSA_BLOCK_TX, + __CSA_MAX +}; + +static const struct blobmsg_policy csa_policy[__CSA_MAX] = { + [CSA_FREQ] = { "freq", BLOBMSG_TYPE_INT32 }, + [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 }, + [CSA_CENTER_FREQ1] = { "center_freq1", BLOBMSG_TYPE_INT32 }, + [CSA_CENTER_FREQ2] = { "center_freq2", BLOBMSG_TYPE_INT32 }, + [CSA_BANDWIDTH] = { "bandwidth", BLOBMSG_TYPE_INT32 }, + [CSA_SEC_CHANNEL_OFFSET] = { "sec_channel_offset", BLOBMSG_TYPE_INT32 }, + [CSA_HT] = { "ht", BLOBMSG_TYPE_BOOL }, + [CSA_VHT] = { "vht", BLOBMSG_TYPE_BOOL }, + [CSA_BLOCK_TX] = { "block_tx", BLOBMSG_TYPE_BOOL }, +}; + +#ifdef NEED_AP_MLME +static int +hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__CSA_MAX]; + struct hostapd_data *hapd = get_hapd_from_object(obj); + struct csa_settings css; + + blobmsg_parse(csa_policy, __CSA_MAX, tb, blob_data(msg), blob_len(msg)); + + if (!tb[CSA_FREQ]) + return UBUS_STATUS_INVALID_ARGUMENT; + + memset(&css, 0, sizeof(css)); + css.freq_params.freq = blobmsg_get_u32(tb[CSA_FREQ]); + +#define SET_CSA_SETTING(name, field, type) \ + do { \ + if (tb[name]) \ + css.field = blobmsg_get_ ## type(tb[name]); \ + } while(0) + + SET_CSA_SETTING(CSA_BCN_COUNT, cs_count, u32); + SET_CSA_SETTING(CSA_CENTER_FREQ1, freq_params.center_freq1, u32); + SET_CSA_SETTING(CSA_CENTER_FREQ2, freq_params.center_freq2, u32); + SET_CSA_SETTING(CSA_BANDWIDTH, freq_params.bandwidth, u32); + SET_CSA_SETTING(CSA_SEC_CHANNEL_OFFSET, freq_params.sec_channel_offset, u32); + SET_CSA_SETTING(CSA_HT, freq_params.ht_enabled, bool); + SET_CSA_SETTING(CSA_VHT, freq_params.vht_enabled, bool); + SET_CSA_SETTING(CSA_BLOCK_TX, block_tx, bool); + + + if (hostapd_switch_channel(hapd, &css) != 0) + return UBUS_STATUS_NOT_SUPPORTED; + return UBUS_STATUS_OK; +#undef SET_CSA_SETTING +} +#endif + +enum { + VENDOR_ELEMENTS, + __VENDOR_ELEMENTS_MAX +}; + +static const struct blobmsg_policy ve_policy[__VENDOR_ELEMENTS_MAX] = { + /* vendor elements are provided as hex-string */ + [VENDOR_ELEMENTS] = { "vendor_elements", BLOBMSG_TYPE_STRING }, +}; + +static int +hostapd_vendor_elements(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__VENDOR_ELEMENTS_MAX]; + struct hostapd_data *hapd = get_hapd_from_object(obj); + struct hostapd_bss_config *bss = hapd->conf; + struct wpabuf *elems; + const char *pos; + size_t len; + + blobmsg_parse(ve_policy, __VENDOR_ELEMENTS_MAX, tb, + blob_data(msg), blob_len(msg)); + + if (!tb[VENDOR_ELEMENTS]) + return UBUS_STATUS_INVALID_ARGUMENT; + + pos = blobmsg_data(tb[VENDOR_ELEMENTS]); + len = os_strlen(pos); + if (len & 0x01) + return UBUS_STATUS_INVALID_ARGUMENT; + + len /= 2; + if (len == 0) { + wpabuf_free(bss->vendor_elements); + bss->vendor_elements = NULL; + return 0; + } + + elems = wpabuf_alloc(len); + if (elems == NULL) + return 1; + + if (hexstr2bin(pos, wpabuf_put(elems, len), len)) { + wpabuf_free(elems); + return UBUS_STATUS_INVALID_ARGUMENT; + } + + wpabuf_free(bss->vendor_elements); + bss->vendor_elements = elems; + + /* update beacons if vendor elements were set successfully */ + if (ieee802_11_update_beacons(hapd->iface) != 0) + return UBUS_STATUS_NOT_SUPPORTED; + return UBUS_STATUS_OK; +} + +static void +hostapd_rrm_print_nr(struct hostapd_neighbor_entry *nr) +{ + const u8 *data; + char *str; + int len; + + blobmsg_printf(&b, "", MACSTR, MAC2STR(nr->bssid)); + + str = blobmsg_alloc_string_buffer(&b, "", nr->ssid.ssid_len + 1); + memcpy(str, nr->ssid.ssid, nr->ssid.ssid_len); + str[nr->ssid.ssid_len] = 0; + blobmsg_add_string_buffer(&b); + + len = wpabuf_len(nr->nr); + str = blobmsg_alloc_string_buffer(&b, "", 2 * len + 1); + wpa_snprintf_hex(str, 2 * len + 1, wpabuf_head_u8(nr->nr), len); + blobmsg_add_string_buffer(&b); +} + +enum { + BSS_MGMT_EN_NEIGHBOR, + BSS_MGMT_EN_BEACON, +#ifdef CONFIG_WNM_AP + BSS_MGMT_EN_BSS_TRANSITION, +#endif + __BSS_MGMT_EN_MAX +}; + +static bool +__hostapd_bss_mgmt_enable_f(struct hostapd_data *hapd, int flag) +{ + struct hostapd_bss_config *bss = hapd->conf; + uint32_t flags; + + switch (flag) { + case BSS_MGMT_EN_NEIGHBOR: + if (bss->radio_measurements[0] & + WLAN_RRM_CAPS_NEIGHBOR_REPORT) + return false; + + bss->radio_measurements[0] |= + WLAN_RRM_CAPS_NEIGHBOR_REPORT; + hostapd_set_own_neighbor_report(hapd); + return true; + case BSS_MGMT_EN_BEACON: + flags = WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE | + WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE | + WLAN_RRM_CAPS_BEACON_REPORT_TABLE; + + if (bss->radio_measurements[0] & flags == flags) + return false; + + bss->radio_measurements[0] |= (u8) flags; + return true; +#ifdef CONFIG_WNM_AP + case BSS_MGMT_EN_BSS_TRANSITION: + if (bss->bss_transition) + return false; + + bss->bss_transition = 1; + return true; +#endif + } +} + +static void +__hostapd_bss_mgmt_enable(struct hostapd_data *hapd, uint32_t flags) +{ + bool update = false; + int i; + + for (i = 0; i < __BSS_MGMT_EN_MAX; i++) { + if (!(flags & (1 << i))) + continue; + + update |= __hostapd_bss_mgmt_enable_f(hapd, i); + } + + if (update) + ieee802_11_update_beacons(hapd->iface); +} + + +static const struct blobmsg_policy bss_mgmt_enable_policy[__BSS_MGMT_EN_MAX] = { + [BSS_MGMT_EN_NEIGHBOR] = { "neighbor_report", BLOBMSG_TYPE_BOOL }, + [BSS_MGMT_EN_BEACON] = { "beacon_report", BLOBMSG_TYPE_BOOL }, +#ifdef CONFIG_WNM_AP + [BSS_MGMT_EN_BSS_TRANSITION] = { "bss_transition", BLOBMSG_TYPE_BOOL }, +#endif +}; + +static int +hostapd_bss_mgmt_enable(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) + +{ + struct hostapd_data *hapd = get_hapd_from_object(obj); + struct blob_attr *tb[__BSS_MGMT_EN_MAX]; + struct blob_attr *cur; + uint32_t flags = 0; + int i; + bool neigh = false, beacon = false; + + blobmsg_parse(bss_mgmt_enable_policy, __BSS_MGMT_EN_MAX, tb, blob_data(msg), blob_len(msg)); + + for (i = 0; i < ARRAY_SIZE(tb); i++) { + if (!tb[i] || !blobmsg_get_bool(tb[i])) + continue; + + flags |= (1 << i); + } + + __hostapd_bss_mgmt_enable(hapd, flags); +} + + +static void +hostapd_rrm_nr_enable(struct hostapd_data *hapd) +{ + __hostapd_bss_mgmt_enable(hapd, 1 << BSS_MGMT_EN_NEIGHBOR); +} + +static int +hostapd_rrm_nr_get_own(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct hostapd_data *hapd = get_hapd_from_object(obj); + struct hostapd_neighbor_entry *nr; + void *c; + + hostapd_rrm_nr_enable(hapd); + + nr = hostapd_neighbor_get(hapd, hapd->own_addr, NULL); + if (!nr) + return UBUS_STATUS_NOT_FOUND; + + blob_buf_init(&b, 0); + + c = blobmsg_open_array(&b, "value"); + hostapd_rrm_print_nr(nr); + blobmsg_close_array(&b, c); + + ubus_send_reply(ctx, req, b.head); + + return 0; +} + +static int +hostapd_rrm_nr_list(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct hostapd_data *hapd = get_hapd_from_object(obj); + struct hostapd_neighbor_entry *nr; + void *c; + + hostapd_rrm_nr_enable(hapd); + blob_buf_init(&b, 0); + + c = blobmsg_open_array(&b, "list"); + dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry, list) { + void *cur; + + if (!memcmp(nr->bssid, hapd->own_addr, ETH_ALEN)) + continue; + + cur = blobmsg_open_array(&b, NULL); + hostapd_rrm_print_nr(nr); + blobmsg_close_array(&b, cur); + } + blobmsg_close_array(&b, c); + + ubus_send_reply(ctx, req, b.head); + + return 0; +} + +enum { + NR_SET_LIST, + __NR_SET_LIST_MAX +}; + +static const struct blobmsg_policy nr_set_policy[__NR_SET_LIST_MAX] = { + [NR_SET_LIST] = { "list", BLOBMSG_TYPE_ARRAY }, +}; + + +static void +hostapd_rrm_nr_clear(struct hostapd_data *hapd) +{ + struct hostapd_neighbor_entry *nr; + +restart: + dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry, list) { + if (!memcmp(nr->bssid, hapd->own_addr, ETH_ALEN)) + continue; + + hostapd_neighbor_remove(hapd, nr->bssid, &nr->ssid); + goto restart; + } +} + +static int +hostapd_rrm_nr_set(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + static const struct blobmsg_policy nr_e_policy[] = { + { .type = BLOBMSG_TYPE_STRING }, + { .type = BLOBMSG_TYPE_STRING }, + { .type = BLOBMSG_TYPE_STRING }, + }; + struct hostapd_data *hapd = get_hapd_from_object(obj); + struct blob_attr *tb_l[__NR_SET_LIST_MAX]; + struct blob_attr *tb[ARRAY_SIZE(nr_e_policy)]; + struct blob_attr *cur; + int ret = 0; + int rem; + + hostapd_rrm_nr_enable(hapd); + + blobmsg_parse(nr_set_policy, __NR_SET_LIST_MAX, tb_l, blob_data(msg), blob_len(msg)); + if (!tb_l[NR_SET_LIST]) + return UBUS_STATUS_INVALID_ARGUMENT; + + hostapd_rrm_nr_clear(hapd); + blobmsg_for_each_attr(cur, tb_l[NR_SET_LIST], rem) { + struct wpa_ssid_value ssid; + struct wpabuf *data; + u8 bssid[ETH_ALEN]; + char *s; + + blobmsg_parse_array(nr_e_policy, ARRAY_SIZE(nr_e_policy), tb, blobmsg_data(cur), blobmsg_data_len(cur)); + if (!tb[0] || !tb[1] || !tb[2]) + goto invalid; + + s = blobmsg_get_string(tb[0]); + if (hwaddr_aton(s, bssid)) + goto invalid; + + s = blobmsg_get_string(tb[1]); + ssid.ssid_len = strlen(s); + if (ssid.ssid_len > sizeof(ssid.ssid)) + goto invalid; + + memcpy(&ssid, s, ssid.ssid_len); + data = wpabuf_parse_bin(blobmsg_get_string(tb[2])); + if (!data) + goto invalid; + + hostapd_neighbor_set(hapd, bssid, &ssid, data, NULL, NULL, 0); + wpabuf_free(data); + continue; + +invalid: + ret = UBUS_STATUS_INVALID_ARGUMENT; + } + + return 0; +} + +enum { + BEACON_REQ_ADDR, + BEACON_REQ_MODE, + BEACON_REQ_OP_CLASS, + BEACON_REQ_CHANNEL, + BEACON_REQ_DURATION, + BEACON_REQ_BSSID, + BEACON_REQ_SSID, + __BEACON_REQ_MAX, +}; + +static const struct blobmsg_policy beacon_req_policy[__BEACON_REQ_MAX] = { + [BEACON_REQ_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, + [BEACON_REQ_OP_CLASS] { "op_class", BLOBMSG_TYPE_INT32 }, + [BEACON_REQ_CHANNEL] { "channel", BLOBMSG_TYPE_INT32 }, + [BEACON_REQ_DURATION] { "duration", BLOBMSG_TYPE_INT32 }, + [BEACON_REQ_MODE] { "mode", BLOBMSG_TYPE_INT32 }, + [BEACON_REQ_BSSID] { "bssid", BLOBMSG_TYPE_STRING }, + [BEACON_REQ_SSID] { "ssid", BLOBMSG_TYPE_STRING }, +}; + +static int +hostapd_rrm_beacon_req(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *ureq, const char *method, + struct blob_attr *msg) +{ + struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); + struct blob_attr *tb[__BEACON_REQ_MAX]; + struct blob_attr *cur; + struct wpabuf *req; + u8 bssid[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + u8 addr[ETH_ALEN]; + int mode, rem, ret; + int buf_len = 13; + + blobmsg_parse(beacon_req_policy, __BEACON_REQ_MAX, tb, blob_data(msg), blob_len(msg)); + + if (!tb[BEACON_REQ_ADDR] || !tb[BEACON_REQ_MODE] || !tb[BEACON_REQ_DURATION] || + !tb[BEACON_REQ_OP_CLASS] || !tb[BEACON_REQ_CHANNEL]) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (tb[BEACON_REQ_SSID]) + buf_len += blobmsg_data_len(tb[BEACON_REQ_SSID]) + 2 - 1; + + mode = blobmsg_get_u32(tb[BEACON_REQ_MODE]); + if (hwaddr_aton(blobmsg_data(tb[BEACON_REQ_ADDR]), addr)) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (tb[BEACON_REQ_BSSID] && + hwaddr_aton(blobmsg_data(tb[BEACON_REQ_BSSID]), bssid)) + return UBUS_STATUS_INVALID_ARGUMENT; + + req = wpabuf_alloc(buf_len); + if (!req) + return UBUS_STATUS_UNKNOWN_ERROR; + + /* 1: regulatory class */ + wpabuf_put_u8(req, blobmsg_get_u32(tb[BEACON_REQ_OP_CLASS])); + + /* 2: channel number */ + wpabuf_put_u8(req, blobmsg_get_u32(tb[BEACON_REQ_CHANNEL])); + + /* 3-4: randomization interval */ + wpabuf_put_le16(req, 0); + + /* 5-6: duration */ + wpabuf_put_le16(req, blobmsg_get_u32(tb[BEACON_REQ_DURATION])); + + /* 7: mode */ + wpabuf_put_u8(req, blobmsg_get_u32(tb[BEACON_REQ_MODE])); + + /* 8-13: BSSID */ + wpabuf_put_data(req, bssid, ETH_ALEN); + + if ((cur = tb[BEACON_REQ_SSID]) != NULL) { + wpabuf_put_u8(req, WLAN_EID_SSID); + wpabuf_put_u8(req, blobmsg_data_len(cur) - 1); + wpabuf_put_data(req, blobmsg_data(cur), blobmsg_data_len(cur) - 1); + } + + ret = hostapd_send_beacon_req(hapd, addr, 0, req); + if (ret < 0) + return -ret; + + return 0; +} + + +#ifdef CONFIG_WNM_AP +enum { + WNM_DISASSOC_ADDR, + WNM_DISASSOC_DURATION, + WNM_DISASSOC_NEIGHBORS, + __WNM_DISASSOC_MAX, +}; + +static const struct blobmsg_policy wnm_disassoc_policy[__WNM_DISASSOC_MAX] = { + [WNM_DISASSOC_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, + [WNM_DISASSOC_DURATION] { "duration", BLOBMSG_TYPE_INT32 }, + [WNM_DISASSOC_NEIGHBORS] { "neighbors", BLOBMSG_TYPE_ARRAY }, +}; + +static int +hostapd_wnm_disassoc_imminent(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *ureq, const char *method, + struct blob_attr *msg) +{ + struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); + struct blob_attr *tb[__WNM_DISASSOC_MAX]; + struct blob_attr *cur; + struct sta_info *sta; + int duration = 10; + int rem; + int nr_len = 0; + u8 *nr = NULL; + u8 req_mode = WNM_BSS_TM_REQ_DISASSOC_IMMINENT; + u8 addr[ETH_ALEN]; + + blobmsg_parse(wnm_disassoc_policy, __WNM_DISASSOC_MAX, tb, blob_data(msg), blob_len(msg)); + + if (!tb[WNM_DISASSOC_ADDR]) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (hwaddr_aton(blobmsg_data(tb[WNM_DISASSOC_ADDR]), addr)) + return UBUS_STATUS_INVALID_ARGUMENT; + + if ((cur = tb[WNM_DISASSOC_DURATION]) != NULL) + duration = blobmsg_get_u32(cur); + + sta = ap_get_sta(hapd, addr); + if (!sta) + return UBUS_STATUS_NOT_FOUND; + + if (tb[WNM_DISASSOC_NEIGHBORS]) { + u8 *nr_cur; + + if (blobmsg_check_array(tb[WNM_DISASSOC_NEIGHBORS], + BLOBMSG_TYPE_STRING) < 0) + return UBUS_STATUS_INVALID_ARGUMENT; + + blobmsg_for_each_attr(cur, tb[WNM_DISASSOC_NEIGHBORS], rem) { + int len = strlen(blobmsg_get_string(cur)); + + if (len % 2) + return UBUS_STATUS_INVALID_ARGUMENT; + + nr_len += (len / 2) + 2; + } + + if (nr_len) { + nr = os_zalloc(nr_len); + if (!nr) + return UBUS_STATUS_UNKNOWN_ERROR; + } + + nr_cur = nr; + blobmsg_for_each_attr(cur, tb[WNM_DISASSOC_NEIGHBORS], rem) { + int len = strlen(blobmsg_get_string(cur)) / 2; + + *nr_cur++ = WLAN_EID_NEIGHBOR_REPORT; + *nr_cur++ = (u8) len; + if (hexstr2bin(blobmsg_data(cur), nr_cur, len)) { + free(nr); + return UBUS_STATUS_INVALID_ARGUMENT; + } + + nr_cur += len; + } + } + + if (nr) + req_mode |= WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED; + + if (wnm_send_bss_tm_req(hapd, sta, req_mode, duration, 0, NULL, + NULL, nr, nr_len, NULL, 0)) + return UBUS_STATUS_UNKNOWN_ERROR; + + return 0; +} +#endif + +static const struct ubus_method bss_methods[] = { + UBUS_METHOD_NOARG("get_clients", hostapd_bss_get_clients), + UBUS_METHOD("del_client", hostapd_bss_del_client, del_policy), + UBUS_METHOD_NOARG("list_bans", hostapd_bss_list_bans), + UBUS_METHOD_NOARG("wps_start", hostapd_bss_wps_start), + UBUS_METHOD_NOARG("wps_cancel", hostapd_bss_wps_cancel), + UBUS_METHOD_NOARG("update_beacon", hostapd_bss_update_beacon), + UBUS_METHOD_NOARG("get_features", hostapd_bss_get_features), +#ifdef NEED_AP_MLME + UBUS_METHOD("switch_chan", hostapd_switch_chan, csa_policy), +#endif + UBUS_METHOD("set_vendor_elements", hostapd_vendor_elements, ve_policy), + UBUS_METHOD("notify_response", hostapd_notify_response, notify_policy), + UBUS_METHOD("bss_mgmt_enable", hostapd_bss_mgmt_enable, bss_mgmt_enable_policy), + UBUS_METHOD_NOARG("rrm_nr_get_own", hostapd_rrm_nr_get_own), + UBUS_METHOD_NOARG("rrm_nr_list", hostapd_rrm_nr_list), + UBUS_METHOD("rrm_nr_set", hostapd_rrm_nr_set, nr_set_policy), + UBUS_METHOD("rrm_beacon_req", hostapd_rrm_beacon_req, beacon_req_policy), +#ifdef CONFIG_WNM_AP + UBUS_METHOD("wnm_disassoc_imminent", hostapd_wnm_disassoc_imminent, wnm_disassoc_policy), +#endif +}; + +static struct ubus_object_type bss_object_type = + UBUS_OBJECT_TYPE("hostapd_bss", bss_methods); + +static int avl_compare_macaddr(const void *k1, const void *k2, void *ptr) +{ + return memcmp(k1, k2, ETH_ALEN); +} + +void hostapd_ubus_add_bss(struct hostapd_data *hapd) +{ + struct ubus_object *obj = &hapd->ubus.obj; + char *name; + int ret; + +#ifdef CONFIG_MESH + if (hapd->conf->mesh & MESH_ENABLED) + return; +#endif + + if (!hostapd_ubus_init()) + return; + + if (asprintf(&name, "hostapd.%s", hapd->conf->iface) < 0) + return; + + avl_init(&hapd->ubus.banned, avl_compare_macaddr, false, NULL); + obj->name = name; + obj->type = &bss_object_type; + obj->methods = bss_object_type.methods; + obj->n_methods = bss_object_type.n_methods; + ret = ubus_add_object(ctx, obj); + hostapd_ubus_ref_inc(); +} + +void hostapd_ubus_free_bss(struct hostapd_data *hapd) +{ + struct ubus_object *obj = &hapd->ubus.obj; + char *name = (char *) obj->name; + + if (!ctx) + return; + + if (obj->id) { + ubus_remove_object(ctx, obj); + hostapd_ubus_ref_dec(); + } + + free(name); +} + +struct ubus_event_req { + struct ubus_notify_request nreq; + int resp; +}; + +static void +ubus_event_cb(struct ubus_notify_request *req, int idx, int ret) +{ + struct ubus_event_req *ureq = container_of(req, struct ubus_event_req, nreq); + + ureq->resp = ret; +} + +int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req) +{ + struct ubus_banned_client *ban; + const char *types[HOSTAPD_UBUS_TYPE_MAX] = { + [HOSTAPD_UBUS_PROBE_REQ] = "probe", + [HOSTAPD_UBUS_AUTH_REQ] = "auth", + [HOSTAPD_UBUS_ASSOC_REQ] = "assoc", + }; + const char *type = "mgmt"; + struct ubus_event_req ureq = {}; + const u8 *addr; + + if (req->mgmt_frame) + addr = req->mgmt_frame->sa; + else + addr = req->addr; + + ban = avl_find_element(&hapd->ubus.banned, addr, ban, avl); + if (ban) + return WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; + + if (!hapd->ubus.obj.has_subscribers) + return WLAN_STATUS_SUCCESS; + + if (req->type < ARRAY_SIZE(types)) + type = types[req->type]; + + blob_buf_init(&b, 0); + blobmsg_add_macaddr(&b, "address", addr); + if (req->mgmt_frame) + blobmsg_add_macaddr(&b, "target", req->mgmt_frame->da); + if (req->frame_info) + blobmsg_add_u32(&b, "signal", req->frame_info->ssi_signal); + blobmsg_add_u32(&b, "freq", hapd->iface->freq); + + if (req->elems) { + if(req->elems->ht_capabilities) + { + struct ieee80211_ht_capabilities *ht_capabilities; + void *ht_cap, *ht_cap_mcs_set, *mcs_set; + + + ht_capabilities = (struct ieee80211_ht_capabilities*) req->elems->ht_capabilities; + ht_cap = blobmsg_open_table(&b, "ht_capabilities"); + blobmsg_add_u16(&b, "ht_capabilities_info", ht_capabilities->ht_capabilities_info); + ht_cap_mcs_set = blobmsg_open_table(&b, "supported_mcs_set"); + blobmsg_add_u16(&b, "a_mpdu_params", ht_capabilities->a_mpdu_params); + blobmsg_add_u16(&b, "ht_extended_capabilities", ht_capabilities->ht_extended_capabilities); + blobmsg_add_u32(&b, "tx_bf_capability_info", ht_capabilities->tx_bf_capability_info); + blobmsg_add_u16(&b, "asel_capabilities", ht_capabilities->asel_capabilities); + mcs_set = blobmsg_open_array(&b, "supported_mcs_set"); + for (int i = 0; i < 16; i++) { + blobmsg_add_u16(&b, NULL, (u16) ht_capabilities->supported_mcs_set[i]); + } + blobmsg_close_array(&b, mcs_set); + blobmsg_close_table(&b, ht_cap_mcs_set); + blobmsg_close_table(&b, ht_cap); + } + if(req->elems->vht_capabilities) + { + struct ieee80211_vht_capabilities *vht_capabilities; + void *vht_cap, *vht_cap_mcs_set; + + vht_capabilities = (struct ieee80211_vht_capabilities*) req->elems->vht_capabilities; + vht_cap = blobmsg_open_table(&b, "vht_capabilities"); + blobmsg_add_u32(&b, "vht_capabilities_info", vht_capabilities->vht_capabilities_info); + vht_cap_mcs_set = blobmsg_open_table(&b, "vht_supported_mcs_set"); + blobmsg_add_u16(&b, "rx_map", vht_capabilities->vht_supported_mcs_set.rx_map); + blobmsg_add_u16(&b, "rx_highest", vht_capabilities->vht_supported_mcs_set.rx_highest); + blobmsg_add_u16(&b, "tx_map", vht_capabilities->vht_supported_mcs_set.tx_map); + blobmsg_add_u16(&b, "tx_highest", vht_capabilities->vht_supported_mcs_set.tx_highest); + blobmsg_close_table(&b, vht_cap_mcs_set); + blobmsg_close_table(&b, vht_cap); + } + } + + if (!hapd->ubus.notify_response) { + ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); + return WLAN_STATUS_SUCCESS; + } + + if (ubus_notify_async(ctx, &hapd->ubus.obj, type, b.head, &ureq.nreq)) + return WLAN_STATUS_SUCCESS; + + ureq.nreq.status_cb = ubus_event_cb; + ubus_complete_request(ctx, &ureq.nreq.req, 100); + + if (ureq.resp) + return ureq.resp; + + return WLAN_STATUS_SUCCESS; +} + +void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *addr) +{ + if (!hapd->ubus.obj.has_subscribers) + return; + + if (!addr) + return; + + blob_buf_init(&b, 0); + blobmsg_add_macaddr(&b, "address", addr); + + ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); +} diff --git a/recipes-connectivity/hostapd/files/src/ap/ubus.h b/recipes-connectivity/hostapd/files/src/ap/ubus.h new file mode 100644 index 0000000..185af5a --- /dev/null +++ b/recipes-connectivity/hostapd/files/src/ap/ubus.h @@ -0,0 +1,78 @@ +/* + * hostapd / ubus support + * Copyright (c) 2013, Felix Fietkau + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ +#ifndef __HOSTAPD_UBUS_H +#define __HOSTAPD_UBUS_H + +enum hostapd_ubus_event_type { + HOSTAPD_UBUS_PROBE_REQ, + HOSTAPD_UBUS_AUTH_REQ, + HOSTAPD_UBUS_ASSOC_REQ, + HOSTAPD_UBUS_TYPE_MAX +}; + +struct hostapd_ubus_request { + enum hostapd_ubus_event_type type; + const struct ieee80211_mgmt *mgmt_frame; + const struct ieee802_11_elems *elems; + const struct hostapd_frame_info *frame_info; + const u8 *addr; +}; + +struct hostapd_iface; +struct hostapd_data; + +#ifdef UBUS_SUPPORT + +#include +#include + +struct hostapd_ubus_bss { + struct ubus_object obj; + struct avl_tree banned; + int notify_response; +}; + +void hostapd_ubus_add_iface(struct hostapd_iface *iface); +void hostapd_ubus_free_iface(struct hostapd_iface *iface); +void hostapd_ubus_add_bss(struct hostapd_data *hapd); +void hostapd_ubus_free_bss(struct hostapd_data *hapd); + +int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req); +void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *mac); + +#else + +struct hostapd_ubus_bss {}; + +static inline void hostapd_ubus_add_iface(struct hostapd_iface *iface) +{ +} + +static inline void hostapd_ubus_free_iface(struct hostapd_iface *iface) +{ +} + +static inline void hostapd_ubus_add_bss(struct hostapd_data *hapd) +{ +} + +static inline void hostapd_ubus_free_bss(struct hostapd_data *hapd) +{ +} + +static inline int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req) +{ + return 0; +} + +static inline void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *mac) +{ +} +#endif + +#endif diff --git a/recipes-connectivity/hostapd/files/src/utils/build_features.h b/recipes-connectivity/hostapd/files/src/utils/build_features.h new file mode 100644 index 0000000..abebecb --- /dev/null +++ b/recipes-connectivity/hostapd/files/src/utils/build_features.h @@ -0,0 +1,45 @@ +#ifndef BUILD_FEATURES_H +#define BUILD_FEATURES_H + +static inline int has_feature(const char *feat) +{ +#if defined(IEEE8021X_EAPOL) || (defined(HOSTAPD) && !defined(CONFIG_NO_RADIUS)) + if (!strcmp(feat, "eap")) + return 1; +#endif +#ifdef CONFIG_IEEE80211N + if (!strcmp(feat, "11n")) + return 1; +#endif +#ifdef CONFIG_IEEE80211AC + if (!strcmp(feat, "11ac")) + return 1; +#endif +#ifdef CONFIG_IEEE80211R + if (!strcmp(feat, "11r")) + return 1; +#endif +#ifdef CONFIG_IEEE80211W + if (!strcmp(feat, "11w")) + return 1; +#endif +#ifdef CONFIG_ACS + if (!strcmp(feat, "acs")) + return 1; +#endif +#ifdef CONFIG_SAE + if (!strcmp(feat, "sae")) + return 1; +#endif +#ifdef CONFIG_OWE + if (!strcmp(feat, "owe")) + return 1; +#endif +#ifdef CONFIG_SUITEB192 + if (!strcmp(feat, "suiteb192")) + return 1; +#endif + return 0; +} + +#endif /* BUILD_FEATURES_H */ diff --git a/recipes-connectivity/hostapd/files/wpa_supplicant-full.config b/recipes-connectivity/hostapd/files/wpa_supplicant-full.config new file mode 100644 index 0000000..f996297 --- /dev/null +++ b/recipes-connectivity/hostapd/files/wpa_supplicant-full.config @@ -0,0 +1,633 @@ +# Example wpa_supplicant build time configuration +# +# This file lists the configuration options that are used when building the +# wpa_supplicant binary. All lines starting with # are ignored. Configuration +# option lines must be commented out complete, if they are not to be included, +# i.e., just setting VARIABLE=n is not disabling that variable. +# +# This file is included in Makefile, so variables like CFLAGS and LIBS can also +# be modified from here. In most cases, these lines should use += in order not +# to override previous values of the variables. + + +# Uncomment following two lines and fix the paths if you have installed OpenSSL +# or GnuTLS in non-default location +# CFLAGS += -I/usr/local/openssl/include +# LIBS += -L/usr/local/openssl/lib + +# Some Red Hat versions seem to include kerberos header files from OpenSSL, but +# the kerberos files are not in the default include path. Following line can be +# used to fix build issues on such systems (krb5.h not found). +#CFLAGS += -I/usr/include/kerberos + +# Driver interface for generic Linux wireless extensions +# Note: WEXT is deprecated in the current Linux kernel version and no new +# functionality is added to it. nl80211-based interface is the new +# replacement for WEXT and its use allows wpa_supplicant to properly control +# the driver to improve existing functionality like roaming and to support new +# functionality. +CONFIG_DRIVER_WEXT=y + +# Driver interface for Linux drivers using the nl80211 kernel interface +CONFIG_DRIVER_NL80211=y + +# Driver interface for Host AP driver +#CONFIG_DRIVER_HOSTAP=y + +# QCA vendor extensions to nl80211 +#CONFIG_DRIVER_NL80211_QCA=y + +# driver_nl80211.c requires libnl. If you are compiling it yourself +# you may need to point hostapd to your version of libnl. +# +#CFLAGS += -I$ +#LIBS += -L$ + +# Use libnl v2.0 (or 3.0) libraries. +#CONFIG_LIBNL20=y + +# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) +# CONFIG_LIBNL32=y + +# Use libnl-tiny +CONFIG_LIBNL_TINY=y + +# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) +#CONFIG_DRIVER_BSD=y +#CFLAGS += -I/usr/local/include +#LIBS += -L/usr/local/lib +#LIBS_p += -L/usr/local/lib +#LIBS_c += -L/usr/local/lib + +# Driver interface for Windows NDIS +#CONFIG_DRIVER_NDIS=y +#CFLAGS += -I/usr/include/w32api/ddk +#LIBS += -L/usr/local/lib +# For native build using mingw +#CONFIG_NATIVE_WINDOWS=y +# Additional directories for cross-compilation on Linux host for mingw target +#CFLAGS += -I/opt/mingw/mingw32/include/ddk +#LIBS += -L/opt/mingw/mingw32/lib +#CC=mingw32-gcc +# By default, driver_ndis uses WinPcap for low-level operations. This can be +# replaced with the following option which replaces WinPcap calls with NDISUIO. +# However, this requires that WZC is disabled (net stop wzcsvc) before starting +# wpa_supplicant. +# CONFIG_USE_NDISUIO=y + +# Driver interface for wired Ethernet drivers +CONFIG_DRIVER_WIRED=y + +# Driver interface for MACsec capable Qualcomm Atheros drivers +#CONFIG_DRIVER_MACSEC_QCA=y + +# Driver interface for Linux MACsec drivers +#CONFIG_DRIVER_MACSEC_LINUX=y + +# Driver interface for the Broadcom RoboSwitch family +#CONFIG_DRIVER_ROBOSWITCH=y + +# Driver interface for no driver (e.g., WPS ER only) +#CONFIG_DRIVER_NONE=y + +# Solaris libraries +#LIBS += -lsocket -ldlpi -lnsl +#LIBS_c += -lsocket + +# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or +# MACsec is included) +CONFIG_IEEE8021X_EAPOL=y + +# EAP-MD5 +CONFIG_EAP_MD5=y + +# EAP-MSCHAPv2 +CONFIG_EAP_MSCHAPV2=y + +# EAP-TLS +CONFIG_EAP_TLS=y + +# EAL-PEAP +CONFIG_EAP_PEAP=y + +# EAP-TTLS +CONFIG_EAP_TTLS=y + +# EAP-FAST +CONFIG_EAP_FAST=y + +# EAP-TEAP +# Note: The current EAP-TEAP implementation is experimental and should not be +# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number +# of conflicting statements and missing details and the implementation has +# vendor specific workarounds for those and as such, may not interoperate with +# any other implementation. This should not be used for anything else than +# experimentation and interoperability testing until those issues has been +# resolved. +#CONFIG_EAP_TEAP=y + +# EAP-GTC +CONFIG_EAP_GTC=y + +# EAP-OTP +CONFIG_EAP_OTP=y + +# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used) +#CONFIG_EAP_SIM=y + +# Enable SIM simulator (Milenage) for EAP-SIM +#CONFIG_SIM_SIMULATOR=y + +# EAP-PSK (experimental; this is _not_ needed for WPA-PSK) +#CONFIG_EAP_PSK=y + +# EAP-pwd (secure authentication using only a password) +#CONFIG_EAP_PWD=y + +# EAP-PAX +#CONFIG_EAP_PAX=y + +# LEAP +CONFIG_EAP_LEAP=y + +# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used) +#CONFIG_EAP_AKA=y + +# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used). +# This requires CONFIG_EAP_AKA to be enabled, too. +#CONFIG_EAP_AKA_PRIME=y + +# Enable USIM simulator (Milenage) for EAP-AKA +#CONFIG_USIM_SIMULATOR=y + +# EAP-SAKE +#CONFIG_EAP_SAKE=y + +# EAP-GPSK +#CONFIG_EAP_GPSK=y +# Include support for optional SHA256 cipher suite in EAP-GPSK +#CONFIG_EAP_GPSK_SHA256=y + +# EAP-TNC and related Trusted Network Connect support (experimental) +#CONFIG_EAP_TNC=y + +# Wi-Fi Protected Setup (WPS) +# CONFIG_WPS=y +# Enable WPS external registrar functionality +#CONFIG_WPS_ER=y +# Disable credentials for an open network by default when acting as a WPS +# registrar. +#CONFIG_WPS_REG_DISABLE_OPEN=y +# Enable WPS support with NFC config method +#CONFIG_WPS_NFC=y + +# EAP-IKEv2 +#CONFIG_EAP_IKEV2=y + +# EAP-EKE +#CONFIG_EAP_EKE=y + +# MACsec +#CONFIG_MACSEC=y + +# PKCS#12 (PFX) support (used to read private key and certificate file from +# a file that usually has extension .p12 or .pfx) +CONFIG_PKCS12=y + +# Smartcard support (i.e., private key on a smartcard), e.g., with openssl +# engine. +CONFIG_SMARTCARD=y + +# PC/SC interface for smartcards (USIM, GSM SIM) +# Enable this if EAP-SIM or EAP-AKA is included +#CONFIG_PCSC=y + +# Support HT overrides (disable HT/HT40, mask MCS rates, etc.) +CONFIG_HT_OVERRIDES=y + +# Support VHT overrides (disable VHT, mask MCS rates, etc.) +CONFIG_VHT_OVERRIDES=y + +# Development testing +#CONFIG_EAPOL_TEST=y + +# Select control interface backend for external programs, e.g, wpa_cli: +# unix = UNIX domain sockets (default for Linux/*BSD) +# udp = UDP sockets using localhost (127.0.0.1) +# udp6 = UDP IPv6 sockets using localhost (::1) +# named_pipe = Windows Named Pipe (default for Windows) +# udp-remote = UDP sockets with remote access (only for tests systems/purpose) +# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose) +# y = use default (backwards compatibility) +# If this option is commented out, control interface is not included in the +# build. +CONFIG_CTRL_IFACE=y + +# Include support for GNU Readline and History Libraries in wpa_cli. +# When building a wpa_cli binary for distribution, please note that these +# libraries are licensed under GPL and as such, BSD license may not apply for +# the resulting binary. +#CONFIG_READLINE=y + +# Include internal line edit mode in wpa_cli. This can be used as a replacement +# for GNU Readline to provide limited command line editing and history support. +#CONFIG_WPA_CLI_EDIT=y + +# Remove debugging code that is printing out debug message to stdout. +# This can be used to reduce the size of the wpa_supplicant considerably +# if debugging code is not needed. The size reduction can be around 35% +# (e.g., 90 kB). +#CONFIG_NO_STDOUT_DEBUG=y + +# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save +# 35-50 kB in code size. +#CONFIG_NO_WPA=y + +# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support +# This option can be used to reduce code size by removing support for +# converting ASCII passphrases into PSK. If this functionality is removed, the +# PSK can only be configured as the 64-octet hexstring (e.g., from +# wpa_passphrase). This saves about 0.5 kB in code size. +#CONFIG_NO_WPA_PASSPHRASE=y + +# Simultaneous Authentication of Equals (SAE), WPA3-Personal +CONFIG_SAE=y + +# Disable scan result processing (ap_mode=1) to save code size by about 1 kB. +# This can be used if ap_scan=1 mode is never enabled. +#CONFIG_NO_SCAN_PROCESSING=y + +# Select configuration backend: +# file = text file (e.g., wpa_supplicant.conf; note: the configuration file +# path is given on command line, not here; this option is just used to +# select the backend that allows configuration files to be used) +# winreg = Windows registry (see win_example.reg for an example) +CONFIG_BACKEND=file + +# Remove configuration write functionality (i.e., to allow the configuration +# file to be updated based on runtime configuration changes). The runtime +# configuration can still be changed, the changes are just not going to be +# persistent over restarts. This option can be used to reduce code size by +# about 3.5 kB. +#CONFIG_NO_CONFIG_WRITE=y + +# Remove support for configuration blobs to reduce code size by about 1.5 kB. +#CONFIG_NO_CONFIG_BLOBS=y + +# Select program entry point implementation: +# main = UNIX/POSIX like main() function (default) +# main_winsvc = Windows service (read parameters from registry) +# main_none = Very basic example (development use only) +#CONFIG_MAIN=main + +# Select wrapper for operating system and C library specific functions +# unix = UNIX/POSIX like systems (default) +# win32 = Windows systems +# none = Empty template +#CONFIG_OS=unix + +# Select event loop implementation +# eloop = select() loop (default) +# eloop_win = Windows events and WaitForMultipleObject() loop +#CONFIG_ELOOP=eloop + +# Should we use poll instead of select? Select is used by default. +#CONFIG_ELOOP_POLL=y + +# Should we use epoll instead of select? Select is used by default. +#CONFIG_ELOOP_EPOLL=y + +# Should we use kqueue instead of select? Select is used by default. +#CONFIG_ELOOP_KQUEUE=y + +# Select layer 2 packet implementation +# linux = Linux packet socket (default) +# pcap = libpcap/libdnet/WinPcap +# freebsd = FreeBSD libpcap +# winpcap = WinPcap with receive thread +# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y) +# none = Empty template +#CONFIG_L2_PACKET=linux + +# Disable Linux packet socket workaround applicable for station interface +# in a bridge for EAPOL frames. This should be uncommented only if the kernel +# is known to not have the regression issue in packet socket behavior with +# bridge interfaces (commit 'bridge: respect RFC2863 operational state')'). +#CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y + +# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS) +CONFIG_PEERKEY=y + +# IEEE 802.11w (management frame protection), also known as PMF +# Driver support is also needed for IEEE 802.11w. +CONFIG_IEEE80211W=y + +# Support Operating Channel Validation +#CONFIG_OCV=y + +# Select TLS implementation +# openssl = OpenSSL (default) +# gnutls = GnuTLS +# internal = Internal TLSv1 implementation (experimental) +# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) +# none = Empty template +CONFIG_TLS=openssl + +# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) +# can be enabled to get a stronger construction of messages when block ciphers +# are used. It should be noted that some existing TLS v1.0 -based +# implementation may not be compatible with TLS v1.1 message (ClientHello is +# sent prior to negotiating which version will be used) +#CONFIG_TLSV11=y + +# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) +# can be enabled to enable use of stronger crypto algorithms. It should be +# noted that some existing TLS v1.0 -based implementation may not be compatible +# with TLS v1.2 message (ClientHello is sent prior to negotiating which version +# will be used) +#CONFIG_TLSV12=y + +# Select which ciphers to use by default with OpenSSL if the user does not +# specify them. +#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" + +# If CONFIG_TLS=internal is used, additional library and include paths are +# needed for LibTomMath. Alternatively, an integrated, minimal version of +# LibTomMath can be used. See beginning of libtommath.c for details on benefits +# and drawbacks of this option. +CONFIG_INTERNAL_LIBTOMMATH=y +#ifndef CONFIG_INTERNAL_LIBTOMMATH +#LTM_PATH=/usr/src/libtommath-0.39 +#CFLAGS += -I$(LTM_PATH) +#LIBS += -L$(LTM_PATH) +#LIBS_p += -L$(LTM_PATH) +#endif +# At the cost of about 4 kB of additional binary size, the internal LibTomMath +# can be configured to include faster routines for exptmod, sqr, and div to +# speed up DH and RSA calculation considerably +CONFIG_INTERNAL_LIBTOMMATH_FAST=y + +# Include NDIS event processing through WMI into wpa_supplicant/wpasvc. +# This is only for Windows builds and requires WMI-related header files and +# WbemUuid.Lib from Platform SDK even when building with MinGW. +#CONFIG_NDIS_EVENTS_INTEGRATED=y +#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib" + +# Add support for new DBus control interface +# (fi.w1.hostap.wpa_supplicant1) +#CONFIG_CTRL_IFACE_DBUS_NEW=y + +# Add introspection support for new DBus control interface +#CONFIG_CTRL_IFACE_DBUS_INTRO=y + +# Add support for loading EAP methods dynamically as shared libraries. +# When this option is enabled, each EAP method can be either included +# statically (CONFIG_EAP_=y) or dynamically (CONFIG_EAP_=dyn). +# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to +# be loaded in the beginning of the wpa_supplicant configuration file +# (see load_dynamic_eap parameter in the example file) before being used in +# the network blocks. +# +# Note that some shared parts of EAP methods are included in the main program +# and in order to be able to use dynamic EAP methods using these parts, the +# main program must have been build with the EAP method enabled (=y or =dyn). +# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries +# unless at least one of them was included in the main build to force inclusion +# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included +# in the main build to be able to load these methods dynamically. +# +# Please also note that using dynamic libraries will increase the total binary +# size. Thus, it may not be the best option for targets that have limited +# amount of memory/flash. +#CONFIG_DYNAMIC_EAP_METHODS=y + +# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode +CONFIG_IEEE80211R=y + +# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt) +#CONFIG_DEBUG_FILE=y + +# Send debug messages to syslog instead of stdout +CONFIG_DEBUG_SYSLOG=y +# Set syslog facility for debug messages +#CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON + +# Add support for sending all debug messages (regardless of debug verbosity) +# to the Linux kernel tracing facility. This helps debug the entire stack by +# making it easy to record everything happening from the driver up into the +# same file, e.g., using trace-cmd. +#CONFIG_DEBUG_LINUX_TRACING=y + +# Add support for writing debug log to Android logcat instead of standard +# output +#CONFIG_ANDROID_LOG=y + +# Enable privilege separation (see README 'Privilege separation' for details) +#CONFIG_PRIVSEP=y + +# Enable mitigation against certain attacks against TKIP by delaying Michael +# MIC error reports by a random amount of time between 0 and 60 seconds +#CONFIG_DELAYED_MIC_ERROR_REPORT=y + +# Enable tracing code for developer debugging +# This tracks use of memory allocations and other registrations and reports +# incorrect use with a backtrace of call (or allocation) location. +#CONFIG_WPA_TRACE=y +# For BSD, uncomment these. +#LIBS += -lexecinfo +#LIBS_p += -lexecinfo +#LIBS_c += -lexecinfo + +# Use libbfd to get more details for developer debugging +# This enables use of libbfd to get more detailed symbols for the backtraces +# generated by CONFIG_WPA_TRACE=y. +#CONFIG_WPA_TRACE_BFD=y +# For BSD, uncomment these. +#LIBS += -lbfd -liberty -lz +#LIBS_p += -lbfd -liberty -lz +#LIBS_c += -lbfd -liberty -lz + +# wpa_supplicant depends on strong random number generation being available +# from the operating system. os_get_random() function is used to fetch random +# data when needed, e.g., for key generation. On Linux and BSD systems, this +# works by reading /dev/urandom. It should be noted that the OS entropy pool +# needs to be properly initialized before wpa_supplicant is started. This is +# important especially on embedded devices that do not have a hardware random +# number generator and may by default start up with minimal entropy available +# for random number generation. +# +# As a safety net, wpa_supplicant is by default trying to internally collect +# additional entropy for generating random data to mix in with the data fetched +# from the OS. This by itself is not considered to be very strong, but it may +# help in cases where the system pool is not initialized properly. However, it +# is very strongly recommended that the system pool is initialized with enough +# entropy either by using hardware assisted random number generator or by +# storing state over device reboots. +# +# wpa_supplicant can be configured to maintain its own entropy store over +# restarts to enhance random number generation. This is not perfect, but it is +# much more secure than using the same sequence of random numbers after every +# reboot. This can be enabled with -e command line option. The +# specified file needs to be readable and writable by wpa_supplicant. +# +# If the os_get_random() is known to provide strong random data (e.g., on +# Linux/BSD, the board in question is known to have reliable source of random +# data from /dev/urandom), the internal wpa_supplicant random pool can be +# disabled. This will save some in binary size and CPU use. However, this +# should only be considered for builds that are known to be used on devices +# that meet the requirements described above. +CONFIG_NO_RANDOM_POOL=y + +# Should we attempt to use the getrandom(2) call that provides more reliable +# yet secure randomness source than /dev/random on Linux 3.17 and newer. +# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. +CONFIG_GETRANDOM=y + +# IEEE 802.11n (High Throughput) support (mainly for AP mode) +#CONFIG_IEEE80211N=y + +# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode) +# (depends on CONFIG_IEEE80211N) +#CONFIG_IEEE80211AC=y + +# Wireless Network Management (IEEE Std 802.11v-2011) +# Note: This is experimental and not complete implementation. +#CONFIG_WNM=y + +# Interworking (IEEE 802.11u) +# This can be used to enable functionality to improve interworking with +# external networks (GAS/ANQP to learn more about the networks and network +# selection based on available credentials). +#CONFIG_INTERWORKING=y + +# Hotspot 2.0 +#CONFIG_HS20=y + +# Enable interface matching in wpa_supplicant +#CONFIG_MATCH_IFACE=y + +# Disable roaming in wpa_supplicant +#CONFIG_NO_ROAMING=y + +# AP mode operations with wpa_supplicant +# This can be used for controlling AP mode operations with wpa_supplicant. It +# should be noted that this is mainly aimed at simple cases like +# WPA2-Personal while more complex configurations like WPA2-Enterprise with an +# external RADIUS server can be supported with hostapd. +#CONFIG_AP=y + +# P2P (Wi-Fi Direct) +# This can be used to enable P2P support in wpa_supplicant. See README-P2P for +# more information on P2P operations. +#CONFIG_P2P=y + +# Enable TDLS support +#CONFIG_TDLS=y + +# Wi-Fi Display +# This can be used to enable Wi-Fi Display extensions for P2P using an external +# program to control the additional information exchanges in the messages. +#CONFIG_WIFI_DISPLAY=y + +# Autoscan +# This can be used to enable automatic scan support in wpa_supplicant. +# See wpa_supplicant.conf for more information on autoscan usage. +# +# Enabling directly a module will enable autoscan support. +# For exponential module: +#CONFIG_AUTOSCAN_EXPONENTIAL=y +# For periodic module: +#CONFIG_AUTOSCAN_PERIODIC=y + +# Password (and passphrase, etc.) backend for external storage +# These optional mechanisms can be used to add support for storing passwords +# and other secrets in external (to wpa_supplicant) location. This allows, for +# example, operating system specific key storage to be used +# +# External password backend for testing purposes (developer use) +#CONFIG_EXT_PASSWORD_TEST=y + +# Enable Fast Session Transfer (FST) +#CONFIG_FST=y + +# Enable CLI commands for FST testing +#CONFIG_FST_TEST=y + +# OS X builds. This is only for building eapol_test. +#CONFIG_OSX=y + +# Automatic Channel Selection +# This will allow wpa_supplicant to pick the channel automatically when channel +# is set to "0". +# +# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative +# to "channel=0". This would enable us to eventually add other ACS algorithms in +# similar way. +# +# Automatic selection is currently only done through initialization, later on +# we hope to do background checks to keep us moving to more ideal channels as +# time goes by. ACS is currently only supported through the nl80211 driver and +# your driver must have survey dump capability that is filled by the driver +# during scanning. +# +# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with +# a newly to create wpa_supplicant.conf variable acs_num_scans. +# +# Supported ACS drivers: +# * ath9k +# * ath5k +# * ath10k +# +# For more details refer to: +# http://wireless.kernel.org/en/users/Documentation/acs +#CONFIG_ACS=y + +# Support Multi Band Operation +#CONFIG_MBO=y + +# Fast Initial Link Setup (FILS) (IEEE 802.11ai) +#CONFIG_FILS=y +# FILS shared key authentication with PFS +#CONFIG_FILS_SK_PFS=y + +# Support RSN on IBSS networks +# This is needed to be able to use mode=1 network profile with proto=RSN and +# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None). +CONFIG_IBSS_RSN=y + +# External PMKSA cache control +# This can be used to enable control interface commands that allow the current +# PMKSA cache entries to be fetched and new entries to be added. +#CONFIG_PMKSA_CACHE_EXTERNAL=y + +# Mesh Networking (IEEE 802.11s) +CONFIG_MESH=y + +# Background scanning modules +# These can be used to request wpa_supplicant to perform background scanning +# operations for roaming within an ESS (same SSID). See the bgscan parameter in +# the wpa_supplicant.conf file for more details. +# Periodic background scans based on signal strength +CONFIG_BGSCAN_SIMPLE=y +# Learn channels used by the network and try to avoid bgscans on other +# channels (experimental) +#CONFIG_BGSCAN_LEARN=y + +# Opportunistic Wireless Encryption (OWE) +# Experimental implementation of draft-harkins-owe-07.txt +#CONFIG_OWE=y + +# Device Provisioning Protocol (DPP) +# This requires CONFIG_IEEE80211W=y to be enabled, too. (see +# wpa_supplicant/README-DPP for details) +#CONFIG_DPP=y + +# uBus IPC/RPC System +# Services can connect to the bus and provide methods +# that can be called by other services or clients. +# CONFIG_UBUS=y + +# OpenWrt patch 380-disable-ctrl-iface-mib.patch +# leads to the MIB only being compiled in if +# CONFIG_CTRL_IFACE_MIB is enabled. +# CONFIG_CTRL_IFACE_MIB=y diff --git a/recipes-connectivity/hostapd/hostapd.inc b/recipes-connectivity/hostapd/hostapd.inc new file mode 100644 index 0000000..7b9cfae --- /dev/null +++ b/recipes-connectivity/hostapd/hostapd.inc @@ -0,0 +1,113 @@ +HOMEPAGE = "http://w1.fi/${PN}/" +BUGTRACKER = "http://w1.fi/security/" +SECTION = "network" +LICENSE = "BSD" +LIC_FILES_CHKSUM = "file://COPYING;md5=279b4f5abb9c153c285221855ddb78cc \ + file://README;beginline=1;endline=56;md5=e7d3dbb01f75f0b9799e192731d1e1ff \ + file://wpa_supplicant/wpa_supplicant.c;beginline=1;endline=12;md5=0a8b56d3543498b742b9c0e94cc2d18b" +DEPENDS = "libnl-tiny" +PACKAGECONFIG ??= "gnutls" +PACKAGECONFIG[gnutls] = ",,gnutls libgcrypt" +PACKAGECONFIG[openssl] = ",,openssl" + +inherit pkgconfig + +PACKAGECONFIG = "openssl" + +SRC_URI = "git://w1.fi/hostap.git;protocol=http \ + file://004-mesh-use-setup-completion-callback-to-complete-mesh-.patch \ + file://005-mesh-update-ssid-frequency-as-pri-sec-channel-switch.patch \ + file://006-mesh-inform-kernel-driver-DFS-handler-in-userspace.patch \ + file://007-mesh-apply-channel-attributes-before-running-Mesh.patch \ + file://011-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch \ + file://013-mesh-do-not-allow-pri-sec-channel-switch.patch \ + file://015-mesh-do-not-use-offchan-mgmt-tx-on-DFS.patch \ + file://016-mesh-fix-channel-switch-error-during-CAC.patch \ + file://018-mesh-make-forwarding-configurable.patch \ + file://051-wpa_supplicant-fix-race-condition-in-mesh-mpm-new-pe.patch \ + file://067-0001-AP-Silently-ignore-management-frame-from-unexpected-.patch \ + file://070-driver_nl80211-fix-WMM-queue-mapping-for-regulatory-.patch \ + file://071-driver_nl80211-fix-regulatory-limits-for-wmm-cwmin-c.patch \ + file://090-wolfssl-fix-crypto_bignum_sum.patch \ + file://100-daemonize_fix.patch \ + file://200-multicall.patch \ + file://300-noscan.patch \ + file://301-mesh-noscan.patch \ + file://310-rescan_immediately.patch \ + file://320-optional_rfkill.patch \ + file://330-nl80211_fix_set_freq.patch \ + file://340-reload_freq_change.patch \ + file://341-mesh-ctrl-iface-channel-switch.patch \ + file://350-nl80211_del_beacon_bss.patch \ + file://360-ctrl_iface_reload.patch \ + file://370-ap_sta_support.patch \ + file://380-disable_ctrl_iface_mib.patch \ + file://381-hostapd_cli_UNKNOWN-COMMAND.patch \ + file://390-wpa_ie_cap_workaround.patch \ + file://400-wps_single_auth_enc_type.patch \ + file://410-limit_debug_messages.patch \ + file://420-indicate-features.patch \ + file://430-hostapd_cli_ifdef.patch \ + file://431-wpa_cli_ifdef.patch \ + file://432-missing-typedef.patch \ + file://450-scan_wait.patch \ + file://460-wpa_supplicant-add-new-config-params-to-be-used-with.patch \ + file://461-driver_nl80211-use-new-parameters-during-ibss-join.patch \ + file://463-add-mcast_rate-to-11s.patch \ + file://464-fix-mesh-obss-check.patch \ + file://470-survey_data_fallback.patch \ + file://500-lto-jobserver-support.patch \ + file://599-wpa_supplicant-fix-warnings.patch \ + file://700-wifi-reload.patch \ + file://800-usleep.patch \ + file://914-wlan-acs-srd-channels.patch \ + file://913-iapp-improvements.patch \ + file://src/utils/build_features.h \ + file://0001-Add-build-artifact-build_features.h-to-gitignore.patch \ + file://0002-Use-environment-variable-EXTRA_CFLAGS.patch \ + file://wpa_supplicant-full.config \ + file://hostapd-full.config \ + " + +SRCREV = "ca8c2bd28ad53f431d6ee60ef754e98cfdb4c17b" +SRC_URI[md5sum] = "a68538fb62766f40f890125026c42c10" +SRC_URI[sha256sum] = "9d9f1c60afa5324ee17219bd3ec61c1a6fa4043b4187da9bb44e59025d3ed31d" + +CVE_PRODUCT = "${TARGET_NAME}" +CONFFILES_${TARGET_NAME} += "${sysconfdir}/${TARGET_NAME}-full.config" + +S = "${WORKDIR}/git" + +export EXTRA_CFLAGS = " \ + ${CFLAGS} \ + -I${STAGING_DIR_TARGET}/usr/include/libnl-tiny \ + -lnl-tiny \ + -DCONFIG_LIBNL20 \ + -DCONFIG_LIBNL_TINY \ + -D_GNU_SOURCE \ +" +LDFLAGS += " -Wl,--gc-sections" + +export BINDIR = "${sbindir}" + +do_configure () { + ${MAKE} -C ${TARGET_NAME} clean + install -m 0755 ${WORKDIR}/${TARGET_NAME}-full.config ${TARGET_NAME}/.config + install -m 0755 ${WORKDIR}/src/utils/build_features.h src/utils/build_features.h + if echo "${PACKAGECONFIG}" | grep -qw "openssl"; then + ssl=openssl + elif echo "${PACKAGECONFIG}" | grep -qw "gnutls"; then + ssl=gnutls + fi + if [ -n "$ssl" ]; then + sed -i "s/%ssl%/$ssl/" ${TARGET_NAME}/.config + fi + + # For rebuild + rm -f ${TARGET_NAME}/*.d ${TARGET_NAME}/dbus/*.d +} + +do_compile () { + unset CFLAGS CPPFLAGS CXXFLAGS + oe_runmake -C ${TARGET_NAME} +} diff --git a/recipes-connectivity/hostapd/hostapd_2.9.bb b/recipes-connectivity/hostapd/hostapd_2.9.bb new file mode 100644 index 0000000..99c4f8b --- /dev/null +++ b/recipes-connectivity/hostapd/hostapd_2.9.bb @@ -0,0 +1,16 @@ +SUMMARY = "Authenticator for Wi-Fi Protected Access (WPA)" + +TARGET_NAME = "hostapd" + +include hostapd.inc + +RRECOMMENDS_${PN}_${PV} = "hostapd-cli" + +PACKAGES_prepend = "hostapd-cli" +FILES_hostpad-cli = "${sbindir}/hostapd_cli" + +do_install () { + install -d ${D}${sbindir} + install -m 755 hostapd/hostapd ${D}${sbindir} + install -m 755 hostapd/hostapd_cli ${D}${sbindir} +} diff --git a/recipes-connectivity/hostapd/wpa-supplicant_2.9.bb b/recipes-connectivity/hostapd/wpa-supplicant_2.9.bb new file mode 100644 index 0000000..847154b --- /dev/null +++ b/recipes-connectivity/hostapd/wpa-supplicant_2.9.bb @@ -0,0 +1,26 @@ +SUMMARY = "Client for Wi-Fi Protected Access (WPA)" + +TARGET_NAME = "wpa_supplicant" +include hostapd.inc + +RRECOMMENDS_${PN}_${PV} = "wpa_supplicant-passphrase wpa_supplicant-cli" + + +PACKAGES_prepend = "wpa_supplicant-passphrase wpa_supplicant-cli" +FILES_wpa_supplicant-passphrase = "${bindir}/wpa_passphrase" +FILES_wpa_supplicant-cli = "${sbindir}/wpa_cli" +FILES_${PN} += "${datadir}/dbus-1/system-services/*" + +do_install () { + install -d ${D}${sbindir} + install -m 755 wpa_supplicant/wpa_supplicant ${D}${sbindir} + install -m 755 wpa_supplicant/wpa_cli ${D}${sbindir} +} + +pkg_postinst_wpa_supplicant () { + # If we're offline, we don't need to do this. + if [ "x$D" = "x" ]; then + killall -q -HUP dbus-daemon || true + fi + +}