From 75878e8f3caad06c38b8916ea8b7aea3b116291a Mon Sep 17 00:00:00 2001 From: Florian Eckert Date: Wed, 22 Aug 2018 13:41:00 +0200 Subject: [PATCH] mwan3: add online_metric for ipsec failover The mwan3 with IPsec does not work in a failover scenario as expected. Because the default table is used for an lookup which traffic should be encrypt. The traffic for encryption is sent out on the interface with the lowest metric. No matter which interface is currently seen as connected by the mwan3. In order for this that mwan3 could work with IPsec, an additional metric is set that indicates which interface is currently connected. And the interface with the lowest 'online_metric' is used as the IPsec interface. If the interface is not considered connected by the mwan3, then the online_metric for this interface is not set and the next route with an higher metric is used. Signed-off-by: Florian Eckert --- net/mwan3/Makefile | 2 + net/mwan3/files/etc/hotplug.d/iface/13-mwan3 | 116 +++++++++++++++++++ net/mwan3/files/etc/init.d/mwan3 | 1 + net/mwan3/files/lib/mwan3/mwan3.sh | 22 ++++ 4 files changed, 141 insertions(+) create mode 100644 net/mwan3/files/etc/hotplug.d/iface/13-mwan3 diff --git a/net/mwan3/Makefile b/net/mwan3/Makefile index c3e486dbf8..2c0cd19cc0 100644 --- a/net/mwan3/Makefile +++ b/net/mwan3/Makefile @@ -76,6 +76,8 @@ define Package/mwan3/install $(1)/etc/config/ $(INSTALL_DIR) $(1)/etc/hotplug.d/iface + $(INSTALL_DATA) ./files/etc/hotplug.d/iface/13-mwan3 \ + $(1)/etc/hotplug.d/iface/ $(INSTALL_DATA) ./files/etc/hotplug.d/iface/15-mwan3 \ $(1)/etc/hotplug.d/iface/ $(INSTALL_DATA) ./files/etc/hotplug.d/iface/16-mwan3-user \ 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 0000000000..082c4fa51d --- /dev/null +++ b/net/mwan3/files/etc/hotplug.d/iface/13-mwan3 @@ -0,0 +1,116 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/functions/network.sh +. /lib/mwan3/mwan3.sh + +initscript=/etc/init.d/mwan3 +. /lib/functions/procd.sh + +logging() { + local level="$1" + local message="$2" + + logger -t "mwan3-hotplug[$$]" -p "daemon.${level}" "${message}" +} + +[ "$ACTION" = "connected" ] || [ "$ACTION" = "disconnected" ] || exit 1 +[ -n "$INTERFACE" ] || exit 2 + +if [ "$ACTION" = "connected" ]; then + [ -n "$DEVICE" ] || exit 3 +fi + +procd_lock + +config_load mwan3 +config_get enabled $INTERFACE enabled 0 +[ "$enabled" == "1" ] || { + exit 0 +} + +config_get online_metric $INTERFACE online_metric 0 +if [ "$online_metric" = 0 ]; then + logging 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 ret + + 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 + ret="$?" + if [ "$ret" -ne 0 ]; then + logging warn "Unable to set online metric for interface '$iface' (IPv4)" + else + logging info "Online metric for interface '$iface' set to '$metric' (IPv4)" + fi + 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 + if [ "$ret" -ne 0 ]; then + logging warn "Unable to set online metric for interface '$iface' (IPv6)" + else + logging info "Online metric for interface '$iface' set to '$metric' (IPv6)" + fi + 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/etc/init.d/mwan3 b/net/mwan3/files/etc/init.d/mwan3 index 33a1f46e53..df3dc830b6 100755 --- a/net/mwan3/files/etc/init.d/mwan3 +++ b/net/mwan3/files/etc/init.d/mwan3 @@ -59,6 +59,7 @@ stop_service() { mwan3_init config_foreach mwan3_interface_shutdown interface + config_foreach mwan3_online_metric_clean interface for family in ipv4 ipv6; do if [ "$family" = "ipv4" ]; then diff --git a/net/mwan3/files/lib/mwan3/mwan3.sh b/net/mwan3/files/lib/mwan3/mwan3.sh index f48a145cb6..6e1b53679c 100644 --- a/net/mwan3/files/lib/mwan3/mwan3.sh +++ b/net/mwan3/files/lib/mwan3/mwan3.sh @@ -1228,3 +1228,25 @@ mwan3_track_clean() rm -rf "${MWAN3_STATUS_DIR:?}/${1}" &> /dev/null rmdir --ignore-fail-on-non-empty "$MWAN3_STATUS_DIR" } + +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 +}