From be91e71805116ac1fd852a1ac0480737538d0b04 Mon Sep 17 00:00:00 2001 From: Florian Eckert Date: Wed, 22 Aug 2018 13:41:00 +0200 Subject: [PATCH] net/mwan3: add online_metric for local_source none If we set the option "local_source" in the globals mwan3 section to "none", traffic generated by the router it self will always use the default route from the wan interface with the lowest metric. If this interface is down the router traffic still uses the connection with the lowest metric but this is disconnected. Load balancing and failover from the lan site is still possible. Only router generated traffic is not load balanced and could not use failover. To solve this issue with router initiated traffic add the additional option "online_metric" to the mwan3 interface section. If the interface is connected then this lower "online metric" is set in the default routing table. With this change we have at least a failover with router initiated traffic. Signed-off-by: Florian Eckert --- net/mwan3/files/etc/hotplug.d/iface/13-mwan3 | 98 ++++++++++++++++++++ net/mwan3/files/lib/mwan3/mwan3.sh | 22 +++++ net/mwan3/files/usr/sbin/mwan3 | 1 + 3 files changed, 121 insertions(+) create mode 100644 net/mwan3/files/etc/hotplug.d/iface/13-mwan3 diff --git a/net/mwan3/files/etc/hotplug.d/iface/13-mwan3 b/net/mwan3/files/etc/hotplug.d/iface/13-mwan3 new file mode 100644 index 000000000..c21e1db98 --- /dev/null +++ b/net/mwan3/files/etc/hotplug.d/iface/13-mwan3 @@ -0,0 +1,98 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/functions/network.sh +. /lib/mwan3/mwan3.sh + +LOG="logger -t mwan3[$$] -p" + +[ "$ACTION" = "connected" -o "$ACTION" = "disconnected" ] || exit 1 +[ -n "$INTERFACE" ] || exit 2 + +if [ "$ACTION" = "connected" ]; then + [ -n "$DEVICE" ] || exit 3 +fi + +config_load mwan3 +config_get_bool enabled globals 'enabled' '0' +config_get local_source globals 'local_source' 'none' +[ ${enabled} = "1" ] || exit 0 +[ ${local_source} = "none" ] || exit 0 + +config_get enabled $INTERFACE enabled 0 +config_get online_metric $INTERFACE online_metric 0 +[ "$enabled" == "1" ] || exit 0 + +if [ "$online_metric" = 0 ]; then + $LOG notice "No online metric for interface "$INTERFACE" found" + exit 0 +fi + +mwan3_add_failover_metric() { + local iface="$1" + local device="$2" + local metric="$3" + + local route_args + + config_get family $iface family ipv4 + + if [ "$family" == "ipv4" ]; then + if ubus call network.interface.${iface}_4 status 1>/dev/null 2>&1; then + network_get_gateway route_args ${iface}_4 + else + network_get_gateway route_args $iface + fi + + if [ -n "$route_args" -a "$route_args" != "0.0.0.0" ]; then + route_args="via $route_args" + else + route_args="" + fi + + $IP4 route add default $route_args dev $device proto static metric $metric 1>/dev/null 2>&1 + fi + + if [ "$family" == "ipv6" ]; then + if ubus call network.interface.${iface}_6 status 1>/dev/null 2>&1; then + network_get_gateway6 route_args ${iface}_6 + else + network_get_gateway6 route_args $iface + fi + + if [ -n "$route_args" -a "$route_args" != "::" ]; then + route_args="via $route_args" + else + route_args="" + fi + + $IP6 route add default $route_args dev $device proto static metric $metric 1>/dev/null 2>&1 + fi +} + +mwan3_del_failover_metric() { + local iface="$1" + local device="$2" + local metric="$3" + + config_get family $iface family ipv4 + + if [ "$family" == "ipv4" ]; then + $IP4 route del default dev $device proto static metric $metric 1>/dev/null 2>&1 + fi + + if [ "$family" == "ipv6" ]; then + $IP6 route del default dev $device proto static metric $metric 1>/dev/null 2>&1 + fi +} + +case "$ACTION" in + connected) + mwan3_add_failover_metric "$INTERFACE" "$DEVICE" "$online_metric" + ;; + disconnected) + mwan3_del_failover_metric "$INTERFACE" "$DEVICE" "$online_metric" + ;; +esac + +exit 0 diff --git a/net/mwan3/files/lib/mwan3/mwan3.sh b/net/mwan3/files/lib/mwan3/mwan3.sh index 89ef06841..42e08beb9 100644 --- a/net/mwan3/files/lib/mwan3/mwan3.sh +++ b/net/mwan3/files/lib/mwan3/mwan3.sh @@ -1219,3 +1219,25 @@ mwan3_track_clean() fi } } + +mwan3_online_metric_clean() { + local iface="$1" + + local online_metric ifname + + config_get family $iface family ipv4 + config_get online_metric $iface online_metric "" + ifname=$(uci_get_state network $iface ifname) + + if [ "$family" == "ipv4" ] \ + && [ "$online_metric" != "" ] \ + && [ "$ifname" != "" ]; then + $IP4 route del default dev $ifname proto static metric $online_metric 1>/dev/null 2>&1 + fi + + if [ "$family" == "ipv6" ] \ + && [ "$online_metric" != "" ] \ + && [ "$ifname" != "" ]; then + $IP6 route del default dev $ifname proto static metric $online_metric 1>/dev/null 2>&1 + fi +} diff --git a/net/mwan3/files/usr/sbin/mwan3 b/net/mwan3/files/usr/sbin/mwan3 index 4ad3bc391..139da3d25 100755 --- a/net/mwan3/files/usr/sbin/mwan3 +++ b/net/mwan3/files/usr/sbin/mwan3 @@ -175,6 +175,7 @@ stop() config_load mwan3 config_foreach mwan3_track_clean interface + config_foreach mwan3_online_metric_clean interface for IP in "$IP4" "$IP6"; do