[packages] multiwan: Adjusted initial restore mark rule
[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 lanip
736 local i
737
738 echo "## Refreshing Routing Tables ##"
739
740 i=0
741 while [ $i -lt $wancount ]
742 do
743 i=`expr $i + 1`
744 group=$(query_config group $i)
745 gateway=$(query_config gateway $group)
746 ifname=$(query_config ifname $group)
747 ipaddr=$(query_config ipaddr $group)
748 ip route flush table $(expr $i + 170) > /dev/null 2>&1
749
750 for TABLE in $(expr $i + 170)
751 do
752 ip route | grep link | grep -Ev ^default | while read ROUTE
753 do
754 ip route add table $TABLE to $ROUTE
755 done
756 done
757
758 if [ "$gateway" != "x" -a "$ipaddr" != "x" -a "$ifname" != "x" ]; then
759 ip route add default via $gateway table $(expr $i + 170) src $ipaddr proto static
760 ip route del default > /dev/null 2>&1
761
762 if [ ! -z $lan_if ]; then
763 lanip=`uci -q -P /var/state get network.${lan_if}.ipaddr`
764 else
765 lanip=`uci -q -P /var/state get network.lan.ipaddr`
766 fi
767
768 ip route add default via $lanip > /dev/null 2>&1
769 fi
770 done
771
772 ip route flush cache
773 }
774
775 iprules_config() {
776
777 local iprule
778 local group
779 local gateway
780 local ipaddr
781
782 group=$(query_config group $1)
783 gateway=$(query_config gateway $group)
784 ipaddr=$(query_config ipaddr $group)
785
786 CHKIPROUTE=`cat /etc/iproute2/rt_tables | grep MWAN${1}`
787 if [ -z "$CHKIPROUTE" ]; then
788 echo "$(expr $1 + 170) MWAN${1}" >> /etc/iproute2/rt_tables
789 fi
790
791 ip rule del prio $(expr $1 \* 10) > /dev/null 2>&1
792 ip rule del prio $(expr $1 \* 10 + 1) > /dev/null 2>&1
793
794 if [ "$gateway" != "x" -a "$ipaddr" != "x" ]; then
795 ip rule add from $ipaddr table $(expr $1 + 170) prio $(expr $1 \* 10)
796 ip rule add fwmark 0x$(expr $1 \* 10) table $(expr $1 + 170) prio $(expr $(expr $1 \* 10) + 1)
797 fi
798 }
799
800 flush() {
801 local i
802
803 echo "## Flushing IP Rules & Routes ##"
804
805 ip rule flush > /dev/null 2>&1
806 ip rule add lookup main prio 32766 > /dev/null 2>&1
807 ip rule add lookup default prio 32767 > /dev/null 2>&1
808
809 ip route flush table 170 > /dev/null
810
811 i=0
812 while [ $i -lt $wancount ]; do
813 i=`expr $i + 1`
814 ip route del default > /dev/null 2>&1
815 ip route flush table $(expr $i + 170) > /dev/null 2>&1
816 done
817
818 echo "## Clearing Rules ##"
819 clear_rules > /dev/null 2>&1
820
821 rm $jobfile > /dev/null 2>&1
822 }
823
824 main_init() {
825 local RP_PATH
826 local group
827 local health_interval
828 local i
829
830 echo "## Main Initialization ##"
831
832 mkdir /tmp/.mwan > /dev/null 2>&1
833
834 mwan_kill
835 flush
836
837
838 echo "## IP Rules Initialization ##"
839
840 CHKIPROUTE=`cat /etc/iproute2/rt_tables | grep LoadBalancer`
841 if [ -z "$CHKIPROUTE" ]; then
842 echo "#" >> /etc/iproute2/rt_tables
843 echo "170 LoadBalancer" >> /etc/iproute2/rt_tables
844 fi
845
846 i=0
847 while [ $i -lt $wancount ]; do
848 i=`expr $i + 1`
849 iprules_config $i
850 done
851
852 refresh_routes
853 iptables_init
854
855 refresh_loadbalancer
856
857 RP_PATH=/proc/sys/net/ipv4/conf
858 for IFACE in `ls $RP_PATH`; do
859 echo 0 > $RP_PATH/$IFACE/rp_filter
860 done
861 echo "## Initialization Complete, switching to background mode. ##"
862 mwnote "Succesfully Initialized on $(exec date -R)."
863 fail_start_check
864
865 stagger_health_monitors() {
866 i=0
867 while [ $i -lt $wancount ]; do
868 i=`expr $i + 1`
869 group=$(query_config group $i)
870 health_interval=`uci -q -P /var/state get multiwan.${group}.health_interval`
871 if [ ! -z "$health_interval" -a "$health_interval" != "disable" -a "$health_interval" -gt 0 ]; then
872 health_monitor $group &
873 sleep 3
874 fi
875 done
876 }
877
878 stagger_health_monitors &
879 bg_task &
880
881 exit
882 }
883
884 health_monitor() {
885 local ipaddr_cur
886 local gateway_cur
887 local ifname_cur
888 local ifname
889 local ipaddr
890 local gateway
891 local failchk
892 local icmp_hosts
893 local icmp_hosts_acquire
894 local default_routes_check
895 local icmp_test_host
896 local timeout
897 local check_test
898 local health_interval
899 local check_for_job
900
901 . /tmp/.mwan/cache
902
903 timeout=`uci -q -P /var/state get multiwan.${1}.timeout`
904 icmp_hosts=`uci -q -P /var/state get multiwan.${1}.icmp_hosts`
905 health_interval=`uci -q -P /var/state get multiwan.${1}.health_interval`
906 ifname_cur=$(query_config ifname $1)
907 ipaddr_cur=$(query_config ipaddr $1)
908 gateway_cur=$(query_config gateway $1)
909
910 while [ 1 ]; do
911
912 ifname=`uci -q -P /var/state get network.${1}.ifname`
913 ipaddr=`uci -q -P /var/state get network.${1}.ipaddr`
914 gateway=`uci -q -P /var/state get network.${1}.gateway`
915
916 if [ -z "$ifname" ]; then
917 ifname="x"
918 fi
919
920 if [ -z "$ipaddr" ]; then
921 ipaddr="x"
922 fi
923
924 if [ -z "$gateway" ]; then
925 gateway="x"
926 fi
927
928 if [ "$ifname_cur" != "$ifname" -o "$ipaddr_cur" != "$ipaddr" -o "$gateway_cur" != "$gateway" ]; then
929 echo $1.acquire >> $jobfile
930 exit
931 else
932 if [ "$gateway" != "x" ]; then
933 default_routes_check=`ip route | grep -o $gateway`
934 if [ -z "$default_routes_check" ]; then
935 check_for_job=`cat $jobfile 2>&1 | grep -o "route.refresh"`
936 if [ -z "$check_for_job" ]; then
937 echo route.refresh >> $jobfile
938 fi
939 fi
940 fi
941 fi
942
943 if [ "$icmp_hosts" != "disable" -a "$ifname" != "x" -a "$ipaddr" != "x" -a "$gateway" != "x" ]; then
944
945 if [ "$icmp_hosts" == "gateway" -o -z "$icmp_hosts" ]; then
946 icmp_hosts_acquire=$gateway
947 elif [ "$icmp_hosts" == "dns" ]; then
948 icmp_hosts_acquire=`uci -q -P /var/state get multiwan.$1.dns`
949 if [ -z "$icmp_hosts_acquire" -o "$icmp_hosts_acquire" == "auto" ]; then
950 icmp_hosts_acquire=`uci -q -P /var/state get network.$1.dns`
951 fi
952 else
953 icmp_hosts_acquire=$icmp_hosts
954 fi
955
956 icmp_hosts=$(echo $icmp_hosts_acquire | sed -e "s/\,/ /g" | sed -e "s/ /\n/g")
957
958 ping_test() {
959 echo "$icmp_hosts" | while read icmp_test_host
960 do
961 ping -c 1 -W $timeout -I $ifname $icmp_test_host 2>&1 | grep -o "round-trip"
962 done
963 }
964
965 check_test=$(ping_test)
966
967 if [ -z "$check_test" ]; then
968 echo "$1.fail" >> $jobfile
969 else
970 echo "$1.pass" >> $jobfile
971 fi
972
973 elif [ "$icmp_hosts" == "disable" ]; then
974 echo "$1.pass" >> $jobfile
975 fi
976
977 sleep $health_interval
978 done
979 }
980
981 bg_task() {
982 local check_iptables
983 local queued_task
984 local bg_counter
985 local current_resolv_file
986
987 bg_counter=0
988
989 while [ 1 ]; do
990
991 . /tmp/.mwan/cache
992
993 if [ "$bg_counter" -eq 5 ]; then
994
995 check_iptables=$(iptables -n -L MultiWan -t mangle | grep "references" | awk -F "(" '{print $2}' | cut -d " " -f 1)
996
997 if [ -z "$check_iptables" -o "$check_iptables" -lt 4 ]; then
998 mwnote "Netfilter rules appear to of been altered."
999 /etc/init.d/multiwan restart &
1000 exit
1001 fi
1002
1003 current_resolv_file=$(ls -l -e /tmp/resolv.conf.auto | awk -F " " '{print $5, $9}')
1004
1005 if [ "$last_resolv_update" != "$current_resolv_file" ]; then
1006 refresh_dns
1007 fi
1008
1009 bg_counter=0
1010
1011 fi
1012
1013 if [ -f $jobfile ]; then
1014
1015 mv $jobfile $jobfile.work
1016
1017 while read LINE
1018 do
1019
1020 execute_task(){
1021 case $2 in
1022 fail) fail_wan $1;;
1023 pass) recover_wan $1;;
1024 acquire) acquire_wan_data $1 && health_monitor $1 &;;
1025 refresh) refresh_routes;;
1026 esac
1027 }
1028
1029 queued_task=`echo $LINE | awk -F "." '{print $1,$2}'`
1030 execute_task $queued_task
1031 done < $jobfile.work
1032
1033 rm $jobfile.work
1034 fi
1035
1036 bg_counter=$(expr $bg_counter + 1)
1037
1038 sleep 1
1039 done
1040 }
1041
1042 fail_start_check(){
1043 local ipaddr
1044 local gateway
1045 local ifname
1046 local group
1047
1048 i=0
1049 while [ $i -lt $wancount ]; do
1050 i=`expr $i + 1`
1051 group=$(query_config group $i)
1052 ifname=$(query_config ifname $group)
1053 ipaddr=$(query_config ipaddr $group)
1054 gateway=$(query_config gateway $group)
1055
1056 if [ "$ifname" == "x" -o "$ipaddr" == "x" -o "$gateway" == "x" ]; then
1057 failover add $group
1058 fi
1059 done
1060 }
1061
1062 wancount=0
1063
1064 config_clear
1065 config_load "multiwan"
1066 config_get default_route config default_route
1067 config_get lan_if config lan_if
1068 config_get debug config debug
1069
1070 config_foreach acquire_wan_data interface
1071
1072 update_cache
1073
1074 CHKFORQOS=`iptables -n -L Default -t mangle 2>&1 | grep "Chain Default"`
1075 CHKFORMODULE=`iptables -m statistic 2>&1 | grep -o "File not found"`
1076
1077 jobfile="/tmp/.mwan/jobqueue"
1078
1079 case $1 in
1080 agent) silencer main_init;;
1081 restart) silencer stop restart;;
1082 stop) silencer stop;;
1083 esac
1084