You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
481 lines
15 KiB
C
481 lines
15 KiB
C
/*
|
|
*
|
|
* Multi WAN
|
|
* By Arctic QQ:317869867 E-Mail:zengchen228@vip.qq.com
|
|
* Fixes/updates (C) 2018 - 2024 pedro
|
|
*
|
|
*/
|
|
|
|
|
|
#include "rc.h"
|
|
|
|
/* needed by logmsg() */
|
|
#define LOGMSG_DISABLE DISABLE_SYSLOG_OS
|
|
#define LOGMSG_NVDEBUG "mwan_debug"
|
|
|
|
|
|
#ifdef TCONFIG_MULTIWAN
|
|
static char mwan_curr[] = {'0', '0', '0', '0', '\0'};
|
|
static char mwan_last[] = {'0', '0', '0', '0', '\0'};
|
|
#else
|
|
static char mwan_curr[] = {'0', '0', '\0'};
|
|
static char mwan_last[] = {'0', '0', '\0'};
|
|
#endif
|
|
|
|
typedef struct
|
|
{
|
|
char wan_name[16];
|
|
char wan_ipaddr[32];
|
|
char wan_netmask[32];
|
|
char wan_gateway[32];
|
|
const dns_list_t *dns;
|
|
int wan_weight;
|
|
} waninfo_t;
|
|
|
|
static waninfo_t wan_info;
|
|
|
|
int get_sta_wan_prefix(char *sPrefix, const size_t buf_sz)
|
|
{
|
|
int mwan_num;
|
|
int wan_unit;
|
|
char prefix[16];
|
|
char tmp[32];
|
|
int found = 0;
|
|
|
|
mwan_num = nvram_get_int("mwan_num");
|
|
if ((mwan_num < 1) || (mwan_num > MWAN_MAX))
|
|
mwan_num = 1;
|
|
|
|
for (wan_unit = 1; wan_unit <= mwan_num; ++wan_unit) {
|
|
memset(prefix, 0, sizeof(prefix));
|
|
get_wan_prefix(wan_unit, prefix);
|
|
|
|
if (strcmp(nvram_safe_get(strlcat_r(prefix, "_sta", tmp, sizeof(tmp))), "")) {
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (found)
|
|
strlcpy(sPrefix, prefix, buf_sz);
|
|
else
|
|
strlcpy(sPrefix, "wan", buf_sz);
|
|
|
|
return found;
|
|
}
|
|
|
|
void get_wan_info(char *sPrefix)
|
|
{
|
|
char tmp[32];
|
|
int proto = get_wanx_proto(sPrefix);
|
|
|
|
/* WAN if name */
|
|
strlcpy(wan_info.wan_name, get_wanface(sPrefix), sizeof(wan_info.wan_name)); /* use correct wan interface */
|
|
|
|
/* WAN IP address */
|
|
switch (proto) {
|
|
case WP_L2TP:
|
|
case WP_PPTP:
|
|
strlcpy(wan_info.wan_ipaddr, nvram_safe_get(strlcat_r(sPrefix, "_ppp_get_ip", tmp, sizeof(tmp))), sizeof(wan_info.wan_ipaddr));
|
|
break;
|
|
case WP_PPPOE:
|
|
if (using_dhcpc(sPrefix))
|
|
strlcpy(wan_info.wan_ipaddr, nvram_safe_get(strlcat_r(sPrefix, "_ppp_get_ip", tmp, sizeof(tmp))), sizeof(wan_info.wan_ipaddr));
|
|
else
|
|
strlcpy(wan_info.wan_ipaddr, nvram_safe_get(strlcat_r(sPrefix, "_ipaddr", tmp, sizeof(tmp))), sizeof(wan_info.wan_ipaddr));
|
|
break;
|
|
default:
|
|
strlcpy(wan_info.wan_ipaddr, nvram_safe_get(strlcat_r(sPrefix, "_ipaddr", tmp, sizeof(tmp))), sizeof(wan_info.wan_ipaddr));
|
|
break;
|
|
}
|
|
|
|
/* WAN netmask */
|
|
if ((proto == WP_L2TP) || (proto == WP_PPTP) || (proto == WP_PPPOE) || (proto == WP_PPP3G))
|
|
strlcpy(wan_info.wan_netmask, "255.255.255.255", sizeof(wan_info.wan_netmask));
|
|
else
|
|
strlcpy(wan_info.wan_netmask, nvram_safe_get(strlcat_r(sPrefix, "_netmask", tmp, sizeof(tmp))), sizeof(wan_info.wan_netmask));
|
|
|
|
/* WAN gateway */
|
|
strlcpy(wan_info.wan_gateway, wan_gateway(sPrefix), sizeof(wan_info.wan_gateway));
|
|
|
|
/* WAN dns */
|
|
wan_info.dns = get_dns(sPrefix); /* static buffer */
|
|
|
|
/* WAN weight */
|
|
wan_info.wan_weight = atoi(nvram_safe_get(strlcat_r(sPrefix, "_weight", tmp, sizeof(tmp))));
|
|
|
|
logmsg(LOG_DEBUG, "*** %s: PREFIX=[%s], wan_name=[%s] wan_ipaddr=[%s] wan_netmask=[%s] wan_gateway=[%s] wan_weight=[%d]", __FUNCTION__, sPrefix, wan_info.wan_name, wan_info.wan_ipaddr, wan_info.wan_netmask, wan_info.wan_gateway, wan_info.wan_weight);
|
|
}
|
|
|
|
void get_wan_ip(int proto, char *name, const size_t buf_sz)
|
|
{
|
|
if ((proto == WP_DHCP) || (proto == WP_LTE) || (proto == WP_STATIC))
|
|
strlcpy(name, wan_info.wan_gateway, buf_sz);
|
|
else
|
|
strlcpy(name, wan_info.wan_ipaddr, buf_sz);
|
|
}
|
|
|
|
void get_cidr(char *ipaddr, char *netmask, char *cidr, const size_t buf_sz)
|
|
{
|
|
struct in_addr in_ipaddr, in_netmask, in_network;
|
|
int netmask_bit = 0;
|
|
unsigned long int bits = 1;
|
|
|
|
inet_aton(ipaddr, &in_ipaddr);
|
|
inet_aton(netmask, &in_netmask);
|
|
|
|
unsigned int i;
|
|
for (i = 1; i < sizeof(bits) * 8; i++) {
|
|
if (in_netmask.s_addr & bits)
|
|
netmask_bit++;
|
|
bits = bits << 1;
|
|
}
|
|
|
|
in_network.s_addr = in_ipaddr.s_addr & in_netmask.s_addr;
|
|
snprintf(cidr, buf_sz, "%s/%d", inet_ntoa(in_network), netmask_bit);
|
|
}
|
|
|
|
void mwan_table_del(char *sPrefix)
|
|
{
|
|
int wan_unit;
|
|
int i;
|
|
char cmd[256];
|
|
|
|
logmsg(LOG_DEBUG, "*** %s IN", __FUNCTION__);
|
|
|
|
wan_unit = get_wan_unit(sPrefix);
|
|
get_wan_info(sPrefix); /* get the current wan infos to work with */
|
|
|
|
/* ip rule del table WAN1 pref 101 (gateway); table: 1 to 4; pref: 101 to 104 */
|
|
memset(cmd, 0, sizeof(cmd));
|
|
snprintf(cmd, sizeof(cmd), "ip rule del table %d pref 10%d", wan_unit, wan_unit);
|
|
logmsg(LOG_DEBUG, "*** %s: PREFIX=[%s], cmd=[%s]", __FUNCTION__, sPrefix, cmd);
|
|
system(cmd);
|
|
|
|
/* ip rule del table WAN1 pref 111 (dns); table: 1 to 4; pref: 111 to 114 */
|
|
/* delete only active & valid DNS; two options right now: only AUTO DNS server (1x DNS) or Manual DNS server (2x DNS) (see GUI basic-network.asp) */
|
|
for (i = 0 ; i < wan_info.dns->count; ++i) {
|
|
memset(cmd, 0, sizeof(cmd));
|
|
snprintf(cmd, sizeof(cmd), "ip rule del table %d pref 11%d", wan_unit, wan_unit);
|
|
logmsg(LOG_DEBUG, "*** %s: PREFIX=[%s], cmd=[%s]", __FUNCTION__, sPrefix, cmd);
|
|
system(cmd);
|
|
}
|
|
|
|
/* ip rule del fwmark 0x100/0xf00 table 1 pref 121 (mark); table: 1 to 4; pref: 121 to 124 */
|
|
memset(cmd, 0, sizeof(cmd));
|
|
snprintf(cmd, sizeof(cmd), "ip rule del table %d pref 12%d", wan_unit, wan_unit);
|
|
logmsg(LOG_DEBUG, "*** %s: PREFIX=[%s], cmd=[%s]", __FUNCTION__, sPrefix, cmd);
|
|
system(cmd);
|
|
|
|
logmsg(LOG_DEBUG, "*** %s OUT", __FUNCTION__);
|
|
}
|
|
|
|
/* set multiwan ip route table & ip rule table */
|
|
void mwan_table_add(char *sPrefix)
|
|
{
|
|
int mwan_num, wan_unit, proto;
|
|
int wanid;
|
|
int i;
|
|
char cmd[256];
|
|
char buf[32];
|
|
|
|
logmsg(LOG_DEBUG, "*** %s IN", __FUNCTION__);
|
|
|
|
/* delete already existed table first */
|
|
mwan_table_del(sPrefix);
|
|
|
|
mwan_num = nvram_get_int("mwan_num");
|
|
if ((mwan_num == 1) || (mwan_num > MWAN_MAX))
|
|
return;
|
|
|
|
wan_unit = get_wan_unit(sPrefix);
|
|
get_wan_info(sPrefix); /* get the current wan infos to work with */
|
|
proto = get_wanx_proto(sPrefix);
|
|
|
|
if (check_wanup(sPrefix)) {
|
|
/* ip rule add from WAN_IP table route_id pref 10X */
|
|
memset(cmd, 0, sizeof(cmd));
|
|
snprintf(cmd, sizeof(cmd), "ip rule add from %s table %d pref 10%d", wan_info.wan_ipaddr, wan_unit, wan_unit);
|
|
logmsg(LOG_DEBUG, "*** %s: PREFIX=[%s], cmd=[%s]", __FUNCTION__, sPrefix, cmd);
|
|
system(cmd);
|
|
|
|
/* set the routing rules of DNS */
|
|
for (i = 0; i < wan_info.dns->count; ++i) {
|
|
memset(cmd, 0, sizeof(cmd));
|
|
snprintf(cmd, sizeof(cmd), "ip rule add to %s table %d pref 11%d", inet_ntoa(wan_info.dns->dns[i].addr), wan_unit, wan_unit);
|
|
logmsg(LOG_DEBUG, "*** %s: PREFIX=[%s], cmd=[%s]", __FUNCTION__, sPrefix, cmd);
|
|
system(cmd);
|
|
}
|
|
|
|
/* ip rule add fwmark 0x100/0xf00 table 1 pref 121 */
|
|
memset(cmd, 0, sizeof(cmd));
|
|
snprintf(cmd, sizeof(cmd), "ip rule add fwmark 0x%d00/0xf00 table %d pref 12%d", wan_unit, wan_unit, wan_unit);
|
|
logmsg(LOG_DEBUG, "*** %s: PREFIX=[%s], cmd=[%s]", __FUNCTION__, sPrefix, cmd);
|
|
system(cmd);
|
|
|
|
for (wanid = 1; wanid <= mwan_num; ++wanid) {
|
|
/* ip route add 10.0.10.1 dev ppp3 proto kernel scope link table route_id */
|
|
memset(cmd, 0, sizeof(cmd));
|
|
if ((proto == WP_DHCP) || (proto == WP_LTE) || (proto == WP_STATIC)) {
|
|
memset(buf, 0, sizeof(buf));
|
|
get_cidr(wan_info.wan_ipaddr, wan_info.wan_netmask, buf, sizeof(buf));
|
|
snprintf(cmd, sizeof(cmd), "ip route append %s dev %s proto kernel scope link src %s table %d", buf, wan_info.wan_name, wan_info.wan_ipaddr, wanid);
|
|
}
|
|
else
|
|
snprintf(cmd, sizeof(cmd), "ip route append %s dev %s proto kernel scope link src %s table %d", wan_info.wan_gateway, wan_info.wan_name, wan_info.wan_ipaddr, wanid);
|
|
|
|
logmsg(LOG_DEBUG, "*** %s: PREFIX=[%s], cmd=[%s]", __FUNCTION__, sPrefix, cmd);
|
|
system(cmd);
|
|
}
|
|
|
|
/* ip route add 192.168.1.0/24 dev br0 proto kernel scope link src 192.168.1.1 table 2 */
|
|
for (i = 0; i < BRIDGE_COUNT; i++) {
|
|
char nvram_var[16];
|
|
char* lan_ifname;
|
|
char* lan_ipaddr;
|
|
char* lan_netmask;
|
|
|
|
memset(nvram_var, 0, sizeof(nvram_var));
|
|
snprintf(nvram_var, sizeof(nvram_var), (i == 0 ? "lan_ifname" : "lan%d_ifname"), i);
|
|
lan_ifname = nvram_safe_get(nvram_var);
|
|
memset(nvram_var, 0, sizeof(nvram_var));
|
|
snprintf(nvram_var, sizeof(nvram_var), (i == 0 ? "lan_ipaddr" : "lan%d_ipaddr"), i);
|
|
lan_ipaddr = nvram_safe_get(nvram_var);
|
|
memset(nvram_var, 0, sizeof(nvram_var));
|
|
snprintf(nvram_var, sizeof(nvram_var), (i == 0 ? "lan_netmask" : "lan%d_netmask"), i);
|
|
lan_netmask = nvram_safe_get(nvram_var);
|
|
|
|
if ((lan_ifname[0] == '\0') || (lan_ipaddr[0] == '\0') || (lan_netmask[0] == '\0'))
|
|
continue;
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
get_cidr(lan_ipaddr, lan_netmask, buf, sizeof(buf));
|
|
memset(cmd, 0, sizeof(cmd));
|
|
snprintf(cmd, sizeof(cmd), "ip route append %s dev %s proto kernel scope link src %s table %d", buf, lan_ifname, lan_ipaddr, wan_unit);
|
|
logmsg(LOG_DEBUG, "*** %s: PREFIX=[%s], cmd=[%s]", __FUNCTION__, sPrefix, cmd);
|
|
system(cmd);
|
|
}
|
|
|
|
/* ip route add 127.0.0.0/8 dev lo scope link table 1 */
|
|
memset(cmd, 0, sizeof(cmd));
|
|
snprintf(cmd, sizeof(cmd), "ip route append 127.0.0.0/8 dev lo scope link table %d", wan_unit);
|
|
logmsg(LOG_DEBUG, "*** %s: PREFIX=[%s], cmd=[%s]", __FUNCTION__, sPrefix, cmd);
|
|
system(cmd);
|
|
|
|
/* ip route add default via 10.0.10.1 dev ppp3 table route_id */
|
|
memset(cmd, 0, sizeof(cmd));
|
|
memset(buf, 0, sizeof(buf));
|
|
get_wan_ip(proto, buf, sizeof(buf));
|
|
snprintf(cmd, sizeof(cmd), "ip route append default via %s dev %s table %d", buf, wan_info.wan_name, wan_unit);
|
|
logmsg(LOG_DEBUG, "*** %s: PREFIX=[%s], cmd=[%s]", __FUNCTION__, sPrefix, cmd);
|
|
system(cmd);
|
|
}
|
|
|
|
logmsg(LOG_DEBUG, "*** %s OUT", __FUNCTION__);
|
|
}
|
|
|
|
void mwan_state_files(void)
|
|
{
|
|
int mwan_num, wan_unit;
|
|
char prefix[16];
|
|
char tmp[64];
|
|
FILE *f;
|
|
|
|
mwan_num = nvram_get_int("mwan_num");
|
|
if ((mwan_num == 1) || (mwan_num > MWAN_MAX))
|
|
return;
|
|
|
|
for (wan_unit = 1; wan_unit <= mwan_num; ++wan_unit) {
|
|
memset(prefix, 0, sizeof(prefix));
|
|
get_wan_prefix(wan_unit, prefix);
|
|
|
|
memset(tmp, 0, sizeof(tmp));
|
|
snprintf(tmp, sizeof(tmp), "/var/lib/misc/%s_state", prefix);
|
|
if ((f = fopen(tmp, "r")) == NULL) {
|
|
/* if file does not exist then we create it with value "0".
|
|
* later on mwwatchdog will set it to 1 when it proves that
|
|
* the wan is actually working (wan can connect but still be not working)
|
|
*/
|
|
f = fopen(tmp, "w+");
|
|
fprintf(f, (nvram_get_int("mwan_state_init") ? "1\n" : "0\n")); /* also allow to init state file with value "1" instead of "0" */
|
|
}
|
|
fclose(f);
|
|
}
|
|
}
|
|
|
|
void mwan_status_update(void)
|
|
{
|
|
int mwan_num, wan_unit;
|
|
char prefix[16];
|
|
|
|
mwan_num = nvram_get_int("mwan_num");
|
|
if ((mwan_num == 1) || (mwan_num > MWAN_MAX))
|
|
return;
|
|
|
|
logmsg(LOG_DEBUG, "*** %s: IN, mwan_curr=%s", __FUNCTION__, mwan_curr);
|
|
|
|
for (wan_unit = 1; wan_unit <= mwan_num; ++wan_unit) {
|
|
memset(prefix, 0, sizeof(prefix));
|
|
get_wan_prefix(wan_unit, prefix);
|
|
get_wan_info(prefix);
|
|
if (check_wanup(prefix)) {
|
|
if (wan_info.wan_weight > 0)
|
|
mwan_curr[wan_unit - 1] = '2'; /* connected, load balancing */
|
|
else
|
|
mwan_curr[wan_unit - 1] = '1'; /* connected, failover */
|
|
}
|
|
else
|
|
mwan_curr[wan_unit - 1] = '0'; /* disconnected */
|
|
}
|
|
|
|
#ifdef TCONFIG_MULTIWAN
|
|
if ((mwan_curr[0] < '2') && (mwan_curr[1] < '2') && (mwan_curr[2] < '2') && (mwan_curr[3] < '2')) {
|
|
#else
|
|
if ((mwan_curr[0] < '2') && (mwan_curr[1] < '2')) {
|
|
#endif
|
|
/* all connections down, searching failover interfaces */
|
|
for (wan_unit = 1; wan_unit <= mwan_num; ++wan_unit) {
|
|
if (mwan_curr[wan_unit - 1] == '1') {
|
|
memset(prefix, 0, sizeof(prefix));
|
|
get_wan_prefix(wan_unit, prefix);
|
|
get_wan_info(prefix);
|
|
if (wan_info.wan_weight == 0) {
|
|
if (mwan_last[wan_unit - 1] != '2')
|
|
logmsg(LOG_INFO, "Failover in action - WAN%d", (wan_unit - 1));
|
|
|
|
mwan_curr[wan_unit - 1] = '2';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
logmsg(LOG_DEBUG, "*** %s: OUT, mwan_curr=%s", __FUNCTION__, mwan_curr);
|
|
}
|
|
|
|
void mwan_load_balance(void)
|
|
{
|
|
int mwan_num, wan_unit, proto, wan_default, wan_weight = 0;
|
|
char prefix[16];
|
|
char cmd[256];
|
|
char lb_cmd[2048];
|
|
char buf[32];
|
|
|
|
mwan_num = nvram_get_int("mwan_num");
|
|
if ((mwan_num == 1) || (mwan_num > MWAN_MAX))
|
|
return;
|
|
|
|
logmsg(LOG_DEBUG, "*** %s: IN, mwan_curr=%s", __FUNCTION__, mwan_curr);
|
|
|
|
mwan_status_update();
|
|
|
|
memset(lb_cmd, 0, sizeof(lb_cmd)); /* loadbalancing cmd */
|
|
strlcpy(lb_cmd, "ip route replace default scope global", sizeof(lb_cmd));
|
|
|
|
for (wan_unit = 1; wan_unit <= mwan_num; ++wan_unit) {
|
|
memset(prefix, 0, sizeof(prefix));
|
|
get_wan_prefix(wan_unit, prefix);
|
|
get_wan_info(prefix);
|
|
proto = get_wanx_proto(prefix);
|
|
memset(buf, 0, sizeof(buf));
|
|
get_wan_ip(proto, buf, sizeof(buf));
|
|
|
|
if (check_wanup(prefix) && (mwan_curr[wan_unit - 1] == '2')) { /* up and actively routing WAN */
|
|
if (wan_info.wan_weight == 0) /* override weight for failover interface */
|
|
wan_info.wan_weight = 1;
|
|
|
|
memset(cmd, 0, sizeof(cmd));
|
|
snprintf(cmd, sizeof(cmd), " nexthop via %s dev %s weight %d", buf, wan_info.wan_name, wan_info.wan_weight);
|
|
strlcat(lb_cmd, cmd, sizeof(lb_cmd));
|
|
}
|
|
/* ip route del default via 10.0.10.1 dev ppp3 (from main route table) */
|
|
if (strcmp(wan_info.wan_name, "none")) { /* skip disabled / disconnected ppp WAN */
|
|
memset(cmd, 0, sizeof(cmd));
|
|
snprintf(cmd, sizeof(cmd), "ip route del default via %s dev %s", buf, wan_info.wan_name);
|
|
logmsg(LOG_DEBUG, "*** %s: PREFIX=[%s], cmd=[%s]", __FUNCTION__, prefix, cmd);
|
|
system(cmd);
|
|
}
|
|
}
|
|
#ifdef TCONFIG_MULTIWAN
|
|
if (strcmp(mwan_curr, "0000")) {
|
|
#else
|
|
if (strcmp(mwan_curr, "00")) {
|
|
#endif
|
|
logmsg(LOG_DEBUG, "*** %s: LOAD BALANCING: cmd=[%s]", __FUNCTION__, lb_cmd);
|
|
}
|
|
else {
|
|
wan_default = 1; /* first assume that main wan is WAN0 */
|
|
for (wan_unit = 1; wan_unit <= mwan_num; ++wan_unit) {
|
|
memset(prefix, 0, sizeof(prefix));
|
|
get_wan_prefix(wan_unit, prefix);
|
|
get_wan_info(prefix);
|
|
|
|
if (wan_unit == 1) {
|
|
wan_weight = wan_info.wan_weight;
|
|
}
|
|
else if (wan_info.wan_weight > wan_weight) { /* but later choose WAN with highest weight */
|
|
wan_default = wan_unit;
|
|
wan_weight = wan_info.wan_weight;
|
|
}
|
|
}
|
|
|
|
memset(prefix, 0, sizeof(prefix));
|
|
get_wan_prefix(wan_default, prefix);
|
|
get_wan_info(prefix);
|
|
proto = get_wanx_proto(prefix);
|
|
|
|
memset(cmd, 0, sizeof(cmd));
|
|
memset(buf, 0, sizeof(buf));
|
|
get_wan_ip(proto, buf, sizeof(buf));
|
|
snprintf(cmd, sizeof(cmd), " nexthop via %s dev %s weight %d", buf, wan_info.wan_name, wan_info.wan_weight);
|
|
strlcat(lb_cmd, cmd, sizeof(lb_cmd));
|
|
|
|
logmsg(LOG_DEBUG, "*** %s: EMERGENCY ROUTE: cmd=[%s]", __FUNCTION__, lb_cmd);
|
|
}
|
|
/* always execute lb_cmd: if all wans are down - add default route via WAN with highest weight */
|
|
system(lb_cmd);
|
|
|
|
logmsg(LOG_DEBUG, "*** %s: OUT, mwan_curr=%s", __FUNCTION__, mwan_curr);
|
|
}
|
|
|
|
int mwan_route_main(int argc, char **argv)
|
|
{
|
|
int check_time = 15;
|
|
int mwan_num;
|
|
FILE *fp;
|
|
|
|
mkdir("/etc/iproute2", 0744);
|
|
if ((fp = fopen("/etc/iproute2/rt_tables", "w")) != NULL) {
|
|
fprintf(fp, "1 WAN1\n"
|
|
"2 WAN2\n"
|
|
#ifdef TCONFIG_MULTIWAN
|
|
"3 WAN3\n"
|
|
"4 WAN4\n"
|
|
#endif
|
|
#ifdef TCONFIG_PPTPD
|
|
"%d %s\n", PPTP_CLIENT_TABLE_ID, PPTP_CLIENT_TABLE_NAME
|
|
#endif
|
|
);
|
|
fclose(fp);
|
|
}
|
|
|
|
mwan_num = nvram_get_int("mwan_num");
|
|
if ((mwan_num == 1) || (mwan_num > MWAN_MAX))
|
|
return 0;
|
|
|
|
logmsg(LOG_DEBUG, "*** %s: MWAN: mwanroute launched", __FUNCTION__);
|
|
|
|
while(1) {
|
|
mwan_status_update();
|
|
|
|
if (strcmp(mwan_last, mwan_curr)) {
|
|
logmsg(LOG_WARNING, "Multiwan status has changed, last_status=%s, now_status=%s, Update multiwan policy", mwan_last, mwan_curr);
|
|
mwan_load_balance();
|
|
|
|
stop_dnsmasq();
|
|
start_dnsmasq();
|
|
}
|
|
strlcpy(mwan_last, mwan_curr, sizeof(mwan_last));
|
|
sleep(check_time);
|
|
}
|
|
}
|