[packages] multiwan: Reverted back from using LAN as default route in main routing...
[openwrt/svn-archive/archive.git] / net / multiwan / files / usr / bin / multiwan
1 #!/bin/sh
2
3 . /etc/functions.sh
4
5 silencer() {
6 if [ -z "$debug" -o "$debug" == "0" ]; then
7 $* > /dev/null 2>&1
8 else
9 $*
10 fi
11 }
12
13 mwnote() {
14 logger "[Multi-WAN Notice]: $1"
15 }
16
17 failover() {
18 local failover_to
19 local failover_to_wanid
20 local failchk
21 local recovrychk
22 local wanid
23 local existing_failover
24
25 failchk=$(query_config failchk $2)
26 recvrychk=$(query_config recvrychk $2)
27
28 wanid=$(query_config wanid $2)
29 failover_to=`uci -q -P /var/state get multiwan.${2}.failover_to`
30 failover_to_wanid=$(query_config wanid $failover_to)
31
32 existing_failover=$(iptables -n -L FW${wanid}MARK -t mangle | echo $(expr $(wc -l) - 2))
33
34 add() {
35
36 wan_fail_map=$(echo $wan_fail_map | sed -e "s/${1}\[${failchk}\]//g")
37 wan_fail_map=$(echo $wan_fail_map${1}[x])
38 wan_recovery_map=$(echo $wan_recovery_map | sed -e "s/${1}\[${recvrychk}\]//g")
39 update_cache
40
41 if [ "$existing_failover" == "2" ]; then
42 if [ "$failover_to" != "balancer" -a "$failover_to" != "fastbalancer" -a "$failover_to" != "disable" -a "$failover_to_wanid" != "$wanid" ]; then
43 iptables -I FW${wanid}MARK 2 -t mangle -j FW${failover_to_wanid}MARK
44 elif [ "$failover_to" == "balancer" ]; then
45 iptables -I FW${wanid}MARK 2 -t mangle -j LoadBalancer
46 elif [ "$failover_to" == "fastbalancer" ]; then
47 iptables -I FW${wanid}MARK 2 -t mangle -j FastBalancer
48 fi
49 fi
50 mwnote "$1 has failed and is currently offline."
51 }
52
53 del() {
54
55 wan_recovery_map=$(echo $wan_recovery_map | sed -e "s/${1}\[${recvrychk}\]//g")
56 wan_fail_map=$(echo $wan_fail_map | sed -e "s/${1}\[${failchk}\]//g")
57 update_cache
58
59 if [ "$existing_failover" == "3" ]; then
60 iptables -D FW${wanid}MARK 2 -t mangle
61 fi
62 mwnote "$1 has recovered and is back online!"
63 }
64
65 case $1 in
66 add) add $2;;
67 del) del $2;;
68 esac
69 }
70
71 fail_wan() {
72 local failchk
73 local recvrychk
74 local new_fail_count
75 local health_fail_retries
76 local weight
77
78 health_fail_retries=`uci -q -P /var/state get multiwan.${1}.health_fail_retries`
79 weight=`uci -q -P /var/state get multiwan.${1}.weight`
80
81 failchk=$(query_config failchk $1)
82 recvrychk=$(query_config recvrychk $1)
83 wan_recovery_map=$(echo $wan_recovery_map | sed -e "s/${1}\[${recvrychk}\]//g")
84
85 if [ -z "$failchk" ]; then
86 wan_fail_map="$wan_fail_map${1}[1]"
87 update_cache
88 if [ "$health_fail_retries" == "1" ]; then
89 fail_wan $1
90 fi
91 else
92 if [ "$failchk" != "x" ]; then
93 new_fail_count=$(expr $failchk + 1)
94 if [ "$new_fail_count" -lt "$health_fail_retries" ]; then
95 wan_fail_map=$(echo $wan_fail_map | sed -e "s/${1}\[${failchk}\]/$1\[${new_fail_count}\]/g")
96 update_cache
97 else
98 failover add $1
99 refresh_dns
100 if [ "$weight" != "disable" ]; then
101 refresh_loadbalancer
102 fi
103 fi
104
105 fi
106 fi
107
108
109 }
110
111 recover_wan() {
112 local failchk
113 local recvrychk
114 local new_fail_count
115 local wanid
116 local health_recovery_retires
117 local weight
118
119 health_recovery_retries=`uci -q -P /var/state get multiwan.${1}.health_recovery_retries`
120 weight=`uci -q -P /var/state get multiwan.${1}.weight`
121
122 failchk=$(query_config failchk $1)
123 recvrychk=$(query_config recvrychk $1)
124 wanid=$(query_config wanid $1)
125
126 if [ ! -z "$failchk" -a "$failchk" != "x" ]; then
127 wan_fail_map=$(echo $wan_fail_map | sed -e "s/${1}\[${failchk}\]//g")
128 update_cache
129 fi
130
131 if [ "$failchk" == "x" ]; then
132 if [ -z "$recvrychk" ]; then
133 wan_recovery_map="$wan_recovery_map${1}[1]"
134 update_cache
135 if [ "$health_recovery_retries" == "1" ]; then
136 recover_wan $1
137 fi
138 else
139 new_recovery_count=$(expr $recvrychk + 1)
140 if [ "$new_recovery_count" -lt "$health_recovery_retries" ]; then
141 wan_recovery_map=$(echo $wan_recovery_map | sed -e "s/${1}\[${recvrychk}\]/$1\[${new_recovery_count}\]/g")
142 update_cache
143 else
144 failover del $1
145 refresh_dns
146 if [ "$weight" != "disable" ]; then
147 refresh_loadbalancer
148 fi
149 fi
150 fi
151 fi
152 }
153
154 acquire_wan_data() {
155 local ipaddr
156 local gateway
157 local ifname
158 local check_old_map
159 local get_wanid
160 local old_ifname
161 local old_ipaddr
162 local old_gateway
163
164 ifname=`uci -q -P /var/state get network.${1}.ifname`
165 ipaddr=`uci -q -P /var/state get network.${1}.ipaddr`
166 gateway=`uci -q -P /var/state get network.${1}.gateway`
167
168 if [ -z "$ifname" ]; then
169 ifname="x"
170 fi
171 if [ -z "$ipaddr" ]; then
172 ipaddr="x"
173 fi
174 if [ -z "$gateway" ]; then
175 gateway="x"
176 fi
177
178 check_old_map=`echo $wan_id_map 2>&1 | grep -o "$1\["`
179
180 if [ -z $check_old_map ]; then
181 wancount=`expr $wancount + 1`
182 if [ $wancount -gt 20 ]; then
183 wancount=20
184 return
185 fi
186 wan_if_map="$wan_if_map${1}[${ifname}]"
187 wan_id_map="$wan_id_map${1}[${wancount}]"
188 wan_gw_map="$wan_gw_map${1}[${gateway}]"
189 wan_ip_map="$wan_ip_map${1}[${ipaddr}]"
190 else
191 old_ipaddr=$(query_config ipaddr $1)
192 old_gateway=$(query_config gateway $1)
193 old_ifname=$(query_config ifname $1)
194 get_wanid=$(query_config wanid $1)
195
196 wan_if_map=$(echo $wan_if_map | sed -e "s/${1}\[${old_ifname}\]/$1\[${ifname}\]/g")
197 wan_ip_map=$(echo $wan_ip_map | sed -e "s/${1}\[${old_ipaddr}\]/$1\[${ipaddr}\]/g")
198 wan_gw_map=$(echo $wan_gw_map | sed -e "s/${1}\[${old_gateway}\]/$1\[${gateway}\]/g")
199
200 if [ "$old_ifname" != "$ifname" ]; then
201 iptables -D MultiWanPreHandler -t mangle -i $old_$ifname -m state --state NEW -j FW${get_wanid}MARK
202 iptables -A MultiWanPreHandler -t mangle -i $ifname -m state --state NEW -j FW${get_wanid}MARK
203 iptables -D MultiWanPostHandler -t mangle -o $old_$ifname -m mark --mark 0x1 -j FW${get_wanid}MARK
204 iptables -A MultiWanPostHandler -t mangle -o $ifname -m mark --mark 0x1 -j FW${get_wanid}MARK
205 fi
206
207 if [ "$ifname" != "x" -a "$ipaddr" != "x" -a "$gateway" != "x" ]; then
208 failover del $1
209 iprules_config $get_wanid
210 else
211 failover add $1
212 fi
213
214 refresh_routes
215 refresh_loadbalancer
216 refresh_dns
217 update_cache
218 fi
219 }
220
221 update_cache() {
222
223 if [ ! -d /tmp/.mwan ]; then
224 mkdir /tmp/.mwan > /dev/null 2>&1
225 fi
226
227 rm /tmp/.mwan/cache > /dev/null 2>&1
228 touch /tmp/.mwan/cache
229
230 echo "# Automatically Generated by Multi-WAN Agent Script. Do not modify or remove. #" > /tmp/.mwan/cache
231 echo "wan_id_map=\"$wan_id_map\"" >> /tmp/.mwan/cache
232 echo "wan_if_map=\"$wan_if_map\"" >> /tmp/.mwan/cache
233 echo "wan_ip_map=\"$wan_ip_map\"" >> /tmp/.mwan/cache
234 echo "wan_gw_map=\"$wan_gw_map\"" >> /tmp/.mwan/cache
235 echo "wan_fail_map=\"$wan_fail_map\"" >> /tmp/.mwan/cache
236 echo "wan_recovery_map=\"$wan_recovery_map\"" >> /tmp/.mwan/cache
237 }
238
239 query_config() {
240
241 case $1 in
242 update) update_cache_data;;
243 ifname) echo $wan_if_map | grep -o "$2\[\w*.*\]" | awk -F "[" '{print $2}' | awk -F "]" '{print $1}';;
244 ipaddr) echo $wan_ip_map | grep -o "$2\[\w*.*\]" | awk -F "[" '{print $2}' | awk -F "]" '{print $1}';;
245 gateway) echo $wan_gw_map | grep -o "$2\[\w*.*\]" | awk -F "[" '{print $2}' | awk -F "]" '{print $1}';;
246 wanid) echo $wan_id_map | grep -o "$2\[\w*.*\]" | awk -F "[" '{print $2}' | awk -F "]" '{print $1}';;
247 failchk) echo $wan_fail_map | grep -o "$2\[\w*.*\]" | awk -F "[" '{print $2}' | awk -F "]" '{print $1}';;
248 recvrychk) echo $wan_recovery_map | grep -o "$2\[\w*.*\]" | awk -F "[" '{print $2}' | awk -F "]" '{print $1}';;
249 group) echo $wan_id_map | grep -o "\w*\[$2\]" | awk -F "[" '{print $1}';;
250 esac
251 }
252
253 mwan_kill() {
254 local otherpids
255 local execute
256 otherpids=$(ps -a 2>&1 | grep 'multiwan agent' | grep -v $$ | awk -F " " '{print $1}')
257 echo "$otherpids" | while read execute
258 do
259 kill -9 ${execute} > /dev/null 2>&1
260 done
261 }
262
263 stop() {
264 local group
265 local i
266
267 mwan_kill
268 flush
269
270 if [ "$1" != "restart" ]; then
271 echo "## Refreshing Interfaces ##"
272 i=0
273 while [ $i -lt $wancount ]; do
274 i=`expr $i + 1`
275 group=$(query_config group $i)
276 fdown $group > /dev/null 2>&1
277 ifup $group > /dev/null 2>&1 &
278 done
279
280 echo "## Unloaded, updating syslog and exiting. ##"
281 mwnote "Succesfully Unloaded on $(exec date -R)."
282 ip route flush cache
283 rm -r /tmp/.mwan > /dev/null 2>&1
284
285 else
286
287 echo "## Restarting Multi-WAN. ##"
288 mwnote "Reinitializing Multi-WAN Configuration."
289 ip route flush cache
290 rm -r /tmp/.mwan > /dev/null 2>&1
291 /etc/init.d/multiwan start & > /dev/null 2>&1
292 fi
293
294 exit
295 }
296
297 clear_rules() {
298 local group
299 local i
300
301 iptables -t mangle -F PREROUTING
302 iptables -t mangle -F FORWARD
303 iptables -t mangle -F POSTROUTING
304 iptables -t mangle -F OUTPUT
305 iptables -t mangle -F MultiWan
306 iptables -t mangle -X MultiWan
307 iptables -t mangle -F MultiWanRules
308 iptables -t mangle -X MultiWanRules
309 iptables -t mangle -F MultiWanDNS
310 iptables -t mangle -X MultiWanDNS
311 iptables -t mangle -F MultiWanPreHandler
312 iptables -t mangle -X MultiWanPreHandler
313 iptables -t mangle -F MultiWanPostHandler
314 iptables -t mangle -X MultiWanPostHandler
315 iptables -t mangle -F LoadBalancer
316 iptables -t mangle -X LoadBalancer
317 iptables -t mangle -F FastBalancer
318 iptables -t mangle -X FastBalancer
319
320 i=0
321 while [ $i -lt $wancount ]; do
322 i=`expr $i + 1`
323 iptables -t mangle -F FW${i}MARK
324 done
325
326 i=0
327 while [ $i -lt $wancount ]; do
328 i=`expr $i + 1`
329 iptables -t mangle -X FW${i}MARK
330 done
331
332 if [ ! -z "$CHKFORQOS" ]; then
333
334 iptables -t mangle -F MultiWanQoS
335 iptables -t mangle -X MultiWanQoS
336
337 i=0
338 while [ $i -lt $wancount ]; do
339 i=`expr $i + 1`
340 group=$(query_config group $i)
341 iptables -t mangle -F qos_${group}
342 iptables -t mangle -F qos_${group}_ct
343 iptables -t mangle -X qos_${group}
344 iptables -t mangle -X qos_${group}_ct
345 done
346
347 fi
348 }
349
350 qos_init() {
351 local ifname
352 local queue_count
353 local get_wan_tc
354 local get_wan_iptables
355 local add_qos_iptables
356 local add_qos_tc
357 local execute
358 local iprule
359 local qos_if_test
360 local i
361 local p
362
363 ifname=$(query_config ifname $1)
364
365 if [ "$ifname" == "x" ]; then
366 return
367 fi
368
369 qos_if_test=$(echo $qos_if_done | grep $ifname.)
370
371 if [ ! -z "$qos_if_test" ]; then
372 return
373 fi
374
375 qos_if_done=$(echo ${qos_if_done}.${ifname})
376
377 queue_count=$(tc filter list dev $ifname | tail -n 1 | awk -F " " '{print $10}' | sed "s/0x//g")
378
379 if [ -z "$queue_count" ]; then
380 return
381 fi
382
383 queue_count=`expr $queue_count + 1`
384
385 iptables -t mangle -N qos_${1}
386 iptables -t mangle -N qos_${1}_ct
387
388 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")
389 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")
390
391
392 i=0
393 while [ $i -lt $queue_count ]; do
394 echo "s/\(0x$i \|0x$i\/0xffffffff\)/0x$(expr $2 \* 10 + $i) /g" >> /tmp/.mwan/qos.$1.sedfilter
395 i=`expr $i + 1`
396 done
397
398 add_qos_iptables=$(echo "$get_wan_iptables" | sed -f /tmp/.mwan/qos.$1.sedfilter)
399 echo "$add_qos_iptables" | while read execute; do ${execute}; done
400
401 rm /tmp/.mwan/qos.$1.sedfilter
402 i=1
403 while [ $i -lt $queue_count ]; do
404 echo "s/0x$i /0x${2}${i} fw /g" >> /tmp/.mwan/qos.$1.sedfilter
405 i=`expr $i + 1`
406 done
407
408 add_qos_tc=$(echo "$get_wan_tc" | sed -f /tmp/.mwan/qos.$1.sedfilter)
409 echo "$add_qos_tc" | while read execute; do ${execute}; done
410 rm /tmp/.mwan/qos.$1.sedfilter
411
412 i=0
413 while [ $i -lt $queue_count ]; do
414 if [ $i -lt $(expr $queue_count - 1) ]; then
415 ip rule add fwmark 0x$(expr $2 \* 10 + $i + 1) table $(expr $2 + 170) prio $(expr $2 \* 10 + $i + 2)
416 fi
417 iptables -t mangle -A MultiWanQoS -m mark --mark 0x$(expr $2 \* 10 + $i) -j qos_${1}
418 i=`expr $i + 1`
419 done
420 }
421
422 mwanrule() {
423 local src
424 local dst
425 local ports
426 local proto
427 local wanrule
428
429 config_get src $1 src
430 config_get dst $1 dst
431 config_get ports $1 ports
432 config_get proto $1 proto
433 config_get wanrule $1 wanrule
434 ports_first=${ports%-*}
435 ports_last=${ports#*-}
436
437 if [ -z "$wanrule" ]; then
438 return
439 fi
440
441 if [ "$wanrule" != "balancer" -a "$wanrule" != "fastbalancer" ]; then
442 wanrule=$(query_config wanid ${wanrule})
443 wanrule="FW${wanrule}MARK"
444 elif [ "$wanrule" == "balancer" ]; then
445 wanrule="LoadBalancer"
446 elif [ "$wanrule" == "fastbalancer" ]; then
447 wanrule="FastBalancer"
448 fi
449 if [ "$dst" == "all" ]; then
450 dst=$NULL
451 fi
452 if [ "$proto" == "all" ]; then
453 proto=$NULL
454 fi
455 if [ "$ports" == "all" ]; then
456 ports=$NULL
457 fi
458 if [ "$ports_first" -ne "$ports_last" ]; then
459 ports="$ports_first:$ports_last"
460 fi
461 add_rule() {
462 if [ "$proto" == "icmp" ]; then
463 ports=$NULL
464 fi
465 if [ "$src" == "all" ]; then
466 src=$NULL
467 fi
468 iptables -t mangle -A MultiWanRules -m mark --mark 0x0\
469 ${proto:+-p $proto} \
470 ${src:+-s $src} \
471 ${dst:+-d $dst} \
472 ${ports:+--dport $ports} \
473 -j $wanrule
474 }
475 if [ -z "$proto" -a ! -z "$ports" ]; then
476 proto=tcp
477 add_rule
478 proto=udp
479 add_rule
480 return
481 fi
482 add_rule
483 }
484
485 refresh_dns() {
486 local dns
487 local group
488 local ipaddr
489 local gateway
490 local ifname
491 local failchk
492 local compile_dns
493 local dns_server
494 local i
495
496 iptables -F MultiWanDNS -t mangle
497
498 rm /tmp/resolv.conf.auto
499 touch /tmp/resolv.conf.auto
500
501 echo "## Refreshing DNS Resolution and Tables ##"
502
503 i=0
504 while [ $i -lt $wancount ]; do
505 i=`expr $i + 1`
506 group=$(query_config group $i)
507 gateway=$(query_config gateway $group)
508 ipaddr=$(query_config ipaddr $group)
509 ifname=$(query_config ifname $group)
510 failchk=$(query_config failchk $group)
511
512 dns=`uci -q -P /var/state get multiwan.${group}.dns`
513
514 if [ -z "$dns" -o "$dns" == "auto" ]; then
515 dns=`uci -q -P /var/state get network.${group}.dns`
516 fi
517
518 dns=$(echo $dns | sed -e "s/ /\n/g")
519
520 if [ ! -z "$dns" -a "$failchk" != "x" -a "$ipaddr" != "x" -a "$gateway" != "x" -a "$ifname" != "x" ]; then
521 echo "$dns" | while read dns_server
522 do
523 iptables -t mangle -A MultiWanDNS -d $dns_server -p tcp --dport 53 -j FW${i}MARK
524 iptables -t mangle -A MultiWanDNS -d $dns_server -p udp --dport 53 -j FW${i}MARK
525
526 compile_dns="nameserver $dns_server"
527 echo "$compile_dns" >> /tmp/resolv.conf.auto
528 done
529 fi
530 done
531
532 last_resolv_update=$(ls -l -e /tmp/resolv.conf.auto | awk -F " " '{print $5, $9}')
533 }
534
535 iptables_init() {
536 echo "## IPTables Rule Initialization ##"
537 local iprule
538 local group
539 local ifname
540 local execute
541 local IMQ_NFO
542 local default_route_id
543 local i
544
545 if [ ! -z "$CHKFORQOS" ]; then
546 echo "## QoS Initialization ##"
547
548 /etc/init.d/qos restart > /dev/null 2>&1
549
550 IMQ_NFO=`iptables -n -L PREROUTING -t mangle -v | grep IMQ | awk -F " " '{print $6,$12}'`
551
552 iptables -t mangle -F PREROUTING
553 iptables -t mangle -F FORWARD
554 iptables -t mangle -F POSTROUTING
555 iptables -t mangle -F OUTPUT
556
557 echo "$IMQ_NFO" | while read execute
558 do
559 iptables -t mangle -A PREROUTING -i $(echo $execute | awk -F " " '{print $1}') -j IMQ --todev $(echo $execute | awk -F " " '{print $2}')
560 done
561
562 iptables -t mangle -N MultiWanQoS
563
564 i=0
565 while [ $i -lt $wancount ]; do
566 i=`expr $i + 1`
567 qos_init $(query_config group $i) $i
568 done
569
570 fi
571
572 iptables -t mangle -N MultiWan
573 iptables -t mangle -N LoadBalancer
574 iptables -t mangle -N FastBalancer
575 iptables -t mangle -N MultiWanRules
576 iptables -t mangle -N MultiWanDNS
577 iptables -t mangle -N MultiWanPreHandler
578 iptables -t mangle -N MultiWanPostHandler
579 iptables -t mangle -N MultiWanLoadBalancer
580
581 echo "## Creating FW Rules ##"
582 i=0
583 while [ $i -lt $wancount ]; do
584 i=`expr $i + 1`
585 iprule=$(expr $i \* 10)
586 iptables -t mangle -N FW${i}MARK
587 iptables -t mangle -A FW${i}MARK -j MARK --set-mark 0x${iprule}
588 iptables -t mangle -A FW${i}MARK -j CONNMARK --save-mark
589 done
590
591 iptables -t mangle -A LoadBalancer -j MARK --set-mark 0x1
592 iptables -t mangle -A LoadBalancer -j CONNMARK --save-mark
593
594 if [ -z "$CHKFORMODULE" ]; then
595 iptables -t mangle -A FastBalancer -j MARK --set-mark 0x2
596 iptables -t mangle -A FastBalancer -j CONNMARK --save-mark
597 else
598 mwnote "Performance load balancer(fastbalanacer) is unavailable due to current kernel limitations.."
599 iptables -t mangle -A FastBalancer -j MARK --set-mark 0x1
600 iptables -t mangle -A FastBalancer -j CONNMARK --save-mark
601 fi
602
603 iptables -t mangle -A MultiWan -j CONNMARK --restore-mark
604 iptables -t mangle -A MultiWan -j MultiWanPreHandler
605 iptables -t mangle -A MultiWan -j MultiWanRules
606 iptables -t mangle -A MultiWan -j MultiWanLoadBalancer
607 iptables -t mangle -A MultiWan -j MultiWanDNS
608 iptables -t mangle -A MultiWan -j MultiWanPostHandler
609
610 iptables -t mangle -I PREROUTING -j MultiWan
611 iptables -t mangle -I FORWARD -j MultiWan
612 iptables -t mangle -I OUTPUT -j MultiWan
613 iptables -t mangle -I POSTROUTING -j MultiWan
614
615
616 refresh_dns
617
618 config_load "multiwan"
619 config_foreach mwanrule mwanfw
620
621 if [ "$default_route" != "balancer" -a "$default_route" != "fastbalancer" ]; then
622 default_route_id=$(query_config wanid $default_route)
623 iptables -t mangle -A MultiWanRules -m mark --mark 0x0 -j FW${default_route_id}MARK
624 elif [ "$default_route" == "fastbalancer" ]; then
625 iptables -t mangle -A MultiWanRules -m mark --mark 0x0 -j FastBalancer
626 else
627 iptables -t mangle -A MultiWanRules -m mark --mark 0x0 -j LoadBalancer
628 fi
629
630 i=0
631 while [ $i -lt $wancount ]; do
632 i=`expr $i + 1`
633 group=$(query_config group $i)
634 ifname=$(query_config ifname $group)
635 iptables -t mangle -A MultiWanPreHandler -i $ifname -m state --state NEW -j FW${i}MARK
636 iptables -t mangle -A MultiWanPostHandler -o $ifname -m mark --mark 0x1 -j FW${i}MARK
637 done
638
639 if [ ! -z "$CHKFORQOS" ]; then
640 iptables -t mangle -A MultiWan -j MultiWanQoS
641 fi
642
643 }
644
645 refresh_loadbalancer() {
646 local group
647 local gateway
648 local ifname
649 local failchk
650 local weight
651 local nexthop
652 local pre_nexthop_chk
653 local rand_probability
654 local total_weight
655 local i
656
657 echo "## Refreshing Load Balancer ##"
658
659 ip rule del prio 9 > /dev/null 2>&1
660 ip route flush table 170 > /dev/null 2>&1
661
662 for TABLE in 170
663 do
664 ip route | grep link | grep -Ev ^default | while read ROUTE
665 do
666 ip route add table $TABLE to $ROUTE
667 done
668 done
669
670 iptables -F MultiWanLoadBalancer -t mangle
671
672 total_weight=0
673
674 i=0
675 while [ $i -lt $wancount ]; do
676 i=`expr $i + 1`
677 group=$(query_config group $i)
678 failchk=$(query_config failchk $group)
679 gateway=$(query_config gateway $group)
680 ifname=$(query_config ifname $group)
681 weight=`uci -q -P /var/state get multiwan.${group}.weight`
682 if [ "$gateway" != "x" -a "$ifname" != "x" -a "$failchk" != "x" -a "$weight" != "disable" ]; then
683 total_weight=$(expr $total_weight + $weight)
684 fi
685 done
686
687 i=0
688 while [ $i -lt $wancount ]; do
689 i=`expr $i + 1`
690 group=$(query_config group $i)
691 failchk=$(query_config failchk $group)
692 gateway=$(query_config gateway $group)
693 ifname=$(query_config ifname $group)
694
695 weight=`uci -q -P /var/state get multiwan.${group}.weight`
696
697 if [ "$gateway" != "x" -a "$ifname" != "x" -a "$failchk" != "x" -a "$weight" != "disable" ]; then
698 nexthop="$nexthop nexthop via $gateway dev $ifname weight $weight"
699
700 rand_probability=$(expr $(expr $weight \* 100) / $total_weight)
701 total_weight=$(expr $total_weight - $weight)
702
703 if [ $rand_probability -lt 10 ]; then
704 rand_probability="0.0${rand_probability}"
705 elif [ $rand_probability -lt 100 ]; then
706 rand_probability="0.${rand_probability}"
707 else
708 rand_probability="1.0"
709 fi
710
711 if [ -z "$CHKFORMODULE" ]; then
712 iptables -A MultiWanLoadBalancer -t mangle -m mark --mark 0x2 -m statistic --mode random --probability $rand_probability -j FW${i}MARK
713 fi
714 fi
715
716 done
717
718 pre_nexthop_chk=`echo $nexthop | awk -F "nexthop" '{print NF-1}'`
719 if [ "$pre_nexthop_chk" == "1" ]; then
720 ip route add default via $(echo $nexthop | awk -F " " '{print $3}') dev $(echo $nexthop | awk -F " " '{print $5}') proto static table 170
721 elif [ "$pre_nexthop_chk" -gt "1" ]; then
722 ip route add proto static table 170 default scope global $nexthop
723 fi
724
725 ip rule add fwmark 0x1 table 170 prio 9
726 ip route flush cache
727 }
728
729 refresh_routes() {
730 local iprule
731 local gateway
732 local group
733 local ifname
734 local ipaddr
735 local i
736
737 echo "## Refreshing Routing Tables ##"
738
739 i=0
740 while [ $i -lt $wancount ]
741 do
742 i=`expr $i + 1`
743 group=$(query_config group $i)
744 gateway=$(query_config gateway $group)
745 ifname=$(query_config ifname $group)
746 ipaddr=$(query_config ipaddr $group)
747 ip route flush table $(expr $i + 170) > /dev/null 2>&1
748
749 for TABLE in $(expr $i + 170)
750 do
751 ip route | grep link | grep -Ev ^default | while read ROUTE
752 do
753 ip route add table $TABLE to $ROUTE
754 done
755 done
756
757 if [ "$gateway" != "x" -a "$ipaddr" != "x" -a "$ifname" != "x" ]; then
758 ip route add default via $gateway table $(expr $i + 170) src $ipaddr proto static
759 route add default gw $gateway > /dev/null 2>&1
760 fi
761 done
762
763 ip route flush cache
764 }
765
766 iprules_config() {
767
768 local iprule
769 local group
770 local gateway
771 local ipaddr
772
773 group=$(query_config group $1)
774 gateway=$(query_config gateway $group)
775 ipaddr=$(query_config ipaddr $group)
776
777 CHKIPROUTE=`cat /etc/iproute2/rt_tables | grep MWAN${1}`
778 if [ -z "$CHKIPROUTE" ]; then
779 echo "$(expr $1 + 170) MWAN${1}" >> /etc/iproute2/rt_tables
780 fi
781
782 ip rule del prio $(expr $1 \* 10) > /dev/null 2>&1
783 ip rule del prio $(expr $1 \* 10 + 1) > /dev/null 2>&1
784
785 if [ "$gateway" != "x" -a "$ipaddr" != "x" ]; then
786 ip rule add from $ipaddr table $(expr $1 + 170) prio $(expr $1 \* 10)
787 ip rule add fwmark 0x$(expr $1 \* 10) table $(expr $1 + 170) prio $(expr $(expr $1 \* 10) + 1)
788 fi
789 }
790
791 flush() {
792 local i
793
794 echo "## Flushing IP Rules & Routes ##"
795
796 ip rule flush > /dev/null 2>&1
797 ip rule add lookup main prio 32766 > /dev/null 2>&1
798 ip rule add lookup default prio 32767 > /dev/null 2>&1
799
800 ip route flush table 170 > /dev/null
801
802 i=0
803 while [ $i -lt $wancount ]; do
804 i=`expr $i + 1`
805 ip route del default > /dev/null 2>&1
806 ip route flush table $(expr $i + 170) > /dev/null 2>&1
807 done
808
809 echo "## Clearing Rules ##"
810 clear_rules > /dev/null 2>&1
811
812 rm $jobfile > /dev/null 2>&1
813 }
814
815 main_init() {
816 local RP_PATH
817 local group
818 local health_interval
819 local i
820
821 echo "## Main Initialization ##"
822
823 mkdir /tmp/.mwan > /dev/null 2>&1
824
825 mwan_kill
826 flush
827
828
829 echo "## IP Rules Initialization ##"
830
831 CHKIPROUTE=`cat /etc/iproute2/rt_tables | grep LoadBalancer`
832 if [ -z "$CHKIPROUTE" ]; then
833 echo "#" >> /etc/iproute2/rt_tables
834 echo "170 LoadBalancer" >> /etc/iproute2/rt_tables
835 fi
836
837 i=0
838 while [ $i -lt $wancount ]; do
839 i=`expr $i + 1`
840 iprules_config $i
841 done
842
843 refresh_routes
844 iptables_init
845
846 refresh_loadbalancer
847
848 RP_PATH=/proc/sys/net/ipv4/conf
849 for IFACE in `ls $RP_PATH`; do
850 echo 0 > $RP_PATH/$IFACE/rp_filter
851 done
852 echo "## Initialization Complete, switching to background mode. ##"
853 mwnote "Succesfully Initialized on $(exec date -R)."
854 fail_start_check
855
856 stagger_health_monitors() {
857 i=0
858 while [ $i -lt $wancount ]; do
859 i=`expr $i + 1`
860 group=$(query_config group $i)
861 health_interval=`uci -q -P /var/state get multiwan.${group}.health_interval`
862 if [ ! -z "$health_interval" -a "$health_interval" != "disable" -a "$health_interval" -gt 0 ]; then
863 health_monitor $group &
864 sleep 3
865 fi
866 done
867 }
868
869 stagger_health_monitors &
870 bg_task &
871
872 exit
873 }
874
875 health_monitor() {
876 local ipaddr_cur
877 local gateway_cur
878 local ifname_cur
879 local ifname
880 local ipaddr
881 local gateway
882 local failchk
883 local icmp_hosts
884 local icmp_hosts_acquire
885 local default_routes_check
886 local icmp_test_host
887 local timeout
888 local check_test
889 local health_interval
890 local check_for_job
891
892 . /tmp/.mwan/cache
893
894 timeout=`uci -q -P /var/state get multiwan.${1}.timeout`
895 icmp_hosts=`uci -q -P /var/state get multiwan.${1}.icmp_hosts`
896 health_interval=`uci -q -P /var/state get multiwan.${1}.health_interval`
897 ifname_cur=$(query_config ifname $1)
898 ipaddr_cur=$(query_config ipaddr $1)
899 gateway_cur=$(query_config gateway $1)
900
901 while [ 1 ]; do
902
903 ifname=`uci -q -P /var/state get network.${1}.ifname`
904 ipaddr=`uci -q -P /var/state get network.${1}.ipaddr`
905 gateway=`uci -q -P /var/state get network.${1}.gateway`
906
907 if [ -z "$ifname" ]; then
908 ifname="x"
909 fi
910
911 if [ -z "$ipaddr" ]; then
912 ipaddr="x"
913 fi
914
915 if [ -z "$gateway" ]; then
916 gateway="x"
917 fi
918
919 if [ "$ifname_cur" != "$ifname" -o "$ipaddr_cur" != "$ipaddr" -o "$gateway_cur" != "$gateway" ]; then
920 echo $1.acquire >> $jobfile
921 exit
922 else
923 if [ "$gateway" != "x" ]; then
924 default_routes_check=`ip route | grep -o $gateway`
925 if [ -z "$default_routes_check" ]; then
926 check_for_job=`cat $jobfile 2>&1 | grep -o "route.refresh"`
927 if [ -z "$check_for_job" ]; then
928 echo route.refresh >> $jobfile
929 fi
930 fi
931 fi
932 fi
933
934 if [ "$icmp_hosts" != "disable" -a "$ifname" != "x" -a "$ipaddr" != "x" -a "$gateway" != "x" ]; then
935
936 if [ "$icmp_hosts" == "gateway" -o -z "$icmp_hosts" ]; then
937 icmp_hosts_acquire=$gateway
938 elif [ "$icmp_hosts" == "dns" ]; then
939 icmp_hosts_acquire=`uci -q -P /var/state get multiwan.$1.dns`
940 if [ -z "$icmp_hosts_acquire" -o "$icmp_hosts_acquire" == "auto" ]; then
941 icmp_hosts_acquire=`uci -q -P /var/state get network.$1.dns`
942 fi
943 else
944 icmp_hosts_acquire=$icmp_hosts
945 fi
946
947 icmp_hosts=$(echo $icmp_hosts_acquire | sed -e "s/\,/ /g" | sed -e "s/ /\n/g")
948
949 ping_test() {
950 echo "$icmp_hosts" | while read icmp_test_host
951 do
952 ping -c 1 -W $timeout -I $ifname $icmp_test_host 2>&1 | grep -o "round-trip"
953 done
954 }
955
956 check_test=$(ping_test)
957
958 if [ -z "$check_test" ]; then
959 echo "$1.fail" >> $jobfile
960 else
961 echo "$1.pass" >> $jobfile
962 fi
963
964 elif [ "$icmp_hosts" == "disable" ]; then
965 echo "$1.pass" >> $jobfile
966 fi
967
968 sleep $health_interval
969 done
970 }
971
972 bg_task() {
973 local check_iptables
974 local queued_task
975 local bg_counter
976 local current_resolv_file
977
978 bg_counter=0
979
980 while [ 1 ]; do
981
982 . /tmp/.mwan/cache
983
984 if [ "$bg_counter" -eq 5 ]; then
985
986 check_iptables=$(iptables -n -L MultiWan -t mangle | grep "references" | awk -F "(" '{print $2}' | cut -d " " -f 1)
987
988 if [ -z "$check_iptables" -o "$check_iptables" -lt 4 ]; then
989 mwnote "Netfilter rules appear to of been altered."
990 /etc/init.d/multiwan restart &
991 exit
992 fi
993
994 current_resolv_file=$(ls -l -e /tmp/resolv.conf.auto | awk -F " " '{print $5, $9}')
995
996 if [ "$last_resolv_update" != "$current_resolv_file" ]; then
997 refresh_dns
998 fi
999
1000 bg_counter=0
1001
1002 fi
1003
1004 if [ -f $jobfile ]; then
1005
1006 mv $jobfile $jobfile.work
1007
1008 while read LINE
1009 do
1010
1011 execute_task(){
1012 case $2 in
1013 fail) fail_wan $1;;
1014 pass) recover_wan $1;;
1015 acquire) acquire_wan_data $1 && health_monitor $1 &;;
1016 refresh) refresh_routes;;
1017 esac
1018 }
1019
1020 queued_task=`echo $LINE | awk -F "." '{print $1,$2}'`
1021 execute_task $queued_task
1022 done < $jobfile.work
1023
1024 rm $jobfile.work
1025 fi
1026
1027 bg_counter=$(expr $bg_counter + 1)
1028
1029 sleep 1
1030 done
1031 }
1032
1033 fail_start_check(){
1034 local ipaddr
1035 local gateway
1036 local ifname
1037 local group
1038
1039 i=0
1040 while [ $i -lt $wancount ]; do
1041 i=`expr $i + 1`
1042 group=$(query_config group $i)
1043 ifname=$(query_config ifname $group)
1044 ipaddr=$(query_config ipaddr $group)
1045 gateway=$(query_config gateway $group)
1046
1047 if [ "$ifname" == "x" -o "$ipaddr" == "x" -o "$gateway" == "x" ]; then
1048 failover add $group
1049 fi
1050 done
1051 }
1052
1053 wancount=0
1054
1055 config_clear
1056 config_load "multiwan"
1057 config_get default_route config default_route
1058 config_get debug config debug
1059
1060 config_foreach acquire_wan_data interface
1061
1062 update_cache
1063
1064 CHKFORQOS=`iptables -n -L Default -t mangle 2>&1 | grep "Chain Default"`
1065 CHKFORMODULE=`iptables -m statistic 2>&1 | grep -o "File not found"`
1066
1067 jobfile="/tmp/.mwan/jobqueue"
1068
1069 case $1 in
1070 agent) silencer main_init;;
1071 restart) silencer stop restart;;
1072 stop) silencer stop;;
1073 esac
1074