[Openvpn-devel,1/2] dco-freebsd: pass address scope to the kernel

Message ID 20250729093857.37832-1-kprovost@netgate.com
State Accepted
Headers show
Series [Openvpn-devel,1/2] dco-freebsd: pass address scope to the kernel | expand

Commit Message

Kristof Provost July 29, 2025, 9:38 a.m. UTC
From: Kristof Provost <kp@FreeBSD.org>

To support link-local (IPv6) addresses we must pass the scope to the kernel as
well. We should also extract it from the kernel notification for float events.

Signed-off-by: Kristof Provost <kprovost@netgate.com>
---
 src/openvpn/dco_freebsd.c | 6 ++++++
 1 file changed, 6 insertions(+)

Comments

Kristof Provost July 29, 2025, 10:55 a.m. UTC | #1
This requires kernel side support: [https://reviews.freebsd.org/D51596](https://reviews.freebsd.org/D51596)


—
Kristof

On 29 Jul 2025, at 11:38, Kristof Provost wrote:
> From: Kristof Provost <kp@FreeBSD.org>
>
> To support link-local (IPv6) addresses we must pass the scope to the kernel as
> well. We should also extract it from the kernel notification for float events.
>
> Signed-off-by: Kristof Provost <kprovost@netgate.com>
> ---
>  src/openvpn/dco_freebsd.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
> index 8add41af..306ecd31 100644
> --- a/src/openvpn/dco_freebsd.c
> +++ b/src/openvpn/dco_freebsd.c
> @@ -62,6 +62,7 @@ sockaddr_to_nvlist(const struct sockaddr *sa)
>              const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *)sa;
>              nvlist_add_binary(nvl, "address", &in6->sin6_addr, sizeof(in6->sin6_addr));
>              nvlist_add_number(nvl, "port", in6->sin6_port);
> +            nvlist_add_number(nvl, "scopeid", in6->sin6_scope_id);
>              break;
>          }
>
> @@ -118,6 +119,11 @@ nvlist_to_sockaddr(const nvlist_t *nvl, struct sockaddr_storage *ss)
>              assert(len == sizeof(in6->sin6_addr));
>              memcpy(&in6->sin6_addr, data, sizeof(in6->sin6_addr));
>              in6->sin6_port = nvlist_get_number(nvl, "port");
> +
> +            if (nvlist_exists_number(nvl, "scopeid"))
> +            {
> +                in6->sin6_scope_id = nvlist_get_number(nvl, "scopeid");
> +            }
>              break;
>          }
>
> -- 
> 2.50.1
Gert Doering July 29, 2025, 11:07 a.m. UTC | #2
Hi,

On Tue, Jul 29, 2025 at 12:55:29PM +0200, Kristof Provost via Openvpn-devel wrote:
> This requires kernel side support: [https://reviews.freebsd.org/D51596](https://reviews.freebsd.org/D51596)

I did not yet test it, but I assume that including scope-id in the
message to an older kernel will not break anything for non-LLA peers?

(For LLA%scope peers, it will not work today, and won't work without
kernel-side support - this much is clear ;-) ).

gert
Kristof Provost July 29, 2025, 11:30 a.m. UTC | #3
On 29 Jul 2025, at 13:07, Gert Doering wrote:
> On Tue, Jul 29, 2025 at 12:55:29PM +0200, Kristof Provost via 
> Openvpn-devel wrote:
>> This requires kernel side support: 
>> [https://reviews.freebsd.org/D51596](https://reviews.freebsd.org/D51596)
>
> I did not yet test it, but I assume that including scope-id in the
> message to an older kernel will not break anything for non-LLA peers?
>
Correct. That’s why we’re using nvlists in the ioctl path. We can 
add fields without confusing either kernel or userspace. They’ll just 
be ignored.

—
Kristof
Gert Doering July 29, 2025, 2:56 p.m. UTC | #4
I have tested that this does not break on kernels that do not have scope
support (as discussed on the list).  Good :-) - float notifications also
still work fine (unsurprisingly).

Need to setup a testbed with client and server on the same LAN, and
then test DCO with link-local addresses, scope, and floating...

Your patch has been applied to the master branch.

commit b5e0032bf09afa928d9728051599a5e738ff4d10
Author: Kristof Provost
Date:   Tue Jul 29 11:38:57 2025 +0200

     dco-freebsd: pass address scope to the kernel

     Signed-off-by: Kristof Provost <kprovost@netgate.com>
     Acked-by: Gert Doering <gert@greenie.muc.de>
     Message-Id: <20250729093857.37832-1-kprovost@netgate.com>
     URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg32401.html
     Signed-off-by: Gert Doering <gert@greenie.muc.de>


--
kind regards,

Gert Doering

Patch

diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index 8add41af..306ecd31 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -62,6 +62,7 @@  sockaddr_to_nvlist(const struct sockaddr *sa)
             const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *)sa;
             nvlist_add_binary(nvl, "address", &in6->sin6_addr, sizeof(in6->sin6_addr));
             nvlist_add_number(nvl, "port", in6->sin6_port);
+            nvlist_add_number(nvl, "scopeid", in6->sin6_scope_id);
             break;
         }
 
@@ -118,6 +119,11 @@  nvlist_to_sockaddr(const nvlist_t *nvl, struct sockaddr_storage *ss)
             assert(len == sizeof(in6->sin6_addr));
             memcpy(&in6->sin6_addr, data, sizeof(in6->sin6_addr));
             in6->sin6_port = nvlist_get_number(nvl, "port");
+
+            if (nvlist_exists_number(nvl, "scopeid"))
+            {
+                in6->sin6_scope_id = nvlist_get_number(nvl, "scopeid");
+            }
             break;
         }