mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-30 18:07:52 +00:00 
			
		
		
		
	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
					Yashvardhan
				
			
				
					committed by
					
						 Rick Sommerville
						Rick Sommerville
					
				
			
			
				
	
			
			
			 Rick Sommerville
						Rick Sommerville
					
				
			
						parent
						
							1bc19d3e99
						
					
				
				
					commit
					feac133dab
				
			| @@ -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); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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)); | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|  | ||||
| @@ -420,6 +418,7 @@ void callback_Radius_Proxy_Config(ovsdb_update_monitor_t *self, | ||||
| 				self->mon_type, self->mon_uuid); | ||||
| 		break; | ||||
| 	} | ||||
| 	set_config_apply_timeout(self); | ||||
| 	return; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -179,6 +179,7 @@ void callback_Wifi_RRM_Config(ovsdb_update_monitor_t *self, | ||||
| 		LOG(ERR, "Wifi_RRM_Config: unexpected mon_type %d %s", self->mon_type, self->mon_uuid); | ||||
| 		break; | ||||
| 	} | ||||
| 	set_config_apply_timeout(self); | ||||
| 	return; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
| 	} | ||||
| } | ||||
| @@ -1034,6 +1034,7 @@ 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); | ||||
| 		if (sec_ctx) | ||||
| 			uci_free_context(sec_ctx); | ||||
| 		return; | ||||
| 	} | ||||
| @@ -1049,8 +1050,8 @@ void vif_section_del(char *section_name) | ||||
| 	} | ||||
| 	uci_commit(sec_ctx, &wireless, false); | ||||
| 	uci_unload(sec_ctx, wireless); | ||||
| 	if (sec_ctx) | ||||
| 		uci_free_context(sec_ctx); | ||||
| 	reload_config = 1; | ||||
| } | ||||
|  | ||||
| void vif_check_radius_proxy() | ||||
| @@ -1326,6 +1327,7 @@ 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); | ||||
| 		if (vif_ctx) | ||||
| 			uci_free_context(vif_ctx); | ||||
| 		return false; | ||||
| 	} | ||||
| @@ -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); | ||||
| 	if (vif_ctx) | ||||
| 		uci_free_context(vif_ctx); | ||||
| 	reload_config = 1; | ||||
| 	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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user