#!/bin/sh

BACKUP=$(uci -q get network.3gwan.backup)
LOAD_BALANCE=$(uci -q get network.3gwan.load_balance)
LOAD_BALANCE_STATE=$(uci -P /var/state/ -q get network.load_balance)
WAN_MODE=$(uci -P /var/state/ -q get network.wan.proto)
WAN_UP=$(uci -P /var/state/ -q get network.wan.up)
WAN3G_UP=$(uci -P /var/state/ -q get network.3gwan.up)

delete_default_route() {
    DEF=$(ip route list table main | grep default)   
    while [ -n "$DEF" ]   
    do        
        ip route del default 
        DEF=$(ip route list table main | grep default)       
    done
}

delete_rule_lb_wan1() {
    RES=$(ip rule list | grep lb_wan1)   
    while [ -n "$RES" ]   
    do        
        ip rule del table lb_wan1 
        RES=$(ip rule list | grep lb_wan1)
    done
}

delete_rule_lb_wan2() {
    RES=$(ip rule list | grep lb_wan2)  
    while [ -n "$RES" ]   
    do       
        ip rule del table lb_wan2 
        RES=$(ip rule list | grep lb_wan2)
    done
}

start_load_balance() {
    # Get the configs of WAN1:
    WAN1_IF=$(uci -P /var/state/ -q get network.wan.ifname)
    WAN1_IP=$(uci -P /var/state/ -q get network.wan.ipaddr)
    WAN1_GW=$(uci -P /var/state/ -q get network.wan.gateway)
    WAN1_NET=$(ip route list table main | grep "dev $WAN1_IF" | awk 'NR==1{print $1}')  
  
    # Get the configs of WAN2:
    WAN2_IF=$(uci -P /var/state/ -q get network.3gwan.ifname)
    WAN2_IP=$(uci -P /var/state/ -q get network.3gwan.ipaddr)
    WAN2_GW=$(uci -P /var/state/ -q get network.3gwan.gateway)
    WAN2_NET=$(ip route list table main | grep "dev $WAN2_IF" | awk 'NR==1{print $1}')   

    if [ -z "$WAN1_NET" ]; then        
        logger -p 160.5 "[3G LOAD BALANCE] ERROR: WAN1 is down"        
    elif [ -z "$WAN2_NET" ]; then        
        logger -p 160.5 "[3G LOAD BALANCE] ERROR: WAN2 is down"       
    else 
        # Check/create the tables for load balance:
        if [ -z "`cat /etc/iproute2/rt_tables | grep '^201'`" ] ; then  
            logger -p 160.5 "[3G LOAD BALANCE] create table: 201 lb_wan1"           
    	    echo "201 lb_wan1" >> /etc/iproute2/rt_tables
        fi
        
        if [ -z "`cat /etc/iproute2/rt_tables | grep '^202'`" ] ; then
            logger -p 160.5 "[3G LOAD BALANCE] create table: 202 lb_wan2"
    	    echo "202 lb_wan2" >> /etc/iproute2/rt_tables    	    
        fi
      
        # Create routing tables:
        logger -p 160.5 "[3G LOAD BALANCE] add static and default routes"      
        ip route add $WAN1_NET dev $WAN1_IF src $WAN1_IP table lb_wan1 
        ip route add default via $WAN1_GW table lb_wan1 
        ip route add $WAN2_NET dev $WAN2_IF src $WAN2_IP table lb_wan2  
        ip route add default via $WAN2_GW table lb_wan2  
    
        # Create routing rules:
        logger -p 160.5 "[3G LOAD BALANCE] add routing rules"       
        delete_rule_lb_wan1
        delete_rule_lb_wan2
        ip rule add from $WAN1_IP table lb_wan1 
        ip rule add from $WAN2_IP table lb_wan2  
       
        # Balance links based on routes:
        logger -p 160.5 "[3G LOAD BALANCE] add route for load balance"            
        delete_default_route
        ip route add default scope global nexthop via $WAN1_GW dev $WAN1_IF weight 1 nexthop via $WAN2_GW dev $WAN2_IF weight 1 

        # Flush cache table:       
        logger -p 160.5 "[3G LOAD BALANCE] flush cache table"       
        ip route flush cache 
        
        uci -P /var/state/ -q revert network.load_balance 
        uci -P /var/state/ -q set network.load_balance=1
        uci -P /var/state/ -q commit network
    fi       
}

