source: packages/net/multiwan/files/usr/bin/multiwan @ 21433

Last change on this file since 21433 was 21433, checked in by craigc, 6 years ago

[packages] multiwan: Changed sed to simply remove the last digit.

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