mirror of
https://github.com/openwrt/packages.git
synced 2025-12-26 13:26:17 +04:00
pbr: update to 1.1.8-32
Makefile:
- add SPDX-Identifier-License
- update Copyright
README:
- add basic README with the link to full documentation
Config:
- add debug_dnsmasq
- add procd_boot_trigger_delay
Init Script:
- move extra_command calls high up for visibility
- bump packageCompat to sync with luci app
- implement support for debug_dnsmasq to dump dnsmasq debug into $packageDebugFile
- create $runningStatusFile json-file allowing more verbose errors/warnings messages
- replaced `state add` calls with json add calls to store errors/warnings messages
- remove no longer needed errorSummary, warningSummary
- ensure environment is only loaded once per run via $load_environment_flag
- bugfix: update is_{host,hostname,domain,ipv4,mac_address} functions to properly sort policy entries
- bugfix: change references to melmac.net to melmac.ca
- add some new error/warning messages
- add delay before service is started on boot via procd_boot_trigger_delay
- bugfix: add logic to identify unknown policy entries instead of silently failing on them
- store error/warning messages as json objects in ubus data for luci app
- update load_validate_config with debug_dnsmasq and procd_boot_trigger_delay entries
Signed-off-by: Stan Grishin <stangri@melmac.ca>
(cherry picked from commit 4b831c6dbf)
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
# Copyright 2017-2024 MOSSDeF, Stan Grishin (stangri@melmac.ca).
|
||||
# This is free software, licensed under AGPL-3.0-or-later.
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
# Copyright 2017-2025 MOSSDeF, Stan Grishin (stangri@melmac.ca).
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=pbr
|
||||
PKG_VERSION:=1.1.8
|
||||
PKG_RELEASE:=16
|
||||
PKG_RELEASE:=32
|
||||
PKG_LICENSE:=AGPL-3.0-or-later
|
||||
PKG_MAINTAINER:=Stan Grishin <stangri@melmac.ca>
|
||||
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
# README
|
||||
# Policy-Based Routing (pbr)
|
||||
|
||||
Documentation for this project is available at [https://docs.openwrt.melmac.net/pbr/](https://docs.openwrt.melmac.net/pbr/).
|
||||
[](https://openwrt.org)
|
||||
[](https://docs.openwrt.melmac.ca/pbr/)
|
||||
[](https://github.com/stangri/pbr/blob/master/LICENSE)
|
||||
|
||||
Flexible policy-based routing (PBR) framework for OpenWrt.
|
||||
Allows routing specific traffic (by IP, MAC, port, protocol, or domain) through a specific WAN, VPN, or tunnel.
|
||||
|
||||
## Features
|
||||
|
||||
- Route by IP, MAC, port, or domain name
|
||||
- Works with WAN, VPNs (WireGuard, OpenVPN), or tunnels
|
||||
- Lightweight shell-based implementation
|
||||
- Optional Web UI integration via LuCI
|
||||
|
||||
**Full documentation:**
|
||||
[https://docs.openwrt.melmac.ca/pbr/](https://docs.openwrt.melmac.ca/pbr/)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
config pbr 'config'
|
||||
option debug_dnsmasq '0'
|
||||
option enabled '0'
|
||||
option verbosity '2'
|
||||
option strict_enforcement '1'
|
||||
@@ -8,6 +9,7 @@ config pbr 'config'
|
||||
list ignored_interface 'vpnserver'
|
||||
option boot_timeout '30'
|
||||
option rule_create_option 'add'
|
||||
option procd_boot_trigger_delay '5000'
|
||||
option procd_reload_delay '1'
|
||||
option webui_show_ignore_target '0'
|
||||
option nft_rule_counter '0'
|
||||
|
||||
@@ -12,21 +12,44 @@ USE_PROCD=1
|
||||
|
||||
[ -n "${IPKG_INSTROOT}" ] && return 0
|
||||
|
||||
if type extra_command >/dev/null 2>&1; then
|
||||
extra_command 'status' "Generates output required to troubleshoot routing issues
|
||||
Use '-d' option for more detailed output
|
||||
Use '-p' option to automatically upload data under PBR paste.ee account
|
||||
WARNING: while paste.ee uploads are unlisted, they are still publicly available
|
||||
List domain names after options to include their lookup in report"
|
||||
extra_command 'version' 'Show version information'
|
||||
extra_command 'on_firewall_reload' ' Run service on firewall reload'
|
||||
extra_command 'on_interface_reload' ' Run service on indicated interface reload'
|
||||
else
|
||||
# shellcheck disable=SC2034
|
||||
EXTRA_COMMANDS='on_firewall_reload on_interface_reload status version'
|
||||
# shellcheck disable=SC2034
|
||||
EXTRA_HELP=" status Generates output required to troubleshoot routing issues
|
||||
Use '-d' option for more detailed output
|
||||
Use '-p' option to automatically upload data under PBR paste.ee account
|
||||
WARNING: while paste.ee uploads are unlisted, they are still publicly available
|
||||
List domain names after options to include their lookup in report"
|
||||
fi
|
||||
|
||||
readonly packageName='pbr'
|
||||
readonly PKG_VERSION='dev-test'
|
||||
readonly packageCompat='11'
|
||||
readonly packageCompat='14'
|
||||
readonly serviceName="$packageName $PKG_VERSION"
|
||||
readonly packageConfigFile="/etc/config/${packageName}"
|
||||
readonly packageDebugFile="/var/run/${packageName}.debug"
|
||||
readonly packageLockFile="/var/run/${packageName}.lock"
|
||||
readonly dnsmasqFileDefault="/var/run/${packageName}.dnsmasq"
|
||||
readonly runningStatusFile="/dev/shm/${packageName}.status.json"
|
||||
readonly runningStatusFileLock="/var/lock/${packageName}.lock"
|
||||
readonly _OK_='\033[0;32m\xe2\x9c\x93\033[0m'
|
||||
readonly __OK__='\033[0;32m[\xe2\x9c\x93]\033[0m'
|
||||
readonly _OKB_='\033[1;34m\xe2\x9c\x93\033[0m'
|
||||
readonly __OKB__='\033[1;34m[\xe2\x9c\x93]\033[0m'
|
||||
readonly _FAIL_='\033[0;31m\xe2\x9c\x97\033[0m'
|
||||
readonly __FAIL__='\033[0;31m[\xe2\x9c\x97]\033[0m'
|
||||
readonly _ERROR_='\033[0;31mERROR\033[0m'
|
||||
readonly _WARNING_='\033[0;33mWARNING\033[0m'
|
||||
readonly _ERROR_='\033[0;31mERROR:\033[0m'
|
||||
readonly _WARNING_='\033[0;33mWARNING:\033[0m'
|
||||
readonly ip_full='/usr/libexec/ip-full'
|
||||
# shellcheck disable=SC2155
|
||||
readonly ipTablePrefix="$packageName"
|
||||
@@ -47,6 +70,7 @@ readonly xrayIfacePrefix='xray_'
|
||||
readonly rtTablesFile='/etc/iproute2/rt_tables'
|
||||
|
||||
# package config options
|
||||
debug_dnsmasq=
|
||||
enabled=
|
||||
fw_mask=
|
||||
icmp_interface=
|
||||
@@ -54,6 +78,7 @@ ignored_interface=
|
||||
ipv6_enabled=
|
||||
nft_user_set_policy=
|
||||
nft_user_set_counter=
|
||||
procd_boot_trigger_delay=
|
||||
procd_reload_delay=
|
||||
procd_lan_device=
|
||||
procd_wan_interface=
|
||||
@@ -76,10 +101,9 @@ nft_set_policy=
|
||||
nft_set_timeout=
|
||||
|
||||
# run-time
|
||||
load_environment_flag=
|
||||
aghConfigFile='/etc/AdGuardHome/AdGuardHome.yaml'
|
||||
gatewaySummary=
|
||||
errorSummary=
|
||||
warningSummary=
|
||||
wanIface4=
|
||||
wanIface6=
|
||||
dnsmasqFileList=
|
||||
@@ -143,6 +167,8 @@ output_okb() { output 1 "$_OKB_"; output 2 "$__OKB__\n"; }
|
||||
output_okbn() { output 1 "$_OKB_\n"; output 2 "$__OKB__\n"; }
|
||||
output_fail() { output 1 "$_FAIL_"; output 2 "$__FAIL__\n"; }
|
||||
output_failn() { output 1 "$_FAIL_\n"; output 2 "$__FAIL__\n"; }
|
||||
output_error() { output "${_ERROR_} $*!\n"; }
|
||||
output_warning() { output "${_WARNING_} $*!\n"; }
|
||||
quiet_mode() {
|
||||
case "$1" in
|
||||
on) verbosity=0;;
|
||||
@@ -215,7 +241,9 @@ uci_get_device() {
|
||||
uci_get_protocol() { uci_get 'network' "$1" 'proto'; }
|
||||
is_default_dev() { [ "$1" = "$(ip -4 r | grep -m1 'dev' | grep -Eso 'dev [^ ]*' | awk '{print $2}')" ]; }
|
||||
is_disabled_interface() { [ "$(uci_get 'network' "$1" 'disabled')" = '1' ]; }
|
||||
is_domain(){ echo "$1" | grep -qE '^([a-zA-Z0-9][a-zA-Z0-9-]{0,61}\.)*[a-zA-Z]{2,}$'; }
|
||||
is_host() { echo "$1" | grep -qE '^[a-zA-Z0-9][a-zA-Z0-9_-]{0,61}[a-zA-Z0-9]$|^[a-zA-Z0-9]$'; }
|
||||
is_hostname() { echo "$1" | grep -qE '^([a-zA-Z0-9]([a-zA-Z0-9_-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$'; }
|
||||
is_domain() { ! is_ipv4 "$1" && ! is_mac_address_bad_notation "$1" && { is_host "$1" || is_hostname "$1"; }; }
|
||||
is_dslite() { local p; network_get_protocol p "$1"; [ "${p:0:6}" = "dslite" ]; }
|
||||
is_family_mismatch() { ( is_ipv4 "${1//!}" && is_ipv6 "${2//!}" ) || ( is_ipv6 "${1//!}" && is_ipv4 "${2//!}" ); }
|
||||
is_greater() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; }
|
||||
@@ -223,7 +251,7 @@ is_greater_or_equal() { test "$(printf '%s\n' "$@" | sort -V | head -n '1')" = "
|
||||
is_ignored_interface() { str_contains_word "$ignored_interface" "$1"; }
|
||||
is_ignore_target() { [ "$(str_to_lower "$1")" = 'ignore' ]; }
|
||||
is_integer() { case "$1" in ''|*[!0-9]*) return 1;; esac; }
|
||||
is_ipv4() { expr "${1%/*}" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; }
|
||||
is_ipv4() { echo "$1" | grep -qE '^((25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(/(3[0-2]|[12]?[0-9]))?$'; }
|
||||
is_ipv6() { ! is_mac_address "$1" && str_contains "$1" ':'; }
|
||||
is_ipv6_global_scope() { [ "${1:0:4}" = '2001' ]; }
|
||||
is_ipv6_local_scope() { is_ipv6_local_link "$1" || is_ipv6_local_unique "$1"; }
|
||||
@@ -232,7 +260,8 @@ is_ipv6_local_unique() { [ "${1:0:2}" = 'fc' ] || [ "${1:0:2}" = 'fd' ]; }
|
||||
is_list() { str_contains "$1" ',' || str_contains "$1" ' '; }
|
||||
is_lan() { local d; network_get_device d "$1"; str_contains "$procd_lan_device" "$d"; }
|
||||
is_l2tp() { local p; network_get_protocol p "$1"; [ "${p:0:4}" = "l2tp" ]; }
|
||||
is_mac_address() { expr "$1" : '[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]$' >/dev/null; }
|
||||
is_mac_address() { echo "$1" | grep -qE '^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$'; }
|
||||
is_mac_address_bad_notation() { echo "$1" | grep -qE '^([0-9A-Fa-f]{2}-){5}([0-9A-Fa-f]{2})$'; }
|
||||
is_negated() { [ "${1:0:1}" = '!' ]; }
|
||||
is_netifd_table() { grep -q "ip.table.*$1" /etc/config/network; }
|
||||
is_netifd_table_interface() { local iface="$1"; [ "$(uci_get 'network' "$iface" 'ip4table')" = "${packageName}_${iface%6}" ]; }
|
||||
@@ -311,47 +340,33 @@ check_dnsmasq_nftset() {
|
||||
check_nft || return 1
|
||||
check_dnsmasq || return 1
|
||||
o="$(dnsmasq -v 2>/dev/null)"
|
||||
[ -n "$debug_dnsmasq" ] && {
|
||||
echo " $(date) dnsmasq output dump:";
|
||||
# shellcheck disable=SC3003
|
||||
echo "${o%$'\n'$'\n'This*}";
|
||||
echo '-------------------------';
|
||||
} >> "$packageDebugFile"
|
||||
! echo "$o" | grep -q 'no-nftset' && echo "$o" | grep -q 'nftset'
|
||||
}
|
||||
print_json_bool() { json_init; json_add_boolean "$1" "$2"; json_dump; json_cleanup; }
|
||||
print_json_string() { json_init; json_add_string "$1" "$2"; json_dump; json_cleanup; }
|
||||
try() {
|
||||
if ! "$@" >/dev/null 2>&1; then
|
||||
state add 'errorSummary' 'errorTryFailed' "$*"
|
||||
json add error 'errorTryFailed' "$*"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
if type extra_command >/dev/null 2>&1; then
|
||||
extra_command 'status' "Generates output required to troubleshoot routing issues
|
||||
Use '-d' option for more detailed output
|
||||
Use '-p' option to automatically upload data under VPR paste.ee account
|
||||
WARNING: while paste.ee uploads are unlisted, they are still publicly available
|
||||
List domain names after options to include their lookup in report"
|
||||
extra_command 'version' 'Show version information'
|
||||
extra_command 'on_firewall_reload' ' Run service on firewall reload'
|
||||
extra_command 'on_interface_reload' ' Run service on indicated interface reload'
|
||||
else
|
||||
# shellcheck disable=SC2034
|
||||
EXTRA_COMMANDS='on_firewall_reload on_interface_reload status version'
|
||||
# shellcheck disable=SC2034
|
||||
EXTRA_HELP=" status Generates output required to troubleshoot routing issues
|
||||
Use '-d' option for more detailed output
|
||||
Use '-p' option to automatically upload data under VPR paste.ee account
|
||||
WARNING: while paste.ee uploads are unlisted, they are still publicly available
|
||||
List domain names after options to include their lookup in report"
|
||||
fi
|
||||
|
||||
get_text() {
|
||||
local r
|
||||
case "$1" in
|
||||
errorConfigValidation) r="Config ($packageConfigFile) validation failure!";;
|
||||
errorNoNft) r="Resolver set support (${resolver_set}) requires nftables, but nft binary cannot be found!";;
|
||||
errorResolverNotSupported) r="Resolver set (${resolver_set}) is not supported on this system!";;
|
||||
errorServiceDisabled) r="The ${packageName} service is currently disabled!";;
|
||||
errorServiceDisabled) r="The ${packageName} service is currently disabled";;
|
||||
errorNoWanGateway) r="The ${serviceName} service failed to discover WAN gateway!";;
|
||||
errorNoWanInterface) r="The %s interface not found, you need to set the 'pbr.config.procd_wan_interface' option!";;
|
||||
errorNoWanInterfaceHint) r="Refer to https://docs.openwrt.melmac.net/pbr/#procd_wan_interface.";;
|
||||
errorNoWanInterfaceHint) r="Refer to https://docs.openwrt.melmac.ca/pbr/#procd_wan_interface.";;
|
||||
errorNftsetNameTooLong) r="The nft set name '%s' is longer than allowed 255 characters!";;
|
||||
errorUnexpectedExit) r="Unexpected exit or service termination: '%s'!";;
|
||||
errorPolicyNoSrcDest) r="Policy '%s' has no source/destination parameters!";;
|
||||
@@ -374,6 +389,7 @@ get_text() {
|
||||
errorPolicyProcessUnknownProtocol) r="Unknown protocol in policy '%s'!";;
|
||||
errorPolicyProcessInsertionFailed) r="Insertion failed for both IPv4 and IPv6 for policy '%s'!";;
|
||||
errorPolicyProcessInsertionFailedIpv4) r="Insertion failed for IPv4 for policy '%s'!";;
|
||||
errorPolicyProcessUnknownEntry) r="Unknown entry in policy '%s'!";;
|
||||
errorInterfaceRoutingEmptyValues) r="Received empty tid/mark or interface name when setting up routing!";;
|
||||
errorFailedToResolve) r="Failed to resolve '%s'!";;
|
||||
errorTryFailed) r="Command failed: %s";;
|
||||
@@ -387,6 +403,7 @@ get_text() {
|
||||
errorDefaultFw4ChainMissing) r="Default fw4 chain '%s' is missing!";;
|
||||
errorRequiredBinaryMissing) r="Required binary '%s' is missing!";;
|
||||
errorInterfaceRoutingUnknownDevType) r="Unknown IPv6 Link type for device '%s'!";;
|
||||
errorUplinkDown) r="Uplink/WAN interface is still down, increase value of 'procd_boot_trigger_delay' option";;
|
||||
warningInvalidOVPNConfig) r="Invalid OpenVPN config for '%s' interface.";;
|
||||
warningResolverNotSupported) r="Resolver set (${resolver_set}) is not supported on this system.";;
|
||||
warningPolicyProcessCMD) r="'%s'";;
|
||||
@@ -397,6 +414,7 @@ get_text() {
|
||||
warningBadNftCallsInUserFile) r="Incompatible nft calls detected in user include file, disabling fw4 nft file support.";;
|
||||
warningDnsmasqInstanceNoConfdir) r="Dnsmasq instance '%s' targeted in settings, but it doesn't have its own confdir.";;
|
||||
warningDhcpLanForce) r="Please set 'dhcp.%s.force=1' to speed up service start-up.";;
|
||||
*) r="Unknown error '%s'!";;
|
||||
esac
|
||||
echo "$r"
|
||||
}
|
||||
@@ -428,13 +446,13 @@ process_url() {
|
||||
dl_temp_file="$(mktemp -u -q -t "${packageName}_tmp.XXXXXXXX")"
|
||||
done
|
||||
if is_url_file "$url" && ! is_present 'curl'; then
|
||||
state add 'errorSummary' 'errorFileSchemaRequiresCurl' "$url"
|
||||
json add error 'errorFileSchemaRequiresCurl' "$url"
|
||||
elif is_url_https "$url" && [ -z "$dl_https_supported" ]; then
|
||||
state add 'errorSummary' 'errorDownloadUrlNoHttps' "$url"
|
||||
json add error 'errorDownloadUrlNoHttps' "$url"
|
||||
elif $dl_command "$url" "$dl_flag" "$dl_temp_file" 2>/dev/null; then
|
||||
sed 'N;s/\n/ /;s/\s\+/ /g;' "$dl_temp_file"
|
||||
else
|
||||
state add 'errorSummary' 'errorDownloadUrl' "$url"
|
||||
json add error 'errorDownloadUrl' "$url"
|
||||
fi
|
||||
rm -f "$dl_temp_file"
|
||||
}
|
||||
@@ -443,6 +461,7 @@ load_package_config() {
|
||||
local param="$1"
|
||||
local user_file_check_result i
|
||||
config_load "$packageName"
|
||||
config_get_bool debug_dnsmasq 'config' 'debug_dnsmasq' '0'
|
||||
config_get_bool enabled 'config' 'enabled' '0'
|
||||
config_get fw_mask 'config' 'fw_mask' 'ff0000'
|
||||
config_get icmp_interface 'config' 'icmp_interface'
|
||||
@@ -461,12 +480,14 @@ load_package_config() {
|
||||
config_get_bool strict_enforcement 'config' 'strict_enforcement' '1'
|
||||
config_get supported_interface 'config' 'supported_interface'
|
||||
config_get verbosity 'config' 'verbosity' '2'
|
||||
config_get procd_reload_delay 'config' 'procd_reload_delay' '0'
|
||||
config_get procd_boot_trigger_delay 'config' 'procd_boot_trigger_delay' '5000'
|
||||
config_get procd_lan_device 'config' 'procd_lan_device' 'br-lan'
|
||||
config_get procd_reload_delay 'config' 'procd_reload_delay' '0'
|
||||
config_get procd_wan_interface 'config' 'procd_wan_interface' 'wan'
|
||||
config_get procd_wan6_interface 'config' 'procd_wan6_interface' 'wan6'
|
||||
config_get wan_ip_rules_priority 'config' 'wan_ip_rules_priority' '30000'
|
||||
config_get wan_mark 'config' 'wan_mark' '010000'
|
||||
|
||||
fw_mask="0x${fw_mask}"
|
||||
wan_mark="0x${wan_mark}"
|
||||
if [ -x "$agh" ] && [ ! -s "$aghConfigFile" ]; then
|
||||
@@ -477,6 +498,10 @@ load_package_config() {
|
||||
fw_maskXor="$(printf '%#x' "$((fw_mask ^ 0xffffffff))")"
|
||||
fw_maskXor="${fw_maskXor:-0xff00ffff}"
|
||||
|
||||
is_integer "$procd_boot_trigger_delay" || procd_boot_trigger_delay='5000'
|
||||
[ "$procd_boot_trigger_delay" -lt '1000' ] && procd_boot_trigger_delay='1000'
|
||||
|
||||
[ "$debug_dnsmasq" != '1' ] && unset debug_dnsmasq
|
||||
[ "$nft_rule_counter" != '1' ] && unset nft_rule_counter
|
||||
[ "$nft_set_auto_merge" != '1' ] && unset nft_set_auto_merge
|
||||
[ "$nft_set_counter" != '1' ] && unset nft_set_counter
|
||||
@@ -513,7 +538,7 @@ load_environment() {
|
||||
_check_dhcp_force() {
|
||||
is_lan "$1" || return 0
|
||||
if [ "$(uci_get dhcp "$1" force 0)" = '0' ]; then
|
||||
state add 'warningSummary' 'warningDhcpLanForce' "$1"
|
||||
json add warning 'warningDhcpLanForce' "$1"
|
||||
fi
|
||||
}
|
||||
local i _ret=0
|
||||
@@ -522,22 +547,22 @@ load_environment() {
|
||||
uci_commit firewall
|
||||
fi
|
||||
if [ "$(readlink /sbin/ip)" != "$ip_full" ]; then
|
||||
state add 'errorSummary' 'errorRequiredBinaryMissing' 'ip-full'
|
||||
json add error 'errorRequiredBinaryMissing' 'ip-full'
|
||||
_ret='1'
|
||||
fi
|
||||
if ! nft_call list table inet fw4; then
|
||||
state add 'errorSummary' 'errorDefaultFw4TableMissing' 'fw4'
|
||||
json add error 'errorDefaultFw4TableMissing' 'fw4'
|
||||
_ret='1'
|
||||
fi
|
||||
if is_config_enabled 'dns_policy' || is_tor_running; then
|
||||
if ! nft_call list chain inet fw4 dstnat; then
|
||||
state add 'errorSummary' 'errorDefaultFw4ChainMissing' 'dstnat'
|
||||
json add error 'errorDefaultFw4ChainMissing' 'dstnat'
|
||||
_ret='1'
|
||||
fi
|
||||
fi
|
||||
for i in $chainsList; do
|
||||
if ! nft_call list chain inet fw4 "mangle_${i}"; then
|
||||
state add 'errorSummary' 'errorDefaultFw4ChainMissing' "mangle_${i}"
|
||||
json add error 'errorDefaultFw4ChainMissing' "mangle_${i}"
|
||||
_ret='1'
|
||||
fi
|
||||
done
|
||||
@@ -546,20 +571,25 @@ load_environment() {
|
||||
return "$_ret"
|
||||
}
|
||||
local param="$1" validation_result="$2"
|
||||
[ -z "$load_environment_flag" ] || return 0
|
||||
json init
|
||||
case "$param" in
|
||||
on_boot|on_start)
|
||||
output 1 "Loading environment ($param) "
|
||||
load_package_config "$param"
|
||||
if [ "$enabled" -eq '0' ]; then
|
||||
output 1 "$_FAIL_\n"
|
||||
state add 'errorSummary' 'errorServiceDisabled'
|
||||
json add error 'errorServiceDisabled'
|
||||
output_error "$(get_text 'errorServiceDisabled')"
|
||||
output "Run the following commands before starting service again:\n"
|
||||
output "uci set ${packageName}.config.enabled='1'; uci commit $packageName;\n"
|
||||
return 1
|
||||
fi
|
||||
if [ -n "$validation_result" ] && [ "$validation_result" != '0' ]; then
|
||||
output 1 "$_FAIL_\n"
|
||||
output "${_ERROR_}: The $packageName config validation failed!\n"
|
||||
json add error 'errorConfigValidation'
|
||||
output_error "$(get_text 'errorConfigValidation')"
|
||||
output "Please check if the '$packageConfigFile' contains correct values for config options.\n"
|
||||
state add 'errorSummary' 'errorConfigValidation'
|
||||
return 1
|
||||
fi
|
||||
_system_health_check || { output 1 "$_FAIL_\n"; return 1; }
|
||||
@@ -578,6 +608,7 @@ load_environment() {
|
||||
load_network "$param"
|
||||
;;
|
||||
esac
|
||||
load_environment_flag=1
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2317
|
||||
@@ -620,8 +651,8 @@ load_network() {
|
||||
is_wan_up() {
|
||||
local sleepCount='1' param="$1"
|
||||
if [ -z "$(uci_get network "$procd_wan_interface")" ]; then
|
||||
state add 'errorSummary' 'errorNoWanInterface' "$procd_wan_interface"
|
||||
state add 'errorSummary' 'errorNoWanInterfaceHint'
|
||||
json add error 'errorNoWanInterface' "$procd_wan_interface"
|
||||
json add error 'errorNoWanInterfaceHint'
|
||||
return 1
|
||||
fi
|
||||
network_flush_cache
|
||||
@@ -629,7 +660,7 @@ is_wan_up() {
|
||||
if [ -n "$wanGW" ]; then
|
||||
return 0
|
||||
else
|
||||
state add 'errorSummary' 'errorNoWanGateway'
|
||||
json add error 'errorNoWanGateway'
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -666,7 +697,7 @@ nft_file() {
|
||||
cp -f "$nftTempFile" "$nftPermFile"; then
|
||||
output_okn
|
||||
else
|
||||
state add 'errorSummary' 'errorNftFileInstall' "$nftTempFile"
|
||||
json add error 'errorNftFileInstall' "$nftTempFile"
|
||||
output_failn
|
||||
fi
|
||||
;;
|
||||
@@ -685,7 +716,7 @@ nftset() {
|
||||
[ -x "$nft" ] || return 1
|
||||
|
||||
if [ "${#nftset4}" -gt '255' ]; then
|
||||
state add 'errorSummary' 'errorNftsetNameTooLong' "$nftset4"
|
||||
json add error 'errorNftsetNameTooLong' "$nftset4"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -706,7 +737,7 @@ nftset() {
|
||||
[ -z "$param4" ] && param4="$(resolveip_to_nftset4 "$param")"
|
||||
[ -z "$param6" ] && param6="$(resolveip_to_nftset6 "$param")"
|
||||
if [ -z "$param4" ] && [ -z "$param6" ]; then
|
||||
state add 'errorSummary' 'errorFailedToResolve' "$param"
|
||||
json add error 'errorFailedToResolve' "$param"
|
||||
else
|
||||
[ -n "$param4" ] && nft4 add element inet "$nftTable" "$nftset4" "{ $param4 }" && ipv4_error=0
|
||||
[ -n "$param6" ] && nft6 add element inet "$nftTable" "$nftset6" "{ $param6 }" && ipv6_error=0
|
||||
@@ -831,73 +862,49 @@ cleanup_sets() {
|
||||
done
|
||||
}
|
||||
|
||||
state() {
|
||||
local action="$1" param="$2" value="${3//#/_}"
|
||||
local array_name
|
||||
shift 3
|
||||
# shellcheck disable=SC2124
|
||||
local extras="$@"
|
||||
local line error_id error_extra label
|
||||
json() {
|
||||
local status message stats i
|
||||
local action="$1" param="$2" value="$3"; shift 3; local info="$*";
|
||||
[ "$param" = 'error' ] && param='errors'
|
||||
[ "$param" = 'warning' ] && param='warnings'
|
||||
{ json_load_file "$runningStatusFile" || json_init; } >/dev/null 2>&1
|
||||
case "$action" in
|
||||
add)
|
||||
line="$(eval echo "\$$param")"
|
||||
eval "$param"='${line:+$line#}${value}${extras:+ $extras}'
|
||||
;;
|
||||
json)
|
||||
json_init
|
||||
json_add_object "$packageName"
|
||||
case "$param" in
|
||||
errorSummary)
|
||||
array_name='errors';;
|
||||
warningSummary)
|
||||
array_name='warnings';;
|
||||
esac
|
||||
json_add_array "$array_name"
|
||||
if [ -n "$(eval echo "\$$param")" ]; then
|
||||
while read -r line; do
|
||||
if str_contains "$line" ' '; then
|
||||
error_id="${line% *}"
|
||||
error_extra="${line#* }"
|
||||
else
|
||||
error_id="$line"
|
||||
'get')
|
||||
if json_select "$param" >/dev/null 2>&1; then
|
||||
if [ -n "$value" ]; then
|
||||
{
|
||||
if json_select "$value"; then
|
||||
json_get_var 'i' "${info:-code}"
|
||||
json_select ..
|
||||
fi
|
||||
json_add_object "$array_name"
|
||||
json_add_string 'id' "$error_id"
|
||||
json_add_string 'extra' "$error_extra"
|
||||
json_close_object
|
||||
done <<EOF
|
||||
$(eval echo "\$$param" | tr \# \\n)
|
||||
EOF
|
||||
} >/dev/null 2>&1
|
||||
else
|
||||
json_get_keys i
|
||||
fi
|
||||
printf "%b" "$i"
|
||||
json_select ..
|
||||
fi
|
||||
json_close_array
|
||||
return
|
||||
;;
|
||||
'add')
|
||||
{ json_select "$param" || json_add_array "$param"; } >/dev/null 2>&1
|
||||
json_add_object ""
|
||||
json_add_string 'code' "$value"
|
||||
json_add_string 'info' "$info"
|
||||
json_close_object
|
||||
json_dump
|
||||
json_select ..
|
||||
;;
|
||||
print)
|
||||
[ -z "$(eval echo "\$$param")" ] && return 0
|
||||
case "$param" in
|
||||
errorSummary)
|
||||
label="${_ERROR_}:";;
|
||||
warningSummary)
|
||||
label="${_WARNING_}:";;
|
||||
esac
|
||||
while read -r line; do
|
||||
if str_contains "$line" ' '; then
|
||||
error_id="${line% *}"
|
||||
error_extra="${line#* }"
|
||||
printf "%b $(get_text "$error_id")\n" "$label" "$error_extra"
|
||||
else
|
||||
error_id="$line"
|
||||
printf "%b $(get_text "$error_id")\n" "$label"
|
||||
fi
|
||||
done <<EOF
|
||||
$(eval echo "\$$param" | tr \# \\n)
|
||||
EOF
|
||||
;;
|
||||
set)
|
||||
eval "$param"='${value}${extras:+ $extras}'
|
||||
'init')
|
||||
json_init
|
||||
json_add_array 'errors'
|
||||
json_close_array
|
||||
json_add_array 'warnings'
|
||||
json_close_array
|
||||
;;
|
||||
esac
|
||||
mkdir -p "${runningStatusFile%/*}"
|
||||
json_dump > "$runningStatusFile"
|
||||
sync
|
||||
}
|
||||
|
||||
resolver() {
|
||||
@@ -952,7 +959,6 @@ resolver() {
|
||||
for d in $value; do
|
||||
nftset 'add_dnsmasq_element' "$iface" "$target" "$type" "$uid" "$name" "$d"
|
||||
done
|
||||
# nftset 'add_dnsmasq_element' "$iface" "$target" "$type" "$uid" "$name" "$(str_to_dnsmsaq_nftset "$value")"
|
||||
;;
|
||||
create_resolver_set)
|
||||
[ -n "$resolver_set_supported" ] || return 1
|
||||
@@ -960,14 +966,14 @@ resolver() {
|
||||
;;
|
||||
check_support)
|
||||
if [ ! -x "$nft" ]; then
|
||||
state add 'errorSummary' 'errorNoNft'
|
||||
json add error 'errorNoNft'
|
||||
return 1
|
||||
fi
|
||||
if ! dnsmasq -v 2>/dev/null | grep -q 'no-nftset' && dnsmasq -v 2>/dev/null | grep -q 'nftset'; then
|
||||
if check_dnsmasq_nftset; then
|
||||
resolver_set_supported='true'
|
||||
return 0
|
||||
else
|
||||
state add 'warningSummary' 'warningResolverNotSupported'
|
||||
json add warning 'warningResolverNotSupported'
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
@@ -1074,20 +1080,20 @@ dns_policy_routing() {
|
||||
|
||||
if [ -z "${dest_dns_ipv4}${dest_dns_ipv6}" ]; then
|
||||
processPolicyError='true'
|
||||
state add 'errorSummary' 'errorPolicyProcessNoInterfaceDns' "'$dest_dns'"
|
||||
json add error 'errorPolicyProcessNoInterfaceDns' "'$dest_dns'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "$ipv6_enabled" ] && is_ipv6 "$(str_first_word "$src_addr")"; then
|
||||
processPolicyError='true'
|
||||
state add 'errorSummary' 'errorPolicyProcessNoIpv6' "$name"
|
||||
json add error 'errorPolicyProcessNoIpv6' "$name"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if { is_ipv4 "$(str_first_word "$src_addr")" && [ -z "$dest_dns_ipv4" ]; } || \
|
||||
{ is_ipv6 "$(str_first_word "$src_addr")" && [ -z "$dest_dns_ipv6" ]; }; then
|
||||
processPolicyError='true'
|
||||
state add 'errorSummary' 'errorPolicyProcessMismatchFamily' "${name}: '$src_addr' '$dest_dns'"
|
||||
json add error 'errorPolicyProcessMismatchFamily' "${name}: '$src_addr' '$dest_dns'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -1119,7 +1125,7 @@ dns_policy_routing() {
|
||||
resolved_ipv4="$(resolveip_to_nftset4 "$d")"
|
||||
resolved_ipv6="$(resolveip_to_nftset6 "$d")"
|
||||
if [ -z "${resolved_ipv4}${resolved_ipv6}" ]; then
|
||||
state add 'errorSummary' 'errorFailedToResolve' "$d"
|
||||
json add error 'errorFailedToResolve' "$d"
|
||||
else
|
||||
[ -n "$resolved_ipv4" ] && inline_set_ipv4="${inline_set_ipv4:+$inline_set_ipv4, }$resolved_ipv4"
|
||||
[ -n "$resolved_ipv6" ] && inline_set_ipv6="${inline_set_ipv6:+$inline_set_ipv6, }$resolved_ipv6"
|
||||
@@ -1154,15 +1160,15 @@ dns_policy_routing() {
|
||||
|
||||
if [ -n "$ipv6_enabled" ] && [ "$ipv4_error" -eq '1' ] && [ "$ipv6_error" -eq '1' ]; then
|
||||
processPolicyError='true'
|
||||
state add 'errorSummary' 'errorPolicyProcessInsertionFailed' "$name"
|
||||
state add 'errorSummary' 'errorPolicyProcessCMD' "nft $param4"
|
||||
state add 'errorSummary' 'errorPolicyProcessCMD' "nft $param6"
|
||||
json add error 'errorPolicyProcessInsertionFailed' "$name"
|
||||
json add error 'errorPolicyProcessCMD' "nft $param4"
|
||||
json add error 'errorPolicyProcessCMD' "nft $param6"
|
||||
logger -t "$packageName" "ERROR: nft $param4"
|
||||
logger -t "$packageName" "ERROR: nft $param6"
|
||||
elif [ -z "$ipv6_enabled" ] && [ "$ipv4_error" -eq '1' ]; then
|
||||
processPolicyError='true'
|
||||
state add 'errorSummary' 'errorPolicyProcessInsertionFailedIpv4' "$name"
|
||||
state add 'errorSummary' 'errorPolicyProcessCMD' "nft $param4"
|
||||
json add error 'errorPolicyProcessInsertionFailedIpv4' "$name"
|
||||
json add error 'errorPolicyProcessCMD' "nft $param4"
|
||||
logger -t "$packageName" "ERROR: nft $param4"
|
||||
fi
|
||||
done
|
||||
@@ -1183,7 +1189,7 @@ policy_routing() {
|
||||
if [ -z "$ipv6_enabled" ] && \
|
||||
{ is_ipv6 "$(str_first_word "$src_addr")" || is_ipv6 "$(str_first_word "$dest_addr")"; }; then
|
||||
processPolicyError='true'
|
||||
state add 'errorSummary' 'errorPolicyProcessNoIpv6' "$name"
|
||||
json add error 'errorPolicyProcessNoIpv6' "$name"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -1203,14 +1209,14 @@ policy_routing() {
|
||||
dest6="return"
|
||||
else
|
||||
processPolicyError='true'
|
||||
state add 'errorSummary' 'errorPolicyProcessUnknownFwmark' "$iface"
|
||||
json add error 'errorPolicyProcessUnknownFwmark' "$iface"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# TODO: implement actual family mismatch check on lists
|
||||
# if is_family_mismatch "$src_addr" "$dest_addr"; then
|
||||
# processPolicyError='true'
|
||||
# state add 'errorSummary' 'errorPolicyProcessMismatchFamily' "${name}: '$src_addr' '$dest_addr'"
|
||||
# json add error 'errorPolicyProcessMismatchFamily' "${name}: '$src_addr' '$dest_addr'"
|
||||
# return 1
|
||||
# fi
|
||||
|
||||
@@ -1229,7 +1235,7 @@ policy_routing() {
|
||||
unset proto_i
|
||||
elif ! is_supported_protocol "$proto_i"; then
|
||||
processPolicyError='true'
|
||||
state add 'errorSummary' 'errorPolicyProcessUnknownProtocol' "${name}: '$proto_i'"
|
||||
json add error 'errorPolicyProcessUnknownProtocol' "${name}: '$proto_i'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -1255,7 +1261,7 @@ policy_routing() {
|
||||
resolved_ipv4="$(resolveip_to_nftset4 "$d")"
|
||||
resolved_ipv6="$(resolveip_to_nftset6 "$d")"
|
||||
if [ -z "${resolved_ipv4}${resolved_ipv6}" ]; then
|
||||
state add 'errorSummary' 'errorFailedToResolve' "$d"
|
||||
json add error 'errorFailedToResolve' "$d"
|
||||
else
|
||||
[ -n "$resolved_ipv4" ] && inline_set_ipv4="${inline_set_ipv4:+$inline_set_ipv4, }$resolved_ipv4"
|
||||
[ -n "$resolved_ipv6" ] && inline_set_ipv6="${inline_set_ipv6:+$inline_set_ipv6, }$resolved_ipv6"
|
||||
@@ -1296,7 +1302,7 @@ policy_routing() {
|
||||
resolved_ipv4="$(resolveip_to_nftset4 "$d")"
|
||||
resolved_ipv6="$(resolveip_to_nftset6 "$d")"
|
||||
if [ -z "${resolved_ipv4}${resolved_ipv6}" ]; then
|
||||
state add 'errorSummary' 'errorFailedToResolve' "$d"
|
||||
json add error 'errorFailedToResolve' "$d"
|
||||
else
|
||||
[ -n "$resolved_ipv4" ] && inline_set_ipv4="${inline_set_ipv4:+$inline_set_ipv4, }$resolved_ipv4"
|
||||
[ -n "$resolved_ipv6" ] && inline_set_ipv6="${inline_set_ipv6:+$inline_set_ipv6, }$resolved_ipv6"
|
||||
@@ -1352,15 +1358,15 @@ policy_routing() {
|
||||
nft6 "$param6" "$dest6" || ipv6_error='1'
|
||||
if [ -n "$ipv6_enabled" ] && [ "$ipv4_error" -eq '1' ] && [ "$ipv6_error" -eq '1' ]; then
|
||||
processPolicyError='true'
|
||||
state add 'errorSummary' 'errorPolicyProcessInsertionFailed' "$name"
|
||||
state add 'errorSummary' 'errorPolicyProcessCMD' "nft $param4 $dest4"
|
||||
state add 'errorSummary' 'errorPolicyProcessCMD' "nft $param6 $dest6"
|
||||
json add error 'errorPolicyProcessInsertionFailed' "$name"
|
||||
json add error 'errorPolicyProcessCMD' "nft $param4 $dest4"
|
||||
json add error 'errorPolicyProcessCMD' "nft $param6 $dest6"
|
||||
logger -t "$packageName" "ERROR: nft $param4 $dest4"
|
||||
logger -t "$packageName" "ERROR: nft $param6 $dest6"
|
||||
elif [ -z "$ipv6_enabled" ] && [ "$ipv4_error" -eq '1' ]; then
|
||||
processPolicyError='true'
|
||||
state add 'errorSummary' 'errorPolicyProcessInsertionFailedIpv4' "$name"
|
||||
state add 'errorSummary' 'errorPolicyProcessCMD' "nft $param4 $dest4"
|
||||
json add error 'errorPolicyProcessInsertionFailedIpv4' "$name"
|
||||
json add error 'errorPolicyProcessCMD' "nft $param4 $dest4"
|
||||
logger -t "$packageName" "ERROR: nft $param4 $dest4"
|
||||
fi
|
||||
done
|
||||
@@ -1384,15 +1390,15 @@ policy_routing() {
|
||||
fi
|
||||
if [ -n "$ipv6_enabled" ] && [ "$ipv4_error" -eq '1' ] && [ "$ipv6_error" -eq '1' ]; then
|
||||
processPolicyError='true'
|
||||
state add 'errorSummary' 'errorPolicyProcessInsertionFailed' "$name"
|
||||
state add 'errorSummary' 'errorPolicyProcessCMD' "nft $param4"
|
||||
state add 'errorSummary' 'errorPolicyProcessCMD' "nft $param6"
|
||||
json add error 'errorPolicyProcessInsertionFailed' "$name"
|
||||
json add error 'errorPolicyProcessCMD' "nft $param4"
|
||||
json add error 'errorPolicyProcessCMD' "nft $param6"
|
||||
logger -t "$packageName" "ERROR: nft $param4"
|
||||
logger -t "$packageName" "ERROR: nft $param6"
|
||||
elif [ -z "$ipv6_enabled" ] && [ "$ipv4_error" -eq '1' ]; then
|
||||
processPolicyError='true'
|
||||
state add 'errorSummary' 'errorPolicyProcessInsertionFailedIpv4' "$name"
|
||||
state add 'errorSummary' 'errorPolicyProcessCMD' "nft $param4"
|
||||
json add error 'errorPolicyProcessInsertionFailedIpv4' "$name"
|
||||
json add error 'errorPolicyProcessCMD' "nft $param4"
|
||||
logger -t "$packageName" "ERROR: nft $param4"
|
||||
fi
|
||||
fi
|
||||
@@ -1427,11 +1433,11 @@ dns_policy_process() {
|
||||
unset processDnsPolicyError
|
||||
output 2 "Routing '$name' DNS to $dest_dns "
|
||||
if [ -z "$src_addr" ]; then
|
||||
state add 'errorSummary' 'errorPolicyNoSrcDest' "$name"
|
||||
json add error 'errorPolicyNoSrcDest' "$name"
|
||||
output_fail; return 1;
|
||||
fi
|
||||
if [ -z "$dest_dns" ]; then
|
||||
state add 'errorSummary' 'errorPolicyNoDns' "$name"
|
||||
json add error 'errorPolicyNoDns' "$name"
|
||||
output_fail; return 1;
|
||||
fi
|
||||
|
||||
@@ -1474,15 +1480,15 @@ policy_process() {
|
||||
[ "$proto" = 'all' ] && unset proto
|
||||
output 2 "Routing '$name' via $interface "
|
||||
if [ -z "${src_addr}${src_port}${dest_addr}${dest_port}" ]; then
|
||||
state add 'errorSummary' 'errorPolicyNoSrcDest' "$name"
|
||||
json add error 'errorPolicyNoSrcDest' "$name"
|
||||
output_fail; return 1;
|
||||
fi
|
||||
if [ -z "$interface" ]; then
|
||||
state add 'errorSummary' 'errorPolicyNoInterface' "$name"
|
||||
json add error 'errorPolicyNoInterface' "$name"
|
||||
output_fail; return 1;
|
||||
fi
|
||||
if ! is_supported_interface "$interface"; then
|
||||
state add 'errorSummary' 'errorPolicyUnknownInterface' "$name"
|
||||
json add error 'errorPolicyUnknownInterface' "$name"
|
||||
output_fail; return 1;
|
||||
fi
|
||||
|
||||
@@ -1509,6 +1515,7 @@ policy_process() {
|
||||
local filter_list_src_addr='phys_dev phys_dev_negative mac_address mac_address_negative domain domain_negative ipv4 ipv4_negative ipv6 ipv6_negative'
|
||||
local filter_list_dest_addr='domain domain_negative ipv4 ipv4_negative ipv6 ipv6_negative'
|
||||
local filter_group_src_addr filtered_value_src_addr filter_group_dest_addr filtered_value_dest_addr
|
||||
local processed_value_src_addr processed_value_dest_addr
|
||||
[ -z "$src_addr" ] && filter_list_src_addr='none'
|
||||
for filter_group_src_addr in $filter_list_src_addr; do
|
||||
filtered_value_src_addr="$(filter_options "$filter_group_src_addr" "$src_addr")"
|
||||
@@ -1524,11 +1531,27 @@ policy_process() {
|
||||
continue
|
||||
fi
|
||||
policy_routing "$name" "$interface" "$filtered_value_src_addr" "$src_port" "$filtered_value_dest_addr" "$dest_port" "$proto" "$chain" "$uid"
|
||||
processed_value_src_addr="${processed_value_src_addr:+$processed_value_src_addr }$filtered_value_src_addr"
|
||||
processed_value_dest_addr="${processed_value_dest_addr:+$processed_value_dest_addr }$filtered_value_dest_addr"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
for i in $src_addr; do
|
||||
if ! str_contains "$processed_value_src_addr" "$i"; then
|
||||
processPolicyError='true'
|
||||
json add error 'errorPolicyProcessUnknownEntry' "$name: $i"
|
||||
fi
|
||||
done
|
||||
|
||||
for i in $dest_addr; do
|
||||
if ! str_contains "$processed_value_dest_addr" "$i"; then
|
||||
processPolicyError='true'
|
||||
json add error 'errorPolicyProcessUnknownEntry' "$name: $i"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$processPolicyError" ]; then
|
||||
output_fail
|
||||
else
|
||||
@@ -1540,7 +1563,7 @@ interface_routing() {
|
||||
local action="$1" tid="$2" mark="$3" iface="$4" gw4="$5" dev="$6" gw6="$7" dev6="$8" priority="$9"
|
||||
local dscp s=0 i ipv4_error=1 ipv6_error=1
|
||||
if [ -z "$tid" ] || [ -z "$mark" ] || [ -z "$iface" ]; then
|
||||
state add 'errorSummary' 'errorInterfaceRoutingEmptyValues'
|
||||
json add error 'errorInterfaceRoutingEmptyValues'
|
||||
return 1
|
||||
fi
|
||||
case "$action" in
|
||||
@@ -1602,7 +1625,7 @@ EOF
|
||||
elif ip -6 address show dev "$dev6" | grep -q "POINTOPOINT"; then
|
||||
try ip -6 route add default dev "$dev6" table "$tid" metric "$procd_wan6_metric" || ipv6_error=1
|
||||
else
|
||||
state add 'errorSummary' 'errorInterfaceRoutingUnknownDevType' "$dev6"
|
||||
json add error 'errorInterfaceRoutingUnknownDevType' "$dev6"
|
||||
fi
|
||||
# if ! ip -6 route add default via "$gw6" dev "$dev6" table "$tid" >/dev/null 2>&1; then
|
||||
# try ip -6 route add default dev "$dev6" table "$tid" metric "$procd_wan6_metric" || ipv6_error=1
|
||||
@@ -1693,7 +1716,7 @@ EOF
|
||||
elif ip -6 address show dev "$dev6" | grep -q "POINTOPOINT"; then
|
||||
try ip -6 route add default dev "$dev6" table "$tid" metric "$procd_wan6_metric" || ipv6_error=1
|
||||
else
|
||||
state add 'errorSummary' 'errorInterfaceRoutingUnknownDevType' "$dev6"
|
||||
json add error 'errorInterfaceRoutingUnknownDevType' "$dev6"
|
||||
fi
|
||||
while read -r i; do
|
||||
# shellcheck disable=SC2086
|
||||
@@ -1752,7 +1775,7 @@ process_interface() {
|
||||
|
||||
if [ "$iface" = 'tor' ]; then
|
||||
case "$action" in
|
||||
create|reload)
|
||||
create|reload|reload_interface)
|
||||
torDnsPort="$(get_tor_dns_port)"
|
||||
torTrafficPort="$(get_tor_traffic_port)"
|
||||
displayText="${iface}/53->${torDnsPort}/80,443->${torTrafficPort}"
|
||||
@@ -1769,7 +1792,7 @@ process_interface() {
|
||||
disabled="$(uci_get 'network' "$iface" 'disabled')"
|
||||
listen_port="$(uci_get 'network' "$iface" 'listen_port')"
|
||||
case "$action" in
|
||||
create|reload)
|
||||
create|reload|reload_interface)
|
||||
if [ "$disabled" != '1' ] && [ -n "$listen_port" ]; then
|
||||
if [ -n "$wanIface4" ]; then
|
||||
ip rule del sport "$listen_port" table "pbr_${wanIface4}" >/dev/null 2>&1
|
||||
@@ -1796,7 +1819,7 @@ process_interface() {
|
||||
[ "$((ifaceMark))" -gt "$((fw_mask))" ] && return 1
|
||||
|
||||
if is_ovpn "$iface" && ! is_ovpn_valid "$iface"; then
|
||||
: || state add 'warningSummary' 'warningInvalidOVPNConfig' "$iface"
|
||||
: || json add warning 'warningInvalidOVPNConfig' "$iface"
|
||||
fi
|
||||
|
||||
network_get_device dev "$iface"
|
||||
@@ -1841,7 +1864,7 @@ process_interface() {
|
||||
gatewaySummary="${gatewaySummary}${displayText}${dispStatus:+ $dispStatus}\n"
|
||||
if is_netifd_table_interface "$iface"; then output_okb; else output_ok; fi
|
||||
else
|
||||
state add 'errorSummary' 'errorFailedSetup' "$displayText"
|
||||
json add error 'errorFailedSetup' "$displayText"
|
||||
output_fail
|
||||
fi
|
||||
;;
|
||||
@@ -1918,7 +1941,7 @@ process_interface() {
|
||||
gatewaySummary="${gatewaySummary}${displayText}${dispStatus:+ $dispStatus}\n"
|
||||
if is_netifd_table_interface "$iface"; then output_okb; else output_ok; fi
|
||||
else
|
||||
state add 'errorSummary' 'errorFailedReload' "$displayText"
|
||||
json add error 'errorFailedReload' "$displayText"
|
||||
output_fail
|
||||
fi
|
||||
else
|
||||
@@ -1936,26 +1959,26 @@ user_file_process() {
|
||||
local shellBin="${SHELL:-/bin/ash}"
|
||||
[ "$enabled" -gt '0' ] || return 0
|
||||
if [ ! -s "$path" ]; then
|
||||
state add 'errorSummary' 'errorUserFileNotFound' "$path"
|
||||
json add error 'errorUserFileNotFound' "$path"
|
||||
output_fail
|
||||
return 1
|
||||
fi
|
||||
if ! $shellBin -n "$path"; then
|
||||
state add 'errorSummary' 'errorUserFileSyntax' "$path"
|
||||
json add error 'errorUserFileSyntax' "$path"
|
||||
output_fail
|
||||
return 1
|
||||
fi
|
||||
if is_bad_user_file_nft_call "$path"; then
|
||||
state add 'errorSummary' 'errorIncompatibleUserFile' "$path"
|
||||
json add error 'errorIncompatibleUserFile' "$path"
|
||||
output_fail
|
||||
return 1
|
||||
fi
|
||||
output 2 "Running $path "
|
||||
# shellcheck disable=SC1090
|
||||
if ! . "$path"; then
|
||||
state add 'errorSummary' 'errorUserFileRunning' "$path"
|
||||
json add error 'errorUserFileRunning' "$path"
|
||||
if grep -q -w 'curl' "$path" && ! is_present 'curl'; then
|
||||
state add 'errorSummary' 'errorUserFileNoCurl' "$path"
|
||||
json add error 'errorUserFileNoCurl' "$path"
|
||||
fi
|
||||
output_fail
|
||||
return 1
|
||||
@@ -1995,11 +2018,14 @@ on_interface_reload() {
|
||||
}
|
||||
|
||||
start_service() {
|
||||
local resolverStoredHash resolverNewHash i param="$1" reloadedIface
|
||||
local resolverStoredHash resolverNewHash i param="$1" reloadedIface k
|
||||
|
||||
[ -n "$pbr_boot_flag" ] && return 0
|
||||
[ "$param" = 'on_boot' ] && return 0
|
||||
load_environment "${param:-on_start}" "$(load_validate_config)" || return 1
|
||||
is_wan_up "$param" || return 1
|
||||
|
||||
output "Processing environment (${param:-on_start}) "
|
||||
is_wan_up "$param" || { output_error "$(get_text 'errorUplinkDown')"; return 1; }
|
||||
|
||||
process_interface 'all' 'prepare'
|
||||
config_foreach process_interface 'interface' 'pre_init'
|
||||
@@ -2056,6 +2082,7 @@ start_service() {
|
||||
|
||||
case $serviceStartTrigger in
|
||||
on_interface_reload)
|
||||
output_okn
|
||||
output 1 "Reloading Interface: $reloadedIface "
|
||||
json_add_array 'gateways'
|
||||
process_interface 'all' 'prepare'
|
||||
@@ -2073,6 +2100,7 @@ start_service() {
|
||||
cleanup_marking_chains
|
||||
cleanup_rt_tables
|
||||
nft_file 'create'
|
||||
output_okn
|
||||
output 1 'Processing interfaces '
|
||||
json_add_array 'gateways'
|
||||
process_interface 'all' 'prepare'
|
||||
@@ -2116,21 +2144,38 @@ start_service() {
|
||||
esac
|
||||
|
||||
if [ -z "$gatewaySummary" ]; then
|
||||
state add 'errorSummary' 'errorNoGateways'
|
||||
json add error 'errorNoGateways'
|
||||
fi
|
||||
json_add_int 'packageCompat' "$packageCompat"
|
||||
json_add_object 'status'
|
||||
[ -n "$gatewaySummary" ] && json_add_string 'gateways' "$gatewaySummary"
|
||||
[ -n "$errorSummary" ] && json_add_string 'errors' "$errorSummary"
|
||||
[ -n "$warningSummary" ] && json_add_string 'warnings' "$warningSummary"
|
||||
json_close_object
|
||||
json_add_array 'errors'
|
||||
for k in $(json get errors); do
|
||||
json_add_object "$k"
|
||||
json_add_string 'code' "$(json get error "$k" 'code')"
|
||||
json_add_string 'info' "$(json get error "$k" 'info')"
|
||||
json_close_object
|
||||
done
|
||||
json_close_array
|
||||
json_add_array 'warnings'
|
||||
for k in $(json get warnings); do
|
||||
json_add_object "$k"
|
||||
json_add_string 'code' "$(json get warning "$k" 'code')"
|
||||
json_add_string 'info' "$(json get warning "$k" 'info')"
|
||||
json_close_object
|
||||
done
|
||||
json_close_array
|
||||
if [ "$strict_enforcement" -ne '0' ] && str_contains "$gatewaySummary" '0.0.0.0'; then
|
||||
json_add_string 'mode' 'strict'
|
||||
fi
|
||||
json_close_object
|
||||
procd_close_data
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
service_started() {
|
||||
[ -n "$pbr_boot_flag" ] && return 0
|
||||
local error warning c
|
||||
if nft_file 'exists'; then
|
||||
procd_set_config_changed firewall
|
||||
if nft_file 'exists'; then
|
||||
@@ -2142,12 +2187,26 @@ service_started() {
|
||||
else
|
||||
[ -n "$gatewaySummary" ] && output "$serviceName (nft mode) started with gateways:\n${gatewaySummary}"
|
||||
fi
|
||||
state print 'errorSummary'
|
||||
state print 'warningSummary'
|
||||
error="$(json get error)"
|
||||
warning="$(json get warning)"
|
||||
if [ -n "$error" ]; then
|
||||
for c in $error; do
|
||||
code="$(json get error "$c" 'code')"
|
||||
info="$(json get error "$c" 'info')"
|
||||
output_error "$(get_text "$code" "$info")"
|
||||
done
|
||||
fi
|
||||
if [ -n "$warning" ]; then
|
||||
for c in $warning; do
|
||||
code="$(json get warning "$c" 'code')"
|
||||
info="$(json get warning "$c" 'info')"
|
||||
output_warning "$(get_text "$code" "$info")"
|
||||
done
|
||||
fi
|
||||
touch "$packageLockFile"
|
||||
if [ -n "$errorSummary" ]; then
|
||||
if [ -n "$error" ]; then
|
||||
return 2
|
||||
elif [ -n "$warningSummary" ]; then
|
||||
elif [ -n "$warning" ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
@@ -2165,9 +2224,9 @@ service_triggers() {
|
||||
load_validate_policy
|
||||
load_validate_include
|
||||
procd_close_validate
|
||||
if [ -n "$pbr_boot_flag" ]; then
|
||||
if [ -n "$pbr_boot_flag" ] && is_integer "$procd_boot_trigger_delay"; then
|
||||
output "Setting trigger (on_boot) "
|
||||
procd_add_raw_trigger "interface.*.up" 5000 "/etc/init.d/${packageName}" start && output_okn || output_failn
|
||||
procd_add_raw_trigger "interface.*.up" "$procd_boot_trigger_delay" "/etc/init.d/${packageName}" start && output_okn || output_failn
|
||||
else
|
||||
procd_open_trigger
|
||||
procd_add_config_trigger "config.change" 'openvpn' "/etc/init.d/${packageName}" reload 'on_openvpn_change'
|
||||
@@ -2353,6 +2412,7 @@ status_service() {
|
||||
# shellcheck disable=SC2120
|
||||
load_validate_config() {
|
||||
uci_load_validate "$packageName" "$packageName" "$1" "${2}${3:+ $3}" \
|
||||
'debug_dnsmasq:bool:0' \
|
||||
'enabled:bool:0' \
|
||||
'strict_enforcement:bool:1' \
|
||||
'ipv6_enabled:bool:0' \
|
||||
@@ -2364,8 +2424,9 @@ load_validate_config() {
|
||||
'icmp_interface:or("", tor, uci("network", "@interface"))' \
|
||||
'ignored_interface:list(or(tor, uci("network", "@interface")))' \
|
||||
'supported_interface:list(or(ignore, tor, regex("xray_.*"), uci("network", "@interface")))' \
|
||||
'procd_reload_delay:integer:0' \
|
||||
'procd_boot_trigger_delay:range(1000,10000):5000' \
|
||||
'procd_lan_device:list(or(network)):br-lan' \
|
||||
'procd_reload_delay:uinteger:0' \
|
||||
'procd_wan_interface:network:wan' \
|
||||
'procd_wan6_interface:network:wan6' \
|
||||
'wan_ip_rules_priority:uinteger:30000' \
|
||||
|
||||
Reference in New Issue
Block a user