--- multiwan.svnr23388 2010-12-02 21:32:21.000000000 -0800 +++ multiwan 2010-12-02 21:18:15.000000000 -0800 @@ -19,6 +19,7 @@ local recvrychk=$(query_config recvrychk $2) local wanid=$(query_config wanid $2) + local wan="$2" local failover_to=$(uci_get_state multiwan ${2} failover_to) local failover_to_wanid=$(query_config wanid $failover_to) @@ -30,7 +31,7 @@ wan_fail_map="$wan_fail_map${1}[x]" wan_recovery_map=$(echo $wan_recovery_map | sed -e "s/${1}\[${recvrychk}\]//g") update_cache - + if [ "$existing_failover" == "2" ]; then if [ "$failover_to" != "balancer" -a "$failover_to" != "fastbalancer" -a "$failover_to" != "disable" -a "$failover_to_wanid" != "$wanid" ]; then iptables -I FW${wanid}MARK 2 -t mangle -j FW${failover_to_wanid}MARK @@ -40,6 +41,9 @@ iptables -I FW${wanid}MARK 2 -t mangle -j FastBalancer fi fi + + config_foreach mwanrule_failover mwanfw $wan "fail" + mwnote "$1 has failed and is currently offline." } @@ -52,6 +56,9 @@ if [ "$existing_failover" == "3" ]; then iptables -D FW${wanid}MARK 2 -t mangle fi + + config_foreach mwanrule_failover mwanfw $wan "recover" + mwnote "$1 has recovered and is back online!" } @@ -378,7 +385,8 @@ local ports local proto local wanrule - + local wmanfw_name="$1" + config_get src $1 src config_get dst $1 dst config_get port_type $1 port_type 'dports' @@ -416,8 +424,9 @@ fi iptables -t mangle -A MultiWanRules ${src:+-s $src} ${dst:+-d $dst} \ -m mark --mark 0x0 ${proto:+-p $proto -m $proto} \ + -m comment --comment "$wmanfw_name" \ ${ports:+-m multiport --$port_type $ports} \ - -j $wanrule + -j $wanrule } if [ -z "$proto" -a ! -z "$ports" ]; then proto=tcp @@ -429,6 +438,112 @@ add_rule } + +# mwanrule_failover [config mwanfw id] [wan name] ["fail" or "recover"] +mwanrule_failover() { + + local src + local dst + local ports + local proto + local wanrule + local state="$3" + local wmanfw_name="$1" + local rulenum + local replacenum + + config_get src $1 src + config_get dst $1 dst + config_get port_type $1 port_type 'dports' + config_get ports $1 ports + config_get proto $1 proto + config_get wanrule $1 wanrule + config_get failover_to $1 failover_to + + if [ -z "$failover_to" -o -z "$wanrule" ]; then + return + fi + + # we dont need to run if the wan that failed/recovered is not the wanrule for this wmanfw + if [ "$wanrule" != "$2" ]; then + return + fi + + if [ "$wanrule" != "balancer" -a "$wanrule" != "fastbalancer" ]; then + wanrule=$(query_config wanid ${wanrule}) + wanrule="FW${wanrule}MARK" + elif [ "$wanrule" == "balancer" ]; then + wanrule="LoadBalancer" + elif [ "$wanrule" == "fastbalancer" ]; then + wanrule="FastBalancer" + fi + + if [ "$failover_to" != "balancer" -a "$failover_to" != "fastbalancer" ]; then + failover_to=$(query_config wanid ${failover_to}) + failover_to="FW${failover_to}MARK" + elif [ "$failover_to" == "balancer" ]; then + failover_to="LoadBalancer" + elif [ "$failover_to" == "fastbalancer" ]; then + failover_to="FastBalancer" + fi + + if [ "$dst" == "all" ]; then + dst=$NULL + fi + if [ "$proto" == "all" ]; then + proto=$NULL + fi + if [ "$ports" == "all" ]; then + ports=$NULL + fi + + # remove all rules matching this wmanfw_name + while true ; do + rulenum=$( iptables -t mangle -L -v -n --line-numbers | grep "/\* $1 \*/" | head -n 1 | awk '{print $1}' ) + + if [ -z "$rulenum" ] ; then + break + fi + + iptables -t mangle -D MultiWanRules $rulenum + + replacenum=$rulenum + done + + replace_rule() { + if [ "$proto" == "icmp" ]; then + ports=$NULL + fi + if [ "$src" == "all" ]; then + src=$NULL + fi + + if [ "$state" == "fail" ]; then + deltarg="$wanrule" + addtarg="$failover_to" + else + deltarg="$failover_to" + addtarg="$wanrule" + fi + + iptables -t mangle -I MultiWanRules $1 ${src:+-s $src} \ + ${dst:+-d $dst} -m mark --mark 0x0 ${proto:+-p $proto -m $proto} \ + -m comment --comment "$wmanfw_name" \ + ${ports:+-m multiport --$port_type $ports} \ + -j $addtarg + } + + if [ -z "$proto" -a ! -z "$ports" ]; then + proto=tcp + replace_rule $replacenum + proto=udp + replace_rule $replacenum + return + fi + + replace_rule $replacenum +} + refresh_dns() { local dns local group