diff --git a/net/mwan3/Makefile b/net/mwan3/Makefile index e32882dd6..339cfb64a 100644 --- a/net/mwan3/Makefile +++ b/net/mwan3/Makefile @@ -8,8 +8,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mwan3 -PKG_VERSION:=2.6.1 -PKG_RELEASE:=1 +PKG_VERSION:=2.6.2 +PKG_RELEASE:=2 PKG_MAINTAINER:=Florian Eckert PKG_LICENSE:=GPLv2 @@ -39,6 +39,22 @@ endef define Build/Compile endef +define Package/mwan3/postinst +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/rpcd restart +fi +exit 0 +endef + +define Package/mwan3/postrm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/rpcd restart +fi +exit 0 +endef + define Package/mwan3/install $(CP) ./files/* $(1) endef diff --git a/net/mwan3/files/etc/hotplug.d/iface/14-mwan3 b/net/mwan3/files/etc/hotplug.d/iface/14-mwan3 new file mode 100644 index 000000000..1ddf0acca --- /dev/null +++ b/net/mwan3/files/etc/hotplug.d/iface/14-mwan3 @@ -0,0 +1,45 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/mwan3/mwan3.sh +. /lib/functions/network.sh + +[ "$ACTION" = "ifup" -o "$ACTION" = "ifdown" ] || exit 1 +[ -n "$INTERFACE" ] || exit 2 + +if [ "$ACTION" = "ifup" ]; then + [ -n "$DEVICE" ] || exit 3 +fi + +config_load mwan3 +config_get local_source globals local_source 'none' +[ "${local_source}" = "none" ] && { + exit 0 +} + +[ "${local_source}" = "$INTERFACE" ] || { + exit 0 +} + +mwan3_lock +src_ip=$(uci -q -P /var/state get mwan3.globals.src_ip 2>/dev/null) +[ "${src_ip}" != "" ] && { + ip route del default via "${src_ip}" dev lo 1>/dev/null 2>&1 + ip addr del "${src_ip}/32" dev lo 1>/dev/null 2>&1 +} + +usleep 10000 + +[ "$ACTION" = "ifup" ] && { + network_get_ipaddr src_ip "${local_source}" + if [ "${src_ip}" = "" ]; then + $LOG warn "Unable to set source ip for own initiated traffic (${local_source})" + else + ip addr add "${src_ip}/32" dev lo + ip route add default via "${src_ip}" dev lo + uci -q -P /var/state set mwan3.globals.src_ip="${src_ip}" + fi +} +mwan3_unlock + +exit 0 diff --git a/net/mwan3/files/etc/hotplug.d/iface/15-mwan3 b/net/mwan3/files/etc/hotplug.d/iface/15-mwan3 index d82fe01aa..f9638e62b 100644 --- a/net/mwan3/files/etc/hotplug.d/iface/15-mwan3 +++ b/net/mwan3/files/etc/hotplug.d/iface/15-mwan3 @@ -3,6 +3,7 @@ . /lib/functions.sh . /lib/functions/network.sh . /lib/mwan3/mwan3.sh +. /usr/share/libubox/jshn.sh [ "$ACTION" == "ifup" -o "$ACTION" == "ifdown" ] || exit 1 [ -n "$INTERFACE" ] || exit 2 @@ -11,10 +12,13 @@ if [ "$ACTION" == "ifup" ]; then [ -n "$DEVICE" ] || exit 3 fi +mwan3_lock mwan3_set_connected_iptables +mwan3_unlock config_load mwan3 config_get enabled $INTERFACE enabled 0 +config_get initial_state $INTERFACE initial_state "online" [ "$enabled" == "1" ] || exit 0 if [ "$ACTION" == "ifup" ]; then @@ -42,24 +46,39 @@ if [ "$ACTION" == "ifup" ]; then [ -n "$gateway" ] || exit 9 fi +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 +else + status=online + running=1 +fi + mwan3_lock -$LOG notice "$ACTION interface $INTERFACE (${DEVICE:-unknown})" +$LOG notice "Execute "$ACTION" event on interface $INTERFACE (${DEVICE:-unknown})" case "$ACTION" in ifup) mwan3_set_general_rules mwan3_set_general_iptables - mwan3_create_iface_rules $INTERFACE $DEVICE mwan3_create_iface_iptables $INTERFACE $DEVICE - mwan3_create_iface_route $INTERFACE $DEVICE - mwan3_track $INTERFACE $DEVICE ${src_ip} - mwan3_set_policies_iptables - mwan3_set_user_rules - mwan3_flush_conntrack $INTERFACE $DEVICE "ifup" + if [ ${running} -eq 1 -a "${status}" = "online" ]; then + mwan3_create_iface_rules $INTERFACE $DEVICE + mwan3_create_iface_route $INTERFACE $DEVICE + mwan3_track $INTERFACE $DEVICE ${src_ip} "online" + mwan3_set_policies_iptables + mwan3_set_user_rules + mwan3_flush_conntrack $INTERFACE $DEVICE "ifup" + else + $LOG notice "Starting tracker on interface $INTERFACE (${DEVICE:-unknown})" + mwan3_track $INTERFACE $DEVICE "offline" + fi ;; ifdown) mwan3_delete_iface_rules $INTERFACE - mwan3_delete_iface_iptables $INTERFACE mwan3_delete_iface_route $INTERFACE mwan3_delete_iface_ipset_entries $INTERFACE mwan3_track_signal $INTERFACE $DEVICE diff --git a/net/mwan3/files/lib/mwan3/mwan3.sh b/net/mwan3/files/lib/mwan3/mwan3.sh index 72091829b..43600568f 100644 --- a/net/mwan3/files/lib/mwan3/mwan3.sh +++ b/net/mwan3/files/lib/mwan3/mwan3.sh @@ -5,9 +5,11 @@ IP6="ip -6" IPS="ipset" IPT4="iptables -t mangle -w" IPT6="ip6tables -t mangle -w" -LOG="logger -t mwan3 -p" +LOG="logger -t mwan3[$$] -p" CONNTRACK_FILE="/proc/net/nf_conntrack" +MWAN3_STATUS_DIR="/var/run/mwan3track" + # mwan3's MARKing mask (at least 3 bits should be set) MMX_MASK=0xff00 @@ -65,6 +67,10 @@ mwan3_unlock() { lock -u /var/run/mwan3.lock } +mwan3_lock_clean() { + rm -rf /var/run/mwan3.lock +} + mwan3_get_iface_id() { local _tmp _iface _iface_count @@ -449,9 +455,9 @@ mwan3_track() } config_list_foreach $1 track_ip mwan3_list_track_ips - kill $(pgrep -f "mwan3track $1") &> /dev/null + kill $(pgrep -f "mwan3track $1 $2") &> /dev/null if [ -n "$track_ips" ]; then - [ -x /usr/sbin/mwan3track ] && /usr/sbin/mwan3track "$1" "$2" "$3" $track_ips & + [ -x /usr/sbin/mwan3track ] && /usr/sbin/mwan3track "$1" "$2" "$3" "$4" $track_ips & fi } @@ -459,7 +465,7 @@ mwan3_track_signal() { local pid - pid="$(pgrep -f "mwan3track $1")" + pid="$(pgrep -f "mwan3track $1 $2")" if [ "${pid}" != "" ]; then kill -USR1 "${pid}" else @@ -789,7 +795,7 @@ mwan3_report_iface_status() config_list_foreach $1 track_ip mwan3_list_track_ips if [ -n "$track_ips" ]; then - if [ -n "$(pgrep -f "mwan3track $1")" ]; then + if [ -n "$(pgrep -f "mwan3track $1 $device")" ]; then tracking="active" else tracking="down" @@ -919,3 +925,13 @@ mwan3_flush_conntrack() $LOG warning "connection tracking not enabled" fi } + +mwan3_track_clean() +{ + rm -rf "$MWAN3_STATUS_DIR/${1}" &> /dev/null + [ -d "$MWAN3_STATUS_DIR" ] && { + if [ -z "$(ls -A "$MWAN3_STATUS_DIR")" ]; then + rm -rf "$MWAN3_STATUS_DIR" + fi + } +} diff --git a/net/mwan3/files/usr/libexec/rpcd/mwan3 b/net/mwan3/files/usr/libexec/rpcd/mwan3 index bbc570f6c..8b7b14ea6 100755 --- a/net/mwan3/files/usr/libexec/rpcd/mwan3 +++ b/net/mwan3/files/usr/libexec/rpcd/mwan3 @@ -1,10 +1,10 @@ #!/bin/sh . /lib/functions.sh +. /lib/functions/network.sh . /usr/share/libubox/jshn.sh MWAN3_STATUS_DIR="/var/run/mwan3track" -MWAN3_PID_FILE="/var/run/mwan3track" IPS="ipset" IPT4="iptables -t mangle -w" @@ -34,18 +34,28 @@ get_mwan3_status() { local iface="${1}" local iface_select="${2}" local running="0" - local pid + local age=0 + local pid device time_p time_n + + network_get_device device $1 if [ "${iface}" = "${iface_select}" ] || [ "${iface_select}" = "" ]; then - pid="$(pgrep -f "mwan3track $iface_selected")" + pid="$(pgrep -f "mwan3track $iface $device")" if [ "${pid}" != "" ]; then running="1" fi + time_p="$(cat "$MWAN3_STATUS_DIR/${iface}/TIME")" + [ -z "${time_p}" ] || { + time_n="$(date +'%s')" + let age=time_n-time_p + } + json_add_object "${iface}" - json_add_string "score" "$(cat "$MWAN3_STATUS_DIR/${iface}/SCORE")" - json_add_string "lost" "$(cat "$MWAN3_STATUS_DIR/${iface}/LOST")" - json_add_string "turn" "$(cat "$MWAN3_STATUS_DIR/${iface}/TURN")" + json_add_int age "$age" + json_add_int "score" "$(cat "$MWAN3_STATUS_DIR/${iface}/SCORE")" + json_add_int "lost" "$(cat "$MWAN3_STATUS_DIR/${iface}/LOST")" + json_add_int "turn" "$(cat "$MWAN3_STATUS_DIR/${iface}/TURN")" json_add_string "status" "$(cat "$MWAN3_STATUS_DIR/${iface}/STATUS")" json_add_boolean "running" "${running}" json_add_array "track_ip" diff --git a/net/mwan3/files/usr/sbin/mwan3 b/net/mwan3/files/usr/sbin/mwan3 index f23d2e71b..1168ba37c 100755 --- a/net/mwan3/files/usr/sbin/mwan3 +++ b/net/mwan3/files/usr/sbin/mwan3 @@ -36,7 +36,9 @@ ifdown() ACTION=ifdown INTERFACE=$1 /sbin/hotplug-call iface - kill $(pgrep -f "mwan3track $1") &> /dev/null + kill $(pgrep -f "mwan3track $1 $2") &> /dev/null + mwan3_delete_iface_iptables $1 + mwan3_track_clean $1 } ifup() @@ -121,6 +123,9 @@ stop() killall mwan3track &> /dev/null + config_load mwan3 + config_foreach mwan3_track_clean interface + for IP in "$IP4" "$IP6"; do 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 @@ -153,6 +158,8 @@ stop() for ipset in $($IPS -n list | grep mwan3 | grep -E '_v4|_v6'); do $IPS -q destroy $ipset done + + mwan3_lock_clean } restart() { diff --git a/net/mwan3/files/usr/sbin/mwan3track b/net/mwan3/files/usr/sbin/mwan3track index d168578df..bdb793b59 100755 --- a/net/mwan3/files/usr/sbin/mwan3track +++ b/net/mwan3/files/usr/sbin/mwan3track @@ -10,12 +10,6 @@ IFDOWN_EVENT=0 clean_up() { $LOG notice "Stopping mwan3track for interface \"${INTERFACE}\"" - if [ "$(pgrep -f "mwan3track ${INTERFACE}")" = "" ]; then - rm -rf "/var/run/mwan3track/${INTERFACE}" &> /dev/null - fi - if [ -z "$(ls -A "/var/run/mwan3track")" ]; then - rm -rf "/var/run/mwan3track" - fi exit 0 } @@ -51,11 +45,13 @@ validate_track_method() { main() { local reliability count timeout interval failure_interval local recovery_interval down up size + local keep_failure_interval - [ -z "$3" ] && echo "Error: should not be started manually" && exit 0 + [ -z "$5" ] && echo "Error: should not be started manually" && exit 0 INTERFACE=$1 DEVICE=$2 + STATUS=$3 mkdir -p /var/run/mwan3track/$1 trap clean_up SIGINT SIGTERM trap if_down SIGUSR1 @@ -74,16 +70,22 @@ main() { config_get up $1 up 5 config_get size $1 size 56 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 local score=$(($down+$up)) - local track_ips=$(echo $* | cut -d ' ' -f 4-99) + local track_ips=$(echo $* | cut -d ' ' -f 5-99) local host_up_count=0 local lost=0 local sleep_time=0 local turn=0 - echo "offline" > /var/run/mwan3track/$1/STATUS + if [ "$STATUS" = "offline" ]; then + echo "offline" > /var/run/mwan3track/$1/STATUS + score=0 + else + echo "online" > /var/run/mwan3track/$1/STATUS + fi while true; do sleep_time=$interval @@ -111,6 +113,9 @@ main() { if [ $score -lt $up ]; then score=0 + [ ${keep_failure_interval} -eq 1 ] && { + sleep_time=$failure_interval + } else sleep_time=$failure_interval fi @@ -138,8 +143,8 @@ main() { 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 - rm -rf "/var/run/mwan3track/${1}" &> /dev/null exit 0 fi fi @@ -149,6 +154,7 @@ main() { echo "${lost}" > /var/run/mwan3track/$1/LOST echo "${score}" > /var/run/mwan3track/$1/SCORE echo "${turn}" > /var/run/mwan3track/$1/TURN + echo "$(date +'%s')" > /var/run/mwan3track/$1/TIME host_up_count=0 sleep "${sleep_time}" &