mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 17:42:41 +00:00
wifi-2342 wifi-2343: APC BDR/DR swap fix and monitor cloud connection
-Reduced the BDR->DR swap time. -Monitor the cloud connection and start/stop APC based on the connection stability. Signed-off-by: Chaitanya Godavarthi <chaitanya.kiran@netexperience.com>
This commit is contained in:
committed by
Rick Sommerville
parent
ebaa9b25ce
commit
53ad416396
@@ -38,9 +38,6 @@ define Package/apc/install
|
||||
$(INSTALL_BIN) ./files/apc.init $(1)/etc/init.d/apc
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_BIN) ./files/apc.config $(1)/etc/config/apc
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
|
||||
$(INSTALL_BIN) ./files/etc/hotplug.d/iface/30-apc $(1)/etc/hotplug.d/iface/30-apc
|
||||
|
||||
|
||||
endef
|
||||
$(eval $(call BuildPackage,apc))
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/sh
|
||||
[ wan = "$INTERFACE" ] || exit 0
|
||||
[ "$ACTION" = ifup -o "$ACTION" = ifdown ] || exit 0
|
||||
|
||||
[ ifup = "$ACTION" ] && {
|
||||
/etc/init.d/apc start
|
||||
}
|
||||
|
||||
[ ifdown = "$ACTION" ] && {
|
||||
/etc/init.d/apc stop
|
||||
}
|
||||
@@ -168,7 +168,7 @@ void apc_iface_new( void )
|
||||
ifa->priority = 0x11;
|
||||
ifa->drip = MyIpAddr;
|
||||
ifa->helloint = 4;
|
||||
ifa->deadint = 16;
|
||||
ifa->deadint = 12;
|
||||
ifa->waitint = 16;
|
||||
|
||||
ifa->type = APC_IT_BCAST;
|
||||
|
||||
@@ -491,7 +491,8 @@ static void inactivity_timer_hook(struct _timer * tmr)
|
||||
apc_ifa->drip = MyIpAddr;
|
||||
apc_ifa->bdrip = 0;
|
||||
memset(&ApcSpec, 0, sizeof(struct apc_spec));
|
||||
WaitingToReelect = 12;
|
||||
WaitingToReelect = 3;
|
||||
|
||||
return;
|
||||
}
|
||||
printf("Inactivity timer expired for nbr %x on %s", n->rid,
|
||||
|
||||
@@ -14,10 +14,16 @@
|
||||
struct ubus_context *ubus_ctx = NULL;
|
||||
static struct blob_buf b;
|
||||
static struct blob_buf nb;
|
||||
static const char *ubus_path;
|
||||
timer *notify_timer;
|
||||
extern struct apc_iface * apc_ifa;
|
||||
/* Mandatorily Notify APC_State period */
|
||||
#define APC_NOTIFY_INTERVAL 10
|
||||
/* Check if any change in APC State and notify period */
|
||||
#define APC_NOTIFY_CHECK 1
|
||||
static ip_addr old_drip;
|
||||
static ip_addr old_bdrip;
|
||||
static u8 old_state;
|
||||
static unsigned int ucount = 0;
|
||||
|
||||
struct apc_state {
|
||||
char mode[4];
|
||||
@@ -95,26 +101,44 @@ apc_info_handle(struct ubus_context *ctx, struct ubus_object *obj,
|
||||
}
|
||||
|
||||
static char apc_mode[APC_MAX_MODE][8] = {"DOWN", "LOOP", "WT", "PTP", "OR", "BDR", "DR"};
|
||||
void apc_update_state()
|
||||
int apc_update_state(void)
|
||||
{
|
||||
struct in_addr dr_addr;
|
||||
struct in_addr bdr_addr;
|
||||
dr_addr.s_addr = htonl(apc_ifa->drip);
|
||||
bdr_addr.s_addr = htonl(apc_ifa->bdrip);
|
||||
ip_addr cur_drip;
|
||||
ip_addr cur_bdrip;
|
||||
u8 cur_state;
|
||||
|
||||
cur_drip = apc_ifa->drip;
|
||||
cur_bdrip = apc_ifa->bdrip;
|
||||
cur_state = apc_ifa->state;
|
||||
ucount++;
|
||||
|
||||
if (cur_drip == old_drip &&
|
||||
cur_bdrip == old_bdrip &&
|
||||
cur_state == old_state && ucount < APC_NOTIFY_INTERVAL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("APC State update %u", ucount);
|
||||
ucount = 0;
|
||||
|
||||
dr_addr.s_addr = htonl(cur_drip);
|
||||
bdr_addr.s_addr = htonl(cur_bdrip);
|
||||
|
||||
state.enabled = true;
|
||||
if ((apc_ifa->state == APC_IS_DR) ||
|
||||
(apc_ifa->state == APC_IS_BACKUP) ||
|
||||
(apc_ifa->state == APC_IS_DROTHER)) {
|
||||
if ((cur_state == APC_IS_DR) ||
|
||||
(cur_state == APC_IS_BACKUP) ||
|
||||
(cur_state == APC_IS_DROTHER)) {
|
||||
snprintf(state.mode, sizeof(state.mode), "%s",
|
||||
&apc_mode[apc_ifa->state][0]);
|
||||
&apc_mode[cur_state][0]);
|
||||
snprintf(state.dr_addr, sizeof(state.dr_addr),
|
||||
"%s", inet_ntoa(dr_addr));
|
||||
snprintf(state.bdr_addr, sizeof(state.bdr_addr),
|
||||
"%s", inet_ntoa(bdr_addr));
|
||||
} else if (apc_ifa->state == APC_IS_WAITING) {
|
||||
snprintf(state.mode, sizeof(state.mode), "%s",
|
||||
&apc_mode[apc_ifa->state][0]);
|
||||
&apc_mode[cur_state][0]);
|
||||
snprintf(state.dr_addr, sizeof(state.dr_addr), "0.0.0.0");
|
||||
snprintf(state.bdr_addr, sizeof(state.bdr_addr), "0.0.0.0");
|
||||
} else {
|
||||
@@ -122,11 +146,21 @@ void apc_update_state()
|
||||
snprintf(state.dr_addr, sizeof(state.dr_addr), "0.0.0.0");
|
||||
snprintf(state.bdr_addr, sizeof(state.bdr_addr), "0.0.0.0");
|
||||
}
|
||||
|
||||
old_drip = cur_drip;
|
||||
old_bdrip = cur_bdrip;
|
||||
old_state = cur_state;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void apc_send_notification(struct _timer * tmr)
|
||||
{
|
||||
apc_update_state();
|
||||
int ustate = 0;
|
||||
|
||||
ustate = apc_update_state();
|
||||
if(ustate != 0)
|
||||
return;
|
||||
|
||||
printf("APC send ubus notification\n");
|
||||
blob_buf_init(&nb, 0);
|
||||
@@ -159,10 +193,10 @@ ubus_init(void) {
|
||||
#endif
|
||||
add_object(&apc_object);
|
||||
notify_timer = tm_new_set(apc_send_notification, NULL,
|
||||
0, APC_NOTIFY_INTERVAL);
|
||||
0, APC_NOTIFY_CHECK);
|
||||
if (notify_timer) {
|
||||
printf("APC Start notify timer\n");
|
||||
tm_start(notify_timer, APC_NOTIFY_INTERVAL);
|
||||
printf("APC Start state check and notify timer\n");
|
||||
tm_start(notify_timer, APC_NOTIFY_CHECK);
|
||||
}
|
||||
|
||||
ubus_ctx->connection_lost = ubus_connection_lost;
|
||||
|
||||
7
feeds/wlan-ap/opensync/files/bin/check_wan_link.sh
Executable file
7
feeds/wlan-ap/opensync/files/bin/check_wan_link.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
if="$(uci get network.wan.ifname)"
|
||||
[ "$(cat /sys/class/net/"${if}"/carrier)" = 0 ] && {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
@@ -781,12 +781,12 @@ void apc_state_set(struct blob_attr *msg)
|
||||
blobmsg_get_string(tb[APC_ATTR_MODE]));
|
||||
}
|
||||
if (tb[APC_ATTR_DR_ADDR]) {
|
||||
LOGD("APC br-addr: %s", blobmsg_get_string(tb[APC_ATTR_DR_ADDR]));
|
||||
LOGD("APC dr-addr: %s", blobmsg_get_string(tb[APC_ATTR_DR_ADDR]));
|
||||
SCHEMA_SET_STR(apc_state.dr_addr,
|
||||
blobmsg_get_string(tb[APC_ATTR_DR_ADDR]));
|
||||
}
|
||||
if (tb[APC_ATTR_BDR_ADDR]) {
|
||||
LOGD("APC dbr-addr: %s", blobmsg_get_string(tb[APC_ATTR_BDR_ADDR]));
|
||||
LOGD("APC bdr-addr: %s", blobmsg_get_string(tb[APC_ATTR_BDR_ADDR]));
|
||||
SCHEMA_SET_STR(apc_state.bdr_addr,
|
||||
blobmsg_get_string(tb[APC_ATTR_BDR_ADDR]));
|
||||
}
|
||||
@@ -800,106 +800,106 @@ void apc_state_set(struct blob_attr *msg)
|
||||
}
|
||||
}
|
||||
|
||||
LOGD("APC_state Updating");
|
||||
LOGI("APC_state Updating: mode: %s, dr-addr: %s bdr-addr: %s",
|
||||
apc_state.mode, apc_state.dr_addr, apc_state.bdr_addr);
|
||||
|
||||
if (!ovsdb_table_update(&table_APC_State, &apc_state))
|
||||
LOG(ERR, "APC_state: failed to update");
|
||||
|
||||
}
|
||||
|
||||
static ovsdb_table_t table_Manager;
|
||||
ev_timer apc_cld_mon_timer;
|
||||
ev_timer apc_cld_disconn_timer;
|
||||
ev_timer apc_backoff_timer;
|
||||
#define APC_CLD_MON_TIME 5
|
||||
#define APC_CLD_DISCONN_TIME 60
|
||||
#define APC_BKOFF_TIME 60
|
||||
static int conn_since = 0;
|
||||
#define APC_CLOUD_MON_PERIOD 60
|
||||
|
||||
static void apc_enable(bool flag) {
|
||||
|
||||
SCHEMA_SET_INT(apc_conf.enabled, flag);
|
||||
if (!ovsdb_table_update(&table_APC_Config, &apc_conf)) {
|
||||
LOG(ERR, "%s:APC_Config: failed to update", __func__);
|
||||
return;
|
||||
}
|
||||
LOGI("APC %s: %s APC", __func__, flag?"enable":"disable");
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
apc_cld_mon_cb(struct ev_loop *loop, ev_timer *timer, int revents)
|
||||
apc_cld_mon_cb(struct schema_Manager *mgr)
|
||||
{
|
||||
struct schema_APC_State state;
|
||||
struct schema_Manager mgr;
|
||||
int i = 0;
|
||||
conn_since = 0;
|
||||
struct schema_APC_State apc_state;
|
||||
json_t *where;
|
||||
int ret = 0;
|
||||
int link = 1;
|
||||
|
||||
where = ovsdb_table_where(&table_APC_State, &state);
|
||||
where = ovsdb_table_where(&table_APC_State, &apc_state);
|
||||
if (false == ovsdb_table_select_one_where(&table_APC_State,
|
||||
where, &state)) {
|
||||
where, &apc_state)) {
|
||||
LOG(ERR, "%s: APC_State read failed", __func__);
|
||||
return;
|
||||
}
|
||||
/*If not DR and not BDR the dont proceed */
|
||||
if ((strncmp(state.mode, "DR", 2) != 0) &&
|
||||
(strncmp(state.mode, "BDR", 3) != 0))
|
||||
return;
|
||||
|
||||
/*If BDR addr is 0 means its a standalone DR*/
|
||||
if ((strncmp(state.bdr_addr, "0.0.0.0", 7) == 0))
|
||||
return;
|
||||
|
||||
where = ovsdb_table_where(&table_Manager, &mgr);
|
||||
if (false == ovsdb_table_select_one_where(&table_Manager,
|
||||
where, &mgr)) {
|
||||
LOG(ERR, "%s: Manager read failed", __func__);
|
||||
return;
|
||||
/*Checks if wan ethernet port is down and disables apc*/
|
||||
ret = system("/bin/check_wan_link.sh");
|
||||
if (WIFEXITED(ret)) {
|
||||
LOGI("The return value: %d\n", WEXITSTATUS(ret));
|
||||
link = WEXITSTATUS(ret);
|
||||
if (link == 0) {
|
||||
apc_enable(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (mgr.is_connected == false) {
|
||||
if (!ev_is_active(&apc_cld_disconn_timer) &&
|
||||
!ev_is_pending(&apc_cld_disconn_timer)) {
|
||||
LOGI("%s: START apc_cld_disconn_timer, %s",
|
||||
__func__, state.mode);
|
||||
ev_timer_set(&apc_cld_disconn_timer,
|
||||
APC_CLD_DISCONN_TIME, 0);
|
||||
ev_timer_start(EV_DEFAULT, &apc_cld_disconn_timer);
|
||||
}
|
||||
/*if cloud conn is false then disable apc*/
|
||||
if (mgr->is_connected == false) {
|
||||
apc_enable(false);
|
||||
}
|
||||
else {
|
||||
if (ev_is_active(&apc_cld_disconn_timer)) {
|
||||
LOGI("%s: STOP apc_cld_disconn_timer", __func__);
|
||||
ev_timer_stop(EV_DEFAULT, &apc_cld_disconn_timer);
|
||||
for(i=0; i < mgr->status_len; i++) {
|
||||
if(!strncmp(mgr->status_keys[i] , "sec_since_connect",
|
||||
strlen("sec_since_connect"))) {
|
||||
conn_since = atoi(mgr->status[i]);
|
||||
LOGI("conn_since: %d", conn_since);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*if the APC was stopped earlier, start it if connection good
|
||||
* for atleast 60 secs*/
|
||||
if (!apc_state.enabled && conn_since > APC_CLOUD_MON_PERIOD) {
|
||||
apc_enable(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
apc_backoff_cb(struct ev_loop *loop, ev_timer *timer, int revents)
|
||||
/*Monitor the cloud connection*/
|
||||
static void callback_Manager(ovsdb_update_monitor_t *mon,
|
||||
struct schema_Manager *old,
|
||||
struct schema_Manager *conf)
|
||||
{
|
||||
LOGI("%s: Enable APC, STOP apc_backoff_timer", __func__);
|
||||
SCHEMA_SET_INT(apc_conf.enabled, true);
|
||||
if (!ovsdb_table_update(&table_APC_Config, &apc_conf))
|
||||
LOG(ERR, "%s: APC_Config: failed to update", __func__);
|
||||
switch (mon->mon_type)
|
||||
{
|
||||
case OVSDB_UPDATE_NEW:
|
||||
case OVSDB_UPDATE_MODIFY:
|
||||
apc_cld_mon_cb(conf);
|
||||
break;
|
||||
|
||||
ev_timer_stop(EV_DEFAULT, &apc_backoff_timer);
|
||||
}
|
||||
case OVSDB_UPDATE_DEL:
|
||||
apc_enable(false);
|
||||
break;
|
||||
|
||||
static void
|
||||
apc_cld_disconn_cb(struct ev_loop *loop, ev_timer *timer, int revents)
|
||||
{
|
||||
LOGI("%s: Disable APC , START apc_backoff_timer", __func__);
|
||||
SCHEMA_SET_INT(apc_conf.enabled, false);
|
||||
if (!ovsdb_table_update(&table_APC_Config, &apc_conf)) {
|
||||
LOG(ERR, "%s:APC_Config: failed to update", __func__);
|
||||
ev_timer_stop(EV_DEFAULT, &apc_cld_disconn_timer);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ev_timer_set(&apc_backoff_timer, APC_BKOFF_TIME, 0);
|
||||
ev_timer_start(EV_DEFAULT, &apc_backoff_timer);
|
||||
|
||||
ev_timer_stop(EV_DEFAULT, &apc_cld_disconn_timer);
|
||||
return;
|
||||
}
|
||||
|
||||
void cloud_disconn_mon(void)
|
||||
{
|
||||
ev_init(&apc_cld_mon_timer, apc_cld_mon_cb);
|
||||
apc_cld_mon_timer.repeat = APC_CLD_MON_TIME;
|
||||
ev_timer_again(EV_DEFAULT, &apc_cld_mon_timer);
|
||||
|
||||
ev_timer_init(&apc_cld_disconn_timer, apc_cld_disconn_cb,
|
||||
APC_CLD_DISCONN_TIME, 0);
|
||||
ev_timer_init(&apc_backoff_timer, apc_backoff_cb,
|
||||
APC_BKOFF_TIME, 0);
|
||||
|
||||
OVSDB_TABLE_INIT_NO_KEY(Manager);
|
||||
OVSDB_TABLE_MONITOR(Manager, false);
|
||||
}
|
||||
|
||||
void apc_init()
|
||||
@@ -907,7 +907,8 @@ void apc_init()
|
||||
/* APC Config */
|
||||
OVSDB_TABLE_INIT_NO_KEY(APC_Config);
|
||||
OVSDB_TABLE_MONITOR(APC_Config, false);
|
||||
SCHEMA_SET_INT(apc_conf.enabled, true);
|
||||
/* Disable APC by default, enable when cloud connected*/
|
||||
SCHEMA_SET_INT(apc_conf.enabled, false);
|
||||
LOGI("APC state/config Initialize");
|
||||
if (!ovsdb_table_insert(&table_APC_Config, &apc_conf)) {
|
||||
LOG(ERR, "APC_Config: failed to initialize");
|
||||
@@ -927,9 +928,8 @@ void apc_init()
|
||||
}
|
||||
|
||||
/* Cloud connection monitor - if cloud unreachable
|
||||
* for certain time, disable APC and enable after a
|
||||
* back-off time. This triggers relection of DR among
|
||||
* other APs*/
|
||||
* for certain time, disable APC and enable after the
|
||||
* cloud connection becomes stable. */
|
||||
cloud_disconn_mon();
|
||||
|
||||
}
|
||||
@@ -962,12 +962,12 @@ bool target_radio_init(const struct target_radio_ops *ops)
|
||||
OVSDB_TABLE_INIT(Radius_Proxy_Config, _uuid);
|
||||
OVSDB_TABLE_MONITOR(Radius_Proxy_Config, false);
|
||||
|
||||
apc_init();
|
||||
|
||||
evsched_task(&periodic_task, NULL, EVSCHED_SEC(5));
|
||||
|
||||
radio_nl80211_init();
|
||||
radio_ubus_init();
|
||||
apc_init();
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &startup_time);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user