summaryrefslogtreecommitdiff
path: root/drivers/net/ovpn
diff options
context:
space:
mode:
authorRalf Lici <ralf@mandelbit.com>2026-08-28 16:50:23 +0200
committerAntonio Quartulli <antonio@openvpn.net>2026-09-21 11:39:13 +0200
commit77393b4d72dfeb764b2af2b848acc659f6fcfd0a (patch)
tree485e0b989b2be7da3a1a54620596525f06599100 /drivers/net/ovpn
parent7a6d08ee0f0e30023d18779bb314db8fd9a3b6d4 (diff)
downloadlinux-next-77393b4d72dfeb764b2af2b848acc659f6fcfd0a.tar.gz
linux-next-77393b4d72dfeb764b2af2b848acc659f6fcfd0a.zip
ovpn: skip UDP source validation for unspecified addresses
ovpn validates the cached local UDP source address before reusing or refreshing a peer dst cache. This is only meaningful when a concrete source address is selected. For IPv6, calling ipv6_chk_addr with :: checks whether the unspecified address itself is configured on the host. A peer may legitimately have bind->local.ipv6 set to :: when no local endpoint was configured or after a stale learned address was cleared. In that case the source should be left unspecified and selected by ip6_dst_lookup_flow(). For IPv4, inet_confirm_addr(..., local = 0, ...) asks for local address autoselection rather than validating a chosen source. Skip the precheck there as well and let ip_route_output_flow select or reject the source. Only validate non-zero/non-any source addresses. Fixes: 08857b5ec5d9 ("ovpn: implement basic TX path (UDP)") Signed-off-by: Ralf Lici <ralf@mandelbit.com> Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
Diffstat (limited to 'drivers/net/ovpn')
-rw-r--r--drivers/net/ovpn/udp.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c
index 7f69e8890b5b..df4750dabd1e 100644
--- a/drivers/net/ovpn/udp.c
+++ b/drivers/net/ovpn/udp.c
@@ -161,8 +161,8 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind,
if (rt)
goto transmit;
- if (unlikely(!inet_confirm_addr(sock_net(sk), NULL, 0, fl.saddr,
- RT_SCOPE_HOST))) {
+ if (fl.saddr && unlikely(!inet_confirm_addr(sock_net(sk), NULL, 0,
+ fl.saddr, RT_SCOPE_HOST))) {
/* we may end up here when the cached address is not usable
* anymore. In this case we reset address/cache and perform a
* new look up
@@ -238,7 +238,8 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind,
if (dst)
goto transmit;
- if (unlikely(!ipv6_chk_addr(sock_net(sk), &fl.saddr, NULL, 0))) {
+ if (!ipv6_addr_any(&fl.saddr) &&
+ unlikely(!ipv6_chk_addr(sock_net(sk), &fl.saddr, NULL, 0))) {
/* we may end up here when the cached address is not usable
* anymore. In this case we reset address/cache and perform a
* new look up