diff options
| author | Ralf Lici <ralf@mandelbit.com> | 2026-08-28 16:50:23 +0200 |
|---|---|---|
| committer | Antonio Quartulli <antonio@openvpn.net> | 2026-09-21 11:39:13 +0200 |
| commit | 77393b4d72dfeb764b2af2b848acc659f6fcfd0a (patch) | |
| tree | 485e0b989b2be7da3a1a54620596525f06599100 /drivers/net/ovpn | |
| parent | 7a6d08ee0f0e30023d18779bb314db8fd9a3b6d4 (diff) | |
| download | linux-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.c | 7 |
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 |
