1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/usr/bin/pinger
#!/bin/sh
[ -z $1 ] && {
echo "Usage: $0 <interface>"
exit;
}
. /lib/config/uci.sh
. /lib/functions/network.sh
uci_add network defaultroute defaultroute
wan_led(){
. /lib/irz/led_utils.sh
local default_route_metric=$(ip route list | awk '/^default.*metric.*[0-9]+/{print $7}' | head -n 1)
[ -z "$default_route_metric" ]||[ "$default_route_metric" -gt 99 ] && led_solid_red WAN || led_solid_green WAN
}
network_device_interface() {
local ifname
ifname=$(cat /tmp/state/network | awk -F. "/ifname='$1'/{print \$2}")
[ -z "$ifname" ] && ifname=$(cat /tmp/state/network | awk -F. "/device='$1'/{print \$2}")
echo $ifname
}
network_current_defaultroute() {
local device
device=$(cat /proc/net/route | awk '/^[a-z0-9.-]+?\t00000000/{print $1}' | head -n1)
echo $(network_device_interface $device)
}
network_current_metric() {
local ifname
network_get_device ifname $1 || ifname=$1
echo $(cat /proc/net/route | awk '/^'$ifname'\t00000000\t/{print $7}' | head -n 1)
}
set_default_route(){
## $1 - device name
## $2 - default gateway
## $3 - new metric
local gateway addr default_route_interface_state default_route_interface_now device current_interface_metric
default_route_interface_state=$(uci_get_state network defaultroute interface)
current_interface_metric=$(network_current_metric $interface)
ip route del default dev $1
ip route add default dev $1 via $2 metric $3 2>&1 | grep -q 'File exists' && {
logger -t "pinger[$$]" "$interface: cannot add default route! check routes priorities"
ip route add default dev $1 via $2 metric 199
return 0
}
default_route_interface_now=$(network_current_defaultroute)
[ "$default_route_interface_state" != "$default_route_interface_now" ] && {
uci_toggle_state network defaultroute interface $default_route_interface_now
network_flush_cache
network_get_gateway gateway $default_route_interface_now
network_get_device device $default_route_interface_now
network_get_ipaddr addr $default_route_interface_now
ubus send defaultroute "{'ADDRESS': '$addr', 'DEVICE': '$device', 'INTERFACE': '$default_route_interface_now', 'GATEWAY': '$gateway', 'ACTION': 'change'}"
}
[ "$current_interface_metric" -lt "$3" ] && action=down
[ "$current_interface_metric" -gt "$3" ] && action=up
ubus send defaultroute "{'ACTION': '$action', 'INTERFACE': '$interface', 'DEVICE': '$1'}"
wan_led
}
interface=$1
address=$(uci -q get network.$interface.ping_ip)
interval=$(uci -q get network.$interface.ping_intvl || echo 30)
maxfail=$(uci -q get network.$interface.ping_maxfail || echo 3)
count=$(uci -q get network.$interface.ping_count || echo 4)
size=$(uci -q get network.$interface.ping_size || echo 32)
use_as_defaultroute=$(uci -q get network.$interface.defaultroute)
[ "$use_as_defaultroute" = "0" ] && use_as_defaultroute=""
fail_count=0
network_get_device devicename $interface
network_get_gateway default_gateway $interface
network_get_ipaddr iface_addr $interface
default_metric=$(uci -q get network.$interface.metric || echo 0)
[ -n "$use_as_defaultroute" ] && [ -z "$default_gateway" ] && exit 126
if [ -n $use_as_defaultroute -a $default_metric -le 99 ]; then
default_metric=$(( default_metric + 100 ))
uci set network.$interface.metric=$default_metric
uci commit network
fi
[ -n "$use_as_defaultroute" ] && worked_metric=$(( default_metric - 100 ))
[ -z $address ] && {
test -n "$use_as_defaultroute" && set_default_route "$devicename" "$default_gateway" "$worked_metric"
exit 127
}
[ -z $iface_addr ] && {
exit 128
}
logger -t "pinger[$$]" "$interface: ping-test started for $address via $iface_addr"
while true; do
ip link show dev $devicename 2>/dev/null | grep -q 'UP,' || exit 0
metric=$(network_current_metric $interface)
ping -c $count -s $size -q $address -I $iface_addr &>/dev/null
res=$?
if [ "$res" = "0" ]; then
[ -n "$use_as_defaultroute" ] && [ "$metric" != "$worked_metric" ] && {
logger -t "pinger[$$]" "$interface: ping-test successfull"
test -n "$use_as_defaultroute" && set_default_route "$devicename" "$default_gateway" "$worked_metric"
}
[ -z "$use_as_defaultroute" ] && [ "$fail_count" -gt 0 ] && {
logger -t "pinger[$$]" "$interface: ping-test successfull"
}
fail_count=0
else
[ -n "$use_as_defaultroute" ] && [ "$metric" != "$default_metric" ] && {
fail_count=0
logger -t "pinger[$$]" "$interface: ping-test fail"
test -n "$use_as_defaultroute" && set_default_route "$devicename" "$default_gateway" "$default_metric"
}
[ -z "$use_as_defaultroute" ] && [ "$fail_count" = "0" ] && {
logger -t "pinger[$$]" "$interface: ping-test fail"
}
fail_count=$(( fail_count + 1 ))
[ "$fail_count" -ge "$maxfail" ] && {
logger -t "pinger[$$]" "$interface: fail limit reached"
sh -c "(sleep 1;ifup $interface)&"
exit 0
# sh -c "(sleep 5;ifup $interface)&"
# ifdown $interface
# fail_count=0
}
fi
sleep $interval
done