Browse Source

Add mwan3 to packages feed

Signed-off-by: Jeroen Louwes <jeroen.louwes@gmail.com>
Adze1502 10 years ago
parent
commit
7afdbd28cf

+ 48
- 0
net/mwan3/Makefile View File

@@ -0,0 +1,48 @@
1
+#
2
+# Copyright (C) 2006-2014 OpenWrt.org
3
+#
4
+# This is free software, licensed under the GNU General Public License v2.
5
+# See /LICENSE for more information.
6
+#
7
+
8
+include $(TOPDIR)/rules.mk
9
+
10
+PKG_NAME:=mwan3
11
+PKG_VERSION:=1.4
12
+PKG_RELEASE:=22
13
+PKG_MAINTAINER:=Jeroen Louwes <jeroen.louwes@gmail.com>
14
+PKG_LICENSE:=GPLv2
15
+
16
+include $(INCLUDE_DIR)/package.mk
17
+
18
+define Package/mwan3
19
+   SECTION:=net
20
+   CATEGORY:=Network
21
+   SUBMENU:=Routing and Redirection
22
+   DEPENDS:=+ip +iptables +iptables-mod-conntrack-extra +iptables-mod-ipopt
23
+   TITLE:=Multiwan hotplug script with connection tracking support
24
+   MAINTAINER:=Jeroen Louwes <jeroen.louwes@gmail.com>
25
+   PKGARCH:=all
26
+endef
27
+
28
+define Package/mwan3/description
29
+   Hotplug script which makes configuration of multiple WAN interfaces simple and manageable. With loadbalancing/failover support for up to 250 wan interfaces, connection tracking and an easy to manage traffic ruleset.
30
+endef
31
+
32
+define Package/mwan3/conffiles
33
+   /etc/config/mwan3
34
+endef
35
+
36
+define Build/Compile
37
+endef
38
+
39
+define Package/mwan3/install
40
+   $(CP) ./files/* $(1)
41
+endef
42
+
43
+define Package/mwan3/postinst
44
+   [ -n "$${IPKG_INSTROOT}" ] || /etc/init.d/mwan3 enable
45
+   exit 0
46
+endef
47
+
48
+$(eval $(call BuildPackage,mwan3))

+ 79
- 0
net/mwan3/files/etc/config/mwan3 View File

@@ -0,0 +1,79 @@
1
+
2
+config interface 'wan'
3
+	option enabled '1'
4
+	list track_ip '8.8.4.4'
5
+	list track_ip '8.8.8.8'
6
+	list track_ip '208.67.222.222'
7
+	list track_ip '208.67.220.220'
8
+	option reliability '2'
9
+	option count '1'
10
+	option timeout '2'
11
+	option interval '5'
12
+	option down '3'
13
+	option up '8'
14
+
15
+config interface 'wan2'
16
+	option enabled '0'
17
+	list track_ip '8.8.8.8'
18
+	list track_ip '208.67.220.220'
19
+	option reliability '1'
20
+	option count '1'
21
+	option timeout '2'
22
+	option interval '5'
23
+	option down '3'
24
+	option up '8'
25
+
26
+config member 'wan_m1_w3'
27
+	option interface 'wan'
28
+	option metric '1'
29
+	option weight '3'
30
+
31
+config member 'wan_m2_w3'
32
+	option interface 'wan'
33
+	option metric '2'
34
+	option weight '3'
35
+
36
+config member 'wan2_m1_w2'
37
+	option interface 'wan2'
38
+	option metric '1'
39
+	option weight '2'
40
+
41
+config member 'wan2_m2_w2'
42
+	option interface 'wan2'
43
+	option metric '2'
44
+	option weight '2'
45
+
46
+config policy 'wan_only'
47
+	list use_member 'wan_m1_w3'
48
+
49
+config policy 'wan2_only'
50
+	list use_member 'wan2_m1_w2'
51
+
52
+config policy 'balanced'
53
+	list use_member 'wan_m1_w3'
54
+	list use_member 'wan2_m1_w2'
55
+
56
+config policy 'wan_wan2'
57
+	list use_member 'wan_m1_w3'
58
+	list use_member 'wan2_m2_w2'
59
+
60
+config policy 'wan2_wan'
61
+	list use_member 'wan_m2_w3'
62
+	list use_member 'wan2_m1_w2'
63
+
64
+config rule 'sticky_even'
65
+	option src_ip '0.0.0.0/0.0.0.1'
66
+	option dest_port '443'
67
+	option proto 'tcp'
68
+	option use_policy 'wan_wan2'
69
+
70
+config rule 'sticky_odd'
71
+	option src_ip '0.0.0.1/0.0.0.1'
72
+	option dest_port '443'
73
+	option proto 'tcp'
74
+	option use_policy 'wan2_wan'
75
+
76
+config rule 'default_rule'
77
+	option dest_ip '0.0.0.0/0'
78
+	option use_policy 'balanced'
79
+

+ 328
- 0
net/mwan3/files/etc/hotplug.d/iface/15-mwan3 View File

@@ -0,0 +1,328 @@
1
+#!/bin/sh
2
+
3
+mwan3_get_iface_id()
4
+{
5
+	let iface_count++
6
+	[ "$1" == "$INTERFACE" ] && iface_id=$iface_count
7
+}
8
+
9
+mwan3_get_route_args()
10
+{
11
+	route_args=$(ip -4 route list dev $DEVICE default | head -1 | sed '/.*via \([^ ]*\) .*$/!d;s//\1/;q' | egrep '[0-9]{1,3}(\.[0-9]{1,3}){3}')
12
+	[ -n "$route_args" ] && route_args="via $route_args"
13
+	route_args="nexthop $route_args dev $DEVICE"
14
+}
15
+
16
+mwan3_set_general_iptables()
17
+{
18
+	if ! iptables -S mwan3_ifaces -t mangle &> /dev/null; then
19
+		iptables -N mwan3_ifaces -t mangle
20
+	fi
21
+
22
+	if ! iptables -S mwan3_rules -t mangle &> /dev/null; then
23
+		iptables -N mwan3_rules -t mangle
24
+	fi
25
+
26
+	if ! iptables -S mwan3_connected -t mangle &> /dev/null; then
27
+		iptables -N mwan3_connected -t mangle
28
+	fi
29
+
30
+	if ! iptables -S mwan3_hook -t mangle &> /dev/null; then
31
+		iptables -N mwan3_hook -t mangle
32
+		iptables -A mwan3_hook -t mangle -j CONNMARK --restore-mark --nfmask 0xff00 --ctmask 0xff00
33
+		iptables -A mwan3_hook -t mangle -m mark --mark 0x0/0xff00 -j mwan3_ifaces
34
+		iptables -A mwan3_hook -t mangle -m mark --mark 0x0/0xff00 -j mwan3_connected
35
+		iptables -A mwan3_hook -t mangle -m mark --mark 0x0/0xff00 -j mwan3_rules
36
+		iptables -A mwan3_hook -t mangle -j CONNMARK --save-mark --nfmask 0xff00 --ctmask 0xff00
37
+	fi
38
+
39
+	if ! iptables -S mwan3_track_hook -t mangle &> /dev/null; then
40
+		iptables -N mwan3_track_hook -t mangle
41
+	fi
42
+
43
+	if ! iptables -S PREROUTING -t mangle | grep mwan3_hook &> /dev/null; then
44
+		iptables -A PREROUTING -t mangle -j mwan3_hook
45
+	fi
46
+
47
+	if ! iptables -S OUTPUT -t mangle | grep mwan3_hook &> /dev/null; then
48
+		iptables -A OUTPUT -t mangle -j mwan3_hook
49
+	fi
50
+
51
+	if ! iptables -S OUTPUT -t mangle | grep mwan3_track_hook &> /dev/null; then
52
+		iptables -A OUTPUT -t mangle -j mwan3_track_hook
53
+	fi
54
+
55
+	iptables -F mwan3_rules -t mangle
56
+}
57
+
58
+mwan3_set_connected_iptables()
59
+{
60
+	local connected_networks
61
+
62
+	if iptables -S mwan3_connected -t mangle &> /dev/null; then
63
+		iptables -F mwan3_connected -t mangle
64
+
65
+		for connected_networks in $(ip -4 route | awk '{print $1}' | egrep '[0-9]{1,3}(\.[0-9]{1,3}){3}'); do
66
+			iptables -A mwan3_connected -t mangle -d $connected_networks -m mark --mark 0x0/0xff00 -j MARK --set-xmark 0xff00/0xff00
67
+		done
68
+
69
+		iptables -I mwan3_connected -t mangle -d 224.0.0.0/3 -m mark --mark 0x0/0xff00 -j MARK --set-xmark 0xff00/0xff00
70
+		iptables -I mwan3_connected -t mangle -d 127.0.0.0/8 -m mark --mark 0x0/0xff00 -j MARK --set-xmark 0xff00/0xff00
71
+	fi
72
+}
73
+
74
+mwan3_set_iface_iptables()
75
+{
76
+	local local_net local_nets
77
+
78
+	local_net=$(ip -4 route list dev $DEVICE scope link | awk '{print $1}' | egrep '[0-9]{1,3}(\.[0-9]{1,3}){3}')
79
+
80
+	if ! iptables -S mwan3_iface_$INTERFACE -t mangle &> /dev/null; then
81
+		iptables -N mwan3_iface_$INTERFACE -t mangle
82
+	fi
83
+
84
+	iptables -F mwan3_iface_$INTERFACE -t mangle
85
+	iptables -D mwan3_ifaces -t mangle -i $DEVICE -m mark --mark 0x0/0xff00 -j mwan3_iface_$INTERFACE &> /dev/null
86
+
87
+	if [ $ACTION == "ifup" ]; then
88
+		if [ -n "$local_net" ]; then
89
+			for local_nets in $local_net ; do
90
+				if [ $ACTION == "ifup" ]; then
91
+					iptables -I mwan3_iface_$INTERFACE -t mangle -s $local_net -m mark --mark 0x0/0xff00 -m comment --comment "$INTERFACE" -j MARK --set-xmark 0xff00/0xff00
92
+				fi
93
+			done
94
+		fi
95
+
96
+		iptables -A mwan3_iface_$INTERFACE -t mangle -m mark --mark 0x0/0xff00 -m comment --comment "$INTERFACE" -j MARK --set-xmark $(($iface_id*256))/0xff00
97
+		iptables -A mwan3_ifaces -t mangle -i $DEVICE -m mark --mark 0x0/0xff00 -j mwan3_iface_$INTERFACE
98
+	fi
99
+
100
+	if [ $ACTION == "ifdown" ]; then
101
+		iptables -X mwan3_iface_$INTERFACE -t mangle
102
+	fi
103
+}
104
+
105
+mwan3_set_iface_route()
106
+{
107
+	ip -4 route flush table $iface_id
108
+	[ $ACTION == "ifup" ] && ip -4 route add table $iface_id default $route_args
109
+}
110
+
111
+mwan3_set_iface_rules()
112
+{
113
+	while [ -n "$(ip -4 rule list | awk '$1 == "'$(($iface_id+1000)):'"')" ]; do
114
+		ip -4 rule del pref $(($iface_id+1000))
115
+	done
116
+
117
+	while [ -n "$(ip -4 rule list | awk '$1 == "'$(($iface_id+2000)):'"')" ]; do
118
+		ip -4 rule del pref $(($iface_id+2000))
119
+	done
120
+
121
+	while [ -n "$(ip -4 rule list | awk '$1 == "2254:"')" ]; do
122
+		ip -4 rule del pref 2254
123
+	done
124
+
125
+	[ $ACTION == "ifup" ] && ip -4 rule add pref $(($iface_id+1000)) iif $DEVICE lookup main
126
+	[ $ACTION == "ifup" ] && ip -4 rule add pref $(($iface_id+2000)) fwmark $(($iface_id*256))/0xff00 lookup $iface_id
127
+        ip rule add pref 2254 fwmark 0xfe00/0xff00 unreachable                                   
128
+}
129
+
130
+mwan3_track()
131
+{
132
+	local track_ip track_ips reliability count timeout interval down up
133
+
134
+	mwan3_list_track_ips()
135
+	{
136
+		track_ips="$1 $track_ips"
137
+	}
138
+	config_list_foreach $INTERFACE track_ip mwan3_list_track_ips
139
+
140
+	if [ -n "$track_ips" ]; then
141
+		config_get reliability $INTERFACE reliability 1
142
+		config_get count $INTERFACE count 1
143
+		config_get timeout $INTERFACE timeout 4
144
+		config_get interval $INTERFACE interval 10
145
+		config_get down $INTERFACE down 5
146
+		config_get up $INTERFACE up 5
147
+
148
+		if ! iptables -S mwan3_track_$INTERFACE -t mangle &> /dev/null; then
149
+			iptables -N mwan3_track_$INTERFACE -t mangle
150
+			iptables -A mwan3_track_hook -t mangle -p icmp -m icmp --icmp-type 8 -m length --length 32 -j mwan3_track_$INTERFACE
151
+		fi
152
+
153
+		iptables -F mwan3_track_$INTERFACE -t mangle
154
+
155
+		for track_ip in $track_ips; do
156
+			iptables -A mwan3_track_$INTERFACE -t mangle -d $track_ip -j MARK --set-xmark 0xff00/0xff00
157
+		done
158
+
159
+		[ -x /usr/sbin/mwan3track ] && /usr/sbin/mwan3track $INTERFACE $DEVICE $reliability $count $timeout $interval $down $up $track_ips &
160
+	else
161
+		iptables -D mwan3_track_hook -t mangle -p icmp -m icmp --icmp-type 8 -m length --length 32 -j mwan3_track_$INTERFACE &> /dev/null
162
+		iptables -F mwan3_track_$INTERFACE -t mangle &> /dev/null
163
+		iptables -X mwan3_track_$INTERFACE -t mangle &> /dev/null
164
+	fi
165
+}
166
+
167
+mwan3_set_policy()
168
+{
169
+	local iface_count iface_id metric probability weight
170
+
171
+	config_get INTERFACE $1 interface
172
+	config_get metric $1 metric 1
173
+	config_get weight $1 weight 1
174
+
175
+	[ -n "$INTERFACE" ] || return 0
176
+	
177
+	config_foreach mwan3_get_iface_id interface
178
+
179
+	[ -n "$iface_id" ] || return 0
180
+
181
+	if iptables -S mwan3_iface_$INTERFACE -t mangle &> /dev/null; then
182
+		if [ "$metric" -lt "$lowest_metric" ]; then
183
+
184
+			total_weight=$weight
185
+			iptables -F mwan3_policy_$policy -t mangle
186
+			iptables -A mwan3_policy_$policy -t mangle -m mark --mark 0x0/0xff00 -m comment --comment "$INTERFACE $weight $weight" -j MARK --set-xmark $(($iface_id*256))/0xff00
187
+
188
+			lowest_metric=$metric
189
+
190
+		elif [ "$metric" -eq "$lowest_metric" ]; then
191
+
192
+			total_weight=$(($total_weight+$weight))
193
+			probability=$(($weight*1000/$total_weight))
194
+			
195
+			if [ "$probability" -lt 10 ]; then
196
+				probability="0.00$probability"
197
+				elif [ $probability -lt 100 ]; then
198
+				probability="0.0$probability"
199
+				elif [ $probability -lt 1000 ]; then
200
+				probability="0.$probability"
201
+			else
202
+				probability="1"
203
+			fi
204
+
205
+			probability="-m statistic --mode random --probability $probability"
206
+			
207
+			iptables -I mwan3_policy_$policy -t mangle -m mark --mark 0x0/0xff00 $probability -m comment --comment "$INTERFACE $weight $total_weight" -j MARK --set-xmark $(($iface_id*256))/0xff00
208
+		fi
209
+	fi
210
+}
211
+
212
+mwan3_set_policies_iptables()
213
+{
214
+	local lowest_metric policy total_weight
215
+
216
+	policy=$1
217
+
218
+	if [ "$policy" != $(echo "$policy" | cut -c1-15) ]; then
219
+		logger -t mwan3 -p warn "Policy $policy exceeds max of 15 chars. Not setting policy" && return 0
220
+	fi
221
+
222
+	if ! iptables -S mwan3_policy_$policy -t mangle &> /dev/null; then
223
+		iptables -N mwan3_policy_$policy -t mangle
224
+	fi
225
+
226
+	iptables -F mwan3_policy_$policy -t mangle
227
+	iptables -A mwan3_policy_$policy -t mangle -m mark --mark 0x0/0xff00 -m comment --comment "unreachable" -j MARK --set-xmark 0xfe00/0xff00
228
+
229
+	lowest_metric=256
230
+	total_weight=0
231
+
232
+	config_list_foreach $policy use_member mwan3_set_policy
233
+
234
+	iptables -X $policy -t mangle &> /dev/null
235
+}
236
+
237
+mwan3_set_user_rules_iptables()
238
+{
239
+	local proto src_ip src_port dest_ip dest_port use_policy
240
+
241
+	config_get proto $1 proto all
242
+	config_get src_ip $1 src_ip 0.0.0.0/0
243
+	config_get src_port $1 src_port 0:65535
244
+	config_get dest_ip $1 dest_ip 0.0.0.0/0
245
+	config_get dest_port $1 dest_port 0:65535
246
+	config_get use_policy $1 use_policy
247
+
248
+	if [ -n "$use_policy" ]; then
249
+		if [ "$use_policy" == "default" ]; then
250
+			use_policy="MARK --set-xmark 0xff00/0xff00"
251
+		elif [ "$use_policy" == "unreachable" ]; then
252
+			use_policy="MARK --set-xmark 0xfe00/0xff00"
253
+		else
254
+			use_policy="mwan3_policy_$use_policy"
255
+		fi
256
+
257
+		case $proto in
258
+			tcp|udp)
259
+			iptables -A mwan3_rules -t mangle -p $proto -s $src_ip -d $dest_ip -m multiport --sports $src_port -m multiport --dports $dest_port -m mark --mark 0/0xff00 -m comment --comment "$1" -j $use_policy &> /dev/null
260
+			;;
261
+			*)
262
+			iptables -A mwan3_rules -t mangle -p $proto -s $src_ip -d $dest_ip -m mark --mark 0/0xff00 -m comment --comment "$1" -j $use_policy &> /dev/null
263
+			;;
264
+		esac
265
+	fi
266
+}
267
+
268
+mwan3_ifupdown()
269
+{
270
+	local counter enabled iface_count iface_id route_args wan_metric
271
+
272
+	[ -n "$DEVICE" ] || exit 0
273
+	[ -n "$INTERFACE" ] || exit 0
274
+	[ "$(uci get -P /var/state mwan3.$INTERFACE 2> /dev/null)" == "interface" ] || return 0
275
+
276
+	config_load mwan3
277
+	config_get enabled $INTERFACE enabled 0
278
+
279
+	counter=0
280
+
281
+	if [ $ACTION == "ifup" ]; then
282
+		[ "$enabled" -eq 1 ] || exit 0
283
+
284
+		while [ -z "$(ip -4 route list dev $DEVICE default | head -1)" -a "$counter" -lt 10 ]; do
285
+			sleep 1
286
+			let counter++
287
+			if [ "$counter" -ge 10 ]; then
288
+				logger -t mwan3 -p warn "Could not find gateway for interface $INTERFACE ($DEVICE)" && exit 0
289
+			fi
290
+		done
291
+
292
+		mwan3_get_route_args
293
+	fi
294
+
295
+	while [ "$(pgrep -f -o hotplug-call)" -ne $$ -a "$counter" -lt 60 ]; do
296
+		sleep 1
297
+		let counter++
298
+		if [ "$counter" -ge 60 ]; then
299
+			logger -t mwan3 -p warn "Timeout waiting for older hotplug processes to finish. $ACTION interface $INTERFACE ($DEVICE) aborted" && exit 0
300
+		fi
301
+	done
302
+
303
+	config_foreach mwan3_get_iface_id interface
304
+
305
+	[ -n "$iface_id" ] || exit 0
306
+	[ "$iface_count" -le 250 ] || exit 0
307
+	unset iface_count
308
+	unset counter
309
+
310
+	logger -t mwan3 -p notice "$ACTION interface $INTERFACE ($DEVICE)"
311
+
312
+	mwan3_set_general_iptables
313
+	mwan3_set_iface_iptables
314
+	mwan3_set_iface_route
315
+	mwan3_set_iface_rules
316
+
317
+	[ $ACTION == "ifup" ] && mwan3_track
318
+
319
+	config_foreach mwan3_set_policies_iptables policy
320
+	config_foreach mwan3_set_user_rules_iptables rule
321
+}
322
+
323
+case "$ACTION" in
324
+	ifup|ifdown)
325
+		mwan3_ifupdown
326
+		mwan3_set_connected_iptables
327
+	;;
328
+esac

+ 20
- 0
net/mwan3/files/etc/init.d/mwan3 View File

@@ -0,0 +1,20 @@
1
+#!/bin/sh /etc/rc.common
2
+START=99
3
+
4
+start() {
5
+	/usr/sbin/mwan3 start
6
+}
7
+
8
+stop() {
9
+	/usr/sbin/mwan3 stop
10
+}
11
+
12
+restart() {
13
+	stop
14
+	start
15
+}
16
+
17
+boot() {
18
+	# Don't start on boot, mwan3 is started by hotplug event.
19
+	return 0
20
+}

+ 208
- 0
net/mwan3/files/usr/sbin/mwan3 View File

@@ -0,0 +1,208 @@
1
+#!/bin/sh /etc/rc.common
2
+
3
+. /lib/network/config.sh
4
+
5
+extra_help() {
6
+	cat <<EOF
7
+
8
+	ifup <iface>	Start service on interface
9
+	ifdown <iface>	Stop service on interface
10
+	interfaces	Show interfaces status
11
+	policies	Show policies status
12
+	rules		Show rules status
13
+	status		Show all status
14
+EOF
15
+}
16
+
17
+EXTRA_COMMANDS="ifdown ifup interfaces policies rules status"
18
+EXTRA_HELP="$(extra_help)"
19
+
20
+
21
+ifdown()
22
+{
23
+	if [ -z "$1" ]; then
24
+		echo "Error: Expecting interface. Usage: mwan3 ifdown <interface>" && exit 0
25
+	fi
26
+
27
+	if [ -n "$2" ]; then
28
+		echo "Error: Too many arguments. Usage: mwan3 ifdown <interface>" && exit 0
29
+	fi
30
+
31
+	local device
32
+	
33
+	device=$(uci get -p /var/state network.$1.ifname) &> /dev/null
34
+	
35
+	if [ -e /var/run/mwan3track-$1.pid ] ; then
36
+		kill $(cat /var/run/mwan3track-$1.pid)
37
+		rm /var/run/mwan3track-$1.pid
38
+	fi
39
+
40
+	if [ -n "$device" ] ; then
41
+		ACTION=ifdown INTERFACE=$1 DEVICE=$device /sbin/hotplug-call iface
42
+	fi
43
+}
44
+
45
+ifup()
46
+{
47
+	config_load mwan3
48
+
49
+	if [ -z "$1" ]; then
50
+		echo "Expecting interface. Usage: mwan3 ifup <interface>" && exit 0
51
+	fi
52
+
53
+	if [ -n "$2" ]; then
54
+		echo "Too many arguments. Usage: mwan3 ifup <interface>" && exit 0
55
+	fi
56
+
57
+	local device enabled
58
+	
59
+	config_get enabled "$1" enabled 0
60
+
61
+	device=$(uci get -p /var/state network.$1.ifname) &> /dev/null
62
+	
63
+	if [ -n "$device" ] ; then
64
+		[ "$enabled" -eq 1 ] && ACTION=ifup INTERFACE=$1 DEVICE=$device /sbin/hotplug-call iface
65
+	fi
66
+}
67
+
68
+interfaces()
69
+{
70
+	config_load mwan3
71
+
72
+	local device enabled iface_id tracking
73
+
74
+	echo "Interface status:"
75
+	
76
+	check_iface_status()
77
+	{
78
+		device=$(uci get -p /var/state network.$1.ifname) &> /dev/null
79
+
80
+		if [ -z "$device" ]; then
81
+			echo "Interface $1 is unknown"
82
+			return 0
83
+		fi
84
+
85
+		config_get enabled "$1" enabled 0
86
+		let iface_id++
87
+
88
+		if [ -n "$(ps -w | grep mwan3track | grep -v grep | sed '/.*\/usr\/sbin\/mwan3track \([^ ]*\) .*$/!d;s//\1/' | awk '$1 == ("'$1'")')" ]; then
89
+			tracking="active"
90
+		else
91
+			tracking="down"
92
+		fi
93
+
94
+		if [ -n "$(ip rule | awk '$5 == ("'$device'")')" -a -n "$(iptables -S mwan3_iface_$1 -t mangle 2> /dev/null)" -a -n "$(ip -4 route list table $iface_id default dev $device 2> /dev/null)" ]; then
95
+			if [ -n "$(uci get -p /var/state mwan3.$1.track_ip 2> /dev/null)" ]; then
96
+				echo "Interface $1 is online (tracking $tracking)"
97
+			else
98
+				echo "Interface $1 is online"
99
+			fi
100
+		elif [ -n "$(ip rule | awk '$5 == ("'$device'")')" -o -n "$(iptables -S mwan3_iface_$1 -t mangle 2> /dev/null)" -o -n "$(ip -4 route list table $iface_id default dev $device 2> /dev/null)" ]; then
101
+			echo "Interface $1 error"
102
+		else
103
+			if [ "$enabled" -eq 1 ]; then
104
+				if [ -n "$(uci get -p /var/state mwan3.$1.track_ip 2> /dev/null)" ]; then
105
+					echo "Interface $1 is offline (tracking $tracking)"
106
+				else
107
+					echo "Interface $1 is offline"
108
+				fi
109
+			else
110
+				echo "Interface $1 is disabled"
111
+			fi
112
+		fi
113
+	}
114
+	config_foreach check_iface_status interface
115
+	echo -e
116
+}
117
+
118
+policies()
119
+{
120
+	local percent policy share total_weight weight iface
121
+
122
+	for policy in $(iptables -S -t mangle | awk '{print $2}' | grep mwan3_policy_ | sort -u); do
123
+		echo "Policy $policy:" | sed 's/mwan3_policy_//g'
124
+
125
+		for iface in $(iptables -S $policy -t mangle | cut -s -d'"' -f2 | awk '{print $1}'); do
126
+			[ -n "$total_weight" ] || total_weight=$(iptables -S $policy -t mangle | grep "$iface " | cut -s -d'"' -f2 | awk '{print $3}')
127
+		done
128
+
129
+		if [ ! -z "${total_weight##*[!0-9]*}" ]; then
130
+			for iface in $(iptables -S $policy -t mangle | cut -s -d'"' -f2 | awk '{print $1}'); do
131
+				weight=$(iptables -S $policy -t mangle | grep "$iface " | cut -s -d'"' -f2 | awk '{print $2}')
132
+				percent=$(($weight*100/$total_weight))
133
+				echo " $iface ($percent%)"
134
+			done
135
+		else
136
+			echo " $(iptables -S $policy -t mangle | sed '/.*--comment \([^ ]*\) .*$/!d;s//\1/;q')"
137
+		fi
138
+
139
+		echo -e
140
+
141
+		unset iface
142
+		unset total_weight
143
+	done
144
+}
145
+rules()
146
+{
147
+	if [ -n "$(iptables -S mwan3_connected -t mangle 2> /dev/null)" ]; then
148
+		echo "Known networks:"
149
+		echo "destination policy hits" | awk '{ printf "%-19s%-19s%-9s%s\n",$1,$2,$3}'
150
+		echo "------------------------------------------------"
151
+		iptables -L mwan3_connected -t mangle -n -v 2> /dev/null | tail -n+3 | sed 's/mark.*//' | sed 's/mwan3_policy_//g' | awk '{printf "%-19s%-19s%-9s%s\n",$9,"default",$1}'
152
+		echo -e
153
+	fi
154
+
155
+	if [ -n "$(iptables -S mwan3_rules -t mangle 2> /dev/null)" ]; then
156
+		echo "Active rules:"
157
+		echo "source destination proto src-port dest-port policy hits" | awk '{ printf "%-19s%-19s%-7s%-14s%-14s%-16s%-9s%s\n",$1,$2,$3,$4,$5,$6,$7}'
158
+		echo "---------------------------------------------------------------------------------------------------"
159
+		iptables -L mwan3_rules -t mangle -n -v 2> /dev/null | tail -n+3 | sed 's/mark.*//' | sed 's/mwan3_policy_//g' | awk '{ printf "%-19s%-19s%-7s%-14s%-14s%-16s%-9s%s\n",$8,$9,$4,$12,$15,$3,$1}'
160
+		echo -e
161
+	fi
162
+}
163
+
164
+status()
165
+{
166
+	interfaces
167
+	policies
168
+	rules
169
+}
170
+
171
+start()
172
+{
173
+	config_load mwan3
174
+	config_foreach ifup interface
175
+}
176
+
177
+stop()
178
+{
179
+	local route rule table
180
+
181
+	killall mwan3track &> /dev/null
182
+	rm /var/run/mwan3track-* &> /dev/null
183
+
184
+	for route in $(ip route list table all | sed 's/.*table \([^ ]*\) .*/\1/' |  awk '{print $1}' | awk '{for(i=1;i<=NF;i++) if($i+0>0) if($i+0<255) {print;break}}'); do
185
+		ip -4 route flush table $route &> /dev/null
186
+	done
187
+
188
+	for rule in $(ip -4 rule list | egrep '^[1-2][0-9]{3}\:' | cut -d ':' -f 1); do
189
+		ip -4 rule del pref $rule &> /dev/null
190
+	done
191
+
192
+	iptables -D PREROUTING -t mangle -j mwan3_hook &> /dev/null
193
+	iptables -D OUTPUT -t mangle -j mwan3_hook &> /dev/null
194
+	iptables -D OUTPUT -t mangle -j mwan3_track_hook &> /dev/null
195
+
196
+	for table in $(iptables -S -t mangle | awk '{print $2}' | grep mwan3 | sort -u); do
197
+		iptables -F $table -t mangle &> /dev/null
198
+	done
199
+
200
+	for table in $(iptables -S -t mangle | awk '{print $2}' | grep mwan3 | sort -u); do
201
+		iptables -X $table -t mangle &> /dev/null
202
+	done
203
+}
204
+
205
+restart() {
206
+	stop
207
+	start
208
+}

