mwan3: improve startup performance; version 2.9.0
improve startup and runtime performance by 1) moving common startup procedures out of hotplug script when called from mwan3 start 2) reducing calls to iptables to check status of rules 3) consolidating iptables updates and updating with iptables-restore 4) do not wait for kill if nothing was killed 5) running interface hotplug scripts in parallel 6) eliminate operations in hotplug script that check status on every single interface unnecessarily 7) consolidate how mwan3track makes hotplug calls 8) do not restart mwan3track on connected events This is a significant refactor, but should not result in any breaking changes or require users to update their configurations. version bump to 2.9.0 Signed-off-by: Aaron Goodman <aaronjg@stanford.edu>
This commit is contained in:
parent
39f58789e6
commit
c07f5230be
9 changed files with 730 additions and 580 deletions
|
@ -8,8 +8,8 @@
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=mwan3
|
PKG_NAME:=mwan3
|
||||||
PKG_VERSION:=2.8.12
|
PKG_VERSION:=2.9.0
|
||||||
PKG_RELEASE:=2
|
PKG_RELEASE:=1
|
||||||
PKG_MAINTAINER:=Florian Eckert <fe@dev.tdt.de>
|
PKG_MAINTAINER:=Florian Eckert <fe@dev.tdt.de>
|
||||||
PKG_LICENSE:=GPL-2.0
|
PKG_LICENSE:=GPL-2.0
|
||||||
|
|
||||||
|
|
|
@ -4,96 +4,101 @@
|
||||||
. /lib/functions/network.sh
|
. /lib/functions/network.sh
|
||||||
. /lib/mwan3/mwan3.sh
|
. /lib/mwan3/mwan3.sh
|
||||||
. /usr/share/libubox/jshn.sh
|
. /usr/share/libubox/jshn.sh
|
||||||
|
. /lib/mwan3/common.sh
|
||||||
|
|
||||||
[ "$ACTION" == "ifup" -o "$ACTION" == "ifdown" ] || exit 1
|
SCRIPTNAME="mwan3-hotplug"
|
||||||
|
[ "$ACTION" = "ifup" ] || [ "$ACTION" = "ifdown" ] || [ "$ACTION" = "connected" ] || [ "$ACTION" = "disconnected" ] || exit 1
|
||||||
[ -n "$INTERFACE" ] || exit 2
|
[ -n "$INTERFACE" ] || exit 2
|
||||||
|
if ( [ "$ACTION" = "ifup" ] || [ "$ACTION" = "connected" ] ) && [ -z "$DEVICE" ]; then
|
||||||
if [ "$ACTION" == "ifup" ]; then
|
LOG notice "$ACTION called on $INTERFACE with no device set"
|
||||||
[ -n "$DEVICE" ] || exit 3
|
exit 3
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mwan3_lock "$ACTION" "$INTERFACE"
|
[ "$MWAN3_STARTUP" = 1 ] || mwan3_lock "$ACTION" "$INTERFACE"
|
||||||
|
|
||||||
config_load mwan3
|
config_load mwan3
|
||||||
config_get_bool enabled globals 'enabled' '0'
|
config_get_bool enabled globals 'enabled' '0'
|
||||||
[ "${enabled}" -gt 0 ] || {
|
[ "${enabled}" -gt 0 ] || {
|
||||||
mwan3_unlock "$ACTION" "$INTERFACE"
|
[ "$MWAN3_STARTUP" = 1 ] || mwan3_unlock "$ACTION" "$INTERFACE"
|
||||||
|
LOG notice "mwan3 hotplug on $INTERFACE not called because globally disabled"
|
||||||
mwan3_flush_conntrack "$INTERFACE" "$ACTION"
|
mwan3_flush_conntrack "$INTERFACE" "$ACTION"
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$IPT4 -S mwan3_hook &>/dev/null || {
|
||||||
|
mwan3_unlock "$ACTION" "$INTERFACE"
|
||||||
|
LOG warn "hotplug called on $INTERFACE before mwan3 has been set up"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
mwan3_init
|
mwan3_init
|
||||||
|
[ "$MWAN3_STARTUP" = 1 ] || {
|
||||||
mwan3_set_connected_iptables
|
mwan3_set_connected_iptables
|
||||||
mwan3_set_custom_ipset
|
mwan3_set_custom_ipset
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$MWAN3_STARTUP" != 1 ]; then
|
||||||
|
mwan3_set_user_iface_rules $INTERFACE $DEVICE
|
||||||
|
fi
|
||||||
|
|
||||||
config_get initial_state $INTERFACE initial_state "online"
|
config_get initial_state $INTERFACE initial_state "online"
|
||||||
config_get_bool enabled $INTERFACE 'enabled' '0'
|
config_get_bool enabled $INTERFACE 'enabled' '0'
|
||||||
[ "${enabled}" -eq 1 ] || {
|
[ "${enabled}" -eq 1 ] || {
|
||||||
mwan3_unlock "$ACTION" "$INTERFACE"
|
[ "$MWAN3_STARTUP" = 1 ] || mwan3_unlock "$ACTION" "$INTERFACE"
|
||||||
|
LOG notice "mwan3 hotplug on $INTERFACE not called because interface disabled"
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ "$ACTION" = "ifup" ]; then
|
trackpid=$(pgrep -f "mwan3track $INTERFACE ")
|
||||||
config_get family $INTERFACE family ipv4
|
|
||||||
if [ "$family" = "ipv4" ]; then
|
|
||||||
ubus call network.interface.${INTERFACE}_4 status &>/dev/null
|
|
||||||
if [ "$?" -eq "0" ]; then
|
|
||||||
network_get_ipaddr src_ip ${INTERFACE}_4
|
|
||||||
else
|
|
||||||
network_get_ipaddr src_ip ${INTERFACE}
|
|
||||||
fi
|
|
||||||
[ -n "$src_ip" ] || src_ip="0.0.0.0"
|
|
||||||
elif [ "$family" = "ipv6" ]; then
|
|
||||||
ubus call network.interface.${INTERFACE}_6 status &>/dev/null
|
|
||||||
if [ "$?" -eq "0" ]; then
|
|
||||||
network_get_ipaddr6 src_ip ${INTERFACE}_6
|
|
||||||
else
|
|
||||||
network_get_ipaddr6 src_ip ${INTERFACE}
|
|
||||||
fi
|
|
||||||
[ -n "$src_ip" ] || src_ip="::"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$initial_state" = "offline" ]; then
|
if [ "$initial_state" = "offline" ]; then
|
||||||
json_load "$(ubus call mwan3 status '{"section":"interfaces"}')"
|
status=$(cat $MWAN3TRACK_STATUS_DIR/$INTERFACE/STATUS 2>/dev/null || echo unknown)
|
||||||
json_select "interfaces"
|
|
||||||
json_select "${INTERFACE}"
|
|
||||||
json_get_var running running
|
|
||||||
json_get_var status status
|
|
||||||
else
|
else
|
||||||
status=online
|
status=online
|
||||||
running=1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$LOG notice "Execute "$ACTION" event on interface $INTERFACE (${DEVICE:-unknown})"
|
[ -z "$TRUE_INTERFACE" ] && mwan3_get_true_iface TRUE_INTERFACE $INTERFACE
|
||||||
|
|
||||||
|
binary_status=$status
|
||||||
|
[ "$binary_status" = "online" ] || binary_status=offline
|
||||||
|
|
||||||
|
LOG notice "Execute "$ACTION" event on interface $INTERFACE (${DEVICE:-unknown})"
|
||||||
|
|
||||||
case "$ACTION" in
|
case "$ACTION" in
|
||||||
ifup)
|
ifup|connected)
|
||||||
mwan3_set_general_rules
|
|
||||||
mwan3_set_general_iptables
|
|
||||||
mwan3_create_iface_iptables $INTERFACE $DEVICE
|
mwan3_create_iface_iptables $INTERFACE $DEVICE
|
||||||
mwan3_create_iface_rules $INTERFACE $DEVICE
|
mwan3_create_iface_rules $INTERFACE $DEVICE
|
||||||
mwan3_create_iface_route $INTERFACE $DEVICE
|
mwan3_create_iface_route $INTERFACE $DEVICE
|
||||||
if [ "${running}" -eq 1 ] && [ "${status}" = "online" ]; then
|
[ "$MWAN3_STARTUP" != 1 ] && mwan3_add_non_default_iface_route $INTERFACE $DEVICE
|
||||||
$LOG notice "Starting tracker on interface $INTERFACE (${DEVICE:-unknown})"
|
mwan3_set_iface_hotplug_state $INTERFACE "$binary_status"
|
||||||
mwan3_set_iface_hotplug_state $INTERFACE "online"
|
|
||||||
mwan3_track $INTERFACE $DEVICE "online" "$src_ip"
|
mwan3_get_src_ip src_ip "$TRUE_INTERFACE"
|
||||||
|
if [ -n "${trackpid}" ]; then
|
||||||
|
device_pid=$(pgrep -f "mwan3track $INTERFACE $DEVICE ")
|
||||||
|
if [ "$device_pid" = "$trackpid" ]; then
|
||||||
|
[ "$ACTION" = ifup ] && kill -USR2 "$trackpid"
|
||||||
else
|
else
|
||||||
$LOG notice "Starting tracker on interface $INTERFACE (${DEVICE:-unknown})"
|
mwan3_track $INTERFACE $DEVICE "$binary_status" "$src_ip"
|
||||||
mwan3_set_iface_hotplug_state $INTERFACE "offline"
|
LOG notice "Restarted tracker [$!] on interface $INTERFACE (${DEVICE:-unknown})"
|
||||||
mwan3_track $INTERFACE $DEVICE "offline" "$src_ip"
|
|
||||||
fi
|
fi
|
||||||
mwan3_set_policies_iptables
|
else
|
||||||
mwan3_set_user_rules
|
mwan3_track $INTERFACE $DEVICE "$binary_status" "$src_ip"
|
||||||
|
LOG notice "Started tracker [$!] on interface $INTERFACE (${DEVICE:-unknown})"
|
||||||
|
fi
|
||||||
|
[ "$MWAN3_STARTUP" != 1 ] && [ "$binary_status" == "online" ] && mwan3_set_policies_iptables
|
||||||
|
|
||||||
;;
|
;;
|
||||||
ifdown)
|
ifdown|disconnected)
|
||||||
mwan3_set_iface_hotplug_state $INTERFACE "offline"
|
mwan3_set_iface_hotplug_state $INTERFACE "offline"
|
||||||
mwan3_delete_iface_ipset_entries $INTERFACE
|
mwan3_delete_iface_ipset_entries $INTERFACE
|
||||||
mwan3_track_signal $INTERFACE $DEVICE
|
mwan3_delete_iface_rules $INTERFACE
|
||||||
|
mwan3_delete_iface_route $INTERFACE
|
||||||
|
mwan3_delete_iface_iptables $INTERFACE
|
||||||
|
if [ "$ACTION" = "ifdown" ]; then
|
||||||
|
[ -n "$trackpid" ] && kill -USR1 "$trackpid"
|
||||||
|
fi
|
||||||
mwan3_set_policies_iptables
|
mwan3_set_policies_iptables
|
||||||
mwan3_set_user_rules
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
[ "$MWAN3_STARTUP" = 1 ] || mwan3_unlock "$ACTION" "$INTERFACE"
|
||||||
mwan3_unlock "$ACTION" "$INTERFACE"
|
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|
|
@ -4,22 +4,22 @@
|
||||||
. /lib/functions.sh
|
. /lib/functions.sh
|
||||||
. /lib/mwan3/mwan3.sh
|
. /lib/mwan3/mwan3.sh
|
||||||
|
|
||||||
mwan3_lock "$ACTION" "user"
|
[ "$MWAN3_STARTUP" = 1 ] || mwan3_lock "$ACTION" "$DEVICE-user"
|
||||||
|
|
||||||
config_load mwan3
|
config_load mwan3
|
||||||
config_get_bool enabled globals 'enabled' '0'
|
config_get_bool enabled globals 'enabled' '0'
|
||||||
[ "${enabled}" -gt 0 ] || {
|
[ "${enabled}" -gt 0 ] || {
|
||||||
mwan3_unlock "$ACTION" "user"
|
[ "$MWAN3_STARTUP" = 1 ] || mwan3_unlock "$ACTION" "$DEVICE-user"
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
config_get_bool enabled "$INTERFACE" enabled 0
|
config_get_bool enabled "$INTERFACE" enabled 0
|
||||||
[ "${enabled}" -eq 1 ] || {
|
[ "${enabled}" -eq 1 ] || {
|
||||||
mwan3_unlock "$ACTION" "user"
|
[ "$MWAN3_STARTUP" = 1 ] || mwan3_unlock "$ACTION" "$DEVICE-user"
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
mwan3_unlock "$ACTION" "user"
|
[ "$MWAN3_STARTUP" = 1 ] || mwan3_unlock "$ACTION" "$DEVICE-user"
|
||||||
|
|
||||||
env -i ACTION="$ACTION" INTERFACE="$INTERFACE" DEVICE="$DEVICE" \
|
env -i ACTION="$ACTION" INTERFACE="$INTERFACE" DEVICE="$DEVICE" \
|
||||||
/bin/sh /etc/mwan3.user
|
/bin/sh /etc/mwan3.user
|
||||||
|
|
|
@ -5,8 +5,9 @@ USE_PROCD=1
|
||||||
|
|
||||||
boot() {
|
boot() {
|
||||||
. /lib/config/uci.sh
|
. /lib/config/uci.sh
|
||||||
uci_toggle_state mwan3 globals enabled "1"
|
# disabled until mwan3 start runs so hotplug scripts
|
||||||
mwan3_boot=1
|
# do not start prematurely
|
||||||
|
uci_toggle_state mwan3 globals enabled "0"
|
||||||
rc_procd start_service
|
rc_procd start_service
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +21,6 @@ reload_service() {
|
||||||
}
|
}
|
||||||
|
|
||||||
start_service() {
|
start_service() {
|
||||||
[ -n "${mwan3_boot}" ] && return 0
|
|
||||||
/usr/sbin/mwan3 start 1000>&-
|
/usr/sbin/mwan3 start 1000>&-
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,3 +4,14 @@ get_uptime() {
|
||||||
local uptime=$(cat /proc/uptime)
|
local uptime=$(cat /proc/uptime)
|
||||||
echo "${uptime%%.*}"
|
echo "${uptime%%.*}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SCRIPTNAME="$(basename "$0")"
|
||||||
|
LOG()
|
||||||
|
{
|
||||||
|
local facility=$1; shift
|
||||||
|
# in development, we want to show 'debug' level logs
|
||||||
|
# when this release is out of beta, the comment in the line below
|
||||||
|
# should be removed
|
||||||
|
[ "$facility" = "debug" ] && return
|
||||||
|
logger -t "$SCRIPTNAME[$$]" -p $facility "$*"
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
. /usr/share/libubox/jshn.sh
|
. /usr/share/libubox/jshn.sh
|
||||||
|
|
||||||
IP4="ip -4"
|
IP4="ip -4"
|
||||||
|
@ -6,7 +7,8 @@ IP6="ip -6"
|
||||||
IPS="ipset"
|
IPS="ipset"
|
||||||
IPT4="iptables -t mangle -w"
|
IPT4="iptables -t mangle -w"
|
||||||
IPT6="ip6tables -t mangle -w"
|
IPT6="ip6tables -t mangle -w"
|
||||||
LOG="logger -t mwan3[$$] -p"
|
IPT4R="iptables-restore -T mangle -w -n"
|
||||||
|
IPT6R="ip6tables-restore -T mangle -w -n"
|
||||||
CONNTRACK_FILE="/proc/net/nf_conntrack"
|
CONNTRACK_FILE="/proc/net/nf_conntrack"
|
||||||
IPv6_REGEX="([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|"
|
IPv6_REGEX="([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|"
|
||||||
IPv6_REGEX="${IPv6_REGEX}([0-9a-fA-F]{1,4}:){1,7}:|"
|
IPv6_REGEX="${IPv6_REGEX}([0-9a-fA-F]{1,4}:){1,7}:|"
|
||||||
|
@ -69,7 +71,7 @@ mwan3_update_dev_to_table()
|
||||||
|
|
||||||
mwan3_update_iface_to_table()
|
mwan3_update_iface_to_table()
|
||||||
{
|
{
|
||||||
local _tid section family cfgtype curr_table _mwan3_iface_tbl
|
local _tid
|
||||||
mwan3_iface_tbl=" "
|
mwan3_iface_tbl=" "
|
||||||
update_table()
|
update_table()
|
||||||
{
|
{
|
||||||
|
@ -163,14 +165,14 @@ mwan3_init()
|
||||||
else
|
else
|
||||||
config_load mwan3
|
config_load mwan3
|
||||||
config_get MMX_MASK globals mmx_mask '0x3F00'
|
config_get MMX_MASK globals mmx_mask '0x3F00'
|
||||||
echo "$MMX_MASK" > "${MWAN3_STATUS_DIR}/mmx_mask"
|
echo "$MMX_MASK"| tr 'A-F' 'a-f' > "${MWAN3_STATUS_DIR}/mmx_mask"
|
||||||
$LOG notice "Using firewall mask ${MMX_MASK}"
|
LOG debug "Using firewall mask ${MMX_MASK}"
|
||||||
|
|
||||||
bitcnt=$(mwan3_count_one_bits MMX_MASK)
|
bitcnt=$(mwan3_count_one_bits MMX_MASK)
|
||||||
mmdefault=$(((1<<bitcnt)-1))
|
mmdefault=$(((1<<bitcnt)-1))
|
||||||
MWAN3_INTERFACE_MAX=$(($mmdefault-3))
|
MWAN3_INTERFACE_MAX=$(($mmdefault-3))
|
||||||
uci_toggle_state mwan3 globals iface_max "$MWAN3_INTERFACE_MAX"
|
uci_toggle_state mwan3 globals iface_max "$MWAN3_INTERFACE_MAX"
|
||||||
$LOG notice "Max interface count is ${MWAN3_INTERFACE_MAX}"
|
LOG debug "Max interface count is ${MWAN3_INTERFACE_MAX}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# mark mask constants
|
# mark mask constants
|
||||||
|
@ -187,14 +189,30 @@ mwan3_init()
|
||||||
|
|
||||||
mwan3_lock() {
|
mwan3_lock() {
|
||||||
lock /var/run/mwan3.lock
|
lock /var/run/mwan3.lock
|
||||||
# $LOG debug "$1 $2 (lock)"
|
#LOG debug "$1 $2 (lock)"
|
||||||
}
|
}
|
||||||
|
|
||||||
mwan3_unlock() {
|
mwan3_unlock() {
|
||||||
# $LOG debug "$1 $2 (unlock)"
|
#LOG debug "$1 $2 (unlock)"
|
||||||
lock -u /var/run/mwan3.lock
|
lock -u /var/run/mwan3.lock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mwan3_get_src_ip()
|
||||||
|
{
|
||||||
|
local family _src_ip true_iface
|
||||||
|
true_iface=$2
|
||||||
|
unset "$1"
|
||||||
|
config_get family "$true_iface" family ipv4
|
||||||
|
if [ "$family" = "ipv4" ]; then
|
||||||
|
network_get_ipaddr _src_ip "$true_iface"
|
||||||
|
[ -n "$_src_ip" ] || _src_ip="0.0.0.0"
|
||||||
|
elif [ "$family" = "ipv6" ]; then
|
||||||
|
network_get_ipaddr6 _src_ip "$true_iface"
|
||||||
|
[ -n "$_src_ip" ] || _src_ip="::"
|
||||||
|
fi
|
||||||
|
export "$1=$_src_ip"
|
||||||
|
}
|
||||||
|
|
||||||
mwan3_get_iface_id()
|
mwan3_get_iface_id()
|
||||||
{
|
{
|
||||||
local _tmp
|
local _tmp
|
||||||
|
@ -202,6 +220,7 @@ mwan3_get_iface_id()
|
||||||
_tmp="${mwan3_iface_tbl##* ${2}=}"
|
_tmp="${mwan3_iface_tbl##* ${2}=}"
|
||||||
_tmp=${_tmp%% *}
|
_tmp=${_tmp%% *}
|
||||||
export "$1=$_tmp"
|
export "$1=$_tmp"
|
||||||
|
new_val=$_tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
mwan3_set_custom_ipset_v4()
|
mwan3_set_custom_ipset_v4()
|
||||||
|
@ -209,8 +228,8 @@ mwan3_set_custom_ipset_v4()
|
||||||
local custom_network_v4
|
local custom_network_v4
|
||||||
|
|
||||||
for custom_network_v4 in $($IP4 route list table "$1" | awk '{print $1}' | egrep '[0-9]{1,3}(\.[0-9]{1,3}){3}'); do
|
for custom_network_v4 in $($IP4 route list table "$1" | awk '{print $1}' | egrep '[0-9]{1,3}(\.[0-9]{1,3}){3}'); do
|
||||||
$LOG notice "Adding network $custom_network_v4 from table $1 to mwan3_custom_v4 ipset"
|
LOG notice "Adding network $custom_network_v4 from table $1 to mwan3_custom_v4 ipset"
|
||||||
$IPS -! add mwan3_custom_v4_temp "$custom_network_v4"
|
mwan3_push_update -! add mwan3_custom_v4 "$custom_network_v4"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,47 +238,48 @@ mwan3_set_custom_ipset_v6()
|
||||||
local custom_network_v6
|
local custom_network_v6
|
||||||
|
|
||||||
for custom_network_v6 in $($IP6 route list table "$1" | awk '{print $1}' | egrep "$IPv6_REGEX"); do
|
for custom_network_v6 in $($IP6 route list table "$1" | awk '{print $1}' | egrep "$IPv6_REGEX"); do
|
||||||
$LOG notice "Adding network $custom_network_v6 from table $1 to mwan3_custom_v6 ipset"
|
LOG notice "Adding network $custom_network_v6 from table $1 to mwan3_custom_v6 ipset"
|
||||||
$IPS -! add mwan3_custom_v6_temp "$custom_network_v6"
|
mwan3_push_update -! add mwan3_custom_v6 "$custom_network_v6"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
mwan3_set_custom_ipset()
|
mwan3_set_custom_ipset()
|
||||||
{
|
{
|
||||||
$IPS -! create mwan3_custom_v4 hash:net
|
local update=""
|
||||||
$IPS create mwan3_custom_v4_temp hash:net
|
|
||||||
|
mwan3_push_update -! create mwan3_custom_v4 hash:net
|
||||||
config_list_foreach "globals" "rt_table_lookup" mwan3_set_custom_ipset_v4
|
config_list_foreach "globals" "rt_table_lookup" mwan3_set_custom_ipset_v4
|
||||||
$IPS swap mwan3_custom_v4_temp mwan3_custom_v4
|
|
||||||
$IPS destroy mwan3_custom_v4_temp
|
|
||||||
|
|
||||||
|
mwan3_push_update -! create mwan3_custom_v6 hash:net family inet6
|
||||||
$IPS -! create mwan3_custom_v6 hash:net family inet6
|
|
||||||
$IPS create mwan3_custom_v6_temp hash:net family inet6
|
|
||||||
config_list_foreach "globals" "rt_table_lookup" mwan3_set_custom_ipset_v6
|
config_list_foreach "globals" "rt_table_lookup" mwan3_set_custom_ipset_v6
|
||||||
$IPS swap mwan3_custom_v6_temp mwan3_custom_v6
|
|
||||||
$IPS destroy mwan3_custom_v6_temp
|
|
||||||
|
|
||||||
$IPS -! create mwan3_connected list:set
|
mwan3_push_update -! create mwan3_connected list:set
|
||||||
$IPS -! add mwan3_connected mwan3_custom_v4
|
mwan3_push_update -! add mwan3_connected mwan3_custom_v4
|
||||||
$IPS -! add mwan3_connected mwan3_custom_v6
|
mwan3_push_update -! add mwan3_connected mwan3_custom_v6
|
||||||
|
error=$(echo "$update" | $IPS restore 2>&1) || LOG error "set_custom_ipset: $error"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mwan3_set_connected_ipv4()
|
mwan3_set_connected_ipv4()
|
||||||
{
|
{
|
||||||
local connected_network_v4 candidate_list cidr_list
|
local connected_network_v4 candidate_list cidr_list
|
||||||
|
local ipv4regex='[0-9]{1,3}(\.[0-9]{1,3}){3}'
|
||||||
|
$IPS -! create mwan3_connected_v4 hash:net
|
||||||
|
$IPS create mwan3_connected_v4_temp hash:net
|
||||||
|
|
||||||
candidate_list=""
|
candidate_list=""
|
||||||
cidr_list=""
|
cidr_list=""
|
||||||
for connected_network_v4 in $($IP4 route | awk '{print $1}' | egrep '[0-9]{1,3}(\.[0-9]{1,3}){3}'); do
|
route_lists()
|
||||||
[ -z "${connected_network_v4##*/*}" ] &&
|
{
|
||||||
cidr_list="$cidr_list $connected_network_v4" ||
|
$IP4 route | awk '{print $1}'
|
||||||
candidate_list="$candidate_list $connected_network_v4"
|
$IP4 route list table 0 | awk '{print $2}'
|
||||||
done
|
}
|
||||||
|
for connected_network_v4 in $(route_lists | egrep "$ipv4regex"); do
|
||||||
for connected_network_v4 in $($IP4 route list table 0 | awk '{print $2}' | egrep '[0-9]{1,3}(\.[0-9]{1,3}){3}'); do
|
if [ -z "${connected_network_v4##*/*}" ]; then
|
||||||
[ -z "${connected_network_v4##*/*}" ] &&
|
cidr_list="$cidr_list $connected_network_v4"
|
||||||
cidr_list="$cidr_list $connected_network_v4" ||
|
else
|
||||||
candidate_list="$candidate_list $connected_network_v4"
|
candidate_list="$candidate_list $connected_network_v4"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
for connected_network_v4 in $cidr_list; do
|
for connected_network_v4 in $cidr_list; do
|
||||||
|
@ -279,41 +299,35 @@ mwan3_set_connected_ipv4()
|
||||||
|
|
||||||
mwan3_set_connected_iptables()
|
mwan3_set_connected_iptables()
|
||||||
{
|
{
|
||||||
local connected_network_v6 source_network_v6
|
local connected_network_v6 source_network_v6 error
|
||||||
|
local update=""
|
||||||
$IPS -! create mwan3_connected_v4 hash:net
|
|
||||||
$IPS create mwan3_connected_v4_temp hash:net
|
|
||||||
|
|
||||||
mwan3_set_connected_ipv4
|
mwan3_set_connected_ipv4
|
||||||
|
|
||||||
[ $NO_IPV6 -eq 0 ] && {
|
[ $NO_IPV6 -eq 0 ] && {
|
||||||
$IPS -! create mwan3_connected_v6 hash:net family inet6
|
mwan3_push_update -! create mwan3_connected_v6 hash:net family inet6
|
||||||
$IPS create mwan3_connected_v6_temp hash:net family inet6
|
mwan3_push_update flush mwan3_connected_v6
|
||||||
|
|
||||||
for connected_network_v6 in $($IP6 route | awk '{print $1}' | egrep "$IPv6_REGEX"); do
|
for connected_network_v6 in $($IP6 route | awk '{print $1}' | egrep "$IPv6_REGEX"); do
|
||||||
$IPS -! add mwan3_connected_v6_temp "$connected_network_v6"
|
mwan3_push_update -! add mwan3_connected_v6 "$connected_network_v6"
|
||||||
done
|
done
|
||||||
$IPS swap mwan3_connected_v6_temp mwan3_connected_v6
|
|
||||||
$IPS destroy mwan3_connected_v6_temp
|
|
||||||
|
|
||||||
$IPS -! create mwan3_source_v6 hash:net family inet6
|
mwan3_push_update -! 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
|
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"
|
mwan3_push_update -! add mwan3_source_v6 "$source_network_v6"
|
||||||
done
|
done
|
||||||
$IPS swap mwan3_source_v6_temp mwan3_source_v6
|
|
||||||
$IPS destroy mwan3_source_v6_temp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$IPS -! create mwan3_connected list:set
|
mwan3_push_update -! create mwan3_connected list:set
|
||||||
$IPS -! add mwan3_connected mwan3_connected_v4
|
mwan3_push_update flush mwan3_connected
|
||||||
[ $NO_IPV6 -eq 0 ] && $IPS -! add mwan3_connected mwan3_connected_v6
|
mwan3_push_update -! add mwan3_connected mwan3_connected_v4
|
||||||
|
[ $NO_IPV6 -eq 0 ] && mwan3_push_update -! add mwan3_connected mwan3_connected_v6
|
||||||
|
|
||||||
$IPS -! create mwan3_dynamic_v4 hash:net
|
mwan3_push_update -! create mwan3_dynamic_v4 hash:net
|
||||||
$IPS -! add mwan3_connected mwan3_dynamic_v4
|
mwan3_push_update -! add mwan3_connected mwan3_dynamic_v4
|
||||||
|
|
||||||
[ $NO_IPV6 -eq 0 ] && $IPS -! create mwan3_dynamic_v6 hash:net family inet6
|
[ $NO_IPV6 -eq 0 ] && mwan3_push_update -! create mwan3_dynamic_v6 hash:net family inet6
|
||||||
[ $NO_IPV6 -eq 0 ] && $IPS -! add mwan3_connected mwan3_dynamic_v6
|
[ $NO_IPV6 -eq 0 ] && mwan3_push_update -! add mwan3_connected mwan3_dynamic_v6
|
||||||
|
error=$(echo "$update" | $IPS restore 2>&1) || LOG error "set_connected_iptables: $error"
|
||||||
}
|
}
|
||||||
|
|
||||||
mwan3_set_general_rules()
|
mwan3_set_general_rules()
|
||||||
|
@ -336,89 +350,96 @@ mwan3_set_general_rules()
|
||||||
|
|
||||||
mwan3_set_general_iptables()
|
mwan3_set_general_iptables()
|
||||||
{
|
{
|
||||||
local IPT
|
local IPT current update error
|
||||||
|
|
||||||
for IPT in "$IPT4" "$IPT6"; do
|
for IPT in "$IPT4" "$IPT6"; do
|
||||||
[ "$IPT" = "$IPT6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
[ "$IPT" = "$IPT6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
||||||
if ! $IPT -S mwan3_ifaces_in &> /dev/null; then
|
current="$($IPT -S)"
|
||||||
$IPT -N mwan3_ifaces_in
|
update="*mangle"
|
||||||
|
if [ -n "${current##*-N mwan3_ifaces_in*}" ]; then
|
||||||
|
mwan3_push_update -N mwan3_ifaces_in
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! $IPT -S mwan3_connected &> /dev/null; then
|
if [ -n "${current##*-N mwan3_connected*}" ]; then
|
||||||
$IPT -N mwan3_connected
|
mwan3_push_update -N mwan3_connected
|
||||||
$IPS -! create mwan3_connected list:set
|
$IPS -! create mwan3_connected list:set
|
||||||
$IPT -A mwan3_connected \
|
mwan3_push_update -A mwan3_connected \
|
||||||
-m set --match-set mwan3_connected dst \
|
-m set --match-set mwan3_connected dst \
|
||||||
-j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK
|
-j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! $IPT -S mwan3_rules &> /dev/null; then
|
if [ -n "${current##*-N mwan3_rules*}" ]; then
|
||||||
$IPT -N mwan3_rules
|
mwan3_push_update -N mwan3_rules
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! $IPT -S mwan3_hook &> /dev/null; then
|
if [ -n "${current##*-N mwan3_hook*}" ]; then
|
||||||
$IPT -N mwan3_hook
|
mwan3_push_update -N mwan3_hook
|
||||||
# do not mangle ipv6 ra service
|
# do not mangle ipv6 ra service
|
||||||
if [ "$IPT" = "$IPT6" ]; then
|
if [ "$IPT" = "$IPT6" ]; then
|
||||||
$IPT6 -A mwan3_hook \
|
mwan3_push_update -A mwan3_hook \
|
||||||
-p ipv6-icmp \
|
-p ipv6-icmp \
|
||||||
-m icmp6 --icmpv6-type 133 \
|
-m icmp6 --icmpv6-type 133 \
|
||||||
-j RETURN
|
-j RETURN
|
||||||
$IPT6 -A mwan3_hook \
|
mwan3_push_update -A mwan3_hook \
|
||||||
-p ipv6-icmp \
|
-p ipv6-icmp \
|
||||||
-m icmp6 --icmpv6-type 134 \
|
-m icmp6 --icmpv6-type 134 \
|
||||||
-j RETURN
|
-j RETURN
|
||||||
$IPT6 -A mwan3_hook \
|
mwan3_push_update -A mwan3_hook \
|
||||||
-p ipv6-icmp \
|
-p ipv6-icmp \
|
||||||
-m icmp6 --icmpv6-type 135 \
|
-m icmp6 --icmpv6-type 135 \
|
||||||
-j RETURN
|
-j RETURN
|
||||||
$IPT6 -A mwan3_hook \
|
mwan3_push_update -A mwan3_hook \
|
||||||
-p ipv6-icmp \
|
-p ipv6-icmp \
|
||||||
-m icmp6 --icmpv6-type 136 \
|
-m icmp6 --icmpv6-type 136 \
|
||||||
-j RETURN
|
-j RETURN
|
||||||
$IPT6 -A mwan3_hook \
|
mwan3_push_update -A mwan3_hook \
|
||||||
-p ipv6-icmp \
|
-p ipv6-icmp \
|
||||||
-m icmp6 --icmpv6-type 137 \
|
-m icmp6 --icmpv6-type 137 \
|
||||||
-j RETURN
|
-j RETURN
|
||||||
# do not mangle outgoing echo request
|
# do not mangle outgoing echo request
|
||||||
$IPT6 -A mwan3_hook \
|
mwan3_push_update -A mwan3_hook \
|
||||||
-m set --match-set mwan3_source_v6 src \
|
-m set --match-set mwan3_source_v6 src \
|
||||||
-p ipv6-icmp \
|
-p ipv6-icmp \
|
||||||
-m icmp6 --icmpv6-type 128 \
|
-m icmp6 --icmpv6-type 128 \
|
||||||
-j RETURN
|
-j RETURN
|
||||||
|
|
||||||
fi
|
fi
|
||||||
$IPT -A mwan3_hook \
|
mwan3_push_update -A mwan3_hook \
|
||||||
-j CONNMARK --restore-mark --nfmask "$MMX_MASK" --ctmask "$MMX_MASK"
|
-j CONNMARK --restore-mark --nfmask "$MMX_MASK" --ctmask "$MMX_MASK"
|
||||||
$IPT -A mwan3_hook \
|
mwan3_push_update -A mwan3_hook \
|
||||||
-m mark --mark 0x0/$MMX_MASK \
|
-m mark --mark 0x0/$MMX_MASK \
|
||||||
-j mwan3_ifaces_in
|
-j mwan3_ifaces_in
|
||||||
$IPT -A mwan3_hook \
|
mwan3_push_update -A mwan3_hook \
|
||||||
-m mark --mark 0x0/$MMX_MASK \
|
-m mark --mark 0x0/$MMX_MASK \
|
||||||
-j mwan3_connected
|
-j mwan3_connected
|
||||||
$IPT -A mwan3_hook \
|
mwan3_push_update -A mwan3_hook \
|
||||||
-m mark --mark 0x0/$MMX_MASK \
|
-m mark --mark 0x0/$MMX_MASK \
|
||||||
-j mwan3_rules
|
-j mwan3_rules
|
||||||
$IPT -A mwan3_hook \
|
mwan3_push_update -A mwan3_hook \
|
||||||
-j CONNMARK --save-mark --nfmask "$MMX_MASK" --ctmask "$MMX_MASK"
|
-j CONNMARK --save-mark --nfmask "$MMX_MASK" --ctmask "$MMX_MASK"
|
||||||
$IPT -A mwan3_hook \
|
mwan3_push_update -A mwan3_hook \
|
||||||
-m mark ! --mark $MMX_DEFAULT/$MMX_MASK \
|
-m mark ! --mark $MMX_DEFAULT/$MMX_MASK \
|
||||||
-j mwan3_connected
|
-j mwan3_connected
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! $IPT -S PREROUTING | grep mwan3_hook &> /dev/null; then
|
if [ -n "${current##*-A PREROUTING -j mwan3_hook*}" ]; then
|
||||||
$IPT -A PREROUTING -j mwan3_hook
|
mwan3_push_update -A PREROUTING -j mwan3_hook
|
||||||
fi
|
fi
|
||||||
|
if [ -n "${current##*-A OUTPUT -j mwan3_hook*}" ]; then
|
||||||
if ! $IPT -S OUTPUT | grep mwan3_hook &> /dev/null; then
|
mwan3_push_update -A OUTPUT -j mwan3_hook
|
||||||
$IPT -A OUTPUT -j mwan3_hook
|
fi
|
||||||
|
mwan3_push_update COMMIT
|
||||||
|
mwan3_push_update ""
|
||||||
|
if [ "$IPT" = "$IPT4" ]; then
|
||||||
|
error=$(echo "$update" | $IPT4R 2>&1) || LOG error "set_general_iptables: $error"
|
||||||
|
else
|
||||||
|
error=$(echo "$update" | $IPT6R 2>&1) || LOG error "set_general_iptables: $error"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
mwan3_create_iface_iptables()
|
mwan3_create_iface_iptables()
|
||||||
{
|
{
|
||||||
local id family connected_name IPT
|
local id family connected_name IPT IPTR current update error
|
||||||
|
|
||||||
config_get family "$1" family ipv4
|
config_get family "$1" family ipv4
|
||||||
mwan3_get_iface_id id "$1"
|
mwan3_get_iface_id id "$1"
|
||||||
|
@ -428,43 +449,53 @@ mwan3_create_iface_iptables()
|
||||||
if [ "$family" = "ipv4" ]; then
|
if [ "$family" = "ipv4" ]; then
|
||||||
connected_name=mwan3_connected
|
connected_name=mwan3_connected
|
||||||
IPT="$IPT4"
|
IPT="$IPT4"
|
||||||
|
IPTR="$IPT4R"
|
||||||
$IPS -! create $connected_name list:set
|
$IPS -! create $connected_name list:set
|
||||||
|
|
||||||
elif [ "$family" = "ipv6" ] && [ $NO_IPV6 -eq 0 ]; then
|
elif [ "$family" = "ipv6" ] && [ $NO_IPV6 -eq 0 ]; then
|
||||||
connected_name=mwan3_connected_v6
|
connected_name=mwan3_connected_v6
|
||||||
IPT="$IPT6"
|
IPT="$IPT6"
|
||||||
|
IPTR="$IPT6R"
|
||||||
$IPS -! create $connected_name hash:net family inet6
|
$IPS -! create $connected_name hash:net family inet6
|
||||||
else
|
else
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
current="$($IPT -S)"
|
||||||
if ! $IPT -S mwan3_ifaces_in &> /dev/null; then
|
update="*mangle"
|
||||||
$IPT -N mwan3_ifaces_in
|
if [ -n "${current##*-N mwan3_ifaces_in*}" ]; then
|
||||||
|
mwan3_push_update -N mwan3_ifaces_in
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! $IPT -S "mwan3_iface_in_$1" &> /dev/null; then
|
if [ -n "${current##*-N mwan3_iface_in_$1*}" ]; then
|
||||||
$IPT -N "mwan3_iface_in_$1"
|
mwan3_push_update -N "mwan3_iface_in_$1"
|
||||||
|
else
|
||||||
|
mwan3_push_update -F "mwan3_iface_in_$1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$IPT -F "mwan3_iface_in_$1"
|
mwan3_push_update -A "mwan3_iface_in_$1" \
|
||||||
$IPT -A "mwan3_iface_in_$1" \
|
|
||||||
-i "$2" \
|
-i "$2" \
|
||||||
-m set --match-set $connected_name src \
|
-m set --match-set $connected_name src \
|
||||||
-m mark --mark 0x0/$MMX_MASK \
|
-m mark --mark 0x0/$MMX_MASK \
|
||||||
-m comment --comment "default" \
|
-m comment --comment "default" \
|
||||||
-j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK
|
-j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK
|
||||||
$IPT -A "mwan3_iface_in_$1" \
|
mwan3_push_update -A "mwan3_iface_in_$1" \
|
||||||
-i "$2" \
|
-i "$2" \
|
||||||
-m mark --mark 0x0/$MMX_MASK \
|
-m mark --mark 0x0/$MMX_MASK \
|
||||||
-m comment --comment "$1" \
|
-m comment --comment "$1" \
|
||||||
-j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK
|
-j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK
|
||||||
|
|
||||||
$IPT -D mwan3_ifaces_in \
|
if [ -n "${current##*-A mwan3_ifaces_in -m mark --mark 0x0/$MMX_MASK -j mwan3_iface_in_${1}*}" ]; then
|
||||||
-m mark --mark 0x0/$MMX_MASK \
|
mwan3_push_update -A mwan3_ifaces_in \
|
||||||
-j "mwan3_iface_in_$1" &> /dev/null
|
|
||||||
$IPT -A mwan3_ifaces_in \
|
|
||||||
-m mark --mark 0x0/$MMX_MASK \
|
-m mark --mark 0x0/$MMX_MASK \
|
||||||
-j "mwan3_iface_in_$1"
|
-j "mwan3_iface_in_$1"
|
||||||
|
LOG debug "create_iface_iptables: mwan3_iface_in_$1 not in iptables, adding"
|
||||||
|
else
|
||||||
|
LOG debug "create_iface_iptables: mwan3_iface_in_$1 already in iptables, skip"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mwan3_push_update COMMIT
|
||||||
|
mwan3_push_update ""
|
||||||
|
error=$(echo "$update" | $IPTR 2>&1) || LOG error "create_iface_iptables: $error"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,7 +599,6 @@ mwan3_add_all_nondefault_routes()
|
||||||
add_route()
|
add_route()
|
||||||
{
|
{
|
||||||
let tid++
|
let tid++
|
||||||
config_get family "$section" family ipv4
|
|
||||||
[ -n "${active_tbls##* $tid *}" ] && return
|
[ -n "${active_tbls##* $tid *}" ] && return
|
||||||
$IP route add table $tid $route_line ||
|
$IP route add table $tid $route_line ||
|
||||||
LOG warn "failed to add $route_line to table $tid"
|
LOG warn "failed to add $route_line to table $tid"
|
||||||
|
@ -615,7 +645,7 @@ mwan3_delete_iface_route()
|
||||||
|
|
||||||
mwan3_create_iface_rules()
|
mwan3_create_iface_rules()
|
||||||
{
|
{
|
||||||
local id family
|
local id family IP
|
||||||
|
|
||||||
config_get family "$1" family ipv4
|
config_get family "$1" family ipv4
|
||||||
mwan3_get_iface_id id "$1"
|
mwan3_get_iface_id id "$1"
|
||||||
|
@ -623,32 +653,23 @@ mwan3_create_iface_rules()
|
||||||
[ -n "$id" ] || return 0
|
[ -n "$id" ] || return 0
|
||||||
|
|
||||||
if [ "$family" = "ipv4" ]; then
|
if [ "$family" = "ipv4" ]; then
|
||||||
|
IP="$IP4"
|
||||||
while [ -n "$($IP4 rule list | awk '$1 == "'$(($id+1000)):'"')" ]; do
|
elif [ "$family" = "ipv6" ] && [ $NO_IPV6 -eq 0 ]; then
|
||||||
$IP4 rule del pref $(($id+1000))
|
IP="$IP6"
|
||||||
done
|
else
|
||||||
|
return
|
||||||
while [ -n "$($IP4 rule list | awk '$1 == "'$(($id+2000)):'"')" ]; do
|
|
||||||
$IP4 rule del pref $(($id+2000))
|
|
||||||
done
|
|
||||||
|
|
||||||
$IP4 rule add pref $(($id+1000)) iif "$2" lookup "$id"
|
|
||||||
$IP4 rule add pref $(($id+2000)) fwmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK lookup "$id"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$family" = "ipv6" ] && [ $NO_IPV6 -eq 0 ]; then
|
while [ -n "$($IP rule list | awk '$1 == "'$(($id+1000)):'"')" ]; do
|
||||||
|
$IP rule del pref $(($id+1000))
|
||||||
while [ -n "$($IP6 rule list | awk '$1 == "'$(($id+1000)):'"')" ]; do
|
|
||||||
$IP6 rule del pref $(($id+1000))
|
|
||||||
done
|
done
|
||||||
|
|
||||||
while [ -n "$($IP6 rule list | awk '$1 == "'$(($id+2000)):'"')" ]; do
|
while [ -n "$($IP rule list | awk '$1 == "'$(($id+2000)):'"')" ]; do
|
||||||
$IP6 rule del pref $(($id+2000))
|
$IP rule del pref $(($id+2000))
|
||||||
done
|
done
|
||||||
|
|
||||||
$IP6 rule add pref $(($id+1000)) iif "$2" lookup "$id"
|
$IP rule add pref $(($id+1000)) iif "$2" lookup "$id"
|
||||||
$IP6 rule add pref $(($id+2000)) fwmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK lookup "$id"
|
$IP rule add pref $(($id+2000)) fwmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK lookup "$id"
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mwan3_delete_iface_rules()
|
mwan3_delete_iface_rules()
|
||||||
|
@ -661,26 +682,20 @@ mwan3_delete_iface_rules()
|
||||||
[ -n "$id" ] || return 0
|
[ -n "$id" ] || return 0
|
||||||
|
|
||||||
if [ "$family" = "ipv4" ]; then
|
if [ "$family" = "ipv4" ]; then
|
||||||
|
IP="$IP4"
|
||||||
while [ -n "$($IP4 rule list | awk '$1 == "'$(($id+1000)):'"')" ]; do
|
elif [ "$family" = "ipv6" ] && [ $NO_IPV6 -eq 0 ]; then
|
||||||
$IP4 rule del pref $(($id+1000))
|
IP="$IP6"
|
||||||
done
|
else
|
||||||
|
return
|
||||||
while [ -n "$($IP4 rule list | awk '$1 == "'$(($id+2000)):'"')" ]; do
|
|
||||||
$IP4 rule del pref $(($id+2000))
|
|
||||||
done
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$family" = "ipv6" ] && [ $NO_IPV6 -eq 0 ]; then
|
while [ -n "$($IP rule list | awk '$1 == "'$(($id+1000)):'"')" ]; do
|
||||||
|
$IP rule del pref $(($id+1000))
|
||||||
while [ -n "$($IP6 rule list | awk '$1 == "'$(($id+1000)):'"')" ]; do
|
|
||||||
$IP6 rule del pref $(($id+1000))
|
|
||||||
done
|
done
|
||||||
|
|
||||||
while [ -n "$($IP6 rule list | awk '$1 == "'$(($id+2000)):'"')" ]; do
|
while [ -n "$($IP rule list | awk '$1 == "'$(($id+2000)):'"')" ]; do
|
||||||
$IP6 rule del pref $(($id+2000))
|
$IP rule del pref $(($id+2000))
|
||||||
done
|
done
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mwan3_delete_iface_ipset_entries()
|
mwan3_delete_iface_ipset_entries()
|
||||||
|
@ -692,7 +707,7 @@ mwan3_delete_iface_ipset_entries()
|
||||||
[ -n "$id" ] || return 0
|
[ -n "$id" ] || return 0
|
||||||
|
|
||||||
for setname in $(ipset -n list | grep ^mwan3_sticky_); do
|
for setname in $(ipset -n list | grep ^mwan3_sticky_); do
|
||||||
for entry in $(ipset list "$setname" | grep "$(echo $(mwan3_id2mask id MMX_MASK) | awk '{ printf "0x%08x", $1; }')" | cut -d ' ' -f 1); do
|
for entry in $(ipset list "$setname" | grep "$(mwan3_id2mask id MMX_MASK | awk '{ printf "0x%08x", $1; }')" | cut -d ' ' -f 1); do
|
||||||
$IPS del "$setname" $entry
|
$IPS del "$setname" $entry
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
@ -712,7 +727,7 @@ mwan3_rtmon()
|
||||||
|
|
||||||
mwan3_track()
|
mwan3_track()
|
||||||
{
|
{
|
||||||
local track_ip track_ips pid
|
local track_ips pids
|
||||||
|
|
||||||
mwan3_list_track_ips()
|
mwan3_list_track_ips()
|
||||||
{
|
{
|
||||||
|
@ -720,28 +735,21 @@ mwan3_track()
|
||||||
}
|
}
|
||||||
config_list_foreach "$1" track_ip mwan3_list_track_ips
|
config_list_foreach "$1" track_ip mwan3_list_track_ips
|
||||||
|
|
||||||
kill -TERM $(pgrep -f "mwan3track $1 $2") > /dev/null 2>&1
|
# don't match device in case it changed from last launch
|
||||||
|
if pids=$(pgrep -f "mwan3track $1 "); then
|
||||||
|
kill -TERM $pids > /dev/null 2>&1
|
||||||
sleep 1
|
sleep 1
|
||||||
kill -KILL $(pgrep -f "mwan3track $1 $2") > /dev/null 2>&1
|
kill -KILL $(pgrep -f "mwan3track $1 ") > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -n "$track_ips" ]; then
|
if [ -n "$track_ips" ]; then
|
||||||
[ -x /usr/sbin/mwan3track ] && /usr/sbin/mwan3track "$1" "$2" "$3" "$4" $track_ips &
|
[ -x /usr/sbin/mwan3track ] && MWAN3_STARTUP=0 /usr/sbin/mwan3track "$1" "$2" "$3" "$4" $track_ips &
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
mwan3_track_signal()
|
|
||||||
{
|
|
||||||
local pid
|
|
||||||
|
|
||||||
pid="$(pgrep -f "mwan3track $1 $2")"
|
|
||||||
[ "${pid}" != "" ] && {
|
|
||||||
kill -USR1 "${pid}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mwan3_set_policy()
|
mwan3_set_policy()
|
||||||
{
|
{
|
||||||
local iface_count id iface family metric probability weight device is_lowest is_offline IPT total_weight
|
local id iface family metric probability weight device is_lowest is_offline IPT IPTR total_weight current update error
|
||||||
|
|
||||||
is_lowest=0
|
is_lowest=0
|
||||||
config_get iface "$1" interface
|
config_get iface "$1" interface
|
||||||
|
@ -750,22 +758,26 @@ mwan3_set_policy()
|
||||||
|
|
||||||
[ -n "$iface" ] || return 0
|
[ -n "$iface" ] || return 0
|
||||||
network_get_device device "$iface"
|
network_get_device device "$iface"
|
||||||
[ "$metric" -gt $DEFAULT_LOWEST_METRIC ] && $LOG warn "Member interface $iface has >$DEFAULT_LOWEST_METRIC metric. Not appending to policy" && return 0
|
[ "$metric" -gt $DEFAULT_LOWEST_METRIC ] && LOG warn "Member interface $iface has >$DEFAULT_LOWEST_METRIC metric. Not appending to policy" && return 0
|
||||||
|
|
||||||
mwan3_get_iface_id id "$iface"
|
mwan3_get_iface_id id "$iface"
|
||||||
|
|
||||||
|
[ -n "$id" ] || return 0
|
||||||
|
|
||||||
[ "$(mwan3_get_iface_hotplug_state "$iface")" = "online" ]
|
[ "$(mwan3_get_iface_hotplug_state "$iface")" = "online" ]
|
||||||
is_offline=$?
|
is_offline=$?
|
||||||
|
|
||||||
[ -n "$id" ] || return 0
|
|
||||||
|
|
||||||
config_get family "$iface" family ipv4
|
config_get family "$iface" family ipv4
|
||||||
|
|
||||||
if [ "$family" = "ipv4" ]; then
|
if [ "$family" = "ipv4" ]; then
|
||||||
IPT="$IPT4"
|
IPT="$IPT4"
|
||||||
|
IPTR="$IPT4R"
|
||||||
elif [ "$family" = "ipv6" ]; then
|
elif [ "$family" = "ipv6" ]; then
|
||||||
IPT="$IPT6"
|
IPT="$IPT6"
|
||||||
|
IPTR="$IPT6R"
|
||||||
fi
|
fi
|
||||||
|
current="$($IPT -S)"
|
||||||
|
update="*mangle"
|
||||||
|
|
||||||
if [ "$family" = "ipv4" ] && [ $is_offline -eq 0 ]; then
|
if [ "$family" = "ipv4" ] && [ $is_offline -eq 0 ]; then
|
||||||
if [ "$metric" -lt "$lowest_metric_v4" ]; then
|
if [ "$metric" -lt "$lowest_metric_v4" ]; then
|
||||||
|
@ -791,10 +803,10 @@ mwan3_set_policy()
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if [ $is_lowest -eq 1 ]; then
|
if [ $is_lowest -eq 1 ]; then
|
||||||
$IPT -F "mwan3_policy_$policy"
|
mwan3_push_update -F "mwan3_policy_$policy"
|
||||||
$IPT -A "mwan3_policy_$policy" \
|
mwan3_push_update -A "mwan3_policy_$policy" \
|
||||||
-m mark --mark 0x0/$MMX_MASK \
|
-m mark --mark 0x0/$MMX_MASK \
|
||||||
-m comment --comment "$iface $weight $weight" \
|
-m comment --comment \"$iface $weight $weight\" \
|
||||||
-j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK
|
-j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK
|
||||||
elif [ $is_offline -eq 0 ]; then
|
elif [ $is_offline -eq 0 ]; then
|
||||||
probability=$(($weight*1000/$total_weight))
|
probability=$(($weight*1000/$total_weight))
|
||||||
|
@ -808,63 +820,76 @@ mwan3_set_policy()
|
||||||
probability="1"
|
probability="1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$IPT -I "mwan3_policy_$policy" \
|
mwan3_push_update -I "mwan3_policy_$policy" \
|
||||||
-m mark --mark 0x0/$MMX_MASK \
|
-m mark --mark 0x0/$MMX_MASK \
|
||||||
-m statistic \
|
-m statistic \
|
||||||
--mode random \
|
--mode random \
|
||||||
--probability "$probability" \
|
--probability "$probability" \
|
||||||
-m comment --comment "$iface $weight $total_weight" \
|
-m comment --comment \"$iface $weight $total_weight\" \
|
||||||
-j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK
|
-j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK
|
||||||
elif [ -n "$device" ]; then
|
elif [ -n "$device" ]; then
|
||||||
$IPT -S "mwan3_policy_$policy" | grep -q '.*--comment ".* [0-9]* [0-9]*"' || \
|
echo "$current" | grep -q "^-A mwan3_policy_$policy.*--comment .* [0-9]* [0-9]*" ||
|
||||||
$IPT -I "mwan3_policy_$policy" \
|
mwan3_push_update -I "mwan3_policy_$policy" \
|
||||||
-o "$device" \
|
-o "$device" \
|
||||||
-m mark --mark 0x0/$MMX_MASK \
|
-m mark --mark 0x0/$MMX_MASK \
|
||||||
-m comment --comment "out $iface $device" \
|
-m comment --comment \"out $iface $device\" \
|
||||||
-j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK
|
-j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK
|
||||||
fi
|
fi
|
||||||
|
mwan3_push_update COMMIT
|
||||||
|
mwan3_push_update ""
|
||||||
|
error=$(echo "$update" | $IPTR 2>&1) || LOG error "set_policy ($1): $error"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mwan3_create_policies_iptables()
|
mwan3_create_policies_iptables()
|
||||||
{
|
{
|
||||||
local last_resort lowest_metric_v4 lowest_metric_v6 total_weight_v4 total_weight_v6 policy IPT
|
local last_resort lowest_metric_v4 lowest_metric_v6 total_weight_v4 total_weight_v6 policy IPT current update error
|
||||||
|
|
||||||
policy="$1"
|
policy="$1"
|
||||||
|
|
||||||
config_get last_resort "$1" last_resort unreachable
|
config_get last_resort "$1" last_resort unreachable
|
||||||
|
|
||||||
if [ "$1" != "$(echo "$1" | cut -c1-15)" ]; then
|
if [ "$1" != "$(echo "$1" | cut -c1-15)" ]; then
|
||||||
$LOG warn "Policy $1 exceeds max of 15 chars. Not setting policy" && return 0
|
LOG warn "Policy $1 exceeds max of 15 chars. Not setting policy" && return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for IPT in "$IPT4" "$IPT6"; do
|
for IPT in "$IPT4" "$IPT6"; do
|
||||||
[ "$IPT" = "$IPT6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
[ "$IPT" = "$IPT6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
||||||
if ! $IPT -S "mwan3_policy_$1" &> /dev/null; then
|
current="$($IPT -S)"
|
||||||
$IPT -N "mwan3_policy_$1"
|
update="*mangle"
|
||||||
|
if [ -n "${current##*-N mwan3_policy_$1*}" ]; then
|
||||||
|
mwan3_push_update -N "mwan3_policy_$1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$IPT -F "mwan3_policy_$1"
|
mwan3_push_update -F "mwan3_policy_$1"
|
||||||
|
|
||||||
case "$last_resort" in
|
case "$last_resort" in
|
||||||
blackhole)
|
blackhole)
|
||||||
$IPT -A "mwan3_policy_$1" \
|
mwan3_push_update -A "mwan3_policy_$1" \
|
||||||
-m mark --mark 0x0/$MMX_MASK \
|
-m mark --mark 0x0/$MMX_MASK \
|
||||||
-m comment --comment "blackhole" \
|
-m comment --comment "blackhole" \
|
||||||
-j MARK --set-xmark $MMX_BLACKHOLE/$MMX_MASK
|
-j MARK --set-xmark $MMX_BLACKHOLE/$MMX_MASK
|
||||||
;;
|
;;
|
||||||
default)
|
default)
|
||||||
$IPT -A "mwan3_policy_$1" \
|
mwan3_push_update -A "mwan3_policy_$1" \
|
||||||
-m mark --mark 0x0/$MMX_MASK \
|
-m mark --mark 0x0/$MMX_MASK \
|
||||||
-m comment --comment "default" \
|
-m comment --comment "default" \
|
||||||
-j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK
|
-j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
$IPT -A "mwan3_policy_$1" \
|
mwan3_push_update -A "mwan3_policy_$1" \
|
||||||
-m mark --mark 0x0/$MMX_MASK \
|
-m mark --mark 0x0/$MMX_MASK \
|
||||||
-m comment --comment "unreachable" \
|
-m comment --comment "unreachable" \
|
||||||
-j MARK --set-xmark $MMX_UNREACHABLE/$MMX_MASK
|
-j MARK --set-xmark $MMX_UNREACHABLE/$MMX_MASK
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
mwan3_push_update COMMIT
|
||||||
|
mwan3_push_update ""
|
||||||
|
if [ "$IPT" = "$IPT4" ]; then
|
||||||
|
error=$(echo "$update" | $IPT4R 2>&1) || LOG error "create_policies_iptables ($1): $error"
|
||||||
|
else
|
||||||
|
error=$(echo "$update" | $IPT6R 2>&1) || LOG error "create_policies_iptables ($1): $error"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
lowest_metric_v4=$DEFAULT_LOWEST_METRIC
|
lowest_metric_v4=$DEFAULT_LOWEST_METRIC
|
||||||
|
@ -884,27 +909,21 @@ mwan3_set_policies_iptables()
|
||||||
mwan3_set_sticky_iptables()
|
mwan3_set_sticky_iptables()
|
||||||
{
|
{
|
||||||
local id iface
|
local id iface
|
||||||
|
for iface in $(echo "$current" | grep "^-A $policy" | cut -s -d'"' -f2 | awk '{print $1}'); do
|
||||||
for iface in $($IPT4 -S "$policy" | cut -s -d'"' -f2 | awk '{print $1}'); do
|
|
||||||
|
|
||||||
if [ "$iface" = "$1" ]; then
|
if [ "$iface" = "$1" ]; then
|
||||||
|
|
||||||
mwan3_get_iface_id id "$1"
|
mwan3_get_iface_id id "$1"
|
||||||
|
|
||||||
[ -n "$id" ] || return 0
|
[ -n "$id" ] || return 0
|
||||||
|
if [ -z "${current##*-N mwan3_iface_in_$1*}" ]; then
|
||||||
for IPT in "$IPT4" "$IPT6"; do
|
mwan3_push_update -I "mwan3_rule_$rule" \
|
||||||
[ "$IPT" = "$IPT6" ] && [ $NO_IPV6 -ne 0 ] && continuea
|
|
||||||
if [ -n "$($IPT -S "mwan3_iface_in_$1" 2> /dev/null)" ]; then
|
|
||||||
$IPT -I "mwan3_rule_$rule" \
|
|
||||||
-m mark --mark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK \
|
-m mark --mark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK \
|
||||||
-m set ! --match-set "mwan3_sticky_$rule" src,src \
|
-m set ! --match-set "mwan3_sticky_$rule" src,src \
|
||||||
-j MARK --set-xmark 0x0/$MMX_MASK
|
-j MARK --set-xmark 0x0/$MMX_MASK
|
||||||
$IPT -I "mwan3_rule_$rule" \
|
mwan3_push_update -I "mwan3_rule_$rule" \
|
||||||
-m mark --mark 0/$MMX_MASK \
|
-m mark --mark 0/$MMX_MASK \
|
||||||
-j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK
|
-j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK
|
||||||
fi
|
fi
|
||||||
done
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
@ -912,53 +931,64 @@ mwan3_set_sticky_iptables()
|
||||||
mwan3_set_user_iptables_rule()
|
mwan3_set_user_iptables_rule()
|
||||||
{
|
{
|
||||||
local ipset family proto policy src_ip src_port src_iface src_dev
|
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 sticky dest_ip dest_port use_policy timeout policy
|
||||||
local global_logging rule_logging loglevel
|
local global_logging rule_logging loglevel rule_policy rule ipv
|
||||||
|
|
||||||
rule="$1"
|
rule="$1"
|
||||||
|
ipv="$2"
|
||||||
|
rule_policy=0
|
||||||
config_get sticky "$1" sticky 0
|
config_get sticky "$1" sticky 0
|
||||||
config_get timeout "$1" timeout 600
|
config_get timeout "$1" timeout 600
|
||||||
config_get ipset "$1" ipset
|
config_get ipset "$1" ipset
|
||||||
config_get proto "$1" proto all
|
config_get proto "$1" proto all
|
||||||
config_get src_ip "$1" src_ip
|
config_get src_ip "$1" src_ip
|
||||||
config_get src_iface "$1" src_iface
|
config_get src_iface "$1" src_iface
|
||||||
network_get_device src_dev "$src_iface"
|
|
||||||
config_get src_port "$1" src_port
|
config_get src_port "$1" src_port
|
||||||
config_get dest_ip "$1" dest_ip
|
config_get dest_ip "$1" dest_ip
|
||||||
config_get dest_port "$1" dest_port
|
config_get dest_port "$1" dest_port
|
||||||
config_get use_policy "$1" use_policy
|
config_get use_policy "$1" use_policy
|
||||||
config_get family "$1" family any
|
config_get family "$1" family any
|
||||||
|
config_get rule_logging "$1" logging 0
|
||||||
|
config_get global_logging globals logging 0
|
||||||
|
config_get loglevel globals loglevel notice
|
||||||
|
|
||||||
|
if [ -n "$src_iface" ]; then
|
||||||
|
network_get_device src_dev "$src_iface"
|
||||||
|
if [ -z "$src_dev" ]; then
|
||||||
|
LOG notice "could not find device corresponding to src_iface $src_iface for rule $1"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
[ -z "$dest_ip" ] && unset dest_ip
|
[ -z "$dest_ip" ] && unset dest_ip
|
||||||
[ -z "$src_ip" ] && unset src_ip
|
[ -z "$src_ip" ] && unset src_ip
|
||||||
[ -z "$ipset" ] && unset ipset
|
[ -z "$ipset" ] && unset ipset
|
||||||
[ -z "$src_port" ] && unset src_port
|
[ -z "$src_port" ] && unset src_port
|
||||||
[ -z "$dest_port" ] && unset dest_port
|
[ -z "$dest_port" ] && unset dest_port
|
||||||
[ "$proto" != 'tcp' ] && [ "$proto" != 'udp' ] && {
|
if [ "$proto" != 'tcp' ] && [ "$proto" != 'udp' ]; then
|
||||||
[ -n "$src_port" ] && {
|
[ -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"
|
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" ] && {
|
[ -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"
|
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 src_port
|
||||||
unset dest_port
|
unset dest_port
|
||||||
}
|
fi
|
||||||
|
|
||||||
config_get rule_logging "$1" logging 0
|
|
||||||
config_get global_logging globals logging 0
|
|
||||||
config_get loglevel globals loglevel notice
|
|
||||||
|
|
||||||
if [ "$1" != "$(echo "$1" | cut -c1-15)" ]; then
|
if [ "$1" != "$(echo "$1" | cut -c1-15)" ]; then
|
||||||
$LOG warn "Rule $1 exceeds max of 15 chars. Not setting rule" && return 0
|
LOG warn "Rule $1 exceeds max of 15 chars. Not setting rule" && return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$ipset" ]; then
|
if [ -n "$ipset" ]; then
|
||||||
ipset="-m set --match-set $ipset dst"
|
ipset="-m set --match-set $ipset dst"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$use_policy" ]; then
|
if [ -z "$use_policy" ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$use_policy" = "default" ]; then
|
if [ "$use_policy" = "default" ]; then
|
||||||
policy="MARK --set-xmark $MMX_DEFAULT/$MMX_MASK"
|
policy="MARK --set-xmark $MMX_DEFAULT/$MMX_MASK"
|
||||||
elif [ "$use_policy" = "unreachable" ]; then
|
elif [ "$use_policy" = "unreachable" ]; then
|
||||||
|
@ -966,67 +996,53 @@ mwan3_set_user_iptables_rule()
|
||||||
elif [ "$use_policy" = "blackhole" ]; then
|
elif [ "$use_policy" = "blackhole" ]; then
|
||||||
policy="MARK --set-xmark $MMX_BLACKHOLE/$MMX_MASK"
|
policy="MARK --set-xmark $MMX_BLACKHOLE/$MMX_MASK"
|
||||||
else
|
else
|
||||||
if [ "$sticky" -eq 1 ]; then
|
rule_policy=1
|
||||||
|
|
||||||
policy="mwan3_policy_$use_policy"
|
policy="mwan3_policy_$use_policy"
|
||||||
|
if [ "$sticky" -eq 1 ]; then
|
||||||
for IPT in "$IPT4" "$IPT6"; do
|
|
||||||
[ "$IPT" = "$IPT6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
|
||||||
if ! $IPT -S "$policy" &> /dev/null; then
|
|
||||||
$IPT -N "$policy"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! $IPT -S "mwan3_rule_$1" &> /dev/null; then
|
|
||||||
$IPT -N "mwan3_rule_$1"
|
|
||||||
fi
|
|
||||||
|
|
||||||
$IPT -F "mwan3_rule_$1"
|
|
||||||
done
|
|
||||||
|
|
||||||
$IPS -! create "mwan3_sticky_v4_$rule" \
|
$IPS -! create "mwan3_sticky_v4_$rule" \
|
||||||
hash:ip,mark markmask "$MMX_MASK" \
|
hash:ip,mark markmask "$MMX_MASK" \
|
||||||
timeout "$timeout"
|
timeout "$timeout"
|
||||||
|
[ $NO_IPV6 -eq 0 ] &&
|
||||||
$IPS -! create "mwan3_sticky_v6_$rule" \
|
$IPS -! create "mwan3_sticky_v6_$rule" \
|
||||||
hash:ip,mark markmask "$MMX_MASK" \
|
hash:ip,mark markmask "$MMX_MASK" \
|
||||||
timeout "$timeout" family inet6
|
timeout "$timeout" family inet6
|
||||||
$IPS -! create "mwan3_sticky_$rule" list:set
|
$IPS -! create "mwan3_sticky_$rule" list:set
|
||||||
$IPS -! add "mwan3_sticky_$rule" "mwan3_sticky_v4_$rule"
|
$IPS -! add "mwan3_sticky_$rule" "mwan3_sticky_v4_$rule"
|
||||||
|
[ $NO_IPV6 -eq 0 ] &&
|
||||||
$IPS -! add "mwan3_sticky_$rule" "mwan3_sticky_v6_$rule"
|
$IPS -! add "mwan3_sticky_$rule" "mwan3_sticky_v6_$rule"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
config_foreach mwan3_set_sticky_iptables interface
|
[ "$ipv" = "ipv6" ] && [ $NO_IPV6 -ne 0 ] && return
|
||||||
|
[ "$family" = "ipv4" ] && [ "$ipv" = "ipv6" ] && return
|
||||||
|
[ "$family" = "ipv6" ] && [ "$ipv" = "ipv4" ] && return
|
||||||
|
|
||||||
for IPT in "$IPT4" "$IPT6"; do
|
if [ $rule_policy -eq 1 ] && [ -n "${current##*-N $policy*}" ]; then
|
||||||
[ "$IPT" = "$IPT6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
mwan3_push_update -N "$policy"
|
||||||
$IPT -A "mwan3_rule_$1" \
|
fi
|
||||||
|
|
||||||
|
if [ $rule_policy -eq 1 ] && [ "$sticky" -eq 1 ]; then
|
||||||
|
if [ -n "${current##*-N mwan3_rule_$1*}" ]; then
|
||||||
|
mwan3_push_update -N "mwan3_rule_$1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mwan3_push_update -F "mwan3_rule_$1"
|
||||||
|
config_foreach mwan3_set_sticky_iptables interface $ipv
|
||||||
|
|
||||||
|
|
||||||
|
mwan3_push_update -A "mwan3_rule_$1" \
|
||||||
-m mark --mark 0/$MMX_MASK \
|
-m mark --mark 0/$MMX_MASK \
|
||||||
-j "$policy"
|
-j "$policy"
|
||||||
$IPT -A "mwan3_rule_$1" \
|
mwan3_push_update -A "mwan3_rule_$1" \
|
||||||
-m mark ! --mark 0xfc00/0xfc00 \
|
-m mark ! --mark 0xfc00/0xfc00 \
|
||||||
-j SET --del-set "mwan3_sticky_$rule" src,src
|
-j SET --del-set "mwan3_sticky_$rule" src,src
|
||||||
$IPT -A "mwan3_rule_$1" \
|
mwan3_push_update -A "mwan3_rule_$1" \
|
||||||
-m mark ! --mark 0xfc00/0xfc00 \
|
-m mark ! --mark 0xfc00/0xfc00 \
|
||||||
-j SET --add-set "mwan3_sticky_$rule" src,src
|
-j SET --add-set "mwan3_sticky_$rule" src,src
|
||||||
done
|
|
||||||
|
|
||||||
policy="mwan3_rule_$1"
|
policy="mwan3_rule_$1"
|
||||||
else
|
|
||||||
policy="mwan3_policy_$use_policy"
|
|
||||||
|
|
||||||
for IPT in "$IPT4" "$IPT6"; do
|
|
||||||
[ "$IPT" = "$IPT6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
|
||||||
if ! $IPT -S "$policy" &> /dev/null; then
|
|
||||||
$IPT -N "$policy"
|
|
||||||
fi
|
fi
|
||||||
done
|
if [ "$global_logging" = "1" ] && [ "$rule_logging" = "1" ]; then
|
||||||
|
mwan3_push_update -A mwan3_rules \
|
||||||
fi
|
|
||||||
fi
|
|
||||||
for IPT in "$IPT4" "$IPT6"; do
|
|
||||||
[ "$IPT" = "$IPT6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
|
||||||
[ "$family" = "ipv4" ] && [ "$IPT" = "$IPT6" ] && continue
|
|
||||||
[ "$family" = "ipv6" ] && [ "$IPT" = "$IPT4" ] && continue
|
|
||||||
[ "$global_logging" = "1" ] && [ "$rule_logging" = "1" ] && {
|
|
||||||
$IPT -A mwan3_rules \
|
|
||||||
-p "$proto" \
|
-p "$proto" \
|
||||||
${src_ip:+-s} $src_ip \
|
${src_ip:+-s} $src_ip \
|
||||||
${src_dev:+-i} $src_dev \
|
${src_dev:+-i} $src_dev \
|
||||||
|
@ -1037,9 +1053,9 @@ mwan3_set_user_iptables_rule()
|
||||||
-m mark --mark 0/$MMX_MASK \
|
-m mark --mark 0/$MMX_MASK \
|
||||||
-m comment --comment "$1" \
|
-m comment --comment "$1" \
|
||||||
-j LOG --log-level "$loglevel" --log-prefix "MWAN3($1)"
|
-j LOG --log-level "$loglevel" --log-prefix "MWAN3($1)"
|
||||||
}
|
fi
|
||||||
|
|
||||||
$IPT -A mwan3_rules \
|
mwan3_push_update -A mwan3_rules \
|
||||||
-p "$proto" \
|
-p "$proto" \
|
||||||
${src_ip:+-s} $src_ip \
|
${src_ip:+-s} $src_ip \
|
||||||
${src_dev:+-i} $src_dev \
|
${src_dev:+-i} $src_dev \
|
||||||
|
@ -1049,24 +1065,75 @@ mwan3_set_user_iptables_rule()
|
||||||
${dest_port:+-m} ${dest_port:+multiport} ${dest_port:+--dports} $dest_port \
|
${dest_port:+-m} ${dest_port:+multiport} ${dest_port:+--dports} $dest_port \
|
||||||
-m mark --mark 0/$MMX_MASK \
|
-m mark --mark 0/$MMX_MASK \
|
||||||
-j $policy
|
-j $policy
|
||||||
done
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mwan3_set_user_iface_rules()
|
||||||
|
{
|
||||||
|
local current iface update family error device is_src_iface
|
||||||
|
iface=$1
|
||||||
|
device=$2
|
||||||
|
|
||||||
|
if [ -z "$device" ]; then
|
||||||
|
LOG notice "set_user_iface_rules: could not find device corresponding to iface $iface"
|
||||||
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
config_get family "$iface" family ipv4
|
||||||
|
|
||||||
|
if [ "$family" = "ipv4" ]; then
|
||||||
|
IPT="$IPT4"
|
||||||
|
IPTR="$IPT4R"
|
||||||
|
elif [ "$family" = "ipv6" ]; then
|
||||||
|
IPT="$IPT6"
|
||||||
|
IPTR="$IPT6R"
|
||||||
|
fi
|
||||||
|
$IPT -S | grep -q "^-A mwan3_rules.*-i $device" && return
|
||||||
|
|
||||||
|
is_src_iface=0
|
||||||
|
|
||||||
|
iface_rule()
|
||||||
|
{
|
||||||
|
local src_iface
|
||||||
|
config_get src_iface "$1" src_iface
|
||||||
|
[ "$src_iface" = "$iface" ] && is_src_iface=1
|
||||||
|
}
|
||||||
|
config_foreach iface_rule rule
|
||||||
|
[ $is_src_iface -eq 1 ] && mwan3_set_user_rules
|
||||||
}
|
}
|
||||||
|
|
||||||
mwan3_set_user_rules()
|
mwan3_set_user_rules()
|
||||||
{
|
{
|
||||||
local IPT
|
local IPT IPTR ipv
|
||||||
|
local current update error
|
||||||
|
|
||||||
for IPT in "$IPT4" "$IPT6"; do
|
for ipv in ipv4 ipv6; do
|
||||||
[ "$IPT" = "$IPT6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
if [ "$ipv" = "ipv4" ]; then
|
||||||
if ! $IPT -S mwan3_rules &> /dev/null; then
|
IPT="$IPT4"
|
||||||
$IPT -N mwan3_rules
|
IPTR="$IPT4R"
|
||||||
|
elif [ "$ipv" = "ipv6" ]; then
|
||||||
|
IPT="$IPT6"
|
||||||
|
IPTR="$IPT6R"
|
||||||
|
fi
|
||||||
|
[ "$ipv" = "ipv6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
||||||
|
update="*mangle"
|
||||||
|
current="$($IPT -S)"
|
||||||
|
|
||||||
|
|
||||||
|
if [ -n "${current##*-N mwan3_rules*}" ]; then
|
||||||
|
mwan3_push_update -N "mwan3_rules"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$IPT -F mwan3_rules
|
mwan3_push_update -F mwan3_rules
|
||||||
|
|
||||||
|
config_foreach mwan3_set_user_iptables_rule rule "$ipv"
|
||||||
|
|
||||||
|
mwan3_push_update COMMIT
|
||||||
|
mwan3_push_update ""
|
||||||
|
error=$(echo "$update" | $IPTR 2>&1) || LOG error "set_user_rules: $error"
|
||||||
done
|
done
|
||||||
|
|
||||||
config_foreach mwan3_set_user_iptables_rule rule
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mwan3_set_iface_hotplug_state() {
|
mwan3_set_iface_hotplug_state() {
|
||||||
|
@ -1228,7 +1295,7 @@ mwan3_flush_conntrack()
|
||||||
|
|
||||||
if [ "$action" = "$flush_conntrack" ]; then
|
if [ "$action" = "$flush_conntrack" ]; then
|
||||||
echo f > ${CONNTRACK_FILE}
|
echo f > ${CONNTRACK_FILE}
|
||||||
$LOG info "Connection tracking flushed for interface '$interface' on action '$action'"
|
LOG info "Connection tracking flushed for interface '$interface' on action '$action'"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1240,9 +1307,5 @@ mwan3_flush_conntrack()
|
||||||
mwan3_track_clean()
|
mwan3_track_clean()
|
||||||
{
|
{
|
||||||
rm -rf "$MWAN3_STATUS_DIR/${1}" &> /dev/null
|
rm -rf "$MWAN3_STATUS_DIR/${1}" &> /dev/null
|
||||||
[ -d "$MWAN3_STATUS_DIR" ] && {
|
rmdir --ignore-fail-on-non-empty "$MWAN3_STATUS_DIR"
|
||||||
if [ -z "$(ls -A "$MWAN3_STATUS_DIR")" ]; then
|
|
||||||
rm -rf "$MWAN3_STATUS_DIR"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
. /usr/share/libubox/jshn.sh
|
. /usr/share/libubox/jshn.sh
|
||||||
. /lib/functions/network.sh
|
. /lib/functions/network.sh
|
||||||
. /lib/mwan3/mwan3.sh
|
. /lib/mwan3/mwan3.sh
|
||||||
|
. /lib/mwan3/common.sh
|
||||||
|
|
||||||
help()
|
help()
|
||||||
{
|
{
|
||||||
|
@ -37,52 +38,64 @@ ifdown()
|
||||||
|
|
||||||
ACTION=ifdown INTERFACE=$1 /sbin/hotplug-call iface
|
ACTION=ifdown INTERFACE=$1 /sbin/hotplug-call iface
|
||||||
|
|
||||||
kill $(pgrep -f "mwan3track $1 $2") &> /dev/null
|
kill $(pgrep -f "mwan3track $1 ") &> /dev/null
|
||||||
mwan3_track_clean $1
|
mwan3_track_clean $1
|
||||||
}
|
}
|
||||||
|
|
||||||
ifup()
|
ifup()
|
||||||
{
|
{
|
||||||
local device enabled up l3_device status
|
local device enabled up l3_device status interface true_iface
|
||||||
|
|
||||||
mwan3_lock "command" "mwan3"
|
if [ -z "$1" ]; then
|
||||||
|
echo "Expecting interface. Usage: mwan3 ifup <interface>"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$2" ]; then
|
||||||
|
echo "Too many arguments. Usage: mwan3 ifup <interface>"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
interface=$1
|
||||||
|
|
||||||
|
if [ "${MWAN3_STARTUP}" != 1 ]; then
|
||||||
|
# It is not necessary to obtain a lock here, because it is obtained in the hotplug
|
||||||
|
# script, but we still want to do the check to print a useful error message
|
||||||
config_load mwan3
|
config_load mwan3
|
||||||
config_get_bool enabled globals 'enabled' 0
|
config_get_bool enabled globals 'enabled' 0
|
||||||
|
|
||||||
[ ${enabled} -gt 0 ] || {
|
[ ${enabled} -gt 0 ] || {
|
||||||
echo "The service mwan3 is global disabled."
|
echo "The service mwan3 is global disabled."
|
||||||
echo "Please execute \"/etc/init.d/mwan3 start\" first."
|
echo "Please execute \"/etc/init.d/mwan3 start\" first."
|
||||||
mwan3_unlock "command" "mwan3"
|
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if [ -z "$1" ]; then
|
enabled=1
|
||||||
echo "Expecting interface. Usage: mwan3 ifup <interface>"
|
|
||||||
mwan3_unlock "command" "mwan3"
|
|
||||||
exit 0
|
|
||||||
fi
|
fi
|
||||||
|
mwan3_get_true_iface true_iface $interface
|
||||||
|
status=$(ubus -S call network.interface.$true_iface status)
|
||||||
|
|
||||||
if [ -n "$2" ]; then
|
|
||||||
echo "Too many arguments. Usage: mwan3 ifup <interface>"
|
|
||||||
mwan3_unlock "command" "mwan3"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
config_get enabled "$1" enabled 0
|
|
||||||
mwan3_unlock "command" "mwan3"
|
|
||||||
|
|
||||||
status=$(ubus -S call network.interface.$1 status)
|
|
||||||
[ -n "$status" ] && {
|
[ -n "$status" ] && {
|
||||||
json_load "$status"
|
json_load "$status"
|
||||||
json_get_vars up l3_device
|
json_get_vars up l3_device
|
||||||
}
|
}
|
||||||
|
hotplug_startup()
|
||||||
|
{
|
||||||
|
MWAN3_STARTUP=$MWAN3_STARTUP ACTION=ifup INTERFACE=$interface DEVICE=$l3_device TRUE_INTERFACE=$true_iface sh /etc/hotplug.d/iface/15-mwan3
|
||||||
|
MWAN3_STARTUP=$MWAN3_STARTUP ACTION=ifup INTERFACE=$interface DEVICE=$l3_device TRUE_INTERFACE=$true_iface sh /etc/hotplug.d/iface/16-mwan3-user
|
||||||
|
}
|
||||||
|
|
||||||
if [ "$up" = "1" ] \
|
if [ "$up" != "1" ] || [ -z "$l3_device" ] || [ "$enabled" != "1" ]; then
|
||||||
&& [ -n "$l3_device" ] \
|
return
|
||||||
&& [ "$enabled" = "1" ]; then
|
|
||||||
ACTION=ifup INTERFACE=$1 DEVICE=$l3_device /sbin/hotplug-call iface
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "${MWAN3_STARTUP}" = 1 ]; then
|
||||||
|
hotplug_startup &
|
||||||
|
hotplug_pids="$hotplug_pids $!"
|
||||||
|
else
|
||||||
|
hotplug_startup
|
||||||
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interfaces()
|
interfaces()
|
||||||
|
@ -137,24 +150,37 @@ status()
|
||||||
|
|
||||||
start()
|
start()
|
||||||
{
|
{
|
||||||
local enabled
|
local enabled hotplug_pids MWAN3_STARTUP
|
||||||
|
MWAN3_STARTUP=1
|
||||||
mwan3_lock "command" "mwan3"
|
mwan3_lock "command" "mwan3"
|
||||||
uci_toggle_state mwan3 globals enabled "1"
|
uci_toggle_state mwan3 globals enabled "1"
|
||||||
mwan3_unlock "command" "mwan3"
|
|
||||||
|
|
||||||
config_load mwan3
|
config_load mwan3
|
||||||
|
|
||||||
|
mwan3_update_iface_to_table
|
||||||
|
mwan3_set_connected_iptables
|
||||||
|
mwan3_set_custom_ipset
|
||||||
|
mwan3_set_general_rules
|
||||||
|
mwan3_set_general_iptables
|
||||||
config_foreach ifup interface
|
config_foreach ifup interface
|
||||||
|
wait $hotplug_pids
|
||||||
|
mwan3_add_all_nondefault_routes
|
||||||
|
mwan3_set_policies_iptables
|
||||||
|
mwan3_set_user_rules
|
||||||
|
|
||||||
|
|
||||||
|
mwan3_unlock "command" "mwan3"
|
||||||
mwan3_rtmon
|
mwan3_rtmon
|
||||||
|
unset MWAN3_STARTUP
|
||||||
}
|
}
|
||||||
|
|
||||||
stop()
|
stop()
|
||||||
{
|
{
|
||||||
local ipset route rule table IP IPT pid
|
local ipset rule IP IPTR IPT kill_pid family table tid
|
||||||
|
|
||||||
mwan3_lock "command" "mwan3"
|
mwan3_lock "command" "mwan3"
|
||||||
uci_toggle_state mwan3 globals enabled "0"
|
uci_toggle_state mwan3 globals enabled "0"
|
||||||
|
|
||||||
|
{
|
||||||
kill -TERM $(pgrep -f "mwan3rtmon") > /dev/null 2>&1
|
kill -TERM $(pgrep -f "mwan3rtmon") > /dev/null 2>&1
|
||||||
kill -TERM $(pgrep -f "mwan3track") > /dev/null 2>&1
|
kill -TERM $(pgrep -f "mwan3track") > /dev/null 2>&1
|
||||||
|
|
||||||
|
@ -162,33 +188,40 @@ stop()
|
||||||
|
|
||||||
kill -KILL $(pgrep -f "mwan3rtmon") > /dev/null 2>&1
|
kill -KILL $(pgrep -f "mwan3rtmon") > /dev/null 2>&1
|
||||||
kill -KILL $(pgrep -f "mwan3track") > /dev/null 2>&1
|
kill -KILL $(pgrep -f "mwan3track") > /dev/null 2>&1
|
||||||
|
} &
|
||||||
|
kill_pid=$!
|
||||||
config_load mwan3
|
config_load mwan3
|
||||||
config_foreach mwan3_track_clean interface
|
config_foreach mwan3_track_clean interface
|
||||||
|
|
||||||
for IP in "$IP4" "$IP6"; do
|
for family in ipv4 ipv6; do
|
||||||
[ "$IP" = "$IP6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
if [ "$family" = "ipv4" ]; then
|
||||||
for route in $(seq 1 $MWAN3_INTERFACE_MAX); do
|
IPT="$IPT4"
|
||||||
$IP route flush table $route &> /dev/null
|
IPTR="$IPT4R"
|
||||||
|
IP="$IP4"
|
||||||
|
elif [ "$family" = "ipv6" ]; then
|
||||||
|
[ $NO_IPV6 -ne 0 ] && continue
|
||||||
|
IPT="$IPT6"
|
||||||
|
IPTR="$IPT6R"
|
||||||
|
IP="$IP6"
|
||||||
|
fi
|
||||||
|
|
||||||
|
for tid in $(ip route list table all | sed -ne 's/.*table \([0-9]\+\).*/\1/p'|sort -u); do
|
||||||
|
[ $tid -gt $MWAN3_INTERFACE_MAX ] && continue
|
||||||
|
$IP route flush table $tid &> /dev/null
|
||||||
done
|
done
|
||||||
|
|
||||||
for rule in $($IP rule list | egrep '^[1-2][0-9]{3}\:' | cut -d ':' -f 1); do
|
for rule in $($IP rule list | egrep '^[1-2][0-9]{3}\:' | cut -d ':' -f 1); do
|
||||||
$IP rule del pref $rule &> /dev/null
|
$IP rule del pref $rule &> /dev/null
|
||||||
done
|
done
|
||||||
done
|
table="$($IPT -S)"
|
||||||
|
{
|
||||||
for IPT in "$IPT4" "$IPT6"; do
|
echo "*mangle";
|
||||||
[ "$IPT" = "$IPT6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
[ -z "${table##*PREROUTING -j mwan3_hook*}" ] && echo "-D PREROUTING -j mwan3_hook"
|
||||||
$IPT -D PREROUTING -j mwan3_hook &> /dev/null
|
[ -z "${table##*OUTPUT -j mwan3_hook*}" ] && echo "-D OUTPUT -j mwan3_hook"
|
||||||
$IPT -D OUTPUT -j mwan3_hook &> /dev/null
|
echo "$table" | awk '{print "-F "$2}' | grep mwan3 | sort -u
|
||||||
|
echo "$table" | awk '{print "-X "$2}' | grep mwan3 | sort -u
|
||||||
for table in $($IPT -S | awk '{print $2}' | grep mwan3 | sort -u); do
|
echo "COMMIT"
|
||||||
$IPT -F $table &> /dev/null
|
} | $IPTR
|
||||||
done
|
|
||||||
|
|
||||||
for table in $($IPT -S | awk '{print $2}' | grep mwan3 | sort -u); do
|
|
||||||
$IPT -X $table &> /dev/null
|
|
||||||
done
|
|
||||||
done
|
done
|
||||||
|
|
||||||
for ipset in $($IPS -n list | grep mwan3_); do
|
for ipset in $($IPS -n list | grep mwan3_); do
|
||||||
|
@ -199,9 +232,19 @@ stop()
|
||||||
$IPS -q destroy $ipset
|
$IPS -q destroy $ipset
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if ! pgrep -f "mwan3track" >/dev/null && ! pgrep -f "mwan3rtmon" >/dev/null; then
|
||||||
|
# mwan3track has already exited, no need to send
|
||||||
|
# TERM signal
|
||||||
|
kill $kill_pid 2>/dev/null
|
||||||
|
else
|
||||||
|
# mwan3track has not exited, wait for the killer
|
||||||
|
# to do its work
|
||||||
|
wait $kill_pid
|
||||||
|
fi
|
||||||
|
rm -rf $MWAN3_STATUS_DIR $MWAN3TRACK_STATUS_DIR
|
||||||
|
|
||||||
mwan3_unlock "command" "mwan3"
|
mwan3_unlock "command" "mwan3"
|
||||||
|
|
||||||
rm -rf $MWAN3_STATUS_DIR $MWAN3TRACK_STATUS_DIR
|
|
||||||
}
|
}
|
||||||
|
|
||||||
restart() {
|
restart() {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
. /lib/functions.sh
|
. /lib/functions.sh
|
||||||
. /lib/functions/network.sh
|
. /lib/functions/network.sh
|
||||||
. /lib/mwan3/mwan3.sh
|
. /lib/mwan3/mwan3.sh
|
||||||
|
. /lib/mwan3/common.sh
|
||||||
|
|
||||||
mwan3_rtmon_route_handle()
|
mwan3_rtmon_route_handle()
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,60 +3,107 @@
|
||||||
. /lib/functions.sh
|
. /lib/functions.sh
|
||||||
. /lib/mwan3/common.sh
|
. /lib/mwan3/common.sh
|
||||||
|
|
||||||
LOG="logger -t $(basename "$0")[$$] -p"
|
|
||||||
INTERFACE=""
|
INTERFACE=""
|
||||||
DEVICE=""
|
DEVICE=""
|
||||||
PING="/bin/ping"
|
PING="/bin/ping"
|
||||||
|
|
||||||
IFDOWN_EVENT=0
|
IFDOWN_EVENT=0
|
||||||
|
IFUP_EVENT=0
|
||||||
|
|
||||||
clean_up() {
|
clean_up() {
|
||||||
$LOG notice "Stopping mwan3track for interface \"${INTERFACE}\""
|
LOG notice "Stopping mwan3track for interface \"${INTERFACE}\""
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if_down() {
|
if_down() {
|
||||||
$LOG info "Detect ifdown event on interface ${INTERFACE} (${DEVICE})"
|
LOG info "Detect ifdown event on interface ${INTERFACE} (${DEVICE})"
|
||||||
IFDOWN_EVENT=1
|
IFDOWN_EVENT=1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if_up() {
|
||||||
|
LOG info "Detect ifup event on interface ${INTERFACE} (${DEVICE})"
|
||||||
|
IFUP_EVENT=1
|
||||||
|
}
|
||||||
|
|
||||||
validate_track_method() {
|
validate_track_method() {
|
||||||
case "$1" in
|
case "$1" in
|
||||||
ping)
|
ping)
|
||||||
command -v ping 1>/dev/null 2>&1 || {
|
[ -x "$PING" ] || {
|
||||||
$LOG warn "Missing ping. Please install iputils-ping package or enable ping util and recompile busybox."
|
LOG warn "Missing ping. Please enable ping util and recompile busybox."
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
;;
|
;;
|
||||||
arping)
|
arping)
|
||||||
command -v arping 1>/dev/null 2>&1 || {
|
command -v arping 1>/dev/null 2>&1 || {
|
||||||
$LOG warn "Missing arping. Please install iputils-arping package."
|
LOG warn "Missing arping. Please install iputils-arping package."
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
;;
|
;;
|
||||||
httping)
|
httping)
|
||||||
command -v httping 1>/dev/null 2>&1 || {
|
command -v httping 1>/dev/null 2>&1 || {
|
||||||
$LOG warn "Missing httping. Please install httping package."
|
LOG warn "Missing httping. Please install httping package."
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
[ -n "$2" -a "$2" != "0.0.0.0" -a "$2" != "::" ] || {
|
[ -n "$2" -a "$2" != "0.0.0.0" -a "$2" != "::" ] || {
|
||||||
$LOG warn "Cannot determine source IP for the interface which is required by httping."
|
LOG warn "Cannot determine source IP for the interface which is required by httping."
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
;;
|
;;
|
||||||
nping-*)
|
nping-*)
|
||||||
command -v nping 1>/dev/null 2>&1 || {
|
command -v nping 1>/dev/null 2>&1 || {
|
||||||
$LOG warn "Missing nping. Please install nping package."
|
LOG warn "Missing nping. Please install nping package."
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
$LOG warn "Unsupported tracking method: $track_method"
|
LOG warn "Unsupported tracking method: $track_method"
|
||||||
return 2
|
return 2
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disconnected() {
|
||||||
|
echo "offline" > /var/run/mwan3track/$INTERFACE/STATUS
|
||||||
|
echo "$(get_uptime)" > /var/run/mwan3track/$INTERFACE/OFFLINE
|
||||||
|
echo "0" > /var/run/mwan3track/$INTERFACE/ONLINE
|
||||||
|
score=0
|
||||||
|
[ "$1" == 1 ] && return
|
||||||
|
LOG notice "Interface $INTERFACE ($DEVICE) is offline"
|
||||||
|
env -i ACTION="disconnected" INTERFACE="$INTERFACE" DEVICE="$DEVICE" /sbin/hotplug-call iface
|
||||||
|
}
|
||||||
|
|
||||||
|
connected() {
|
||||||
|
echo "online" > /var/run/mwan3track/$INTERFACE/STATUS
|
||||||
|
echo "0" > /var/run/mwan3track/$INTERFACE/OFFLINE
|
||||||
|
echo "$(get_uptime)" > /var/run/mwan3track/$INTERFACE/ONLINE
|
||||||
|
host_up_count=0
|
||||||
|
lost=0
|
||||||
|
turn=0
|
||||||
|
loss=0
|
||||||
|
[ "$1" == 1 ] && return
|
||||||
|
LOG notice "Interface $INTERFACE ($DEVICE) is online"
|
||||||
|
env -i ACTION="connected" INTERFACE="$INTERFACE" DEVICE="$DEVICE" /sbin/hotplug-call iface
|
||||||
|
}
|
||||||
|
|
||||||
|
firstconnect() {
|
||||||
|
if [ "$STATUS" = "offline" ]; then
|
||||||
|
disconnected 1
|
||||||
|
else
|
||||||
|
connected 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
update_status() {
|
||||||
|
local status track_ip
|
||||||
|
track_ip=$1
|
||||||
|
status=$2
|
||||||
|
|
||||||
|
echo "$1" > /var/run/mwan3track/$INTERFACE/TRACK_${track_ip}
|
||||||
|
[ -z "$3" ] && return
|
||||||
|
echo "$3" > /var/run/mwan3track/$INTERFACE/LATENCY_${track_ip}
|
||||||
|
echo "$4" > /var/run/mwan3track/$INTERFACE/LOSS_${track_ip}
|
||||||
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
local reliability count timeout interval failure_interval
|
local reliability count timeout interval failure_interval
|
||||||
local recovery_interval down up size
|
local recovery_interval down up size
|
||||||
|
@ -70,64 +117,49 @@ main() {
|
||||||
DEVICE=$2
|
DEVICE=$2
|
||||||
STATUS=$3
|
STATUS=$3
|
||||||
SRC_IP=$4
|
SRC_IP=$4
|
||||||
mkdir -p /var/run/mwan3track/$1
|
mkdir -p /var/run/mwan3track/$INTERFACE
|
||||||
trap clean_up TERM
|
trap clean_up TERM
|
||||||
trap if_down USR1
|
trap if_down USR1
|
||||||
|
trap if_up USR2
|
||||||
|
|
||||||
config_load mwan3
|
config_load mwan3
|
||||||
config_get track_method $1 track_method ping
|
config_get track_method $INTERFACE track_method ping
|
||||||
config_get_bool httping_ssl $1 httping_ssl 0
|
config_get_bool httping_ssl $INTERFACE httping_ssl 0
|
||||||
validate_track_method $track_method $SRC_IP || {
|
validate_track_method $track_method $SRC_IP || {
|
||||||
track_method=ping
|
track_method=ping
|
||||||
if validate_track_method $track_method; then
|
if validate_track_method $track_method; then
|
||||||
$LOG warn "Using ping to track interface $INTERFACE avaliability"
|
LOG warn "Using ping to track interface $INTERFACE avaliability"
|
||||||
else
|
else
|
||||||
$LOG err "No track method avaliable"
|
LOG err "No track method avaliable"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
config_get reliability $1 reliability 1
|
config_get reliability $INTERFACE reliability 1
|
||||||
config_get count $1 count 1
|
config_get count $INTERFACE count 1
|
||||||
config_get timeout $1 timeout 4
|
config_get timeout $INTERFACE timeout 4
|
||||||
config_get interval $1 interval 10
|
config_get interval $INTERFACE interval 10
|
||||||
config_get down $1 down 5
|
config_get down $INTERFACE down 5
|
||||||
config_get up $1 up 5
|
config_get up $INTERFACE up 5
|
||||||
config_get size $1 size 56
|
config_get size $INTERFACE size 56
|
||||||
config_get max_ttl $1 max_ttl 60
|
config_get max_ttl $INTERFACE max_ttl 60
|
||||||
config_get failure_interval $1 failure_interval $interval
|
config_get failure_interval $INTERFACE failure_interval $interval
|
||||||
config_get_bool keep_failure_interval $1 keep_failure_interval 0
|
config_get_bool keep_failure_interval $INTERFACE keep_failure_interval 0
|
||||||
config_get recovery_interval $1 recovery_interval $interval
|
config_get recovery_interval $INTERFACE recovery_interval $interval
|
||||||
config_get_bool check_quality $1 check_quality 0
|
config_get_bool check_quality $INTERFACE check_quality 0
|
||||||
config_get failure_latency $1 failure_latency 1000
|
config_get failure_latency $INTERFACE failure_latency 1000
|
||||||
config_get recovery_latency $1 recovery_latency 500
|
config_get recovery_latency $INTERFACE recovery_latency 500
|
||||||
config_get failure_loss $1 failure_loss 40
|
config_get failure_loss $INTERFACE failure_loss 40
|
||||||
config_get recovery_loss $1 recovery_loss 10
|
config_get recovery_loss $INTERFACE recovery_loss 10
|
||||||
|
|
||||||
local score=$(($down+$up))
|
local score=$(($down+$up))
|
||||||
local track_ips=$(echo $* | cut -d ' ' -f 5-99)
|
local track_ips=$(echo $* | cut -d ' ' -f 5-99)
|
||||||
local host_up_count=0
|
local host_up_count=0
|
||||||
local lost=0
|
local lost=0
|
||||||
local sleep_time=0
|
|
||||||
local turn=0
|
local turn=0
|
||||||
local result
|
|
||||||
local ping_protocol=4
|
local ping_protocol=4
|
||||||
local ping_result
|
local sleep_time result ping_result ping_result_raw ping_status loss latency
|
||||||
local ping_result_raw
|
|
||||||
local ping_status
|
|
||||||
local loss=0
|
|
||||||
local latency=0
|
|
||||||
|
|
||||||
if [ "$STATUS" = "offline" ]; then
|
firstconnect
|
||||||
echo "offline" > /var/run/mwan3track/$1/STATUS
|
|
||||||
echo "0" > /var/run/mwan3track/$1/ONLINE
|
|
||||||
echo "$(get_uptime)" > /var/run/mwan3track/$1/OFFLINE
|
|
||||||
score=0
|
|
||||||
else
|
|
||||||
echo "online" > /var/run/mwan3track/$1/STATUS
|
|
||||||
echo "0" > /var/run/mwan3track/$1/OFFLINE
|
|
||||||
echo "$(get_uptime)" > /var/run/mwan3track/$1/ONLINE
|
|
||||||
env -i ACTION="connected" INTERFACE="$1" DEVICE="$2" /sbin/hotplug-call iface
|
|
||||||
fi
|
|
||||||
while true; do
|
while true; do
|
||||||
|
|
||||||
sleep_time=$interval
|
sleep_time=$interval
|
||||||
|
@ -139,16 +171,16 @@ main() {
|
||||||
# pinging IPv6 hosts with an interface is troublesome
|
# pinging IPv6 hosts with an interface is troublesome
|
||||||
# https://bugs.openwrt.org/index.php?do=details&task_id=2897
|
# https://bugs.openwrt.org/index.php?do=details&task_id=2897
|
||||||
# so get the IP address of the interface and use that instead
|
# so get the IP address of the interface and use that instead
|
||||||
if echo $track_ip | grep -q ':'; then
|
if [ -z ${track_ip##*:*} ]; then
|
||||||
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
|
ping_protocol=6
|
||||||
|
else
|
||||||
|
unset SRC_IP
|
||||||
fi
|
fi
|
||||||
if [ $check_quality -eq 0 ]; then
|
if [ $check_quality -eq 0 ]; then
|
||||||
$PING -$ping_protocol -I ${ADDR:-$DEVICE} -c $count -W $timeout -s $size -t $max_ttl -q $track_ip &> /dev/null
|
$PING -$ping_protocol -I ${SRC_IP:-$DEVICE} -c $count -W $timeout -s $size -t $max_ttl -q $track_ip &> /dev/null
|
||||||
result=$?
|
result=$?
|
||||||
else
|
else
|
||||||
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_result_raw="$($PING -$ping_protocol -I ${SRC_IP:-$DEVICE} -c $count -W $timeout -s $size -t $max_ttl -q $track_ip 2>/dev/null)"
|
||||||
ping_status=$?
|
ping_status=$?
|
||||||
ping_result=$(echo "$ping_result_raw" | tail -n2)
|
ping_result=$(echo "$ping_result_raw" | tail -n2)
|
||||||
loss="$(echo "$ping_result" | grep "packet loss" | cut -d "," -f3 | awk '{print $1}' | sed -e 's/%//')"
|
loss="$(echo "$ping_result" | grep "packet loss" | cut -d "," -f3 | awk '{print $1}' | sed -e 's/%//')"
|
||||||
|
@ -188,42 +220,40 @@ main() {
|
||||||
if [ $check_quality -eq 0 ]; then
|
if [ $check_quality -eq 0 ]; then
|
||||||
if [ $result -eq 0 ]; then
|
if [ $result -eq 0 ]; then
|
||||||
let host_up_count++
|
let host_up_count++
|
||||||
echo "up" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
update_status "$track_ip" "up"
|
||||||
|
|
||||||
if [ $score -le $up ]; then
|
if [ $score -le $up ]; then
|
||||||
$LOG info "Check ($track_method) success for target \"$track_ip\" on interface $1 ($2)"
|
LOG info "Check ($track_method) success for target \"$track_ip\" on interface $INTERFACE ($DEVICE). Current score: $score"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
let lost++
|
let lost++
|
||||||
echo "down" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
update_status "$track_ip" "down"
|
||||||
|
|
||||||
if [ $score -gt $up ]; then
|
if [ $score -gt $up ]; then
|
||||||
$LOG info "Check ($track_method) failed for target \"$track_ip\" on interface $1 ($2)"
|
LOG info "Check ($track_method) failed for target \"$track_ip\" on interface $INTERFACE ($DEVICE). Current score: $score"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [ "$loss" -ge "$failure_loss" -o "$latency" -ge "$failure_latency" ]; then
|
if [ "$loss" -ge "$failure_loss" -o "$latency" -ge "$failure_latency" ]; then
|
||||||
let lost++
|
let lost++
|
||||||
echo "down" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
update_status "$track_ip" "down" $latency $loss
|
||||||
echo "$latency" > /var/run/mwan3track/$1/LATENCY_${track_ip}
|
|
||||||
echo "$loss" > /var/run/mwan3track/$1/LOSS_${track_ip}
|
|
||||||
|
|
||||||
if [ $score -gt $up ]; then
|
if [ $score -gt $up ]; then
|
||||||
$LOG info "Check (${track_method}: latency=${latency}ms loss=${loss}%) failed for target \"$track_ip\" on interface $1 ($2)"
|
LOG info "Check (${track_method}: latency=${latency}ms loss=${loss}%) failed for target \"$track_ip\" on interface $INTERFACE ($DEVICE). Current score: $score"
|
||||||
fi
|
fi
|
||||||
elif [ "$loss" -le "$recovery_loss" -a "$latency" -le "$recovery_latency" ]; then
|
elif [ "$loss" -le "$recovery_loss" -a "$latency" -le "$recovery_latency" ]; then
|
||||||
let host_up_count++
|
let host_up_count++
|
||||||
echo "up" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
update_status "$track_ip" "up" $latency $loss
|
||||||
echo "$latency" > /var/run/mwan3track/$1/LATENCY_${track_ip}
|
|
||||||
echo "$loss" > /var/run/mwan3track/$1/LOSS_${track_ip}
|
|
||||||
|
|
||||||
if [ $score -le $up ]; then
|
if [ $score -le $up ]; then
|
||||||
$LOG info "Check (${track_method}: latency=${latency}ms loss=${loss}%) success for target \"$track_ip\" on interface $1 ($2)"
|
LOG info "Check (${track_method}: latency=${latency}ms loss=${loss}%) success for target \"$track_ip\" on interface $INTERFACE ($DEVICE). Current score: $score"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "skipped" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
echo "skipped" > /var/run/mwan3track/$INTERFACE/TRACK_${track_ip}
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "skipped" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
echo "skipped" > /var/run/mwan3track/$INTERFACE/TRACK_${track_ip}
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@ -240,53 +270,50 @@ main() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $score -eq $up ]; then
|
if [ $score -eq $up ]; then
|
||||||
echo "offline" > /var/run/mwan3track/$1/STATUS
|
disconnected
|
||||||
env -i ACTION=ifdown INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface
|
|
||||||
score=0
|
score=0
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [ $score -lt $(($down+$up)) ] && [ $lost -gt 0 ]; then
|
if [ $score -lt $(($down+$up)) ] && [ $lost -gt 0 ]; then
|
||||||
$LOG info "Lost $(($lost*$count)) ping(s) on interface $1 ($2)"
|
LOG info "Lost $(($lost*$count)) ping(s) on interface $INTERFACE ($DEVICE). Current score: $score"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
let score++
|
let score++
|
||||||
lost=0
|
lost=0
|
||||||
|
|
||||||
if [ $score -gt $up ]; then
|
if [ $score -gt $up ]; then
|
||||||
echo "online" > /var/run/mwan3track/$1/STATUS
|
echo "online" > /var/run/mwan3track/$INTERFACE/STATUS
|
||||||
score=$(($down+$up))
|
score=$(($down+$up))
|
||||||
elif [ $score -le $up ]; then
|
elif [ $score -le $up ]; then
|
||||||
sleep_time=$recovery_interval
|
sleep_time=$recovery_interval
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $score -eq $up ]; then
|
if [ $score -eq $up ]; then
|
||||||
$LOG notice "Interface $1 ($2) is online"
|
connected $INTERFACE $DEVICE
|
||||||
echo "online" > /var/run/mwan3track/$1/STATUS
|
|
||||||
env -i ACTION=ifup INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface
|
|
||||||
exit 0
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
let turn++
|
let turn++
|
||||||
mkdir -p "/var/run/mwan3track/${1}"
|
mkdir -p "/var/run/mwan3track/${1}"
|
||||||
echo "${lost}" > /var/run/mwan3track/$1/LOST
|
echo "${lost}" > /var/run/mwan3track/$INTERFACE/LOST
|
||||||
echo "${score}" > /var/run/mwan3track/$1/SCORE
|
echo "${score}" > /var/run/mwan3track/$INTERFACE/SCORE
|
||||||
echo "${turn}" > /var/run/mwan3track/$1/TURN
|
echo "${turn}" > /var/run/mwan3track/$INTERFACE/TURN
|
||||||
echo "$(get_uptime)" > /var/run/mwan3track/$1/TIME
|
echo "$(get_uptime)" > /var/run/mwan3track/$INTERFACE/TIME
|
||||||
|
|
||||||
host_up_count=0
|
host_up_count=0
|
||||||
sleep "${sleep_time}" &
|
sleep "${sleep_time}" &
|
||||||
wait
|
wait
|
||||||
|
|
||||||
if [ "${IFDOWN_EVENT}" -eq 1 ]; then
|
if [ "${IFDOWN_EVENT}" -eq 1 ]; then
|
||||||
echo "offline" > /var/run/mwan3track/$1/STATUS
|
LOG debug "Register ifdown event on interface ${INTERFACE} (${DEVICE})"
|
||||||
echo "$(get_uptime)" > /var/run/mwan3track/$1/OFFLINE
|
disconnected 1
|
||||||
echo "0" > /var/run/mwan3track/$1/ONLINE
|
|
||||||
$LOG notice "Interface $1 ($2) is offline"
|
|
||||||
env -i ACTION="disconnected" INTERFACE="$1" DEVICE="$2" /sbin/hotplug-call iface
|
|
||||||
score=0
|
|
||||||
IFDOWN_EVENT=0
|
IFDOWN_EVENT=0
|
||||||
fi
|
fi
|
||||||
|
if [ "${IFUP_EVENT}" -eq 1 ]; then
|
||||||
|
LOG debug "Register ifup event on interface ${INTERFACE} (${DEVICE})"
|
||||||
|
firstconnect
|
||||||
|
IFUP_EVENT=0
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue