From 02ebd831c1247508ab5555ffa7dbfebe95e3501d Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Wed, 20 May 2020 05:33:06 -0400 Subject: [PATCH 1/8] mwan3: reduce calls to `ip route list' Signed-off-by: Aaron Goodman --- net/mwan3/files/lib/mwan3/mwan3.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/net/mwan3/files/lib/mwan3/mwan3.sh b/net/mwan3/files/lib/mwan3/mwan3.sh index 88159e8b9..1b09da337 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 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 From aafdd0730c765f32ed40c8f3b2ef11ec7cece3c0 Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Wed, 20 May 2020 05:33:41 -0400 Subject: [PATCH 2/8] mwan3: don't add ipv6 link local address to routing tables Signed-off-by: Aaron Goodman --- net/mwan3/files/lib/mwan3/mwan3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mwan3/files/lib/mwan3/mwan3.sh b/net/mwan3/files/lib/mwan3/mwan3.sh index 1b09da337..ce3fc4e90 100644 --- a/net/mwan3/files/lib/mwan3/mwan3.sh +++ b/net/mwan3/files/lib/mwan3/mwan3.sh @@ -74,7 +74,7 @@ mwan3_rtmon_ipv6() 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 From 35a86bdc119dda766801409a08e6d98dcf370c72 Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Wed, 20 May 2020 05:34:16 -0400 Subject: [PATCH 3/8] mwan3: force busybox ping openwrt 19.07 uses iputils 20101006-1 This ancient version of iputils has a bug where the -I option is not respected. https://github.com/iputils/iputils/issues/55 https://github.com/iputils/iputils/issues/56 https://bugs.openwrt.org/index.php?do=details&task_id=1486 Thus, we should force using busybox ping at "/bin/ping" until the iputils version gets an upgrade in the next major release Signed-off-by: Aaron Goodman --- net/mwan3/files/usr/sbin/mwan3track | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/net/mwan3/files/usr/sbin/mwan3track b/net/mwan3/files/usr/sbin/mwan3track index 136b3249c..f42e0ba54 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 @@ -137,15 +141,19 @@ main() { # 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') + 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 From b7d1f81f10302dc5b2de24e3e3d430770516ce45 Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Wed, 20 May 2020 05:42:14 -0400 Subject: [PATCH 4/8] mwan3: version bump to 2.8.6 Signed-off-by: Aaron Goodman --- net/mwan3/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mwan3/Makefile b/net/mwan3/Makefile index 0a2a4d297..8c7e849f6 100644 --- a/net/mwan3/Makefile +++ b/net/mwan3/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mwan3 -PKG_VERSION:=2.8.5 +PKG_VERSION:=2.8.6 PKG_RELEASE:=1 PKG_MAINTAINER:=Florian Eckert PKG_LICENSE:=GPL-2.0 From cf38136b005219917098a0562b0833fa28e007d7 Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Thu, 28 May 2020 18:27:59 -0400 Subject: [PATCH 5/8] mwan3: Do not mangle outgoing ipv6 pings Signed-off-by: Aaron Goodman --- net/mwan3/files/lib/mwan3/mwan3.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/net/mwan3/files/lib/mwan3/mwan3.sh b/net/mwan3/files/lib/mwan3/mwan3.sh index ce3fc4e90..e8044f76a 100644 --- a/net/mwan3/files/lib/mwan3/mwan3.sh +++ b/net/mwan3/files/lib/mwan3/mwan3.sh @@ -240,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 @@ -272,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 @@ -343,6 +351,12 @@ 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 From 5147dfc73aafd5b5accc6e480d51a639b000eac5 Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Thu, 28 May 2020 18:29:56 -0400 Subject: [PATCH 6/8] mwan3: Allow user to specify rules based on source interface Add an option for adding rules based on source interface. The default 0.0.0.0/0 src and destination ip addresses has been removed. It is unclear how the 'any' family of rules would have worked, as it appears each rule always required an ipv4 or ipv6 address src and destination address. With this change, the any family will work again. I also cleaned up a bunch of repeated code around adding the iptables rules for ipv4/ipv6/any in making the change. Signed-off-by: Aaron Goodman --- net/mwan3/files/lib/mwan3/mwan3.sh | 190 ++++++++--------------------- 1 file changed, 49 insertions(+), 141 deletions(-) diff --git a/net/mwan3/files/lib/mwan3/mwan3.sh b/net/mwan3/files/lib/mwan3/mwan3.sh index e8044f76a..1c30fea45 100644 --- a/net/mwan3/files/lib/mwan3/mwan3.sh +++ b/net/mwan3/files/lib/mwan3/mwan3.sh @@ -890,13 +890,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 @@ -969,144 +987,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 } From 4efaa44b213a9500a66c30b8c256138ef527dd97 Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Fri, 29 May 2020 01:04:57 -0400 Subject: [PATCH 7/8] mwan3: Use /128 for ipv6 if no other source address was found Signed-off-by: Aaron Goodman --- net/mwan3/files/usr/sbin/mwan3track | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mwan3/files/usr/sbin/mwan3track b/net/mwan3/files/usr/sbin/mwan3track index f42e0ba54..e112475ce 100755 --- a/net/mwan3/files/usr/sbin/mwan3track +++ b/net/mwan3/files/usr/sbin/mwan3track @@ -140,7 +140,8 @@ 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 '/\/128/d' -e '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 From 38be40843b97ca3af9ebe37aae8ebfda7b6af65c Mon Sep 17 00:00:00 2001 From: Aaron Goodman Date: Sat, 13 Jun 2020 15:25:42 -0400 Subject: [PATCH 8/8] mwan3: address reviewer comments on 5147dfc7 Signed-off-by: Aaron Goodman --- net/mwan3/files/lib/mwan3/mwan3.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/net/mwan3/files/lib/mwan3/mwan3.sh b/net/mwan3/files/lib/mwan3/mwan3.sh index 1c30fea45..64b07d658 100644 --- a/net/mwan3/files/lib/mwan3/mwan3.sh +++ b/net/mwan3/files/lib/mwan3/mwan3.sh @@ -353,9 +353,10 @@ mwan3_set_general_iptables() -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 + -m set --match-set mwan3_source_v6 src \ + -p ipv6-icmp \ + -m icmp6 --icmpv6-type 128 \ + -j RETURN fi $IPT -A mwan3_hook \ @@ -880,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"