+ 65
- 0
net/mwan3/files/usr/sbin/mwan3track View File

@@ -0,0 +1,65 @@
1
+#!/bin/sh
2
+
3
+[ -z "$9" ] && echo "Error: should not be started manually" && exit 0
4
+
5
+if [ -e /var/run/mwan3track-$1.pid ] ; then
6
+	kill $(cat /var/run/mwan3track-$1.pid) &> /dev/null
7
+	rm /var/run/mwan3track-$1.pid &> /dev/null
8
+fi
9
+
10
+echo "$$" > /var/run/mwan3track-$1.pid
11
+
12
+score=$(($7+$8))
13
+track_ips=$(echo $* | cut -d ' ' -f 9-99)
14
+host_up_count=0
15
+lost=0
16
+
17
+while true; do
18
+
19
+	for track_ip in $track_ips; do
20
+		ping -I $2 -c $4 -W $5 -s 4 -q $track_ip &> /dev/null
21
+		if [ $? -eq 0 ]; then
22
+			let host_up_count++
23
+		else
24
+			let lost++
25
+		fi
26
+	done
27
+		
28
+	if [ $host_up_count -lt $3 ]; then
29
+		let score--
30
+
31
+		if [ $score -lt $8 ]; then score=0 ; fi
32
+		if [ $score -eq $8 ]; then
33
+
34
+			logger -t mwan3track -p notice "Interface $1 ($2) is offline"
35
+			env -i ACTION=ifdown INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface
36
+			score=0
37
+
38
+		fi
39
+
40
+	else
41
+
42
+		if [ $score -lt $(($7+$8)) ] && [ $lost -gt 0 ]; then
43
+
44
+			logger -t mwan3track -p info "Lost $(($lost*$4)) ping(s) on interface $1 ($2)"
45
+
46
+		fi
47
+
48
+		let score++
49
+		lost=0
50
+
51
+		if [ $score -gt $8 ]; then score=$(($7+$8)); fi
52
+		if [ $score -eq $8 ]; then
53
+
54
+			logger -t mwan3track -p notice "Interface $1 ($2) is online"
55
+			env -i ACTION=ifup INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface
56
+			rm /var/run/mwan3track-$1.pid
57
+			exit 0
58
+		fi
59
+	fi
60
+
61
+	host_up_count=0
62
+	sleep $6
63
+done
64
+
65
+exit 1