stop_load_balance() {            
    # Delete the routing rules:
    logger -p 160.5 "[3G LOAD BALANCE] delete routing rules"     
    delete_rule_lb_wan1
    delete_rule_lb_wan2
  
    # Delete the routing tables:
    logger -p 160.5 "[3G LOAD BALANCE] flush routing tables"  
    ip route flush table lb_wan1 
    ip route flush table lb_wan2  

    # Balance links based on routes:   
    logger -p 160.5 "[3G LOAD BALANCE] delete route for load balance and add default route for WAN1"   
    delete_default_route
    
    if [ "$WAN_UP" == "1" ]; then 
        # Get the configs of WAN1:
        WAN1_IF=$(uci -P /var/state/ -q get network.wan.ifname)
        WAN1_GW=$(uci -P /var/state/ -q get network.wan.gateway)      
        ip route add default via $WAN1_GW dev $WAN1_IF 
    elif [ "$WAN3G_UP" == "1" ]; then 
        # Get the configs of WAN1:
        WAN2_IF=$(uci -P /var/state/ -q get network.3gwan.ifname)
        WAN2_GW=$(uci -P /var/state/ -q get network.3gwan.gateway)      
        ip route add default via $WAN2_GW dev $WAN2_IF     
    fi
    
    # Flush cache table:       
    logger -p 160.5 "[3G LOAD BALANCE] flush cache table"       
    ip route flush cache 
         
    uci -P /var/state/ -q revert network.load_balance
    uci -P /var/state/ -q set network.load_balance=0 
    uci -P /var/state/ -q commit network       
}

#For dual 3G load balance: WAN mode should be 3G and backup should enable dual 3G load balance  
if [ "$ACTION" == "ifup" ] || [ "$ACTION" == "ifdown" ]; then
    if [ "$INTERFACE" == "wan" ] || [ "$INTERFACE" == "3gwan" ]; then
        if [ "$LOAD_BALANCE" == "1" ]; then
            logger -p 160.5 "[3G LOAD BALANCE] ----- Set up the IP route and rule (1: WAN:$WAN_MODE,$WAN_UP, 3GWAN:$WAN3G_UP) -----"           
            if [ "$WAN_MODE" == "3g" -a "$WAN_UP" == "1" -a "$WAN3G_UP" == "1" ]; then 
                start_load_balance                      
            else                
                if [ "$WAN_MODE" != "3g" ]; then
                    #Backup mode=Dual 3G load balance, but WAN mode change from 3g to non-3g 
                    logger -p 160.5 "[3G LOAD BALANCE] ----- WAN mode isn't 3g, disable load balance -----"                    
                    stop_load_balance 
                    if [ "$WAN3G_UP" == "1" ]; then                        
                        logger -p 160.5 "[3G LOAD BALANCE] ----- WAN mode isn't 3g => ifdown 3gwan -----"  
                        ifdown 3gwan
                    fi    
                elif [ "$WAN_MODE" == "3g" -a "$WAN3G_UP" != "1" ]; then
                    #Backup mode=Dual 3G load balance, WAN mode change from non-3g to 3g                      
                    logger -p 160.5 "[3G LOAD BALANCE] ----- WAN mode is 3g => ifup 3gwan -----"
                    ifup 3gwan
                fi       	    
            fi              
        elif [ "$LOAD_BALANCE" == "0" -a "$LOAD_BALANCE" != "$LOAD_BALANCE_STATE" ]; then		       
            logger -p 160.5 "[3G LOAD BALANCE] ----- Set up the IP route and rule (0) -----"
            stop_load_balance                 
        fi
    fi
fi            