wifi-2075- Fix for inconsistency in applying vif configuration

- During the configuration process, AP was triggering network
   and wireless reload multiple times in a very short window
   resulting in a poorly configured hostapd. This patch makes sure
   that network/wireless is reloaded only once after all the configuration
   is committed to UCI files.

Signed-off-by: Yashvardhan <yashvardhan@netexperience.com>
This commit is contained in:
Yashvardhan
2021-06-12 10:10:13 -07:00
committed by Rick Sommerville
parent 1791870562
commit 39bd8f30c0
10 changed files with 169 additions and 59 deletions

View File

@@ -159,7 +159,6 @@ static void syslog_handler(int type,
blob_to_uci_section(uci, "system", "@system[-1]", "system",
b.head, &log_param, NULL);
uci_commit_all(uci);
system("/sbin/reload_config");
if (del)
node_state_del("syslog");
else
@@ -252,7 +251,6 @@ static void ntp_handler(int type,
blob_to_uci_section(uci, "system", "ntp", "timeserver",
b.head, &ntp_param, NULL);
uci_commit_all(uci);
system("/sbin/reload_config");
ntp_state(0);
}
@@ -376,7 +374,6 @@ static void led_handler(int type,
globfree(&gl);
}
uci_commit_all(uci);
system("/sbin/reload_config");
led_state(0);
}

View File

