[packages] multiwan: Adjusted initial restore mark rule
[openwrt/svn-archive/archive.git] / net / multiwan / files / usr / bin / multiwan
index 41080135344c6a92fa60756757b578498ab50121..8a269af874d169663e1bccce31a3f4e75122e6c6 100755 (executable)
@@ -39,10 +39,12 @@ add() {
        update_cache
 
 if [ "$existing_failover" == "2" ]; then
-       if [ "$failover_to" != "balancer" -a "$failover_to" != "disable" -a "$failover_to_wanid" != "$wanid" ]; 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
        elif [ "$failover_to" == "balancer" ]; then
                iptables -I FW${wanid}MARK 2 -t mangle -j LoadBalancer
+       elif [ "$failover_to" == "fastbalancer" ]; then
+               iptables -I FW${wanid}MARK 2 -t mangle -j FastBalancer
        fi
 fi
         mwnote "$1 has failed and is currently offline."
@@ -150,8 +152,6 @@ fi
 }
 
 acquire_wan_data() {
-if [ $wancount -lt 9 ]; then
-
 local ipaddr
 local gateway
 local ifname
@@ -179,6 +179,10 @@ check_old_map=`echo $wan_id_map 2>&1 | grep -o "$1\["`
 
        if [ -z $check_old_map ]; then
                wancount=`expr $wancount + 1`
+               if [ $wancount -gt 20 ]; then
+                  wancount=20
+                   return
+                fi
                wan_if_map="$wan_if_map${1}[${ifname}]"
                wan_id_map="$wan_id_map${1}[${wancount}]"
                wan_gw_map="$wan_gw_map${1}[${gateway}]"
@@ -196,8 +200,8 @@ check_old_map=`echo $wan_id_map 2>&1 | grep -o "$1\["`
                 if [ "$old_ifname" != "$ifname" ]; then
                iptables -D MultiWanPreHandler -t mangle -i $old_$ifname -m state --state NEW -j FW${get_wanid}MARK
                iptables -A MultiWanPreHandler -t mangle -i $ifname -m state --state NEW -j FW${get_wanid}MARK 
-               iptables -D MultiWanPostHandler -t mangle -o $old_$ifname -m mark --mark 0x123 -j FW${get_wanid}MARK
-               iptables -A MultiWanPostHandler -t mangle -o $ifname -m mark --mark 0x123 -j FW${get_wanid}MARK 
+               iptables -D MultiWanPostHandler -t mangle -o $old_$ifname -m mark --mark 0x1 -j FW${get_wanid}MARK
+               iptables -A MultiWanPostHandler -t mangle -o $ifname -m mark --mark 0x1 -j FW${get_wanid}MARK 
                 fi 
 
                 if [ "$ifname" != "x" -a "$ipaddr" != "x" -a "$gateway" != "x" ]; then
@@ -212,9 +216,6 @@ check_old_map=`echo $wan_id_map 2>&1 | grep -o "$1\["`
                 refresh_dns
                update_cache
        fi
-else
-wancount=9
-fi
 }
 
 update_cache() {
@@ -276,10 +277,6 @@ echo "## Refreshing Interfaces ##"
                ifup $group > /dev/null 2>&1 &
        done
 
-if [ ! -z "$CHKFORQOS" ]; then
-/etc/init.d/qos restart & > /dev/null 2>&1
-fi
-
 echo "## Unloaded, updating syslog and exiting. ##"
 mwnote "Succesfully Unloaded on $(exec date -R)."
 ip route flush cache
@@ -317,6 +314,8 @@ iptables -t mangle -F MultiWanPostHandler
 iptables -t mangle -X MultiWanPostHandler
 iptables -t mangle -F LoadBalancer
 iptables -t mangle -X LoadBalancer
+iptables -t mangle -F FastBalancer
+iptables -t mangle -X FastBalancer
 
 i=0
 while [ $i -lt $wancount ]; do 
@@ -339,10 +338,10 @@ i=0
 while [ $i -lt $wancount ]; do 
 i=`expr $i + 1` 
 group=$(query_config group $i)
-iptables -t mangle -F MultiWanQoS_${group}
-iptables -t mangle -F MultiWanQoS_${group}_ct
-iptables -t mangle -X MultiWanQoS_${group}
-iptables -t mangle -X MultiWanQoS_${group}_ct
+iptables -t mangle -F qos_${group}
+iptables -t mangle -F qos_${group}_ct
+iptables -t mangle -X qos_${group}
+iptables -t mangle -X qos_${group}_ct
 done
 
 fi
@@ -356,6 +355,8 @@ local get_wan_iptables
 local add_qos_iptables
 local add_qos_tc
 local execute
+local iprule
+local qos_if_test
 local i 
 local p
 
@@ -365,6 +366,14 @@ if [ "$ifname" == "x" ]; then
 return
 fi
 
+qos_if_test=$(echo $qos_if_done | grep $ifname.)
+
+if [ ! -z "$qos_if_test" ]; then
+return
+fi
+
+qos_if_done=$(echo ${qos_if_done}.${ifname})
+
 queue_count=$(tc filter list dev $ifname | tail -n 1 | awk -F " " '{print $10}' | sed "s/0x//g")
 
 if [ -z "$queue_count" ]; then
@@ -373,15 +382,16 @@ fi
 
 queue_count=`expr $queue_count + 1`
 
-iptables -t mangle -N MultiWanQoS_${1}
-iptables -t mangle -N MultiWanQoS_${1}_ct
+iptables -t mangle -N qos_${1}
+iptables -t mangle -N qos_${1}_ct
 
 get_wan_tc=$(tc filter list dev $ifname | grep "0x" | sed -e "s/filter /tc filter add dev $ifname /g" -e "s/pref/prio/g" -e "s/fw//g") 
-get_wan_iptables=$(iptables-save | egrep  '(-A Default )|(-A Default_ct )' | grep -v "MultiWanQoS" | sed -e "s/Default /MultiWanQoS_${1} /g" -e "s/Default_ct /MultiWanQoS_${1}_ct /g" -e "s/-A/iptables -t mangle -A/g")
+get_wan_iptables=$(iptables-save | egrep  '(-A Default )|(-A Default_ct )' | grep -v "MultiWanQoS" | sed -e "s/Default /qos_${1} /g" -e "s/Default_ct /qos_${1}_ct /g" -e "s/-A/iptables -t mangle -A/g")
+
 
 i=0
 while [ $i -lt $queue_count ]; do 
-echo "s/\(0x$i \|0x$i\/0xffffffff\)/0x${2}${i} /g" >> /tmp/.mwan/qos.$1.sedfilter
+echo "s/\(0x$i \|0x$i\/0xffffffff\)/0x$(expr $2 \* 10 + $i) /g" >> /tmp/.mwan/qos.$1.sedfilter
 i=`expr $i + 1` 
 done
 
@@ -401,11 +411,10 @@ rm /tmp/.mwan/qos.$1.sedfilter
 
 i=0
 while [ $i -lt $queue_count ]; do
-  p=`expr $i + $2 \* 10`
 if [ $i -lt $(expr $queue_count - 1) ]; then
-  ip rule add fwmark 0x$(expr $p + 1) table $(expr $2 \* 10) prio $(expr $p + 2)
+  ip rule add fwmark 0x$(expr $2 \* 10 + $i + 1) table $(expr $2 + 170) prio $(expr $2 \* 10 + $i + 2)
 fi
-  iptables -t mangle -A MultiWanQoS -m mark --mark 0x$p -j MultiWanQoS_${1}
+  iptables -t mangle -A MultiWanQoS -m mark --mark 0x$(expr $2 \* 10 + $i) -j qos_${1}
   i=`expr $i + 1`
 done
 }
