@ -1,6 +1,6 @@
#!/bin/sh /etc/rc.common
#!/bin/sh /etc/rc.common
# Copyright 2017-2020 Stan Grishin (stangri@melmac.net)
# Copyright 2017-2020 Stan Grishin (stangri@melmac.net)
# shellcheck disable=SC2039,SC1091,SC2018,SC2019
# shellcheck disable=SC2039,SC1091,SC2018,SC2019,SC3043,SC3057,SC3060
PKG_VERSION='dev-test'
PKG_VERSION='dev-test'
# sysctl net.ipv4.conf.default.rp_filter=1
# sysctl net.ipv4.conf.default.rp_filter=1
@ -18,9 +18,10 @@ if type extra_command 1>/dev/null 2>&1; then
WARNING: while paste.ee uploads are unlisted, they are still publicly available
WARNING: while paste.ee uploads are unlisted, they are still publicly available
List domain names after options to include their lookup in report"
List domain names after options to include their lookup in report"
extra_command 'version' 'Show version information'
extra_command 'version' 'Show version information'
extra_command 'reload_interface' 'Reload specific interface only'
else
else
# shellcheck disable=SC2034
# shellcheck disable=SC2034
EXTRA_COMMANDS='support version'
EXTRA_COMMANDS='reload_interface support version'
# shellcheck disable=SC2034
# shellcheck disable=SC2034
EXTRA_HELP=" support Generates output required to troubleshoot routing issues
EXTRA_HELP=" support Generates output required to troubleshoot routing issues
Use '-d' option for more detailed output
Use '-d' option for more detailed output
@ -50,15 +51,12 @@ wanIface4=''; wanIface6=''; ifaceMark=''; ifaceTableID='';
ifAll=''; ifSupported=''; ignoredIfaces=''; supportedIfaces=''; icmpIface='';
ifAll=''; ifSupported=''; ignoredIfaces=''; supportedIfaces=''; icmpIface='';
wanGW4=''; wanGW6=''; bootTimeout=''; insertOption='';
wanGW4=''; wanGW6=''; bootTimeout=''; insertOption='';
webuiChainColumn=''; webuiShowIgnore=''; dnsmasqIpsetSupported='';
webuiChainColumn=''; webuiShowIgnore=''; dnsmasqIpsetSupported='';
procdReloadDelay='';
procdReloadDelay=''; mainTableListing='';
usedChainsList='PREROUTING'
usedChainsList='PREROUTING'
ipsetSupported='true'
ipsetSupported='true'
configLoaded='false'
configLoaded='false'
version() { echo "$PKG_VERSION"; }
version() { echo "$PKG_VERSION"; }
create_lock() { [ -e "$PIDFile" ] && return 1; touch "$PIDFile"; }
remove_lock() { [ -e "$PIDFile" ] && rm -f "$PIDFile"; }
trap remove_lock EXIT
output_ok() { output 1 "$_OK_"; output 2 "$__OK__\\n"; }
output_ok() { output 1 "$_OK_"; output 2 "$__OK__\\n"; }
output_okn() { output 1 "$_OK_\\n"; output 2 "$__OK__\\n"; }
output_okn() { output 1 "$_OK_\\n"; output 2 "$__OK__\\n"; }
output_fail() { s=1; output 1 "$_FAIL_"; output 2 "$__FAIL__\\n"; }
output_fail() { s=1; output 1 "$_FAIL_"; output 2 "$__FAIL__\\n"; }
@ -75,7 +73,7 @@ output() {
# Can take a single parameter (text) to be output at any verbosity
# Can take a single parameter (text) to be output at any verbosity
# Or target verbosity level and text to be output at specifc verbosity
# Or target verbosity level and text to be output at specifc verbosity
local msg memmsg logmsg
local msg memmsg logmsg
if [ $# -ne 1 ]; then
if [ " $#" -ne 1 ]; then
if [ $((verbosity & $1)) -gt 0 ] || [ "$verbosity" = "$1" ]; then shift; else return 0; fi
if [ $((verbosity & $1)) -gt 0 ] || [ "$verbosity" = "$1" ]; then shift; else return 0; fi
fi
fi
[ -t 1 ] && printf "%b" "$1"
[ -t 1 ] && printf "%b" "$1"
@ -125,7 +123,7 @@ vpr_get_gateway6() {
}
}
is_l2tp() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:4}" = "l2tp" ]; }
is_l2tp() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:4}" = "l2tp" ]; }
is_oc() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:11}" = "openconnect" ]; }
is_oc() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:11}" = "openconnect" ]; }
is_ovpn() { local dev; dev=$(uci -q get network."$1".ifname) ; [ "${dev:0:3}" = "tun" ] || [ "${dev:0:3}" = "tap" ] || [ -f "/sys/devices/virtual/net/${dev}/tun_flags" ]; }
is_ovpn() { local dev i; for i in ifname device; do [ -z "$dev" ] && dev="$(uci -q get "network.${1}.${i}")"; done ; [ "${dev:0:3}" = "tun" ] || [ "${dev:0:3}" = "tap" ] || [ -f "/sys/devices/virtual/net/${dev}/tun_flags" ]; }
is_pptp() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:4}" = "pptp" ]; }
is_pptp() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:4}" = "pptp" ]; }
is_tor() { [ "$(str_to_lower "$1")" = "tor" ]; }
is_tor() { [ "$(str_to_lower "$1")" = "tor" ]; }
is_tor_running() {
is_tor_running() {
@ -160,13 +158,15 @@ dnsmasq_kill() { killall -q -HUP dnsmasq; }
dnsmasq_restart() { output 3 'Restarting DNSMASQ '; if /etc/init.d/dnsmasq restart >/dev/null 2>&1; then output_okn; else output_failn; fi; }
dnsmasq_restart() { output 3 'Restarting DNSMASQ '; if /etc/init.d/dnsmasq restart >/dev/null 2>&1; then output_okn; else output_failn; fi; }
is_default_dev() { [ "$1" = "$(ip -4 r | grep -m1 'dev' | grep -Eso 'dev [^ ]*' | awk '{print $2}')" ]; }
is_default_dev() { [ "$1" = "$(ip -4 r | grep -m1 'dev' | grep -Eso 'dev [^ ]*' | awk '{print $2}')" ]; }
is_supported_iface_dev() {
is_supported_iface_dev() {
local n
for n in $ifSupported; do
for n in $ifSupported; do
if [ "$1" = "$(uci -q get "network.${n}.ifname" || echo "$n")" ] || \
if [ "$1" = "$(uci -q get "network.${n}.ifname" || echo "$n")" ] || \
[ "$1" = "$(uci -q get "network.${n}.device" || echo "$n")" ] || \
[ "$1" = "$(uci -q get "network.${n}.proto")-${n}" ] ; then return 0; fi
[ "$1" = "$(uci -q get "network.${n}.proto")-${n}" ] ; then return 0; fi
done
done
return 1
return 1
}
}
is_supported_protocol () { grep -o '^[^#]*' /etc/protocols | grep -w -v '0' | grep . | awk '{print $1}' | grep -q "$1"; }
is_supported_protocol() { grep -o '^[^#]*' /etc/protocols | grep -w -v '0' | grep . | awk '{print $1}' | grep -q "$1"; }
append_chains_targets() {
append_chains_targets() {
local chain iface name
local chain iface name
config_get name "$1" 'name' 'blank'
config_get name "$1" 'name' 'blank'
@ -195,6 +195,7 @@ load_package_config() {
config_get_bool ipv6Enabled 'config' 'ipv6_enabled' 0
config_get_bool ipv6Enabled 'config' 'ipv6_enabled' 0
config_get_bool srcIpset 'config' 'src_ipset' 0
config_get_bool srcIpset 'config' 'src_ipset' 0
config_get_bool destIpset 'config' 'dest_ipset' 0
config_get_bool destIpset 'config' 'dest_ipset' 0
config_get_bool mainTableListing 'config' 'quick_table_create' 0
config_get resolverIpset 'config' 'resolver_ipset' 'dnsmasq.ipset'
config_get resolverIpset 'config' 'resolver_ipset' 'dnsmasq.ipset'
config_get verbosity 'config' 'verbosity' '2'
config_get verbosity 'config' 'verbosity' '2'
config_get wanTableID 'config' 'wan_tid' '201'
config_get wanTableID 'config' 'wan_tid' '201'
@ -220,6 +221,12 @@ load_package_config() {
mkdir -p "${jsonFile%/*}"
mkdir -p "${jsonFile%/*}"
mkdir -p "${dnsmasqFile%/*}"
mkdir -p "${dnsmasqFile%/*}"
if [ "$mainTableListing" -ne 0 ]; then
mainTableListing='default'
else
mainTableListing=''
fi
if [ -n "$icmpIface" ] && ! str_contains_word "$usedChainsList" 'OUTPUT'; then
if [ -n "$icmpIface" ] && ! str_contains_word "$usedChainsList" 'OUTPUT'; then
usedChainsList="$usedChainsList OUTPUT"
usedChainsList="$usedChainsList OUTPUT"
fi
fi
@ -482,7 +489,7 @@ insert_policy() {
return 0
return 0
}
}
r_process_policy(){
r_process_policy() {
local comment="$1" iface="$2" laddr="$3" lport="$4" raddr="$5" rport="$6" proto="$7" chain="$8" resolved_laddr resolved_raddr i ipsFailFlag
local comment="$1" iface="$2" laddr="$3" lport="$4" raddr="$5" rport="$6" proto="$7" chain="$8" resolved_laddr resolved_raddr i ipsFailFlag
if str_contains "$laddr" '[ ;\{\}]'; then
if str_contains "$laddr" '[ ;\{\}]'; then
for i in $(str_extras_to_space "$laddr"); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$i" "$lport" "$raddr" "$rport" "$proto" "$chain"; done
for i in $(str_extras_to_space "$laddr"); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$i" "$lport" "$raddr" "$rport" "$proto" "$chain"; done
@ -546,7 +553,7 @@ r_process_policy(){
fi
fi
}
}
process_policy(){
process_policy() {
local name comment iface laddr lport raddr rport param mark processPolicyError processPolicyWarning proto chain enabled
local name comment iface laddr lport raddr rport param mark processPolicyError processPolicyWarning proto chain enabled
config_get comment "$1" 'comment'
config_get comment "$1" 'comment'
config_get name "$1" 'name' 'blank'
config_get name "$1" 'name' 'blank'
@ -597,22 +604,18 @@ process_policy(){
fi
fi
}
}
table_destroy(){
table_destroy() {
local tid="$1" iface="$2" mark="$3"
local tid="$1" iface="$2" mark="$3"
if [ -n "$tid" ] && [ -n "$iface" ] && [ -n "$mark" ]; then
if [ -n "$tid" ] && [ -n "$iface" ] && [ -n "$mark" ]; then
ipt -t mangle -F "VPR_MARK${mark}"
ipt -t mangle -F "VPR_MARK${mark}"
ipt -t mangle -X "VPR_MARK${mark}"
ipt -t mangle -X "VPR_MARK${mark}"
ip -4 rule del fwmark "$mark" table "$tid" >/dev/null 2>&1
ip -6 rule del fwmark "$mark" table "$tid" >/dev/null 2>&1
ip -4 rule del table "$tid" >/dev/null 2>&1
ip -6 rule del table "$tid" >/dev/null 2>&1
ip -4 route flush table "$tid" >/dev/null 2>&1
ip -6 route flush table "$tid" >/dev/null 2>&1
ip rule del fwmark "$mark" table "$tid" >/dev/null 2>&1
ip rule del table "$tid" >/dev/null 2>&1
ip route flush table "$tid" >/dev/null 2>&1
ips 'flush' "${iface}"; ips 'destroy' "${iface}";
ips 'flush' "${iface}"; ips 'destroy' "${iface}";
ips 'flush' "${iface}_ip"; ips 'destroy' "${iface}_ip";
ips 'flush' "${iface}_ip"; ips 'destroy' "${iface}_ip";
ips 'flush' "${iface}_mac"; ips 'destroy' "${iface}_mac";
ips 'flush' "${iface}_mac"; ips 'destroy' "${iface}_mac";
ip -4 route flush cache
ip -6 route flush cache
ip route flush cache
sed -i "/$iface/d" /etc/iproute2/rt_tables
sed -i "/$iface/d" /etc/iproute2/rt_tables
return 0
return 0
else
else
@ -621,31 +624,33 @@ table_destroy(){
}
}
# shellcheck disable=SC2086
# shellcheck disable=SC2086
table_create(){
local tid="$1" mark="$2" iface="$3" gw4="$4" dev="$5" gw6="$6" dev6="$7" dscp s=0 i ipv4_error=0 ipv6_error=1
table_create() {
local tid="$1" mark="$2" iface="$3" gw4="$4" dev="$5" gw6="$6" dev6="$7" match="$8" dscp s=0 i ipv4_error=0 ipv6_error=1
if [ -z "$tid" ] || [ -z "$mark" ] || [ -z "$iface" ]; then
if [ -z "$tid" ] || [ -z "$mark" ] || [ -z "$iface" ]; then
return 1
return 1
fi
fi
table_destroy "$tid" "$iface" "$mark"
sed -i "/$iface/d" /etc/iproute2/rt_tables
ip route flush table "$tid" >/dev/null 2>&1
if [ -n "$gw4" ] || [ "$strictMode" -ne 0 ]; then
if [ -n "$gw4" ] || [ "$strictMode" -ne 0 ]; then
echo "$tid" " $iface" >> /etc/iproute2/rt_tables
echo "$tid $iface" >> /etc/iproute2/rt_tables
if [ -z "$gw4" ]; then
if [ -z "$gw4" ]; then
ip -4 route add unreachable default table "$tid" >/dev/null 2>&1 || ipv4_error=1
ip -4 route add unreachable default table "$tid" >/dev/null 2>&1 || ipv4_error=1
else
else
ip -4 route add default via "$gw4" dev "$dev" table "$tid" >/dev/null 2>&1 || ipv4_error=1
ip -4 route add default via "$gw4" dev "$dev" table "$tid" >/dev/null 2>&1 || ipv4_error=1
fi
fi
# ip -4 route list table main | grep -v 'br-lan' | while read -r i; do
ip -4 route list table main | while read -r i; do
while read -r i; do
idev="$(echo "$i" | grep -Eso 'dev [^ ]*' | awk '{print $2}')"
idev="$(echo "$i" | grep -Eso 'dev [^ ]*' | awk '{print $2}')"
if ! is_supported_iface_dev "$idev"; then
if ! is_supported_iface_dev "$idev"; then
ip -4 route add $i table "$tid" >/dev/null 2>&1 || ipv4_error=1
ip -4 route add $i table "$tid" >/dev/null 2>&1 || ipv4_error=1
fi
fi
done
ip -4 route flush cache || ipv4_error=1
ip -4 rule add fwmark "${mark}/${fwMask}" table "$tid" || ipv4_error=1
done << EOF
$(ip -4 route list $mainTableListing table main)
EOF
[ -n "$(ip rule list fwmark "${mark}/${fwMask}" table "$tid")" ] || \
ip rule add fwmark "${mark}/${fwMask}" table "$tid" || ipv4_error=1
ipt -t mangle -N "VPR_MARK${mark}" || ipv4_error=1
ipt -t mangle -N "VPR_MARK${mark}" || ipv4_error=1
ipt -t mangle -A "VPR_MARK${mark}" -j MARK --set-xmark "${mark}/${fwMask}" || ipv4_error=1
ipt -t mangle -A "VPR_MARK${mark}" -j MARK --set-xmark "${mark}/${fwMask}" || ipv4_error=1
ipt -t mangle -A "VPR_MARK${mark}" -j RETURN || ipv4_error=1
ipt -t mangle -A "VPR_MARK${mark}" -j RETURN || ipv4_error=1
@ -657,16 +662,16 @@ table_create(){
if [ -z "$gw6" ] || [ "$gw6" = "::/0" ]; then
if [ -z "$gw6" ] || [ "$gw6" = "::/0" ]; then
ip -6 route add unreachable default table "$tid" || ipv6_error=1
ip -6 route add unreachable default table "$tid" || ipv6_error=1
else
else
ip -6 route list table main | grep " dev $dev6 " | while read -r i; do
while read -r i; do
ip -6 route add $i table "$tid" >/dev/null 2>&1 || ipv6_error=1
ip -6 route add $i table "$tid" >/dev/null 2>&1 || ipv6_error=1
done
done << EOF
$(ip -6 route list $mainTableListing table main | grep " dev $dev6 ")
EOF
fi
fi
ip -6 route flush cache || ipv6_error=1
ip -6 rule add fwmark "${mark}/${fwMask}" table "$tid" || ipv6_error=1
fi
fi
fi
fi
if [ $ipv4_error -eq 0 ] || [ $ipv6_error -eq 0 ]; then
if [ " $ipv4_error" -eq 0 ] || [ " $ipv6_error" -eq 0 ]; then
dscp="$(uci -q get "${packageName}".config."${iface}"_dscp)"
dscp="$(uci -q get "${packageName}".config."${iface}"_dscp)"
if [ "${dscp:-0}" -ge 1 ] && [ "${dscp:-0}" -le 63 ]; then
if [ "${dscp:-0}" -ge 1 ] && [ "${dscp:-0}" -le 63 ]; then
ipt -t mangle -I VPR_PREROUTING -m dscp --dscp "${dscp}" -g "VPR_MARK${mark}" || s=1
ipt -t mangle -I VPR_PREROUTING -m dscp --dscp "${dscp}" -g "VPR_MARK${mark}" || s=1
@ -704,8 +709,59 @@ table_create(){
return $s
return $s
}
}
process_interface(){
local gw4 gw6 dev dev6 s=0 dscp iface="$1" action="$2" displayText
table_reload() {
local tid="$1" mark="$2" iface="$3" gw4="$4" dev="$5" gw6="$6" dev6="$7" match="$8" dscp s=0 i ipv4_error=0 ipv6_error=1
if [ -z "$tid" ] || [ -z "$mark" ] || [ -z "$iface" ]; then
return 1
fi
ip -4 route del default table "$tid" >/dev/null 2>&1
if [ -n "$gw4" ] || [ "$strictMode" -ne 0 ]; then
if [ -z "$gw4" ]; then
ip -4 route add unreachable default table "$tid" >/dev/null 2>&1 || ipv4_error=1
else
ip -4 route add default via "$gw4" dev "$dev" table "$tid" >/dev/null 2>&1 || ipv4_error=1
fi
ip -4 route flush cache || ipv4_error=1
ip -4 rule del fwmark "${mark}/${fwMask}" table "$tid" >/dev/null 2>&1
ip -4 rule add fwmark "${mark}/${fwMask}" table "$tid" || ipv4_error=1
fi
if [ "$ipv6Enabled" -ne 0 ]; then
ip -6 route del default table "$tid" >/dev/null 2>&1
ipv6_error=0
if { [ -n "$gw6" ] && [ "$gw6" != "::/0" ]; } || [ "$strictMode" -ne 0 ]; then
if [ -z "$gw6" ] || [ "$gw6" = "::/0" ]; then
ip -6 route add unreachable default table "$tid" || ipv6_error=1
else
ip -6 route list table main | grep " dev $dev6 " | while read -r i; do
ip -6 route add "$i" table "$tid" >/dev/null 2>&1 || ipv6_error=1
done
fi
ip -6 route flush cache || ipv6_error=1
ip -6 rule del fwmark "${mark}/${fwMask}" table "$tid" >/dev/null 2>&1
ip -6 rule add fwmark "${mark}/${fwMask}" table "$tid" || ipv6_error=1
fi
fi
if [ "$ipv4_error" -eq 0 ] || [ "$ipv6_error" -eq 0 ]; then
dscp="$(uci -q get "${packageName}".config."${iface}"_dscp)"
if [ "${dscp:-0}" -ge 1 ] && [ "${dscp:-0}" -le 63 ]; then
ipt -t mangle -I VPR_PREROUTING -m dscp --dscp "${dscp}" -g "VPR_MARK${mark}" || s=1
fi
if [ "$iface" = "$icmpIface" ]; then
ipt -t mangle -I VPR_OUTPUT -p icmp -g "VPR_MARK${mark}" || s=1
fi
else
s=1
fi
return $s
}
process_interface() {
local gw4 gw6 dev dev6 s=0 dscp iface="$1" action="$2" match="$3" displayText
is_supported_interface "$iface" || return 0
is_supported_interface "$iface" || return 0
is_wan6 "$iface" && return 0
is_wan6 "$iface" && return 0
@ -713,9 +769,11 @@ process_interface(){
network_get_device dev "$iface"
network_get_device dev "$iface"
[ -z "$dev" ] && config_get dev "$iface" 'ifname'
[ -z "$dev" ] && config_get dev "$iface" 'ifname'
[ -z "$dev" ] && config_get dev "$iface" 'device'
if is_wan "$iface" && [ -n "$wanIface6" ]; then
if is_wan "$iface" && [ -n "$wanIface6" ]; then
network_get_device dev6 "$wanIface6"
network_get_device dev6 "$wanIface6"
[ -z "$dev6" ] && config_get dev6 "$wanIface6" 'ifname'
[ -z "$dev6" ] && config_get dev6 "$wanIface6" 'ifname'
[ -z "$dev6" ] && config_get dev6 "$wanIface6" 'device'
fi
fi
[ -z "$dev6" ] && dev6="$dev"
[ -z "$dev6" ] && dev6="$dev"
@ -729,7 +787,6 @@ process_interface(){
create)
create)
eval "mark_${iface//-/_}"='$ifaceMark'
eval "mark_${iface//-/_}"='$ifaceMark'
eval "tid_${iface//-/_}"='$ifaceTableID'
eval "tid_${iface//-/_}"='$ifaceTableID'
table_destroy "${ifaceTableID}" "${iface}"
vpr_get_gateway gw4 "$iface" "$dev"
vpr_get_gateway gw4 "$iface" "$dev"
vpr_get_gateway6 gw6 "$iface" "$dev6"
vpr_get_gateway6 gw6 "$iface" "$dev6"
if [ "$iface" = "$dev" ]; then
if [ "$iface" = "$dev" ]; then
@ -738,14 +795,29 @@ process_interface(){
displayText="${iface}/${dev}/${gw4:-0.0.0.0}"
displayText="${iface}/${dev}/${gw4:-0.0.0.0}"
fi
fi
[ "$ipv6Enabled" -ne 0 ] && displayText="${displayText}/${gw6:-::/0}"
[ "$ipv6Enabled" -ne 0 ] && displayText="${displayText}/${gw6:-::/0}"
output 2 "Creating table '$displayText' "
is_default_dev "$dev" && displayText="${displayText} ${__OK__}"
if table_create "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6"; then
gatewaySummary="${gatewaySummary}${displayText}\\n"
output_ok
if [ -z "$match" ]; then
output 2 "Creating table '$displayText' "
is_default_dev "$dev" && displayText="${displayText} ${__OK__}"
if table_create "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6" "$match"; then
gatewaySummary="${gatewaySummary}${displayText}\\n"
output_ok
else
errorSummary="${errorSummary}${_ERROR_}: Failed to set up '$displayText'\\n"
output_fail
fi
elif [ "$iface" = "$match" ]; then
output 2 "Reloading table '$displayText' "
is_default_dev "$dev" && displayText="${displayText} ${__OK__}"
if table_reload "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6" "$match"; then
gatewaySummary="${gatewaySummary}${displayText}\\n"
output_ok
else
errorSummary="${errorSummary}${_ERROR_}: Failed to reload '$displayText'\\n"
output_fail
fi
else
else
errorSummary="${errorSummary}${_ERROR_}: Failed to set up '$displayText'\\n"
output_fail
is_default_dev "$dev" && displayText="${displayText} ${__OK__} "
gatewaySummary="${gatewaySummary}${displayText}\\n"
fi
fi
ifaceTableID="$((ifaceTableID + 1))"; ifaceMark="$(printf '0x%06x' $((ifaceMark + wanMark)))";
ifaceTableID="$((ifaceTableID + 1))"; ifaceMark="$(printf '0x%06x' $((ifaceMark + wanMark)))";
;;
;;
@ -753,7 +825,7 @@ process_interface(){
return $s
return $s
}
}
process_tor_interface(){
process_tor_interface() {
local s=0 iface="$1" action="$2" displayText
local s=0 iface="$1" action="$2" displayText
case "$action" in
case "$action" in
destroy)
destroy)
@ -783,7 +855,7 @@ process_tor_interface(){
s=1
s=1
fi
fi
displayText="${iface}/53->${dnsPort}/80,443->${transPort}"
displayText="${iface}/53->${dnsPort}/80,443->${transPort}"
if [ "$s" -eq " 0" ]; then
if [ "$s" -eq 0 ]; then
gatewaySummary="${gatewaySummary}${displayText}\\n"
gatewaySummary="${gatewaySummary}${displayText}\\n"
output_ok
output_ok
else
else
@ -795,7 +867,7 @@ process_tor_interface(){
return $s
return $s
}
}
convert_config(){
convert_config() {
local i src_ipset dest_ipset resolver_ipset
local i src_ipset dest_ipset resolver_ipset
[ -s "/etc/config/${packageName}" ] || return 0
[ -s "/etc/config/${packageName}" ] || return 0
grep -q "ignored_interfaces" "/etc/config/${packageName}" && sed -i 's/ignored_interfaces/ignored_interface/g' "/etc/config/${packageName}"
grep -q "ignored_interfaces" "/etc/config/${packageName}" && sed -i 's/ignored_interfaces/ignored_interface/g' "/etc/config/${packageName}"
@ -853,8 +925,8 @@ convert_config(){
done
done
}
}
check_config(){ local en; config_get_bool en "$1" 'enabled' 1; [ "$en" -gt 0 ] && _cfg_enabled=0; }
is_config_enabled(){
check_config() { local en; config_get_bool en "$1" 'enabled' 1; [ "$en" -gt 0 ] && _cfg_enabled=0; }
is_config_enabled() {
local cfg="$1" _cfg_enabled=1
local cfg="$1" _cfg_enabled=1
[ -n "$1" ] || return 1
[ -n "$1" ] || return 1
config_load "$packageName"
config_load "$packageName"
@ -862,7 +934,7 @@ is_config_enabled(){
return "$_cfg_enabled"
return "$_cfg_enabled"
}
}
process_user_file(){
process_user_file() {
local path enabled shellBin="${SHELL:-/bin/ash}"
local path enabled shellBin="${SHELL:-/bin/ash}"
config_get_bool enabled "$1" 'enabled' 1
config_get_bool enabled "$1" 'enabled' 1
config_get path "$1" 'path'
config_get path "$1" 'path'
@ -893,37 +965,46 @@ process_user_file(){
fi
fi
}
}
boot() { rc_procd start_service && rc_procd service_triggers; }
start_service() {
start_service() {
local dnsmasqStoredHash dnsmasqNewHash i modprobeStatus=0
local dnsmasqStoredHash dnsmasqNewHash i modprobeStatus=0 reloadedIface="$1"
convert_config
convert_config
is_enabled 'on_start' || return 1
is_enabled 'on_start' || return 1
is_wan_up || return 1
is_wan_up || return 1
if create_lock; then
if [ -s "$dnsmasqFile" ]; then
dnsmasqStoredHash="$(md5sum $dnsmasqFile | awk '{ print $1; }')"
rm -f "$dnsmasqFile"
fi
for i in xt_set ip_set ip_set_hash_ip; do
modprobe "$i" >/dev/null 2>/dev/null || modprobeStatus=$((modprobeStatus + 1))
done
iptables -t 'mangle' --list 'VPR_PREROUTING' >/dev/null 2>&1 || unset reloadedIface
[ -n "$(tmpfs get status)" ] || unset reloadedIface
if [ "$modprobeStatus" -gt 0 ] && ! is_chaos_calmer; then
errorSummary="${errorSummary}${_ERROR_}: Failed to load kernel modules\\n"
fi
if [ -s "$dnsmasqFile" ]; then
dnsmasqStoredHash="$(md5sum $dnsmasqFile | awk '{ print $1; }')"
rm -f "$dnsmasqFile"
fi
for i in xt_set ip_set ip_set_hash_ip; do
modprobe "$i" >/dev/null 2>/dev/null || modprobeStatus=$((modprobeStatus + 1))
done
if [ "$modprobeStatus" -gt 0 ] && ! is_chaos_calmer; then
errorSummary="${errorSummary}${_ERROR_}: Failed to load kernel modules\\n"
fi
if [ -z "$reloadedIface" ]; then
for i in $usedChainsList; do
for i in $usedChainsList; do
ipt -t mangle -N "VPR_${i}"
ipt -t mangle -N "VPR_${i}"
ipt -t mangle "$insertOption" "$i" -m mark --mark "0x0/${fwMask}" -j "VPR_${i}"
ipt -t mangle "$insertOption" "$i" -m mark --mark "0x0/${fwMask}" -j "VPR_${i}"
done
done
fi
if [ -z "$reloadedIface" ]; then
output 1 'Processing Interfaces '
output 1 'Processing Interfaces '
config_load 'network'; config_foreach process_interface 'interface' 'create';
config_load 'network'; config_foreach process_interface 'interface' 'create';
process_tor_interface 'tor' 'destroy'; is_tor_running && process_tor_interface 'tor' 'create';
process_tor_interface 'tor' 'destroy'; is_tor_running && process_tor_interface 'tor' 'create';
ip route flush cache
output 1 '\n'
output 1 '\n'
if is_config_enabled 'policy'; then
if is_config_enabled 'policy'; then
output 1 'Processing Policies '
output 1 'Processing Policies '
config_load "$packageName"; config_foreach process_policy 'policy';
config_load "$packageName"; config_foreach process_policy 'policy' "$reloadedIface" ;
output 1 '\n'
output 1 '\n'
fi
fi
if is_config_enabled 'include'; then
if is_config_enabled 'include'; then
@ -931,38 +1012,37 @@ start_service() {
config_load "$packageName"; config_foreach process_user_file 'include';
config_load "$packageName"; config_foreach process_user_file 'include';
output 1 '\n'
output 1 '\n'
fi
fi
else
output 1 "Reloading Interface: $reloadedIface "
config_load 'network'; config_foreach process_interface 'interface' 'create' "$reloadedIface";
output 1 '\n'
fi
if [ -s "$dnsmasqFile" ]; then
dnsmasqNewHash="$(md5sum $dnsmasqFile | awk '{ print $1; }')"
fi
[ "$dnsmasqNewHash" != "$dnsmasqStoredHash" ] && dnsmasq_restart
if [ -s "$dnsmasqFile" ]; then
dnsmasqNewHash="$(md5sum $dnsmasqFile | awk '{ print $1; }')"
fi
[ "$dnsmasqNewHash" != "$dnsmasqStoredHash" ] && dnsmasq_restart
if [ -z "$gatewaySummary" ]; then
errorSummary="${errorSummary}${_ERROR_}: failed to set up any gateway!\\n"
fi
procd_open_instance "main"
procd_set_param command /bin/true
procd_set_param stdout 1
procd_set_param stderr 1
procd_open_data
json_add_array 'status'
json_add_object ''
[ -n "$gatewaySummary" ] && json_add_string gateway "$gatewaySummary"
[ -n "$errorSummary" ] && json_add_string error "$errorSummary"
[ -n "$warningSummary" ] && json_add_string warning "$warningSummary"
if [ "$strictMode" -ne 0 ] && str_contains "$gatewaySummary" '0.0.0.0'; then
json_add_string mode "strict"
fi
json_close_object
json_close_array
procd_close_data
procd_close_instance
remove_lock
else
output "$serviceName: another instance of ${packageName} is currently running "
output_failn
return 1
if [ -z "$gatewaySummary" ]; then
errorSummary="${errorSummary}${_ERROR_}: failed to set up any gateway!\\n"
fi
fi
procd_open_instance "main"
procd_set_param command /bin/true
procd_set_param stdout 1
procd_set_param stderr 1
procd_open_data
json_add_array 'status'
json_add_object ''
[ -n "$gatewaySummary" ] && json_add_string gateway "$gatewaySummary"
[ -n "$errorSummary" ] && json_add_string error "$errorSummary"
[ -n "$warningSummary" ] && json_add_string warning "$warningSummary"
if [ "$strictMode" -ne 0 ] && str_contains "$gatewaySummary" '0.0.0.0'; then
json_add_string mode "strict"
fi
json_close_object
json_close_array
procd_close_data
procd_close_instance
}
}
tmpfs() {
tmpfs() {
@ -1025,30 +1105,25 @@ service_started() {
stop_service() {
stop_service() {
local i
local i
iptables -t mangle -L | grep -q VPR_PREROUTING || return 0
iptables -t mangle -L | grep -q VPR_PREROUTING || return 0
if create_lock; then
load_package_config
for i in PREROUTING FORWARD INPUT OUTPUT; do
ipt -t mangle -D "${i}" -m mark --mark "0x0/${fwMask}" -j "VPR_${i}"
ipt -t mangle -F "VPR_${i}"; ipt -t mangle -X "VPR_${i}";
done
config_load 'network'; config_foreach process_interface 'interface' 'destroy';
process_tor_interface 'tor' 'destroy'
unset ifaceTableID; unset ifaceMark;
if [ -s "$dnsmasqFile" ]; then
rm -f "$dnsmasqFile"
dnsmasq_restart
fi
if [ "$serviceEnabled" -ne 0 ]; then
output "$serviceName stopped "; output_okn;
fi
remove_lock
else
output "$serviceName: another instance of ${packageName} is currently running "; output_failn;
return 1
load_package_config
for i in PREROUTING FORWARD INPUT OUTPUT; do
ipt -t mangle -D "${i}" -m mark --mark "0x0/${fwMask}" -j "VPR_${i}"
ipt -t mangle -F "VPR_${i}"; ipt -t mangle -X "VPR_${i}";
done
config_load 'network'; config_foreach process_interface 'interface' 'destroy';
process_tor_interface 'tor' 'destroy'
unset ifaceTableID; unset ifaceMark;
if [ -s "$dnsmasqFile" ]; then
rm -f "$dnsmasqFile"
dnsmasq_restart
fi
if [ "$serviceEnabled" -ne 0 ]; then
output "$serviceName stopped "; output_okn;
fi
fi
}
}
# shellcheck disable=SC2119
reload_interface() { rc_procd start_service "$1"; }
service_triggers() {
service_triggers() {
local n
local n
is_enabled || return 1
is_enabled || return 1
@ -1070,7 +1145,9 @@ service_triggers() {
procd_add_service_trigger "service.restart" "firewall" /etc/init.d/${packageName} reload
procd_add_service_trigger "service.restart" "firewall" /etc/init.d/${packageName} reload
fi
fi
procd_add_config_trigger "config.change" "${packageName}" /etc/init.d/${packageName} reload
procd_add_config_trigger "config.change" "${packageName}" /etc/init.d/${packageName} reload
for n in $ifSupported; do procd_add_reload_interface_trigger "$n"; procd_add_interface_trigger "interface.*" "$n" /etc/init.d/${packageName} reload; done;
for n in $ifSupported; do
procd_add_interface_trigger "interface.*" "$n" /etc/init.d/${packageName} reload_interface "$n"
done
procd_close_trigger
procd_close_trigger
output 3 "$serviceName monitoring interfaces: $ifSupported"; output_okn;
output 3 "$serviceName monitoring interfaces: $ifSupported"; output_okn;
@ -1085,10 +1162,12 @@ support() {
json_load "$(ubus call system board)"; json_select release; json_get_var dist distribution; json_get_var vers version
json_load "$(ubus call system board)"; json_select release; json_get_var dist distribution; json_get_var vers version
if [ -n "$wanIface4" ]; then
if [ -n "$wanIface4" ]; then
network_get_gateway wanGW4 "$wanIface4"
network_get_gateway wanGW4 "$wanIface4"
dev="$(uci -q get network."${wanIface4}".ifname)"
[ -z "$dev" ] && dev="$(uci -q get network."${wanIface4}".ifname)"
[ -z "$dev" ] && dev="$(uci -q get network."${wanIface4}".device)"
fi
fi
if [ -n "$wanIface6" ]; then
if [ -n "$wanIface6" ]; then
dev6="$(uci -q get network."${wanIface6}".ifname)"
[ -z "$dev6" ] && dev6="$(uci -q get network."${wanIface6}".ifname)"
[ -z "$dev6" ] && dev6="$(uci -q get network."${wanIface6}".device)"
wanGW6=$(ip -6 route show | grep -m1 " dev $dev6 " | awk '{print $1}')
wanGW6=$(ip -6 route show | grep -m1 " dev $dev6 " | awk '{print $1}')
[ "$wanGW6" = "default" ] && wanGW6=$(ip -6 route show | grep -m1 " dev $dev6 " | awk '{print $3}')
[ "$wanGW6" = "default" ] && wanGW6=$(ip -6 route show | grep -m1 " dev $dev6 " | awk '{print $3}')
fi
fi