diff --git a/net/mwan3/Makefile b/net/mwan3/Makefile index 67a1a58f4..1ef345aac 100644 --- a/net/mwan3/Makefile +++ b/net/mwan3/Makefile @@ -8,8 +8,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mwan3 -PKG_VERSION:=2.8.4 -PKG_RELEASE:=2 +PKG_VERSION:=2.8.8 +PKG_RELEASE:=1 PKG_MAINTAINER:=Florian Eckert PKG_LICENSE:=GPL-2.0 diff --git a/net/mwan3/files/etc/init.d/mwan3 b/net/mwan3/files/etc/init.d/mwan3 index 2dccef363..af750e55e 100755 --- a/net/mwan3/files/etc/init.d/mwan3 +++ b/net/mwan3/files/etc/init.d/mwan3 @@ -1,20 +1,28 @@ #!/bin/sh /etc/rc.common START=19 - -reload() { - /usr/sbin/mwan3 restart -} +USE_PROCD=1 boot() { . /lib/config/uci.sh uci_toggle_state mwan3 globals enabled "1" + mwan3_boot=1 + rc_procd start_service } -start() { +reload_service() { + /usr/sbin/mwan3 restart +} + +start_service() { + [ -n "${mwan3_boot}" ] && return 0 /usr/sbin/mwan3 start } -stop() { +stop_service() { /usr/sbin/mwan3 stop } + +service_triggers() { + procd_add_reload_trigger 'mwan3' +} diff --git a/net/mwan3/files/lib/mwan3/mwan3.sh b/net/mwan3/files/lib/mwan3/mwan3.sh index 88159e8b9..64b07d658 100644 --- a/net/mwan3/files/lib/mwan3/mwan3.sh +++ b/net/mwan3/files/lib/mwan3/mwan3.sh @@ -39,14 +39,16 @@ mwan3_rtmon_ipv4() local tid=1 local idx=0 local ret=1 + local tbl="" mkdir -p /tmp/mwan3rtmon ($IP4 route list table main | grep -v "^default\|linkdown" | sort -n; echo empty fixup) >/tmp/mwan3rtmon/ipv4.main while uci get mwan3.@interface[$idx] >/dev/null 2>&1 ; do idx=$((idx+1)) tid=$idx [ "$(uci get mwan3.@interface[$((idx-1))].family)" = "ipv4" ] && { - if $IP4 route list table $tid | grep -q ^default; then - ($IP4 route list table $tid | grep -v "^default\|linkdown" | sort -n; echo empty fixup) >/tmp/mwan3rtmon/ipv4.$tid + tbl=$($IP4 route list table $tid) + if echo "$tbl" | grep -q ^default; then + (echo "$tbl" | grep -v "^default\|linkdown" | sort -n; echo empty fixup) >/tmp/mwan3rtmon/ipv4.$tid cat /tmp/mwan3rtmon/ipv4.$tid | grep -v -x -F -f /tmp/mwan3rtmon/ipv4.main | while read line; do $IP4 route del table $tid $line done @@ -70,14 +72,16 @@ mwan3_rtmon_ipv6() local tid=1 local idx=0 local ret=1 + local tbl="" mkdir -p /tmp/mwan3rtmon - ($IP6 route list table main | grep -v "^default\|^::/0\|^unreachable" | sort -n; echo empty fixup) >/tmp/mwan3rtmon/ipv6.main + ($IP6 route list table main | grep -v "^default\|^::/0\|^fe80::/64\|^unreachable" | sort -n; echo empty fixup) >/tmp/mwan3rtmon/ipv6.main while uci get mwan3.@interface[$idx] >/dev/null 2>&1 ; do idx=$((idx+1)) tid=$idx [ "$(uci get mwan3.@interface[$((idx-1))].family)" = "ipv6" ] && { - if $IP6 route list table $tid | grep -q "^default\|^::/0"; then - ($IP6 route list table $tid | grep -v "^default\|^::/0\|^unreachable" | sort -n; echo empty fixup) >/tmp/mwan3rtmon/ipv6.$tid + tbl=$($IP6 route list table $tid) + if echo "$tbl" | grep -q "^default\|^::/0"; then + (echo "$tbl" | grep -v "^default\|^::/0\|^unreachable" | sort -n; echo empty fixup) >/tmp/mwan3rtmon/ipv6.$tid cat /tmp/mwan3rtmon/ipv6.$tid | grep -v -x -F -f /tmp/mwan3rtmon/ipv6.main | while read line; do $IP6 route del table $tid $line done @@ -236,7 +240,7 @@ mwan3_set_custom_ipset() mwan3_set_connected_iptables() { - local connected_network_v4 connected_network_v6 + local connected_network_v4 connected_network_v6 source_network_v6 $IPS -! create mwan3_connected_v4 hash:net $IPS create mwan3_connected_v4_temp hash:net @@ -268,6 +272,14 @@ mwan3_set_connected_iptables() $IPS -! add mwan3_connected mwan3_connected_v4 $IPS -! add mwan3_connected mwan3_connected_v6 + $IPS -! create mwan3_source_v6 hash:net family inet6 + $IPS create mwan3_source_v6_temp hash:net family inet6 + for source_network_v6 in $($IP6 addr ls | sed -ne 's/ *inet6 \([^ \/]*\).* scope global.*/\1/p'); do + $IPS -! add mwan3_source_v6_temp $source_network_v6 + done + $IPS swap mwan3_source_v6_temp mwan3_source_v6 + $IPS destroy mwan3_source_v6_temp + $IPS -! create mwan3_dynamic_v4 hash:net $IPS -! add mwan3_connected mwan3_dynamic_v4 @@ -339,6 +351,13 @@ mwan3_set_general_iptables() -p ipv6-icmp \ -m icmp6 --icmpv6-type 137 \ -j RETURN + # do not mangle outgoing echo request + $IPT6 -A mwan3_hook \ + -m set --match-set mwan3_source_v6 src \ + -p ipv6-icmp \ + -m icmp6 --icmpv6-type 128 \ + -j RETURN + fi $IPT -A mwan3_hook \ -j CONNMARK --restore-mark --nfmask $MMX_MASK --ctmask $MMX_MASK @@ -862,8 +881,8 @@ mwan3_set_sticky_iptables() mwan3_set_user_iptables_rule() { - local ipset family proto policy src_ip src_port sticky dest_ip - local dest_port use_policy timeout rule policy IPT + local ipset family proto policy src_ip src_port src_iface src_dev + local sticky dest_ip dest_port use_policy timeout rule policy IPT local global_logging rule_logging loglevel rule="$1" @@ -872,13 +891,31 @@ mwan3_set_user_iptables_rule() config_get timeout $1 timeout 600 config_get ipset $1 ipset config_get proto $1 proto all - config_get src_ip $1 src_ip 0.0.0.0/0 - config_get src_port $1 src_port 0:65535 - config_get dest_ip $1 dest_ip 0.0.0.0/0 - config_get dest_port $1 dest_port 0:65535 + config_get src_ip $1 src_ip + config_get src_iface $1 src_iface + network_get_device src_dev $src_iface + config_get src_port $1 src_port + config_get dest_ip $1 dest_ip + config_get dest_port $1 dest_port config_get use_policy $1 use_policy config_get family $1 family any + [ -z "$dest_ip" ] && unset dest_ip + [ -z "$src_ip" ] && unset src_ip + [ -z "$ipset" ] && unset ipset + [ -z "$src_port" ] && unset src_port + [ -z "$dest_port" ] && unset dest_port + [ "$proto" != 'tcp' ] && [ "$proto" != 'udp' ] && { + [ -n "$src_port" ] && { + $LOG warn "src_port set to '$src_port' but proto set to '$proto' not tcp or udp. src_port will be ignored" + } + [ -n "$dest_port" ] && { + $LOG warn "dest_port set to '$dest_port' but proto set to '$proto' not tcp or udp. dest_port will be ignored" + } + unset src_port + unset dest_port + } + config_get rule_logging $1 logging 0 config_get global_logging globals logging 0 config_get loglevel globals loglevel notice @@ -951,144 +988,34 @@ mwan3_set_user_iptables_rule() fi fi + for IPT in "$IPT4" "$IPT6"; do + [ "$family" == "ipv4" ] && [ "$IPT" == "$IPT6" ] && continue + [ "$family" == "ipv6" ] && [ "$IPT" == "$IPT4" ] && continue + [ "$global_logging" = "1" ] && [ "$rule_logging" = "1" ] && { + $IPT -A mwan3_rules \ + -p $proto \ + ${src_ip:+-s} $src_ip \ + ${src_dev:+-i} $src_dev \ + ${dest_ip:+-d} $dest_ip\ + $ipset \ + ${src_port:+-m} ${src_port:+multiport} ${src_port:+--sports} $src_port \ + ${dest_port:+-m} ${dest_port:+multiport} ${dest_port:+--dports} $dest_port \ + -m mark --mark 0/$MMX_MASK \ + -m comment --comment "$1" \ + -j LOG --log-level "$loglevel" --log-prefix "MWAN3($1)" &> /dev/null + } - if [ "$family" == "any" ]; then - - for IPT in "$IPT4" "$IPT6"; do - case $proto in - tcp|udp) - [ "$global_logging" = "1" ] && [ "$rule_logging" = "1" ] && { - $IPT -A mwan3_rules \ - -p $proto \ - -s $src_ip \ - -d $dest_ip $ipset \ - -m multiport --sports $src_port \ - -m multiport --dports $dest_port \ - -m mark --mark 0/$MMX_MASK \ - -m comment --comment "$1" \ - -j LOG --log-level "$loglevel" --log-prefix "MWAN3($1)" &> /dev/null - } - $IPT -A mwan3_rules \ - -p $proto \ - -s $src_ip \ - -d $dest_ip $ipset \ - -m multiport --sports $src_port \ - -m multiport --dports $dest_port \ - -m mark --mark 0/$MMX_MASK \ - -m comment --comment "$1" \ - -j $policy &> /dev/null - ;; - *) - [ "$global_logging" = "1" ] && [ "$rule_logging" = "1" ] && { - $IPT -A mwan3_rules \ - -p $proto \ - -s $src_ip \ - -d $dest_ip $ipset \ - -m mark --mark 0/$MMX_MASK \ - -m comment --comment "$1" \ - -j LOG --log-level "$loglevel" --log-prefix "MWAN3($1)" &> /dev/null - } - $IPT -A mwan3_rules \ - -p $proto \ - -s $src_ip \ - -d $dest_ip $ipset \ - -m mark --mark 0/$MMX_MASK \ - -m comment --comment "$1" \ - -j $policy &> /dev/null - ;; - esac - done - - elif [ "$family" == "ipv4" ]; then - - case $proto in - tcp|udp) - [ "$global_logging" = "1" ] && [ "$rule_logging" = "1" ] && { - $IPT4 -A mwan3_rules \ - -p $proto \ - -s $src_ip \ - -d $dest_ip $ipset \ - -m multiport --sports $src_port \ - -m multiport --dports $dest_port \ - -m mark --mark 0/$MMX_MASK \ - -m comment --comment "$1" \ - -j LOG --log-level "$loglevel" --log-prefix "MWAN3($1)" &> /dev/null - } - $IPT4 -A mwan3_rules \ - -p $proto \ - -s $src_ip \ - -d $dest_ip $ipset \ - -m multiport --sports $src_port \ - -m multiport --dports $dest_port \ - -m mark --mark 0/$MMX_MASK \ - -m comment --comment "$1" \ - -j $policy &> /dev/null - ;; - *) - [ "$global_logging" = "1" ] && [ "$rule_logging" = "1" ] && { - $IPT4 -A mwan3_rules \ - -p $proto \ - -s $src_ip \ - -d $dest_ip $ipset \ - -m mark --mark 0/$MMX_MASK \ - -m comment --comment "$1" \ - -j LOG --log-level "$loglevel" --log-prefix "MWAN3($1)" &> /dev/null - } - $IPT4 -A mwan3_rules \ - -p $proto \ - -s $src_ip \ - -d $dest_ip $ipset \ - -m mark --mark 0/$MMX_MASK \ - -m comment --comment "$1" \ - -j $policy &> /dev/null - ;; - esac - - elif [ "$family" == "ipv6" ]; then - - case $proto in - tcp|udp) - [ "$global_logging" = "1" ] && [ "$rule_logging" = "1" ] && { - $IPT6 -A mwan3_rules \ - -p $proto \ - -s $src_ip \ - -d $dest_ip $ipset \ - -m multiport --sports $src_port \ - -m multiport --dports $dest_port \ - -m mark --mark 0/$MMX_MASK \ - -m comment --comment "$1" \ - -j LOG --log-level "$loglevel" --log-prefix "MWAN3($1)" &> /dev/null - } - $IPT6 -A mwan3_rules \ - -p $proto \ - -s $src_ip \ - -d $dest_ip $ipset \ - -m multiport --sports $src_port \ - -m multiport --dports $dest_port \ - -m mark --mark 0/$MMX_MASK \ - -m comment --comment "$1" \ - -j $policy &> /dev/null - ;; - *) - [ "$global_logging" = "1" ] && [ "$rule_logging" = "1" ] && { - $IPT6 -A mwan3_rules \ - -p $proto \ - -s $src_ip \ - -d $dest_ip $ipset \ - -m mark --mark 0/$MMX_MASK \ - -m comment --comment "$1" \ - -j LOG --log-level "$loglevel" --log-prefix "MWAN3($1)" &> /dev/null - } - $IPT6 -A mwan3_rules \ - -p $proto \ - -s $src_ip \ - -d $dest_ip $ipset \ - -m mark --mark 0/$MMX_MASK \ - -m comment --comment "$1" \ - -j $policy &> /dev/null - ;; - esac - fi + $IPT -A mwan3_rules \ + -p $proto \ + ${src_ip:+-s} $src_ip \ + ${src_dev:+-i} $src_dev \ + ${dest_ip:+-d} $dest_ip\ + $ipset \ + ${src_port:+-m} ${src_port:+multiport} ${src_port:+--sports} $src_port \ + ${dest_port:+-m} ${dest_port:+multiport} ${dest_port:+--dports} $dest_port \ + -m mark --mark 0/$MMX_MASK \ + -j $policy &> /dev/null + done fi } diff --git a/net/mwan3/files/usr/libexec/rpcd/mwan3 b/net/mwan3/files/usr/libexec/rpcd/mwan3 index b8b55212a..33e3e0284 100755 --- a/net/mwan3/files/usr/libexec/rpcd/mwan3 +++ b/net/mwan3/files/usr/libexec/rpcd/mwan3 @@ -77,7 +77,7 @@ get_mwan3_status() { local online=0 local offline=0 local up="0" - local enabled pid device time_p time_n time_u time_d + local enabled pid device time_p time_n time_u time_d status network_get_device device $1 @@ -111,6 +111,12 @@ get_mwan3_status() { network_get_uptime uptime "$iface" network_is_up "$iface" && up="1" + if [ -f "$MWAN3TRACK_STATUS_DIR/${iface}/STATUS" ]; then + status="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/STATUS")" + else + status="unknown" + fi + json_add_object "${iface}" json_add_int age "$age" json_add_int online "${online}" @@ -119,7 +125,7 @@ get_mwan3_status() { json_add_int "score" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/SCORE")" json_add_int "lost" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/LOST")" json_add_int "turn" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/TURN")" - json_add_string "status" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/STATUS")" + json_add_string "status" "${status}" json_add_boolean "enabled" "${enabled}" json_add_boolean "running" "${running}" json_add_boolean "up" "${up}" diff --git a/net/mwan3/files/usr/sbin/mwan3 b/net/mwan3/files/usr/sbin/mwan3 index b5ee29aea..a854dfda2 100755 --- a/net/mwan3/files/usr/sbin/mwan3 +++ b/net/mwan3/files/usr/sbin/mwan3 @@ -129,6 +129,7 @@ start() uci_toggle_state mwan3 globals enabled "1" + config_load mwan3 config_foreach ifup interface } diff --git a/net/mwan3/files/usr/sbin/mwan3track b/net/mwan3/files/usr/sbin/mwan3track index d60760f3c..e112475ce 100755 --- a/net/mwan3/files/usr/sbin/mwan3track +++ b/net/mwan3/files/usr/sbin/mwan3track @@ -6,6 +6,7 @@ LOG="logger -t $(basename "$0")[$$] -p" INTERFACE="" DEVICE="" +PING="/bin/ping" IFDOWN_EVENT=0 @@ -109,7 +110,10 @@ main() { 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 @@ -136,16 +140,21 @@ main() { # 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 's/ *inet6 \([^ \/]*\).* scope global.*/\1/p') + 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') + ping_protocol=6 fi if [ $check_quality -eq 0 ]; then - ping -I ${ADDR:-$DEVICE} -c $count -W $timeout -s $size -t $max_ttl -q $track_ip &> /dev/null + $PING -$ping_protocol -I ${ADDR:-$DEVICE} -c $count -W $timeout -s $size -t $max_ttl -q $track_ip &> /dev/null result=$? else - ping_result="$(ping -I ${ADDR:-$DEVICE} -c $count -W $timeout -s $size -t $max_ttl -q $track_ip | tail -2)" + 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_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/%//')" - if [ "$loss" -eq 100 ]; then + if [ "$ping_status" -ne 0 ] || [ "$loss" -eq 100 ]; then latency=999999 + loss=100 else latency="$(echo "$ping_result" | grep -E 'rtt|round-trip' | cut -d "=" -f2 | cut -d "/" -f2 | cut -d "." -f1)" fi