@@ -3,6 +3,10 @@
#ifndef _RADIO_H__
#define _RADIO_H__
#include "ovsdb_update.h"
#define CONFIG_APPLY_TIMEOUT 35
struct rrm_neighbor {
char *mac;
char *ssid;
@@ -10,7 +14,6 @@ struct rrm_neighbor {
};
extern const struct target_radio_ops *radio_ops;
extern int reload_config;
extern struct blob_buf b;
extern struct uci_context *uci;
@@ -22,5 +25,6 @@ extern int hapd_rrm_set_neighbors(char *name, struct rrm_neighbor *neigh, int co
extern void radio_maverick(void *arg);
int nl80211_channel_get(char *name, unsigned int *chan);
void set_config_apply_timeout(ovsdb_update_monitor_t *mon);
#endif

View File

@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#ifndef __TIMER_H__
#define __TIMER_H__
#include <sys/time.h>
struct timeout;
typedef void (*timeout_handler)(struct timeout *t);
struct timeout {
bool pending;
timeout_handler cb;
struct timeval time;
};
int timeout_set(struct timeout *timeout, int msecs);
void timer_expiry_check(struct timeout *timeout);
#endif

View File

@@ -47,6 +47,7 @@ UNIT_SRC_TOP += $(OVERRIDE_DIR)/src/dhcpdiscovery.c
UNIT_SRC_TOP += $(OVERRIDE_DIR)/src/radius_probe.c
UNIT_SRC_TOP += $(OVERRIDE_DIR)/src/rrm_config.c
UNIT_SRC_TOP += $(OVERRIDE_DIR)/src/radius_proxy.c
UNIT_SRC_TOP += $(OVERRIDE_DIR)/src/timer.c
CONFIG_USE_KCONFIG=y
CONFIG_INET_ETH_LINUX=y

View File

@@ -27,6 +27,7 @@
#include "rrm_config.h"
#include "vlan.h"
#include "radius_proxy.h"
#include "timer.h"
ovsdb_table_t table_Hotspot20_Config;
ovsdb_table_t table_Hotspot20_OSU_Providers;
@@ -35,6 +36,10 @@ ovsdb_table_t table_Radius_Proxy_Config;
ovsdb_table_t table_APC_Config;
ovsdb_table_t table_APC_State;
ovsdb_table_t table_Wifi_VIF_Config;
ovsdb_table_t table_Wifi_Inet_Config;
ovsdb_table_t table_Node_Config;
unsigned int radproxy_apc = 0;
extern json_t* ovsdb_table_where(ovsdb_table_t *table, void *record);
@@ -42,7 +47,6 @@ static struct uci_package *wireless;
struct uci_context *uci;
struct blob_buf b = { };
struct blob_buf del = { };
int reload_config = 0;
static struct timespec startup_time;
enum {
@@ -488,20 +492,14 @@ bool target_radio_config_set2(const struct schema_Wifi_Radio_Config *rconf,
blob_to_uci_section(uci, "wireless", rconf->if_name, "wifi-device",
b.head, &wifi_device_param, del.head);
reload_config = 1;
uci_commit_all(uci);
return true;
}
static void periodic_task(void *arg)
{
static int counter = 0;
struct uci_element *e = NULL, *tmp = NULL;
int ret = 0;
if ((counter % 15) && !reload_config)
goto done;
struct uci_element *e = NULL, *tmp = NULL;
if (startup_time.tv_sec) {
static struct timespec current_time;
@@ -512,20 +510,11 @@ static void periodic_task(void *arg)
radio_maverick(NULL);
}
}
if (reload_config) {
LOGD("periodic: reload_config");
reload_config = 0;
uci_commit_all(uci);
sync();
system("reload_config");
}
LOGD("periodic: start state update ");
ret = uci_load(uci, "wireless", &wireless);
if (ret) {
LOGE("%s: uci_load() failed with rc %d", __func__, ret);
return;
goto out;
}
uci_foreach_element_safe(&wireless->sections, tmp, e) {
struct uci_section *s = uci_to_section(e);
@@ -543,9 +532,8 @@ static void periodic_task(void *arg)
uci_unload(uci, wireless);
LOGD("periodic: stop state update ");
done:
counter++;
evsched_task_reschedule_ms(EVSCHED_SEC(1));
out:
evsched_task_reschedule_ms(EVSCHED_SEC(15));
}
bool target_radio_config_init2(void)
@@ -578,7 +566,6 @@ bool target_radio_config_init2(void)
}
if (invalidVifFound) {
uci_commit(uci, &wireless, false);
reload_config = 1;
}
uci_unload(uci, wireless);
@@ -661,6 +648,7 @@ void radio_maverick(void *arg)
uci_unload(uci, wireless);
}
static void callback_Hotspot20_Config(ovsdb_update_monitor_t *mon,
struct schema_Hotspot20_Config *old,
struct schema_Hotspot20_Config *conf)
@@ -680,6 +668,7 @@ static void callback_Hotspot20_Config(ovsdb_update_monitor_t *mon,
LOG(ERR, "Hotspot20_Config: unexpected mon_type %d %s", mon->mon_type, mon->mon_uuid);
break;
}
set_config_apply_timeout(mon);
return;
}
@@ -703,6 +692,7 @@ static void callback_Hotspot20_OSU_Providers(ovsdb_update_monitor_t *mon,
mon->mon_type, mon->mon_uuid);
break;
}
set_config_apply_timeout(mon);
return;
}
@@ -727,6 +717,7 @@ static void callback_Hotspot20_Icon_Config(ovsdb_update_monitor_t *mon,
mon->mon_type, mon->mon_uuid);
break;
}
set_config_apply_timeout(mon);
return;
}
@@ -1032,6 +1023,51 @@ void apc_init()
}
static void apply_config_handler(struct timeout *timeout)
{
uci_commit_all(uci);
sync();
LOGI("====Calling reload_config====");
system("/sbin/reload_config");
}
static struct timeout config_timer = {
.cb = apply_config_handler
};
static void config_timer_task(void *arg)
{
timer_expiry_check(&config_timer);
evsched_task_reschedule_ms(EVSCHED_SEC(1));
}
void set_config_apply_timeout(ovsdb_update_monitor_t *mon)
{
static bool firstconfig = true;
LOGI("=====Received config update - table:%s uuid:%s Action:%d======", mon->mon_table, mon->mon_uuid, mon->mon_type);
if(firstconfig) {
firstconfig = false;
timeout_set(&config_timer, CONFIG_APPLY_TIMEOUT * 1000);
evsched_task(&config_timer_task, NULL, EVSCHED_SEC(1));
} else {
timeout_set(&config_timer, CONFIG_APPLY_TIMEOUT * 1000);
}
}
static void callback_Wifi_Inet_Config(ovsdb_update_monitor_t *mon,
struct schema_Wifi_Inet_Config *old_rec,
struct schema_Wifi_Inet_Config *iconf)
{
set_config_apply_timeout(mon);
}
static void callback_Node_Config(ovsdb_update_monitor_t *mon,
struct schema_Node_Config *old,
struct schema_Node_Config *conf)
{
set_config_apply_timeout(mon);
}
bool target_radio_init(const struct target_radio_ops *ops)
{
uci = uci_alloc_context();
@@ -1060,6 +1096,11 @@ bool target_radio_init(const struct target_radio_ops *ops)
OVSDB_TABLE_INIT(Radius_Proxy_Config, _uuid);
OVSDB_TABLE_MONITOR(Radius_Proxy_Config, false);
OVSDB_TABLE_INIT(Wifi_Inet_Config, _uuid);
OVSDB_TABLE_MONITOR(Wifi_Inet_Config, false);
OVSDB_TABLE_INIT(Node_Config, _uuid);
OVSDB_TABLE_MONITOR(Node_Config, false);
evsched_task(&periodic_task, NULL, EVSCHED_SEC(5));

View File

@@ -365,7 +365,6 @@ static bool radius_proxy_config_set(struct schema_Radius_Proxy_Config *conf)
blob_to_uci_section(uci, "radsecproxy", name, "realm",
uci_buf.head, &radius_proxy_realm_param, NULL);
}
uci_commit_all(uci);
return true;
}
@@ -394,7 +393,6 @@ static bool radius_proxy_config_delete()
uci_commit(rad_uci, &radsecproxy, false);
uci_unload(rad_uci, radsecproxy);
uci_free_context(rad_uci);
reload_config = 1;
return true;
}
@@ -419,7 +417,8 @@ void callback_Radius_Proxy_Config(ovsdb_update_monitor_t *self,
LOG(ERR, "Radius_Proxy_Config: unexpected mon_type %d %s",
self->mon_type, self->mon_uuid);
break;
}
}
set_config_apply_timeout(self);
return;
}