@@ -429,11 +438,13 @@ mwanrule() {
           return
        fi
 
-    if [ "$wanrule" != "balancer" ]; then
+    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 [ "$dst" == "all" ]; then
        dst=$NULL
@@ -509,7 +520,8 @@ dns=$(echo $dns | sed -e "s/ /\n/g")
 if [ ! -z "$dns" -a "$failchk" != "x" -a "$ipaddr" != "x" -a "$gateway" != "x" -a "$ifname" != "x" ]; then
 echo "$dns" | while read dns_server 
 do
-       iptables -t mangle -A MultiWanDNS -d $dns_server -j FW${i}MARK
+       iptables -t mangle -A MultiWanDNS -d $dns_server -p tcp --dport 53 -j FW${i}MARK
+       iptables -t mangle -A MultiWanDNS -d $dns_server -p udp --dport 53 -j FW${i}MARK
 
                compile_dns="nameserver $dns_server"
                echo "$compile_dns" >> /tmp/resolv.conf.auto
@@ -559,10 +571,12 @@ fi
 
 iptables -t mangle -N MultiWan
 iptables -t mangle -N LoadBalancer
+iptables -t mangle -N FastBalancer
 iptables -t mangle -N MultiWanRules
 iptables -t mangle -N MultiWanDNS
 iptables -t mangle -N MultiWanPreHandler
 iptables -t mangle -N MultiWanPostHandler
+iptables -t mangle -N MultiWanLoadBalancer
 
 echo "## Creating FW Rules ##"
 i=0
@@ -574,45 +588,58 @@ iptables -t mangle -A FW${i}MARK -j MARK --set-mark 0x${iprule}
 iptables -t mangle -A FW${i}MARK -j CONNMARK --save-mark
 done
 
-iptables -t mangle -A LoadBalancer -j MARK --set-mark 0x123
+iptables -t mangle -A LoadBalancer -j MARK --set-mark 0x1
 iptables -t mangle -A LoadBalancer -j CONNMARK --save-mark
 
+if [ -z "$CHKFORMODULE" ]; then
+iptables -t mangle -A FastBalancer -j MARK --set-mark 0x2
+iptables -t mangle -A FastBalancer -j CONNMARK --save-mark
+else
+mwnote "Performance load balancer(fastbalanacer) is unavailable due to current kernel limitations.."
+iptables -t mangle -A FastBalancer -j MARK --set-mark 0x1
+iptables -t mangle -A FastBalancer -j CONNMARK --save-mark
+fi
+
+iptables -t mangle -A MultiWan -j CONNMARK --restore-mark
+iptables -t mangle -A MultiWan -j MultiWanPreHandler
+iptables -t mangle -A MultiWan -j MultiWanRules
+iptables -t mangle -A MultiWan -j MultiWanLoadBalancer
+iptables -t mangle -A MultiWan -j MultiWanDNS
+iptables -t mangle -A MultiWan -j MultiWanPostHandler
+
 iptables -t mangle -I PREROUTING -j MultiWan
 iptables -t mangle -I FORWARD -j MultiWan
 iptables -t mangle -I OUTPUT -j MultiWan
 iptables -t mangle -I POSTROUTING -j MultiWan
 
-iptables -t mangle -A MultiWan -j CONNMARK --restore-mark
-iptables -t mangle -A MultiWan -j MultiWanPreHandler
 
 refresh_dns
 
 config_load "multiwan"
 config_foreach mwanrule mwanfw
 
-if [ "$default_route" != "balancer" ]; then 
+if [ "$default_route" != "balancer" -a "$default_route" != "fastbalancer" ]; then 
 default_route_id=$(query_config wanid $default_route)
 iptables -t mangle -A MultiWanRules -m mark --mark 0x0 -j FW${default_route_id}MARK
+elif [ "$default_route" == "fastbalancer" ]; then
+iptables -t mangle -A MultiWanRules -m mark --mark 0x0 -j FastBalancer
 else
 iptables -t mangle -A MultiWanRules -m mark --mark 0x0 -j LoadBalancer
 fi
 
-iptables -t mangle -A MultiWan -j MultiWanRules
-iptables -t mangle -A MultiWan -j MultiWanDNS
-iptables -t mangle -A MultiWan -j MultiWanPostHandler
-
 i=0
 while [ $i -lt $wancount ]; do 
 i=`expr $i + 1` 
 group=$(query_config group $i)
 ifname=$(query_config ifname $group)
 iptables -t mangle -A MultiWanPreHandler -i $ifname -m state --state NEW -j FW${i}MARK
-iptables -t mangle -A MultiWanPostHandler -o $ifname -m mark --mark 0x123 -j FW${i}MARK
+iptables -t mangle -A MultiWanPostHandler -o $ifname -m mark --mark 0x1 -j FW${i}MARK
 done
 
 if [ ! -z "$CHKFORQOS" ]; then
 iptables -t mangle -A MultiWan -j MultiWanQoS
 fi
+
 }
 
 refresh_loadbalancer() {
@@ -623,19 +650,16 @@ local failchk
 local weight
 local nexthop
 local pre_nexthop_chk
+local rand_probability
+local total_weight
 local i
 
-
 echo "## Refreshing Load Balancer ##"
 
-CHKIPROUTE=`cat /etc/iproute2/rt_tables | grep LoadBalancer`
- if [ -z "$CHKIPROUTE" ]; then
-echo "123     LoadBalancer" >> /etc/iproute2/rt_tables
- fi
-ip rule del prio 123 > /dev/null 2>&1 
-ip route flush table 123 > /dev/null 2>&1
+ip rule del prio 9 > /dev/null 2>&1 
+ip route flush table 170 > /dev/null 2>&1
 
-        for TABLE in 123
+        for TABLE in 170
         do
                 ip route | grep link | grep -Ev ^default | while read ROUTE
                 do
@@ -643,6 +667,23 @@ ip route flush table 123 > /dev/null 2>&1
                 done
          done
 
+iptables -F MultiWanLoadBalancer -t mangle
+
+total_weight=0
+
+i=0
+while [ $i -lt $wancount ]; do 
+i=`expr $i + 1` 
+group=$(query_config group $i)
+failchk=$(query_config failchk $group)
+gateway=$(query_config gateway $group)
+ifname=$(query_config ifname $group)
+weight=`uci -q -P /var/state get multiwan.${group}.weight`
+        if [ "$gateway" != "x" -a "$ifname" != "x" -a "$failchk" != "x" -a "$weight" != "disable" ]; then
+                total_weight=$(expr $total_weight + $weight)
+        fi
+done
+
 i=0
 while [ $i -lt $wancount ]; do 
 i=`expr $i + 1` 
@@ -655,17 +696,33 @@ weight=`uci -q -P /var/state get multiwan.${group}.weight`
 
 if [ "$gateway" != "x" -a "$ifname" != "x" -a "$failchk" != "x" -a "$weight" != "disable" ]; then
 nexthop="$nexthop nexthop via $gateway dev $ifname weight $weight"
+
+rand_probability=$(expr $(expr $weight \* 100) / $total_weight)
+total_weight=$(expr $total_weight - $weight)
+
+        if [ $rand_probability -lt 10 ]; then
+                rand_probability="0.0${rand_probability}"
+        elif [ $rand_probability -lt 100 ]; then
+                rand_probability="0.${rand_probability}"
+        else
+                rand_probability="1.0"
+        fi
+
+       if [ -z "$CHKFORMODULE" ]; then
+               iptables -A MultiWanLoadBalancer -t mangle -m mark --mark 0x2 -m statistic --mode random --probability $rand_probability -j FW${i}MARK
+       fi
 fi
+
 done
 
 pre_nexthop_chk=`echo $nexthop | awk -F "nexthop" '{print NF-1}'`
 if [ "$pre_nexthop_chk" == "1" ]; then
-ip route add default via $(echo $nexthop | awk -F " " '{print $3}') dev $(echo $nexthop | awk -F " " '{print $5}') proto static table 123
+ip route add default via $(echo $nexthop | awk -F " " '{print $3}') dev $(echo $nexthop | awk -F " " '{print $5}') proto static table 170
 elif [ "$pre_nexthop_chk" -gt "1" ]; then
-ip route add proto static table 123 default scope global $nexthop
+ip route add proto static table 170 default scope global $nexthop
 fi
 
-ip rule add fwmark 0x123 table 123 prio 123
+ip rule add fwmark 0x1 table 170 prio 9
 ip route flush cache
 }
 
