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
-F PREROUTING
261 iptables
-t mangle
-F FORWARD
262 iptables
-t mangle
-F POSTROUTING
263 iptables
-t mangle
-F OUTPUT
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 MultiWanQoS
289 iptables
-t mangle
-X MultiWanQoS
292 while [ $
((i
++)) -lt $wancount ]; do
293 group
=$
(query_config group
$i)
294 iptables
-t mangle
-F qos_
${group}
295 iptables
-t mangle
-F qos_
${group}_ct
296 iptables
-t mangle
-X qos_
${group}
297 iptables
-t mangle
-X qos_
${group}_ct
301 [ "$restore_single" == 'single' ] &&
302 /etc
/init.d
/qos restart
> /dev
/null
2>&1
309 local get_wan_iptables
310 local add_qos_iptables
316 ifname
=$
(query_config ifname
$1)
318 if [ "$ifname" == "x" ]; then
322 qos_if_test
=$
(echo $qos_if_done |
grep $ifname.
)
324 if [ ! -z "$qos_if_test" ]; then
328 qos_if_done
=$
(echo ${qos_if_done}.
${ifname})
330 queue_count
=$
(tc filter list dev
$ifname |
tail -n 1 |
awk -F " " '{print $10}' |
sed "s/0x//g")
332 if [ -z "$queue_count" ]; then
336 queue_count
=$
(($queue_count + 1))
338 iptables
-t mangle
-N qos_
${1}
339 iptables
-t mangle
-N qos_
${1}_ct
341 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")
342 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")
346 while [ $i -lt $queue_count ]; do
347 echo "s/\(0x$i \|0x$i\/0xffffffff\)/0x$(($2 * 10 + $i)) /g" >> /tmp
/.mwan
/qos.
$1.sedfilter
351 add_qos_iptables
=$
(echo "$get_wan_iptables" |
sed -f /tmp
/.mwan
/qos.
$1.sedfilter
)
352 echo "$add_qos_iptables" |
while read execute
; do ${execute}; done
354 rm /tmp
/.mwan
/qos.
$1.sedfilter
356 while [ $i -lt $queue_count ]; do
357 echo "s/0x$i /0x${2}${i} fw /g" >> /tmp
/.mwan
/qos.
$1.sedfilter
361 add_qos_tc
=$
(echo "$get_wan_tc" |
sed -f /tmp
/.mwan
/qos.
$1.sedfilter
)
362 echo "$add_qos_tc" |
while read execute
; do ${execute}; done
363 rm /tmp
/.mwan
/qos.
$1.sedfilter
366 while [ $i -lt $queue_count ]; do
367 if [ $i -lt $
(($queue_count - 1)) ]; then
368 ip rule add fwmark
0x$
(($2 * 10 + $i + 1)) table $
(($2 + 170)) prio $
(( $2 * 10 + $i + 2))
370 iptables
-t mangle
-A MultiWanQoS
-m mark
--mark 0x$
(($2 * 10 + $i)) -j qos_
${1}
382 config_get src
$1 src
383 config_get dst
$1 dst
384 config_get port_type
$1 port_type
'dports'
385 config_get ports
$1 ports
386 config_get proto
$1 proto
387 config_get wanrule
$1 wanrule
389 if [ -z "$wanrule" ]; then
393 if [ "$wanrule" != "balancer" -a "$wanrule" != "fastbalancer" ]; then
394 wanrule
=$
(query_config wanid
${wanrule})
395 wanrule
="FW${wanrule}MARK"
396 elif [ "$wanrule" == "balancer" ]; then
397 wanrule
="LoadBalancer"
398 elif [ "$wanrule" == "fastbalancer" ]; then
399 wanrule
="FastBalancer"
401 if [ "$dst" == "all" ]; then
404 if [ "$proto" == "all" ]; then
407 if [ "$ports" == "all" ]; then
411 if [ "$proto" == "icmp" ]; then
414 if [ "$src" == "all" ]; then
417 iptables
-t mangle
-A MultiWanRules
${src:+-s $src} ${dst:+-d $dst} \
418 -m mark
--mark 0x0 ${proto:+-p $proto -m $proto} \
419 ${ports:+-m multiport --$port_type $ports} \
422 if [ -z "$proto" -a ! -z "$ports" ]; then
442 iptables
-F MultiWanDNS
-t mangle
444 rm /tmp
/resolv.conf.auto
445 touch /tmp
/resolv.conf.auto
447 echo "## Refreshing DNS Resolution and Tables ##"
450 while [ $
((i
++)) -lt $wancount ]; do
451 group
=$
(query_config group
$i)
452 gateway
=$
(query_config gateway
$group)
453 ipaddr
=$
(query_config ipaddr
$group)
454 ifname
=$
(query_config ifname
$group)
455 failchk
=$
(query_config failchk
$group)
457 dns
=$
(uci_get_state multiwan
${group} dns
'auto')
458 [ "$dns" == "auto" ] && dns
=$
(uci_get_state network
${group} dns
)
459 dns
=$
(echo $dns |
sed -e "s/ /\n/g")
461 if [ ! -z "$dns" -a "$failchk" != "x" -a "$ipaddr" != "x" -a "$gateway" != "x" -a "$ifname" != "x" ]; then
462 echo "$dns" |
while read dns_server
; do
463 iptables
-t mangle
-A MultiWanDNS
-d $dns_server -p tcp
--dport 53 -j FW
${i}MARK
464 iptables
-t mangle
-A MultiWanDNS
-d $dns_server -p udp
--dport 53 -j FW
${i}MARK
466 compile_dns
="nameserver $dns_server"
467 echo "$compile_dns" >> /tmp
/resolv.conf.auto
472 last_resolv_update
=$
(ls -l -e /tmp
/resolv.conf.auto |
awk -F " " '{print $5, $9}')
476 echo "## IPTables Rule Initialization ##"
482 local default_route_id
485 if [ ! -z "$CHKFORQOS" ]; then
486 echo "## QoS Initialization ##"
488 /etc
/init.d
/qos restart
> /dev
/null
2>&1
490 IMQ_NFO
=$
(iptables
-n -L PREROUTING
-t mangle
-v |
grep IMQ |
awk -F " " '{print $6,$12}')
492 iptables
-t mangle
-F PREROUTING
493 iptables
-t mangle
-F FORWARD
494 iptables
-t mangle
-F POSTROUTING
495 iptables
-t mangle
-F OUTPUT
497 echo "$IMQ_NFO" |
while read execute
; do
498 iptables
-t mangle
-A PREROUTING
-i $
(echo $execute |
awk -F " " '{print $1}') -j IMQ
--todev $
(echo $execute |
awk -F " " '{print $2}')
501 iptables
-t mangle
-N MultiWanQoS
504 while [ $
((i
++)) -lt $wancount ]; do
505 qos_init $
(query_config group
$i) $i
510 iptables
-t mangle
-N MultiWan
511 iptables
-t mangle
-N LoadBalancer
512 iptables
-t mangle
-N FastBalancer
513 iptables
-t mangle
-N MultiWanRules
514 iptables
-t mangle
-N MultiWanDNS
515 iptables
-t mangle
-N MultiWanPreHandler
516 iptables
-t mangle
-N MultiWanPostHandler
517 iptables
-t mangle
-N MultiWanLoadBalancer
519 echo "## Creating FW Rules ##"
521 while [ $
((i
++)) -lt $wancount ]; do
523 iptables
-t mangle
-N FW
${i}MARK
524 iptables
-t mangle
-A FW
${i}MARK
-j MARK
--set-mark 0x
${iprule}
525 iptables
-t mangle
-A FW
${i}MARK
-j CONNMARK
--save-mark
528 iptables
-t mangle
-A LoadBalancer
-j MARK
--set-mark 0x1
529 iptables
-t mangle
-A LoadBalancer
-j CONNMARK
--save-mark
531 if [ -z "$CHKFORMODULE" ]; then
532 iptables
-t mangle
-A FastBalancer
-j MARK
--set-mark 0x2
533 iptables
-t mangle
-A FastBalancer
-j CONNMARK
--save-mark
535 mwnote
"Performance load balancer(fastbalanacer) is unavailable due to current kernel limitations."
536 iptables
-t mangle
-A FastBalancer
-j MARK
--set-mark 0x1
537 iptables
-t mangle
-A FastBalancer
-j CONNMARK
--save-mark
540 iptables
-t mangle
-A MultiWan
-j CONNMARK
--restore-mark
541 iptables
-t mangle
-A MultiWan
-j MultiWanPreHandler
542 iptables
-t mangle
-A MultiWan
-j MultiWanRules
543 iptables
-t mangle
-A MultiWan
-j MultiWanLoadBalancer
544 iptables
-t mangle
-A MultiWan
-j MultiWanDNS
545 iptables
-t mangle
-A MultiWan
-j MultiWanPostHandler
547 iptables
-t mangle
-I PREROUTING
-j MultiWan
548 iptables
-t mangle
-I FORWARD
-j MultiWan
549 iptables
-t mangle
-I OUTPUT
-j MultiWan
550 iptables
-t mangle
-I POSTROUTING
-j MultiWan
555 config_load
"multiwan"
556 config_foreach mwanrule mwanfw
558 if [ "$default_route" != "balancer" -a "$default_route" != "fastbalancer" ]; then
559 default_route_id
=$
(query_config wanid
$default_route)
560 iptables
-t mangle
-A MultiWanRules
-m mark
--mark 0x0 -j FW
${default_route_id}MARK
561 elif [ "$default_route" == "fastbalancer" ]; then
562 iptables
-t mangle
-A MultiWanRules
-m mark
--mark 0x0 -j FastBalancer
564 iptables
-t mangle
-A MultiWanRules
-m mark
--mark 0x0 -j LoadBalancer
568 while [ $
((i
++)) -lt $wancount ]; do
569 group
=$
(query_config group
$i)
570 ifname
=$
(query_config ifname
$group)
571 iptables
-t mangle
-A MultiWanPreHandler
-i $ifname -m state
--state NEW
-j FW
${i}MARK
572 iptables
-t mangle
-A MultiWanPostHandler
-o $ifname -m mark
--mark 0x1 -j FW
${i}MARK
575 if [ ! -z "$CHKFORQOS" ]; then
576 iptables
-t mangle
-A MultiWan
-j MultiWanQoS
580 refresh_loadbalancer
() {
587 local pre_nexthop_chk
588 local rand_probability
590 echo "## Refreshing Load Balancer ##"
592 ip rule del prio
9 > /dev
/null
2>&1
593 ip route flush table
170 > /dev
/null
2>&1
596 ip route |
grep -Ev ^default |
while read ROUTE
; do
597 ip route add table
$TABLE to
$ROUTE
601 iptables
-F MultiWanLoadBalancer
-t mangle
606 while [ $
((i
++)) -lt $wancount ]; do
607 group
=$
(query_config group
$i)
608 failchk
=$
(query_config failchk
$group)
609 gateway
=$
(query_config gateway
$group)
610 ifname
=$
(query_config ifname
$group)
611 weight
=$
(uci_get_state multiwan
${group} weight
)
612 if [ "$gateway" != "x" -a "$ifname" != "x" -a "$failchk" != "x" -a "$weight" != "disable" ]; then
613 total_weight
=$
(($total_weight + $weight))
618 while [ $
((i
++)) -lt $wancount ]; do
619 group
=$
(query_config group
$i)
620 failchk
=$
(query_config failchk
$group)
621 gateway
=$
(query_config gateway
$group)
622 ifname
=$
(query_config ifname
$group)
624 weight
=$
(uci_get_state multiwan
${group} weight
)
626 if [ "$gateway" != "x" -a "$ifname" != "x" -a "$failchk" != "x" -a "$weight" != "disable" ]; then
627 nexthop
="$nexthop nexthop via $gateway dev $ifname weight $weight"
629 rand_probability
=$
(($weight * 100 / $total_weight))
630 total_weight
=$
(($total_weight - $weight))
632 if [ $rand_probability -lt 10 ]; then
633 rand_probability
="0.0${rand_probability}"
634 elif [ $rand_probability -lt 100 ]; then
635 rand_probability
="0.${rand_probability}"
637 rand_probability
="1.0"
640 if [ -z "$CHKFORMODULE" ]; then
641 iptables
-A MultiWanLoadBalancer
-t mangle
-m mark
--mark 0x2 -m statistic
--mode random
--probability $rand_probability -j FW
${i}MARK
647 pre_nexthop_chk
=$
(echo $nexthop |
awk -F "nexthop" '{print NF-1}')
648 if [ "$pre_nexthop_chk" == "1" ]; then
649 ip route add default via $
(echo $nexthop |
awk -F " " '{print $3}') dev $
(echo $nexthop |
awk -F " " '{print $5}') proto static table
170
650 elif [ "$pre_nexthop_chk" -gt "1" ]; then
651 ip route add proto static table
170 default scope global
$nexthop
654 ip rule add fwmark
0x1 table
170 prio
9
665 echo "## Refreshing Routing Tables ##"
668 while [ $
((i
++)) -lt $wancount ]; do
669 group
=$
(query_config group
$i)
670 gateway
=$
(query_config gateway
$group)
671 ifname
=$
(query_config ifname
$group)
672 ipaddr
=$
(query_config ipaddr
$group)
673 ip route flush table $
(($i + 170)) > /dev
/null
2>&1
676 ip route |
grep -Ev ^default |
while read ROUTE
; do
677 ip route add table
$TABLE to
$ROUTE
680 if [ "$gateway" != "x" -a "$ipaddr" != "x" -a "$ifname" != "x" ]; then
681 ip route add default via
$gateway table $
(($i + 170)) src
$ipaddr proto static
682 route add default gw
$gateway > /dev
/null
2>&1
695 group
=$
(query_config group
$1)
696 gateway
=$
(query_config gateway
$group)
697 ipaddr
=$
(query_config ipaddr
$group)
699 CHKIPROUTE
=$
(grep MWAN
${1} /etc
/iproute
2/rt_tables
)
700 if [ -z "$CHKIPROUTE" ]; then
701 echo "$(($1 + 170)) MWAN${1}" >> /etc
/iproute
2/rt_tables
704 ip rule del prio $
(($1 * 10)) > /dev
/null
2>&1
705 ip rule del prio $
(($1 * 10 + 1)) > /dev
/null
2>&1
707 if [ "$gateway" != "x" -a "$ipaddr" != "x" ]; then
708 ip rule add from
$ipaddr table $
(($1 + 170)) prio $
(($1 * 10))
709 ip rule add fwmark
0x$
(($1 * 10)) table $
(($1 + 170)) prio $
(($1 * 10 + 1))
714 local restore_single
=$1
715 echo "## Flushing IP Rules & Routes ##"
717 ip rule flush
> /dev
/null
2>&1
718 ip rule add lookup main prio
32766 > /dev
/null
2>&1
719 ip rule add lookup default prio
32767 > /dev
/null
2>&1
721 ip route flush table
170 > /dev
/null
724 while [ $
((i
++)) -lt $wancount ]; do
725 ip route del default
> /dev
/null
2>&1
726 ip route flush table $
(($i + 170)) > /dev
/null
2>&1
729 echo "## Clearing Rules ##"
730 clear_rules
$restore_single > /dev
/null
2>&1
732 rm $jobfile > /dev
/null
2>&1
738 local health_interval
740 echo "## Main Initialization ##"
742 mkdir
/tmp
/.mwan
> /dev
/null
2>&1
747 echo "## IP Rules Initialization ##"
749 CHKIPROUTE
=$
(grep LoadBalancer
/etc
/iproute
2/rt_tables
)
750 if [ -z "$CHKIPROUTE" ]; then
751 echo "#" >> /etc
/iproute
2/rt_tables
752 echo "170 LoadBalancer" >> /etc
/iproute
2/rt_tables
756 while [ $
((i
++)) -lt $wancount ]; do
765 RP_PATH
=/proc
/sys
/net
/ipv
4/conf
766 for IFACE
in $
(ls $RP_PATH); do
767 echo 0 > $RP_PATH/$IFACE/rp_filter
769 mwnote
"Succesfully Initialized on $(date -R)."
779 local ifname ipaddr gateway icmp_hosts_acquire icmp_test_host
784 local timeout
=$
(uci_get_state multiwan
${1} timeout
)
785 local icmp_hosts
=$
(uci_get_state multiwan
${1} icmp_hosts
)
786 local icmp_count
=$
(uci_get_state multiwan
${1} icmp_count
'1')
787 local health_interval
=$
(uci_get_state multiwan
${1} health_interval
)
788 local ifname_cur
=$
(query_config ifname
$1)
789 local ipaddr_cur
=$
(query_config ipaddr
$1)
790 local gateway_cur
=$
(query_config gateway
$1)
793 [ "${health_monitor%.*}" = 'parallel' ] && sleep $health_interval
795 ifname
=$
(uci_get_state network
${1} ifname
'x')
796 ipaddr
=$
(uci_get_state network
${1} ipaddr
'x')
797 gateway
=$
(uci_get_state network
${1} gateway
'x')
799 if [ "$ifname_cur" != "$ifname" -o "$ipaddr_cur" != "$ipaddr" -o "$gateway_cur" != "$gateway" ]; then
800 add_task
"$1" acquire
801 if [ "${health_monitor%.*}" = 'parallel' ]; then
807 [ "$gateway" != "x" ] && ! ip route |
grep -o $gateway >&- 2>&- &&
808 add_task route refresh
811 if [ "$icmp_hosts" != "disable" -a "$ifname" != "x" -a "$ipaddr" != "x" -a "$gateway" != "x" ]; then
813 if [ "$icmp_hosts" == "gateway" -o -z "$icmp_hosts" ]; then
814 icmp_hosts_acquire
=$gateway
815 elif [ "$icmp_hosts" == "dns" ]; then
816 icmp_hosts_acquire
=$
(uci_get_state multiwan
$1 dns
'auto')
817 [ "$icmp_hosts_acquire" == "auto" ] &&
818 icmp_hosts_acquire
=$
(uci_get_state network
$1 dns
)
820 icmp_hosts_acquire
=$icmp_hosts
823 icmp_hosts
=$
(echo $icmp_hosts_acquire |
sed -e "s/\,/ /g" |
sed -e "s/ /\n/g")
826 echo "$icmp_hosts" |
while read icmp_test_host
; do
827 ping -c "$icmp_count" -W $timeout -I $ifname $icmp_test_host 2>&1 |
grep -o "round-trip"
831 check_test
=$
(ping_test
)
833 if [ -z "$check_test" ]; then
839 elif [ "$icmp_hosts" == "disable" ]; then
843 [ "$health_monitor" = 'serial' ] && {
844 wan_monitor_map
=$
(echo $wan_monitor_map |
sed -e "s/$1\[\w*\]/$1\[$(date +%s)\]/g")
851 # Add a task to the $jobfile while ensuring
852 # no duplicate tasks for the specified group
856 grep -o "$group.$task" $jobfile >&- 2>&- ||
echo "$group.$task" >> $jobfile
859 # For health_monitor "parallel", start a background monitor for each group.
860 # For health_monitor "serial", queue monitor tasks for do_tasks.
862 local group health_interval monitored_last_at current_time
diff delay
865 get_health_interval
() {
866 group
=$
(query_config group
$1)
867 health_interval
=$
(uci_get_state multiwan
${group} health_interval
'disable')
868 [ "$health_interval" = "disable" ] && health_interval
=0
871 [ "$health_monitor" = 'parallel' ] && {
872 while [ $
((i
++)) -lt $wancount ]; do
873 get_health_interval
$i
874 if [ "$health_interval" -gt 0 ]; then
879 echo "## Started background monitor_wan ##"
880 health_monitor
="parallel.started"
883 [ "$health_monitor" = 'serial' ] && {
884 local monitor_disabled
=1
886 until [ -f $jobfile ]; do
887 current_time
=$
(date +%s
)
891 while [ $
((i
++)) -lt $wancount ]; do
892 get_health_interval
$i
893 if [ "$health_interval" -gt 0 ]; then
896 monitored_last
=$
(query_config monitor
$group)
897 [ -z "$monitored_last" ] && {
898 monitored_last
=$current_time
899 wan_monitor_map
="${wan_monitor_map}${group}[$monitored_last]"
903 will_monitor_at
=$
(($monitored_last + $health_interval))
904 diff=$
(($will_monitor_at - $current_time))
905 [ $diff -le 0 ] && add_task
"$group" 'monitor'
907 delay
=$
(($delay > $diff ?
$diff : $delay))
911 [ "$monitor_disabled" -eq 1 ] && {
912 # Although health monitors are disabled, still
913 # need to check up on iptables rules in do_tasks
914 sleep "$iptables_interval"
917 [ $delay -gt 0 ] && sleep $delay
923 # Process each task in the $jobfile in FIFO order
927 local current_resolv_file
933 if [ "$((++rule_counter))" -eq 5 -o "$health_monitor" = 'serial' ]; then
935 check_iptables
=$
(iptables
-n -L MultiWan
-t mangle |
grep "references" |
awk -F "(" '{print $2}' | cut
-d " " -f 1)
937 if [ -z "$check_iptables" -o "$check_iptables" -lt 4 ]; then
938 mwnote
"Netfilter rules appear to of been altered."
939 /etc
/init.d
/multiwan restart
943 current_resolv_file
=$
(ls -l -e /tmp
/resolv.conf.auto |
awk -F " " '{print $5, $9}')
945 if [ "$last_resolv_update" != "$current_resolv_file" ]; then
952 if [ -f $jobfile ]; then
954 mv $jobfile $jobfile.work
961 pass
) recover_wan
$1;;
964 [ "${health_monitor%.* }" = 'parallel' ] && {
966 echo "## Started background monitor_wan ##"
969 monitor
) monitor_wan
$1;;
970 refresh
) refresh_routes
;;
971 *) echo "## Unknown task command: $2 ##";;
975 queued_task
=$
(echo $LINE |
awk -F "." '{print $1,$2}')
976 execute_task
$queued_task
982 if [ "$health_monitor" = 'serial' ]; then
997 while [ $
((i
++)) -lt $wancount ]; do
998 group
=$
(query_config group
$i)
999 ifname
=$
(query_config ifname
$group)
1000 ipaddr
=$
(query_config ipaddr
$group)
1001 gateway
=$
(query_config gateway
$group)
1003 if [ "$ifname" == "x" -o "$ipaddr" == "x" -o "$gateway" == "x" ]; then
1010 max_interval
=$
(((1<<31) - 1))
1013 config_load "multiwan"
1014 config_get_bool enabled config enabled '1'
1015 [ "$enabled" -gt 0 ] || exit
1016 config_get default_route config default_route
1017 config_get health_monitor config health_monitor
1018 config_get iptables_interval config iptables_interval '30'
1019 config_get debug config debug
1021 [ "$health_monitor" = 'serial' ] || health_monitor='parallel'
1023 config_foreach acquire_wan_data interface
1027 CHKFORQOS=$(iptables -n -L Default -t mangle 2>&1 | grep "Chain Default")
1028 CHKFORMODULE=$(iptables -m statistic 2>&1 | grep -o "File not found")
1030 jobfile="/tmp/.mwan/jobqueue"
1033 agent) silencer main_init;;
1034 stop) silencer stop;;
1035 restart) silencer stop restart;;
1036 single) silencer stop single;;