View File

@@ -178,7 +178,8 @@ void callback_Wifi_RRM_Config(ovsdb_update_monitor_t *self,
default:
LOG(ERR, "Wifi_RRM_Config: unexpected mon_type %d %s", self->mon_type, self->mon_uuid);
break;
}
}
set_config_apply_timeout(self);
return;
}

View File

@@ -0,0 +1,62 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
#include "log.h"
#include "evsched.h"
#include "timer.h"
static int tv_diff(struct timeval *t1, struct timeval *t2)
{
return
(t1->tv_sec - t2->tv_sec) * 1000 +
(t1->tv_usec - t2->tv_usec) / 1000;
}
static void gettime(struct timeval *tv)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
tv->tv_sec = ts.tv_sec;
tv->tv_usec = ts.tv_nsec / 1000;
}
int timeout_set(struct timeout *timeout, int msecs)
{
if (!timeout) {
LOGE("%s No timer data", __func__);
return -1;
}
struct timeval *time = &timeout->time;
if (timeout->pending)
timeout->pending = false;
gettime(time);
time->tv_sec += msecs / 1000;
time->tv_usec += (msecs % 1000) * 1000;
if (time->tv_usec > 1000000) {
time->tv_sec++;
time->tv_usec -= 1000000;
}
timeout->pending = true;
return 0;
}
void timer_expiry_check(struct timeout *t)
{
struct timeval tv;
gettime(&tv);
if (t->pending && tv_diff(&t->time, &tv) <= 0) {
t->pending = false;
LOGI("%s Timer Expired..Executing callback", __func__);
if (t->cb)
t->cb(t);
}
}

View File

