Merge pull request #23880 from stangri/master-pbr

pbr: update to 1.1.4-r15
This commit is contained in:
Stan Grishin 2024-04-12 13:57:44 -07:00 committed by GitHub
commit 45998b82b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 300 additions and 2636 deletions

View File

@ -5,13 +5,13 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=pbr
PKG_VERSION:=1.1.4
PKG_RELEASE:=r7
PKG_RELEASE:=r15
PKG_LICENSE:=GPL-3.0-or-later
PKG_MAINTAINER:=Stan Grishin <stangri@melmac.ca>
include $(INCLUDE_DIR)/package.mk
define Package/pbr-service/Default
define Package/pbr/default
SECTION:=net
CATEGORY:=Network
SUBMENU:=Routing and Redirection
@ -21,60 +21,60 @@ define Package/pbr-service/Default
DEPENDS+=+!BUSYBOX_DEFAULT_AWK:gawk
DEPENDS+=+!BUSYBOX_DEFAULT_GREP:grep
DEPENDS+=+!BUSYBOX_DEFAULT_SED:sed
PROVIDES:=pbr-service
CONFLICTS:=vpnbypass vpn-policy-routing
PROVIDES:=pbr
PKGARCH:=all
endef
define Package/pbr
$(call Package/pbr-service/Default)
$(call Package/pbr/default)
TITLE+= with nft/nft set support
DEPENDS+=+kmod-nft-core +kmod-nft-nat +nftables-json
DEFAULT_VARIANT:=1
VARIANT:=nftables
PROVIDES+=pbr vpnbypass vpn-policy-routing
DEFAULT_VARIANT:=1
PROVIDES+=vpnbypass vpn-policy-routing
endef
define Package/pbr-iptables
$(call Package/pbr-service/Default)
$(call Package/pbr/default)
TITLE+= with iptables/ipset support
DEPENDS+=+ipset +iptables +kmod-ipt-ipset +iptables-mod-ipopt
VARIANT:=iptables
endef
define Package/pbr-netifd
$(call Package/pbr-service/Default)
$(call Package/pbr/default)
TITLE+= with netifd support
VARIANT:=netifd
endef
define Package/pbr-service/description
define Package/pbr/default/description
This service enables policy-based routing for WAN interfaces and various VPN tunnels.
endef
define Package/pbr/description
$(call Package/pbr-service/description)
$(call Package/pbr/default/description)
This version supports OpenWrt with both firewall3/ipset/iptables and firewall4/nft.
endef
define Package/pbr-iptables/description
$(call Package/pbr-service/description)
$(call Package/pbr/default/description)
This version supports OpenWrt with firewall3/ipset/iptables.
endef
define Package/pbr-netifd/description
$(call Package/pbr-service/description)
$(call Package/pbr/default/description)
This version supports OpenWrt with both firewall3/ipset/iptables and firewall4/nft.
This version uses OpenWrt native netifd/tables to set up interfaces. This is WIP.
endef
define Package/pbr-service/conffiles
define Package/pbr/default/conffiles
/etc/config/pbr
endef
Package/pbr/conffiles = $(Package/pbr-service/conffiles)
Package/pbr-iptables/conffiles = $(Package/pbr-service/conffiles)
Package/pbr-netifd/conffiles = $(Package/pbr-service/conffiles)
Package/pbr/conffiles = $(Package/pbr/default/conffiles)
Package/pbr-iptables/conffiles = $(Package/pbr/default/conffiles)
Package/pbr-netifd/conffiles = $(Package/pbr/default/conffiles)
define Build/Configure
endef
@ -82,7 +82,7 @@ endef
define Build/Compile
endef
define Package/pbr-service/install
define Package/pbr/default/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/etc/init.d/pbr $(1)/etc/init.d/pbr
$(SED) "s|^\(readonly PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(1)/etc/init.d/pbr
@ -98,29 +98,33 @@ endef
# $(INSTALL_DATA) ./files/etc/hotplug.d/iface/70-pbr $(1)/etc/hotplug.d/iface/70-pbr
define Package/pbr/install
$(call Package/pbr-service/install,$(1))
$(call Package/pbr/default/install,$(1))
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) ./files/etc/config/pbr $(1)/etc/config/pbr
$(INSTALL_DIR) $(1)/usr/share/pbr
$(INSTALL_DATA) ./files/usr/share/pbr/firewall.include $(1)/usr/share/pbr/firewall.include
$(INSTALL_DIR) $(1)/usr/share/nftables.d
$(CP) ./files/usr/share/nftables.d/* $(1)/usr/share/nftables.d/
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/etc/uci-defaults/91-pbr-nft $(1)/etc/uci-defaults/91-pbr-nft
endef
define Package/pbr-iptables/install
$(call Package/pbr-service/install,$(1))
$(call Package/pbr/default/install,$(1))
$(INSTALL_DIR) $(1)/etc/hotplug.d/firewall
$(INSTALL_DATA) ./files/etc/hotplug.d/firewall/70-pbr $(1)/etc/hotplug.d/firewall/70-pbr
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) ./files/etc/config/pbr.iptables $(1)/etc/config/pbr
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/etc/uci-defaults/91-pbr-iptables $(1)/etc/uci-defaults/91-pbr-iptables
endef
define Package/pbr-netifd/install
$(call Package/pbr-service/install,$(1))
$(call Package/pbr/default/install,$(1))
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) ./files/etc/config/pbr $(1)/etc/config/pbr
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/etc/uci-defaults/91-pbr $(1)/etc/uci-defaults/91-pbr
$(INSTALL_BIN) ./files/etc/uci-defaults/91-pbr-netifd $(1)/etc/uci-defaults/91-pbr-netifd
endef
define Package/pbr/postinst
@ -141,8 +145,8 @@ define Package/pbr/prerm
# check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then
uci -q delete firewall.pbr || true
echo "Stopping pbr service... "
/etc/init.d/pbr stop quiet && echo "OK" || echo "FAIL"
echo -n "Stopping pbr service... "
/etc/init.d/pbr stop quiet >/dev/null 2>&1 && echo "OK" || echo "FAIL"
echo -n "Removing rc.d symlink for pbr... "
/etc/init.d/pbr disable && echo "OK" || echo "FAIL"
fi
@ -173,8 +177,8 @@ define Package/pbr-iptables/prerm
# check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then
uci -q delete firewall.pbr || true
echo "Stopping pbr-iptables service... "
/etc/init.d/pbr stop quiet && echo "OK" || echo "FAIL"
echo -n "Stopping pbr-iptables service... "
/etc/init.d/pbr stop quiet >/dev/null 2>&1 && echo "OK" || echo "FAIL"
echo -n "Removing rc.d symlink for pbr-iptables... "
/etc/init.d/pbr disable && echo "OK" || echo "FAIL"
fi
@ -196,10 +200,29 @@ define Package/pbr-netifd/prerm
# check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then
uci -q delete firewall.pbr || true
echo "Stopping pbr-netifd service... "
/etc/init.d/pbr stop quiet && echo "OK" || echo "FAIL"
echo -n "Stopping pbr-netifd service... "
/etc/init.d/pbr stop quiet >/dev/null 2>&1 && echo "OK" || echo "FAIL"
echo -n "Removing rc.d symlink for pbr... "
/etc/init.d/pbr disable && echo "OK" || echo "FAIL"
echo -n "Cleaning up /etc/iproute2/rt_tables... "
if sed -i '/pbr_/d' /etc/iproute2/rt_tables; then
echo "OK"
else
echo "FAIL"
fi
echo -n "Cleaning up /etc/config/network... "
if sed -i '/ip.table.*pbr_/d' /etc/config/network; then
echo "OK"
else
echo "FAIL"
fi
echo -n "Restarting Network... "
if /etc/init.d/network restart >/dev/null 2>&1; then
echo "OK"
else
echo "FAIL"
fi
fi
exit 0
endef

View File

@ -22,8 +22,10 @@ readonly packageConfigFile="/etc/config/${packageName}"
readonly packageLockFile="/var/run/${packageName}.lock"
readonly dnsmasqFileDefault="/var/dnsmasq.d/${packageName}"
readonly _OK_='\033[0;32m\xe2\x9c\x93\033[0m'
readonly _FAIL_='\033[0;31m\xe2\x9c\x97\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'
@ -55,6 +57,7 @@ readonly chainsList='forward input output postrouting prerouting'
readonly ssConfigFile='/etc/shadowsocks'
readonly torConfigFile='/etc/tor/torrc'
readonly xrayIfacePrefix='xray_'
readonly rtTablesFile='/etc/iproute2/rt_tables'
# package config options
procd_boot_timeout=
@ -124,6 +127,8 @@ torTrafficPort=
output_ok() { output 1 "$_OK_"; output 2 "$__OK__\\n"; }
output_okn() { output 1 "$_OK_\\n"; output 2 "$__OK__\\n"; }
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"; }
# shellcheck disable=SC2317
@ -236,7 +241,8 @@ is_ipv4_netmask() { local ip="${1%/*}"; [ "$ip" != "$1" ] && is_ipv4 "$ip"; }
is_lan() { local d; network_get_device d "$1"; str_contains "$d" 'br-lan'; }
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_netifd_table() { local iface="$1"; [ "$(uci_get 'network' "$iface" 'ip4table')" = "${packageName}_${iface%6}" ]; }
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}" ]; }
is_oc() { local p; network_get_protocol p "$1"; [ "${p:0:11}" = "openconnect" ]; }
is_ovpn() { local d; uci_get_device d "$1"; [ "${d:0:3}" = "tun" ] || [ "${d:0:3}" = "tap" ] || [ -f "/sys/devices/virtual/net/${d}/tun_flags" ]; }
is_ovpn_valid() { local dev_net dev_ovpn; uci_get_device dev_net "$1"; dev_ovpn="$(uci_get 'openvpn' "$1" 'dev')"; [ -n "$dev_net" ] && [ -n "$dev_ovpn" ] && [ "$dev_net" = "$dev_ovpn" ]; }
@ -284,9 +290,9 @@ get_tor_dns_port() { local i="$(grep -m1 DNSPort "$torConfigFile" | awk -F: '{pr
# shellcheck disable=SC2155
get_tor_traffic_port() { local i="$(grep -m1 TransPort "$torConfigFile" | awk -F: '{print $2}')"; echo "${i:-9040}"; }
get_xray_traffic_port() { local i="${1//$xrayIfacePrefix}"; [ "$i" = "$1" ] && unset i; echo "$i"; }
get_rt_tables_id() { local iface="$1"; grep "${ipTablePrefix}_${iface}\$" '/etc/iproute2/rt_tables' | awk '{print $1;}'; }
get_rt_tables_next_id() { echo "$(($(sort -r -n '/etc/iproute2/rt_tables' | grep -o -E -m 1 "^[0-9]+")+1))"; }
get_rt_tables_non_pbr_next_id() { echo "$(($(grep -v "${ipTablePrefix}_" '/etc/iproute2/rt_tables' | sort -r -n | grep -o -E -m 1 "^[0-9]+")+1))"; }
get_rt_tables_id() { local iface="$1"; grep "${ipTablePrefix}_${iface}\$" "$rtTablesFile" | awk '{print $1;}'; }
get_rt_tables_next_id() { echo "$(($(sort -r -n "$rtTablesFile" | grep -o -E -m 1 "^[0-9]+")+1))"; }
get_rt_tables_non_pbr_next_id() { echo "$(($(grep -v "${ipTablePrefix}_" "$rtTablesFile" | sort -r -n | grep -o -E -m 1 "^[0-9]+")+1))"; }
# shellcheck disable=SC2016
resolveip_to_ipt() { resolveip "$@" | sed -n 'H;${x;s/\n/,/g;s/^,//;p;};d'; }
resolveip_to_ipt4() { resolveip_to_ipt -4 "$@"; }
@ -386,6 +392,8 @@ get_text() {
errorResolverNotSupported) r="Resolver set (${resolver_set}) is not supported on this system!";;
errorServiceDisabled) r="The ${packageName} service is currently disabled!";;
errorNoWanGateway) r="The ${serviceName} service failed to discover WAN gateway!";;
errorNoWanInterface) r="The %s inteface 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.";;
errorIpsetNameTooLong) r="The ipset name '%s' is longer than allowed 31 characters!";;
errorNftsetNameTooLong) r="The nft set name '%s' is longer than allowed 255 characters!";;
errorUnexpectedExit) r="Unexpected exit or service termination: '%s'!";;
@ -409,6 +417,7 @@ get_text() {
errorPolicyProcessInsertionFailedIpv4) r="Insertion failed for IPv4 for 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";;
errorNftFileInstall) r="Failed to install fw4 nft file '%s'!";;
errorDownloadUrlNoHttps) r="Failed to download '%s', HTTPS is not supported!";;
errorDownloadUrl) r="Failed to download '%s'!";;
@ -630,6 +639,11 @@ is_wan_up() {
load_network "$param"
[ "$procd_wan_ignore_status" -eq '0' ] || return 0
[ "$param" = 'on_boot' ] || procd_boot_timeout='1'
if [ -z "$(uci_get network "$procd_wan_interface")" ]; then
state add 'errorSummary' 'errorNoWanInterface' "$procd_wan_interface"
state add 'errorSummary' 'errorNoWanInterfaceHint'
return 1
fi
while [ -z "$wanGW" ] ; do
load_network "$param"
if [ $((sleepCount)) -gt $((procd_boot_timeout)) ] || [ -n "$wanGW" ]; then break; fi
@ -959,7 +973,14 @@ nftset() {
fi
}
cleanup_rt_tables() { sed -i "/${ipTablePrefix}_/d" '/etc/iproute2/rt_tables'; sync; }
cleanup_rt_tables() {
local i
# shellcheck disable=SC2013
for i in $(grep -oh "${ipTablePrefix}_.*" $rtTablesFile); do
! is_netifd_table "$i" && sed -i "/${i}/d" "$rtTablesFile"
done
sync
}
cleanup_main_chains() {
local i
@ -1962,6 +1983,13 @@ policy_process() {
fi
}
try() {
if ! "$@"; then
state add 'errorSummary' 'errorTryFailed' "$*"
return 1
fi
}
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
@ -1971,14 +1999,14 @@ interface_routing() {
fi
case "$action" in
create)
if is_netifd_table "$iface"; then
if is_netifd_table_interface "$iface"; then
ipv4_error=0
$ip_bin rule del table "$tid" >/dev/null 2>&1
$ip_bin -4 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv4_error=1
try "$ip_bin" -4 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv4_error=1
if is_nft_mode; then
nft add chain inet "$nftTable" "${nftPrefix}_mark_${mark}" || ipv4_error=1
nft add rule inet "$nftTable" "${nftPrefix}_mark_${mark} counter mark set mark and ${fw_maskXor} xor ${mark}" || ipv4_error=1
nft add rule inet "$nftTable" "${nftPrefix}_mark_${mark} return" || ipv4_error=1
try nft add chain inet "$nftTable" "${nftPrefix}_mark_${mark}" || ipv4_error=1
try nft add rule inet "$nftTable" "${nftPrefix}_mark_${mark} counter mark set mark and ${fw_maskXor} xor ${mark}" || ipv4_error=1
try nft add rule inet "$nftTable" "${nftPrefix}_mark_${mark} return" || ipv4_error=1
else
ipt -t mangle -N "${iptPrefix}_MARK_${mark}" || ipv4_error=1
ipt -t mangle -A "${iptPrefix}_MARK_${mark}" -j MARK --set-xmark "${mark}/${fw_mask}" || ipv4_error=1
@ -1986,13 +2014,13 @@ interface_routing() {
fi
if [ -n "$ipv6_enabled" ]; then
ipv6_error=0
$ip_bin -6 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv6_error=1
try "$ip_bin" -6 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv6_error=1
fi
else
if ! grep -q "$tid ${ipTablePrefix}_${iface}" '/etc/iproute2/rt_tables'; then
sed -i "/${ipTablePrefix}_${iface}/d" '/etc/iproute2/rt_tables'
if ! grep -q "$tid ${ipTablePrefix}_${iface}" "$rtTablesFile"; then
sed -i "/${ipTablePrefix}_${iface}/d" "$rtTablesFile"
sync
echo "$tid ${ipTablePrefix}_${iface}" >> '/etc/iproute2/rt_tables'
echo "$tid ${ipTablePrefix}_${iface}" >> "$rtTablesFile"
sync
fi
$ip_bin rule del table "$tid" >/dev/null 2>&1
@ -2000,9 +2028,9 @@ interface_routing() {
if [ -n "$gw4" ] || [ "$strict_enforcement" -ne 0 ]; then
ipv4_error=0
if [ -z "$gw4" ]; then
$ip_bin -4 route add unreachable default table "$tid" >/dev/null 2>&1 || ipv4_error=1
try "$ip_bin" -4 route add unreachable default table "$tid" >/dev/null 2>&1 || ipv4_error=1
else
$ip_bin -4 route add default via "$gw4" dev "$dev" table "$tid" >/dev/null 2>&1 || ipv4_error=1
try "$ip_bin" -4 route add default via "$gw4" dev "$dev" table "$tid" >/dev/null 2>&1 || ipv4_error=1
fi
# shellcheck disable=SC2086
while read -r i; do
@ -2010,16 +2038,16 @@ interface_routing() {
i="$(echo "$i" | sed 's/ onlink$//')"
idev="$(echo "$i" | grep -Eso 'dev [^ ]*' | awk '{print $2}')"
if ! is_supported_iface_dev "$idev"; then
$ip_bin -4 route add $i table "$tid" >/dev/null 2>&1 || ipv4_error=1
try "$ip_bin" -4 route add $i table "$tid" >/dev/null 2>&1 || ipv4_error=1
fi
done << EOF
$($ip_bin -4 route list table main)
EOF
$ip_bin -4 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv4_error=1
try "$ip_bin" -4 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv4_error=1
if is_nft_mode; then
nft add chain inet "$nftTable" "${nftPrefix}_mark_${mark}" || ipv4_error=1
nft add rule inet "$nftTable" "${nftPrefix}_mark_${mark} counter mark set mark and ${fw_maskXor} xor ${mark}" || ipv4_error=1
nft add rule inet "$nftTable" "${nftPrefix}_mark_${mark} return" || ipv4_error=1
try nft add chain inet "$nftTable" "${nftPrefix}_mark_${mark}" || ipv4_error=1
try nft add rule inet "$nftTable" "${nftPrefix}_mark_${mark} counter mark set mark and ${fw_maskXor} xor ${mark}" || ipv4_error=1
try nft add rule inet "$nftTable" "${nftPrefix}_mark_${mark} return" || ipv4_error=1
else
ipt -t mangle -N "${iptPrefix}_MARK_${mark}" || ipv4_error=1
ipt -t mangle -A "${iptPrefix}_MARK_${mark}" -j MARK --set-xmark "${mark}/${fw_mask}" || ipv4_error=1
@ -2030,38 +2058,38 @@ EOF
ipv6_error=0
if { [ -n "$gw6" ] && [ "$gw6" != "::/0" ]; } || [ "$strict_enforcement" -ne 0 ]; then
if [ -z "$gw6" ] || [ "$gw6" = "::/0" ]; then
$ip_bin -6 route add unreachable default table "$tid" >/dev/null 2>&1 || ipv6_error=1
elif $ip_bin -6 route list table main | grep -q " dev $dev6 "; then
$ip_bin -6 route add default via "$gw6" dev "$dev6" table "$tid" >/dev/null 2>&1 || ipv6_error=1
try "$ip_bin" -6 route add unreachable default table "$tid" >/dev/null 2>&1 || ipv6_error=1
elif try "$ip_bin" -6 route list table main | grep -q " dev $dev6 "; then
try "$ip_bin" -6 route add default via "$gw6" dev "$dev6" table "$tid" >/dev/null 2>&1 || ipv6_error=1
while read -r i; do
i="$(echo "$i" | sed 's/ linkdown$//')"
i="$(echo "$i" | sed 's/ onlink$//')"
# shellcheck disable=SC2086
$ip_bin -6 route add $i table "$tid" >/dev/null 2>&1 || ipv6_error=1
try "$ip_bin" -6 route add $i table "$tid" >/dev/null 2>&1 || ipv6_error=1
done << EOF
$($ip_bin -6 route list table main | grep " dev $dev6 ")
EOF
else
$ip_bin -6 route add "$($ip_bin -6 -o a show "$dev6" | awk '{print $4}')" dev "$dev6" table "$tid" >/dev/null 2>&1 || ipv6_error=1
$ip_bin -6 route add default dev "$dev6" table "$tid" >/dev/null 2>&1 || ipv6_error=1
try "$ip_bin" -6 route add "$($ip_bin -6 -o a show "$dev6" | awk '{print $4}')" dev "$dev6" table "$tid" >/dev/null 2>&1 || ipv6_error=1
try "$ip_bin" -6 route add default dev "$dev6" table "$tid" >/dev/null 2>&1 || ipv6_error=1
fi
fi
$ip_bin -6 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" >/dev/null 2>&1 || ipv6_error=1
try "$ip_bin" -6 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" >/dev/null 2>&1 || ipv6_error=1
fi
fi
if [ "$ipv4_error" -eq 0 ] || [ "$ipv6_error" -eq 0 ]; then
dscp="$(uci_get "$packageName" 'config' "${iface}_dscp")"
if is_nft_mode; then
if [ "${dscp:-0}" -ge 1 ] && [ "${dscp:-0}" -le 63 ]; then
nft add rule inet "$nftTable" "${nftPrefix}_prerouting ${nftIPv4Flag} dscp ${dscp} goto ${nftPrefix}_mark_${mark}" || s=1
try nft add rule inet "$nftTable" "${nftPrefix}_prerouting ${nftIPv4Flag} dscp ${dscp} goto ${nftPrefix}_mark_${mark}" || s=1
if [ -n "$ipv6_enabled" ]; then
nft add rule inet "$nftTable" "${nftPrefix}_prerouting ${nftIPv6Flag} dscp ${dscp} goto ${nftPrefix}_mark_${mark}" || s=1
try nft add rule inet "$nftTable" "${nftPrefix}_prerouting ${nftIPv6Flag} dscp ${dscp} goto ${nftPrefix}_mark_${mark}" || s=1
fi
fi
if [ "$iface" = "$icmp_interface" ]; then
nft add rule inet "$nftTable" "${nftPrefix}_output ${nftIPv4Flag} protocol icmp goto ${nftPrefix}_mark_${mark}" || s=1
try nft add rule inet "$nftTable" "${nftPrefix}_output ${nftIPv4Flag} protocol icmp goto ${nftPrefix}_mark_${mark}" || s=1
if [ -n "$ipv6_enabled" ]; then
nft add rule inet "$nftTable" "${nftPrefix}_output ${nftIPv6Flag} protocol icmp goto ${nftPrefix}_mark_${mark}" || s=1
try nft add rule inet "$nftTable" "${nftPrefix}_output ${nftIPv6Flag} protocol icmp goto ${nftPrefix}_mark_${mark}" || s=1
fi
fi
else
@ -2093,46 +2121,46 @@ EOF
;;
delete|destroy)
$ip_bin rule del table "$tid" >/dev/null 2>&1
if ! is_netifd_table "$iface"; then
if ! is_netifd_table_interface "$iface"; then
$ip_bin route flush table "$tid" >/dev/null 2>&1
sed -i "/${ipTablePrefix}_${iface}\$/d" '/etc/iproute2/rt_tables'
sed -i "/${ipTablePrefix}_${iface}\$/d" "$rtTablesFile"
sync
fi
return "$s"
;;
reload_interface)
is_netifd_table "$iface" && return 0;
is_netifd_table_interface "$iface" && return 0;
ipv4_error=0
$ip_bin rule del table "$tid" >/dev/null 2>&1
if ! is_netifd_table "$iface"; then
if ! is_netifd_table_interface "$iface"; then
$ip_bin route flush table "$tid" >/dev/null 2>&1
fi
if [ -n "$gw4" ] || [ "$strict_enforcement" -ne 0 ]; then
if [ -z "$gw4" ]; then
$ip_bin -4 route add unreachable default table "$tid" >/dev/null 2>&1 || ipv4_error=1
try "$ip_bin" -4 route add unreachable default table "$tid" >/dev/null 2>&1 || ipv4_error=1
else
$ip_bin -4 route add default via "$gw4" dev "$dev" table "$tid" >/dev/null 2>&1 || ipv4_error=1
try "$ip_bin" -4 route add default via "$gw4" dev "$dev" table "$tid" >/dev/null 2>&1 || ipv4_error=1
fi
$ip_bin rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv4_error=1
try "$ip_bin" rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv4_error=1
fi
if [ -n "$ipv6_enabled" ]; then
ipv6_error=0
if { [ -n "$gw6" ] && [ "$gw6" != "::/0" ]; } || [ "$strict_enforcement" -ne 0 ]; then
if [ -z "$gw6" ] || [ "$gw6" = "::/0" ]; then
$ip_bin -6 route add unreachable default table "$tid" || ipv6_error=1
try "$ip_bin" -6 route add unreachable default table "$tid" || ipv6_error=1
elif $ip_bin -6 route list table main | grep -q " dev $dev6 "; then
while read -r i; do
# shellcheck disable=SC2086
$ip_bin -6 route add $i table "$tid" >/dev/null 2>&1 || ipv6_error=1
try "$ip_bin" -6 route add $i table "$tid" >/dev/null 2>&1 || ipv6_error=1
done << EOF
$($ip_bin -6 route list table main | grep " dev $dev6 ")
EOF
else
$ip_bin -6 route add "$($ip_bin -6 -o a show "$dev6" | awk '{print $4}')" dev "$dev6" table "$tid" >/dev/null 2>&1 || ipv6_error=1
$ip_bin -6 route add default dev "$dev6" table "$tid" >/dev/null 2>&1 || ipv6_error=1
try "$ip_bin" -6 route add "$($ip_bin -6 -o a show "$dev6" | awk '{print $4}')" dev "$dev6" table "$tid" >/dev/null 2>&1 || ipv6_error=1
try "$ip_bin" -6 route add default dev "$dev6" table "$tid" >/dev/null 2>&1 || ipv6_error=1
fi
fi
$ip_bin -6 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv6_error=1
try "$ip_bin" -6 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv6_error=1
fi
if [ "$ipv4_error" -eq 0 ] || [ "$ipv6_error" -eq 0 ]; then
s=0
@ -2209,66 +2237,112 @@ interface_process() {
[ -z "$ifaceMark" ] && ifaceMark="$(printf '0x%06x' "$wan_mark")"
[ -z "$ifacePriority" ] && ifacePriority="$wan_ip_rules_priority"
if [ "$action" = 'pre-init' ]; then
pbr_get_gateway6 gw6 "$iface" "$dev6"
[ -n "$gw6" ] && ipv6_enabled=1
[ -z "$ifaceTableID" ] && ifaceTableID="$(get_rt_tables_non_pbr_next_id)"
eval "pre_init_mark_${iface//-/_}"='$ifaceMark'
eval "pre_init_priority_${iface//-/_}"='$ifacePriority'
eval "pre_init_tid_${iface//-/_}"='$ifaceTableID'
ifaceMark="$(printf '0x%06x' $((ifaceMark + wan_mark)))"
ifacePriority="$((ifacePriority + 1))"
ifaceTableID="$((ifaceTableID + 1))"
return 0
fi
# TODO: if interfaces are started out of order the rt_tables ID may be incorrect
# use the expected_tid_${iface} ???
ifaceTableID="$(get_rt_tables_id "$iface")"
[ -z "$ifaceTableID" ] && ifaceTableID="$(get_rt_tables_next_id)"
eval "mark_${iface//-/_}"='$ifaceMark'
eval "tid_${iface//-/_}"='$ifaceTableID'
pbr_get_gateway gw4 "$iface" "$dev"
pbr_get_gateway6 gw6 "$iface" "$dev6"
dispGw4="${gw4:-0.0.0.0}"
dispGw6="${gw6:-::/0}"
[ "$iface" != "$dev" ] && dispDev="$dev"
if is_default_dev "$dev"; then
[ "$verbosity" = '1' ] && dispStatus="$_OK_" || dispStatus="$__OK__"
fi
displayText="${iface}/${dispDev:+$dispDev/}${dispGw4}${ipv6_enabled:+/$dispGw6}"
case "$action" in
pre_init)
[ -z "$ifaceTableID" ] && ifaceTableID="$(get_rt_tables_non_pbr_next_id)"
eval "pre_init_mark_${iface//-/_}"='$ifaceMark'
eval "pre_init_priority_${iface//-/_}"='$ifacePriority'
eval "pre_init_tid_${iface//-/_}"='$ifaceTableID'
ifaceMark="$(printf '0x%06x' $((ifaceMark + wan_mark)))"
ifacePriority="$((ifacePriority - 1))"
ifaceTableID="$((ifaceTableID + 1))"
return 0
;;
create)
ifaceTableID="$(get_rt_tables_id "$iface")"
[ -z "$ifaceTableID" ] && ifaceTableID="$(get_rt_tables_next_id)"
eval "mark_${iface//-/_}"='$ifaceMark'
eval "tid_${iface//-/_}"='$ifaceTableID'
pbr_get_gateway gw4 "$iface" "$dev"
pbr_get_gateway6 gw6 "$iface" "$dev6"
dispGw4="${gw4:-0.0.0.0}"
dispGw6="${gw6:-::/0}"
[ "$iface" != "$dev" ] && dispDev="$dev"
if is_default_dev "$dev"; then
[ "$verbosity" = '1' ] && dispStatus="$_OK_" || dispStatus="$__OK__"
fi
displayText="${iface}/${dispDev:+$dispDev/}${dispGw4}${ipv6_enabled:+/$dispGw6}"
output 2 "Setting up routing for '$displayText' "
if interface_routing 'create' "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6" "$ifacePriority"; then
json_add_gateway 'create' "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6" "$ifacePriority" "$dispStatus"
gatewaySummary="${gatewaySummary}${displayText}${dispStatus:+ $dispStatus}\\n"
output_ok
if is_netifd_table_interface "$iface"; then output_okb; else output_ok; fi
else
state add 'errorSummary' 'errorFailedSetup' "$displayText"
output_fail
fi
;;
create_user_set)
ifaceTableID="$(get_rt_tables_id "$iface")"
[ -z "$ifaceTableID" ] && ifaceTableID="$(get_rt_tables_next_id)"
eval "mark_${iface//-/_}"='$ifaceMark'
eval "tid_${iface//-/_}"='$ifaceTableID'
pbr_get_gateway gw4 "$iface" "$dev"
pbr_get_gateway6 gw6 "$iface" "$dev6"
dispGw4="${gw4:-0.0.0.0}"
dispGw6="${gw6:-::/0}"
[ "$iface" != "$dev" ] && dispDev="$dev"
if is_default_dev "$dev"; then
[ "$verbosity" = '1' ] && dispStatus="$_OK_" || dispStatus="$__OK__"
fi
displayText="${iface}/${dispDev:+$dispDev/}${dispGw4}${ipv6_enabled:+/$dispGw6}"
interface_routing 'create_user_set' "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6" "$ifacePriority"
;;
destroy)
ifaceTableID="$(get_rt_tables_id "$iface")"
[ -z "$ifaceTableID" ] && ifaceTableID="$(get_rt_tables_next_id)"
eval "mark_${iface//-/_}"='$ifaceMark'
eval "tid_${iface//-/_}"='$ifaceTableID'
pbr_get_gateway gw4 "$iface" "$dev"
pbr_get_gateway6 gw6 "$iface" "$dev6"
dispGw4="${gw4:-0.0.0.0}"
dispGw6="${gw6:-::/0}"
[ "$iface" != "$dev" ] && dispDev="$dev"
if is_default_dev "$dev"; then
[ "$verbosity" = '1' ] && dispStatus="$_OK_" || dispStatus="$__OK__"
fi
displayText="${iface}/${dispDev:+$dispDev/}${dispGw4}${ipv6_enabled:+/$dispGw6}"
displayText="${iface}/${dispDev:+$dispDev/}${dispGw4}${ipv6_enabled:+/$dispGw6}"
output 2 "Removing routing for '$displayText' "
interface_routing 'destroy' "${ifaceTableID}" "${ifaceMark}" "${iface}"
output_ok
if is_netifd_table_interface "$iface"; then output_okb; else output_ok; fi
;;
reload)
ifaceTableID="$(get_rt_tables_id "$iface")"
[ -z "$ifaceTableID" ] && ifaceTableID="$(get_rt_tables_next_id)"
eval "mark_${iface//-/_}"='$ifaceMark'
eval "tid_${iface//-/_}"='$ifaceTableID'
pbr_get_gateway gw4 "$iface" "$dev"
pbr_get_gateway6 gw6 "$iface" "$dev6"
dispGw4="${gw4:-0.0.0.0}"
dispGw6="${gw6:-::/0}"
[ "$iface" != "$dev" ] && dispDev="$dev"
if is_default_dev "$dev"; then
[ "$verbosity" = '1' ] && dispStatus="$_OK_" || dispStatus="$__OK__"
fi
displayText="${iface}/${dispDev:+$dispDev/}${dispGw4}${ipv6_enabled:+/$dispGw6}"
gatewaySummary="${gatewaySummary}${displayText}${dispStatus:+ $dispStatus}\\n"
;;
reload_interface)
ifaceTableID="$(get_rt_tables_id "$iface")"
[ -z "$ifaceTableID" ] && ifaceTableID="$(get_rt_tables_next_id)"
eval "mark_${iface//-/_}"='$ifaceMark'
eval "tid_${iface//-/_}"='$ifaceTableID'
pbr_get_gateway gw4 "$iface" "$dev"
pbr_get_gateway6 gw6 "$iface" "$dev6"
dispGw4="${gw4:-0.0.0.0}"
dispGw6="${gw6:-::/0}"
[ "$iface" != "$dev" ] && dispDev="$dev"
if is_default_dev "$dev"; then
[ "$verbosity" = '1' ] && dispStatus="$_OK_" || dispStatus="$__OK__"
fi
displayText="${iface}/${dispDev:+$dispDev/}${dispGw4}${ipv6_enabled:+/$dispGw6}"
if [ "$iface" = "$reloadedIface" ]; then
output 2 "Reloading routing for '$displayText' "
if interface_routing 'reload_interface' "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6" "$ifacePriority"; then
json_add_gateway 'reload_interface' "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6" "$ifacePriority" "$dispStatus"
gatewaySummary="${gatewaySummary}${displayText}${dispStatus:+ $dispStatus}\\n"
output_ok
if is_netifd_table_interface "$iface"; then output_okb; else output_ok; fi
else
state add 'errorSummary' 'errorFailedReload' "$displayText"
output_fail
@ -2280,7 +2354,7 @@ interface_process() {
esac
# ifaceTableID="$((ifaceTableID + 1))"
ifaceMark="$(printf '0x%06x' $((ifaceMark + wan_mark)))"
ifacePriority="$((ifacePriority + 1))"
ifacePriority="$((ifacePriority - 1))"
return $s
}
@ -2351,7 +2425,7 @@ start_service() {
is_wan_up "$param" || return 1
interface_process 'all' 'prepare'
config_foreach interface_process 'interface' 'pre-init'
config_foreach interface_process 'interface' 'pre_init'
case "$param" in
on_boot)
@ -2682,7 +2756,7 @@ status_service_nft() {
# echo "$_SEPARATOR_"
# ip rule list | grep "${packageName}_"
echo "$_SEPARATOR_"
tableCount="$(grep -c "${packageName}_" /etc/iproute2/rt_tables)" || tableCount=0
tableCount="$(grep -c "${packageName}_" $rtTablesFile)" || tableCount=0
wan_tid=$(($(get_rt_tables_next_id)-tableCount))
i=0; while [ $i -lt "$tableCount" ]; do
echo "IPv4 table $((wan_tid + i)) route: $($ip_bin -4 route show table $((wan_tid + i)) | grep default)"
@ -2729,7 +2803,7 @@ status_service_iptables() {
echo "$_SEPARATOR_"
echo "Routes/IP Rules"
tableCount="$(grep -c "${packageName}_" /etc/iproute2/rt_tables)" || tableCount=0
tableCount="$(grep -c "${packageName}_" $rtTablesFile)" || tableCount=0
if [ -n "$set_d" ]; then route; else route | grep '^default'; fi
if [ -n "$set_d" ]; then ip rule list; fi
wan_tid=$(($(get_rt_tables_next_id)-tableCount))

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
#!/bin/sh
# shellcheck disable=SC2015,SC3037,SC3043
readonly pbrFunctionsFile='/etc/init.d/pbr'
if [ -s "$pbrFunctionsFile" ]; then
# shellcheck source=../../etc/init.d/pbr
. "$pbrFunctionsFile"
else
printf "%b: pbr init.d file (%s) not found! \n" '\033[0;31mERROR\033[0m' "$pbrFunctionsFile"
fi
# Transition resolver_set depending on dnsmasq support
if [ "$(uci_get pbr config resolver_set)" != 'dnsmasq.ipset' ] && [ "$(uci_get pbr config resolver_set)" != 'adguardhome.ipset' ]; then
if check_agh_ipset; then
output "Setting resolver_set to 'adguardhome.ipset'... "
uci_set pbr config resolver_set 'adguardhome.ipset' && output_okn || output_failn
elif check_dnsmasq_ipset; then
output "Setting resolver_set to 'dnsmasq.ipset'... "
uci_set pbr config resolver_set 'dnsmasq.ipset' && output_okn || output_failn
else
output "Setting resolver_set to 'none'... "
uci_set pbr config resolver_set 'none' && output_okn || output_failn
fi
uci_commit pbr
fi
exit 0

View File

@ -0,0 +1,38 @@
#!/bin/sh
# shellcheck disable=SC3037,SC3043
readonly pbrFunctionsFile='/etc/init.d/pbr'
if [ -s "$pbrFunctionsFile" ]; then
# shellcheck source=../../etc/init.d/pbr
. "$pbrFunctionsFile"
else
printf "%b: pbr init.d file (%s) not found! \n" '\033[0;31mERROR\033[0m' "$pbrFunctionsFile"
fi
# shellcheck disable=SC2317
pbr_iface_setup() {
local iface="${1}"
local proto
if is_supported_interface "${iface}"; then
output "Setting up ${packageName} routing tables for ${iface}... "
uci_set 'network' "${iface}" 'ip4table' "${ipTablePrefix}_${iface%6}"
uci_set 'network' "${iface}" 'ip6table' "${ipTablePrefix}_${iface%6}"
if ! grep -q -E -e "^[0-9]+\s+${ipTablePrefix}_${iface%6}$" "$rtTablesFile"; then
sed -i -e "\$a $(($(sort -r -n "$rtTablesFile" | grep -o -E -m 1 "^[0-9]+")+1))\t${ipTablePrefix}_${iface%6}" \
"$rtTablesFile"
fi
output_okbn
fi
}
sed -i "/${ipTablePrefix}_/d" "$rtTablesFile"
sync
config_load network
config_foreach pbr_iface_setup interface
uci_commit network
sync
output "Restarting network... "
/etc/init.d/network restart
output_okn
exit 0

View File

@ -0,0 +1,30 @@
#!/bin/sh
# shellcheck disable=SC2015,SC3037,SC3043
readonly pbrFunctionsFile='/etc/init.d/pbr'
if [ -s "$pbrFunctionsFile" ]; then
# shellcheck source=../../etc/init.d/pbr
. "$pbrFunctionsFile"
else
printf "%b: pbr init.d file (%s) not found! \n" '\033[0;31mERROR\033[0m' "$pbrFunctionsFile"
fi
# Transition resolver_set depending on dnsmasq support
if [ "$(uci_get pbr config resolver_set)" != 'dnsmasq.nftset' ]; then
if check_dnsmasq_nftset; then
output "Setting resolver_set to 'dnsmasq.nftset'... "
uci_set pbr config resolver_set 'dnsmasq.nftset' && output_okn || output_failn
elif check_agh_ipset; then
output "Setting resolver_set to 'adguardhome.ipset'... "
uci_set pbr config resolver_set 'adguardhome.ipset' && output_okn || output_failn
elif check_dnsmasq_ipset; then
output "Setting resolver_set to 'dnsmasq.ipset'... "
uci_set pbr config resolver_set 'dnsmasq.ipset' && output_okn || output_failn
else
output "Setting resolver_set to 'none'... "
uci_set pbr config resolver_set 'none' && output_okn || output_failn
fi
uci_commit pbr
fi
exit 0