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 <fe@dev.tdt.de>
This commit is contained in:
Florian Eckert 2018-08-22 13:41:00 +02:00
parent 723c4360c4
commit 75878e8f3c
4 changed files with 141 additions and 0 deletions

View File

@ -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 \

View File

@ -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

View File

@ -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

View File

@ -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
}