aboutsummaryrefslogtreecommitdiffstats
path: root/package/network/services/hostapd/patches
diff options
context:
space:
mode:
authorJohn Crispin <john@phrozen.org>2019-10-30 16:57:22 +0100
committerDaniel Golle <daniel@makrotopia.org>2019-11-12 11:52:26 +0100
commit60fb4c92b6b0d1582d31e02167b90b424185f3a2 (patch)
treef707a8fe5cc2e1abf21b51d38f9767f1b1d69996 /package/network/services/hostapd/patches
parent155ede4f1fdb192b11f8ae2dbffda5f7ef4903bd (diff)
downloadupstream-60fb4c92b6b0d1582d31e02167b90b424185f3a2.tar.gz
upstream-60fb4c92b6b0d1582d31e02167b90b424185f3a2.tar.bz2
upstream-60fb4c92b6b0d1582d31e02167b90b424185f3a2.zip
hostapd: add ubus reload
Add ubus interface to hostapd and wpa_supplicant to allow dynamically reloading wiface configuration without having to restart the hostapd process. As a consequence, both hostapd and wpa_supplicant are now started persistently on boot for each wifi device in the system and then receive ubus calls adding, modifying or removing interface configuration. At a later stage it would be desirable to reduce the services to one single instance managing all radios. Signed-off-by: John Crispin <john@phrozen.org> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Diffstat (limited to 'package/network/services/hostapd/patches')
-rw-r--r--package/network/services/hostapd/patches/600-ubus_support.patch127
-rw-r--r--package/network/services/hostapd/patches/700-wifi-reload.patch118
2 files changed, 243 insertions, 2 deletions
diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch
index 0eb0a4a3ba..6842c0e63e 100644
--- a/package/network/services/hostapd/patches/600-ubus_support.patch
+++ b/package/network/services/hostapd/patches/600-ubus_support.patch
@@ -22,7 +22,16 @@
#define OCE_STA_CFON_ENABLED(hapd) \
((hapd->conf->oce & OCE_STA_CFON) && \
-@@ -145,6 +146,7 @@ struct hostapd_data {
+@@ -72,6 +73,8 @@ struct hapd_interfaces {
+ #ifdef CONFIG_DPP
+ struct dpp_global *dpp;
+ #endif /* CONFIG_DPP */
++ struct ubus_object ubus;
++ char *name;
+ };
+
+ enum hostapd_chan_status {
+@@ -145,6 +148,7 @@ struct hostapd_data {
struct hostapd_iface *iface;
struct hostapd_config *iconf;
struct hostapd_bss_config *conf;
@@ -30,6 +39,14 @@
int interface_added; /* virtual interface added for this BSS */
unsigned int started:1;
unsigned int disabled:1;
+@@ -580,6 +584,7 @@ hostapd_alloc_bss_data(struct hostapd_if
+ struct hostapd_bss_config *bss);
+ int hostapd_setup_interface(struct hostapd_iface *iface);
+ int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err);
++void hostapd_set_own_neighbor_report(struct hostapd_data *hapd);
+ void hostapd_interface_deinit(struct hostapd_iface *iface);
+ void hostapd_interface_free(struct hostapd_iface *iface);
+ struct hostapd_iface * hostapd_alloc_iface(void);
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -380,6 +380,7 @@ static void hostapd_free_hapd_data(struc
@@ -298,6 +315,36 @@
/* Remove interface from the global list of interfaces */
prev = global->ifaces;
if (prev == wpa_s) {
+@@ -6520,6 +6524,8 @@ struct wpa_global * wpa_supplicant_init(
+ if (params->override_ctrl_interface)
+ global->params.override_ctrl_interface =
+ os_strdup(params->override_ctrl_interface);
++ if (params->name)
++ global->params.name = os_strdup(params->name);
+ #ifdef CONFIG_MATCH_IFACE
+ global->params.match_iface_count = params->match_iface_count;
+ if (params->match_iface_count) {
+@@ -6626,8 +6632,12 @@ int wpa_supplicant_run(struct wpa_global
+ eloop_register_signal_terminate(wpa_supplicant_terminate, global);
+ eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
+
++ wpas_ubus_add(global);
++
+ eloop_run();
+
++ wpas_ubus_free(global);
++
+ return 0;
+ }
+
+@@ -6687,6 +6697,7 @@ void wpa_supplicant_deinit(struct wpa_gl
+ #ifdef CONFIG_MATCH_IFACE
+ os_free(global->params.match_ifaces);
+ #endif /* CONFIG_MATCH_IFACE */
++ os_free(global->params.name);
+ #ifdef CONFIG_P2P
+ os_free(global->params.conf_p2p_dev);
+ #endif /* CONFIG_P2P */
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -17,6 +17,7 @@
@@ -308,7 +355,25 @@
extern const char *const wpa_supplicant_version;
extern const char *const wpa_supplicant_license;
-@@ -506,6 +507,7 @@ struct wpa_supplicant {
+@@ -246,6 +247,8 @@ struct wpa_params {
+ */
+ int match_iface_count;
+ #endif /* CONFIG_MATCH_IFACE */
++
++ char *name;
+ };
+
+ struct p2p_srv_bonjour {
+@@ -306,6 +309,8 @@ struct wpa_global {
+ #endif /* CONFIG_WIFI_DISPLAY */
+
+ struct psk_list_entry *add_psk; /* From group formation */
++
++ struct ubus_object ubus_global;
+ };
+
+
+@@ -506,6 +511,7 @@ struct wpa_supplicant {
unsigned char own_addr[ETH_ALEN];
unsigned char perm_addr[ETH_ALEN];
char ifname[100];
@@ -335,3 +400,61 @@
if (wpa_s->conf->wps_cred_processing == 1)
return 0;
+--- a/hostapd/main.c
++++ b/hostapd/main.c
+@@ -688,7 +688,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:g:G:v::");
++ c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:g:G:n:v::");
+ if (c < 0)
+ break;
+ switch (c) {
+@@ -763,6 +763,8 @@ int main(int argc, char *argv[])
+ if (hostapd_get_interface_names(&if_names,
+ &if_names_size, optarg))
+ goto out;
++ case 'n':
++ interfaces.name = optarg;
+ break;
+ default:
+ usage();
+@@ -894,6 +896,7 @@ int main(int argc, char *argv[])
+ }
+
+ hostapd_global_ctrl_iface_init(&interfaces);
++ hostapd_ubus_add(&interfaces);
+
+ if (hostapd_global_run(&interfaces, daemonize, pid_file)) {
+ wpa_printf(MSG_ERROR, "Failed to start eloop");
+@@ -903,6 +906,7 @@ int main(int argc, char *argv[])
+ ret = 0;
+
+ out:
++ hostapd_ubus_free(&interfaces);
+ hostapd_global_ctrl_iface_deinit(&interfaces);
+ /* Deinitialize all interfaces */
+ for (i = 0; i < interfaces.count; i++) {
+--- a/wpa_supplicant/main.c
++++ b/wpa_supplicant/main.c
+@@ -203,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:qsTtuv::W");
++ "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:n:No:O:p:P:qsTtuv::W");
+ if (c < 0)
+ break;
+ switch (c) {
+@@ -271,6 +271,10 @@ int main(int argc, char *argv[])
+ params.conf_p2p_dev = optarg;
+ break;
+ #endif /* CONFIG_P2P */
++ case 'n':
++ params.name = optarg;
++ iface_count = 0;
++ break;
+ case 'o':
+ params.override_driver = optarg;
+ break;
diff --git a/package/network/services/hostapd/patches/700-wifi-reload.patch b/package/network/services/hostapd/patches/700-wifi-reload.patch
new file mode 100644
index 0000000000..c5ba631a0f
--- /dev/null
+++ b/package/network/services/hostapd/patches/700-wifi-reload.patch
@@ -0,0 +1,118 @@
+--- a/hostapd/config_file.c
++++ b/hostapd/config_file.c
+@@ -2470,6 +2470,8 @@ static int hostapd_config_fill(struct ho
+ 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) {
+--- a/src/ap/ap_config.c
++++ b/src/ap/ap_config.c
+@@ -698,6 +698,7 @@ void hostapd_config_free_bss(struct host
+ 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);
+--- 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;
+ };
+
+ /**
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -242,13 +242,13 @@ int hostapd_reload_config(struct hostapd
+ if (newconf == NULL)
+ return -1;
+
+- hostapd_clear_old(iface);
+-
+ oldconf = hapd->iconf;
+ if (hostapd_iface_conf_changed(newconf, oldconf)) {
+ char *fname;
+ int res;
+
++ 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 +273,22 @@ int hostapd_reload_config(struct hostapd
+ 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 +305,12 @@ int hostapd_reload_config(struct hostapd
+
+ 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);
+@@ -2257,6 +2279,10 @@ hostapd_alloc_bss_data(struct hostapd_if
+ hapd->iconf = conf;
+ hapd->conf = bss;
+ hapd->iface = hapd_iface;
++ if (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;
+--- a/src/ap/hostapd.h
++++ b/src/ap/hostapd.h
+@@ -149,6 +149,7 @@ struct hostapd_data {
+ struct hostapd_config *iconf;
+ struct hostapd_bss_config *conf;
+ struct hostapd_ubus_bss ubus;
++ char *config_id;
+ int interface_added; /* virtual interface added for this BSS */
+ unsigned int started:1;
+ unsigned int disabled:1;
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -4295,6 +4295,9 @@ static int wpa_driver_nl80211_set_ap(voi
+ 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,