From bb02e8b73412f0db624d2df31a58803a4cd9ea47 Mon Sep 17 00:00:00 2001 From: Chen Minqiang Date: Tue, 31 Mar 2026 00:21:21 +0800 Subject: [PATCH] openvpn: handler: refine netifd routing and config Introduce a new `ipv6` proto option for OpenVPN netifd integration and export it to the hotplug environment. IPv6 remains enabled by default, but can now be explicitly disabled per instance. Update the hotplug helper to apply IPv6 addresses and routes only when IPv6 is enabled, allowing cleaner IPv4-only tunnel deployments. Also improve route handling by: - ignoring invalid default gateway values (0.0.0.0 / ::) - replacing fixed `seq` loops with shell-safe while loops - keeping trusted peer host routes conditional on valid gateways Signed-off-by: Chen Minqiang --- net/openvpn/Makefile | 2 +- net/openvpn/files/lib/netifd/proto/openvpn.sh | 7 +++ net/openvpn/files/usr/libexec/openvpn-hotplug | 62 +++++++++++-------- 3 files changed, 45 insertions(+), 26 deletions(-) diff --git a/net/openvpn/Makefile b/net/openvpn/Makefile index 634c031659..7b9a3a84df 100644 --- a/net/openvpn/Makefile +++ b/net/openvpn/Makefile @@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=openvpn PKG_VERSION:=2.7.1 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE_URL:=\ https://build.openvpn.net/downloads/releases/ \ diff --git a/net/openvpn/files/lib/netifd/proto/openvpn.sh b/net/openvpn/files/lib/netifd/proto/openvpn.sh index 3e3458af27..2cf5dd718e 100755 --- a/net/openvpn/files/lib/netifd/proto/openvpn.sh +++ b/net/openvpn/files/lib/netifd/proto/openvpn.sh @@ -92,6 +92,7 @@ option_builder() { # Not real config params used by openvpn - only by our proto handler PROTO_BOOLS=' allow_deprecated +ipv6 ' PROTO_STRINGS=' @@ -191,6 +192,7 @@ proto_openvpn_setup() { # Add default hotplug handling if 'script_security' option is equal '3' if [ "$script_security" -eq '3' ]; then + local ipv6 local up down route_up route_pre_down local client tls_client tls_server local tls_crypt_v2_verify mode learn_address client_connect @@ -206,6 +208,11 @@ proto_openvpn_setup() { json_get_vars tls_crypt_v2_verify mode learn_address client_connect json_get_vars client_crresponse client_disconnect auth_user_pass_verify + json_get_vars ipv6 + #default ipv6 is enabled + [ -n "$ipv6" ] || ipv6=1 + append exec_params "--setenv IPV6 '$ipv6'" + json_get_vars ifconfig_noexec route_noexec [ -z "$ifconfig_noexec" ] && append exec_params "--ifconfig-noexec" [ -z "$route_noexec" ] && append exec_params "--route-noexec" diff --git a/net/openvpn/files/usr/libexec/openvpn-hotplug b/net/openvpn/files/usr/libexec/openvpn-hotplug index b2b66d929f..96734f6532 100644 --- a/net/openvpn/files/usr/libexec/openvpn-hotplug +++ b/net/openvpn/files/usr/libexec/openvpn-hotplug @@ -49,13 +49,17 @@ case "$script_type" in [ -n "$ifconfig_local" ] && proto_add_ipv4_address "$ifconfig_local" "${ifconfig_netmask:-255.255.255.255}" - [ -n "$trusted_ip" ] && [ -n "$route_net_gateway" ] && { - proto_add_ipv4_route "$trusted_ip" 32 "$route_net_gateway" + [ -n "$trusted_ip" ] && { + if [ -n "$route_net_gateway" -a "$route_net_gateway" != "0.0.0.0" ]; then + proto_add_ipv4_route "$trusted_ip" 32 "$route_net_gateway" + fi } [ -n "$route_vpn_gateway" ] && proto_add_ipv4_route "0.0.0.0" 0 "$route_vpn_gateway" - for i in $(seq 1 32); do + i=0 + while :; do + i=$((i+1)) eval "net=\$route_network_$i mask=\$route_netmask_$i gw=\$route_gateway_$i" [ -z "$net" ] && break [ -z "$mask" ] && continue @@ -64,32 +68,40 @@ case "$script_type" in proto_add_ipv4_route "$net" "$plen" "$gw" done - if [ -n "$ifconfig_ipv6_local" ]; then - read -r v6addr v6plen <<-EOF - $(parse_cidr6 "$ifconfig_ipv6_local" "${ifconfig_ipv6_netbits:-128}") - EOF - proto_add_ipv6_address "$v6addr" "$v6plen" + if [ "$IPV6" = "1" ]; then + if [ -n "$ifconfig_ipv6_local" ]; then + read -r v6addr v6plen <<-EOF + $(parse_cidr6 "$ifconfig_ipv6_local" "${ifconfig_ipv6_netbits:-128}") + EOF + proto_add_ipv6_address "$v6addr" "$v6plen" + fi + + [ -n "$trusted_ip6" ] && { + if [ -n "$route_ipv6_gateway" -a "$route_ipv6_gateway" != "::" ]; then + proto_add_ipv6_route "$trusted_ip6" 128 "$route_ipv6_gateway" + fi + } + + [ -n "$ifconfig_ipv6_remote" ] && proto_add_ipv6_route "::" 0 "$ifconfig_ipv6_remote" + + i=0 + while :; do + i=$((i+1)) + eval "net=\$route_ipv6_network_$i gw=\$route_ipv6_gateway_$i" + [ -z "$net" ] && break + + read -r v6net v6plen <<-EOF + $(parse_cidr6 "$net" 128) + EOF + proto_add_ipv6_route "$v6net" "$v6plen" "$gw" + done fi - [ -n "$trusted_ip6" ] && [ -n "$route_ipv6_gateway" ] && { - proto_add_ipv6_route "$trusted_ip6" 128 "$route_ipv6_gateway" - } - - [ -n "$ifconfig_ipv6_remote" ] && proto_add_ipv6_route "::" 0 "$ifconfig_ipv6_remote" - - for i in $(seq 1 32); do - eval "net=\$route_ipv6_network_$i gw=\$route_ipv6_gateway_$i" - [ -z "$net" ] && break - - read -r v6net v6plen <<-EOF - $(parse_cidr6 "$net" 128) - EOF - proto_add_ipv6_route "$v6net" "$v6plen" "$gw" - done - [ -n "$tun_mtu" ] && json_add_int mtu "$tun_mtu" - for i in $(seq 1 32); do + i=0 + while :; do + i=$((i+1)) eval "option=\$foreign_option_$i" [ -z "$option" ] && break