@@ -1034,7 +1034,8 @@ void vif_section_del(char *section_name)
ret= uci_load(sec_ctx, "wireless", &wireless);
if (ret) {
LOGE("%s: %s uci_load() failed with rc %d", section_name, __func__, ret);
uci_free_context(sec_ctx);
if (sec_ctx)
uci_free_context(sec_ctx);
return;
}
uci_foreach_element_safe(&wireless->sections, tmp, e) {
@@ -1049,8 +1050,8 @@ void vif_section_del(char *section_name)
}
uci_commit(sec_ctx, &wireless, false);
uci_unload(sec_ctx, wireless);
uci_free_context(sec_ctx);
reload_config = 1;
if (sec_ctx)
uci_free_context(sec_ctx);
}
void vif_check_radius_proxy()
@@ -1326,7 +1327,8 @@ bool target_vif_config_del(const struct schema_Wifi_VIF_Config *vconf)
ret= uci_load(vif_ctx, "wireless", &wireless);
if (ret) {
LOGE("%s: %s uci_load() failed with rc %d", vconf->if_name, __func__, ret);
uci_free_context(vif_ctx);
if (vif_ctx)
uci_free_context(vif_ctx);
return false;
}
uci_foreach_element_safe(&wireless->sections, tmp, e) {
@@ -1346,8 +1348,8 @@ bool target_vif_config_del(const struct schema_Wifi_VIF_Config *vconf)
}
uci_commit(vif_ctx, &wireless, false);
uci_unload(vif_ctx, wireless);
uci_free_context(vif_ctx);
reload_config = 1;
if (vif_ctx)
uci_free_context(vif_ctx);
return true;
}
@@ -1402,7 +1404,7 @@ void vif_hs20_osu_update(struct schema_Hotspot20_OSU_Providers *osuconf)
blob_to_uci_section(uci, "wireless", osuconf->osu_provider_name, "osu-provider",
osu.head, &wifi_hs20_osu_param, NULL);
reload_config = 1;
uci_commit_all(uci);
}
@@ -1433,7 +1435,7 @@ void vif_hs20_icon_update(struct schema_Hotspot20_Icon_Config *iconconf)
blob_to_uci_section(uci, "wireless", iconconf->icon_config_name, "hs20-icon",
hs20.head, &wifi_hs20_icon_param, NULL);
reload_config = 1;
uci_commit_all(uci);
}
}
@@ -1456,9 +1458,9 @@ void vif_hs20_update(struct schema_Hotspot20_Config *hs2conf)
hs20_vif_config(&b, hs2conf);
blob_to_uci_section(uci, "wireless", vconf.if_name, "wifi-iface",
b.head, &wifi_iface_param, NULL);
reload_config = 1;
}
}
uci_commit_all(uci);
}
/* Mesh options table */
@@ -1526,8 +1528,7 @@ static int mesh_vif_config_set(const struct schema_Wifi_Radio_Config *rconf,
blobmsg_add_string(&mesh, "master", "bat0");
blob_to_uci_section(uci, "network", vconf->if_name, "interface",
mesh.head, &wifi_mesh_param, NULL);
reload_config = 1;
uci_commit_all(uci);
return 0;
}
@@ -1646,8 +1647,7 @@ static int ap_vif_config_set(const struct schema_Wifi_Radio_Config *rconf,
{
vif_dhcp_opennds_allowlist_set(vconf,(char*)vconf->if_name);
}
reload_config = 1;
uci_commit_all(uci);
return 0;
}

View File

@@ -75,7 +75,6 @@ const struct uci_blob_param_list network_param = {
.params = network_policy,
};
int reload_config = 0;
ovsdb_table_t table_Wifi_Inet_Config;
struct blob_buf b = { };
struct blob_buf del = { };
@@ -342,7 +341,6 @@ static int wifi_inet_conf_add(struct schema_Wifi_Inet_Config *iconf)
}
uci_commit_all(uci);
reload_config = 1;
return 0;
}
@@ -361,7 +359,6 @@ static void wifi_inet_conf_del(struct schema_Wifi_Inet_Config *iconf)
uci_section_del(uci, "network", "network", iconf->if_name, "interface");
uci_commit_all(uci);
reload_config = 1;
}
static void callback_Wifi_Inet_Config(ovsdb_update_monitor_t *mon,
@@ -388,17 +385,6 @@ static void callback_Wifi_Inet_Config(ovsdb_update_monitor_t *mon,
return;
}
static void periodic_task(void *arg)
{
if (reload_config) {
uci_commit_all(uci);
system("reload_config");
reload_config = 0;
}
evsched_task_reschedule_ms(EVSCHED_SEC(5));
}
void wifi_inet_config_init(void)
{
struct uci_element *e = NULL;
@@ -418,7 +404,6 @@ void wifi_inet_config_init(void)
}
uci_unload(uci, network);
OVSDB_TABLE_MONITOR(Wifi_Inet_Config, false);
evsched_task(&periodic_task, NULL, EVSCHED_SEC(5));
return;
}