@@ -675,6 +732,7 @@ local gateway
 local group
 local ifname
 local ipaddr
+local lanip
 local i
 
 echo "## Refreshing Routing Tables ##"
@@ -687,11 +745,9 @@ group=$(query_config group $i)
 gateway=$(query_config gateway $group)
 ifname=$(query_config ifname $group)
 ipaddr=$(query_config ipaddr $group)
+ip route flush table $(expr $i + 170) > /dev/null 2>&1
 
-iprule=$(expr $i \* 10)
-ip route flush table $iprule > /dev/null 2>&1
-
-        for TABLE in $iprule
+        for TABLE in $(expr $i + 170)
         do
                 ip route | grep link | grep -Ev ^default | while read ROUTE
                 do
@@ -700,8 +756,16 @@ ip route flush table $iprule > /dev/null 2>&1
          done
 
 if [ "$gateway" != "x" -a "$ipaddr" != "x" -a "$ifname" != "x" ]; then
-ip route add default via $gateway table $iprule src $ipaddr proto static
-route add default gw $gateway dev $ifname 
+ip route add default via $gateway table $(expr $i + 170) src $ipaddr proto static
+ip route del default > /dev/null 2>&1
+
+   if [ ! -z $lan_if ]; then
+      lanip=`uci -q -P /var/state get network.${lan_if}.ipaddr`
+   else
+      lanip=`uci -q -P /var/state get network.lan.ipaddr`
+   fi
+
+ip route add default via $lanip > /dev/null 2>&1
 fi
 done
 
