mwan3: improve startup performance; version 2.9.0
improve startup and runtime performance by 1) moving common startup procedures out of hotplug script when called from mwan3 start 2) reducing calls to iptables to check status of rules 3) consolidating iptables updates and updating with iptables-restore 4) do not wait for kill if nothing was killed 5) running interface hotplug scripts in parallel 6) eliminate operations in hotplug script that check status on every single interface unnecessarily 7) consolidate how mwan3track makes hotplug calls 8) do not restart mwan3track on connected events This is a significant refactor, but should not result in any breaking changes or require users to update their configurations. version bump to 2.9.0 Signed-off-by: Aaron Goodman <aaronjg@stanford.edu>
This commit is contained in:
parent
39f58789e6
commit
c07f5230be
9 changed files with 730 additions and 580 deletions
|
@ -8,8 +8,8 @@
|
|||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=mwan3
|
||||
PKG_VERSION:=2.8.12
|
||||
PKG_RELEASE:=2
|
||||
PKG_VERSION:=2.9.0
|
||||
PKG_RELEASE:=1
|
||||
PKG_MAINTAINER:=Florian Eckert <fe@dev.tdt.de>
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
|
|
|
@ -4,96 +4,101 @@
|
|||
. /lib/functions/network.sh
|
||||
. /lib/mwan3/mwan3.sh
|
||||
. /usr/share/libubox/jshn.sh
|
||||
. /lib/mwan3/common.sh
|
||||
|
||||
[ "$ACTION" == "ifup" -o "$ACTION" == "ifdown" ] || exit 1
|
||||
SCRIPTNAME="mwan3-hotplug"
|
||||
[ "$ACTION" = "ifup" ] || [ "$ACTION" = "ifdown" ] || [ "$ACTION" = "connected" ] || [ "$ACTION" = "disconnected" ] || exit 1
|
||||
[ -n "$INTERFACE" ] || exit 2
|
||||
|
||||
if [ "$ACTION" == "ifup" ]; then
|
||||
[ -n "$DEVICE" ] || exit 3
|
||||
if ( [ "$ACTION" = "ifup" ] || [ "$ACTION" = "connected" ] ) && [ -z "$DEVICE" ]; then
|
||||
LOG notice "$ACTION called on $INTERFACE with no device set"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
mwan3_lock "$ACTION" "$INTERFACE"
|
||||
[ "$MWAN3_STARTUP" = 1 ] || mwan3_lock "$ACTION" "$INTERFACE"
|
||||
|
||||
config_load mwan3
|
||||
config_get_bool enabled globals 'enabled' '0'
|
||||
[ "${enabled}" -gt 0 ] || {
|
||||
mwan3_unlock "$ACTION" "$INTERFACE"
|
||||
[ "$MWAN3_STARTUP" = 1 ] || mwan3_unlock "$ACTION" "$INTERFACE"
|
||||
LOG notice "mwan3 hotplug on $INTERFACE not called because globally disabled"
|
||||
mwan3_flush_conntrack "$INTERFACE" "$ACTION"
|
||||
exit 0
|
||||
}
|
||||
|
||||
$IPT4 -S mwan3_hook &>/dev/null || {
|
||||
mwan3_unlock "$ACTION" "$INTERFACE"
|
||||
LOG warn "hotplug called on $INTERFACE before mwan3 has been set up"
|
||||
exit 0
|
||||
}
|
||||
|
||||
mwan3_init
|
||||
mwan3_set_connected_iptables
|
||||
mwan3_set_custom_ipset
|
||||
[ "$MWAN3_STARTUP" = 1 ] || {
|
||||
mwan3_set_connected_iptables
|
||||
mwan3_set_custom_ipset
|
||||
}
|
||||
|
||||
if [ "$MWAN3_STARTUP" != 1 ]; then
|
||||
mwan3_set_user_iface_rules $INTERFACE $DEVICE
|
||||
fi
|
||||
|
||||
config_get initial_state $INTERFACE initial_state "online"
|
||||
config_get_bool enabled $INTERFACE 'enabled' '0'
|
||||
[ "${enabled}" -eq 1 ] || {
|
||||
mwan3_unlock "$ACTION" "$INTERFACE"
|
||||
[ "$MWAN3_STARTUP" = 1 ] || mwan3_unlock "$ACTION" "$INTERFACE"
|
||||
LOG notice "mwan3 hotplug on $INTERFACE not called because interface disabled"
|
||||
exit 0
|
||||
}
|
||||
|
||||
if [ "$ACTION" = "ifup" ]; then
|
||||
config_get family $INTERFACE family ipv4
|
||||
if [ "$family" = "ipv4" ]; then
|
||||
ubus call network.interface.${INTERFACE}_4 status &>/dev/null
|
||||
if [ "$?" -eq "0" ]; then
|
||||
network_get_ipaddr src_ip ${INTERFACE}_4
|
||||
else
|
||||
network_get_ipaddr src_ip ${INTERFACE}
|
||||
fi
|
||||
[ -n "$src_ip" ] || src_ip="0.0.0.0"
|
||||
elif [ "$family" = "ipv6" ]; then
|
||||
ubus call network.interface.${INTERFACE}_6 status &>/dev/null
|
||||
if [ "$?" -eq "0" ]; then
|
||||
network_get_ipaddr6 src_ip ${INTERFACE}_6
|
||||
else
|
||||
network_get_ipaddr6 src_ip ${INTERFACE}
|
||||
fi
|
||||
[ -n "$src_ip" ] || src_ip="::"
|
||||
fi
|
||||
fi
|
||||
trackpid=$(pgrep -f "mwan3track $INTERFACE ")
|
||||
|
||||
if [ "$initial_state" = "offline" ]; then
|
||||
json_load "$(ubus call mwan3 status '{"section":"interfaces"}')"
|
||||
json_select "interfaces"
|
||||
json_select "${INTERFACE}"
|
||||
json_get_var running running
|
||||
json_get_var status status
|
||||
status=$(cat $MWAN3TRACK_STATUS_DIR/$INTERFACE/STATUS 2>/dev/null || echo unknown)
|
||||
else
|
||||
status=online
|
||||
running=1
|
||||
fi
|
||||
|
||||
$LOG notice "Execute "$ACTION" event on interface $INTERFACE (${DEVICE:-unknown})"
|
||||
[ -z "$TRUE_INTERFACE" ] && mwan3_get_true_iface TRUE_INTERFACE $INTERFACE
|
||||
|
||||
binary_status=$status
|
||||
[ "$binary_status" = "online" ] || binary_status=offline
|
||||
|
||||
LOG notice "Execute "$ACTION" event on interface $INTERFACE (${DEVICE:-unknown})"
|
||||
|
||||
case "$ACTION" in
|
||||
ifup)
|
||||
mwan3_set_general_rules
|
||||
mwan3_set_general_iptables
|
||||
ifup|connected)
|
||||
mwan3_create_iface_iptables $INTERFACE $DEVICE
|
||||
mwan3_create_iface_rules $INTERFACE $DEVICE
|
||||
mwan3_create_iface_route $INTERFACE $DEVICE
|
||||
if [ "${running}" -eq 1 ] && [ "${status}" = "online" ]; then
|
||||
$LOG notice "Starting tracker on interface $INTERFACE (${DEVICE:-unknown})"
|
||||
mwan3_set_iface_hotplug_state $INTERFACE "online"
|
||||
mwan3_track $INTERFACE $DEVICE "online" "$src_ip"
|
||||
[ "$MWAN3_STARTUP" != 1 ] && mwan3_add_non_default_iface_route $INTERFACE $DEVICE
|
||||
mwan3_set_iface_hotplug_state $INTERFACE "$binary_status"
|
||||
|
||||
mwan3_get_src_ip src_ip "$TRUE_INTERFACE"
|
||||
if [ -n "${trackpid}" ]; then
|
||||
device_pid=$(pgrep -f "mwan3track $INTERFACE $DEVICE ")
|
||||
if [ "$device_pid" = "$trackpid" ]; then
|
||||
[ "$ACTION" = ifup ] && kill -USR2 "$trackpid"
|
||||
else
|
||||
mwan3_track $INTERFACE $DEVICE "$binary_status" "$src_ip"
|
||||
LOG notice "Restarted tracker [$!] on interface $INTERFACE (${DEVICE:-unknown})"
|
||||
fi
|
||||
else
|
||||
$LOG notice "Starting tracker on interface $INTERFACE (${DEVICE:-unknown})"
|
||||
mwan3_set_iface_hotplug_state $INTERFACE "offline"
|
||||
mwan3_track $INTERFACE $DEVICE "offline" "$src_ip"
|
||||
mwan3_track $INTERFACE $DEVICE "$binary_status" "$src_ip"
|
||||
LOG notice "Started tracker [$!] on interface $INTERFACE (${DEVICE:-unknown})"
|
||||
fi
|
||||
mwan3_set_policies_iptables
|
||||
mwan3_set_user_rules
|
||||
[ "$MWAN3_STARTUP" != 1 ] && [ "$binary_status" == "online" ] && mwan3_set_policies_iptables
|
||||
|
||||
;;
|
||||
ifdown)
|
||||
ifdown|disconnected)
|
||||
mwan3_set_iface_hotplug_state $INTERFACE "offline"
|
||||
mwan3_delete_iface_ipset_entries $INTERFACE
|
||||
mwan3_track_signal $INTERFACE $DEVICE
|
||||
mwan3_delete_iface_rules $INTERFACE
|
||||
mwan3_delete_iface_route $INTERFACE
|
||||
mwan3_delete_iface_iptables $INTERFACE
|
||||
if [ "$ACTION" = "ifdown" ]; then
|
||||
[ -n "$trackpid" ] && kill -USR1 "$trackpid"
|
||||
fi
|
||||
mwan3_set_policies_iptables
|
||||
mwan3_set_user_rules
|
||||
;;
|
||||
esac
|
||||
|
||||
mwan3_unlock "$ACTION" "$INTERFACE"
|
||||
|
||||
[ "$MWAN3_STARTUP" = 1 ] || mwan3_unlock "$ACTION" "$INTERFACE"
|
||||
exit 0
|
||||
|
|
|
@ -4,22 +4,22 @@
|
|||
. /lib/functions.sh
|
||||
. /lib/mwan3/mwan3.sh
|
||||
|
||||
mwan3_lock "$ACTION" "user"
|
||||
[ "$MWAN3_STARTUP" = 1 ] || mwan3_lock "$ACTION" "$DEVICE-user"
|
||||
|
||||
config_load mwan3
|
||||
config_get_bool enabled globals 'enabled' '0'
|
||||
[ "${enabled}" -gt 0 ] || {
|
||||
mwan3_unlock "$ACTION" "user"
|
||||
[ "$MWAN3_STARTUP" = 1 ] || mwan3_unlock "$ACTION" "$DEVICE-user"
|
||||
exit 0
|
||||
}
|
||||
|
||||
config_get_bool enabled "$INTERFACE" enabled 0
|
||||
[ "${enabled}" -eq 1 ] || {
|
||||
mwan3_unlock "$ACTION" "user"
|
||||
[ "$MWAN3_STARTUP" = 1 ] || mwan3_unlock "$ACTION" "$DEVICE-user"
|
||||
exit 0
|
||||
}
|
||||
|
||||
mwan3_unlock "$ACTION" "user"
|
||||
[ "$MWAN3_STARTUP" = 1 ] || mwan3_unlock "$ACTION" "$DEVICE-user"
|
||||
|
||||
env -i ACTION="$ACTION" INTERFACE="$INTERFACE" DEVICE="$DEVICE" \
|
||||
/bin/sh /etc/mwan3.user
|
||||
|
|
|
@ -5,8 +5,9 @@ USE_PROCD=1
|
|||
|
||||
boot() {
|
||||
. /lib/config/uci.sh
|
||||
uci_toggle_state mwan3 globals enabled "1"
|
||||
mwan3_boot=1
|
||||
# disabled until mwan3 start runs so hotplug scripts
|
||||
# do not start prematurely
|
||||
uci_toggle_state mwan3 globals enabled "0"
|
||||
rc_procd start_service
|
||||
}
|
||||
|
||||
|
@ -20,7 +21,6 @@ reload_service() {
|
|||
}
|
||||
|
||||
start_service() {
|
||||
[ -n "${mwan3_boot}" ] && return 0
|
||||
/usr/sbin/mwan3 start 1000>&-
|
||||
}
|
||||
|
||||
|
|
|
@ -4,3 +4,14 @@ get_uptime() {
|
|||
local uptime=$(cat /proc/uptime)
|
||||
echo "${uptime%%.*}"
|
||||
}
|
||||
|
||||
SCRIPTNAME="$(basename "$0")"
|
||||
LOG()
|
||||
{
|
||||
local facility=$1; shift
|
||||
# in development, we want to show 'debug' level logs
|
||||
# when this release is out of beta, the comment in the line below
|
||||
# should be removed
|
||||
[ "$facility" = "debug" ] && return
|
||||
logger -t "$SCRIPTNAME[$$]" -p $facility "$*"
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4,6 +4,7 @@
|
|||
. /usr/share/libubox/jshn.sh
|
||||
. /lib/functions/network.sh
|
||||
. /lib/mwan3/mwan3.sh
|
||||
. /lib/mwan3/common.sh
|
||||
|
||||
help()
|
||||
{
|
||||
|
@ -37,52 +38,64 @@ ifdown()
|
|||
|
||||
ACTION=ifdown INTERFACE=$1 /sbin/hotplug-call iface
|
||||
|
||||
kill $(pgrep -f "mwan3track $1 $2") &> /dev/null
|
||||
kill $(pgrep -f "mwan3track $1 ") &> /dev/null
|
||||
mwan3_track_clean $1
|
||||
}
|
||||
|
||||
ifup()
|
||||
{
|
||||
local device enabled up l3_device status
|
||||
|
||||
mwan3_lock "command" "mwan3"
|
||||
|
||||
config_load mwan3
|
||||
config_get_bool enabled globals 'enabled' 0
|
||||
|
||||
[ ${enabled} -gt 0 ] || {
|
||||
echo "The service mwan3 is global disabled."
|
||||
echo "Please execute \"/etc/init.d/mwan3 start\" first."
|
||||
mwan3_unlock "command" "mwan3"
|
||||
exit 1
|
||||
}
|
||||
local device enabled up l3_device status interface true_iface
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Expecting interface. Usage: mwan3 ifup <interface>"
|
||||
mwan3_unlock "command" "mwan3"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -n "$2" ]; then
|
||||
echo "Too many arguments. Usage: mwan3 ifup <interface>"
|
||||
mwan3_unlock "command" "mwan3"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
config_get enabled "$1" enabled 0
|
||||
mwan3_unlock "command" "mwan3"
|
||||
interface=$1
|
||||
|
||||
if [ "${MWAN3_STARTUP}" != 1 ]; then
|
||||
# It is not necessary to obtain a lock here, because it is obtained in the hotplug
|
||||
# script, but we still want to do the check to print a useful error message
|
||||
config_load mwan3
|
||||
config_get_bool enabled globals 'enabled' 0
|
||||
|
||||
[ ${enabled} -gt 0 ] || {
|
||||
echo "The service mwan3 is global disabled."
|
||||
echo "Please execute \"/etc/init.d/mwan3 start\" first."
|
||||
exit 1
|
||||
}
|
||||
else
|
||||
enabled=1
|
||||
fi
|
||||
mwan3_get_true_iface true_iface $interface
|
||||
status=$(ubus -S call network.interface.$true_iface status)
|
||||
|
||||
status=$(ubus -S call network.interface.$1 status)
|
||||
[ -n "$status" ] && {
|
||||
json_load "$status"
|
||||
json_get_vars up l3_device
|
||||
}
|
||||
hotplug_startup()
|
||||
{
|
||||
MWAN3_STARTUP=$MWAN3_STARTUP ACTION=ifup INTERFACE=$interface DEVICE=$l3_device TRUE_INTERFACE=$true_iface sh /etc/hotplug.d/iface/15-mwan3
|
||||
MWAN3_STARTUP=$MWAN3_STARTUP ACTION=ifup INTERFACE=$interface DEVICE=$l3_device TRUE_INTERFACE=$true_iface sh /etc/hotplug.d/iface/16-mwan3-user
|
||||
}
|
||||
|
||||
if [ "$up" = "1" ] \
|
||||
&& [ -n "$l3_device" ] \
|
||||
&& [ "$enabled" = "1" ]; then
|
||||
ACTION=ifup INTERFACE=$1 DEVICE=$l3_device /sbin/hotplug-call iface
|
||||
if [ "$up" != "1" ] || [ -z "$l3_device" ] || [ "$enabled" != "1" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "${MWAN3_STARTUP}" = 1 ]; then
|
||||
hotplug_startup &
|
||||
hotplug_pids="$hotplug_pids $!"
|
||||
else
|
||||
hotplug_startup
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
interfaces()
|
||||
|
@ -137,58 +150,78 @@ status()
|
|||
|
||||
start()
|
||||
{
|
||||
local enabled
|
||||
|
||||
local enabled hotplug_pids MWAN3_STARTUP
|
||||
MWAN3_STARTUP=1
|
||||
mwan3_lock "command" "mwan3"
|
||||
uci_toggle_state mwan3 globals enabled "1"
|
||||
mwan3_unlock "command" "mwan3"
|
||||
|
||||
config_load mwan3
|
||||
|
||||
mwan3_update_iface_to_table
|
||||
mwan3_set_connected_iptables
|
||||
mwan3_set_custom_ipset
|
||||
mwan3_set_general_rules
|
||||
mwan3_set_general_iptables
|
||||
config_foreach ifup interface
|
||||
wait $hotplug_pids
|
||||
mwan3_add_all_nondefault_routes
|
||||
mwan3_set_policies_iptables
|
||||
mwan3_set_user_rules
|
||||
|
||||
|
||||
mwan3_unlock "command" "mwan3"
|
||||
mwan3_rtmon
|
||||
unset MWAN3_STARTUP
|
||||
}
|
||||
|
||||
stop()
|
||||
{
|
||||
local ipset route rule table IP IPT pid
|
||||
local ipset rule IP IPTR IPT kill_pid family table tid
|
||||
|
||||
mwan3_lock "command" "mwan3"
|
||||
uci_toggle_state mwan3 globals enabled "0"
|
||||
|
||||
kill -TERM $(pgrep -f "mwan3rtmon") > /dev/null 2>&1
|
||||
kill -TERM $(pgrep -f "mwan3track") > /dev/null 2>&1
|
||||
{
|
||||
kill -TERM $(pgrep -f "mwan3rtmon") > /dev/null 2>&1
|
||||
kill -TERM $(pgrep -f "mwan3track") > /dev/null 2>&1
|
||||
|
||||
sleep 1
|
||||
|
||||
kill -KILL $(pgrep -f "mwan3rtmon") > /dev/null 2>&1
|
||||
kill -KILL $(pgrep -f "mwan3track") > /dev/null 2>&1
|
||||
sleep 1
|
||||
|
||||
kill -KILL $(pgrep -f "mwan3rtmon") > /dev/null 2>&1
|
||||
kill -KILL $(pgrep -f "mwan3track") > /dev/null 2>&1
|
||||
} &
|
||||
kill_pid=$!
|
||||
config_load mwan3
|
||||
config_foreach mwan3_track_clean interface
|
||||
|
||||
for IP in "$IP4" "$IP6"; do
|
||||
[ "$IP" = "$IP6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
||||
for route in $(seq 1 $MWAN3_INTERFACE_MAX); do
|
||||
$IP route flush table $route &> /dev/null
|
||||
for family in ipv4 ipv6; do
|
||||
if [ "$family" = "ipv4" ]; then
|
||||
IPT="$IPT4"
|
||||
IPTR="$IPT4R"
|
||||
IP="$IP4"
|
||||
elif [ "$family" = "ipv6" ]; then
|
||||
[ $NO_IPV6 -ne 0 ] && continue
|
||||
IPT="$IPT6"
|
||||
IPTR="$IPT6R"
|
||||
IP="$IP6"
|
||||
fi
|
||||
|
||||
for tid in $(ip route list table all | sed -ne 's/.*table \([0-9]\+\).*/\1/p'|sort -u); do
|
||||
[ $tid -gt $MWAN3_INTERFACE_MAX ] && continue
|
||||
$IP route flush table $tid &> /dev/null
|
||||
done
|
||||
|
||||
for rule in $($IP rule list | egrep '^[1-2][0-9]{3}\:' | cut -d ':' -f 1); do
|
||||
$IP rule del pref $rule &> /dev/null
|
||||
done
|
||||
done
|
||||
|
||||
for IPT in "$IPT4" "$IPT6"; do
|
||||
[ "$IPT" = "$IPT6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
||||
$IPT -D PREROUTING -j mwan3_hook &> /dev/null
|
||||
$IPT -D OUTPUT -j mwan3_hook &> /dev/null
|
||||
|
||||
for table in $($IPT -S | awk '{print $2}' | grep mwan3 | sort -u); do
|
||||
$IPT -F $table &> /dev/null
|
||||
done
|
||||
|
||||
for table in $($IPT -S | awk '{print $2}' | grep mwan3 | sort -u); do
|
||||
$IPT -X $table &> /dev/null
|
||||
done
|
||||
table="$($IPT -S)"
|
||||
{
|
||||
echo "*mangle";
|
||||
[ -z "${table##*PREROUTING -j mwan3_hook*}" ] && echo "-D PREROUTING -j mwan3_hook"
|
||||
[ -z "${table##*OUTPUT -j mwan3_hook*}" ] && echo "-D OUTPUT -j mwan3_hook"
|
||||
echo "$table" | awk '{print "-F "$2}' | grep mwan3 | sort -u
|
||||
echo "$table" | awk '{print "-X "$2}' | grep mwan3 | sort -u
|
||||
echo "COMMIT"
|
||||
} | $IPTR
|
||||
done
|
||||
|
||||
for ipset in $($IPS -n list | grep mwan3_); do
|
||||
|
@ -199,9 +232,19 @@ stop()
|
|||
$IPS -q destroy $ipset
|
||||
done
|
||||
|
||||
if ! pgrep -f "mwan3track" >/dev/null && ! pgrep -f "mwan3rtmon" >/dev/null; then
|
||||
# mwan3track has already exited, no need to send
|
||||
# TERM signal
|
||||
kill $kill_pid 2>/dev/null
|
||||
else
|
||||
# mwan3track has not exited, wait for the killer
|
||||
# to do its work
|
||||
wait $kill_pid
|
||||
fi
|
||||
rm -rf $MWAN3_STATUS_DIR $MWAN3TRACK_STATUS_DIR
|
||||
|
||||
mwan3_unlock "command" "mwan3"
|
||||
|
||||
rm -rf $MWAN3_STATUS_DIR $MWAN3TRACK_STATUS_DIR
|
||||
}
|
||||
|
||||
restart() {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#!/bin/sh
|
||||
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. /lib/mwan3/mwan3.sh
|
||||
|
||||
. /lib/mwan3/common.sh
|
||||
|
||||
mwan3_rtmon_route_handle()
|
||||
{
|
||||
|
|
|
@ -3,60 +3,107 @@
|
|||
. /lib/functions.sh
|
||||
. /lib/mwan3/common.sh
|
||||
|
||||
LOG="logger -t $(basename "$0")[$$] -p"
|
||||
INTERFACE=""
|
||||
DEVICE=""
|
||||
PING="/bin/ping"
|
||||
|
||||
IFDOWN_EVENT=0
|
||||
IFUP_EVENT=0
|
||||
|
||||
clean_up() {
|
||||
$LOG notice "Stopping mwan3track for interface \"${INTERFACE}\""
|
||||
LOG notice "Stopping mwan3track for interface \"${INTERFACE}\""
|
||||
exit 0
|
||||
}
|
||||
|
||||
if_down() {
|
||||
$LOG info "Detect ifdown event on interface ${INTERFACE} (${DEVICE})"
|
||||
LOG info "Detect ifdown event on interface ${INTERFACE} (${DEVICE})"
|
||||
IFDOWN_EVENT=1
|
||||
}
|
||||
|
||||
if_up() {
|
||||
LOG info "Detect ifup event on interface ${INTERFACE} (${DEVICE})"
|
||||
IFUP_EVENT=1
|
||||
}
|
||||
|
||||
validate_track_method() {
|
||||
case "$1" in
|
||||
ping)
|
||||
command -v ping 1>/dev/null 2>&1 || {
|
||||
$LOG warn "Missing ping. Please install iputils-ping package or enable ping util and recompile busybox."
|
||||
[ -x "$PING" ] || {
|
||||
LOG warn "Missing ping. Please enable ping util and recompile busybox."
|
||||
return 1
|
||||
}
|
||||
;;
|
||||
arping)
|
||||
command -v arping 1>/dev/null 2>&1 || {
|
||||
$LOG warn "Missing arping. Please install iputils-arping package."
|
||||
LOG warn "Missing arping. Please install iputils-arping package."
|
||||
return 1
|
||||
}
|
||||
;;
|
||||
httping)
|
||||
command -v httping 1>/dev/null 2>&1 || {
|
||||
$LOG warn "Missing httping. Please install httping package."
|
||||
LOG warn "Missing httping. Please install httping package."
|
||||
return 1
|
||||
}
|
||||
[ -n "$2" -a "$2" != "0.0.0.0" -a "$2" != "::" ] || {
|
||||
$LOG warn "Cannot determine source IP for the interface which is required by httping."
|
||||
LOG warn "Cannot determine source IP for the interface which is required by httping."
|
||||
return 1
|
||||
}
|
||||
;;
|
||||
nping-*)
|
||||
command -v nping 1>/dev/null 2>&1 || {
|
||||
$LOG warn "Missing nping. Please install nping package."
|
||||
LOG warn "Missing nping. Please install nping package."
|
||||
return 1
|
||||
}
|
||||
;;
|
||||
*)
|
||||
$LOG warn "Unsupported tracking method: $track_method"
|
||||
LOG warn "Unsupported tracking method: $track_method"
|
||||
return 2
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
disconnected() {
|
||||
echo "offline" > /var/run/mwan3track/$INTERFACE/STATUS
|
||||
echo "$(get_uptime)" > /var/run/mwan3track/$INTERFACE/OFFLINE
|
||||
echo "0" > /var/run/mwan3track/$INTERFACE/ONLINE
|
||||
score=0
|
||||
[ "$1" == 1 ] && return
|
||||
LOG notice "Interface $INTERFACE ($DEVICE) is offline"
|
||||
env -i ACTION="disconnected" INTERFACE="$INTERFACE" DEVICE="$DEVICE" /sbin/hotplug-call iface
|
||||
}
|
||||
|
||||
connected() {
|
||||
echo "online" > /var/run/mwan3track/$INTERFACE/STATUS
|
||||
echo "0" > /var/run/mwan3track/$INTERFACE/OFFLINE
|
||||
echo "$(get_uptime)" > /var/run/mwan3track/$INTERFACE/ONLINE
|
||||
host_up_count=0
|
||||
lost=0
|
||||
turn=0
|
||||
loss=0
|
||||
[ "$1" == 1 ] && return
|
||||
LOG notice "Interface $INTERFACE ($DEVICE) is online"
|
||||
env -i ACTION="connected" INTERFACE="$INTERFACE" DEVICE="$DEVICE" /sbin/hotplug-call iface
|
||||
}
|
||||
|
||||
firstconnect() {
|
||||
if [ "$STATUS" = "offline" ]; then
|
||||
disconnected 1
|
||||
else
|
||||
connected 1
|
||||
fi
|
||||
}
|
||||
|
||||
update_status() {
|
||||
local status track_ip
|
||||
track_ip=$1
|
||||
status=$2
|
||||
|
||||
echo "$1" > /var/run/mwan3track/$INTERFACE/TRACK_${track_ip}
|
||||
[ -z "$3" ] && return
|
||||
echo "$3" > /var/run/mwan3track/$INTERFACE/LATENCY_${track_ip}
|
||||
echo "$4" > /var/run/mwan3track/$INTERFACE/LOSS_${track_ip}
|
||||
}
|
||||
|
||||
main() {
|
||||
local reliability count timeout interval failure_interval
|
||||
local recovery_interval down up size
|
||||
|
@ -70,64 +117,49 @@ main() {
|
|||
DEVICE=$2
|
||||
STATUS=$3
|
||||
SRC_IP=$4
|
||||
mkdir -p /var/run/mwan3track/$1
|
||||
mkdir -p /var/run/mwan3track/$INTERFACE
|
||||
trap clean_up TERM
|
||||
trap if_down USR1
|
||||
trap if_up USR2
|
||||
|
||||
config_load mwan3
|
||||
config_get track_method $1 track_method ping
|
||||
config_get_bool httping_ssl $1 httping_ssl 0
|
||||
config_get track_method $INTERFACE track_method ping
|
||||
config_get_bool httping_ssl $INTERFACE httping_ssl 0
|
||||
validate_track_method $track_method $SRC_IP || {
|
||||
track_method=ping
|
||||
if validate_track_method $track_method; then
|
||||
$LOG warn "Using ping to track interface $INTERFACE avaliability"
|
||||
LOG warn "Using ping to track interface $INTERFACE avaliability"
|
||||
else
|
||||
$LOG err "No track method avaliable"
|
||||
LOG err "No track method avaliable"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
config_get reliability $1 reliability 1
|
||||
config_get count $1 count 1
|
||||
config_get timeout $1 timeout 4
|
||||
config_get interval $1 interval 10
|
||||
config_get down $1 down 5
|
||||
config_get up $1 up 5
|
||||
config_get size $1 size 56
|
||||
config_get max_ttl $1 max_ttl 60
|
||||
config_get failure_interval $1 failure_interval $interval
|
||||
config_get_bool keep_failure_interval $1 keep_failure_interval 0
|
||||
config_get recovery_interval $1 recovery_interval $interval
|
||||
config_get_bool check_quality $1 check_quality 0
|
||||
config_get failure_latency $1 failure_latency 1000
|
||||
config_get recovery_latency $1 recovery_latency 500
|
||||
config_get failure_loss $1 failure_loss 40
|
||||
config_get recovery_loss $1 recovery_loss 10
|
||||
config_get reliability $INTERFACE reliability 1
|
||||
config_get count $INTERFACE count 1
|
||||
config_get timeout $INTERFACE timeout 4
|
||||
config_get interval $INTERFACE interval 10
|
||||
config_get down $INTERFACE down 5
|
||||
config_get up $INTERFACE up 5
|
||||
config_get size $INTERFACE size 56
|
||||
config_get max_ttl $INTERFACE max_ttl 60
|
||||
config_get failure_interval $INTERFACE failure_interval $interval
|
||||
config_get_bool keep_failure_interval $INTERFACE keep_failure_interval 0
|
||||
config_get recovery_interval $INTERFACE recovery_interval $interval
|
||||
config_get_bool check_quality $INTERFACE check_quality 0
|
||||
config_get failure_latency $INTERFACE failure_latency 1000
|
||||
config_get recovery_latency $INTERFACE recovery_latency 500
|
||||
config_get failure_loss $INTERFACE failure_loss 40
|
||||
config_get recovery_loss $INTERFACE recovery_loss 10
|
||||
|
||||
local score=$(($down+$up))
|
||||
local track_ips=$(echo $* | cut -d ' ' -f 5-99)
|
||||
local host_up_count=0
|
||||
local lost=0
|
||||
local sleep_time=0
|
||||
local turn=0
|
||||
local result
|
||||
local ping_protocol=4
|
||||
local ping_result
|
||||
local ping_result_raw
|
||||
local ping_status
|
||||
local loss=0
|
||||
local latency=0
|
||||
local sleep_time result ping_result ping_result_raw ping_status loss latency
|
||||
|
||||
if [ "$STATUS" = "offline" ]; then
|
||||
echo "offline" > /var/run/mwan3track/$1/STATUS
|
||||
echo "0" > /var/run/mwan3track/$1/ONLINE
|
||||
echo "$(get_uptime)" > /var/run/mwan3track/$1/OFFLINE
|
||||
score=0
|
||||
else
|
||||
echo "online" > /var/run/mwan3track/$1/STATUS
|
||||
echo "0" > /var/run/mwan3track/$1/OFFLINE
|
||||
echo "$(get_uptime)" > /var/run/mwan3track/$1/ONLINE
|
||||
env -i ACTION="connected" INTERFACE="$1" DEVICE="$2" /sbin/hotplug-call iface
|
||||
fi
|
||||
firstconnect
|
||||
while true; do
|
||||
|
||||
sleep_time=$interval
|
||||
|
@ -139,16 +171,16 @@ main() {
|
|||
# pinging IPv6 hosts with an interface is troublesome
|
||||
# https://bugs.openwrt.org/index.php?do=details&task_id=2897
|
||||
# so get the IP address of the interface and use that instead
|
||||
if echo $track_ip | grep -q ':'; then
|
||||
ADDR=$(ip -6 addr ls dev "$DEVICE" | sed -ne '/\/128/d' -e 's/ *inet6 \([^ \/]*\).* scope global.*/\1/p' | head -n1)
|
||||
[ -z "$ADDR" ] && ADDR=$(ip -6 addr ls dev "$DEVICE" | sed -ne 's/ *inet6 \([^ \/]*\).* scope global.*/\1/p')
|
||||
if [ -z ${track_ip##*:*} ]; then
|
||||
ping_protocol=6
|
||||
else
|
||||
unset SRC_IP
|
||||
fi
|
||||
if [ $check_quality -eq 0 ]; then
|
||||
$PING -$ping_protocol -I ${ADDR:-$DEVICE} -c $count -W $timeout -s $size -t $max_ttl -q $track_ip &> /dev/null
|
||||
$PING -$ping_protocol -I ${SRC_IP:-$DEVICE} -c $count -W $timeout -s $size -t $max_ttl -q $track_ip &> /dev/null
|
||||
result=$?
|
||||
else
|
||||
ping_result_raw="$($PING -$ping_protocol -I ${ADDR:-$DEVICE} -c $count -W $timeout -s $size -t $max_ttl -q $track_ip 2>/dev/null)"
|
||||
ping_result_raw="$($PING -$ping_protocol -I ${SRC_IP:-$DEVICE} -c $count -W $timeout -s $size -t $max_ttl -q $track_ip 2>/dev/null)"
|
||||
ping_status=$?
|
||||
ping_result=$(echo "$ping_result_raw" | tail -n2)
|
||||
loss="$(echo "$ping_result" | grep "packet loss" | cut -d "," -f3 | awk '{print $1}' | sed -e 's/%//')"
|
||||
|
@ -188,42 +220,40 @@ main() {
|
|||
if [ $check_quality -eq 0 ]; then
|
||||
if [ $result -eq 0 ]; then
|
||||
let host_up_count++
|
||||
echo "up" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
||||
update_status "$track_ip" "up"
|
||||
|
||||
if [ $score -le $up ]; then
|
||||
$LOG info "Check ($track_method) success for target \"$track_ip\" on interface $1 ($2)"
|
||||
LOG info "Check ($track_method) success for target \"$track_ip\" on interface $INTERFACE ($DEVICE). Current score: $score"
|
||||
fi
|
||||
else
|
||||
let lost++
|
||||
echo "down" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
||||
update_status "$track_ip" "down"
|
||||
|
||||
if [ $score -gt $up ]; then
|
||||
$LOG info "Check ($track_method) failed for target \"$track_ip\" on interface $1 ($2)"
|
||||
LOG info "Check ($track_method) failed for target \"$track_ip\" on interface $INTERFACE ($DEVICE). Current score: $score"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if [ "$loss" -ge "$failure_loss" -o "$latency" -ge "$failure_latency" ]; then
|
||||
let lost++
|
||||
echo "down" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
||||
echo "$latency" > /var/run/mwan3track/$1/LATENCY_${track_ip}
|
||||
echo "$loss" > /var/run/mwan3track/$1/LOSS_${track_ip}
|
||||
update_status "$track_ip" "down" $latency $loss
|
||||
|
||||
if [ $score -gt $up ]; then
|
||||
$LOG info "Check (${track_method}: latency=${latency}ms loss=${loss}%) failed for target \"$track_ip\" on interface $1 ($2)"
|
||||
LOG info "Check (${track_method}: latency=${latency}ms loss=${loss}%) failed for target \"$track_ip\" on interface $INTERFACE ($DEVICE). Current score: $score"
|
||||
fi
|
||||
elif [ "$loss" -le "$recovery_loss" -a "$latency" -le "$recovery_latency" ]; then
|
||||
let host_up_count++
|
||||
echo "up" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
||||
echo "$latency" > /var/run/mwan3track/$1/LATENCY_${track_ip}
|
||||
echo "$loss" > /var/run/mwan3track/$1/LOSS_${track_ip}
|
||||
update_status "$track_ip" "up" $latency $loss
|
||||
|
||||
if [ $score -le $up ]; then
|
||||
$LOG info "Check (${track_method}: latency=${latency}ms loss=${loss}%) success for target \"$track_ip\" on interface $1 ($2)"
|
||||
LOG info "Check (${track_method}: latency=${latency}ms loss=${loss}%) success for target \"$track_ip\" on interface $INTERFACE ($DEVICE). Current score: $score"
|
||||
fi
|
||||
else
|
||||
echo "skipped" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
||||
echo "skipped" > /var/run/mwan3track/$INTERFACE/TRACK_${track_ip}
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "skipped" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
||||
echo "skipped" > /var/run/mwan3track/$INTERFACE/TRACK_${track_ip}
|
||||
fi
|
||||
done
|
||||
|
||||
|
@ -240,53 +270,50 @@ main() {
|
|||
fi
|
||||
|
||||
if [ $score -eq $up ]; then
|
||||
echo "offline" > /var/run/mwan3track/$1/STATUS
|
||||
env -i ACTION=ifdown INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface
|
||||
disconnected
|
||||
score=0
|
||||
fi
|
||||
else
|
||||
if [ $score -lt $(($down+$up)) ] && [ $lost -gt 0 ]; then
|
||||
$LOG info "Lost $(($lost*$count)) ping(s) on interface $1 ($2)"
|
||||
LOG info "Lost $(($lost*$count)) ping(s) on interface $INTERFACE ($DEVICE). Current score: $score"
|
||||
fi
|
||||
|
||||
let score++
|
||||
lost=0
|
||||
|
||||
if [ $score -gt $up ]; then
|
||||
echo "online" > /var/run/mwan3track/$1/STATUS
|
||||
echo "online" > /var/run/mwan3track/$INTERFACE/STATUS
|
||||
score=$(($down+$up))
|
||||
elif [ $score -le $up ]; then
|
||||
sleep_time=$recovery_interval
|
||||
fi
|
||||
|
||||
if [ $score -eq $up ]; then
|
||||
$LOG notice "Interface $1 ($2) is online"
|
||||
echo "online" > /var/run/mwan3track/$1/STATUS
|
||||
env -i ACTION=ifup INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface
|
||||
exit 0
|
||||
connected $INTERFACE $DEVICE
|
||||
fi
|
||||
fi
|
||||
|
||||
let turn++
|
||||
mkdir -p "/var/run/mwan3track/${1}"
|
||||
echo "${lost}" > /var/run/mwan3track/$1/LOST
|
||||
echo "${score}" > /var/run/mwan3track/$1/SCORE
|
||||
echo "${turn}" > /var/run/mwan3track/$1/TURN
|
||||
echo "$(get_uptime)" > /var/run/mwan3track/$1/TIME
|
||||
echo "${lost}" > /var/run/mwan3track/$INTERFACE/LOST
|
||||
echo "${score}" > /var/run/mwan3track/$INTERFACE/SCORE
|
||||
echo "${turn}" > /var/run/mwan3track/$INTERFACE/TURN
|
||||
echo "$(get_uptime)" > /var/run/mwan3track/$INTERFACE/TIME
|
||||
|
||||
host_up_count=0
|
||||
sleep "${sleep_time}" &
|
||||
wait
|
||||
|
||||
if [ "${IFDOWN_EVENT}" -eq 1 ]; then
|
||||
echo "offline" > /var/run/mwan3track/$1/STATUS
|
||||
echo "$(get_uptime)" > /var/run/mwan3track/$1/OFFLINE
|
||||
echo "0" > /var/run/mwan3track/$1/ONLINE
|
||||
$LOG notice "Interface $1 ($2) is offline"
|
||||
env -i ACTION="disconnected" INTERFACE="$1" DEVICE="$2" /sbin/hotplug-call iface
|
||||
score=0
|
||||
LOG debug "Register ifdown event on interface ${INTERFACE} (${DEVICE})"
|
||||
disconnected 1
|
||||
IFDOWN_EVENT=0
|
||||
fi
|
||||
if [ "${IFUP_EVENT}" -eq 1 ]; then
|
||||
LOG debug "Register ifup event on interface ${INTERFACE} (${DEVICE})"
|
||||
firstconnect
|
||||
IFUP_EVENT=0
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue