6 if [ -z "$debug" -o "$debug" == "0" ]; then
14 logger
${debug:+-s} -p 5 -t multiwan
"$1"
18 local failchk
=$
(query_config failchk
$2)
19 local recvrychk
=$
(query_config recvrychk
$2)
21 local wanid
=$
(query_config wanid
$2)
22 local failover_to
=$
(uci_get_state multiwan
${2} failover_to
)
23 local failover_to_wanid
=$
(query_config wanid
$failover_to)
25 local existing_failover
=$
(iptables
-n -L FW
${wanid}MARK
-t mangle |
echo $
(($
(wc -l) - 2)))
29 wan_fail_map
=$
(echo $wan_fail_map |
sed -e "s/${1}\[${failchk}\]//g")
30 wan_fail_map
="$wan_fail_map${1}[x]"
31 wan_recovery_map
=$
(echo $wan_recovery_map |
sed -e "s/${1}\[${recvrychk}\]//g")
34 if [ "$existing_failover" == "2" ]; then
35 if [ "$failover_to" != "balancer" -a "$failover_to" != "fastbalancer" -a "$failover_to" != "disable" -a "$failover_to_wanid" != "$wanid" ]; then
36 iptables
-I FW
${wanid}MARK
2 -t mangle
-j FW
${failover_to_wanid}MARK
37 elif [ "$failover_to" == "balancer" ]; then
38 iptables
-I FW
${wanid}MARK
2 -t mangle
-j LoadBalancer
39 elif [ "$failover_to" == "fastbalancer" ]; then
40 iptables
-I FW
${wanid}MARK
2 -t mangle
-j FastBalancer
43 mwnote
"$1 has failed and is currently offline."
48 wan_recovery_map
=$
(echo $wan_recovery_map |
sed -e "s/${1}\[${recvrychk}\]//g")
49 wan_fail_map
=$
(echo $wan_fail_map |
sed -e "s/${1}\[${failchk}\]//g")
52 if [ "$existing_failover" == "3" ]; then
53 iptables
-D FW
${wanid}MARK
2 -t mangle
55 mwnote
"$1 has recovered and is back online!"
67 local health_fail_retries
=$
(uci_get_state multiwan
${1} health_fail_retries
)
68 local weight
=$
(uci_get_state multiwan
${1} weight
)
70 local failchk
=$
(query_config failchk
$1)
71 local recvrychk
=$
(query_config recvrychk
$1)
72 wan_recovery_map
=$
(echo $wan_recovery_map |
sed -e "s/${1}\[${recvrychk}\]//g")
74 if [ -z "$failchk" ]; then
76 wan_fail_map
="$wan_fail_map${1}[1]"
79 if [ "$failchk" != "x" ]; then
80 new_fail_count
=$
(($failchk + 1))
81 if [ "$new_fail_count" -lt "$health_fail_retries" ]; then
82 wan_fail_map
=$
(echo $wan_fail_map |
sed -e "s/${1}\[${failchk}\]/$1\[${new_fail_count}\]/g")
86 if [ "$weight" != "disable" ]; then
97 local health_recovery_retries
=$
(uci_get_state multiwan
${1} health_recovery_retries
)
98 local weight
=$
(uci_get_state multiwan
${1} weight
)
100 local failchk
=$
(query_config failchk
$1)
101 local recvrychk
=$
(query_config recvrychk
$1)
102 local wanid
=$
(query_config wanid
$1)
104 if [ ! -z "$failchk" -a "$failchk" != "x" ]; then
105 wan_fail_map
=$
(echo $wan_fail_map |
sed -e "s/${1}\[${failchk}\]//g")
109 if [ "$failchk" == "x" ]; then
110 if [ -z "$recvrychk" ]; then
111 wan_recovery_map
="$wan_recovery_map${1}[1]"
113 if [ "$health_recovery_retries" == "1" ]; then
117 new_recovery_count
=$
(($recvrychk + 1))
118 if [ "$new_recovery_count" -lt "$health_recovery_retries" ]; then
119 wan_recovery_map
=$
(echo $wan_recovery_map |
sed -e "s/${1}\[${recvrychk}\]/$1\[${new_recovery_count}\]/g")
124 if [ "$weight" != "disable" ]; then
139 local ifname
=$
(uci_get_state network
${1} ifname
'x')
140 local ipaddr
=$
(uci_get_state network
${1} ipaddr
'x')
141 local gateway
=$
(uci_get_state network
${1} gateway
'x')
143 check_old_map
=$
(echo $wan_id_map 2>&1 |
grep -o "$1\[")
145 if [ -z $check_old_map ]; then
146 wancount
=$
(($wancount + 1))
147 if [ $wancount -gt 20 ]; then
151 wan_if_map
="$wan_if_map${1}[${ifname}]"
152 wan_id_map
="$wan_id_map${1}[${wancount}]"
153 wan_gw_map
="$wan_gw_map${1}[${gateway}]"
154 wan_ip_map
="$wan_ip_map${1}[${ipaddr}]"
156 old_ipaddr
=$
(query_config ipaddr
$1)
157 old_gateway
=$
(query_config gateway
$1)
158 old_ifname
=$
(query_config ifname
$1)
159 get_wanid
=$
(query_config wanid
$1)
161 wan_if_map
=$
(echo $wan_if_map |
sed -e "s/${1}\[${old_ifname}\]/$1\[${ifname}\]/g")
162 wan_ip_map
=$
(echo $wan_ip_map |
sed -e "s/${1}\[${old_ipaddr}\]/$1\[${ipaddr}\]/g")
163 wan_gw_map
=$
(echo $wan_gw_map |
sed -e "s/${1}\[${old_gateway}\]/$1\[${gateway}\]/g")
165 if [ "$old_ifname" != "$ifname" ]; then
166 iptables
-D MultiWanPreHandler
-t mangle
-i $old_$ifname -m state
--state NEW
-j FW
${get_wanid}MARK
167 iptables
-A MultiWanPreHandler
-t mangle
-i $ifname -m state
--state NEW
-j FW
${get_wanid}MARK
168 iptables
-D MultiWanPostHandler
-t mangle
-o $old_$ifname -m mark
--mark 0x1 -j FW
${get_wanid}MARK
169 iptables
-A MultiWanPostHandler
-t mangle
-o $ifname -m mark
--mark 0x1 -j FW
${get_wanid}MARK
172 if [ "$ifname" != "x" -a "$ipaddr" != "x" -a "$gateway" != "x" ]; then
174 iprules_config
$get_wanid
187 if [ ! -d /tmp
/.mwan
]; then
188 mkdir
/tmp
/.mwan
> /dev
/null
2>&1
191 rm /tmp
/.mwan
/cache
> /dev
/null
2>&1
192 touch /tmp
/.mwan
/cache
194 echo "# Automatically Generated by Multi-WAN Agent Script. Do not modify or remove. #" > /tmp
/.mwan
/cache
195 echo "wan_id_map=\"$wan_id_map\"" >> /tmp
/.mwan
/cache
196 echo "wan_if_map=\"$wan_if_map\"" >> /tmp
/.mwan
/cache
197 echo "wan_ip_map=\"$wan_ip_map\"" >> /tmp
/.mwan
/cache
198 echo "wan_gw_map=\"$wan_gw_map\"" >> /tmp
/.mwan
/cache
199 echo "wan_fail_map=\"$wan_fail_map\"" >> /tmp
/.mwan
/cache
200 echo "wan_recovery_map=\"$wan_recovery_map\"" >> /tmp
/.mwan
/cache
201 echo "wan_monitor_map=\"$wan_monitor_map\"" >> /tmp
/.mwan
/cache
206 ifname
) echo $wan_if_map |
grep -o "$2\[\w*.*\]" |
awk -F "[" '{print $2}' |
awk -F "]" '{print $1}';;
207 ipaddr
) echo $wan_ip_map |
grep -o "$2\[\w*.*\]" |
awk -F "[" '{print $2}' |
awk -F "]" '{print $1}';;
208 gateway
) echo $wan_gw_map |
grep -o "$2\[\w*.*\]" |
awk -F "[" '{print $2}' |
awk -F "]" '{print $1}';;
209 wanid
) echo $wan_id_map |
grep -o "$2\[\w*.*\]" |
awk -F "[" '{print $2}' |
awk -F "]" '{print $1}';;
210 failchk
) echo $wan_fail_map |
grep -o "$2\[\w*.*\]" |
awk -F "[" '{print $2}' |
awk -F "]" '{print $1}';;
211 recvrychk
) echo $wan_recovery_map |
grep -o "$2\[\w*.*\]" |
awk -F "[" '{print $2}' |
awk -F "]" '{print $1}';;
212 monitor
) echo $wan_monitor_map |
grep -o "$2\[\w*.*\]" |
awk -F "[" '{print $2}' |
awk -F "]" '{print $1}';;
213 group
) echo $wan_id_map |
grep -o "\w*\[$2\]" |
awk -F "[" '{print $1}';;
218 local otherpids
=$
(ps
2>&1 |
grep 'multiwan agent' |
grep -v $$ |
awk '{print $1}')
219 [ -n "$otherpids" ] && kill $otherpids > /dev
/null
2>&1
223 # For system shutdownl: stop
224 # A plain stop will leave network in a limp state, without wan access
225 # stop single: restore to a single wan
226 # stop restart: restart multiple wan's
231 if [ "$1" == "single" ]; then
232 # ifup is quite expensive--do it only when single wan is requested
233 echo "## Refreshing Interfaces ##"
235 while [ $
((i
++)) -lt $wancount ]; do
236 local group
=$
(query_config group
$i)
237 ifup
$group >&- 2>&- && sleep 1
240 echo "## Unloaded, updating syslog and exiting. ##"
241 mwnote
"Succesfully Unloaded on $(exec date -R)."
242 rm -fr /tmp
/.mwan
>&- 2>&-
246 if [ "$1" == "restart" ]; then
247 echo "## Restarting Multi-WAN. ##"
248 mwnote
"Reinitializing Multi-WAN Configuration."
249 rm -fr /tmp
/.mwan
>&- 2>&-
250 /etc
/init.d
/multiwan start
>&- 2>&-
257 local restore_single
=$1
260 iptables
-t mangle
-D PREROUTING
-j MultiWan
261 iptables
-t mangle
-D FORWARD
-j MultiWan
262 iptables
-t mangle
-D OUTPUT
-j MultiWan
263 iptables
-t mangle
-D POSTROUTING
-j MultiWan
264 iptables
-t mangle
-F MultiWan
265 iptables
-t mangle
-X MultiWan
266 iptables
-t mangle
-F MultiWanRules
267 iptables
-t mangle
-X MultiWanRules
268 iptables
-t mangle
-F MultiWanDNS
269 iptables
-t mangle
-X MultiWanDNS
270 iptables
-t mangle
-F MultiWanPreHandler
271 iptables
-t mangle
-X MultiWanPreHandler
272 iptables
-t mangle
-F MultiWanPostHandler
273 iptables
-t mangle
-X MultiWanPostHandler
274 iptables
-t mangle
-F LoadBalancer
275 iptables
-t mangle
-X LoadBalancer
276 iptables
-t mangle
-F FastBalancer
277 iptables
-t mangle
-X FastBalancer
278 iptables
-t mangle
-F MultiWanLoadBalancer
279 iptables
-t mangle
-X MultiWanLoadBalancer
282 while [ $
((i
++)) -lt $wancount ]; do
283 iptables
-t mangle
-F FW
${i}MARK
284 iptables
-t mangle
-X FW
${i}MARK
287 if [ ! -z "$CHKFORQOS" ]; then
288 iptables
-t mangle
-F PREROUTING
289 iptables
-t mangle
-F FORWARD
290 iptables
-t mangle
-F OUTPUT
291 iptables
-t mangle
-F POSTROUTING
292 iptables
-t mangle
-F MultiWanQoS
293 iptables
-t mangle
-X MultiWanQoS
296 while [ $
((i
++)) -lt $wancount ]; do
297 group
=$
(query_config group
$i)
298 iptables
-t mangle
-F qos_
${group}
299 iptables
-t mangle
-F qos_
${group}_ct
300 iptables
-t mangle
-X qos_
${group}
301 iptables
-t mangle
-X qos_
${group}_ct
305 [ "$restore_single" == 'single' ] &&
306 /etc
/init.d
/qos restart
> /dev
/null
2>&1
313 local get_wan_iptables
314 local add_qos_iptables
320 ifname
=$
(query_config ifname
$1)
322 if [ "$ifname" == "x" ]; then
326 qos_if_test
=$
(echo $qos_if_done |
grep $ifname.
)
328 if [ ! -z "$qos_if_test" ]; then
332 qos_if_done
=$
(echo ${qos_if_done}.
${ifname})
334 queue_count
=$
(tc filter list dev
$ifname |
tail -n 1 |
awk -F " " '{print $10}' |
sed "s/0x//g")
336 if [ -z "$queue_count" ]; then
340 queue_count
=$
(($queue_count + 1))
342 iptables
-t mangle
-N qos_
${1}
343 iptables
-t mangle
-N qos_
${1}_ct
345 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")
346 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")
350 while [ $i -lt $queue_count ]; do
351 echo "s/\(0x$i \|0x$i\/0xffffffff\)/0x$(($2 * 10 + $i)) /g" >> /tmp
/.mwan
/qos.
$1.sedfilter
355 add_qos_iptables
=$
(echo "$get_wan_iptables" |
sed -f /tmp
/.mwan
/qos.
$1.sedfilter
)
356 echo "$add_qos_iptables" |
while read execute
; do ${execute}; done
358 rm /tmp
/.mwan
/qos.
$1.sedfilter
360 while [ $i -lt $queue_count ]; do
361 echo "s/0x$i /0x${2}${i} fw /g" >> /tmp
/.mwan
/qos.
$1.sedfilter
365 add_qos_tc
=$
(echo "$get_wan_tc" |
sed -f /tmp
/.mwan
/qos.
$1.sedfilter
)
366 echo "$add_qos_tc" |
while read execute
; do ${execute}; done
367 rm /tmp
/.mwan
/qos.
$1.sedfilter
370 while [ $i -lt $queue_count ]; do
371 if [ $i -lt $
(($queue_count - 1)) ]; then
372 ip rule add fwmark
0x$
(($2 * 10 + $i + 1)) table $
(($2 + 170)) prio $
(( $2 * 10 + $i + 2))
374 iptables
-t mangle
-A MultiWanQoS
-m mark
--mark 0x$
(($2 * 10 + $i)) -j qos_
${1}
386 config_get src
$1 src
387 config_get dst
$1 dst
388 config_get port_type
$1 port_type
'dports'
389 config_get ports
$1 ports
390 config_get proto
$1 proto
391 config_get wanrule
$1 wanrule
393 if [ -z "$wanrule" ]; then
397 if [ "$wanrule" != "balancer" -a "$wanrule" != "fastbalancer" ]; then
398 wanrule
=$
(query_config wanid
${wanrule})
399 wanrule
="FW${wanrule}MARK"
400 elif [ "$wanrule" == "balancer" ]; then
401 wanrule
="LoadBalancer"
402 elif [ "$wanrule" == "fastbalancer" ]; then
403 wanrule
="FastBalancer"
405 if [ "$dst" == "all" ]; then
408 if [ "$proto" == "all" ]; then
411 if [ "$ports" == "all" ]; then
415 if [ "$proto" == "icmp" ]; then
418 if [ "$src" == "all" ]; then
421 iptables
-t mangle
-A MultiWanRules
${src:+-s $src} ${dst:+-d $dst} \
422 -m mark
--mark 0x0 ${proto:+-p $proto -m $proto} \
423 ${ports:+-m multiport --$port_type $ports} \
426 if [ -z "$proto" -a ! -z "$ports" ]; then
446 iptables
-F MultiWanDNS
-t mangle
448 rm /tmp
/resolv.conf.auto
449 touch /tmp
/resolv.conf.auto
451 echo "## Refreshing DNS Resolution and Tables ##"
454 while [ $
((i
++)) -lt $wancount ]; do
455 group
=$
(query_config group
$i)
456 gateway
=$
(query_config gateway
$group)
457 ipaddr
=$
(query_config ipaddr
$group)
458 ifname
=$
(query_config ifname
$group)
459 failchk
=$
(query_config failchk
$group)
461 dns
=$
(uci_get_state multiwan
${group} dns
'auto')
462 [ "$dns" == "auto" ] && dns
=$
(uci_get_state network
${group} dns
)
463 dns
=$
(echo $dns |
sed -e "s/ /\n/g")
465 if [ ! -z "$dns" -a "$failchk" != "x" -a "$ipaddr" != "x" -a "$gateway" != "x" -a "$ifname" != "x" ]; then
466 echo "$dns" |
while read dns_server
; do
467 iptables
-t mangle
-A MultiWanDNS
-d $dns_server -p tcp
--dport 53 -j FW
${i}MARK
468 iptables
-t mangle
-A MultiWanDNS
-d $dns_server -p udp
--dport 53 -j FW
${i}MARK
470 compile_dns
="nameserver $dns_server"
471 echo "$compile_dns" >> /tmp
/resolv.conf.auto
476 last_resolv_update
=$
(ls -l -e /tmp
/resolv.conf.auto |
awk -F " " '{print $5, $9}')
480 echo "## IPTables Rule Initialization ##"
486 local default_route_id
489 if [ ! -z "$CHKFORQOS" ]; then
490 echo "## QoS Initialization ##"
492 /etc
/init.d
/qos restart
> /dev
/null
2>&1
494 IMQ_NFO
=$
(iptables
-n -L PREROUTING
-t mangle
-v |
grep IMQ |
awk -F " " '{print $6,$12}')
496 iptables
-t mangle
-F PREROUTING
497 iptables
-t mangle
-F FORWARD
498 iptables
-t mangle
-F POSTROUTING
499 iptables
-t mangle
-F OUTPUT
501 echo "$IMQ_NFO" |
while read execute
; do
502 iptables
-t mangle
-A PREROUTING
-i $
(echo $execute |
awk -F " " '{print $1}') -j IMQ
--todev $
(echo $execute |
awk -F " " '{print $2}')
505 iptables
-t mangle
-N MultiWanQoS
508 while [ $
((i
++)) -lt $wancount ]; do
509 qos_init $
(query_config group
$i) $i
514 iptables
-t mangle
-N MultiWan
515 iptables
-t mangle
-N LoadBalancer
516 iptables
-t mangle
-N FastBalancer
517 iptables
-t mangle
-N MultiWanRules
518 iptables
-t mangle
-N MultiWanDNS
519 iptables
-t mangle
-N MultiWanPreHandler
520 iptables
-t mangle
-N MultiWanPostHandler
521 iptables
-t mangle
-N MultiWanLoadBalancer
523 echo "## Creating FW Rules ##"
525 while [ $
((i
++)) -lt $wancount ]; do
527 iptables
-t mangle
-N FW
${i}MARK
528 iptables
-t mangle
-A FW
${i}MARK
-j MARK
--set-mark 0x
${iprule}
529 iptables
-t mangle
-A FW
${i}MARK
-j CONNMARK
--save-mark
532 iptables
-t mangle
-A LoadBalancer
-j MARK
--set-mark 0x1
533 iptables
-t mangle
-A LoadBalancer
-j CONNMARK
--save-mark
535 if [ -z "$CHKFORMODULE" ]; then
536 iptables
-t mangle
-A FastBalancer
-j MARK
--set-mark 0x2
537 iptables
-t mangle
-A FastBalancer
-j CONNMARK
--save-mark
539 mwnote
"Performance load balancer(fastbalanacer) is unavailable due to current kernel limitations."
540 iptables
-t mangle
-A FastBalancer
-j MARK
--set-mark 0x1
541 iptables
-t mangle
-A FastBalancer
-j CONNMARK
--save-mark
544 iptables
-t mangle
-A MultiWan
-j CONNMARK
--restore-mark
545 iptables
-t mangle
-A MultiWan
-j MultiWanPreHandler
546 iptables
-t mangle
-A MultiWan
-j MultiWanRules
547 iptables
-t mangle
-A MultiWan
-j MultiWanLoadBalancer
548 iptables
-t mangle
-A MultiWan
-j MultiWanDNS
549 iptables
-t mangle
-A MultiWan
-j MultiWanPostHandler
551 iptables
-t mangle
-I PREROUTING
-j MultiWan
552 iptables
-t mangle
-I FORWARD
-j MultiWan
553 iptables
-t mangle
-I OUTPUT
-j MultiWan
554 iptables
-t mangle
-I POSTROUTING
-j MultiWan
559 config_load
"multiwan"
560 config_foreach mwanrule mwanfw
562 if [ "$default_route" != "balancer" -a "$default_route" != "fastbalancer" ]; then
563 default_route_id
=$
(query_config wanid
$default_route)
564 iptables
-t mangle
-A MultiWanRules
-m mark
--mark 0x0 -j FW
${default_route_id}MARK
565 elif [ "$default_route" == "fastbalancer" ]; then
566 iptables
-t mangle
-A MultiWanRules
-m mark
--mark 0x0 -j FastBalancer
568 iptables
-t mangle
-A MultiWanRules
-m mark
--mark 0x0 -j LoadBalancer
572 while [ $
((i
++)) -lt $wancount ]; do
573 group
=$
(query_config group
$i)
574 ifname
=$
(query_config ifname
$group)
575 iptables
-t mangle
-A MultiWanPreHandler
-i $ifname -m state
--state NEW
-j FW
${i}MARK
576 iptables
-t mangle
-A MultiWanPostHandler
-o $ifname -m mark
--mark 0x1 -j FW
${i}MARK
579 if [ ! -z "$CHKFORQOS" ]; then
580 iptables
-t mangle
-A MultiWan
-j MultiWanQoS
584 refresh_loadbalancer
() {
591 local pre_nexthop_chk
592 local rand_probability
594 echo "## Refreshing Load Balancer ##"
596 ip rule del prio
9 > /dev
/null
2>&1
597 ip route flush table
170 > /dev
/null
2>&1
600 ip route |
grep -Ev ^default |
while read ROUTE
; do
601 ip route add table
$TABLE to
$ROUTE
605 iptables
-F MultiWanLoadBalancer
-t mangle
610 while [ $
((i
++)) -lt $wancount ]; do
611 group
=$
(query_config group
$i)
612 failchk
=$
(query_config failchk
$group)
613 gateway
=$
(query_config gateway
$group)
614 ifname
=$
(query_config ifname
$group)
615 weight
=$
(uci_get_state multiwan
${group} weight
)
616 if [ "$gateway" != "x" -a "$ifname" != "x" -a "$failchk" != "x" -a "$weight" != "disable" ]; then
617 total_weight
=$
(($total_weight + $weight))
622 while [ $
((i
++)) -lt $wancount ]; do
623 group
=$
(query_config group
$i)
624 failchk
=$
(query_config failchk
$group)
625 gateway
=$
(query_config gateway
$group)
626 ifname
=$
(query_config ifname
$group)
628 weight
=$
(uci_get_state multiwan
${group} weight
)
630 if [ "$gateway" != "x" -a "$ifname" != "x" -a "$failchk" != "x" -a "$weight" != "disable" ]; then
631 nexthop
="$nexthop nexthop via $gateway dev $ifname weight $weight"
633 rand_probability
=$
(($weight * 100 / $total_weight))
634 total_weight
=$
(($total_weight - $weight))
636 if [ $rand_probability -lt 10 ]; then
637 rand_probability
="0.0${rand_probability}"
638 elif [ $rand_probability -lt 100 ]; then
639 rand_probability
="0.${rand_probability}"
641 rand_probability
="1.0"
644 if [ -z "$CHKFORMODULE" ]; then
645 iptables
-A MultiWanLoadBalancer
-t mangle
-m mark
--mark 0x2 -m statistic
--mode random
--probability $rand_probability -j FW
${i}MARK
651 pre_nexthop_chk
=$
(echo $nexthop |
awk -F "nexthop" '{print NF-1}')
652 if [ "$pre_nexthop_chk" == "1" ]; then
653 ip route add default via $
(echo $nexthop |
awk -F " " '{print $3}') dev $
(echo $nexthop |
awk -F " " '{print $5}') proto static table
170
654 elif [ "$pre_nexthop_chk" -gt "1" ]; then
655 ip route add proto static table
170 default scope global
$nexthop
658 ip rule add fwmark
0x1 table
170 prio
9
669 echo "## Refreshing Routing Tables ##"
672 while [ $
((i
++)) -lt $wancount ]; do
673 group
=$
(query_config group
$i)
674 gateway
=$
(query_config gateway
$group)
675 ifname
=$
(query_config ifname
$group)
676 ipaddr
=$
(query_config ipaddr
$group)
677 ip route flush table $
(($i + 170)) > /dev
/null
2>&1
680 ip route |
grep -Ev ^default |
while read ROUTE
; do
681 ip route add table
$TABLE to
$ROUTE
684 if [ "$gateway" != "x" -a "$ipaddr" != "x" -a "$ifname" != "x" ]; then
685 ip route add default via
$gateway table $
(($i + 170)) src
$ipaddr proto static
686 route add default gw
$gateway > /dev
/null
2>&1
699 group
=$
(query_config group
$1)
700 gateway
=$
(query_config gateway
$group)
701 ipaddr
=$
(query_config ipaddr
$group)
703 CHKIPROUTE
=$
(grep MWAN
${1} /etc
/iproute
2/rt_tables
)
704 if [ -z "$CHKIPROUTE" ]; then
705 echo "$(($1 + 170)) MWAN${1}" >> /etc
/iproute
2/rt_tables
708 ip rule del prio $
(($1 * 10)) > /dev
/null
2>&1
709 ip rule del prio $
(($1 * 10 + 1)) > /dev
/null
2>&1
711 if [ "$gateway" != "x" -a "$ipaddr" != "x" ]; then
712 ip rule add from
$ipaddr table $
(($1 + 170)) prio $
(($1 * 10))
713 ip rule add fwmark
0x$
(($1 * 10)) table $
(($1 + 170)) prio $
(($1 * 10 + 1))
718 local restore_single
=$1
719 echo "## Flushing IP Rules & Routes ##"
721 ip rule flush
> /dev
/null
2>&1
722 ip rule add lookup main prio
32766 > /dev
/null
2>&1
723 ip rule add lookup default prio
32767 > /dev
/null
2>&1
725 ip route flush table
170 > /dev
/null
728 while [ $
((i
++)) -lt $wancount ]; do
729 ip route del default
> /dev
/null
2>&1
730 ip route flush table $
(($i + 170)) > /dev
/null
2>&1
733 echo "## Clearing Rules ##"
734 clear_rules
$restore_single > /dev
/null
2>&1
736 rm $jobfile > /dev
/null
2>&1
742 local health_interval
744 echo "## Main Initialization ##"
746 mkdir
/tmp
/.mwan
> /dev
/null
2>&1
751 echo "## IP Rules Initialization ##"
753 CHKIPROUTE
=$
(grep LoadBalancer
/etc
/iproute
2/rt_tables
)
754 if [ -z "$CHKIPROUTE" ]; then
755 echo "#" >> /etc
/iproute
2/rt_tables
756 echo "170 LoadBalancer" >> /etc
/iproute
2/rt_tables
760 while [ $
((i
++)) -lt $wancount ]; do
769 RP_PATH
=/proc
/sys
/net
/ipv
4/conf
770 for IFACE
in $
(ls $RP_PATH); do
771 echo 0 > $RP_PATH/$IFACE/rp_filter
773 mwnote
"Succesfully Initialized on $(date -R)."
783 local ifname ipaddr gateway icmp_hosts_acquire icmp_test_host
788 local timeout
=$
(uci_get_state multiwan
${1} timeout
)
789 local icmp_hosts
=$
(uci_get_state multiwan
${1} icmp_hosts
)
790 local icmp_count
=$
(uci_get_state multiwan
${1} icmp_count
'1')
791 local health_interval
=$
(uci_get_state multiwan
${1} health_interval
)
792 local ifname_cur
=$
(query_config ifname
$1)
793 local ipaddr_cur
=$
(query_config ipaddr
$1)
794 local gateway_cur
=$
(query_config gateway
$1)
797 [ "${health_monitor%.*}" = 'parallel' ] && sleep $health_interval
799 ifname
=$
(uci_get_state network
${1} ifname
'x')
800 ipaddr
=$
(uci_get_state network
${1} ipaddr
'x')
801 gateway
=$
(uci_get_state network
${1} gateway
'x')
803 if [ "$ifname_cur" != "$ifname" -o "$ipaddr_cur" != "$ipaddr" -o "$gateway_cur" != "$gateway" ]; then
804 add_task
"$1" acquire
805 if [ "${health_monitor%.*}" = 'parallel' ]; then
811 [ "$gateway" != "x" ] && ! ip route |
grep -o $gateway >&- 2>&- &&
812 add_task route refresh
815 if [ "$icmp_hosts" != "disable" -a "$ifname" != "x" -a "$ipaddr" != "x" -a "$gateway" != "x" ]; then
817 if [ "$icmp_hosts" == "gateway" -o -z "$icmp_hosts" ]; then
818 icmp_hosts_acquire
=$gateway
819 elif [ "$icmp_hosts" == "dns" ]; then
820 icmp_hosts_acquire
=$
(uci_get_state multiwan
$1 dns
'auto')
821 [ "$icmp_hosts_acquire" == "auto" ] &&
822 icmp_hosts_acquire
=$
(uci_get_state network
$1 dns
)
824 icmp_hosts_acquire
=$icmp_hosts
827 icmp_hosts
=$
(echo $icmp_hosts_acquire |
sed -e "s/\,/ /g" |
sed -e "s/ /\n/g")
830 echo "$icmp_hosts" |
while read icmp_test_host
; do
831 ping -c "$icmp_count" -W $timeout -I $ifname $icmp_test_host 2>&1 |
grep -o "round-trip"
835 check_test
=$
(ping_test
)
837 if [ -z "$check_test" ]; then
843 elif [ "$icmp_hosts" == "disable" ]; then
847 [ "$health_monitor" = 'serial' ] && {
848 wan_monitor_map
=$
(echo $wan_monitor_map |
sed -e "s/$1\[\w*\]/$1\[$(date +%s)\]/g")
855 # Add a task to the $jobfile while ensuring
856 # no duplicate tasks for the specified group
860 grep -o "$group.$task" $jobfile >&- 2>&- ||
echo "$group.$task" >> $jobfile
863 # For health_monitor "parallel", start a background monitor for each group.
864 # For health_monitor "serial", queue monitor tasks for do_tasks.
866 local group health_interval monitored_last_at current_time
diff delay
869 get_health_interval
() {
870 group
=$
(query_config group
$1)
871 health_interval
=$
(uci_get_state multiwan
${group} health_interval
'disable')
872 [ "$health_interval" = "disable" ] && health_interval
=0
875 [ "$health_monitor" = 'parallel' ] && {
876 while [ $
((i
++)) -lt $wancount ]; do
877 get_health_interval
$i
878 if [ "$health_interval" -gt 0 ]; then
883 echo "## Started background monitor_wan ##"
884 health_monitor
="parallel.started"
887 [ "$health_monitor" = 'serial' ] && {
888 local monitor_disabled
=1
890 until [ -f $jobfile ]; do
891 current_time
=$
(date +%s
)
895 while [ $
((i
++)) -lt $wancount ]; do
896 get_health_interval
$i
897 if [ "$health_interval" -gt 0 ]; then
900 monitored_last
=$
(query_config monitor
$group)
901 [ -z "$monitored_last" ] && {
902 monitored_last
=$current_time
903 wan_monitor_map
="${wan_monitor_map}${group}[$monitored_last]"
907 will_monitor_at
=$
(($monitored_last + $health_interval))
908 diff=$
(($will_monitor_at - $current_time))
909 [ $diff -le 0 ] && add_task
"$group" 'monitor'
911 delay
=$
(($delay > $diff ?
$diff : $delay))
915 [ "$monitor_disabled" -eq 1 ] && {
916 # Although health monitors are disabled, still
917 # need to check up on iptables rules in do_tasks
918 sleep "$iptables_interval"
921 [ $delay -gt 0 ] && sleep $delay
927 # Process each task in the $jobfile in FIFO order
931 local current_resolv_file
937 if [ "$((++rule_counter))" -eq 5 -o "$health_monitor" = 'serial' ]; then
939 check_iptables
=$
(iptables
-n -L MultiWan
-t mangle |
grep "references" |
awk -F "(" '{print $2}' | cut
-d " " -f 1)
941 if [ -z "$check_iptables" -o "$check_iptables" -lt 4 ]; then
942 mwnote
"Netfilter rules appear to of been altered."
943 /etc
/init.d
/multiwan restart
947 current_resolv_file
=$
(ls -l -e /tmp
/resolv.conf.auto |
awk -F " " '{print $5, $9}')
949 if [ "$last_resolv_update" != "$current_resolv_file" ]; then
956 if [ -f $jobfile ]; then
958 mv $jobfile $jobfile.work
965 pass
) recover_wan
$1;;
968 [ "${health_monitor%.* }" = 'parallel' ] && {
970 echo "## Started background monitor_wan ##"
973 monitor
) monitor_wan
$1;;
974 refresh
) refresh_routes
;;
975 *) echo "## Unknown task command: $2 ##";;
979 queued_task
=$
(echo $LINE |
awk -F "." '{print $1,$2}')
980 execute_task
$queued_task
986 if [ "$health_monitor" = 'serial' ]; then
1001 while [ $
((i
++)) -lt $wancount ]; do
1002 group
=$
(query_config group
$i)
1003 ifname
=$
(query_config ifname
$group)
1004 ipaddr
=$
(query_config ipaddr
$group)
1005 gateway
=$
(query_config gateway
$group)
1007 if [ "$ifname" == "x" -o "$ipaddr" == "x" -o "$gateway" == "x" ]; then
1014 max_interval
=$
(((1<<31) - 1))
1017 config_load "multiwan"
1018 config_get_bool enabled config enabled '1'
1019 [ "$enabled" -gt 0 ] || exit
1020 config_get default_route config default_route
1021 config_get health_monitor config health_monitor
1022 config_get iptables_interval config iptables_interval '30'
1023 config_get debug config debug
1025 [ "$health_monitor" = 'serial' ] || health_monitor='parallel'
1027 config_foreach acquire_wan_data interface
1031 CHKFORQOS=$(iptables -n -L Default -t mangle 2>&1 | grep "Chain Default")
1032 CHKFORMODULE=$(iptables -m statistic 2>&1 | grep -o "File not found")
1034 jobfile="/tmp/.mwan/jobqueue"
1037 agent) silencer main_init;;
1038 stop) silencer stop;;
1039 restart) silencer stop restart;;
1040 single) silencer stop single;;