@@ -715,27 +779,25 @@ local group
 local gateway
 local ipaddr
 
-iprule=$(expr $1 \* 10)
 group=$(query_config group $1)
 gateway=$(query_config gateway $group)
 ipaddr=$(query_config ipaddr $group)
 
 CHKIPROUTE=`cat /etc/iproute2/rt_tables | grep MWAN${1}`
  if [ -z "$CHKIPROUTE" ]; then
-echo "$iprule      MWAN${1}" >> /etc/iproute2/rt_tables
+echo "$(expr $1 + 170) MWAN${1}" >> /etc/iproute2/rt_tables
  fi
 
-ip rule del prio $iprule > /dev/null 2>&1 
-ip rule del prio $(expr $iprule + 1) > /dev/null 2>&1
+ip rule del prio $(expr $1 \* 10) > /dev/null 2>&1 
+ip rule del prio $(expr $1 \* 10 + 1) > /dev/null 2>&1
 
 if [ "$gateway" != "x" -a "$ipaddr" != "x" ]; then
-ip rule add from $ipaddr table $iprule prio $iprule
-ip rule add fwmark 0x${iprule} table $iprule prio $(expr $iprule + 1)
+ip rule add from $ipaddr table $(expr $1 + 170) prio $(expr $1 \* 10)
+ip rule add fwmark 0x$(expr $1 \* 10) table $(expr $1 + 170) prio $(expr $(expr $1 \* 10) + 1)
 fi
 }
 
 flush() {
-local iprule
 local i
 
 echo "## Flushing IP Rules & Routes ##"
@@ -744,14 +806,13 @@ ip rule flush > /dev/null 2>&1
 ip rule add lookup main prio 32766 > /dev/null 2>&1
 ip rule add lookup default prio 32767 > /dev/null 2>&1
 
-ip route flush table 123 > /dev/null
+ip route flush table 170 > /dev/null
 
        i=0
        while [ $i -lt $wancount ]; do 
                i=`expr $i + 1` 
-               iprule=$(expr $i \* 10)
                 ip route del default > /dev/null 2>&1
-                ip route flush table $iprule > /dev/null 2>&1
+                ip route flush table $(expr $i + 170) > /dev/null 2>&1
        done
 
 echo "## Clearing Rules ##"
@@ -773,9 +834,15 @@ mkdir /tmp/.mwan > /dev/null 2>&1
 mwan_kill
 flush
 
-refresh_loadbalancer
 
 echo "## IP Rules Initialization ##"
+
+CHKIPROUTE=`cat /etc/iproute2/rt_tables | grep LoadBalancer`
+ if [ -z "$CHKIPROUTE" ]; then
+echo "#" >> /etc/iproute2/rt_tables
+echo "170 LoadBalancer" >> /etc/iproute2/rt_tables
+ fi
+
 i=0
 while [ $i -lt $wancount ]; do 
 i=`expr $i + 1` 
@@ -785,6 +852,8 @@ done
 refresh_routes
 iptables_init
 
+refresh_loadbalancer
+
 RP_PATH=/proc/sys/net/ipv4/conf
 for IFACE in `ls $RP_PATH`; do
    echo 0 > $RP_PATH/$IFACE/rp_filter
@@ -995,6 +1064,7 @@ wancount=0
 config_clear
 config_load "multiwan"
 config_get default_route    config default_route
+config_get lan_if           config lan_if
 config_get debug            config debug 
 
 config_foreach acquire_wan_data interface
@@ -1002,6 +1072,7 @@ config_foreach acquire_wan_data interface
 update_cache
 
 CHKFORQOS=`iptables -n -L Default -t mangle 2>&1 | grep "Chain Default"`
+CHKFORMODULE=`iptables -m statistic 2>&1 | grep -o "File not found"`
 
 jobfile="/tmp/.mwan/jobqueue"