2015-11-19 09:37:30 +01:00
|
|
|
#!/bin/sh
|
2020-07-26 23:21:50 +02:00
|
|
|
|
2020-11-10 14:46:55 +01:00
|
|
|
. "${IPKG_INSTROOT}/usr/share/libubox/jshn.sh"
|
2022-03-08 10:15:04 +01:00
|
|
|
. "${IPKG_INSTROOT}/lib/mwan3/common.sh"
|
2019-06-28 13:55:29 +02:00
|
|
|
|
2017-03-14 13:57:45 +01:00
|
|
|
CONNTRACK_FILE="/proc/net/nf_conntrack"
|
2018-10-15 11:02:55 +02:00
|
|
|
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,6}:[0-9a-fA-F]{1,4}|"
|
|
|
|
IPv6_REGEX="${IPv6_REGEX}([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|"
|
|
|
|
IPv6_REGEX="${IPv6_REGEX}([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|"
|
|
|
|
IPv6_REGEX="${IPv6_REGEX}([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|"
|
|
|
|
IPv6_REGEX="${IPv6_REGEX}([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|"
|
|
|
|
IPv6_REGEX="${IPv6_REGEX}[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|"
|
|
|
|
IPv6_REGEX="${IPv6_REGEX}:((:[0-9a-fA-F]{1,4}){1,7}|:)|"
|
|
|
|
IPv6_REGEX="${IPv6_REGEX}fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|"
|
|
|
|
IPv6_REGEX="${IPv6_REGEX}::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|"
|
|
|
|
IPv6_REGEX="${IPv6_REGEX}([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])"
|
2020-09-01 01:20:17 +02:00
|
|
|
IPv4_REGEX="((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2017-11-28 21:36:22 +01:00
|
|
|
DEFAULT_LOWEST_METRIC=256
|
2017-07-24 10:20:46 +02:00
|
|
|
|
2020-07-25 17:35:09 +02:00
|
|
|
mwan3_push_update()
|
|
|
|
{
|
|
|
|
# helper function to build an update string to pass on to
|
|
|
|
# IPTR or IPS RESTORE. Modifies the 'update' variable in
|
|
|
|
# the local scope.
|
2020-08-13 02:38:56 +02:00
|
|
|
update="$update"$'\n'"$*";
|
2020-07-25 17:35:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_update_dev_to_table()
|
|
|
|
{
|
|
|
|
local _tid
|
2020-09-01 01:15:09 +02:00
|
|
|
# shellcheck disable=SC2034
|
2020-07-25 17:35:09 +02:00
|
|
|
mwan3_dev_tbl_ipv4=" "
|
2020-09-01 01:15:09 +02:00
|
|
|
# shellcheck disable=SC2034
|
2020-07-25 17:35:09 +02:00
|
|
|
mwan3_dev_tbl_ipv6=" "
|
|
|
|
|
|
|
|
update_table()
|
|
|
|
{
|
|
|
|
local family curr_table device enabled
|
|
|
|
let _tid++
|
|
|
|
config_get family "$1" family ipv4
|
|
|
|
network_get_device device "$1"
|
|
|
|
[ -z "$device" ] && return
|
|
|
|
config_get enabled "$1" enabled
|
|
|
|
[ "$enabled" -eq 0 ] && return
|
|
|
|
curr_table=$(eval "echo \"\$mwan3_dev_tbl_${family}\"")
|
|
|
|
export "mwan3_dev_tbl_$family=${curr_table}${device}=$_tid "
|
|
|
|
}
|
|
|
|
network_flush_cache
|
|
|
|
config_foreach update_table interface
|
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_update_iface_to_table()
|
|
|
|
{
|
2020-07-26 23:21:50 +02:00
|
|
|
local _tid
|
2020-07-25 17:35:09 +02:00
|
|
|
mwan3_iface_tbl=" "
|
|
|
|
update_table()
|
|
|
|
{
|
|
|
|
let _tid++
|
|
|
|
export mwan3_iface_tbl="${mwan3_iface_tbl}${1}=$_tid "
|
|
|
|
}
|
|
|
|
config_foreach update_table interface
|
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_route_line_dev()
|
|
|
|
{
|
|
|
|
# must have mwan3 config already loaded
|
|
|
|
# arg 1 is route device
|
2020-09-01 01:15:09 +02:00
|
|
|
local _tid route_line route_device route_family entry curr_table
|
2020-07-25 17:35:09 +02:00
|
|
|
route_line=$2
|
|
|
|
route_family=$3
|
|
|
|
route_device=$(echo "$route_line" | sed -ne "s/.*dev \([^ ]*\).*/\1/p")
|
|
|
|
unset "$1"
|
|
|
|
[ -z "$route_device" ] && return
|
|
|
|
|
2020-12-08 14:46:07 +01:00
|
|
|
curr_table=$(eval "echo \"\$mwan3_dev_tbl_${route_family}\"")
|
2020-07-25 17:35:09 +02:00
|
|
|
for entry in $curr_table; do
|
|
|
|
if [ "${entry%%=*}" = "$route_device" ]; then
|
|
|
|
_tid=${entry##*=}
|
|
|
|
export "$1=$_tid"
|
|
|
|
return
|
2018-04-15 13:55:25 +02:00
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
2017-08-04 19:27:13 +02:00
|
|
|
|
|
|
|
# counts how many bits are set to 1
|
|
|
|
# n&(n-1) clears the lowest bit set to 1
|
|
|
|
mwan3_count_one_bits()
|
|
|
|
{
|
|
|
|
local count n
|
|
|
|
count=0
|
|
|
|
n=$(($1))
|
|
|
|
while [ "$n" -gt "0" ]; do
|
|
|
|
n=$((n&(n-1)))
|
|
|
|
count=$((count+1))
|
|
|
|
done
|
|
|
|
echo $count
|
|
|
|
}
|
|
|
|
|
2015-11-19 09:37:30 +01:00
|
|
|
mwan3_get_iface_id()
|
|
|
|
{
|
2020-07-25 17:35:09 +02:00
|
|
|
local _tmp
|
|
|
|
[ -z "$mwan3_iface_tbl" ] && mwan3_update_iface_to_table
|
|
|
|
_tmp="${mwan3_iface_tbl##* ${2}=}"
|
|
|
|
_tmp=${_tmp%% *}
|
2015-11-19 09:37:30 +01:00
|
|
|
export "$1=$_tmp"
|
|
|
|
}
|
|
|
|
|
2018-10-15 11:22:35 +02:00
|
|
|
mwan3_set_custom_ipset_v4()
|
|
|
|
{
|
|
|
|
local custom_network_v4
|
|
|
|
|
2020-09-01 01:20:17 +02:00
|
|
|
for custom_network_v4 in $($IP4 route list table "$1" | awk '{print $1}' | grep -E "$IPv4_REGEX"); do
|
2020-07-26 23:21:50 +02:00
|
|
|
LOG notice "Adding network $custom_network_v4 from table $1 to mwan3_custom_v4 ipset"
|
2022-03-01 08:58:32 +01:00
|
|
|
mwan3_push_update -! add mwan3_custom_ipv4 "$custom_network_v4"
|
2018-10-15 11:22:35 +02:00
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_set_custom_ipset_v6()
|
|
|
|
{
|
|
|
|
local custom_network_v6
|
|
|
|
|
2020-09-01 01:15:09 +02:00
|
|
|
for custom_network_v6 in $($IP6 route list table "$1" | awk '{print $1}' | grep -E "$IPv6_REGEX"); do
|
2020-07-26 23:21:50 +02:00
|
|
|
LOG notice "Adding network $custom_network_v6 from table $1 to mwan3_custom_v6 ipset"
|
2022-03-01 08:58:32 +01:00
|
|
|
mwan3_push_update -! add mwan3_custom_ipv6 "$custom_network_v6"
|
2018-10-15 11:22:35 +02:00
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_set_custom_ipset()
|
|
|
|
{
|
2020-07-26 23:21:50 +02:00
|
|
|
local update=""
|
2018-10-15 11:22:35 +02:00
|
|
|
|
2022-03-01 08:58:32 +01:00
|
|
|
mwan3_push_update -! create mwan3_custom_ipv4 hash:net
|
|
|
|
mwan3_push_update flush mwan3_custom_ipv4
|
2020-07-26 23:21:50 +02:00
|
|
|
config_list_foreach "globals" "rt_table_lookup" mwan3_set_custom_ipset_v4
|
2018-10-15 11:22:35 +02:00
|
|
|
|
2022-02-25 15:58:49 +01:00
|
|
|
if [ $NO_IPV6 -eq 0 ]; then
|
2022-03-01 08:58:32 +01:00
|
|
|
mwan3_push_update -! create mwan3_custom_ipv6 hash:net family inet6
|
|
|
|
mwan3_push_update flush mwan3_custom_ipv6
|
2022-02-25 15:58:49 +01:00
|
|
|
config_list_foreach "globals" "rt_table_lookup" mwan3_set_custom_ipset_v6
|
|
|
|
fi
|
2018-10-15 11:22:35 +02:00
|
|
|
|
2022-03-08 12:52:11 +01:00
|
|
|
echo "$update" > "${MWAN3_STATUS_IPTABLES_LOG_DIR}/ipset-set_custom_ipset.dump"
|
2020-07-26 23:21:50 +02:00
|
|
|
error=$(echo "$update" | $IPS restore 2>&1) || LOG error "set_custom_ipset: $error"
|
2018-10-15 11:22:35 +02:00
|
|
|
}
|
|
|
|
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-05-30 01:47:38 +02:00
|
|
|
mwan3_set_connected_ipv4()
|
|
|
|
{
|
2022-02-24 12:59:31 +01:00
|
|
|
local connected_network_v4 error
|
|
|
|
local candidate_list cidr_list
|
|
|
|
local update=""
|
|
|
|
|
2022-03-01 08:58:32 +01:00
|
|
|
mwan3_push_update -! create mwan3_connected_ipv4 hash:net
|
|
|
|
mwan3_push_update flush mwan3_connected_ipv4
|
2020-07-26 23:21:50 +02:00
|
|
|
|
2020-05-30 01:47:38 +02:00
|
|
|
candidate_list=""
|
|
|
|
cidr_list=""
|
2020-07-26 23:21:50 +02:00
|
|
|
route_lists()
|
|
|
|
{
|
|
|
|
$IP4 route | awk '{print $1}'
|
|
|
|
$IP4 route list table 0 | awk '{print $2}'
|
|
|
|
}
|
2020-09-01 01:20:17 +02:00
|
|
|
for connected_network_v4 in $(route_lists | grep -E "$IPv4_REGEX"); do
|
2020-07-26 23:21:50 +02:00
|
|
|
if [ -z "${connected_network_v4##*/*}" ]; then
|
|
|
|
cidr_list="$cidr_list $connected_network_v4"
|
|
|
|
else
|
|
|
|
candidate_list="$candidate_list $connected_network_v4"
|
|
|
|
fi
|
2020-05-30 01:47:38 +02:00
|
|
|
done
|
|
|
|
|
|
|
|
for connected_network_v4 in $cidr_list; do
|
2022-03-01 08:58:32 +01:00
|
|
|
mwan3_push_update -! add mwan3_connected_ipv4 "$connected_network_v4"
|
2015-11-19 09:37:30 +01:00
|
|
|
done
|
2020-05-30 01:47:38 +02:00
|
|
|
for connected_network_v4 in $candidate_list; do
|
2022-03-01 08:58:32 +01:00
|
|
|
mwan3_push_update -! add mwan3_connected_ipv4 "$connected_network_v4"
|
2020-05-30 01:47:38 +02:00
|
|
|
done
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2022-03-01 08:58:32 +01:00
|
|
|
mwan3_push_update add mwan3_connected_ipv4 224.0.0.0/3
|
|
|
|
|
2022-03-08 12:52:11 +01:00
|
|
|
echo "$update" > "${MWAN3_STATUS_IPTABLES_LOG_DIR}/ipset-set_connected_ipv4.dump"
|
2022-02-24 12:59:31 +01:00
|
|
|
error=$(echo "$update" | $IPS restore 2>&1) || LOG error "set_connected_ipv4: $error"
|
2020-05-30 01:47:38 +02:00
|
|
|
}
|
|
|
|
|
2020-08-16 01:58:55 +02:00
|
|
|
mwan3_set_connected_ipv6()
|
2020-05-30 01:47:38 +02:00
|
|
|
{
|
2020-10-12 00:37:25 +02:00
|
|
|
local connected_network_v6 error
|
2020-07-26 23:21:50 +02:00
|
|
|
local update=""
|
2020-08-16 01:58:55 +02:00
|
|
|
[ $NO_IPV6 -eq 0 ] || return
|
2020-05-30 01:47:38 +02:00
|
|
|
|
2022-03-01 08:58:32 +01:00
|
|
|
mwan3_push_update -! create mwan3_connected_ipv6 hash:net family inet6
|
|
|
|
mwan3_push_update flush mwan3_connected_ipv6
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-08-16 01:58:55 +02:00
|
|
|
for connected_network_v6 in $($IP6 route | awk '{print $1}' | grep -E "$IPv6_REGEX"); do
|
2022-03-01 08:58:32 +01:00
|
|
|
mwan3_push_update -! add mwan3_connected_ipv6 "$connected_network_v6"
|
2020-08-16 01:58:55 +02:00
|
|
|
done
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2022-03-08 12:52:11 +01:00
|
|
|
echo "$update" > "${MWAN3_STATUS_IPTABLES_LOG_DIR}/ipset-set_connected_ipv6.dump"
|
2020-08-16 01:58:55 +02:00
|
|
|
error=$(echo "$update" | $IPS restore 2>&1) || LOG error "set_connected_ipv6: $error"
|
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_set_connected_ipset()
|
|
|
|
{
|
|
|
|
local error
|
|
|
|
local update=""
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2022-03-01 08:58:32 +01:00
|
|
|
mwan3_push_update -! create mwan3_connected_ipv4 hash:net
|
|
|
|
mwan3_push_update flush mwan3_connected_ipv4
|
2018-08-10 14:31:59 +02:00
|
|
|
|
2020-08-16 01:58:55 +02:00
|
|
|
if [ $NO_IPV6 -eq 0 ]; then
|
2022-03-01 08:58:32 +01:00
|
|
|
mwan3_push_update -! create mwan3_connected_ipv6 hash:net family inet6
|
|
|
|
mwan3_push_update flush mwan3_connected_ipv6
|
2020-08-16 01:58:55 +02:00
|
|
|
fi
|
|
|
|
|
2022-03-08 12:52:11 +01:00
|
|
|
echo "$update" > "${MWAN3_STATUS_IPTABLES_LOG_DIR}/ipset-set_connected_ipset.dump"
|
2020-08-16 01:58:55 +02:00
|
|
|
error=$(echo "$update" | $IPS restore 2>&1) || LOG error "set_connected_ipset: $error"
|
2015-11-19 09:37:30 +01:00
|
|
|
}
|
|
|
|
|
2022-03-01 08:58:32 +01:00
|
|
|
mwan3_set_dynamic_ipset()
|
|
|
|
{
|
|
|
|
local error
|
|
|
|
local update=""
|
|
|
|
|
|
|
|
mwan3_push_update -! create mwan3_dynamic_ipv4 list:set
|
|
|
|
mwan3_push_update flush mwan3_dynamic_ipv4
|
|
|
|
|
|
|
|
if [ $NO_IPV6 -eq 0 ]; then
|
|
|
|
mwan3_push_update -! create mwan3_dynamic_ipv6 hash:net family inet6
|
|
|
|
mwan3_push_update flush mwan3_dynamic_ipv6
|
|
|
|
fi
|
|
|
|
|
2022-03-08 12:52:11 +01:00
|
|
|
echo "$update" > "${MWAN3_STATUS_IPTABLES_LOG_DIR}/ipset-set_dynamic_ipset.dump"
|
2022-03-01 08:58:32 +01:00
|
|
|
error=$(echo "$update" | $IPS restore 2>&1) || LOG error "set_dynamic_ipset: $error"
|
|
|
|
}
|
|
|
|
|
2015-11-19 09:37:30 +01:00
|
|
|
mwan3_set_general_rules()
|
|
|
|
{
|
|
|
|
local IP
|
|
|
|
|
|
|
|
for IP in "$IP4" "$IP6"; do
|
2020-07-16 03:40:16 +02:00
|
|
|
[ "$IP" = "$IP6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
2020-09-01 01:15:09 +02:00
|
|
|
RULE_NO=$((MM_BLACKHOLE+2000))
|
2017-08-04 19:27:13 +02:00
|
|
|
if [ -z "$($IP rule list | awk -v var="$RULE_NO:" '$1 == var')" ]; then
|
|
|
|
$IP rule add pref $RULE_NO fwmark $MMX_BLACKHOLE/$MMX_MASK blackhole
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
|
2020-09-01 01:15:09 +02:00
|
|
|
RULE_NO=$((MM_UNREACHABLE+2000))
|
2017-08-04 19:27:13 +02:00
|
|
|
if [ -z "$($IP rule list | awk -v var="$RULE_NO:" '$1 == var')" ]; then
|
|
|
|
$IP rule add pref $RULE_NO fwmark $MMX_UNREACHABLE/$MMX_MASK unreachable
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_set_general_iptables()
|
|
|
|
{
|
2022-03-01 08:58:32 +01:00
|
|
|
local IPT current update error family
|
|
|
|
|
2015-11-19 09:37:30 +01:00
|
|
|
for IPT in "$IPT4" "$IPT6"; do
|
2020-07-16 03:40:16 +02:00
|
|
|
[ "$IPT" = "$IPT6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
2020-08-31 21:51:25 +02:00
|
|
|
current="$($IPT -S)"$'\n'
|
2020-07-26 23:21:50 +02:00
|
|
|
update="*mangle"
|
|
|
|
if [ -n "${current##*-N mwan3_ifaces_in*}" ]; then
|
|
|
|
mwan3_push_update -N mwan3_ifaces_in
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
|
2022-03-01 08:58:32 +01:00
|
|
|
if [ "$IPT" = "$IPT6" ]; then
|
|
|
|
family="ipv6"
|
|
|
|
else
|
|
|
|
family="ipv4"
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
|
2022-03-01 08:58:32 +01:00
|
|
|
for chain in custom connected dynamic; do
|
|
|
|
echo "${current}" | grep -q "\-N mwan3_${chain}_${family}$"
|
|
|
|
local ret="$?"
|
|
|
|
if [ "$ret" = 1 ]; then
|
|
|
|
mwan3_push_update -N mwan3_${chain}_${family}
|
|
|
|
mwan3_push_update -A mwan3_${chain}_${family} \
|
|
|
|
-m set --match-set mwan3_${chain}_${family} dst \
|
|
|
|
-j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
if [ -n "${current##*-N mwan3_rules*}" ]; then
|
|
|
|
mwan3_push_update -N mwan3_rules
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
if [ -n "${current##*-N mwan3_hook*}" ]; then
|
|
|
|
mwan3_push_update -N mwan3_hook
|
2018-05-23 10:51:52 +02:00
|
|
|
# do not mangle ipv6 ra service
|
|
|
|
if [ "$IPT" = "$IPT6" ]; then
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -A mwan3_hook \
|
|
|
|
-p ipv6-icmp \
|
|
|
|
-m icmp6 --icmpv6-type 133 \
|
|
|
|
-j RETURN
|
|
|
|
mwan3_push_update -A mwan3_hook \
|
|
|
|
-p ipv6-icmp \
|
|
|
|
-m icmp6 --icmpv6-type 134 \
|
|
|
|
-j RETURN
|
|
|
|
mwan3_push_update -A mwan3_hook \
|
|
|
|
-p ipv6-icmp \
|
|
|
|
-m icmp6 --icmpv6-type 135 \
|
|
|
|
-j RETURN
|
|
|
|
mwan3_push_update -A mwan3_hook \
|
|
|
|
-p ipv6-icmp \
|
|
|
|
-m icmp6 --icmpv6-type 136 \
|
|
|
|
-j RETURN
|
|
|
|
mwan3_push_update -A mwan3_hook \
|
|
|
|
-p ipv6-icmp \
|
|
|
|
-m icmp6 --icmpv6-type 137 \
|
|
|
|
-j RETURN
|
2020-05-29 00:27:59 +02:00
|
|
|
|
2018-05-23 10:51:52 +02:00
|
|
|
fi
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -A mwan3_hook \
|
2020-10-12 00:37:25 +02:00
|
|
|
-m mark --mark 0x0/$MMX_MASK \
|
2020-07-26 23:21:50 +02:00
|
|
|
-j CONNMARK --restore-mark --nfmask "$MMX_MASK" --ctmask "$MMX_MASK"
|
|
|
|
mwan3_push_update -A mwan3_hook \
|
|
|
|
-m mark --mark 0x0/$MMX_MASK \
|
|
|
|
-j mwan3_ifaces_in
|
2022-03-01 08:58:32 +01:00
|
|
|
|
|
|
|
for chain in custom connected dynamic; do
|
|
|
|
mwan3_push_update -A mwan3_hook \
|
|
|
|
-m mark --mark 0x0/$MMX_MASK \
|
|
|
|
-j mwan3_${chain}_${family}
|
|
|
|
done
|
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -A mwan3_hook \
|
|
|
|
-m mark --mark 0x0/$MMX_MASK \
|
|
|
|
-j mwan3_rules
|
|
|
|
mwan3_push_update -A mwan3_hook \
|
|
|
|
-j CONNMARK --save-mark --nfmask "$MMX_MASK" --ctmask "$MMX_MASK"
|
2022-03-01 08:58:32 +01:00
|
|
|
|
|
|
|
for chain in custom connected dynamic; do
|
|
|
|
mwan3_push_update -A mwan3_hook \
|
|
|
|
-m mark ! --mark $MMX_DEFAULT/$MMX_MASK \
|
|
|
|
-j mwan3_${chain}_${family}
|
|
|
|
done
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
|
2023-05-03 01:42:30 +02:00
|
|
|
if [ -n "${current##*-N mwan3_pre*}" ]; then
|
|
|
|
mwan3_push_update -N mwan3_pre
|
|
|
|
mwan3_push_update -A mwan3_pre \
|
|
|
|
-j MARK --set-xmark "0x0/$MMX_MASK"
|
|
|
|
fi
|
|
|
|
|
2023-05-05 12:46:33 +02:00
|
|
|
if [ -n "${current##*-N mwan3_post*}" ]; then
|
|
|
|
mwan3_push_update -N mwan3_post
|
|
|
|
mwan3_push_update -A mwan3_post \
|
|
|
|
-j MARK --set-xmark "0x0/$MMX_MASK"
|
|
|
|
fi
|
|
|
|
|
2023-05-03 01:42:30 +02:00
|
|
|
if [ -n "${current##*-A PREROUTING -j mwan3_pre*}" ]; then
|
|
|
|
mwan3_push_update -A PREROUTING -j mwan3_pre
|
|
|
|
fi
|
2020-07-26 23:21:50 +02:00
|
|
|
if [ -n "${current##*-A PREROUTING -j mwan3_hook*}" ]; then
|
|
|
|
mwan3_push_update -A PREROUTING -j mwan3_hook
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
2020-07-26 23:21:50 +02:00
|
|
|
if [ -n "${current##*-A OUTPUT -j mwan3_hook*}" ]; then
|
|
|
|
mwan3_push_update -A OUTPUT -j mwan3_hook
|
|
|
|
fi
|
2023-05-05 12:46:33 +02:00
|
|
|
if [ -n "${current##*-A POSTROUTING -j mwan3_post*}" ]; then
|
|
|
|
mwan3_push_update -A POSTROUTING -j mwan3_post
|
|
|
|
fi
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update COMMIT
|
|
|
|
mwan3_push_update ""
|
2022-03-08 12:52:11 +01:00
|
|
|
|
|
|
|
echo "$update" > "${MWAN3_STATUS_IPTABLES_LOG_DIR}/iptables-set_general_iptables-${family}.dump"
|
2020-07-26 23:21:50 +02:00
|
|
|
if [ "$IPT" = "$IPT4" ]; then
|
2022-03-08 11:51:02 +01:00
|
|
|
error=$(echo "$update" | $IPT4R 2>&1) || LOG error "set_general_iptables (${family}): $error"
|
2020-07-26 23:21:50 +02:00
|
|
|
else
|
2022-03-08 11:51:02 +01:00
|
|
|
error=$(echo "$update" | $IPT6R 2>&1) || LOG error "set_general_iptables (${family}): $error"
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_create_iface_iptables()
|
|
|
|
{
|
2020-08-16 01:58:55 +02:00
|
|
|
local id family IPT IPTR current update error
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-14 10:46:24 +02:00
|
|
|
config_get family "$1" family ipv4
|
|
|
|
mwan3_get_iface_id id "$1"
|
2015-11-19 09:37:30 +01:00
|
|
|
|
|
|
|
[ -n "$id" ] || return 0
|
|
|
|
|
2020-07-14 09:24:28 +02:00
|
|
|
if [ "$family" = "ipv4" ]; then
|
2020-07-20 05:19:50 +02:00
|
|
|
IPT="$IPT4"
|
2020-07-26 23:21:50 +02:00
|
|
|
IPTR="$IPT4R"
|
2020-07-20 05:19:50 +02:00
|
|
|
elif [ "$family" = "ipv6" ] && [ $NO_IPV6 -eq 0 ]; then
|
|
|
|
IPT="$IPT6"
|
2020-07-26 23:21:50 +02:00
|
|
|
IPTR="$IPT6R"
|
2020-07-20 05:19:50 +02:00
|
|
|
else
|
|
|
|
return
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
2020-08-31 21:51:25 +02:00
|
|
|
|
|
|
|
current="$($IPT -S)"$'\n'
|
2020-07-26 23:21:50 +02:00
|
|
|
update="*mangle"
|
|
|
|
if [ -n "${current##*-N mwan3_ifaces_in*}" ]; then
|
|
|
|
mwan3_push_update -N mwan3_ifaces_in
|
2020-07-20 05:19:50 +02:00
|
|
|
fi
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-08-31 21:51:25 +02:00
|
|
|
if [ -n "${current##*-N mwan3_iface_in_$1$'\n'*}" ]; then
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -N "mwan3_iface_in_$1"
|
|
|
|
else
|
|
|
|
mwan3_push_update -F "mwan3_iface_in_$1"
|
2020-07-20 05:19:50 +02:00
|
|
|
fi
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2022-03-01 08:58:32 +01:00
|
|
|
for chain in custom connected dynamic; do
|
|
|
|
mwan3_push_update -A "mwan3_iface_in_$1" \
|
|
|
|
-i "$2" \
|
|
|
|
-m set --match-set mwan3_${chain}_${family} src \
|
|
|
|
-m mark --mark "0x0/$MMX_MASK" \
|
|
|
|
-m comment --comment "default" \
|
|
|
|
-j MARK --set-xmark "$MMX_DEFAULT/$MMX_MASK"
|
|
|
|
done
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -A "mwan3_iface_in_$1" \
|
|
|
|
-i "$2" \
|
2020-09-01 01:15:09 +02:00
|
|
|
-m mark --mark "0x0/$MMX_MASK" \
|
2020-07-26 23:21:50 +02:00
|
|
|
-m comment --comment "$1" \
|
2020-09-01 01:15:09 +02:00
|
|
|
-j MARK --set-xmark "$(mwan3_id2mask id MMX_MASK)/$MMX_MASK"
|
2020-07-26 23:21:50 +02:00
|
|
|
|
2020-08-31 21:51:25 +02:00
|
|
|
if [ -n "${current##*-A mwan3_ifaces_in -m mark --mark 0x0/$MMX_MASK -j mwan3_iface_in_${1}$'\n'*}" ]; then
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -A mwan3_ifaces_in \
|
|
|
|
-m mark --mark 0x0/$MMX_MASK \
|
|
|
|
-j "mwan3_iface_in_$1"
|
2020-09-01 01:15:09 +02:00
|
|
|
LOG debug "create_iface_iptables: mwan3_iface_in_$1 not in iptables, adding"
|
2020-07-26 23:21:50 +02:00
|
|
|
else
|
2020-09-01 01:15:09 +02:00
|
|
|
LOG debug "create_iface_iptables: mwan3_iface_in_$1 already in iptables, skip"
|
2020-07-26 23:21:50 +02:00
|
|
|
fi
|
2020-07-20 05:19:50 +02:00
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update COMMIT
|
|
|
|
mwan3_push_update ""
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2022-03-08 12:52:11 +01:00
|
|
|
echo "$update" > "${MWAN3_STATUS_IPTABLES_LOG_DIR}/iptables-create_iface_iptables-${1}.dump"
|
|
|
|
error=$(echo "$update" | $IPTR 2>&1) || LOG error "create_iface_iptables (${1}): $error"
|
2015-11-19 09:37:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_delete_iface_iptables()
|
|
|
|
{
|
2022-02-25 16:17:39 +01:00
|
|
|
local IPT update
|
2020-07-14 10:46:24 +02:00
|
|
|
config_get family "$1" family ipv4
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-14 09:24:28 +02:00
|
|
|
if [ "$family" = "ipv4" ]; then
|
2020-07-20 05:19:50 +02:00
|
|
|
IPT="$IPT4"
|
|
|
|
fi
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-20 05:19:50 +02:00
|
|
|
if [ "$family" = "ipv6" ]; then
|
|
|
|
[ $NO_IPV6 -ne 0 ] && return
|
|
|
|
IPT="$IPT6"
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
|
2022-02-25 16:17:39 +01:00
|
|
|
update="*mangle"
|
|
|
|
|
|
|
|
mwan3_push_update -D mwan3_ifaces_in \
|
|
|
|
-m mark --mark 0x0/$MMX_MASK \
|
|
|
|
-j "mwan3_iface_in_$1" &> /dev/null
|
|
|
|
mwan3_push_update -F "mwan3_iface_in_$1" &> /dev/null
|
|
|
|
mwan3_push_update -X "mwan3_iface_in_$1" &> /dev/null
|
|
|
|
|
|
|
|
mwan3_push_update COMMIT
|
|
|
|
mwan3_push_update ""
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2022-03-08 12:52:11 +01:00
|
|
|
echo "$update" > "${MWAN3_STATUS_IPTABLES_LOG_DIR}/iptables-delete_iface_iptables-${1}.dump"
|
2022-03-08 11:51:02 +01:00
|
|
|
error=$(echo "$update" | $IPTR 2>&1) || LOG error "delete_iface_iptables (${1}): $error"
|
2015-11-19 09:37:30 +01:00
|
|
|
}
|
|
|
|
|
2021-07-03 16:04:33 +02:00
|
|
|
mwan3_extra_tables_routes()
|
|
|
|
{
|
|
|
|
$IP route list table "$1"
|
|
|
|
}
|
|
|
|
|
2020-08-16 01:58:55 +02:00
|
|
|
mwan3_get_routes()
|
2015-11-19 09:37:30 +01:00
|
|
|
{
|
2021-07-03 16:04:33 +02:00
|
|
|
{
|
|
|
|
$IP route list table main
|
|
|
|
config_list_foreach "globals" "rt_table_lookup" mwan3_extra_tables_routes
|
|
|
|
} | sed -ne "$MWAN3_ROUTE_LINE_EXP" | sort -u
|
2020-07-25 17:35:09 +02:00
|
|
|
}
|
|
|
|
|
2020-08-16 01:58:55 +02:00
|
|
|
mwan3_create_iface_route()
|
2020-07-25 17:35:09 +02:00
|
|
|
{
|
2020-08-16 01:58:55 +02:00
|
|
|
local tid route_line family IP id tbl
|
2020-07-25 17:35:09 +02:00
|
|
|
config_get family "$1" family ipv4
|
|
|
|
mwan3_get_iface_id id "$1"
|
|
|
|
|
|
|
|
[ -n "$id" ] || return 0
|
2018-09-24 14:26:53 +02:00
|
|
|
|
2020-07-25 17:35:09 +02:00
|
|
|
if [ "$family" = "ipv4" ]; then
|
|
|
|
IP="$IP4"
|
|
|
|
elif [ "$family" = "ipv6" ]; then
|
|
|
|
IP="$IP6"
|
|
|
|
fi
|
|
|
|
|
2020-08-16 01:58:55 +02:00
|
|
|
tbl=$($IP route list table $id 2>/dev/null)$'\n'
|
2020-07-25 17:35:09 +02:00
|
|
|
mwan3_update_dev_to_table
|
2020-08-16 01:58:55 +02:00
|
|
|
mwan3_get_routes | while read -r route_line; do
|
2020-07-25 17:35:09 +02:00
|
|
|
mwan3_route_line_dev "tid" "$route_line" "$family"
|
2020-08-16 01:58:55 +02:00
|
|
|
{ [ -z "${route_line##default*}" ] || [ -z "${route_line##fe80::/64*}" ]; } && [ "$tid" != "$id" ] && continue
|
2020-07-25 17:35:09 +02:00
|
|
|
if [ -z "$tid" ] || [ "$tid" = "$id" ]; then
|
2020-08-16 01:58:55 +02:00
|
|
|
# possible that routes are already in the table
|
|
|
|
# if 'connected' was called after 'ifup'
|
|
|
|
[ -n "$tbl" ] && [ -z "${tbl##*$route_line$'\n'*}" ] && continue
|
2020-07-25 17:35:09 +02:00
|
|
|
$IP route add table $id $route_line ||
|
2022-09-14 14:46:58 +02:00
|
|
|
LOG debug "Route '$route_line' already added to table $id"
|
2020-07-25 17:35:09 +02:00
|
|
|
fi
|
|
|
|
|
|
|
|
done
|
2015-11-19 09:37:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_delete_iface_route()
|
|
|
|
{
|
2020-08-16 01:58:55 +02:00
|
|
|
local id family
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-14 10:46:24 +02:00
|
|
|
config_get family "$1" family ipv4
|
|
|
|
mwan3_get_iface_id id "$1"
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-08-16 01:58:55 +02:00
|
|
|
if [ -z "$id" ]; then
|
|
|
|
LOG warn "delete_iface_route: could not find table id for interface $1"
|
|
|
|
return 0
|
|
|
|
fi
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-14 09:24:28 +02:00
|
|
|
if [ "$family" = "ipv4" ]; then
|
2020-07-14 10:46:24 +02:00
|
|
|
$IP4 route flush table "$id"
|
2020-08-16 01:58:55 +02:00
|
|
|
elif [ "$family" = "ipv6" ] && [ $NO_IPV6 -eq 0 ]; then
|
2020-07-14 10:46:24 +02:00
|
|
|
$IP6 route flush table "$id"
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_create_iface_rules()
|
|
|
|
{
|
2020-07-26 23:21:50 +02:00
|
|
|
local id family IP
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-14 10:46:24 +02:00
|
|
|
config_get family "$1" family ipv4
|
|
|
|
mwan3_get_iface_id id "$1"
|
2015-11-19 09:37:30 +01:00
|
|
|
|
|
|
|
[ -n "$id" ] || return 0
|
|
|
|
|
2020-07-14 09:24:28 +02:00
|
|
|
if [ "$family" = "ipv4" ]; then
|
2020-07-26 23:21:50 +02:00
|
|
|
IP="$IP4"
|
|
|
|
elif [ "$family" = "ipv6" ] && [ $NO_IPV6 -eq 0 ]; then
|
|
|
|
IP="$IP6"
|
|
|
|
else
|
|
|
|
return
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
|
2020-08-16 01:58:55 +02:00
|
|
|
mwan3_delete_iface_rules "$1"
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-09-01 01:15:09 +02:00
|
|
|
$IP rule add pref $((id+1000)) iif "$2" lookup "$id"
|
|
|
|
$IP rule add pref $((id+2000)) fwmark "$(mwan3_id2mask id MMX_MASK)/$MMX_MASK" lookup "$id"
|
2020-08-16 01:58:55 +02:00
|
|
|
$IP rule add pref $((id+3000)) fwmark "$(mwan3_id2mask id MMX_MASK)/$MMX_MASK" unreachable
|
2015-11-19 09:37:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_delete_iface_rules()
|
|
|
|
{
|
2020-08-16 01:58:55 +02:00
|
|
|
local id family IP rule_id
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-14 10:46:24 +02:00
|
|
|
config_get family "$1" family ipv4
|
|
|
|
mwan3_get_iface_id id "$1"
|
2015-11-19 09:37:30 +01:00
|
|
|
|
|
|
|
[ -n "$id" ] || return 0
|
|
|
|
|
2020-07-14 09:24:28 +02:00
|
|
|
if [ "$family" = "ipv4" ]; then
|
2020-07-26 23:21:50 +02:00
|
|
|
IP="$IP4"
|
|
|
|
elif [ "$family" = "ipv6" ] && [ $NO_IPV6 -eq 0 ]; then
|
|
|
|
IP="$IP6"
|
|
|
|
else
|
|
|
|
return
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
|
2020-08-16 01:58:55 +02:00
|
|
|
for rule_id in $(ip rule list | awk '$1 % 1000 == '$id' && $1 > 1000 && $1 < 4000 {print substr($1,0,4)}'); do
|
|
|
|
$IP rule del pref $rule_id
|
2020-07-26 23:21:50 +02:00
|
|
|
done
|
2015-11-19 09:37:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_delete_iface_ipset_entries()
|
|
|
|
{
|
|
|
|
local id setname entry
|
|
|
|
|
2020-07-14 10:46:24 +02:00
|
|
|
mwan3_get_iface_id id "$1"
|
2015-11-19 09:37:30 +01:00
|
|
|
|
|
|
|
[ -n "$id" ] || return 0
|
|
|
|
|
2022-03-28 14:02:18 +02:00
|
|
|
for setname in $(ipset -n list | grep ^mwan3_rule_); do
|
2020-07-26 23:21:50 +02:00
|
|
|
for entry in $(ipset list "$setname" | grep "$(mwan3_id2mask id MMX_MASK | awk '{ printf "0x%08x", $1; }')" | cut -d ' ' -f 1); do
|
2020-11-10 14:44:49 +01:00
|
|
|
$IPS del "$setname" $entry ||
|
|
|
|
LOG notice "failed to delete $entry from $setname"
|
2015-11-19 09:37:30 +01:00
|
|
|
done
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
mwan3_set_policy()
|
|
|
|
{
|
2020-07-26 23:21:50 +02:00
|
|
|
local id iface family metric probability weight device is_lowest is_offline IPT IPTR total_weight current update error
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-20 05:19:50 +02:00
|
|
|
is_lowest=0
|
2020-07-14 10:46:24 +02:00
|
|
|
config_get iface "$1" interface
|
|
|
|
config_get metric "$1" metric 1
|
|
|
|
config_get weight "$1" weight 1
|
2015-11-19 09:37:30 +01:00
|
|
|
|
|
|
|
[ -n "$iface" ] || return 0
|
2020-07-14 10:46:24 +02:00
|
|
|
network_get_device device "$iface"
|
2020-07-26 23:21:50 +02:00
|
|
|
[ "$metric" -gt $DEFAULT_LOWEST_METRIC ] && LOG warn "Member interface $iface has >$DEFAULT_LOWEST_METRIC metric. Not appending to policy" && return 0
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-14 10:46:24 +02:00
|
|
|
mwan3_get_iface_id id "$iface"
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
[ -n "$id" ] || return 0
|
|
|
|
|
2020-07-20 05:19:50 +02:00
|
|
|
[ "$(mwan3_get_iface_hotplug_state "$iface")" = "online" ]
|
|
|
|
is_offline=$?
|
|
|
|
|
2020-07-14 10:46:24 +02:00
|
|
|
config_get family "$iface" family ipv4
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-14 09:24:28 +02:00
|
|
|
if [ "$family" = "ipv4" ]; then
|
2020-07-20 05:19:50 +02:00
|
|
|
IPT="$IPT4"
|
2020-07-26 23:21:50 +02:00
|
|
|
IPTR="$IPT4R"
|
2020-07-20 05:19:50 +02:00
|
|
|
elif [ "$family" = "ipv6" ]; then
|
|
|
|
IPT="$IPT6"
|
2020-07-26 23:21:50 +02:00
|
|
|
IPTR="$IPT6R"
|
2020-07-20 05:19:50 +02:00
|
|
|
fi
|
2020-08-31 21:51:25 +02:00
|
|
|
current="$($IPT -S)"$'\n'
|
2020-07-26 23:21:50 +02:00
|
|
|
update="*mangle"
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-20 05:19:50 +02:00
|
|
|
if [ "$family" = "ipv4" ] && [ $is_offline -eq 0 ]; then
|
|
|
|
if [ "$metric" -lt "$lowest_metric_v4" ]; then
|
|
|
|
is_lowest=1
|
|
|
|
total_weight_v4=$weight
|
|
|
|
lowest_metric_v4=$metric
|
|
|
|
elif [ "$metric" -eq "$lowest_metric_v4" ]; then
|
2020-09-01 01:15:09 +02:00
|
|
|
total_weight_v4=$((total_weight_v4+weight))
|
2020-07-20 05:19:50 +02:00
|
|
|
total_weight=$total_weight_v4
|
2018-04-15 13:55:25 +02:00
|
|
|
else
|
2020-07-20 05:19:50 +02:00
|
|
|
return
|
|
|
|
fi
|
|
|
|
elif [ "$family" = "ipv6" ] && [ $NO_IPV6 -eq 0 ] && [ $is_offline -eq 0 ]; then
|
|
|
|
if [ "$metric" -lt "$lowest_metric_v6" ]; then
|
|
|
|
is_lowest=1
|
|
|
|
total_weight_v6=$weight
|
|
|
|
lowest_metric_v6=$metric
|
|
|
|
elif [ "$metric" -eq "$lowest_metric_v6" ]; then
|
2020-09-01 01:15:09 +02:00
|
|
|
total_weight_v6=$((total_weight_v6+weight))
|
2020-07-20 05:19:50 +02:00
|
|
|
total_weight=$total_weight_v6
|
|
|
|
else
|
|
|
|
return
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
fi
|
2020-07-20 05:19:50 +02:00
|
|
|
if [ $is_lowest -eq 1 ]; then
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -F "mwan3_policy_$policy"
|
|
|
|
mwan3_push_update -A "mwan3_policy_$policy" \
|
|
|
|
-m mark --mark 0x0/$MMX_MASK \
|
|
|
|
-m comment --comment \"$iface $weight $weight\" \
|
2020-09-01 01:15:09 +02:00
|
|
|
-j MARK --set-xmark "$(mwan3_id2mask id MMX_MASK)/$MMX_MASK"
|
2020-07-20 05:19:50 +02:00
|
|
|
elif [ $is_offline -eq 0 ]; then
|
2020-09-01 01:15:09 +02:00
|
|
|
probability=$((weight*1000/total_weight))
|
2020-07-20 05:19:50 +02:00
|
|
|
if [ "$probability" -lt 10 ]; then
|
|
|
|
probability="0.00$probability"
|
|
|
|
elif [ $probability -lt 100 ]; then
|
|
|
|
probability="0.0$probability"
|
|
|
|
elif [ $probability -lt 1000 ]; then
|
|
|
|
probability="0.$probability"
|
2018-04-15 13:55:25 +02:00
|
|
|
else
|
2020-07-20 05:19:50 +02:00
|
|
|
probability="1"
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
2020-07-25 17:35:09 +02:00
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -I "mwan3_policy_$policy" \
|
|
|
|
-m mark --mark 0x0/$MMX_MASK \
|
|
|
|
-m statistic \
|
|
|
|
--mode random \
|
|
|
|
--probability "$probability" \
|
|
|
|
-m comment --comment \"$iface $weight $total_weight\" \
|
2020-09-01 01:15:09 +02:00
|
|
|
-j MARK --set-xmark "$(mwan3_id2mask id MMX_MASK)/$MMX_MASK"
|
2020-07-20 05:19:50 +02:00
|
|
|
elif [ -n "$device" ]; then
|
2020-07-26 23:21:50 +02:00
|
|
|
echo "$current" | grep -q "^-A mwan3_policy_$policy.*--comment .* [0-9]* [0-9]*" ||
|
|
|
|
mwan3_push_update -I "mwan3_policy_$policy" \
|
|
|
|
-o "$device" \
|
|
|
|
-m mark --mark 0x0/$MMX_MASK \
|
|
|
|
-m comment --comment \"out $iface $device\" \
|
|
|
|
-j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update COMMIT
|
|
|
|
mwan3_push_update ""
|
|
|
|
|
2022-03-08 12:52:11 +01:00
|
|
|
echo "$update" > "${MWAN3_STATUS_IPTABLES_LOG_DIR}/iptables-set_policy-${1}.dump"
|
|
|
|
error=$(echo "$update" | $IPTR 2>&1) || LOG error "set_policy ($1): $error"
|
2015-11-19 09:37:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_create_policies_iptables()
|
|
|
|
{
|
2020-07-26 23:21:50 +02:00
|
|
|
local last_resort lowest_metric_v4 lowest_metric_v6 total_weight_v4 total_weight_v6 policy IPT current update error
|
2015-11-19 09:37:30 +01:00
|
|
|
|
|
|
|
policy="$1"
|
|
|
|
|
2020-07-14 10:46:24 +02:00
|
|
|
config_get last_resort "$1" last_resort unreachable
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-14 10:46:24 +02:00
|
|
|
if [ "$1" != "$(echo "$1" | cut -c1-15)" ]; then
|
2020-07-26 23:21:50 +02:00
|
|
|
LOG warn "Policy $1 exceeds max of 15 chars. Not setting policy" && return 0
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
|
|
|
|
for IPT in "$IPT4" "$IPT6"; do
|
2020-07-16 03:40:16 +02:00
|
|
|
[ "$IPT" = "$IPT6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
2020-08-31 21:51:25 +02:00
|
|
|
current="$($IPT -S)"$'\n'
|
2020-07-26 23:21:50 +02:00
|
|
|
update="*mangle"
|
2020-08-31 21:51:25 +02:00
|
|
|
if [ -n "${current##*-N mwan3_policy_$1$'\n'*}" ]; then
|
2020-09-01 01:15:09 +02:00
|
|
|
mwan3_push_update -N "mwan3_policy_$1"
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -F "mwan3_policy_$1"
|
2015-11-19 09:37:30 +01:00
|
|
|
|
|
|
|
case "$last_resort" in
|
|
|
|
blackhole)
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -A "mwan3_policy_$1" \
|
|
|
|
-m mark --mark 0x0/$MMX_MASK \
|
|
|
|
-m comment --comment "blackhole" \
|
|
|
|
-j MARK --set-xmark $MMX_BLACKHOLE/$MMX_MASK
|
|
|
|
;;
|
2015-11-19 09:37:30 +01:00
|
|
|
default)
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -A "mwan3_policy_$1" \
|
|
|
|
-m mark --mark 0x0/$MMX_MASK \
|
|
|
|
-m comment --comment "default" \
|
|
|
|
-j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK
|
|
|
|
;;
|
2015-11-19 09:37:30 +01:00
|
|
|
*)
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -A "mwan3_policy_$1" \
|
|
|
|
-m mark --mark 0x0/$MMX_MASK \
|
|
|
|
-m comment --comment "unreachable" \
|
|
|
|
-j MARK --set-xmark $MMX_UNREACHABLE/$MMX_MASK
|
|
|
|
;;
|
2015-11-19 09:37:30 +01:00
|
|
|
esac
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update COMMIT
|
|
|
|
mwan3_push_update ""
|
2022-03-08 12:52:11 +01:00
|
|
|
|
|
|
|
echo "$update" > "${MWAN3_STATUS_IPTABLES_LOG_DIR}/iptables-create_policies_iptables-${1}.dump"
|
2020-07-26 23:21:50 +02:00
|
|
|
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
|
2015-11-19 09:37:30 +01:00
|
|
|
done
|
|
|
|
|
2017-11-28 21:36:22 +01:00
|
|
|
lowest_metric_v4=$DEFAULT_LOWEST_METRIC
|
2015-11-19 09:37:30 +01:00
|
|
|
total_weight_v4=0
|
|
|
|
|
2017-11-28 21:36:22 +01:00
|
|
|
lowest_metric_v6=$DEFAULT_LOWEST_METRIC
|
2015-11-19 09:37:30 +01:00
|
|
|
total_weight_v6=0
|
|
|
|
|
2020-07-14 10:46:24 +02:00
|
|
|
config_list_foreach "$1" use_member mwan3_set_policy
|
2015-11-19 09:37:30 +01:00
|
|
|
}
|
|
|
|
|
2015-12-17 11:50:18 +01:00
|
|
|
mwan3_set_policies_iptables()
|
|
|
|
{
|
|
|
|
config_foreach mwan3_create_policies_iptables policy
|
|
|
|
}
|
|
|
|
|
2015-11-19 09:37:30 +01:00
|
|
|
mwan3_set_sticky_iptables()
|
|
|
|
{
|
2022-03-01 08:58:32 +01:00
|
|
|
local rule="${1}"
|
|
|
|
local interface="${2}"
|
|
|
|
local ipv="${3}"
|
|
|
|
local policy="${4}"
|
|
|
|
|
2015-12-17 11:50:18 +01:00
|
|
|
local id iface
|
2020-07-26 23:21:50 +02:00
|
|
|
for iface in $(echo "$current" | grep "^-A $policy" | cut -s -d'"' -f2 | awk '{print $1}'); do
|
2022-03-01 08:58:32 +01:00
|
|
|
if [ "$iface" = "$interface" ]; then
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2022-03-01 08:58:32 +01:00
|
|
|
mwan3_get_iface_id id "$iface"
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2015-12-17 11:50:18 +01:00
|
|
|
[ -n "$id" ] || return 0
|
2022-03-01 08:58:32 +01:00
|
|
|
if [ -z "${current##*-N mwan3_iface_in_${iface}$'\n'*}" ]; then
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -I "mwan3_rule_$rule" \
|
2020-09-01 01:15:09 +02:00
|
|
|
-m mark --mark "$(mwan3_id2mask id MMX_MASK)/$MMX_MASK" \
|
2022-03-28 14:02:18 +02:00
|
|
|
-m set ! --match-set "mwan3_rule_${ipv}_${rule}" src,src \
|
2020-09-01 01:15:09 +02:00
|
|
|
-j MARK --set-xmark "0x0/$MMX_MASK"
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -I "mwan3_rule_$rule" \
|
2020-09-01 01:15:09 +02:00
|
|
|
-m mark --mark "0/$MMX_MASK" \
|
|
|
|
-j MARK --set-xmark "$(mwan3_id2mask id MMX_MASK)/$MMX_MASK"
|
2020-07-26 23:21:50 +02:00
|
|
|
fi
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2022-02-25 16:02:49 +01:00
|
|
|
mwan3_set_sticky_ipset()
|
|
|
|
{
|
|
|
|
local rule="$1"
|
|
|
|
local mmx="$2"
|
|
|
|
local timeout="$3"
|
|
|
|
|
|
|
|
local error
|
|
|
|
local update=""
|
|
|
|
|
2022-03-28 14:02:18 +02:00
|
|
|
mwan3_push_update -! create "mwan3_rule_ipv4_$rule" \
|
2022-02-25 16:02:49 +01:00
|
|
|
hash:ip,mark markmask "$mmx" \
|
|
|
|
timeout "$timeout"
|
|
|
|
|
|
|
|
[ $NO_IPV6 -eq 0 ] &&
|
2022-03-28 14:02:18 +02:00
|
|
|
mwan3_push_update -! create "mwan3_rule_ipv6_$rule" \
|
2022-02-25 16:02:49 +01:00
|
|
|
hash:ip,mark markmask "$mmx" \
|
|
|
|
timeout "$timeout" family inet6
|
|
|
|
|
2022-03-08 12:52:11 +01:00
|
|
|
echo "$update" > "${MWAN3_STATUS_IPTABLES_LOG_DIR}/ipset-set_sticky_ipset-${rule}.dump"
|
2022-03-08 11:51:02 +01:00
|
|
|
error=$(echo "$update" | $IPS restore 2>&1) || LOG error "set_sticky_ipset (${rule}): $error"
|
2022-02-25 16:02:49 +01:00
|
|
|
}
|
|
|
|
|
2015-11-19 09:37:30 +01:00
|
|
|
mwan3_set_user_iptables_rule()
|
|
|
|
{
|
2020-06-13 21:25:42 +02:00
|
|
|
local ipset family proto policy src_ip src_port src_iface src_dev
|
2020-07-26 23:21:50 +02:00
|
|
|
local sticky dest_ip dest_port use_policy timeout policy
|
2020-09-01 01:15:09 +02:00
|
|
|
local global_logging rule_logging loglevel rule_policy rule ipv
|
2015-11-19 09:37:30 +01:00
|
|
|
|
|
|
|
rule="$1"
|
2020-07-26 23:21:50 +02:00
|
|
|
ipv="$2"
|
|
|
|
rule_policy=0
|
2020-07-14 10:46:24 +02:00
|
|
|
config_get sticky "$1" sticky 0
|
|
|
|
config_get timeout "$1" timeout 600
|
|
|
|
config_get ipset "$1" ipset
|
|
|
|
config_get proto "$1" proto all
|
|
|
|
config_get src_ip "$1" src_ip
|
|
|
|
config_get src_iface "$1" src_iface
|
|
|
|
config_get src_port "$1" src_port
|
|
|
|
config_get dest_ip "$1" dest_ip
|
|
|
|
config_get dest_port "$1" dest_port
|
|
|
|
config_get use_policy "$1" use_policy
|
|
|
|
config_get family "$1" family any
|
2020-07-26 23:21:50 +02:00
|
|
|
config_get rule_logging "$1" logging 0
|
|
|
|
config_get global_logging globals logging 0
|
|
|
|
config_get loglevel globals loglevel notice
|
|
|
|
|
2020-08-16 01:58:55 +02:00
|
|
|
[ "$ipv" = "ipv6" ] && [ $NO_IPV6 -ne 0 ] && return
|
|
|
|
[ "$family" = "ipv4" ] && [ "$ipv" = "ipv6" ] && return
|
|
|
|
[ "$family" = "ipv6" ] && [ "$ipv" = "ipv4" ] && return
|
|
|
|
|
2020-09-01 01:20:17 +02:00
|
|
|
for ipaddr in "$src_ip" "$dest_ip"; do
|
|
|
|
if [ -n "$ipaddr" ] && { { [ "$ipv" = "ipv4" ] && echo "$ipaddr" | grep -qE "$IPv6_REGEX"; } ||
|
|
|
|
{ [ "$ipv" = "ipv6" ] && echo "$ipaddr" | grep -qE $IPv4_REGEX; } }; then
|
|
|
|
LOG warn "invalid $ipv address $ipaddr specified for rule $rule"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
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
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-05-29 00:29:56 +02:00
|
|
|
[ -z "$dest_ip" ] && unset dest_ip
|
|
|
|
[ -z "$src_ip" ] && unset src_ip
|
|
|
|
[ -z "$ipset" ] && unset ipset
|
2020-09-01 01:15:09 +02:00
|
|
|
[ -z "$src_port" ] && unset src_port
|
|
|
|
[ -z "$dest_port" ] && unset dest_port
|
|
|
|
if [ "$proto" != 'tcp' ] && [ "$proto" != 'udp' ]; then
|
2020-05-29 00:29:56 +02:00
|
|
|
[ -n "$src_port" ] && {
|
2020-07-26 23:21:50 +02:00
|
|
|
LOG warn "src_port set to '$src_port' but proto set to '$proto' not tcp or udp. src_port will be ignored"
|
2020-05-29 00:29:56 +02:00
|
|
|
}
|
2020-07-26 23:21:50 +02:00
|
|
|
|
2020-05-29 00:29:56 +02:00
|
|
|
[ -n "$dest_port" ] && {
|
2020-07-26 23:21:50 +02:00
|
|
|
LOG warn "dest_port set to '$dest_port' but proto set to '$proto' not tcp or udp. dest_port will be ignored"
|
2020-05-29 00:29:56 +02:00
|
|
|
}
|
|
|
|
unset src_port
|
|
|
|
unset dest_port
|
2020-07-26 23:21:50 +02:00
|
|
|
fi
|
2019-01-08 15:44:54 +01:00
|
|
|
|
2020-07-14 10:46:24 +02:00
|
|
|
if [ "$1" != "$(echo "$1" | cut -c1-15)" ]; then
|
2020-07-26 23:21:50 +02:00
|
|
|
LOG warn "Rule $1 exceeds max of 15 chars. Not setting rule" && return 0
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -n "$ipset" ]; then
|
|
|
|
ipset="-m set --match-set $ipset dst"
|
|
|
|
fi
|
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
if [ -z "$use_policy" ]; then
|
|
|
|
return
|
|
|
|
fi
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
if [ "$use_policy" = "default" ]; then
|
|
|
|
policy="MARK --set-xmark $MMX_DEFAULT/$MMX_MASK"
|
|
|
|
elif [ "$use_policy" = "unreachable" ]; then
|
|
|
|
policy="MARK --set-xmark $MMX_UNREACHABLE/$MMX_MASK"
|
|
|
|
elif [ "$use_policy" = "blackhole" ]; then
|
|
|
|
policy="MARK --set-xmark $MMX_BLACKHOLE/$MMX_MASK"
|
|
|
|
else
|
|
|
|
rule_policy=1
|
|
|
|
policy="mwan3_policy_$use_policy"
|
|
|
|
if [ "$sticky" -eq 1 ]; then
|
2022-02-25 16:02:49 +01:00
|
|
|
mwan3_set_sticky_ipset "$rule" "$MMX_MASK" "$timeout"
|
2020-07-26 23:21:50 +02:00
|
|
|
fi
|
|
|
|
fi
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-08-31 21:51:25 +02:00
|
|
|
if [ $rule_policy -eq 1 ] && [ -n "${current##*-N $policy$'\n'*}" ]; then
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -N "$policy"
|
|
|
|
fi
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
if [ $rule_policy -eq 1 ] && [ "$sticky" -eq 1 ]; then
|
2020-08-31 21:51:25 +02:00
|
|
|
if [ -n "${current##*-N mwan3_rule_$1$'\n'*}" ]; then
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -N "mwan3_rule_$1"
|
|
|
|
fi
|
2015-12-17 11:50:18 +01:00
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -F "mwan3_rule_$1"
|
2022-03-01 08:58:32 +01:00
|
|
|
config_foreach mwan3_set_sticky_iptables interface $ipv "$policy"
|
2015-12-21 16:50:59 +01:00
|
|
|
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -A "mwan3_rule_$1" \
|
|
|
|
-m mark --mark 0/$MMX_MASK \
|
|
|
|
-j "$policy"
|
|
|
|
mwan3_push_update -A "mwan3_rule_$1" \
|
|
|
|
-m mark ! --mark 0xfc00/0xfc00 \
|
2022-03-28 14:02:18 +02:00
|
|
|
-j SET --del-set "mwan3_rule_${ipv}_${rule}" src,src
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -A "mwan3_rule_$1" \
|
|
|
|
-m mark ! --mark 0xfc00/0xfc00 \
|
2022-03-28 14:02:18 +02:00
|
|
|
-j SET --add-set "mwan3_rule_${ipv}_${rule}" src,src
|
2020-07-26 23:21:50 +02:00
|
|
|
policy="mwan3_rule_$1"
|
|
|
|
fi
|
|
|
|
if [ "$global_logging" = "1" ] && [ "$rule_logging" = "1" ]; then
|
|
|
|
mwan3_push_update -A mwan3_rules \
|
|
|
|
-p "$proto" \
|
|
|
|
${src_ip:+-s} $src_ip \
|
|
|
|
${src_dev:+-i} $src_dev \
|
|
|
|
${dest_ip:+-d} $dest_ip \
|
|
|
|
$ipset \
|
|
|
|
${src_port:+-m} ${src_port:+multiport} ${src_port:+--sports} $src_port \
|
|
|
|
${dest_port:+-m} ${dest_port:+multiport} ${dest_port:+--dports} $dest_port \
|
|
|
|
-m mark --mark 0/$MMX_MASK \
|
|
|
|
-m comment --comment "$1" \
|
|
|
|
-j LOG --log-level "$loglevel" --log-prefix "MWAN3($1)"
|
|
|
|
fi
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
mwan3_push_update -A mwan3_rules \
|
|
|
|
-p "$proto" \
|
|
|
|
${src_ip:+-s} $src_ip \
|
|
|
|
${src_dev:+-i} $src_dev \
|
|
|
|
${dest_ip:+-d} $dest_ip \
|
|
|
|
$ipset \
|
|
|
|
${src_port:+-m} ${src_port:+multiport} ${src_port:+--sports} $src_port \
|
|
|
|
${dest_port:+-m} ${dest_port:+multiport} ${dest_port:+--dports} $dest_port \
|
|
|
|
-m mark --mark 0/$MMX_MASK \
|
|
|
|
-j $policy
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
config_get family "$iface" family ipv4
|
|
|
|
|
|
|
|
if [ "$family" = "ipv4" ]; then
|
|
|
|
IPT="$IPT4"
|
|
|
|
IPTR="$IPT4R"
|
|
|
|
elif [ "$family" = "ipv6" ]; then
|
|
|
|
IPT="$IPT6"
|
|
|
|
IPTR="$IPT6R"
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
2020-07-26 23:21:50 +02:00
|
|
|
$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
|
2015-11-19 09:37:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_set_user_rules()
|
|
|
|
{
|
2020-07-26 23:21:50 +02:00
|
|
|
local IPT IPTR ipv
|
|
|
|
local current update error
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
for ipv in ipv4 ipv6; do
|
|
|
|
if [ "$ipv" = "ipv4" ]; then
|
|
|
|
IPT="$IPT4"
|
|
|
|
IPTR="$IPT4R"
|
|
|
|
elif [ "$ipv" = "ipv6" ]; then
|
|
|
|
IPT="$IPT6"
|
|
|
|
IPTR="$IPT6R"
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
2020-07-26 23:21:50 +02:00
|
|
|
[ "$ipv" = "ipv6" ] && [ $NO_IPV6 -ne 0 ] && continue
|
|
|
|
update="*mangle"
|
2020-08-31 21:51:25 +02:00
|
|
|
current="$($IPT -S)"$'\n'
|
2020-07-26 23:21:50 +02:00
|
|
|
|
|
|
|
|
|
|
|
if [ -n "${current##*-N mwan3_rules*}" ]; then
|
|
|
|
mwan3_push_update -N "mwan3_rules"
|
|
|
|
fi
|
|
|
|
|
|
|
|
mwan3_push_update -F mwan3_rules
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
config_foreach mwan3_set_user_iptables_rule rule "$ipv"
|
|
|
|
|
|
|
|
mwan3_push_update COMMIT
|
|
|
|
mwan3_push_update ""
|
2022-03-08 12:52:11 +01:00
|
|
|
|
|
|
|
echo "$update" > "${MWAN3_STATUS_IPTABLES_LOG_DIR}/iptables-set_user_rules-${ipv}.dump"
|
2022-03-08 11:51:02 +01:00
|
|
|
error=$(echo "$update" | $IPTR 2>&1) || LOG error "set_user_rules (${ipv}): $error"
|
2015-11-19 09:37:30 +01:00
|
|
|
done
|
|
|
|
|
2020-07-26 23:21:50 +02:00
|
|
|
|
2015-11-19 09:37:30 +01:00
|
|
|
}
|
|
|
|
|
2020-08-13 02:38:56 +02:00
|
|
|
mwan3_interface_hotplug_shutdown()
|
|
|
|
{
|
|
|
|
local interface status device ifdown
|
|
|
|
interface="$1"
|
|
|
|
ifdown="$2"
|
|
|
|
[ -f $MWAN3TRACK_STATUS_DIR/$interface/STATUS ] && {
|
|
|
|
status=$(cat $MWAN3TRACK_STATUS_DIR/$interface/STATUS)
|
|
|
|
}
|
|
|
|
|
|
|
|
[ "$status" != "online" ] && [ "$ifdown" != 1 ] && return
|
|
|
|
|
|
|
|
if [ "$ifdown" = 1 ]; then
|
|
|
|
env -i ACTION=ifdown \
|
|
|
|
INTERFACE=$interface \
|
|
|
|
DEVICE=$device \
|
|
|
|
sh /etc/hotplug.d/iface/15-mwan3
|
|
|
|
else
|
|
|
|
[ "$status" = "online" ] && {
|
|
|
|
env -i MWAN3_SHUTDOWN="1" \
|
|
|
|
ACTION="disconnected" \
|
|
|
|
INTERFACE="$interface" \
|
|
|
|
DEVICE="$device" /sbin/hotplug-call iface
|
|
|
|
}
|
|
|
|
fi
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_interface_shutdown()
|
|
|
|
{
|
|
|
|
mwan3_interface_hotplug_shutdown $1
|
|
|
|
mwan3_track_clean $1
|
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_ifup()
|
|
|
|
{
|
2020-11-04 16:24:55 +01:00
|
|
|
local interface=$1
|
|
|
|
local caller=$2
|
2020-08-13 02:38:56 +02:00
|
|
|
|
2020-11-04 16:24:55 +01:00
|
|
|
local up l3_device status true_iface
|
2020-08-13 02:38:56 +02:00
|
|
|
|
2020-11-04 16:24:55 +01:00
|
|
|
if [ "${caller}" = "cmd" ]; then
|
2020-08-13 02:38:56 +02:00
|
|
|
# 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
|
|
|
|
/etc/init.d/mwan3 running || {
|
|
|
|
echo 'The service mwan3 is global disabled.'
|
|
|
|
echo 'Please execute "/etc/init.d/mwan3 start" first.'
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
config_load mwan3
|
|
|
|
fi
|
|
|
|
mwan3_get_true_iface true_iface $interface
|
|
|
|
status=$(ubus -S call network.interface.$true_iface status)
|
|
|
|
|
|
|
|
[ -n "$status" ] && {
|
|
|
|
json_load "$status"
|
|
|
|
json_get_vars up l3_device
|
|
|
|
}
|
|
|
|
hotplug_startup()
|
|
|
|
{
|
2020-11-04 16:24:55 +01:00
|
|
|
env -i MWAN3_STARTUP=$caller ACTION=ifup \
|
2020-08-13 02:38:56 +02:00
|
|
|
INTERFACE=$interface DEVICE=$l3_device \
|
|
|
|
sh /etc/hotplug.d/iface/15-mwan3
|
|
|
|
}
|
|
|
|
|
|
|
|
if [ "$up" != "1" ] || [ -z "$l3_device" ]; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
2020-11-04 16:24:55 +01:00
|
|
|
if [ "${caller}" = "init" ]; then
|
2020-08-13 02:38:56 +02:00
|
|
|
hotplug_startup &
|
|
|
|
hotplug_pids="$hotplug_pids $!"
|
|
|
|
else
|
|
|
|
hotplug_startup
|
|
|
|
fi
|
|
|
|
|
|
|
|
}
|
|
|
|
|
mwan3: fix interface-bound traffic when interface is offline
This commit fixed what 6d99b602 was supposed to fix without affecting
interface-bound traffic.
Before 6d99b602 interface-bound traffic was working normally as long
as at least one interface was online. However when the last interface
went offline, it was impossible to ping and such state was
unrecoverable.
Commit 6d99b602 fixed unrecoverable offline state problem (it was
possible to ping -I iface) but messed inteface-bound traffic. Traffic
with interface source address was not working if the interface was in
"offline" state, even if another interface was online.
The problem was caused by an inconsistent "offline" interface state:
iptables-related rules were kept while routing table and policy were
deleted.
The idea behind this commit is to:
1. Keep all the rules for each interface (iptables, routing table,
policy) regardless of its state. This ensures consistency,
2. Make interface state hotplug events affect only iptables'
mwan3_policy_* rules. Interface-related iptables, routing table
and policy is removed only when mwan3 is manually stopped.
To make such changes possible, it's necessary to change the way
mwan3_policy_* rule generator keeps track of interface state hotplug
events.
Until now, it checked for the existence of custom interface-related
routing table (table id 1, 2, 3, ...). Clearly we can no longer rely
on that so each interface state is stored explicitly in file.
Signed-off-by: Marcin Jurkowski <marcin1j@gmail.com>
2017-09-03 00:56:09 +02:00
|
|
|
mwan3_set_iface_hotplug_state() {
|
|
|
|
local iface=$1
|
|
|
|
local state=$2
|
|
|
|
|
2020-07-14 10:46:24 +02:00
|
|
|
echo "$state" > "$MWAN3_STATUS_DIR/iface_state/$iface"
|
mwan3: fix interface-bound traffic when interface is offline
This commit fixed what 6d99b602 was supposed to fix without affecting
interface-bound traffic.
Before 6d99b602 interface-bound traffic was working normally as long
as at least one interface was online. However when the last interface
went offline, it was impossible to ping and such state was
unrecoverable.
Commit 6d99b602 fixed unrecoverable offline state problem (it was
possible to ping -I iface) but messed inteface-bound traffic. Traffic
with interface source address was not working if the interface was in
"offline" state, even if another interface was online.
The problem was caused by an inconsistent "offline" interface state:
iptables-related rules were kept while routing table and policy were
deleted.
The idea behind this commit is to:
1. Keep all the rules for each interface (iptables, routing table,
policy) regardless of its state. This ensures consistency,
2. Make interface state hotplug events affect only iptables'
mwan3_policy_* rules. Interface-related iptables, routing table
and policy is removed only when mwan3 is manually stopped.
To make such changes possible, it's necessary to change the way
mwan3_policy_* rule generator keeps track of interface state hotplug
events.
Until now, it checked for the existence of custom interface-related
routing table (table id 1, 2, 3, ...). Clearly we can no longer rely
on that so each interface state is stored explicitly in file.
Signed-off-by: Marcin Jurkowski <marcin1j@gmail.com>
2017-09-03 00:56:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_get_iface_hotplug_state() {
|
|
|
|
local iface=$1
|
|
|
|
|
2020-07-14 10:46:24 +02:00
|
|
|
cat "$MWAN3_STATUS_DIR/iface_state/$iface" 2>/dev/null || echo "offline"
|
mwan3: fix interface-bound traffic when interface is offline
This commit fixed what 6d99b602 was supposed to fix without affecting
interface-bound traffic.
Before 6d99b602 interface-bound traffic was working normally as long
as at least one interface was online. However when the last interface
went offline, it was impossible to ping and such state was
unrecoverable.
Commit 6d99b602 fixed unrecoverable offline state problem (it was
possible to ping -I iface) but messed inteface-bound traffic. Traffic
with interface source address was not working if the interface was in
"offline" state, even if another interface was online.
The problem was caused by an inconsistent "offline" interface state:
iptables-related rules were kept while routing table and policy were
deleted.
The idea behind this commit is to:
1. Keep all the rules for each interface (iptables, routing table,
policy) regardless of its state. This ensures consistency,
2. Make interface state hotplug events affect only iptables'
mwan3_policy_* rules. Interface-related iptables, routing table
and policy is removed only when mwan3 is manually stopped.
To make such changes possible, it's necessary to change the way
mwan3_policy_* rule generator keeps track of interface state hotplug
events.
Until now, it checked for the existence of custom interface-related
routing table (table id 1, 2, 3, ...). Clearly we can no longer rely
on that so each interface state is stored explicitly in file.
Signed-off-by: Marcin Jurkowski <marcin1j@gmail.com>
2017-09-03 00:56:09 +02:00
|
|
|
}
|
|
|
|
|
2015-11-19 09:37:30 +01:00
|
|
|
mwan3_report_iface_status()
|
|
|
|
{
|
2020-11-10 14:51:07 +01:00
|
|
|
local device result tracking IP IPT error
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-14 10:46:24 +02:00
|
|
|
mwan3_get_iface_id id "$1"
|
|
|
|
network_get_device device "$1"
|
2015-11-19 09:37:30 +01:00
|
|
|
config_get enabled "$1" enabled 0
|
|
|
|
config_get family "$1" family ipv4
|
|
|
|
|
2020-07-14 09:24:28 +02:00
|
|
|
if [ "$family" = "ipv4" ]; then
|
2015-11-19 09:37:30 +01:00
|
|
|
IP="$IP4"
|
|
|
|
IPT="$IPT4"
|
|
|
|
fi
|
|
|
|
|
2020-07-14 09:24:28 +02:00
|
|
|
if [ "$family" = "ipv6" ]; then
|
2015-11-19 09:37:30 +01:00
|
|
|
IP="$IP6"
|
|
|
|
IPT="$IPT6"
|
|
|
|
fi
|
|
|
|
|
2020-07-14 11:47:15 +02:00
|
|
|
if [ -z "$id" ] || [ -z "$device" ]; then
|
2019-01-11 12:47:16 +01:00
|
|
|
result="offline"
|
2020-11-10 14:51:07 +01:00
|
|
|
else
|
|
|
|
error=0
|
|
|
|
[ -n "$($IP rule | awk '$1 == "'$((id+1000)):'"')" ] ||
|
|
|
|
error=$((error+1))
|
|
|
|
[ -n "$($IP rule | awk '$1 == "'$((id+2000)):'"')" ] ||
|
|
|
|
error=$((error+2))
|
|
|
|
[ -n "$($IP rule | awk '$1 == "'$((id+3000)):'"')" ] ||
|
|
|
|
error=$((error+4))
|
|
|
|
[ -n "$($IPT -S mwan3_iface_in_$1 2> /dev/null)" ] ||
|
|
|
|
error=$((error+8))
|
|
|
|
[ -n "$($IP route list table $id default dev $device 2> /dev/null)" ] ||
|
|
|
|
error=$((error+16))
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ "$result" = "offline" ]; then
|
|
|
|
:
|
|
|
|
elif [ $error -eq 0 ]; then
|
2020-11-13 01:21:04 +01:00
|
|
|
online=$(get_online_time "$1")
|
|
|
|
network_get_uptime uptime "$1"
|
2020-09-01 01:15:09 +02:00
|
|
|
online="$(printf '%02dh:%02dm:%02ds\n' $((online/3600)) $((online%3600/60)) $((online%60)))"
|
|
|
|
uptime="$(printf '%02dh:%02dm:%02ds\n' $((uptime/3600)) $((uptime%3600/60)) $((uptime%60)))"
|
2019-06-28 13:55:29 +02:00
|
|
|
result="$(mwan3_get_iface_hotplug_state $1) $online, uptime $uptime"
|
2020-11-10 14:51:07 +01:00
|
|
|
elif [ $error -gt 0 ] && [ $error -ne 31 ]; then
|
|
|
|
result="error (${error})"
|
2020-07-14 09:24:28 +02:00
|
|
|
elif [ "$enabled" = "1" ]; then
|
mwan3: fix interface-bound traffic when interface is offline
This commit fixed what 6d99b602 was supposed to fix without affecting
interface-bound traffic.
Before 6d99b602 interface-bound traffic was working normally as long
as at least one interface was online. However when the last interface
went offline, it was impossible to ping and such state was
unrecoverable.
Commit 6d99b602 fixed unrecoverable offline state problem (it was
possible to ping -I iface) but messed inteface-bound traffic. Traffic
with interface source address was not working if the interface was in
"offline" state, even if another interface was online.
The problem was caused by an inconsistent "offline" interface state:
iptables-related rules were kept while routing table and policy were
deleted.
The idea behind this commit is to:
1. Keep all the rules for each interface (iptables, routing table,
policy) regardless of its state. This ensures consistency,
2. Make interface state hotplug events affect only iptables'
mwan3_policy_* rules. Interface-related iptables, routing table
and policy is removed only when mwan3 is manually stopped.
To make such changes possible, it's necessary to change the way
mwan3_policy_* rule generator keeps track of interface state hotplug
events.
Until now, it checked for the existence of custom interface-related
routing table (table id 1, 2, 3, ...). Clearly we can no longer rely
on that so each interface state is stored explicitly in file.
Signed-off-by: Marcin Jurkowski <marcin1j@gmail.com>
2017-09-03 00:56:09 +02:00
|
|
|
result="offline"
|
2015-11-19 09:37:30 +01:00
|
|
|
else
|
mwan3: fix interface-bound traffic when interface is offline
This commit fixed what 6d99b602 was supposed to fix without affecting
interface-bound traffic.
Before 6d99b602 interface-bound traffic was working normally as long
as at least one interface was online. However when the last interface
went offline, it was impossible to ping and such state was
unrecoverable.
Commit 6d99b602 fixed unrecoverable offline state problem (it was
possible to ping -I iface) but messed inteface-bound traffic. Traffic
with interface source address was not working if the interface was in
"offline" state, even if another interface was online.
The problem was caused by an inconsistent "offline" interface state:
iptables-related rules were kept while routing table and policy were
deleted.
The idea behind this commit is to:
1. Keep all the rules for each interface (iptables, routing table,
policy) regardless of its state. This ensures consistency,
2. Make interface state hotplug events affect only iptables'
mwan3_policy_* rules. Interface-related iptables, routing table
and policy is removed only when mwan3 is manually stopped.
To make such changes possible, it's necessary to change the way
mwan3_policy_* rule generator keeps track of interface state hotplug
events.
Until now, it checked for the existence of custom interface-related
routing table (table id 1, 2, 3, ...). Clearly we can no longer rely
on that so each interface state is stored explicitly in file.
Signed-off-by: Marcin Jurkowski <marcin1j@gmail.com>
2017-09-03 00:56:09 +02:00
|
|
|
result="disabled"
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
|
2020-08-13 02:38:56 +02:00
|
|
|
tracking="$(mwan3_get_mwan3track_status $1)"
|
2015-11-19 09:37:30 +01:00
|
|
|
echo " interface $1 is $result and tracking is $tracking"
|
|
|
|
}
|
|
|
|
|
2018-10-15 16:24:25 +02:00
|
|
|
mwan3_report_policies()
|
2015-11-19 09:37:30 +01:00
|
|
|
{
|
2018-10-15 16:24:25 +02:00
|
|
|
local ipt="$1"
|
|
|
|
local policy="$2"
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2018-10-15 16:24:25 +02:00
|
|
|
local percent total_weight weight iface
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-07-14 10:46:24 +02:00
|
|
|
total_weight=$($ipt -S "$policy" | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | head -1 | awk '{print $3}')
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2020-09-01 01:15:09 +02:00
|
|
|
if [ -n "${total_weight##*[!0-9]*}" ]; then
|
2020-07-14 10:46:24 +02:00
|
|
|
for iface in $($ipt -S "$policy" | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | awk '{print $1}'); do
|
|
|
|
weight=$($ipt -S "$policy" | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | awk '$1 == "'$iface'"' | awk '{print $2}')
|
2020-09-01 01:15:09 +02:00
|
|
|
percent=$((weight*100/total_weight))
|
2018-10-15 16:24:25 +02:00
|
|
|
echo " $iface ($percent%)"
|
|
|
|
done
|
|
|
|
else
|
2020-07-14 10:46:24 +02:00
|
|
|
echo " $($ipt -S "$policy" | grep -v '.*--comment "out .*" .*$' | sed '/.*--comment \([^ ]*\) .*$/!d;s//\1/;q')"
|
2018-10-15 16:24:25 +02:00
|
|
|
fi
|
|
|
|
}
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2018-10-15 16:24:25 +02:00
|
|
|
mwan3_report_policies_v4()
|
|
|
|
{
|
|
|
|
local policy
|
2015-11-19 09:37:30 +01:00
|
|
|
|
2018-10-15 16:24:25 +02:00
|
|
|
for policy in $($IPT4 -S | awk '{print $2}' | grep mwan3_policy_ | sort -u); do
|
|
|
|
echo "$policy:" | sed 's/mwan3_policy_//'
|
|
|
|
mwan3_report_policies "$IPT4" "$policy"
|
2015-11-19 09:37:30 +01:00
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_report_policies_v6()
|
|
|
|
{
|
2018-10-15 16:24:25 +02:00
|
|
|
local policy
|
2015-11-19 09:37:30 +01:00
|
|
|
|
|
|
|
for policy in $($IPT6 -S | awk '{print $2}' | grep mwan3_policy_ | sort -u); do
|
|
|
|
echo "$policy:" | sed 's/mwan3_policy_//'
|
2018-10-15 16:24:25 +02:00
|
|
|
mwan3_report_policies "$IPT6" "$policy"
|
2015-11-19 09:37:30 +01:00
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_report_connected_v4()
|
|
|
|
{
|
2022-03-01 08:58:32 +01:00
|
|
|
if [ -n "$($IPT4 -S mwan3_connected_ipv4 2> /dev/null)" ]; then
|
|
|
|
$IPS -o save list mwan3_connected_ipv4 | grep add | cut -d " " -f 3
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_report_connected_v6()
|
|
|
|
{
|
2022-03-01 08:58:32 +01:00
|
|
|
if [ -n "$($IPT6 -S mwan3_connected_ipv6 2> /dev/null)" ]; then
|
|
|
|
$IPS -o save list mwan3_connected_ipv6 | grep add | cut -d " " -f 3
|
2015-11-19 09:37:30 +01:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_report_rules_v4()
|
|
|
|
{
|
|
|
|
if [ -n "$($IPT4 -S mwan3_rules 2> /dev/null)" ]; then
|
|
|
|
$IPT4 -L mwan3_rules -n -v 2> /dev/null | tail -n+3 | sed 's/mark.*//' | sed 's/mwan3_policy_/- /' | sed 's/mwan3_rule_/S /'
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
mwan3_report_rules_v6()
|
|
|
|
{
|
|
|
|
if [ -n "$($IPT6 -S mwan3_rules 2> /dev/null)" ]; then
|
|
|
|
$IPT6 -L mwan3_rules -n -v 2> /dev/null | tail -n+3 | sed 's/mark.*//' | sed 's/mwan3_policy_/- /' | sed 's/mwan3_rule_/S /'
|
|
|
|
fi
|
|
|
|
}
|
2017-03-14 13:57:45 +01:00
|
|
|
|
|
|
|
mwan3_flush_conntrack()
|
|
|
|
{
|
2019-05-22 09:14:38 +02:00
|
|
|
local interface="$1"
|
|
|
|
local action="$2"
|
2017-03-14 13:57:45 +01:00
|
|
|
|
2019-05-22 09:14:38 +02:00
|
|
|
handle_flush() {
|
|
|
|
local flush_conntrack="$1"
|
|
|
|
local action="$2"
|
|
|
|
|
|
|
|
if [ "$action" = "$flush_conntrack" ]; then
|
|
|
|
echo f > ${CONNTRACK_FILE}
|
2020-07-26 23:21:50 +02:00
|
|
|
LOG info "Connection tracking flushed for interface '$interface' on action '$action'"
|
2019-05-22 09:14:38 +02:00
|
|
|
fi
|
|
|
|
}
|
2017-03-14 13:57:45 +01:00
|
|
|
|
|
|
|
if [ -e "$CONNTRACK_FILE" ]; then
|
2019-05-22 09:14:38 +02:00
|
|
|
config_list_foreach "$interface" flush_conntrack handle_flush "$action"
|
2017-03-14 13:57:45 +01:00
|
|
|
fi
|
|
|
|
}
|
2017-07-24 10:20:46 +02:00
|
|
|
|
|
|
|
mwan3_track_clean()
|
|
|
|
{
|
2020-09-01 01:15:09 +02:00
|
|
|
rm -rf "${MWAN3_STATUS_DIR:?}/${1}" &> /dev/null
|
2020-07-26 23:21:50 +02:00
|
|
|
rmdir --ignore-fail-on-non-empty "$MWAN3_STATUS_DIR"
|
2017-07-24 10:20:46 +02:00
|
|
|
}
|