4 .
/lib
/functions
/network.sh
7 if [ -z "$debug" -o "$debug" == "0" ]; then
15 logger
${debug:+-s} -p 5 -t multiwan
"$1"
19 local failchk
=$
(query_config failchk
$2)
20 local recvrychk
=$
(query_config recvrychk
$2)
22 local wanid
=$
(query_config wanid
$2)
23 local failover_to
=$
(uci_get_state multiwan
${2} failover_to
)
24 local failover_to_wanid
=$
(query_config wanid
$failover_to)
26 local existing_failover
=$
(iptables
-n -L FW
${wanid}MARK
-t mangle |
echo $
(($
(wc -l) - 2)))
30 wan_fail_map
=$
(echo $wan_fail_map |
sed -e "s/${1}\[${failchk}\]//g")
31 wan_fail_map
="$wan_fail_map${1}[x]"
32 wan_recovery_map
=$
(echo $wan_recovery_map |
sed -e "s/${1}\[${recvrychk}\]//g")
35 if [ "$existing_failover" == "2" ]; then
36 if [ "$failover_to" != "balancer" -a "$failover_to" != "fastbalancer" -a "$failover_to" != "disable" -a "$failover_to_wanid" != "$wanid" ]; then
37 iptables
-I FW
${wanid}MARK
2 -t mangle
-j FW
${failover_to_wanid}MARK
38 elif [ "$failover_to" == "balancer" ]; then
39 iptables
-I FW
${wanid}MARK
2 -t mangle
-j LoadBalancer
40 elif [ "$failover_to" == "fastbalancer" ]; then
41 iptables
-I FW
${wanid}MARK
2 -t mangle
-j FastBalancer
44 mwnote
"$1 has failed and is currently offline."
49 wan_recovery_map
=$
(echo $wan_recovery_map |
sed -e "s/${1}\[${recvrychk}\]//g")
50 wan_fail_map
=$
(echo $wan_fail_map |
sed -e "s/${1}\[${failchk}\]//g")
53 if [ "$existing_failover" == "3" ]; then
54 iptables
-D FW
${wanid}MARK
2 -t mangle
56 mwnote
"$1 has recovered and is back online!"
68 local health_fail_retries
=$
(uci_get_state multiwan
${1} health_fail_retries
)
69 local weight
=$
(uci_get_state multiwan
${1} weight
)
71 local failchk
=$
(query_config failchk
$1)
72 local recvrychk
=$
(query_config recvrychk
$1)
73 wan_recovery_map
=$
(echo $wan_recovery_map |
sed -e "s/${1}\[${recvrychk}\]//g")
75 if [ -z "$failchk" ]; then
77 wan_fail_map
="$wan_fail_map${1}[1]"
80 if [ "$failchk" != "x" ]; then
81 new_fail_count
=$
(($failchk + 1))
82 if [ "$new_fail_count" -lt "$health_fail_retries" ]; then
83 wan_fail_map
=$
(echo $wan_fail_map |
sed -e "s/${1}\[${failchk}\]/$1\[${new_fail_count}\]/g")
87 if [ "$weight" != "disable" ]; then
98 local health_recovery_retries
=$
(uci_get_state multiwan
${1} health_recovery_retries
)
99 local weight
=$
(uci_get_state multiwan
${1} weight
)
101 local failchk
=$
(query_config failchk
$1)
102 local recvrychk
=$
(query_config recvrychk
$1)
103 local wanid
=$
(query_config wanid
$1)
105 if [ ! -z "$failchk" -a "$failchk" != "x" ]; then
106 wan_fail_map
=$
(echo $wan_fail_map |
sed -e "s/${1}\[${failchk}\]//g")
110 if [ "$failchk" == "x" ]; then
111 if [ -z "$recvrychk" ]; then
112 wan_recovery_map
="$wan_recovery_map${1}[1]"
114 if [ "$health_recovery_retries" == "1" ]; then
118 new_recovery_count
=$
(($recvrychk + 1))
119 if [ "$new_recovery_count" -lt "$health_recovery_retries" ]; then
120 wan_recovery_map
=$
(echo $wan_recovery_map |
sed -e "s/${1}\[${recvrychk}\]/$1\[${new_recovery_count}\]/g")
125 if [ "$weight" != "disable" ]; then
140 local ifname ipaddr gateway
141 network_get_device ifname
${1} || ifname
=x
142 network_get_ipaddr ipaddr
${1} || ipaddr
=x
143 network_get_gateway gateway
${1} || gateway
=x
145 check_old_map
=$
(echo $wan_id_map 2>&1 |
grep -o "$1\[")
147 if [ -z $check_old_map ]; then
148 wancount
=$
(($wancount + 1))
149 if [ $wancount -gt 20 ]; then
153 wan_if_map
="$wan_if_map${1}[${ifname}]"
154 wan_id_map
="$wan_id_map${1}[${wancount}]"
155 wan_gw_map
="$wan_gw_map${1}[${gateway}]"
156 wan_ip_map
="$wan_ip_map${1}[${ipaddr}]"
158 old_ipaddr
=$
(query_config ipaddr
$1)
159 old_gateway
=$
(query_config gateway
$1)
160 old_ifname
=$
(query_config ifname
$1)
161 get_wanid
=$
(query_config wanid
$1)
163 wan_if_map
=$
(echo $wan_if_map |
sed -e "s/${1}\[${old_ifname}\]/$1\[${ifname}\]/g")
164 wan_ip_map
=$
(echo $wan_ip_map |
sed -e "s/${1}\[${old_ipaddr}\]/$1\[${ipaddr}\]/g")
165 wan_gw_map
=$
(echo $wan_gw_map |
sed -e "s/${1}\[${old_gateway}\]/$1\[${gateway}\]/g")
167 if [ "$old_ifname" != "$ifname" ]; then
168 iptables
-D MultiWanPreHandler
-t mangle
-i $old_$ifname -m state
--state NEW
-j FW
${get_wanid}MARK
169 iptables
-A MultiWanPreHandler
-t mangle
-i $ifname -m state
--state NEW
-j FW
${get_wanid}MARK
170 iptables
-D MultiWanPostHandler
-t mangle
-o $old_$ifname -m mark
--mark 0x1 -j FW
${get_wanid}MARK
171 iptables
-A MultiWanPostHandler
-t mangle
-o $ifname -m mark
--mark 0x1 -j FW
${get_wanid}MARK
174 if [ "$ifname" != "x" -a "$ipaddr" != "x" -a "$gateway" != "x" ]; then
176 iprules_config
$get_wanid
189 if [ ! -d /tmp
/.mwan
]; then
190 mkdir
/tmp
/.mwan
> /dev
/null
2>&1
193 rm /tmp
/.mwan
/cache
> /dev
/null
2>&1
194 touch /tmp
/.mwan
/cache
196 echo "# Automatically Generated by Multi-WAN Agent Script. Do not modify or remove. #" > /tmp
/.mwan
/cache
197 echo "wan_id_map=\"$wan_id_map\"" >> /tmp
/.mwan
/cache
198 echo "wan_if_map=\"$wan_if_map\"" >> /tmp
/.mwan
/cache
199 echo "wan_ip_map=\"$wan_ip_map\"" >> /tmp
/.mwan
/cache
200 echo "wan_gw_map=\"$wan_gw_map\"" >> /tmp
/.mwan
/cache
201 echo "wan_fail_map=\"$wan_fail_map\"" >> /tmp
/.mwan
/cache
202 echo "wan_recovery_map=\"$wan_recovery_map\"" >> /tmp
/.mwan
/cache
203 echo "wan_monitor_map=\"$wan_monitor_map\"" >> /tmp
/.mwan
/cache
208 ifname
) echo $wan_if_map |
grep -o "$2\[\w*.*\]" |
awk -F "[" '{print $2}' |
awk -F "]" '{print $1}';;
209 ipaddr
) echo $wan_ip_map |
grep -o "$2\[\w*.*\]" |
awk -F "[" '{print $2}' |
awk -F "]" '{print $1}';;
210 gateway
) echo $wan_gw_map |
grep -o "$2\[\w*.*\]" |
awk -F "[" '{print $2}' |
awk -F "]" '{print $1}';;
211 wanid
) echo $wan_id_map |
grep -o "$2\[\w*.*\]" |
awk -F "[" '{print $2}' |
awk -F "]" '{print $1}';;
212 failchk
) echo $wan_fail_map |
grep -o "$2\[\w*.*\]" |
awk -F "[" '{print $2}' |
awk -F "]" '{print $1}';;
213 recvrychk
) echo $wan_recovery_map |
grep -o "$2\[\w*.*\]" |
awk -F "[" '{print $2}' |
awk -F "]" '{print $1}';;
214 monitor
) echo $wan_monitor_map |
grep -o "$2\[\w*.*\]" |
awk -F "[" '{print $2}' |
awk -F "]" '{print $1}';;
215 group
) echo $wan_id_map |
grep -o "\w*\[$2\]" |
awk -F "[" '{print $1}';;
220 local otherpids
=$
(ps
2>&1 |
grep 'multiwan agent' |
grep -v $$ |
awk '{print $1}')
221 [ -n "$otherpids" ] && kill $otherpids > /dev
/null
2>&1
225 # For system shutdownl: stop
226 # A plain stop will leave network in a limp state, without wan access
227 # stop single: restore to a single wan
228 # stop restart: restart multiple wan's
233 if [ "$1" == "single" ]; then
234 # ifup is quite expensive--do it only when single wan is requested
235 echo "## Refreshing Interfaces ##"
237 while [ $
((i
++)) -lt $wancount ]; do
238 local group
=$
(query_config group
$i)
239 ifup
$group >&- 2>&- && sleep 1
242 echo "## Unloaded, updating syslog and exiting. ##"
243 mwnote
"Succesfully Unloaded on $(exec date -R)."
244 rm -fr /tmp
/.mwan
>&- 2>&-
248 if [ "$1" == "restart" ]; then
249 echo "## Restarting Multi-WAN. ##"
250 mwnote
"Reinitializing Multi-WAN Configuration."
251 rm -fr /tmp
/.mwan
>&- 2>&-
252 /etc
/init.d
/multiwan start
>&- 2>&-
259 local restore_single
=$1
262 iptables
-t mangle
-D PREROUTING
-j MultiWan
263 iptables
-t mangle
-D FORWARD
-j MultiWan
264 iptables
-t mangle
-D OUTPUT
-j MultiWan
265 iptables
-t mangle
-D POSTROUTING
-j MultiWan
266 iptables
-t mangle
-F MultiWan
267 iptables
-t mangle
-X MultiWan
268 iptables
-t mangle
-F MultiWanRules
269 iptables
-t mangle
-X MultiWanRules
270 iptables
-t mangle
-F MultiWanDNS
271 iptables
-t mangle
-X MultiWanDNS
272 iptables
-t mangle
-F MultiWanPreHandler
273 iptables
-t mangle
-X MultiWanPreHandler
274 iptables
-t mangle
-F MultiWanPostHandler
275 iptables
-t mangle
-X MultiWanPostHandler
276 iptables
-t mangle
-F LoadBalancer
277 iptables
-t mangle
-X LoadBalancer
278 iptables
-t mangle
-F FastBalancer
279 iptables
-t mangle
-X FastBalancer
280 iptables
-t mangle
-F MultiWanLoadBalancer
281 iptables
-t mangle
-X MultiWanLoadBalancer
284 while [ $
((i
++)) -lt $wancount ]; do
285 iptables
-t mangle
-F FW
${i}MARK
286 iptables
-t mangle
-X FW
${i}MARK
289 if [ ! -z "$CHKFORQOS" ]; then
290 iptables
-t mangle
-F PREROUTING
291 iptables
-t mangle
-F FORWARD
292 iptables
-t mangle
-F OUTPUT
293 iptables
-t mangle
-F POSTROUTING
294 iptables
-t mangle
-F MultiWanQoS
295 iptables
-t mangle
-X MultiWanQoS
298 while [ $
((i
++)) -lt $wancount ]; do
299 group
=$
(query_config group
$i)
300 iptables
-t mangle
-F qos_
${group}
301 iptables
-t mangle
-F qos_
${group}_ct
302 iptables
-t mangle
-X qos_
${group}
303 iptables
-t mangle
-X qos_
${group}_ct
307 [ "$restore_single" == 'single' ] &&
308 /etc
/init.d
/qos restart
> /dev
/null
2>&1
315 local get_wan_iptables
316 local add_qos_iptables
322 ifname
=$
(query_config ifname
$1)
324 if [ "$ifname" == "x" ]; then
328 qos_if_test
=$
(echo $qos_if_done |
grep $ifname.
)
330 if [ ! -z "$qos_if_test" ]; then
334 qos_if_done
=$
(echo ${qos_if_done}.
${ifname})
336 queue_count
=$
(tc filter list dev
$ifname |
tail -n 1 |
awk -F " " '{print $10}' |
sed "s/0x//g")
338 if [ -z "$queue_count" ]; then
342 queue_count
=$
(($queue_count + 1))
344 iptables
-t mangle
-N qos_
${1}
345 iptables
-t mangle
-N qos_
${1}_ct
347 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")
348 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")
352 while [ $i -lt $queue_count ]; do
353 echo "s/\(0x$i \|0x$i\/0xffffffff\)/0x$(($2 * 10 + $i)) /g" >> /tmp
/.mwan
/qos.
$1.sedfilter
357 add_qos_iptables
=$
(echo "$get_wan_iptables" |
sed -f /tmp
/.mwan
/qos.
$1.sedfilter
)
358 echo "$add_qos_iptables" |
while read execute
; do ${execute}; done
360 rm /tmp
/.mwan
/qos.
$1.sedfilter
362 while [ $i -lt $queue_count ]; do
363 echo "s/0x$i /0x${2}${i} fw /g" >> /tmp
/.mwan
/qos.
$1.sedfilter
367 add_qos_tc
=$
(echo "$get_wan_tc" |
sed -f /tmp
/.mwan
/qos.
$1.sedfilter
)
368 echo "$add_qos_tc" |
while read execute
; do ${execute}; done
369 rm /tmp
/.mwan
/qos.
$1.sedfilter
372 while [ $i -lt $queue_count ]; do
373 if [ $i -lt $
(($queue_count - 1)) ]; then
374 ip rule add fwmark
0x$
(($2 * 10 + $i + 1)) table $
(($2 + 170)) prio $
(( $2 * 10 + $i + 2))
376 iptables
-t mangle
-A MultiWanQoS
-m mark
--mark 0x$
(($2 * 10 + $i)) -j qos_
${1}
388 config_get src
$1 src
389 config_get dst
$1 dst
390 config_get port_type
$1 port_type
'dports'
391 config_get ports
$1 ports
392 config_get proto
$1 proto
393 config_get wanrule
$1 wanrule
395 if [ -z "$wanrule" ]; then
399 if [ "$wanrule" != "balancer" -a "$wanrule" != "fastbalancer" ]; then
400 wanrule
=$
(query_config wanid
${wanrule})
401 wanrule
="FW${wanrule}MARK"
402 elif [ "$wanrule" == "balancer" ]; then
403 wanrule
="LoadBalancer"
404 elif [ "$wanrule" == "fastbalancer" ]; then
405 wanrule
="FastBalancer"
407 if [ "$dst" == "all" ]; then
410 if [ "$proto" == "all" ]; then
413 if [ "$ports" == "all" ]; then
417 if [ "$proto" == "icmp" ]; then
420 if [ "$src" == "all" ]; then
423 iptables
-t mangle
-A MultiWanRules
${src:+-s $src} ${dst:+-d $dst} \
424 -m mark
--mark 0x0 ${proto:+-p $proto -m $proto} \
425 ${ports:+-m multiport --$port_type $ports} \
428 if [ -z "$proto" -a ! -z "$ports" ]; then
448 iptables
-F MultiWanDNS
-t mangle
450 rm /tmp
/resolv.conf.auto
451 touch /tmp
/resolv.conf.auto
453 echo "## Refreshing DNS Resolution and Tables ##"
456 while [ $
((i
++)) -lt $wancount ]; do
457 group
=$
(query_config group
$i)
458 gateway
=$
(query_config gateway
$group)
459 ipaddr
=$
(query_config ipaddr
$group)
460 ifname
=$
(query_config ifname
$group)
461 failchk
=$
(query_config failchk
$group)
463 dns
=$
(uci_get_state multiwan
${group} dns
'auto')
464 [ "$dns" == "auto" ] && network_get_dnsserver dns
${group}
465 dns
=$
(echo $dns |
sed -e "s/ /\n/g")
467 if [ ! -z "$dns" -a "$failchk" != "x" -a "$ipaddr" != "x" -a "$gateway" != "x" -a "$ifname" != "x" ]; then
468 echo "$dns" |
while read dns_server
; do
469 iptables
-t mangle
-A MultiWanDNS
-d $dns_server -p tcp
--dport 53 -j FW
${i}MARK
470 iptables
-t mangle
-A MultiWanDNS
-d $dns_server -p udp
--dport 53 -j FW
${i}MARK
472 compile_dns
="nameserver $dns_server"
473 echo "$compile_dns" >> /tmp
/resolv.conf.auto
478 last_resolv_update
=$
(ls -l -e /tmp
/resolv.conf.auto |
awk -F " " '{print $5, $9}')
482 echo "## IPTables Rule Initialization ##"
488 local default_route_id
491 if [ ! -z "$CHKFORQOS" ]; then
492 echo "## QoS Initialization ##"
494 /etc
/init.d
/qos restart
> /dev
/null
2>&1
496 IMQ_NFO
=$
(iptables
-n -L PREROUTING
-t mangle
-v |
grep IMQ |
awk -F " " '{print $6,$12}')
498 iptables
-t mangle
-F PREROUTING
499 iptables
-t mangle
-F FORWARD
500 iptables
-t mangle
-F POSTROUTING
501 iptables
-t mangle
-F OUTPUT
503 echo "$IMQ_NFO" |
while read execute
; do
504 iptables
-t mangle
-A PREROUTING
-i $
(echo $execute |
awk -F " " '{print $1}') -j IMQ
--todev $
(echo $execute |
awk -F " " '{print $2}')
507 iptables
-t mangle
-N MultiWanQoS
510 while [ $
((i
++)) -lt $wancount ]; do
511 qos_init $
(query_config group
$i) $i
516 iptables
-t mangle
-N MultiWan
517 iptables
-t mangle
-N LoadBalancer
518 iptables
-t mangle
-N FastBalancer
519 iptables
-t mangle
-N MultiWanRules
520 iptables
-t mangle
-N MultiWanDNS
521 iptables
-t mangle
-N MultiWanPreHandler
522 iptables
-t mangle
-N MultiWanPostHandler
523 iptables
-t mangle
-N MultiWanLoadBalancer
525 echo "## Creating FW Rules ##"
527 while [ $
((i
++)) -lt $wancount ]; do
529 iptables
-t mangle
-N FW
${i}MARK
530 iptables
-t mangle
-A FW
${i}MARK
-j MARK
--set-mark 0x
${iprule}
531 iptables
-t mangle
-A FW
${i}MARK
-j CONNMARK
--save-mark
534 iptables
-t mangle
-A LoadBalancer
-j MARK
--set-mark 0x1
535 iptables
-t mangle
-A LoadBalancer
-j CONNMARK
--save-mark
537 if [ -z "$CHKFORMODULE" ]; then
538 iptables
-t mangle
-A FastBalancer
-j MARK
--set-mark 0x2
539 iptables
-t mangle
-A FastBalancer
-j CONNMARK
--save-mark
541 mwnote
"Performance load balancer(fastbalanacer) is unavailable due to current kernel limitations."
542 iptables
-t mangle
-A FastBalancer
-j MARK
--set-mark 0x1
543 iptables
-t mangle
-A FastBalancer
-j CONNMARK
--save-mark
546 iptables
-t mangle
-A MultiWan
-j CONNMARK
--restore-mark
547 iptables
-t mangle
-A MultiWan
-j MultiWanPreHandler
548 iptables
-t mangle
-A MultiWan
-j MultiWanRules
549 iptables
-t mangle
-A MultiWan
-j MultiWanLoadBalancer
550 iptables
-t mangle
-A MultiWan
-j MultiWanDNS
551 iptables
-t mangle
-A MultiWan
-j MultiWanPostHandler
553 iptables
-t mangle
-I PREROUTING
-j MultiWan
554 iptables
-t mangle
-I FORWARD
-j MultiWan
555 iptables
-t mangle
-I OUTPUT
-j MultiWan
556 iptables
-t mangle
-I POSTROUTING
-j MultiWan
561 config_load
"multiwan"
562 config_foreach mwanrule mwanfw
564 if [ "$default_route" != "balancer" -a "$default_route" != "fastbalancer" ]; then
565 default_route_id
=$
(query_config wanid
$default_route)
566 iptables
-t mangle
-A MultiWanRules
-m mark
--mark 0x0 -j FW
${default_route_id}MARK
567 elif [ "$default_route" == "fastbalancer" ]; then
568 iptables
-t mangle
-A MultiWanRules
-m mark
--mark 0x0 -j FastBalancer
570 iptables
-t mangle
-A MultiWanRules
-m mark
--mark 0x0 -j LoadBalancer
574 while [ $
((i
++)) -lt $wancount ]; do
575 group
=$
(query_config group
$i)
576 ifname
=$
(query_config ifname
$group)
577 iptables
-t mangle
-A MultiWanPreHandler
-i $ifname -m state
--state NEW
-j FW
${i}MARK
578 iptables
-t mangle
-A MultiWanPostHandler
-o $ifname -m mark
--mark 0x1 -j FW
${i}MARK
581 if [ ! -z "$CHKFORQOS" ]; then
582 iptables
-t mangle
-A MultiWan
-j MultiWanQoS
586 refresh_loadbalancer
() {
593 local pre_nexthop_chk
594 local rand_probability
596 echo "## Refreshing Load Balancer ##"
598 ip rule del prio
9 > /dev
/null
2>&1
599 ip route flush table
170 > /dev
/null
2>&1
602 ip route |
grep -Ev ^default |
while read ROUTE
; do
603 ip route add table
$TABLE to
$ROUTE
607 iptables
-F MultiWanLoadBalancer
-t mangle
612 while [ $
((i
++)) -lt $wancount ]; do
613 group
=$
(query_config group
$i)
614 failchk
=$
(query_config failchk
$group)
615 gateway
=$
(query_config gateway
$group)
616 ifname
=$
(query_config ifname
$group)
617 weight
=$
(uci_get_state multiwan
${group} weight
)
618 if [ "$gateway" != "x" -a "$ifname" != "x" -a "$failchk" != "x" -a "$weight" != "disable" ]; then
619 total_weight
=$
(($total_weight + $weight))
624 while [ $
((i
++)) -lt $wancount ]; do
625 group
=$
(query_config group
$i)
626 failchk
=$
(query_config failchk
$group)
627 gateway
=$
(query_config gateway
$group)
628 ifname
=$
(query_config ifname
$group)
630 weight
=$
(uci_get_state multiwan
${group} weight
)
632 if [ "$gateway" != "x" -a "$ifname" != "x" -a "$failchk" != "x" -a "$weight" != "disable" ]; then
633 nexthop
="$nexthop nexthop via $gateway dev $ifname weight $weight"
635 rand_probability
=$
(($weight * 100 / $total_weight))
636 total_weight
=$
(($total_weight - $weight))
638 if [ $rand_probability -lt 10 ]; then
639 rand_probability
="0.0${rand_probability}"
640 elif [ $rand_probability -lt 100 ]; then
641 rand_probability
="0.${rand_probability}"
643 rand_probability
="1.0"
646 if [ -z "$CHKFORMODULE" ]; then
647 iptables
-A MultiWanLoadBalancer
-t mangle
-m mark
--mark 0x2 -m statistic
--mode random
--probability $rand_probability -j FW
${i}MARK
653 pre_nexthop_chk
=$
(echo $nexthop |
awk -F "nexthop" '{print NF-1}')
654 if [ "$pre_nexthop_chk" == "1" ]; then
655 ip route add default via $
(echo $nexthop |
awk -F " " '{print $3}') dev $
(echo $nexthop |
awk -F " " '{print $5}') proto static table
170
656 elif [ "$pre_nexthop_chk" -gt "1" ]; then
657 ip route add proto static table
170 default scope global
$nexthop
660 ip rule add fwmark
0x1 table
170 prio
9
671 echo "## Refreshing Routing Tables ##"
674 while [ $
((i
++)) -lt $wancount ]; do
675 group
=$
(query_config group
$i)
676 gateway
=$
(query_config gateway
$group)
677 ifname
=$
(query_config ifname
$group)
678 ipaddr
=$
(query_config ipaddr
$group)
679 ip route flush table $
(($i + 170)) > /dev
/null
2>&1
682 ip route |
grep -Ev ^default |
while read ROUTE
; do
683 ip route add table
$TABLE to
$ROUTE
686 if [ "$gateway" != "x" -a "$ipaddr" != "x" -a "$ifname" != "x" ]; then
687 ip route add default via
$gateway table $
(($i + 170)) src
$ipaddr proto static
688 route add default gw
$gateway > /dev
/null
2>&1
701 group
=$
(query_config group
$1)
702 gateway
=$
(query_config gateway
$group)
703 ipaddr
=$
(query_config ipaddr
$group)
705 CHKIPROUTE
=$
(grep MWAN
${1} /etc
/iproute
2/rt_tables
)
706 if [ -z "$CHKIPROUTE" ]; then
707 echo "$(($1 + 170)) MWAN${1}" >> /etc
/iproute
2/rt_tables
710 ip rule del prio $
(($1 * 10)) > /dev
/null
2>&1
711 ip rule del prio $
(($1 * 10 + 1)) > /dev
/null
2>&1
713 if [ "$gateway" != "x" -a "$ipaddr" != "x" ]; then
714 ip rule add from
$ipaddr table $
(($1 + 170)) prio $
(($1 * 10))
715 ip rule add fwmark
0x$
(($1 * 10)) table $
(($1 + 170)) prio $
(($1 * 10 + 1))
720 local restore_single
=$1
721 echo "## Flushing IP Rules & Routes ##"
723 ip rule flush
> /dev
/null
2>&1
724 ip rule add lookup main prio
32766 > /dev
/null
2>&1
725 ip rule add lookup default prio
32767 > /dev
/null
2>&1
727 ip route flush table
170 > /dev
/null
730 while [ $
((i
++)) -lt $wancount ]; do
731 ip route del default
> /dev
/null
2>&1
732 ip route flush table $
(($i + 170)) > /dev
/null
2>&1
735 echo "## Clearing Rules ##"
736 clear_rules
$restore_single > /dev
/null
2>&1
738 rm $jobfile > /dev
/null
2>&1
744 local health_interval
746 echo "## Main Initialization ##"
748 mkdir
/tmp
/.mwan
> /dev
/null
2>&1
753 echo "## IP Rules Initialization ##"
755 CHKIPROUTE
=$
(grep LoadBalancer
/etc
/iproute
2/rt_tables
)
756 if [ -z "$CHKIPROUTE" ]; then
757 echo "#" >> /etc
/iproute
2/rt_tables
758 echo "170 LoadBalancer" >> /etc
/iproute
2/rt_tables
762 while [ $
((i
++)) -lt $wancount ]; do
771 RP_PATH
=/proc
/sys
/net
/ipv
4/conf
772 for IFACE
in $
(ls $RP_PATH); do
773 echo 0 > $RP_PATH/$IFACE/rp_filter
775 mwnote
"Succesfully Initialized on $(date -R)."
785 local ifname ipaddr gateway icmp_hosts_acquire icmp_test_host
790 local timeout
=$
(uci_get_state multiwan
${1} timeout
)
791 local icmp_hosts
=$
(uci_get_state multiwan
${1} icmp_hosts
)
792 local icmp_count
=$
(uci_get_state multiwan
${1} icmp_count
'1')
793 local health_interval
=$
(uci_get_state multiwan
${1} health_interval
)
794 local ifname_cur
=$
(query_config ifname
$1)
795 local ipaddr_cur
=$
(query_config ipaddr
$1)
796 local gateway_cur
=$
(query_config gateway
$1)
799 [ "${health_monitor%.*}" = 'parallel' ] && sleep $health_interval
801 network_get_device ifname
${1} || ifname
=x
802 network_get_ipaddr ipaddr
${1} || ipaddr
=x
803 network_get_gateway gateway
${1} || gateway
=x
805 if [ "$ifname_cur" != "$ifname" -o "$ipaddr_cur" != "$ipaddr" -o "$gateway_cur" != "$gateway" ]; then
806 add_task
"$1" acquire
807 if [ "${health_monitor%.*}" = 'parallel' ]; then
813 [ "$gateway" != "x" ] && ! ip route |
grep -o $gateway >&- 2>&- &&
814 add_task route refresh
817 if [ "$icmp_hosts" != "disable" -a "$ifname" != "x" -a "$ipaddr" != "x" -a "$gateway" != "x" ]; then
819 if [ "$icmp_hosts" == "gateway" -o -z "$icmp_hosts" ]; then
820 icmp_hosts_acquire
=$gateway
821 elif [ "$icmp_hosts" == "dns" ]; then
822 icmp_hosts_acquire
=$
(uci_get_state multiwan
$1 dns
'auto')
823 [ "$icmp_hosts_acquire" == "auto" ] &&
824 network_get_dnsserver icmp_hosts_acquire
$1
826 icmp_hosts_acquire
=$icmp_hosts
829 icmp_hosts
=$
(echo $icmp_hosts_acquire |
sed -e "s/\,/ /g" |
sed -e "s/ /\n/g")
832 echo "$icmp_hosts" |
while read icmp_test_host
; do
833 ping -c "$icmp_count" -W $timeout -I $ifname $icmp_test_host 2>&1 |
grep -o "round-trip"
837 check_test
=$
(ping_test
)
839 if [ -z "$check_test" ]; then
845 elif [ "$icmp_hosts" == "disable" ]; then
849 [ "$health_monitor" = 'serial' ] && {
850 wan_monitor_map
=$
(echo $wan_monitor_map |
sed -e "s/$1\[\w*\]/$1\[$(date +%s)\]/g")
857 # Add a task to the $jobfile while ensuring
858 # no duplicate tasks for the specified group
862 grep -o "$group.$task" $jobfile >&- 2>&- ||
echo "$group.$task" >> $jobfile
865 # For health_monitor "parallel", start a background monitor for each group.
866 # For health_monitor "serial", queue monitor tasks for do_tasks.
868 local group health_interval monitored_last_at current_time
diff delay
871 get_health_interval
() {
872 group
=$
(query_config group
$1)
873 health_interval
=$
(uci_get_state multiwan
${group} health_interval
'disable')
874 [ "$health_interval" = "disable" ] && health_interval
=0
877 [ "$health_monitor" = 'parallel' ] && {
878 while [ $
((i
++)) -lt $wancount ]; do
879 get_health_interval
$i
880 if [ "$health_interval" -gt 0 ]; then
885 echo "## Started background monitor_wan ##"
886 health_monitor
="parallel.started"
889 [ "$health_monitor" = 'serial' ] && {
890 local monitor_disabled
=1
892 until [ -f $jobfile ]; do
893 current_time
=$
(date +%s
)
897 while [ $
((i
++)) -lt $wancount ]; do
898 get_health_interval
$i
899 if [ "$health_interval" -gt 0 ]; then
902 monitored_last
=$
(query_config monitor
$group)
903 [ -z "$monitored_last" ] && {
904 monitored_last
=$current_time
905 wan_monitor_map
="${wan_monitor_map}${group}[$monitored_last]"
909 will_monitor_at
=$
(($monitored_last + $health_interval))
910 diff=$
(($will_monitor_at - $current_time))
911 [ $diff -le 0 ] && add_task
"$group" 'monitor'
913 delay
=$
(($delay > $diff ?
$diff : $delay))
917 [ "$monitor_disabled" -eq 1 ] && {
918 # Although health monitors are disabled, still
919 # need to check up on iptables rules in do_tasks
920 sleep "$iptables_interval"
923 [ $delay -gt 0 ] && sleep $delay
929 # Process each task in the $jobfile in FIFO order
933 local current_resolv_file
939 if [ "$((++rule_counter))" -eq 5 -o "$health_monitor" = 'serial' ]; then
941 check_iptables
=$
(iptables
-n -L MultiWan
-t mangle |
grep "references" |
awk -F "(" '{print $2}' | cut
-d " " -f 1)
943 if [ -z "$check_iptables" -o "$check_iptables" -lt 4 ]; then
944 mwnote
"Netfilter rules appear to of been altered."
945 /etc
/init.d
/multiwan restart
949 current_resolv_file
=$
(ls -l -e /tmp
/resolv.conf.auto |
awk -F " " '{print $5, $9}')
951 if [ "$last_resolv_update" != "$current_resolv_file" ]; then
958 if [ -f $jobfile ]; then
960 mv $jobfile $jobfile.work
967 pass
) recover_wan
$1;;
970 [ "${health_monitor%.*}" = 'parallel' ] && {
972 echo "## Started background monitor_wan ##"
975 monitor
) monitor_wan
$1;;
976 refresh
) refresh_routes
;;
977 *) echo "## Unknown task command: $2 ##";;
981 queued_task
=$
(echo $LINE |
awk -F "." '{print $1,$2}')
982 execute_task
$queued_task
988 if [ "$health_monitor" = 'serial' ]; then
1003 while [ $
((i
++)) -lt $wancount ]; do
1004 group
=$
(query_config group
$i)
1005 ifname
=$
(query_config ifname
$group)
1006 ipaddr
=$
(query_config ipaddr
$group)
1007 gateway
=$
(query_config gateway
$group)
1009 if [ "$ifname" == "x" -o "$ipaddr" == "x" -o "$gateway" == "x" ]; then
1016 max_interval
=$
(((1<<31) - 1))
1018 config_load "multiwan"
1019 config_get_bool enabled config enabled '1'
1020 [ "$enabled" -gt 0 ] || exit
1021 config_get default_route config default_route
1022 config_get health_monitor config health_monitor
1023 config_get iptables_interval config iptables_interval '30'
1024 config_get debug config debug
1026 [ "$health_monitor" = 'serial' ] || health_monitor='parallel'
1028 config_foreach acquire_wan_data interface
1032 CHKFORQOS=$(iptables -n -L Default -t mangle 2>&1 | grep "Chain Default")
1033 CHKFORMODULE=$(iptables -m statistic 2>&1 | grep -o "File not found")
1035 jobfile="/tmp/.mwan/jobqueue"
1038 agent) silencer main_init;;
1039 stop) silencer stop;;
1040 restart) silencer stop restart;;
1041 single) silencer stop single;;