[Openvpn-devel] [PATCH] dco-freebsd: dynamically re-allocate buffer if it's too small

2024-01-24 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

It's possible for the buffer we provude for OVPN_GET_PEER_STATS to be
too small. Handle the error, re-allocate a larger buffer and try again
rather than failing.

Signed-off-by: Kristof Provost 
---
 src/openvpn/dco_freebsd.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index 3ba1c817..577c65f8 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -698,7 +698,8 @@ dco_get_peer_stats_multi(dco_context_t *dco, struct 
multi_context *m)
 {
 
 struct ifdrv drv;
-uint8_t buf[4096];
+uint8_t *buf = NULL;
+size_t buf_size = 4096;
 nvlist_t *nvl;
 const nvlist_t *const *nvpeers;
 size_t npeers;
@@ -712,17 +713,28 @@ dco_get_peer_stats_multi(dco_context_t *dco, struct 
multi_context *m)
 CLEAR(drv);
 snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
 drv.ifd_cmd = OVPN_GET_PEER_STATS;
-drv.ifd_len = sizeof(buf);
+
+retry:
+buf = realloc(buf, buf_size);
+drv.ifd_len = buf_size;
 drv.ifd_data = buf;
 
 ret = ioctl(dco->fd, SIOCGDRVSPEC, );
+if (ret && errno == ENOSPC)
+{
+buf_size *= 2;
+goto retry;
+}
+
 if (ret)
 {
+free(buf);
 msg(M_WARN | M_ERRNO, "Failed to get peer stats");
 return -EINVAL;
 }
 
 nvl = nvlist_unpack(buf, drv.ifd_len, 0);
+free(buf);
 if (!nvl)
 {
 msg(M_WARN, "Failed to unpack nvlist");
-- 
2.43.0



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] DCO: support key rotation notifications

2023-04-14 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Allow the kernel driver to notify us that it's time to renegotiate keys.
The intent is to avoid IV re-use after 2^32 packets.

This is a first draft intended for discussion. The accompanying kernel
change for FreeBSD can be found in https://reviews.freebsd.org/D39570

Signed-off-by: Kristof Provost 
---
 src/openvpn/dco_freebsd.c  |  4 
 src/openvpn/dco_freebsd.h  |  1 +
 src/openvpn/forward.c  | 32 +---
 src/openvpn/multi.c|  4 
 src/openvpn/ovpn_dco_freebsd.h |  1 +
 src/openvpn/ssl.c  |  6 ++
 src/openvpn/ssl.h  |  3 +++
 7 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index a334d5d2..abeb 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -550,6 +550,10 @@ dco_do_read(dco_context_t *dco)
 dco->dco_message_type = OVPN_CMD_DEL_PEER;
 break;
 
+case OVPN_NOTIF_ROTATE_KEY:
+dco->dco_message_type = OVPN_CMD_SWAP_KEYS;
+break;
+
 default:
 msg(M_WARN, "Unknown kernel notification %d", type);
 break;
diff --git a/src/openvpn/dco_freebsd.h b/src/openvpn/dco_freebsd.h
index a07f9b69..e1a054e0 100644
--- a/src/openvpn/dco_freebsd.h
+++ b/src/openvpn/dco_freebsd.h
@@ -35,6 +35,7 @@ typedef enum ovpn_key_cipher dco_cipher_t;
 enum ovpn_message_type_t {
 OVPN_CMD_DEL_PEER,
 OVPN_CMD_PACKET,
+OVPN_CMD_SWAP_KEYS,
 };
 
 enum ovpn_del_reason_t {
diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c
index b3e0ba5d..d50eb457 100644
--- a/src/openvpn/forward.c
+++ b/src/openvpn/forward.c
@@ -1232,20 +1232,30 @@ process_incoming_dco(struct context *c)
 return;
 }
 
-if (dco->dco_message_type != OVPN_CMD_DEL_PEER)
+switch (dco->dco_message_type)
 {
-msg(D_DCO_DEBUG, "%s: received message of type %u - ignoring", 
__func__,
-dco->dco_message_type);
-return;
-}
+case OVPN_CMD_DEL_PEER:
+if (dco->dco_del_peer_reason == OVPN_DEL_PEER_REASON_EXPIRED)
+{
+msg(D_DCO_DEBUG, "%s: received peer expired notification 
of for peer-id "
+"%d", __func__, dco->dco_message_peer_id);
+trigger_ping_timeout_signal(c);
+return;
+}
+break;
 
-if (dco->dco_del_peer_reason == OVPN_DEL_PEER_REASON_EXPIRED)
-{
-msg(D_DCO_DEBUG, "%s: received peer expired notification of for 
peer-id "
-"%d", __func__, dco->dco_message_peer_id);
-trigger_ping_timeout_signal(c);
-return;
+case OVPN_CMD_SWAP_KEYS:
+msg(D_DCO_DEBUG, "%s: received key rotation notification for 
peer-id %d",
+__func__, dco->dco_message_peer_id);
+tls_session_soft_reset(c->c2.tls_multi);
+break;
+
+default:
+msg(D_DCO_DEBUG, "%s: received message of type %u - ignoring", 
__func__,
+dco->dco_message_type);
+return;
 }
+
 #endif /* if defined(ENABLE_DCO) && (defined(TARGET_LINUX) || 
defined(TARGET_FREEBSD)) */
 }
 
diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c
index 5444e752..6fb9cff2 100644
--- a/src/openvpn/multi.c
+++ b/src/openvpn/multi.c
@@ -3284,6 +3284,10 @@ multi_process_incoming_dco(struct multi_context *m)
 {
 process_incoming_del_peer(m, mi, dco);
 }
+else if (dco->dco_message_type == OVPN_CMD_SWAP_KEYS)
+{
+tls_session_soft_reset(mi->context.c2.tls_multi);
+}
 }
 else
 {
diff --git a/src/openvpn/ovpn_dco_freebsd.h b/src/openvpn/ovpn_dco_freebsd.h
index fec33835..53f94dfd 100644
--- a/src/openvpn/ovpn_dco_freebsd.h
+++ b/src/openvpn/ovpn_dco_freebsd.h
@@ -36,6 +36,7 @@
 
 enum ovpn_notif_type {
 OVPN_NOTIF_DEL_PEER,
+OVPN_NOTIF_ROTATE_KEY,
 };
 
 enum ovpn_del_reason {
diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index 60aaee8d..26e86c8d 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -1918,6 +1918,12 @@ key_state_soft_reset(struct tls_session *session)
 ks->remote_addr = ks_lame->remote_addr;
 }
 
+void
+tls_session_soft_reset(struct tls_multi *tls_multi)
+{
+   key_state_soft_reset(_multi->session[TM_ACTIVE]);
+}
+
 /*
  * Read/write strings from/to a struct buffer with a u16 length prefix.
  */
diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h
index 4ed4cfaa..3c40fbed 100644
--- a/src/openvpn/ssl.h
+++ b/src/openvpn/ssl.h
@@ -573,6 +573,9 @@ bool
 tls_session_generate_data_channel_keys(struct tls_multi *multi,
struct tls_session *session);
 
+void
+tls_session_soft_reset(struct tls_multi *multi);
+
 /**
  * Load ovpn.xkey provider used for external key signing
  */
-- 
2.40.0



___
Openvpn-devel 

[Openvpn-devel] [PATCH] dco: print FreeBSD version

2023-03-09 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Implement dco_version_string() for FreeBSD.
Unlike Linux and Windows the DCO driver is built into the operating
system itself, so we log the OS version as a proxy for the DCO version.
---
 src/openvpn/dco_freebsd.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index 2b94b2a2..5238ebdd 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -31,6 +31,8 @@
 #include 
 #include 
 #include 
+#include 
+
 #include 
 
 #include "dco_freebsd.h"
@@ -627,7 +629,15 @@ out:
 const char *
 dco_version_string(struct gc_arena *gc)
 {
-return "v0";
+struct utsname* uts;
+ALLOC_OBJ_GC(uts, struct utsname, gc);
+
+if (uname(uts) != 0)
+{
+return "N/A";
+}
+
+return uts->version;
 }
 
 void
-- 
2.39.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] dco: print FreeBSD version

2023-03-09 Thread Kristof Provost via Openvpn-devel
On 9 Mar 2023, at 13:06, Arne Schwabe wrote:
> Am 09.03.23 um 10:26 schrieb Kristof Provost via Openvpn-devel:
>> From: Kristof Provost 
>>
>> Implement dco_version_string() for FreeBSD.
>> Unlike Linux and Windows the DCO driver is built into the operating
>> system itself, so we log the OS version as a proxy for the DCO version.
>> ---
>>   src/openvpn/dco_freebsd.c | 14 +-
>>   1 file changed, 13 insertions(+), 1 deletion(-)
>>
>> diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
>> index 2b94b2a2..a5e96bb2 100644
>> --- a/src/openvpn/dco_freebsd.c
>> +++ b/src/openvpn/dco_freebsd.c
>> @@ -31,6 +31,8 @@
>>   #include 
>>   #include 
>>   #include 
>> +#include 
>> +
>>   #include 
>>#include "dco_freebsd.h"
>> @@ -627,7 +629,17 @@ out:
>>   const char *
>>   dco_version_string(struct gc_arena *gc)
>>   {
>> -return "v0";
>> +struct utsname name;
>> +struct buffer out = alloc_buf_gc(256, gc);
>> +int ret;
>> +
>> +ret = uname();
>> +if (ret != 0)
>> +return "N/A";
>
> There should be { around the return

I’ll fix that.

>> +
>> +buf_printf(, "%s", name.version);
>> +
>> +return (char *)out.data;
>
> This should use BSTR(data) instead.
>
I copied Antonio’s code here, but that is better, so I’ll fix that too.

> Instead of copying/printf, you could also just do:
>
> struct utsname* uts;
> ALLOC_OBJ_GC(uts, struct utsname, gc);
>
>
> if (uname() != 0)
> {
> return "N/A";
> }
>
> return uts->name;
>
I was going to object that we can’t return stack variables, but that’s an 
allocation of utsname, and it removes an intermediate step, so yeah, that’s 
better too (and means I can just copy your code, call it my own and pretend I 
did work ;))

Thanks.
Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] dco: print FreeBSD version

2023-03-09 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Implement dco_version_string() for FreeBSD.
Unlike Linux and Windows the DCO driver is built into the operating
system itself, so we log the OS version as a proxy for the DCO version.
---
 src/openvpn/dco_freebsd.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index 2b94b2a2..a5e96bb2 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -31,6 +31,8 @@
 #include 
 #include 
 #include 
+#include 
+
 #include 
 
 #include "dco_freebsd.h"
@@ -627,7 +629,17 @@ out:
 const char *
 dco_version_string(struct gc_arena *gc)
 {
-return "v0";
+struct utsname name;
+struct buffer out = alloc_buf_gc(256, gc);
+int ret;
+
+ret = uname();
+if (ret != 0)
+return "N/A";
+
+buf_printf(, "%s", name.version);
+
+return (char *)out.data;
 }
 
 void
-- 
2.39.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] dco: print version to log if available

2023-03-09 Thread Kristof Provost via Openvpn-devel
On 9 Mar 2023, at 9:57, Antonio Quartulli wrote:
> On 09/03/2023 09:36, Kristof Provost wrote:
>> On 9 Mar 2023, at 1:52, Antonio Quartulli wrote:
>>> In order to provide better support in case of troubleshooting issues,
>>> it's important to know what exact DCO version is loaded on the user
>>> system.
>>>
>>> Therefore print the DCO version during bootup.
>>>
>>> For Windows and FreeBSD we currently implement a placeholder printing 'v0'.
>>> This should be improved with a follow-up patch.
>>>
>> FreeBSD is a bit special in this regard, because the DCO driver is part of 
>> the base operating system and not an add-on as in Linux and Windows.
>>
>> Arguably the thing to do for FreeBSD is to log the OS version.
>
> Isn't it possible to install DCO "out-of-tree" (as we can do on Linux)?
>
With some effort it could be done, but any version (in the source tree) before 
DCO was actually imported isn’t going to work. I made a few (small) tweaks to 
the network stack to make things work.

Realistically this isn’t something people will do, and if they do decide to the 
usual warranty applies (i.e. they get to keep all of the pieces it breaks into).

> However, what you said will also apply to linux in the future: we will also 
> need to report the kernel version, *if* DCO is compiled in (to be 
> implemented).
>
> This said, reporting the kernel/os version is absolutely appropriate if 
> that's what identifies the DCO version.
>
There’s no API in FreeBSD’s DCO to identify its version either, which is 
another reason to just use the OS version.

> Is that something you could implement in dco_freebsd.c?
>
Sure. I’ll send a patch later today.

Best regards,
Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] dco: print version to log if available

2023-03-09 Thread Kristof Provost via Openvpn-devel
On 9 Mar 2023, at 1:52, Antonio Quartulli wrote:
> In order to provide better support in case of troubleshooting issues,
> it's important to know what exact DCO version is loaded on the user
> system.
>
> Therefore print the DCO version during bootup.
>
> For Windows and FreeBSD we currently implement a placeholder printing 'v0'.
> This should be improved with a follow-up patch.
>
FreeBSD is a bit special in this regard, because the DCO driver is part of the 
base operating system and not an add-on as in Linux and Windows.

Arguably the thing to do for FreeBSD is to log the OS version.

Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] dco: define OVPN_DEL_PEER_REASON_TRANSPORT_DISCONNECT on FreeBSD

2023-03-03 Thread Kristof Provost via Openvpn-devel
On 3 Mar 2023, at 12:48, Antonio Quartulli wrote:
> On 03/03/2023 12:27, Antonio Quartulli wrote:
>> Hi,
>>
>> On 03/03/2023 12:05, Kristof Provost via Openvpn-devel wrote:
>>> From: Kristof Provost 
>>>
>>> FreeBSD's if_ovpn will never emit this as a peer deletion reason
>>> (because it doesn't support TCP), but this allows us to align the
>>> defines between Linux and FreeBSD, and remove a Linux-specific case from
>>> process_incoming_del_peer().
>>
>> SoB missing
>
> Sorry for being very condensed, however the patch looks good and gets my ACK:
>
> Acked-by: Antonio Quartulli 
>
> I normally put my ACK under the SoB, so when I couldn't find it, my brain 
> just threw that exception :-P
>
Ah yes. Do you want me to send an update with the line included, or is this 
sufficient:

Signed-off-by: Kristof Provost 

Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] dco: define OVPN_DEL_PEER_REASON_TRANSPORT_DISCONNECT on FreeBSD

2023-03-03 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

FreeBSD's if_ovpn will never emit this as a peer deletion reason
(because it doesn't support TCP), but this allows us to align the
defines between Linux and FreeBSD, and remove a Linux-specific case from
process_incoming_del_peer().
---
 src/openvpn/dco_freebsd.h | 1 +
 src/openvpn/multi.c   | 3 ---
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/openvpn/dco_freebsd.h b/src/openvpn/dco_freebsd.h
index 2e35f3ac..970beca0 100644
--- a/src/openvpn/dco_freebsd.h
+++ b/src/openvpn/dco_freebsd.h
@@ -41,6 +41,7 @@ enum ovpn_del_reason_t {
 OVPN_DEL_PEER_REASON_EXPIRED,
 OVPN_DEL_PEER_REASON_TRANSPORT_ERROR,
 OVPN_DEL_PEER_REASON_USERSPACE,
+OVPN_DEL_PEER_REASON_TRANSPORT_DISCONNECT,
 };
 
 typedef struct dco_context {
diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c
index f2559016..99123c39 100644
--- a/src/openvpn/multi.c
+++ b/src/openvpn/multi.c
@@ -3244,12 +3244,9 @@ process_incoming_del_peer(struct multi_context *m, 
struct multi_instance *mi,
 reason = "ovpn-dco: transport error";
 break;
 
-#ifdef TARGET_LINUX
-/* FIXME: this is linux-only today and breaks FreeBSD compilation */
 case OVPN_DEL_PEER_REASON_TRANSPORT_DISCONNECT:
 reason = "ovpn-dco: transport disconnected";
 break;
-#endif
 
 case OVPN_DEL_PEER_REASON_USERSPACE:
 /* We assume that is ourselves. Unfortunately, sometimes these
-- 
2.39.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 1/2] configure: improve FreeBSD DCO check

2023-03-01 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

The libnv check doesn't work as expected on FreeBSD 14.x, because
FreeBSD has namespaced libnv to avoid conflicts with libnvpair.
This means that the naive check generated by AC_CHECK_LIB() fails to
detect libnv even though it's present.

Instead check for the if_ovpn.h header. This is a more accurate check
anyway, as libnv is present on FreeBSD versions prior to 14 (which do
not support DCO).

Signed-off-by: Kristof Provost 
---
 configure.ac | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/configure.ac b/configure.ac
index 4c271464..67f680b2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -832,9 +832,7 @@ if test "$enable_dco" != "no"; then
fi
;;
*-*-freebsd*)
-   AC_CHECK_LIB(
-   [nv],
-   [nvlist_create],
+   AC_CHECK_HEADERS([net/if_ovpn.h],
[
 LIBS="${LIBS} -lnv"
 AC_DEFINE(ENABLE_DCO, 1, [Enable data channel 
offload for FreeBSD])
@@ -842,7 +840,7 @@ if test "$enable_dco" != "no"; then
],
[
 enable_dco="no"
-AC_MSG_WARN([Name/Value pair library not 
found.])
+AC_MSG_WARN([DCO header not found.])
]
)
if test "$enable_dco" = "no"; then
-- 
2.39.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 2/2] options.c: enforce a minimal fragment size

2023-03-01 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Very low values for 'fragment' can result in a division by zero in
optimal_fragment_size() (because it rounds max_frag_size down with
FRAG_SIZE_ROUND_MASK).

Enforce a minimal fragment size of 68 bytes, based on RFC 791 ("Every
internet module must be able to forward a datagram of 68 octets without
further fragmentation.")

Signed-off-by: Kristof Provost 
---
 src/openvpn/options.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 9105449c..9f79da09 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -6549,6 +6549,12 @@ add_option(struct options *options,
 VERIFY_PERMISSION(OPT_P_MTU|OPT_P_CONNECTION);
 options->ce.fragment = positive_atoi(p[1]);
 
+if (options->ce.fragment < 68)
+{
+msg(msglevel, "fragment needs to be at least 68");
+goto err;
+}
+
 if (p[2] && streq(p[2], "mtu"))
 {
 options->ce.fragment_encap = true;
-- 
2.39.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 1/4] Read DCO traffic stats from the kernel

2022-12-05 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

When DCO is active userspace doesn't see all of the traffic, so when we
access these stats we must update them.

Retrieve kernel statistics every time we access the
link_(read|write)_bytes values.

Introduce a dco_(read|write)_bytes so that we don't clobber the existing
statistics, which still count control packets, sent or received directly
through the socket.

Signed-off-by: Kristof Provost 
---
 src/openvpn/dco.h  |  8 
 src/openvpn/dco_freebsd.c  | 78 ++
 src/openvpn/dco_linux.c|  7 +++
 src/openvpn/dco_win.c  |  7 +++
 src/openvpn/multi.c| 30 +++--
 src/openvpn/openvpn.h  |  2 +
 src/openvpn/ovpn_dco_freebsd.h |  1 +
 7 files changed, 120 insertions(+), 13 deletions(-)

diff --git a/src/openvpn/dco.h b/src/openvpn/dco.h
index e051db06..e5d89358 100644
--- a/src/openvpn/dco.h
+++ b/src/openvpn/dco.h
@@ -225,6 +225,14 @@ void dco_install_iroute(struct multi_context *m, struct 
multi_instance *mi,
  */
 void dco_delete_iroutes(struct multi_context *m, struct multi_instance *mi);
 
+/**
+ * Update traffic statistics for all peers
+ *
+ * @param dco  DCO device context
+ * @param mthe server context
+ **/
+int dco_get_peer_stats(dco_context_t *dco, struct multi_context *m);
+
 /**
  * Retrieve the list of ciphers supported by the current platform
  *
diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index a52ac8c1..5b352859 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -37,6 +37,7 @@
 #include "dco.h"
 #include "tun.h"
 #include "crypto.h"
+#include "multi.h"
 #include "ssl_common.h"
 
 static nvlist_t *
@@ -641,6 +642,83 @@ dco_event_set(dco_context_t *dco, struct event_set *es, 
void *arg)
 nvlist_destroy(nvl);
 }
 
+static void
+dco_update_peer_stat(struct multi_context *m, uint32_t peerid, const nvlist_t 
*nvl)
+{
+struct hash_element *he;
+struct hash_iterator hi;
+
+hash_iterator_init(m->hash, );
+
+while ((he = hash_iterator_next()))
+{
+struct multi_instance *mi = (struct multi_instance *) he->value;
+
+if (mi->context.c2.tls_multi->peer_id != peerid)
+continue;
+
+mi->context.c2.dco_read_bytes = nvlist_get_number(nvl, "in");
+mi->context.c2.dco_write_bytes = nvlist_get_number(nvl, "out");
+
+return;
+}
+
+msg(M_INFO, "Peer %d returned by kernel, but not found locally", peerid);
+}
+
+int
+dco_get_peer_stats(dco_context_t *dco, struct multi_context *m)
+{
+
+struct ifdrv drv;
+uint8_t buf[4096];
+nvlist_t *nvl;
+const nvlist_t *const *nvpeers;
+size_t npeers;
+int ret;
+
+if (!dco || !dco->open)
+{
+return 0;
+}
+
+CLEAR(drv);
+snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
+drv.ifd_cmd = OVPN_GET_PEER_STATS;
+drv.ifd_len = sizeof(buf);
+drv.ifd_data = buf;
+
+ret = ioctl(dco->fd, SIOCGDRVSPEC, );
+if (ret)
+{
+msg(M_WARN | M_ERRNO, "Failed to get peer stats");
+return -EINVAL;
+}
+
+nvl = nvlist_unpack(buf, drv.ifd_len, 0);
+if (! nvl)
+{
+msg(M_WARN, "Failed to unpack nvlist");
+return -EINVAL;
+}
+
+if (! nvlist_exists_nvlist_array(nvl, "peers")) {
+/* no peers */
+return 0;
+}
+
+nvpeers = nvlist_get_nvlist_array(nvl, "peers", );
+for (size_t i = 0; i < npeers; i++)
+{
+const nvlist_t *peer = nvpeers[i];
+uint32_t peerid = nvlist_get_number(peer, "peerid");
+
+dco_update_peer_stat(m, peerid, nvlist_get_nvlist(peer, "bytes"));
+}
+
+return 0;
+}
+
 const char *
 dco_get_supported_ciphers()
 {
diff --git a/src/openvpn/dco_linux.c b/src/openvpn/dco_linux.c
index 10935820..0306cec3 100644
--- a/src/openvpn/dco_linux.c
+++ b/src/openvpn/dco_linux.c
@@ -911,6 +911,13 @@ nla_put_failure:
 return ret;
 }
 
+int
+dco_get_peer_stats(dco_context_t *dco, struct multi_context *m)
+{
+/* Not implemented. */
+return 0;
+}
+
 bool
 dco_available(int msglevel)
 {
diff --git a/src/openvpn/dco_win.c b/src/openvpn/dco_win.c
index 48a1755a..68ec931c 100644
--- a/src/openvpn/dco_win.c
+++ b/src/openvpn/dco_win.c
@@ -399,6 +399,13 @@ dco_do_write(dco_context_t *dco, int peer_id, struct 
buffer *buf)
 return 0;
 }
 
+int
+dco_get_peer_stats(dco_context_t *dco, struct multi_context *m)
+{
+/* Not implemented. */
+return 0;
+}
+
 void
 dco_event_set(dco_context_t *dco, struct event_set *es, void *arg)
 {
diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c
index 0a23c2bc..38da87b8 100644
--- a/src/openvpn/multi.c
+++ b/src/openvpn/multi.c
@@ -538,29 +538,31 @@ multi_del_iroutes(struct multi_context *m,
 }
 
 static void
-setenv_stats(struct context *c)
+setenv_stats(struct multi_context *m, struct context *c)
 {
-setenv_counter(c->c2.es, "bytes_received", c->c2.link_read_bytes);
-setenv_counter(c->c2.es, "bytes_sent", 

[Openvpn-devel] [PATCH 3/4] Read the peer deletion reason from the kernel

2022-12-05 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Recent FreeBSD kernels supply a reason for the OVPN_NOTIF_DEL_PEER
notification. Parse this from the nvlist so we can distinguish
user-requested removals from timeouts.

Signed-off-by: Kristof Provost 
---
 src/openvpn/dco_freebsd.c  | 13 +
 src/openvpn/ovpn_dco_freebsd.h |  5 +
 2 files changed, 18 insertions(+)

diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index 2ae46589..8d7ceb70 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -529,6 +529,19 @@ dco_do_read(dco_context_t *dco)
 {
 dco->dco_del_peer_reason = OVPN_DEL_PEER_REASON_EXPIRED;
 
+if (nvlist_exists_number(nvl, "del_reason"))
+{
+uint32_t reason = nvlist_get_number(nvl, "del_reason");
+if (reason == OVPN_DEL_REASON_TIMEOUT)
+{
+dco->dco_del_peer_reason = OVPN_DEL_PEER_REASON_EXPIRED;
+}
+else
+{
+dco->dco_del_peer_reason = OVPN_DEL_PEER_REASON_USERSPACE;
+}
+}
+
 if (nvlist_exists_nvlist(nvl, "bytes"))
 {
 const nvlist_t *bytes = nvlist_get_nvlist(nvl, "bytes");
diff --git a/src/openvpn/ovpn_dco_freebsd.h b/src/openvpn/ovpn_dco_freebsd.h
index cc90111e..fec33835 100644
--- a/src/openvpn/ovpn_dco_freebsd.h
+++ b/src/openvpn/ovpn_dco_freebsd.h
@@ -38,6 +38,11 @@ enum ovpn_notif_type {
 OVPN_NOTIF_DEL_PEER,
 };
 
+enum ovpn_del_reason {
+OVPN_DEL_REASON_REQUESTED   = 0,
+OVPN_DEL_REASON_TIMEOUT = 1
+};
+
 enum ovpn_key_slot {
 OVPN_KEY_SLOT_PRIMARY   = 0,
 OVPN_KEY_SLOT_SECONDARY = 1
-- 
2.38.1



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 4/4] dco: cleanup FreeBSD dco_do_read()

2022-12-05 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Remove support for reading packets through the control interface.
FreeBSD no longer does this, so there's no point in keeping the code for
it.

While here also check that we know what type of notification we're
getting. There's currently only one, but we should check anyway.

Signed-off-by: Kristof Provost 
---
 src/openvpn/dco_freebsd.c | 19 ---
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index 8d7ceb70..b6d869b0 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -489,8 +489,7 @@ dco_do_read(dco_context_t *dco)
 struct ifdrv drv;
 uint8_t buf[4096];
 nvlist_t *nvl;
-const uint8_t *pkt;
-size_t pktlen;
+enum ovpn_notif_type type;
 int ret;
 
 /* Flush any pending data from the pipe. */
@@ -518,15 +517,9 @@ dco_do_read(dco_context_t *dco)
 
 dco->dco_message_peer_id = nvlist_get_number(nvl, "peerid");
 
-if (nvlist_exists_binary(nvl, "packet"))
-{
-pkt = nvlist_get_binary(nvl, "packet", );
-memcpy(BPTR(>dco_packet_in), pkt, pktlen);
-dco->dco_packet_in.len = pktlen;
-dco->dco_message_type = OVPN_CMD_PACKET;
-}
-else
-{
+type = nvlist_get_number(nvl, "notification");
+switch (type) {
+case OVPN_NOTIF_DEL_PEER:
 dco->dco_del_peer_reason = OVPN_DEL_PEER_REASON_EXPIRED;
 
 if (nvlist_exists_number(nvl, "del_reason"))
@@ -551,6 +544,10 @@ dco_do_read(dco_context_t *dco)
 }
 
 dco->dco_message_type = OVPN_CMD_DEL_PEER;
+break;
+default:
+msg(M_WARN, "Unknown kernel notification %d", type);
+break;
 }
 
 nvlist_destroy(nvl);
-- 
2.38.1



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH]: FreeBSD DCO updates

2022-12-05 Thread Kristof Provost via Openvpn-devel
Hi,

This patch series is version two of the "Read DCO traffic stats from the
kernel" patch. This version should build for FreeBSD, Linux and Windows
now (although I've not tested Windows builds, because I lack Windows
machines).

It also adds the ability for DCO drivers to include counters in the peer
deletion notification.

It also includes extensions to read the reason a peer went away from the
kernel (which the FreeBSD kernel started including from
https://cgit.freebsd.org/src/commit/?id=da69782bf06645f38852a8b23afc965fc30d0e08)
Happily this will still work even when the kernel doesn't include that
data.

Finally there's a small cleanup patch to remove reading packets through
the ioctl interface.

If anyone wants to play around with the peer counters on FreeBSD you'll
also want these patches for FreeBSD:

 * https://reviews.freebsd.org/D37602 (not related, but required to have
   the next patches apply cleanly)
 * https://reviews.freebsd.org/D37603
 * https://reviews.freebsd.org/D37604
 * https://reviews.freebsd.org/D37605 (not related, but required to have
   the next one apply cleanly)
 * https://reviews.freebsd.org/D37606

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 2/4] dco: Update counters when a client disconnects

2022-12-05 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

When the kernel module (Linux or FreeBSD) notifies us that a peer has
disconnected we'd like to get a final count of the in/out bytes for that
peer.
We can't request that information any more, because the kernel has
already removed the peer at that point.

Have the kernel send that information as part of the "delete peer"
notification, and update the counters a final time.

This implements the FreeBSD-specific DCO code, but not the
Linux-specific code. It will simply add 0 to the count on Linux.

Signed-off-by: Kristof Provost 
---
 src/openvpn/dco_freebsd.c | 9 +
 src/openvpn/dco_freebsd.h | 2 ++
 src/openvpn/dco_linux.h   | 2 ++
 src/openvpn/multi.c   | 4 
 4 files changed, 17 insertions(+)

diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index 5b352859..2ae46589 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -528,6 +528,15 @@ dco_do_read(dco_context_t *dco)
 else
 {
 dco->dco_del_peer_reason = OVPN_DEL_PEER_REASON_EXPIRED;
+
+if (nvlist_exists_nvlist(nvl, "bytes"))
+{
+const nvlist_t *bytes = nvlist_get_nvlist(nvl, "bytes");
+
+dco->dco_read_bytes = nvlist_get_number(bytes, "in");
+dco->dco_write_bytes = nvlist_get_number(bytes, "out");
+}
+
 dco->dco_message_type = OVPN_CMD_DEL_PEER;
 }
 
diff --git a/src/openvpn/dco_freebsd.h b/src/openvpn/dco_freebsd.h
index 7de11697..0d059dda 100644
--- a/src/openvpn/dco_freebsd.h
+++ b/src/openvpn/dco_freebsd.h
@@ -55,6 +55,8 @@ typedef struct dco_context {
 int dco_message_type;
 int dco_message_peer_id;
 int dco_del_peer_reason;
+uint64_t dco_read_bytes;
+uint64_t dco_write_bytes;
 } dco_context_t;
 
 #endif /* defined(ENABLE_DCO) && defined(TARGET_FREEBSD) */
diff --git a/src/openvpn/dco_linux.h b/src/openvpn/dco_linux.h
index 416ea30a..7d56308b 100644
--- a/src/openvpn/dco_linux.h
+++ b/src/openvpn/dco_linux.h
@@ -53,6 +53,8 @@ typedef struct
 int dco_message_type;
 int dco_message_peer_id;
 int dco_del_peer_reason;
+uint64_t dco_read_bytes;
+uint64_t dco_write_bytes;
 } dco_context_t;
 
 #endif /* defined(ENABLE_DCO) && defined(TARGET_LINUX) */
diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c
index 38da87b8..74671303 100644
--- a/src/openvpn/multi.c
+++ b/src/openvpn/multi.c
@@ -3245,6 +3245,8 @@ process_incoming_del_peer(struct multi_context *m, struct 
multi_instance *mi,
  * installed, and we do not need to clean up the state in the kernel */
 mi->context.c2.tls_multi->dco_peer_id = -1;
 mi->context.sig->signal_text = reason;
+mi->context.c2.dco_read_bytes = dco->dco_read_bytes;
+mi->context.c2.dco_write_bytes = dco->dco_write_bytes;
 multi_signal_instance(m, mi, SIGTERM);
 }
 
@@ -3278,6 +3280,8 @@ multi_process_incoming_dco(struct multi_context *m)
 
 dco->dco_message_type = 0;
 dco->dco_message_peer_id = -1;
+dco->dco_read_bytes = 0;
+dco->dco_write_bytes = 0;
 return ret > 0;
 }
 #endif /* if defined(ENABLE_DCO) && defined(TARGET_LINUX) */
-- 
2.38.1



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] Read DCO traffic stats from the kernel

2022-11-27 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

When DCO is active userspace doesn't see all of the traffic, so when we
access these stats we must update them.

Retrieve kernel statistics every time we access the
link_(read|write)_bytes values.

Introduce a dco_(read|write)_bytes so that we don't clobber the existing
statistics, which still count control packets, sent or received directly
through the socket.
---
 src/openvpn/dco.h  |  8 
 src/openvpn/dco_freebsd.c  | 78 ++
 src/openvpn/multi.c| 30 +++--
 src/openvpn/openvpn.h  |  2 +
 src/openvpn/ovpn_dco_freebsd.h |  1 +
 5 files changed, 106 insertions(+), 13 deletions(-)

diff --git a/src/openvpn/dco.h b/src/openvpn/dco.h
index e051db06..e5d89358 100644
--- a/src/openvpn/dco.h
+++ b/src/openvpn/dco.h
@@ -225,6 +225,14 @@ void dco_install_iroute(struct multi_context *m, struct 
multi_instance *mi,
  */
 void dco_delete_iroutes(struct multi_context *m, struct multi_instance *mi);
 
+/**
+ * Update traffic statistics for all peers
+ *
+ * @param dco  DCO device context
+ * @param mthe server context
+ **/
+int dco_get_peer_stats(dco_context_t *dco, struct multi_context *m);
+
 /**
  * Retrieve the list of ciphers supported by the current platform
  *
diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index 4e03f52e..111c3fa7 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -37,6 +37,7 @@
 #include "dco.h"
 #include "tun.h"
 #include "crypto.h"
+#include "multi.h"
 #include "ssl_common.h"
 
 static nvlist_t *
@@ -639,6 +640,83 @@ dco_event_set(dco_context_t *dco, struct event_set *es, 
void *arg)
 nvlist_destroy(nvl);
 }
 
+static void
+dco_update_peer_stat(struct multi_context *m, uint32_t peerid, const nvlist_t 
*nvl)
+{
+struct hash_element *he;
+struct hash_iterator hi;
+
+hash_iterator_init(m->hash, );
+
+while ((he = hash_iterator_next()))
+{
+struct multi_instance *mi = (struct multi_instance *) he->value;
+
+if (mi->context.c2.tls_multi->peer_id != peerid)
+continue;
+
+mi->context.c2.dco_read_bytes = nvlist_get_number(nvl, "in");
+mi->context.c2.dco_write_bytes = nvlist_get_number(nvl, "out");
+
+return;
+}
+
+msg(M_INFO, "Peer %d returned by kernel, but not found locally", peerid);
+}
+
+int
+dco_get_peer_stats(dco_context_t *dco, struct multi_context *m)
+{
+
+struct ifdrv drv;
+uint8_t buf[4096];
+nvlist_t *nvl;
+const nvlist_t *const *nvpeers;
+size_t npeers;
+int ret;
+
+if (!dco || !dco->open)
+{
+return 0;
+}
+
+CLEAR(drv);
+snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
+drv.ifd_cmd = OVPN_GET_PEER_STATS;
+drv.ifd_len = sizeof(buf);
+drv.ifd_data = buf;
+
+ret = ioctl(dco->fd, SIOCGDRVSPEC, );
+if (ret)
+{
+msg(M_WARN | M_ERRNO, "Failed to get peer stats");
+return -EINVAL;
+}
+
+nvl = nvlist_unpack(buf, drv.ifd_len, 0);
+if (! nvl)
+{
+msg(M_WARN, "Failed to unpack nvlist");
+return -EINVAL;
+}
+
+if (! nvlist_exists_nvlist_array(nvl, "peers")) {
+/* no peers */
+return 0;
+}
+
+nvpeers = nvlist_get_nvlist_array(nvl, "peers", );
+for (size_t i = 0; i < npeers; i++)
+{
+const nvlist_t *peer = nvpeers[i];
+uint32_t peerid = nvlist_get_number(peer, "peerid");
+
+dco_update_peer_stat(m, peerid, nvlist_get_nvlist(peer, "bytes"));
+}
+
+return 0;
+}
+
 const char *
 dco_get_supported_ciphers()
 {
diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c
index b9b087e0..10a674c0 100644
--- a/src/openvpn/multi.c
+++ b/src/openvpn/multi.c
@@ -538,29 +538,31 @@ multi_del_iroutes(struct multi_context *m,
 }
 
 static void
-setenv_stats(struct context *c)
+setenv_stats(struct multi_context *m, struct context *c)
 {
-setenv_counter(c->c2.es, "bytes_received", c->c2.link_read_bytes);
-setenv_counter(c->c2.es, "bytes_sent", c->c2.link_write_bytes);
+dco_get_peer_stats(>top.c1.tuntap->dco, m);
+
+setenv_counter(c->c2.es, "bytes_received", c->c2.link_read_bytes + 
c->c2.dco_read_bytes);
+setenv_counter(c->c2.es, "bytes_sent", c->c2.link_write_bytes + 
c->c2.dco_write_bytes);
 }
 
 static void
-multi_client_disconnect_setenv(struct multi_instance *mi)
+multi_client_disconnect_setenv(struct multi_context *m, struct multi_instance 
*mi)
 {
 /* setenv client real IP address */
 setenv_trusted(mi->context.c2.es, get_link_socket_info(>context));
 
 /* setenv stats */
-setenv_stats(>context);
+setenv_stats(m, >context);
 
 /* setenv connection duration */
 setenv_long_long(mi->context.c2.es, "time_duration", now - mi->created);
 }
 
 static void
-multi_client_disconnect_script(struct multi_instance *mi)
+multi_client_disconnect_script(struct multi_context *m, struct multi_instance 
*mi)
 {
-multi_client_disconnect_setenv(mi);
+

[Openvpn-devel] [DRAFT]: packet counting for DCO

2022-11-27 Thread Kristof Provost via Openvpn-devel
Hi,

Here's an initial draft for how I'd approach getting traffic statistics
in DCO mode.
Userspace doesn't see all of the traffic, so we need to ask the kernel
too.

I've added new variables for the kernel numbers so that we can keep the
userspace numbers, for the control packets which go through the socket
directly (so not through the DCO driver).

This isn't intended to be a finished patch, rather it's intended to
serve as a basis for discussion.

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] dco: pass control packets through the socket on FreeBSD

2022-11-26 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

FreeBSD allows packets to be sent through the socket even when the
if_dco driver is active, so prefer that path.

Also remove the FreeBSD dco_do_write() implementation, as this function
will never be called any more on FreeBSD. Assert this.

Signed-off-by: Kristof Provost 
---
 src/openvpn/dco_freebsd.c | 33 -
 src/openvpn/forward.c |  7 +--
 2 files changed, 9 insertions(+), 31 deletions(-)

diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index 8e5ee436..4e03f52e 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -536,35 +536,10 @@ dco_do_read(dco_context_t *dco)
 int
 dco_do_write(dco_context_t *dco, int peer_id, struct buffer *buf)
 {
-struct ifdrv drv;
-nvlist_t *nvl;
-int ret;
-
-nvl = nvlist_create(0);
-
-nvlist_add_binary(nvl, "packet", BSTR(buf), BLEN(buf));
-nvlist_add_number(nvl, "peerid", peer_id);
-
-CLEAR(drv);
-snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
-drv.ifd_cmd = OVPN_SEND_PKT;
-drv.ifd_data = nvlist_pack(nvl, _len);
-
-ret = ioctl(dco->fd, SIOCSDRVSPEC, );
-if (ret)
-{
-msg(M_WARN | M_ERRNO, "Failed to send control packet");
-ret = -errno;
-}
-else
-{
-ret = BLEN(buf);
-}
-
-free(drv.ifd_data);
-nvlist_destroy(nvl);
-
-return ret;
+/* Control packets are passed through the socket, so this should never get
+ * called. See should_use_dco_socket(). */
+ASSERT(0);
+return -EINVAL;
 }
 
 bool
diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c
index 622be841..1dcaabd8 100644
--- a/src/openvpn/forward.c
+++ b/src/openvpn/forward.c
@@ -1635,20 +1635,23 @@ process_ip_header(struct context *c, unsigned int 
flags, struct buffer *buf)
 }
 }
 
-/* Linux-like DCO implementations pass the socket to the kernel and
+/* Linux DCO implementations pass the socket to the kernel and
  * disallow usage of it from userland, so (control) packets sent and
  * received by OpenVPN need to go through the DCO interface.
  *
  * Windows DCO needs control packets to be sent via the normal
  * standard Overlapped I/O.
  *
+ * FreeBSD DCO allows control packets to pass through the socket in both
+ * directions.
+ *
  * Hide that complexity (...especially if more platforms show up
  * in the future...) in a small inline function.
  */
 static inline bool
 should_use_dco_socket(struct link_socket_actual *actual)
 {
-#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
+#if defined(TARGET_LINUX)
 return actual->dco_installed;
 #else
 return false;
-- 
2.38.1



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] dco: pass control packets through the socket on FreeBSD

2022-11-25 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

FreeBSD allows packets to be sent through the socket even when the
if_dco driver is active, so prefer that path.

Also remove the FreeBSD dco_do_write() implementation, as this function
will never be called any more on FreeBSD. Assert this.

Signed-off-by: Kristof Provost 
---
 src/openvpn/dco_freebsd.c | 33 -
 src/openvpn/forward.c |  7 +--
 2 files changed, 9 insertions(+), 31 deletions(-)

diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index 8e5ee436..910f 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -536,35 +536,10 @@ dco_do_read(dco_context_t *dco)
 int
 dco_do_write(dco_context_t *dco, int peer_id, struct buffer *buf)
 {
-struct ifdrv drv;
-nvlist_t *nvl;
-int ret;
-
-nvl = nvlist_create(0);
-
-nvlist_add_binary(nvl, "packet", BSTR(buf), BLEN(buf));
-nvlist_add_number(nvl, "peerid", peer_id);
-
-CLEAR(drv);
-snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
-drv.ifd_cmd = OVPN_SEND_PKT;
-drv.ifd_data = nvlist_pack(nvl, _len);
-
-ret = ioctl(dco->fd, SIOCSDRVSPEC, );
-if (ret)
-{
-msg(M_WARN | M_ERRNO, "Failed to send control packet");
-ret = -errno;
-}
-else
-{
-ret = BLEN(buf);
-}
-
-free(drv.ifd_data);
-nvlist_destroy(nvl);
-
-return ret;
+/* Control packets are passed through the socket, so this should never get
+ * called. See should_use_dco_socket(). */
+assert(false);
+return -EINVAL;
 }
 
 bool
diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c
index 622be841..1dcaabd8 100644
--- a/src/openvpn/forward.c
+++ b/src/openvpn/forward.c
@@ -1635,20 +1635,23 @@ process_ip_header(struct context *c, unsigned int 
flags, struct buffer *buf)
 }
 }
 
-/* Linux-like DCO implementations pass the socket to the kernel and
+/* Linux DCO implementations pass the socket to the kernel and
  * disallow usage of it from userland, so (control) packets sent and
  * received by OpenVPN need to go through the DCO interface.
  *
  * Windows DCO needs control packets to be sent via the normal
  * standard Overlapped I/O.
  *
+ * FreeBSD DCO allows control packets to pass through the socket in both
+ * directions.
+ *
  * Hide that complexity (...especially if more platforms show up
  * in the future...) in a small inline function.
  */
 static inline bool
 should_use_dco_socket(struct link_socket_actual *actual)
 {
-#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
+#if defined(TARGET_LINUX)
 return actual->dco_installed;
 #else
 return false;
-- 
2.38.1



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH]: FreeBSD DCO can use the socket for control packets

2022-11-25 Thread Kristof Provost via Openvpn-devel
Hi,

The next e-mail has a patch to teach OpenVPN it can pass control packets
through the socket on FreeBSD. This patch does that, and also removes
the now unused dco_do_write() implementation.

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] FreeBSD DCO: support AES-192-GCM

2022-11-11 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

As of 2c58d0cb3bb3e3a5b714ffac940500efbe5303ca FreeBSD also allows
AES-192-GCM in DCO. Announce this support.

Signed-off-by: Kristof Provost 
---
 src/openvpn/dco_freebsd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index c8361028..8e5ee436 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -667,7 +667,7 @@ dco_event_set(dco_context_t *dco, struct event_set *es, 
void *arg)
 const char *
 dco_get_supported_ciphers()
 {
-return "none:AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305";
+return "none:AES-256-GCM:AES-192-GCM:AES-128-GCM:CHACHA20-POLY1305";
 }
 
 #endif /* defined(ENABLE_DCO) && defined(TARGET_FREEBSD) */
-- 
2.38.1



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH]: FreeBSD DCO supports AES-192-GCM

2022-11-11 Thread Kristof Provost via Openvpn-devel

On 11 Nov 2022, at 11:36, Arne Schwabe wrote:

Am 11.11.2022 um 11:20 schrieb Kristof Provost via Openvpn-devel:

Minor update, but FreeBSD's if_ovpn now also supports AES-192-GCM.
We may as well announce this support.


This seems to be missing the patch.

Git’s send-email sent it as a separate mail, which has turned up with 
a bit of a delay for me.

I’m hoping it’ll actually turn up for you too, but in the mean time:

From: Kristof Provost 

As of 2c58d0cb3bb3e3a5b714ffac940500efbe5303ca FreeBSD also allows
AES-192-GCM in DCO. Announce this support.

Signed-off-by: Kristof Provost 
---
 src/openvpn/dco_freebsd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index c8361028..8e5ee436 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
	@@ -667,7 +667,7 @@ dco_event_set(dco_context_t *dco, struct event_set 
*es, void *arg)

 const char *
 dco_get_supported_ciphers()
 {
-return "none:AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305";
	+return 
"none:AES-256-GCM:AES-192-GCM:AES-128-GCM:CHACHA20-POLY1305";

 }

 #endif /* defined(ENABLE_DCO) && defined(TARGET_FREEBSD) */
--
2.38.1


Best regards,
Kristof___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH]: FreeBSD DCO supports AES-192-GCM

2022-11-11 Thread Kristof Provost via Openvpn-devel
Minor update, but FreeBSD's if_ovpn now also supports AES-192-GCM. 
We may as well announce this support.

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH 1/2] FreeBSD: for topology subnet, put tun interface into IFF_BROADCAST mode

2022-10-17 Thread Kristof Provost via Openvpn-devel
Signed-off-by:  Kristof Provost 

On 12 Oct 2022, at 16:59, Gert Doering wrote:
> For reasons unknown, OpenVPN has always put FreeBSD tun(4) interfaces
> into point-to-point mode (IFF_POINTOPOINT), which means "local and
> remote address, no on-link subnet".
>
> "--topology subnet" was emulated by adding a subnet-route to the "remote"
> (which was just picking a free address from the subnet).
>
> This works well enough for classic tun(4) interfaces that have no
> next-hop resolution, and routes pointing to "that fake remote" only
> (because all routing is done inside OpenVPN and it does not matter how
> packets get there) - but for ovpn(4) interfaces, it breaks iroute setup,
> where the route next-hop must be an on-link address.
>
> Thus, change interface to IFF_BROADCAST mode, and get rid of all the
> special code needed to "fake" subnet mode.
>
> Tested with tun(4) and ovpn(4) on FreeBSD 14, client and server, and
> with tun(4) on FreeBSD 12 and 7.4
>
> To actually work with ovpn(4) / FreeBSD DCO, a followup patch for
> kernel ovpn(4) and OpenVPN dco_freebsd.c is needed.
>
> Signed-off-by: Gert Doering 
> ---
>  Changes.rst   |  5 +
>  src/openvpn/tun.c | 37 -
>  2 files changed, 17 insertions(+), 25 deletions(-)
>
> diff --git a/Changes.rst b/Changes.rst
> index df56f76a..0397cb94 100644
> --- a/Changes.rst
> +++ b/Changes.rst
> @@ -163,6 +163,11 @@ User-visible Changes
>  - :code:`link_mtu` parameter is removed from environment or replaced with 0 
> when scripts are
>called with parameters. This parameter is unreliable and no longer 
> internally calculated.
>
> +- FreeBSD tun interfaces with ``--topology subnet`` are now put into real
> +  subnet mode (IFF_BROADCAST instead of IFF_POINTOPOINT) - this might upset
> +  software that enumerates interfaces, looking for "broadcast capable?" and
> +  expecting certain results.  Normal uses should not see any difference.
> +
>  Overview of changes in 2.5
>  ==
>
> diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c
> index ddee49f9..a83ec9e6 100644
> --- a/src/openvpn/tun.c
> +++ b/src/openvpn/tun.c
> @@ -1479,43 +1479,23 @@ do_ifconfig_ipv4(struct tuntap *tt, const char 
> *ifname, int tun_mtu,
>
>  #elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
>
> -in_addr_t remote_end;   /* for "virtual" subnet topology */
> -
>  /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 
> 255.255.255.255 up */
> -if (tun)
> +if (tun)   /* point-to-point tun */
>  {
>  argv_printf(, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
>  IFCONFIG_PATH, ifname, ifconfig_local,
>  ifconfig_remote_netmask, tun_mtu);
>  }
> -else if (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET)
> -{
> -remote_end = create_arbitrary_remote( tt );
> -argv_printf(, "%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH,
> -ifname, ifconfig_local, print_in_addr_t(remote_end, 0, 
> ),
> -tun_mtu, ifconfig_remote_netmask);
> -}
> -else
> +else/* tun with topology subnet and tap mode (always subnet) 
> */
>  {
> -argv_printf(, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
> -ifname, ifconfig_local, ifconfig_remote_netmask, 
> tun_mtu);
> +int netbits = netmask_to_netbits2(tt->remote_netmask);
> +argv_printf(, "%s %s %s/%d mtu %d up", IFCONFIG_PATH,
> +ifname, ifconfig_local, netbits, tun_mtu );
>  }
>
>  argv_msg(M_INFO, );
>  openvpn_execve_check(, es, S_FATAL, "FreeBSD ifconfig failed");
>
> -/* Add a network route for the local tun interface */
> -if (!tun && tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET)
> -{
> -struct route_ipv4 r;
> -CLEAR(r);
> -r.flags = RT_DEFINED;
> -r.network = tt->local & tt->remote_netmask;
> -r.netmask = tt->remote_netmask;
> -r.gateway = remote_end;
> -add_route(, tt, 0, NULL, es, NULL);
> -}
> -
>  #elif defined(TARGET_AIX)
>  {
>  /* AIX ifconfig will complain if it can't find ODM path in env */
> @@ -2949,12 +2929,19 @@ open_tun(const char *dev, const char *dev_type, const 
> char *dev_node, struct tun
>
>  if (tt->fd >= 0 && tt->type == DEV_TYPE_TUN)
>  {
> +/* see "Interface Flags" in ifnet(9) */
>  int i = IFF_POINTOPOINT | IFF_MULTICAST;
> +if (tt->topology == TOP_SUBNET)
> +{
> +i = IFF_BROADCAST | IFF_MULTICAST;
> +}
>
>  if (ioctl(tt->fd, TUNSIFMODE, ) < 0)
>  {
>  msg(M_WARN | M_ERRNO, "ioctl(TUNSIFMODE)");
>  }
> +
> +/* multi_af mode for v4+v6, see "tun(4)" */
>  i = 1;
>  if (ioctl(tt->fd, TUNSIFHEAD, ) < 0)
>  {
> -- 
> 2.37.3
>
>
>
> 

Re: [Openvpn-devel] [PATCH 2/2] FreeBSD DCO: introduce real subnet mode

2022-10-17 Thread Kristof Provost via Openvpn-devel
Signed-off-by:  Kristof Provost 

On 12 Oct 2022, at 16:59, Gert Doering wrote:

> To be able to configure a FreeBSD interface to "subnet" mode
> (as opposed to point-to-point mode), it needs to have its
> if_iflags set to IFF_BROADCAST.  For tun(4) interface this is
> done with the TUNSIFMODE ioctl(), but this does not work for
> more modern interfaces like ovpn(4) which communicate over
> a common SIOCSDRVSPEC ioctl() that contains a "cmd" and a
> "parameter list".
>
> Introduce OVPN_SET_IFMODE cmd, add dco_set_ifmode() function
> to put kernel interface into IFF_BROADCAST or IFF_POINTOPOINT
> as needed.
>
> (This needs a kernel patch to add the OVPN_SET_IFMODE on the
> other side - with an older kernel, OpenVPN will just fail now)
>
> Signed-off-by: Gert Doering 
> ---
>  src/openvpn/dco_freebsd.c  | 36 ++
>  src/openvpn/ovpn_dco_freebsd.h |  1 +
>  2 files changed, 37 insertions(+)
>
> diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
> index c6da6ce3..8adbf7f1 100644
> --- a/src/openvpn/dco_freebsd.c
> +++ b/src/openvpn/dco_freebsd.c
> @@ -165,6 +165,34 @@ ovpn_dco_init(int mode, dco_context_t *dco)
>  return true;
>  }
>
> +static int
> +dco_set_ifmode(dco_context_t *dco, int ifmode)
> +{
> +struct ifdrv drv;
> +nvlist_t *nvl;
> +int ret;
> +
> +msg(M_INFO, "ifmode=%08x", ifmode);
> +nvl = nvlist_create(0);
> +nvlist_add_number(nvl, "ifmode", ifmode);
> +
> +CLEAR(drv);
> +snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
> +drv.ifd_cmd = OVPN_SET_IFMODE;
> +drv.ifd_data = nvlist_pack(nvl, _len);
> +
> +ret = ioctl(dco->fd, SIOCSDRVSPEC, );
> +if (ret)
> +{
> +msg(M_WARN | M_ERRNO, "Failed to set ifmode");
> +}
> +
> +free(drv.ifd_data);
> +nvlist_destroy(nvl);
> +
> +return ret;
> +}
> +
>  static int
>  create_interface(struct tuntap *tt, const char *dev)
>  {
> @@ -205,6 +233,14 @@ create_interface(struct tuntap *tt, const char *dev)
>  snprintf(tt->dco.ifname, IFNAMSIZ, "%s", ifr.ifr_data);
>  tt->actual_name = string_alloc(tt->dco.ifname, NULL);
>
> +/* see "Interface Flags" in ifnet(9) */
> +int i = IFF_POINTOPOINT | IFF_MULTICAST;
> +if (tt->topology == TOP_SUBNET)
> +{
> +i = IFF_BROADCAST | IFF_MULTICAST;
> +}
> +dco_set_ifmode(>dco, i);
> +
>  return 0;
>  }
>
> diff --git a/src/openvpn/ovpn_dco_freebsd.h b/src/openvpn/ovpn_dco_freebsd.h
> index 7ceec06e..cf92d597 100644
> --- a/src/openvpn/ovpn_dco_freebsd.h
> +++ b/src/openvpn/ovpn_dco_freebsd.h
> @@ -60,5 +60,6 @@ enum ovpn_key_cipher {
>  #define OVPN_SEND_PKT   _IO('D', 9)
>  #define OVPN_POLL_PKT   _IO('D', 10)
>  #define OVPN_GET_PKT_IO('D', 11)
> +#define OVPN_SET_IFMODE _IO('D', 12)
>
>  #endif /* ifndef _NET_IF_OVPN_H_ */
> -- 
> 2.37.3
>
>
>
> ___
> Openvpn-devel mailing list
> Openvpn-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/openvpn-devel


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] big packet loss with FreeBSD DCO

2022-09-12 Thread Kristof Provost via Openvpn-devel
On 12 Sep 2022, at 14:45, Gert Doering wrote:
> Hi,
>
> On Mon, Sep 12, 2022 at 02:09:52PM +0200, Gert Doering wrote:
>> So, observation suggests "it's happening inside the DCO module".  I'll
>> go instrument my kernel with printf()'s now... and will report if I find
>> anything useful.
>
> ok... so at the beginning of ovpn_transmit_to_peer(), I have
>
> ping -s 1460
> Sep 12 14:36:34 fbsd14 kernel: GERT: ovpn_transmit_to_peer, tunnel_len=1488
>
> ping -s 1461
> Sep 12 14:36:43 fbsd14 kernel: GERT: ovpn_transmit_to_peer, tunnel_len=1489
>
> -> check!
>
> ... and then there is code that deals with rounding up...?!
>
> --- snip --
> printf( "GERT: ovpn_transmit_to_peer, real_len=%d\n", (int) real_len );
>
> ovpn_hdr_len = sizeof(struct ovpn_wire_header);
> if (key->encrypt->cipher == OVPN_CIPHER_ALG_NONE)
> ovpn_hdr_len -= 16; /* No auth tag. */
> else {
> /* Round up the len to a multiple of our block size. */
> len = roundup2(real_len, AES_BLOCK_LEN);
>
> /* Now extend the mbuf. */
> m_append(m, len - real_len, EMPTY_BUFFER);
> }
>
> printf( "GERT: ovpn_transmit_to_peer, len=%d\n", (int) len );
> --- snip --
>
> and after this block:
>
> Sep 12 14:40:40 fbsd14 kernel: GERT: ovpn_transmit_to_peer, tunnel_len=1489
> Sep 12 14:40:40 fbsd14 kernel: GERT: ovpn_transmit_to_peer, real_len=1489
> Sep 12 14:40:40 fbsd14 kernel: GERT: ovpn_transmit_to_peer, len=1504
>
> Wohoo, 1504!  +16!
>
>
> Now, I have no idea about crypto, *and* I have no idea about OpenVPN
> wire format (Arne is the resident expert on this), but Arne tells me
> "there is no padding needed"
>
> 14:00 <@cron2__> is there padding with AES-GCM?
> 14:04 <@plaisthos> cron2__: no. AES-GCM is basically CTR and a stream cipher
>
> ... so, not sure what that code does.
>
> If I just kill it :-)
>
> /* Round up the len to a multiple of our block size. */
> // len = roundup2(real_len, AES_BLOCK_LEN);
>
> I can ping just fine...
>
> gert@fbsd14:/usr/obj $ SU ping -s 1461 10.194.0.1
> PING 10.194.0.1 (10.194.0.1): 1461 data bytes
> 1469 bytes from 10.194.0.1: icmp_seq=0 ttl=64 time=124.774 ms
> 1469 bytes from 10.194.0.1: icmp_seq=1 ttl=64 time=124.930 ms
>
> and with double fragmentation too...
>
> gert@fbsd14:/usr/obj $ SU ping -s 3000 10.194.0.1
> PING 10.194.0.1 (10.194.0.1): 3000 data bytes
> 3008 bytes from 10.194.0.1: icmp_seq=0 ttl=64 time=126.363 ms
> 3008 bytes from 10.194.0.1: icmp_seq=1 ttl=64 time=126.642 ms
> 3008 bytes from 10.194.0.1: icmp_seq=2 ttl=64 time=126.200 ms
>
>
> Now, I'm not submitting a patch for that, because usually there is
> a good reason for rounding up and doing blocks and all that - so, I
> found the offending lines, but do not feel qualified for a correct
> fix.
>
The offending code is almost certainly wrong.
I know the guy who wrote them and … he means well ;)

I think I was confused about what was needed in packet size. I’ll try to test 
your patch in the next couple of days.

Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] more crashes with FreeBSD DCO...

2022-09-12 Thread Kristof Provost via Openvpn-devel
On 12 Sep 2022, at 14:36, Gert Doering wrote:
> On Mon, Sep 12, 2022 at 02:27:57PM +0200, Gert Doering wrote:
>> trying to load my newly-instrumented if_ovpn.ko, I kldunload'ed the
>> existing one - without shutting down *all* OpenVPN instances first.
>>
>> *Boom*...
>>
>> Console attached.
>
> Ah, nice, dmesg has all the info in text format, no need to send PNGs
> to the list :-)
>
>
>  snip 
> ovpn3: changing name to 'tun11'
> tun8: link state changed to DOWN
> ovpn4: changing name to 'tun4'
> tun4: link state changed to UP
> tun4: promiscuous mode enabled
>
> Warning: memory type ovpn leaked memory on destroy (1 allocations, 2048 bytes 
> leaked).
>
>
> Fatal trap 12: page fault while in kernel mode
> cpuid = 3; apic id = 06
> fault virtual address   = 0x82f81d70
> fault code  = supervisor read instruction, page not present
> instruction pointer = 0x20:0x82f81d70
> stack pointer   = 0x28:0xfe000859edf8
> frame pointer   = 0x28:0xfe000859ee40
> code segment= base 0x0, limit 0xf, type 0x1b
> = DPL 0, pres 1, long 1, def32 0, gran 1
> processor eflags= interrupt enabled, resume, IOPL = 0
> current process = 0 (softirq_3)
> trap number = 12
> panic: page fault
> cpuid = 3
> time = 1662985342
> KDB: stack backtrace:
> db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfe000859ebb0
> vpanic() at vpanic+0x151/frame 0xfe000859ec00
> panic() at panic+0x43/frame 0xfe000859ec60
> trap_fatal() at trap_fatal+0x387/frame 0xfe000859ecc0
> trap_pfault() at trap_pfault+0xab/frame 0xfe000859ed20
> calltrap() at calltrap+0x8/frame 0xfe000859ed20
> --- trap 0xc, rip = 0x82f81d70, rsp = 0xfe000859edf8, rbp = 
> 0xfe000859ee40 ---
> __stop_set_sysinit_set() at __stop_set_sysinit_set+0x5350/frame 
> 0xfe000859ee40
> gtaskqueue_run_locked() at gtaskqueue_run_locked+0xa7/frame 0xfe000859eec0
> gtaskqueue_thread_loop() at gtaskqueue_thread_loop+0xc2/frame 
> 0xfe000859eef0
> fork_exit() at fork_exit+0x80/frame 0xfe000859ef30
> fork_trampoline() at fork_trampoline+0xe/frame 0xfe000859ef30
> --- trap 0, rip = 0, rsp = 0, rbp = 0 ---
> KDB: enter: panic
> ---<>---
>
I can reproduce the memory leak, but not the panic. I’m also entirely unclear 
how if_ovpn would trigger anything in gtaskqueue*. It doesn’t use any task 
queues, only callouts (for pings and idle timeout).

Can you reproduce the panic?

Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] big packet loss with FreeBSD DCO

2022-09-12 Thread Kristof Provost via Openvpn-devel
On 12 Sep 2022, at 14:09, Gert Doering wrote:
> it *does* bump the outside packet length up by +16 bytes ("bad length 1512" ->
> "1528").  Smells cipher algorithm padding or so - but why 16?  And why pad
> at all (AES-256-GCM used, so I think we should not pad)?
>
I would still expect padding. AES will operate on 16 byte blocks, so no matter 
the block chaining mode we’re going to have that multiple-of-16-bytes thing.

> Sep 12 08:01:59 phillip tun-udp-p2mp[52730]: 
> freebsd-14-amd64/194.97.140.5:14894 tun packet too large on write 
> (tried=1504,max=1500)
>
> this is the "I have received a packet from the network, decrypted it, and
> tried to send it onwards towards the tun interface, and it was too large".
>
> So my guess is that "something" gets confused on the sending side DCO, and
> corrupts the payload size (-> so '-s 1461' becomes '-s 1476' = 16 byte
> increase instead of +1, resulting in 'ip packet size 1504' on the receiving
> end).  The t_client server is running a slightly older master, which
> enforces the "mtu is 1500, so no bigger packets", newer openvpn are
> are somewhat more permissive on incoming baby giants.
>
That’s very interesting information. You may be closing in on the cause.
What version do you run on the t_client server? Perhaps that will help me to 
reproduce it.

> So, observation suggests "it's happening inside the DCO module".  I'll
> go instrument my kernel with printf()'s now... and will report if I find
> anything useful.
>
Thanks!

I’m on my way to Vienna for EuroBSDCon now, so I will be distracted until early 
next week, but when I’m back I should be able to dig into this as well.

Best regards,
Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] Adjust Linux+FreeBSD DCO device name handling to 'non DCO linux style'

2022-08-30 Thread Kristof Provost via Openvpn-devel
On 29 Aug 2022, at 21:01, Gert Doering wrote:
> On Linux, tun devices are created according to the following algorithm
>   --dev tun-> try tun0, tun1, ... tun255, use first free
>   --dev anything -> create a TUN device named "anything"
> (as long as "anything" is not "null" or "tap[N]")
>
> DCO was following the "other platform convention", where everything
> not having a digit was iterated ("--dev tun-home" -> "tun-home0") -
> which does not work for classic tun/tap devices on the BSDs anyway,
> so is not the best model.
>
> Adjust open_tun_dco_generic() to document expected behaviour and
> do the thing.
>
> Signed-off-by: Gert Doering 
Acked-by: Kristof Provost 


Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] DCO: require valid netbits setting for non-primary iroutes.

2022-08-23 Thread Kristof Provost via Openvpn-devel
On 20 Aug 2022, at 16:01, Gert Doering wrote:
> The existing DCO code had extra logic for "if this is not
> MR_WITH_NETBITS, set 32/128 as address length", but only for
> iroute addition.  For iroute deletion, this was missing, and
> subsequently iroute deletion for IPv4 host routes failed on
> FreeBSD DCO (commit 3433577a99).
>
> Iroute handling differenciates between "primary" iroutes (coming
> from anm IP pool or ccd/ifconfig-push), and "non-primary" iroutes,
> coming from --iroute and --iroute-ipv6 statements in per-client config.
>
> "Primary" iroutes always use "-1" for their netbits, but since these
> are not installed via DCO, this is of no concern here.  Whether these
> can and should be changed needs further study on internal route
> learning and cleanup.
>
> Refactor options.c and multi.c to ensure that netbits is always set
> for non-primary iroutes - and ASSERT() on this in the DCO path, so we can
> find out if there might be other code violating this.
>
> Change options.c::option_iroute() to always set netbits=32 for IPv4
> host routes (options_iroute_ipv6() never differenciated).  Since
> netmask_to_netbits() also insists on "-1" for host routes, change
> to netmask_to_netbits2().
>
> Remove all the extra MR_WITH_NETBITS logic from dco.c, where it should
> have never appeared.
>
> Signed-off-by: Gert Doering 

Seems sane to me. Passes the FreeBSD automated tests.
Minor style nitpicks below.

Acked-by: Kristof Provost 

> diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c
> index 95414429..1f9d0201 100644
> --- a/src/openvpn/multi.c
> +++ b/src/openvpn/multi.c
> @@ -1241,6 +1241,7 @@ multi_learn_in_addr_t(struct multi_context *m,
>  /* "primary" is the VPN ifconfig address of the peer and already
>   * known to DCO, so only install "extra" iroutes (primary = false)
>   */
> +ASSERT(netbits>=0);  /* DCO requires populated netbits */
I’d put spaces around the comparison, so ‘ASSERT(netbits >= 0);’. That seems to 
be what’s done in all conditionals anyway.

> diff --git a/src/openvpn/options.c b/src/openvpn/options.c
> index 2b0bb20c..21e2f69b 100644
> --- a/src/openvpn/options.c
> +++ b/src/openvpn/options.c
> @@ -1572,12 +1572,14 @@ option_iroute(struct options *o,
>
>  ALLOC_OBJ_GC(ir, struct iroute, >gc);
>  ir->network = getaddr(GETADDR_HOST_ORDER, network_str, 0, NULL, NULL);
> -ir->netbits = -1;
> +ir->netbits = 32;/* host route if no netmask given */
>
>  if (netmask_str)
>  {
>  const in_addr_t netmask = getaddr(GETADDR_HOST_ORDER, netmask_str, 
> 0, NULL, NULL);
> -if (!netmask_to_netbits(ir->network, netmask, >netbits))
> +ir->netbits = netmask_to_netbits2(netmask);
> +
> +if (ir->netbits<0)
And here too. So ‘if (ir->netbits < 0)’

>  {
>  msg(msglevel, "in --iroute %s %s : Bad network/subnet 
> specification",
>  network_str,

Regards,
Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH]: FreeBSD networking cleanup

2022-08-22 Thread Kristof Provost via Openvpn-devel
I’ll post a patch.

>  - any particular reason you used argv_printf() + argv_printf_cat(),
>instead of just putting all into a single argv_printf() call?
>
Mostly that that’s what src/openvpn/networking_iproute2.c does too.  I
don’t have particularly strong feelings either way, so I’ll add that to
the upcoming patch.

>  - the "openvpn_execve_check()" messages state "route *add* command failed",
>while it could be "del" as well.  Making this "proper" might not be
>worth it, as it would need string manipulation (or "duplicate whole
>message").
>
It might be nice to turn openvpn_execve_check() into a variadic function
so we could do this:

status = openvpn_execve_check(, NULL, 0,
  "ERROR: FreeBSD route %s command failed”, op);

But I think I’ll just remove the ‘add’, which makes the error message
make sense for both add and del.

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] FreeBSD networking cleanup

2022-08-22 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Address a few minor code review remarks:

 - use constants for the inet_ntop() buffers
 - replace argv_printf() + argv_printf_cat() with a single argv_printf()
 - net_route_v4/6 both add and remove, so adjust the error message to
   reflect that.

Signed-off-by: Kristof Provost 
---
 src/openvpn/networking_freebsd.c | 34 +++-
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/src/openvpn/networking_freebsd.c b/src/openvpn/networking_freebsd.c
index 5fcb738e..0633dce7 100644
--- a/src/openvpn/networking_freebsd.c
+++ b/src/openvpn/networking_freebsd.c
@@ -15,7 +15,7 @@ net_route_v4(const char *op, const in_addr_t *dst, int 
prefixlen,
  const in_addr_t *gw, const char *iface, uint32_t table,
  int metric)
 {
-char buf1[16], buf2[16];
+char buf1[INET_ADDRSTRLEN], buf2[INET_ADDRSTRLEN];
 in_addr_t _dst, _gw;
 struct argv argv = argv_new();
 bool status;
@@ -23,17 +23,16 @@ net_route_v4(const char *op, const in_addr_t *dst, int 
prefixlen,
 _dst = ntohl(*dst);
 _gw = ntohl(*gw);
 
-argv_printf(, "%s %s",
-ROUTE_PATH, op);
-argv_printf_cat(, "-net %s/%d %s -fib %d",
-inet_ntop(AF_INET, &_dst, buf1, sizeof(buf1)),
-prefixlen,
-inet_ntop(AF_INET, &_gw, buf2, sizeof(buf2)),
-table);
+argv_printf(, "%s %s -net %s/%d %s -fib %d",
+ROUTE_PATH, op,
+inet_ntop(AF_INET, &_dst, buf1, sizeof(buf1)),
+prefixlen,
+inet_ntop(AF_INET, &_gw, buf2, sizeof(buf2)),
+table);
 
 argv_msg(M_INFO, );
 status = openvpn_execve_check(, NULL, 0,
-  "ERROR: FreeBSD route add command failed");
+  "ERROR: FreeBSD route command failed");
 
 argv_free();
 
@@ -45,21 +44,20 @@ net_route_v6(const char *op, const struct in6_addr *dst,
  int prefixlen, const struct in6_addr *gw, const char *iface,
  uint32_t table, int metric)
 {
-char buf1[64], buf2[64];
+char buf1[INET6_ADDRSTRLEN], buf2[INET6_ADDRSTRLEN];
 struct argv argv = argv_new();
 bool status;
 
-argv_printf(, "%s -6 %s",
-ROUTE_PATH, op);
-argv_printf_cat(, "-net %s/%d %s -fib %d",
-inet_ntop(AF_INET6, dst, buf1, sizeof(buf1)),
-prefixlen,
-inet_ntop(AF_INET6, gw, buf2, sizeof(buf2)),
-table);
+argv_printf(, "%s -6 %s -net %s/%d %s -fib %d",
+ROUTE_PATH, op,
+inet_ntop(AF_INET6, dst, buf1, sizeof(buf1)),
+prefixlen,
+inet_ntop(AF_INET6, gw, buf2, sizeof(buf2)),
+table);
 
 argv_msg(M_INFO, );
 status = openvpn_execve_check(, NULL, 0,
-  "ERROR: FreeBSD route add command failed");
+  "ERROR: FreeBSD route command failed");
 
 argv_free();
 
-- 
2.37.2



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] FreeBSD-DCO: repair device iteration to find first free interface.

2022-08-20 Thread Kristof Provost via Openvpn-devel
Acked-by: Kristof Provost 

Thanks!

Kristof

On 19 Aug 2022, at 20:24, Gert Doering wrote:
> During review/update phase, FreeBSD/DCO's ability to find the first
> free tun interface on "--dev tun" got broken, due to two issues:
>
>  - create_interface() called msg(M_ERR|...), which is a fatal error
>and aborts OpenVPN, so "no retry with 'tun1' after 'tun0' failed"
>
>Change to M_WARN|M_ERRNO (= warning level, add strerror(errno), return).
>
>  - open_tun_dco_generic() expects "-errno" as return value of
>open_tun_dco(), and breaks the loop on -EPERM.  create_interface()
>was returning "-1" instead (ioctl() error signalling), which happens
>to be "-EPERM" on FreeBSD.
>
>Change create_interface() to return -errno.
>
> While at it, remove logging of errors from dco_freebsd.c::open_tun_dco()
> (because all errors from create_interface() would be already logged there),
> reducing open_tun_dco() to just a wrapper around create_interface().
>
> Signed-off-by: Gert Doering 
> ---
>  src/openvpn/dco_freebsd.c | 17 +
>  1 file changed, 5 insertions(+), 12 deletions(-)
>
> diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
> index 06b4d6a9..c6da6ce3 100644
> --- a/src/openvpn/dco_freebsd.c
> +++ b/src/openvpn/dco_freebsd.c
> @@ -178,7 +178,8 @@ create_interface(struct tuntap *tt, const char *dev)
>  ret = ioctl(tt->dco.fd, SIOCIFCREATE2, );
>  if (ret)
>  {
> -msg(M_ERR | M_ERRNO, "Failed to create interface %s", ifr.ifr_name);
> +ret = -errno;
> +msg(M_WARN|M_ERRNO, "Failed to create interface %s (SIOCIFCREATE2)", 
> ifr.ifr_name);
>  return ret;
>  }
>
> @@ -194,9 +195,10 @@ create_interface(struct tuntap *tt, const char *dev)
>  ret = ioctl(tt->dco.fd, SIOCSIFNAME, );
>  if (ret)
>  {
> +ret = -errno;
>  /* Delete the created interface again. */
>  (void)ioctl(tt->dco.fd, SIOCIFDESTROY, );
> -msg(M_ERR | M_ERRNO, "Failed to create interface %s", ifr.ifr_data);
> +msg(M_WARN|M_ERRNO, "Failed to create interface %s (SIOCSIFNAME)", 
> ifr.ifr_data);
>  return ret;
>  }
>
> @@ -229,16 +231,7 @@ remove_interface(struct tuntap *tt)
>  int
>  open_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx, const char *dev)
>  {
> -int ret;
> -
> -ret = create_interface(tt, dev);
> -
> -if (ret < 0)
> -{
> -msg(M_ERR, "Failed to create interface");
> -}
> -
> -return ret;
> +return create_interface(tt, dev);
>  }
>
>  void
> -- 
> 2.37.1


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH 1/2] ovpn-dco: introduce FreeBSD data-channel offload support

2022-08-13 Thread Kristof Provost via Openvpn-devel
On 11 Aug 2022, at 23:11, Gert Doering wrote:
> If you're interested, I can unicast you the full file I use for
> my DCO client tests, with different ciphers, some instances with
> compression (= does it properly fall back?), some with http/socks
> proxy, etc., plus a set of client+ca certificates to run against
> our test server.
>
That’d be useful, yes. I’ve not yet been able to get the tests to run the way 
they’re supposed to.

Best regards,
Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH 1/2] ovpn-dco: introduce FreeBSD data-channel offload support

2022-08-13 Thread Kristof Provost via Openvpn-devel
On 13 Aug 2022, at 10:10, Gert Doering wrote:
> On Thu, Aug 11, 2022 at 05:25:05PM +0200, Kristof Provost via Openvpn-devel 
> wrote:
>>>  - running openvpn over TCP gives me a kernel panic - this is not so
>>>nice... (see attached .png from the vmware console) - userland seems
>>>to assume "kernel can do TCP", kernel panics on "if !udp, panic()"
>>>(so intentional panic, not corruption panic).
>>>
>>>This is on freebsd git FreeBSD 14.0-CURRENT #1 main-n257130-c0665d5c824
>>>
>> I???ve pushed a fix for this panic in 
>> fd6b3bede5a5c210f327e5c9bd3e415ee905048b.
>> I simply didn???t think that user space might give us a non-UDP
>> socket, so checking for that and rejecting the peer in that case
>> fixes the panic. Thanks for finding that.
>
> JFTR, I have tested "main-n257320-3a3af6b2a16" with the old DCO userland
> patch, and it no longer crashes.  Of course the TCP tests failed, because
> userland only sees "mmmh, it fails!" but has no idea it should fall back
> to non-DCO  (with the new userland patches, this works).
>
Thanks!

> In case you plan to include kernel TCP support, it would be good to
> have this "soonish" - like, before FreeBSD 14 and OpenVPN 2.6.0 release,
> because otherwise this will be a bit painful to synchronize.
>
There’s not plan to add TCP support at the moment.

Best regards,
Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH 1/2] ovpn-dco: introduce FreeBSD data-channel offload support

2022-08-12 Thread Kristof Provost via Openvpn-devel
Remarks inline. Mostly ACK.

I’ll post an updated version soon. (I’ve also added a check for UDP in 
dco_check_option_conflict_ce().

On 10 Aug 2022, at 18:32, Gert Doering wrote:
> On Mon, Aug 08, 2022 at 04:34:23PM +0200, Kristof Provost via Openvpn-devel 
> wrote:
>> diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
>> new file mode 100644
>> index ..a8a53fe3
>> --- /dev/null
>> +++ b/src/openvpn/dco_freebsd.c
>> @@ -0,0 +1,636 @@
> [..]
>> +static nvlist_t *
>> +sockaddr_to_nvlist(const struct sockaddr *sa)
>> +{
> [..]
>> +default:
>> +abort();
>
> please use "ASSERT(0);" here.  It will do the same thing, but if ever
> hit, it will print a __FILE__, __LINE__ message to the log, so it's
> easier for us to see *where* it triggered a "this must never happen"
> condition.
>
Fixed.

>> +int
>> +dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
>> + struct sockaddr *localaddr, struct sockaddr *remoteaddr,
>> + struct in_addr *remote_in4, struct in6_addr *remote_in6)
>> +{
>> +struct ifdrv drv;
>> +nvlist_t *nvl;
>> +int ret;
>> +
>> +nvl = nvlist_create(0);
>
> We use C99 these days, so this could be written as
>
>> +nvlist_t *nvl = nvlist_create(0);
>
> but this is a matter of personal preference.  Both are fine, just wanted
> to point out that the option exists.
>
That’s FreeBSD’s style(9) showing here. If it’s acceptable to OpenVPN I’m just 
going to keep it as-is.

>> +
>> +nvlist_add_number(nvl, "fd", sd);
>> +nvlist_add_number(nvl, "peerid", peerid);
>> +
>> +bzero(, sizeof(drv));
>> +snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
>> +drv.ifd_cmd = OVPN_NEW_PEER;
>> +drv.ifd_data = nvlist_pack(nvl, _len);
>> +
>> +ret = ioctl(dco->fd, SIOCSDRVSPEC, );
>> +free(drv.ifd_data);
>
> What happens should nvlist_pack() fail here?  Manpage says it returns
> NULL, will the ioctl() handle this gracefully, or will something crash?
>
That’d really only happen if a memory allocation fails, and given modern OS’s 
overcommit behaviour that’s also not going to happen. (If you manage to run the 
system out of memory malloc() will still give you virtual memory, but the OOM 
killer will come to visit when you get around to actually using it.)

> (If the ioctl() returns something like EINVAL in this case, perfectly fine)
>
The copyin() in the kernel will fail, and that’d return an error, without 
crashing things.
So, yes, that’s what’d happen.

>> +nvlist_destroy(nvl);
>> +if (ret)
>> +{
>> +msg(D_DCO, "Failed to create new peer %d", errno);
>> +return ret;
>> +}
>> +
>> +return 0;
>> +}
>
> Most functions in OpenVPN that do use a "ret" variable would look
> more like this:
>
>> +if (ret)
>> +{
>> +msg(D_DCO, "Failed to create new peer %d", errno);
>> +}
>> +
>> +return ret;
>> +}
>
> we do have all sorts of variants (*sigh*), but since you also used both
> versions, let's go for this one.
>
Fixed.

>> +msg(D_DCO, "Failed to create new peer %d", errno);
>
> this can be written as
>
>> +msg(D_DCO|M_ERRNO, "Failed to create new peer");
>
> M_ERRNO will automatically append the strerror(errno) stuff.
>
Oh neat. I’ve made that change.

> D_DCO is "--verb 3", so that message won't be visible in normal operation
> - if we consider this an error, then it should be
>
>> +msg(M_WARN|M_ERRNO, "Failed to create new peer");
>
> instead (or if it's "fatal error, give up" -> M_ERR).
>
These are generally fatal errors, yes.
There are follow-up error messages from the calling code that do get logged, 
but they’re usually less clear about what the actual problem is. I’ll see about 
changing D_DCO -> M_ERR or M_WARN.

> Now, I'm not sure if accessing errno after the free() call is guaranteed
> to be save - so maybe move the msg() call up?
>
I’m pretty sure free() doesn’t mess with errno (as in, I’ve looked at the 
jemalloc code), but it’s better to not have to check.
Happily, thanks to your earlier suggestion it’s much easier to just move the 
free after the log, so I’ll do that.

>> +bool
>> +ovpn_dco_init(int mode, dco_context_t *dco)
>> +{
>> +if (open_fd(dco) < 0)
>> +{
>> +msg(D_DCO, "Failed to open socket");
>
> Same here - if you want this to be heard, D

[Openvpn-devel] [PATCHv2]: FreeBSD DCO support

2022-08-12 Thread Kristof Provost via Openvpn-devel
Hi,

Here's the updated version of the FreeBSD DCO patch. It should address
all remarks on the userspace side of things.

I'm still trying to reproduce the fragmentation issue. I've gotten
Gert's additional information, but I've not yet been able to act on it.
I'm fairly certain that any bug is going to be on the kernel side, so
it makes sense to me to continue these changes while I dig into that.

Best regards,
Kristof



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 1/2] ovpn-dco: introduce FreeBSD data-channel offload support

2022-08-12 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Implement data-channel offload for FreeBSD. The implementation and flow
is very similar to that of the Linux DCO support.

Signed-off-by: Kristof Provost 
---
 configure.ac   |   5 +
 src/openvpn/Makefile.am|   1 +
 src/openvpn/dco.c  |   8 +
 src/openvpn/dco_freebsd.c  | 645 +
 src/openvpn/dco_freebsd.h  |  59 +++
 src/openvpn/dco_internal.h |   1 +
 src/openvpn/forward.c  |   8 +-
 src/openvpn/mtcp.c |   4 +-
 src/openvpn/mudp.c |   2 +-
 src/openvpn/multi.c|   4 +-
 src/openvpn/options.c  |   8 +-
 src/openvpn/options.h  |   4 +-
 src/openvpn/ovpn_dco_freebsd.h |  64 
 src/openvpn/tun.c  |  39 +-
 src/openvpn/tun.h  |   6 +
 15 files changed, 827 insertions(+), 31 deletions(-)
 create mode 100644 src/openvpn/dco_freebsd.c
 create mode 100644 src/openvpn/dco_freebsd.h
 create mode 100644 src/openvpn/ovpn_dco_freebsd.h

diff --git a/configure.ac b/configure.ac
index 9466fe15..f715b404 100644
--- a/configure.ac
+++ b/configure.ac
@@ -787,6 +787,11 @@ dnl
AC_DEFINE(ENABLE_DCO, 1, [Enable shared data channel 
offload])
AC_MSG_NOTICE([Enabled ovpn-dco support for Linux])
;;
+   *-*-freebsd*)
+   LIBS="${LIBS} -lnv"
+   AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
for FreeBSD])
+   AC_MSG_NOTICE([Enabled ovpn-dco support for FreeBSD])
+   ;;
*)
AC_MSG_NOTICE([Ignoring --enable-dco on non Linux 
platform])
;;
diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index aaa1dbce..2a139b23 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -54,6 +54,7 @@ openvpn_SOURCES = \
crypto_openssl.c crypto_openssl.h \
crypto_mbedtls.c crypto_mbedtls.h \
dco.c dco.h dco_internal.h \
+   dco_freebsd.c dco_freebsd.h \
dco_linux.c dco_linux.h \
dhcp.c dhcp.h \
dns.c dns.h \
diff --git a/src/openvpn/dco.c b/src/openvpn/dco.c
index 4f40255e..07dc1087 100644
--- a/src/openvpn/dco.c
+++ b/src/openvpn/dco.c
@@ -271,6 +271,14 @@ dco_check_option_conflict_ce(const struct connection_entry 
*ce, int msglevel)
 return false;
 }
 
+#if defined(TARGET_FREEBSD)
+if (! proto_is_udp(ce->proto))
+{
+msg(msglevel, "TCP is not supported.");
+return false;
+}
+#endif
+
 return true;
 }
 
diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
new file mode 100644
index ..06b4d6a9
--- /dev/null
+++ b/src/openvpn/dco_freebsd.c
@@ -0,0 +1,645 @@
+/*
+ *  Interface to FreeBSD dco networking code
+ *
+ *  Copyright (C) 2022 Rubicon Communications, LLC (Netgate). All Rights 
Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#if defined(ENABLE_DCO) && defined(TARGET_FREEBSD)
+
+#include "syshead.h"
+
+#include 
+#include 
+#include 
+#include 
+
+#include "dco_freebsd.h"
+#include "dco.h"
+#include "tun.h"
+#include "crypto.h"
+#include "ssl_common.h"
+
+static nvlist_t *
+sockaddr_to_nvlist(const struct sockaddr *sa)
+{
+nvlist_t *nvl = nvlist_create(0);
+
+nvlist_add_number(nvl, "af", sa->sa_family);
+
+switch (sa->sa_family)
+{
+case AF_INET:
+{
+const struct sockaddr_in *in = (const struct sockaddr_in *)sa;
+nvlist_add_binary(nvl, "address", >sin_addr, 
sizeof(in->sin_addr));
+nvlist_add_number(nvl, "port", in->sin_port);
+break;
+}
+
+case AF_INET6:
+{
+const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *)sa;
+nvlist_add_binary(nvl, "address", >sin6_addr, 
sizeof(in6->sin6_addr));
+nvlist_add_number(nvl, "port", in6->sin6_port);
+break;
+}
+
+default:
+ASSERT(0);
+}
+
+return (nvl);
+}
+
+int
+dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
+ struct sockaddr *localaddr, 

[Openvpn-devel] [PATCH 2/2] Support creating iroute route entries on FreeBSD

2022-08-12 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Signed-off-by: Kristof Provost 
---
 src/openvpn/Makefile.am  |   1 +
 src/openvpn/dco.c|   8 +--
 src/openvpn/dco_freebsd.h|   2 +
 src/openvpn/networking.h |   9 +++
 src/openvpn/networking_freebsd.c | 101 +++
 5 files changed, 117 insertions(+), 4 deletions(-)
 create mode 100644 src/openvpn/networking_freebsd.c

diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 2a139b23..5155a180 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -88,6 +88,7 @@ openvpn_SOURCES = \
mtu.c mtu.h \
mudp.c mudp.h \
multi.c multi.h \
+   networking_freebsd.c \
networking_iproute2.c networking_iproute2.h \
networking_sitnl.c networking_sitnl.h \
networking.h \
diff --git a/src/openvpn/dco.c b/src/openvpn/dco.c
index 07dc1087..3ffc56d1 100644
--- a/src/openvpn/dco.c
+++ b/src/openvpn/dco.c
@@ -599,7 +599,7 @@ void
 dco_install_iroute(struct multi_context *m, struct multi_instance *mi,
struct mroute_addr *addr)
 {
-#if defined(TARGET_LINUX)
+#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
 if (!dco_enabled(>top.options))
 {
 return;
@@ -642,13 +642,13 @@ dco_install_iroute(struct multi_context *m, struct 
multi_instance *mi,
  >context.c2.push_ifconfig_local, dev, 0,
  DCO_IROUTE_METRIC);
 }
-#endif /* if defined(TARGET_LINUX) */
+#endif /* if defined(TARGET_LINUX) || defined(TARGET_FREEBSD) */
 }
 
 void
 dco_delete_iroutes(struct multi_context *m, struct multi_instance *mi)
 {
-#if defined(TARGET_LINUX)
+#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
 if (!dco_enabled(>top.options))
 {
 return;
@@ -681,7 +681,7 @@ dco_delete_iroutes(struct multi_context *m, struct 
multi_instance *mi)
  0, DCO_IROUTE_METRIC);
 }
 }
-#endif /* if defined(TARGET_LINUX) */
+#endif /* if defined(TARGET_LINUX) || defined(TARGET_FREEBSD) */
 }
 
 #endif /* defined(ENABLE_DCO) */
diff --git a/src/openvpn/dco_freebsd.h b/src/openvpn/dco_freebsd.h
index 3594f229..7de11697 100644
--- a/src/openvpn/dco_freebsd.h
+++ b/src/openvpn/dco_freebsd.h
@@ -27,6 +27,8 @@
 
 #include "ovpn_dco_freebsd.h"
 
+#define DCO_IROUTE_METRIC   100
+
 typedef enum ovpn_key_slot dco_key_slot_t;
 typedef enum ovpn_key_cipher dco_cipher_t;
 
diff --git a/src/openvpn/networking.h b/src/openvpn/networking.h
index cf6d39ac..b0b31ea1 100644
--- a/src/openvpn/networking.h
+++ b/src/openvpn/networking.h
@@ -31,6 +31,9 @@ struct context;
 #include "networking_sitnl.h"
 #elif ENABLE_IPROUTE
 #include "networking_iproute2.h"
+#elif defined(TARGET_FREEBSD)
+typedef void *openvpn_net_ctx_t;
+typedef char openvpn_net_iface_t;
 #else
 /* define mock types to ensure code builds on any platform */
 typedef void *openvpn_net_ctx_t;
@@ -238,7 +241,9 @@ int net_addr_ptp_v4_del(openvpn_net_ctx_t *ctx,
 const openvpn_net_iface_t *iface,
 const in_addr_t *local, const in_addr_t *remote);
 
+#endif /* ENABLE_SITNL || ENABLE_IPROUTE */
 
+#if defined(ENABLE_SITNL) || defined(ENABLE_IPROUTE) || defined(TARGET_FREEBSD)
 /**
  * Add a route for an IPv4 address/network
  *
@@ -315,6 +320,10 @@ int net_route_v6_del(openvpn_net_ctx_t *ctx, const struct 
in6_addr *dst,
  const openvpn_net_iface_t *iface,
  uint32_t table, int metric);
 
+#endif /* ENABLE_SITNL || ENABLE_IPROUTE || TARGET_FREEBSD */
+
+#if defined(ENABLE_SITNL) || defined(ENABLE_IPROUTE)
+
 /**
  * Retrieve the gateway and outgoing interface for the specified IPv4
  * address/network
diff --git a/src/openvpn/networking_freebsd.c b/src/openvpn/networking_freebsd.c
new file mode 100644
index ..4e36941e
--- /dev/null
+++ b/src/openvpn/networking_freebsd.c
@@ -0,0 +1,101 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+#include "syshead.h"
+#include "errlevel.h"
+#include "run_command.h"
+#include "networking.h"
+
+#if defined(TARGET_FREEBSD)
+
+static int
+net_route_v4(const char *op, const in_addr_t *dst, int prefixlen,
+ const in_addr_t *gw, const char *iface, uint32_t table,
+ int metric)
+{
+char buf1[16], buf2[16];
+in_addr_t _dst, _gw;
+struct argv argv = argv_new();
+bool status;
+
+_dst = ntohl(*dst);
+_gw = ntohl(*gw);
+
+argv_printf(, "%s %s",
+ROUTE_PATH, op);
+argv_printf_cat(, "-net %s/%d %s -fib %d",
+inet_ntop(AF_INET, &_dst, buf1, sizeof(buf1)),
+prefixlen,
+inet_ntop(AF_INET, &_gw, buf2, sizeof(buf2)),
+table);
+
+argv_msg(M_INFO, );
+status = openvpn_execve_check(, NULL, 0,
+  "ERROR: FreeBSD route add command failed");
+
+argv_free();
+
+return 

Re: [Openvpn-devel] [PATCH 1/2] ovpn-dco: introduce FreeBSD data-channel offload support

2022-08-11 Thread Kristof Provost via Openvpn-devel
On 10 Aug 2022, at 18:32, Gert Doering wrote:
> as promised, here's test results and code review.
>
> Test results:
>
>  - running openvpn over TCP gives me a kernel panic - this is not so
>nice... (see attached .png from the vmware console) - userland seems
>to assume "kernel can do TCP", kernel panics on "if !udp, panic()"
>(so intentional panic, not corruption panic).
>
>This is on freebsd git FreeBSD 14.0-CURRENT #1 main-n257130-c0665d5c824
>
I’ve pushed a fix for this panic in fd6b3bede5a5c210f327e5c9bd3e415ee905048b.
I simply didn’t think that user space might give us a non-UDP socket, so 
checking for that and rejecting the peer in that case fixes the panic. Thanks 
for finding that.

>  - running openvpn over UDP has issues with fragmentation - almost all
>t_client tests that *do* use DCO fail the "big ping" test
>
> run IPv4 ping tests (want_ok), 64 byte packets...
> run IPv4 ping tests (want_ok), 1440 byte packets...
> run IPv4 ping tests (want_ok), 3000 byte packets...
>
> FAIL: IPv4 ping test (3000 bytes) failed, but should succeed.
> run IPv6 ping tests (want_ok), 64 byte packets...
> run IPv6 ping tests (want_ok), 1440 byte packets...
> run IPv6 ping tests (want_ok), 3000 byte packets...
>
> FAIL: IPv6 ping test (3000 bytes) failed, but should succeed.
>
>this is "with no special mtu related options to OpenVPN", so the
>tun interface is MTU 1500, and the pings are created by
>
> fping -b 3000 -C 20 -p 250 -q -C 5 -p 400 10.194.5.1 10.194.0.1
> fping6 -b 3000 -C 20 -p 250 -q -C 5 -p 400 fd00:abcd:194:5::1 
> fd00:abcd:194:0::1
>
>(testing the host "on the p2p link" and "something behind a --route
> pushed by the server")
>
I’m failing to reproduce this in my own test setup. With a simple ‘ping -c 
2000’ on a 1500 MTU tunnel I see two layers of fragmentation (the ICMP packet 
gets fragmented before it goes through the tunnel, and then the outer UDP 
packet gets fragmented as well), as I’d expect. Traffic flows in both 
directions. (i.e. the ping succeeds).

Is there any documentation on how t_client.sh works? It’s not at all clear to 
me what goes in t_client.in (e.g. in OPENVPN_BASE_P2P).

>I have not investigated exactly what happens at which point yet, but
>with Linux DCO, we had a similar effect where a fragmented *inside*
>packet ("ICMP") carried over a flag in the sk_buff that resulted in
>the kernel refusing to fragment the resulting *outside* packet.
>
>(Inside MTU 1500 -> fping -s 3000 -> 3 "inside" fragments,
> 1500+1500+68, adding openvpn overhead -> packet > 1500 ->
> external fragmentation needed for the first two)
>
>Inside tcpdump (tun0):
>
> 17:28:37.342050 IP (tos 0x0, ttl 64, id 50758, offset 0, flags [+], proto 
> ICMP (1), length 1500)
> 10.194.5.222 > 10.194.5.1: ICMP echo request, id 2433, seq 0, length 1480
> 17:28:37.342142 IP (tos 0x0, ttl 64, id 50758, offset 1480, flags [+], proto 
> ICMP (1), length 1500)
> 10.194.5.222 > 10.194.5.1: ip-proto-1
> 17:28:37.342270 IP (tos 0x0, ttl 64, id 50758, offset 2960, flags [none], 
> proto ICMP (1), length 68)
> 10.194.5.222 > 10.194.5.1: ip-proto-1
>
>Outside tcpdump (em0):
>
> 17:28:37.342103 IP (tos 0x0, ttl 64, id 50759, offset 0, flags [+], proto UDP 
> (17), length 1500)
> 194.97.140.5.15738 > 199.102.77.82.51197: UDP, bad length 1528 > 1472
> 17:28:37.342123 IP (tos 0x0, ttl 64, id 50759, offset 1480, flags [none], 
> proto UDP (17), length 76)
> 194.97.140.5 > 199.102.77.82: ip-proto-17
> 17:28:37.342185 IP (tos 0x0, ttl 64, id 50760, offset 0, flags [+], proto UDP 
> (17), length 1500)
> 194.97.140.5.15738 > 199.102.77.82.51197: UDP, bad length 1528 > 1472
> 17:28:37.342228 IP (tos 0x0, ttl 64, id 50760, offset 1480, flags [none], 
> proto UDP (17), length 76)
> 194.97.140.5 > 199.102.77.82: ip-proto-17
> 17:28:37.342300 IP (tos 0x0, ttl 64, id 50761, offset 0, flags [none], proto 
> UDP (17), length 132)
> 194.97.140.5.15738 > 199.102.77.82.51197: UDP, length 104
>
>
>... this *does* look correct, but there is never a reply from the other
>end, so something is not right.  Either inside or outside.
>
Is your server in this scenario a FreeBSD DCO machine, or Linux DCO or 
something else?
In my setup the server is non-DCO FreeBSD.

Best regards,
Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH 1/2] ovpn-dco: introduce FreeBSD data-channel offload support

2022-08-10 Thread Kristof Provost via Openvpn-devel
Thanks!

On 10 Aug 2022, at 18:32, Gert Doering wrote:
> Test results:
>
>  - running openvpn over TCP gives me a kernel panic - this is not so
>nice... (see attached .png from the vmware console) - userland seems
>to assume "kernel can do TCP", kernel panics on "if !udp, panic()"
>(so intentional panic, not corruption panic).
>
>This is on freebsd git FreeBSD 14.0-CURRENT #1 main-n257130-c0665d5c824
>
I think I see what the problem is. I’m writing up a test case to reproduce it 
and will commit a fix soon. Hopefully tomorrow.

>  - running openvpn over UDP has issues with fragmentation - almost all
>t_client tests that *do* use DCO fail the "big ping" test
>
I’m going to have to do some digging here.

> - tcpdump'ing on the DCO interface gave me complains from the kernel
>   about locking on ctrl-c'ing
>
> Aug 10 17:28:41 fbsd14 kernel: lock order bpf global lock -> iflib ctx 
> lock attempted at:
> Aug 10 17:28:41 fbsd14 kernel: #0 0x80c5c3dd at 
> witness_checkorder+0xbfd
> Aug 10 17:28:41 fbsd14 kernel: #1 0x80bf5303 at _sx_xlock+0x63
> Aug 10 17:28:41 fbsd14 kernel: #2 0x80d3874f at 
> iflib_if_ioctl+0x2df
> Aug 10 17:28:41 fbsd14 kernel: #3 0x80d19b5e at if_setflag+0xde
> Aug 10 17:28:41 fbsd14 kernel: #4 0x80d19a2a at ifpromisc+0x2a
> Aug 10 17:28:41 fbsd14 kernel: #5 0x80d0e72b at 
> bpf_detachd_locked+0x27b
> Aug 10 17:28:41 fbsd14 kernel: #6 0x80d111f7 at bpf_dtor+0x87
> Aug 10 17:28:41 fbsd14 kernel: #7 0x80a7818b at 
> devfs_destroy_cdevpriv+0xab
> Aug 10 17:28:41 fbsd14 kernel: #8 0x80a7bda4 at devfs_close_f+0x64
> Aug 10 17:28:41 fbsd14 kernel: #9 0x80b876eb at _fdrop+0x1b
> Aug 10 17:28:41 fbsd14 kernel: #10 0x80b8af3b at closef+0x1db
> Aug 10 17:28:41 fbsd14 kernel: #11 0x80b8ec97 at closefp_impl+0x77
> Aug 10 17:28:41 fbsd14 kernel: #12 0x810c733e at 
> amd64_syscall+0x12e
> Aug 10 17:28:41 fbsd14 kernel: #13 0x8109ae0b at 
> fast_syscall_common+0xf8
>
>... so while this is outside "openvpn source code patches", it's
>still something that smells like it needs to be addressed.
>
That appears to be unrelated to DCO. It’s a problem with iflib, and I think 
I’ve seen it before.
Out of scope for DCO, at least.

> Now, coding style ;-) - as promised, I went through the code for things
> that need to be done in a certain way in OpenVPN land, due to agreed
> convention... inline (things I do not comment could go in "as is").
>
I’ll fix those once I’ve dealt with the panic and fragmentation issues.

Thanks for the review.

Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] Handle exceeding 'max-clients'

2022-08-08 Thread Kristof Provost via Openvpn-devel
Apologies,

This patch isn’t part of the series (and has in fact already landed), but got 
sent because of a stray patch file in my working tree.

Kristof

On 8 Aug 2022, at 16:34, Kristof Provost wrote:
> From: Kristof Provost 
>
> If 'max-clients' is set multi_create_instance() can return NULL (for any
> client that would take us over the client limit).
>
> If mi is NULL we don't add it to the hash map, but we do potentially
> dereference it to increment the session count.
> Do not attempt to do so if 'mi == NULL'.
>
> Signed-off-by: Kristof Provost 
> ---
>  src/openvpn/mudp.c | 19 ++-
>  1 file changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c
> index 0810fada..0cbca1a9 100644
> --- a/src/openvpn/mudp.c
> +++ b/src/openvpn/mudp.c
> @@ -241,15 +241,16 @@ multi_get_create_instance_udp(struct multi_context *m, 
> bool *floated)
>  hash_add_fast(hash, bucket, >real, hv, mi);
>  mi->did_real_hash = true;
>  multi_assign_peer_id(m, mi);
> -}
> -/* If we have a session id already, ensure that the
> - * state is using the same */
> -if (session_id_defined(_session_id)
> -&& session_id_defined((_session_id)))
> -{
> -mi->context.c2.tls_multi->n_sessions++;
> -struct tls_session *session = 
> >context.c2.tls_multi->session[TM_ACTIVE];
> -session_skip_to_pre_start(session, , 
> >top.c2.from);
> +
> +/* If we have a session id already, ensure that the
> + * state is using the same */
> +if (session_id_defined(_session_id)
> +&& session_id_defined((_session_id)))
> +{
> +mi->context.c2.tls_multi->n_sessions++;
> +struct tls_session *session = 
> >context.c2.tls_multi->session[TM_ACTIVE];
> +session_skip_to_pre_start(session, , 
> >top.c2.from);
> +}
>  }
>  }
>  else
> -- 
> 2.37.0


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH]: FreeBSD DCO support

2022-08-08 Thread Kristof Provost via Openvpn-devel
Hi,

Now that the Linux DCO support has landed in the master tree I've
re-based the FreeBSD DCO support code.
This patch series also includes a patch to support adding iroutes on
FreeBSD.

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] Handle exceeding 'max-clients'

2022-08-08 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

If 'max-clients' is set multi_create_instance() can return NULL (for any
client that would take us over the client limit).

If mi is NULL we don't add it to the hash map, but we do potentially
dereference it to increment the session count.
Do not attempt to do so if 'mi == NULL'.

Signed-off-by: Kristof Provost 
---
 src/openvpn/mudp.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c
index 0810fada..0cbca1a9 100644
--- a/src/openvpn/mudp.c
+++ b/src/openvpn/mudp.c
@@ -241,15 +241,16 @@ multi_get_create_instance_udp(struct multi_context *m, 
bool *floated)
 hash_add_fast(hash, bucket, >real, hv, mi);
 mi->did_real_hash = true;
 multi_assign_peer_id(m, mi);
-}
-/* If we have a session id already, ensure that the
- * state is using the same */
-if (session_id_defined(_session_id)
-&& session_id_defined((_session_id)))
-{
-mi->context.c2.tls_multi->n_sessions++;
-struct tls_session *session = 
>context.c2.tls_multi->session[TM_ACTIVE];
-session_skip_to_pre_start(session, , 
>top.c2.from);
+
+/* If we have a session id already, ensure that the
+ * state is using the same */
+if (session_id_defined(_session_id)
+&& session_id_defined((_session_id)))
+{
+mi->context.c2.tls_multi->n_sessions++;
+struct tls_session *session = 
>context.c2.tls_multi->session[TM_ACTIVE];
+session_skip_to_pre_start(session, , 
>top.c2.from);
+}
 }
 }
 else
-- 
2.37.0



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 2/2] Support creating iroute route entries on FreeBSD

2022-08-08 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Signed-off-by: Kristof Provost 
---
 src/openvpn/Makefile.am  |   1 +
 src/openvpn/dco.c|   8 +--
 src/openvpn/dco_freebsd.h|   2 +
 src/openvpn/networking.h |   9 +++
 src/openvpn/networking_freebsd.c | 101 +++
 5 files changed, 117 insertions(+), 4 deletions(-)
 create mode 100644 src/openvpn/networking_freebsd.c

diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 2a139b23..5155a180 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -88,6 +88,7 @@ openvpn_SOURCES = \
mtu.c mtu.h \
mudp.c mudp.h \
multi.c multi.h \
+   networking_freebsd.c \
networking_iproute2.c networking_iproute2.h \
networking_sitnl.c networking_sitnl.h \
networking.h \
diff --git a/src/openvpn/dco.c b/src/openvpn/dco.c
index 4f40255e..b9cc0b83 100644
--- a/src/openvpn/dco.c
+++ b/src/openvpn/dco.c
@@ -591,7 +591,7 @@ void
 dco_install_iroute(struct multi_context *m, struct multi_instance *mi,
struct mroute_addr *addr)
 {
-#if defined(TARGET_LINUX)
+#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
 if (!dco_enabled(>top.options))
 {
 return;
@@ -634,13 +634,13 @@ dco_install_iroute(struct multi_context *m, struct 
multi_instance *mi,
  >context.c2.push_ifconfig_local, dev, 0,
  DCO_IROUTE_METRIC);
 }
-#endif /* if defined(TARGET_LINUX) */
+#endif /* if defined(TARGET_LINUX) || defined(TARGET_FREEBSD) */
 }
 
 void
 dco_delete_iroutes(struct multi_context *m, struct multi_instance *mi)
 {
-#if defined(TARGET_LINUX)
+#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
 if (!dco_enabled(>top.options))
 {
 return;
@@ -673,7 +673,7 @@ dco_delete_iroutes(struct multi_context *m, struct 
multi_instance *mi)
  0, DCO_IROUTE_METRIC);
 }
 }
-#endif /* if defined(TARGET_LINUX) */
+#endif /* if defined(TARGET_LINUX) || defined(TARGET_FREEBSD) */
 }
 
 #endif /* defined(ENABLE_DCO) */
diff --git a/src/openvpn/dco_freebsd.h b/src/openvpn/dco_freebsd.h
index 3594f229..7de11697 100644
--- a/src/openvpn/dco_freebsd.h
+++ b/src/openvpn/dco_freebsd.h
@@ -27,6 +27,8 @@
 
 #include "ovpn_dco_freebsd.h"
 
+#define DCO_IROUTE_METRIC   100
+
 typedef enum ovpn_key_slot dco_key_slot_t;
 typedef enum ovpn_key_cipher dco_cipher_t;
 
diff --git a/src/openvpn/networking.h b/src/openvpn/networking.h
index cf6d39ac..b0b31ea1 100644
--- a/src/openvpn/networking.h
+++ b/src/openvpn/networking.h
@@ -31,6 +31,9 @@ struct context;
 #include "networking_sitnl.h"
 #elif ENABLE_IPROUTE
 #include "networking_iproute2.h"
+#elif defined(TARGET_FREEBSD)
+typedef void *openvpn_net_ctx_t;
+typedef char openvpn_net_iface_t;
 #else
 /* define mock types to ensure code builds on any platform */
 typedef void *openvpn_net_ctx_t;
@@ -238,7 +241,9 @@ int net_addr_ptp_v4_del(openvpn_net_ctx_t *ctx,
 const openvpn_net_iface_t *iface,
 const in_addr_t *local, const in_addr_t *remote);
 
+#endif /* ENABLE_SITNL || ENABLE_IPROUTE */
 
+#if defined(ENABLE_SITNL) || defined(ENABLE_IPROUTE) || defined(TARGET_FREEBSD)
 /**
  * Add a route for an IPv4 address/network
  *
@@ -315,6 +320,10 @@ int net_route_v6_del(openvpn_net_ctx_t *ctx, const struct 
in6_addr *dst,
  const openvpn_net_iface_t *iface,
  uint32_t table, int metric);
 
+#endif /* ENABLE_SITNL || ENABLE_IPROUTE || TARGET_FREEBSD */
+
+#if defined(ENABLE_SITNL) || defined(ENABLE_IPROUTE)
+
 /**
  * Retrieve the gateway and outgoing interface for the specified IPv4
  * address/network
diff --git a/src/openvpn/networking_freebsd.c b/src/openvpn/networking_freebsd.c
new file mode 100644
index ..4e36941e
--- /dev/null
+++ b/src/openvpn/networking_freebsd.c
@@ -0,0 +1,101 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+#include "syshead.h"
+#include "errlevel.h"
+#include "run_command.h"
+#include "networking.h"
+
+#if defined(TARGET_FREEBSD)
+
+static int
+net_route_v4(const char *op, const in_addr_t *dst, int prefixlen,
+ const in_addr_t *gw, const char *iface, uint32_t table,
+ int metric)
+{
+char buf1[16], buf2[16];
+in_addr_t _dst, _gw;
+struct argv argv = argv_new();
+bool status;
+
+_dst = ntohl(*dst);
+_gw = ntohl(*gw);
+
+argv_printf(, "%s %s",
+ROUTE_PATH, op);
+argv_printf_cat(, "-net %s/%d %s -fib %d",
+inet_ntop(AF_INET, &_dst, buf1, sizeof(buf1)),
+prefixlen,
+inet_ntop(AF_INET, &_gw, buf2, sizeof(buf2)),
+table);
+
+argv_msg(M_INFO, );
+status = openvpn_execve_check(, NULL, 0,
+  "ERROR: FreeBSD route add command failed");
+
+argv_free();
+
+return 

[Openvpn-devel] [PATCH 1/2] ovpn-dco: introduce FreeBSD data-channel offload support

2022-08-08 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Implement data-channel offload for FreeBSD. The implementation and flow
is very similar to that of the Linux DCO support.

Signed-off-by: Kristof Provost 
---
 configure.ac   |   5 +
 src/openvpn/Makefile.am|   1 +
 src/openvpn/dco_freebsd.c  | 636 +
 src/openvpn/dco_freebsd.h  |  59 +++
 src/openvpn/dco_internal.h |   1 +
 src/openvpn/forward.c  |   8 +-
 src/openvpn/mtcp.c |   4 +-
 src/openvpn/mudp.c |   2 +-
 src/openvpn/multi.c|   4 +-
 src/openvpn/options.c  |   8 +-
 src/openvpn/options.h  |   4 +-
 src/openvpn/ovpn_dco_freebsd.h |  64 
 src/openvpn/tun.c  |  38 +-
 src/openvpn/tun.h  |   6 +
 14 files changed, 808 insertions(+), 32 deletions(-)
 create mode 100644 src/openvpn/dco_freebsd.c
 create mode 100644 src/openvpn/dco_freebsd.h
 create mode 100644 src/openvpn/ovpn_dco_freebsd.h

diff --git a/configure.ac b/configure.ac
index 353da08c..ed1332da 100644
--- a/configure.ac
+++ b/configure.ac
@@ -787,6 +787,11 @@ dnl
AC_DEFINE(ENABLE_DCO, 1, [Enable shared data channel 
offload])
AC_MSG_NOTICE([Enabled ovpn-dco support for Linux])
;;
+   *-*-freebsd*)
+   LIBS="${LIBS} -lnv"
+   AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
for FreeBSD])
+   AC_MSG_NOTICE([Enabled ovpn-dco support for FreeBSD])
+   ;;
*)
AC_MSG_NOTICE([Ignoring --enable-dco on non Linux 
platform])
;;
diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index aaa1dbce..2a139b23 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -54,6 +54,7 @@ openvpn_SOURCES = \
crypto_openssl.c crypto_openssl.h \
crypto_mbedtls.c crypto_mbedtls.h \
dco.c dco.h dco_internal.h \
+   dco_freebsd.c dco_freebsd.h \
dco_linux.c dco_linux.h \
dhcp.c dhcp.h \
dns.c dns.h \
diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
new file mode 100644
index ..a8a53fe3
--- /dev/null
+++ b/src/openvpn/dco_freebsd.c
@@ -0,0 +1,636 @@
+/*
+ *  Interface to FreeBSD dco networking code
+ *
+ *  Copyright (C) 2022 Rubicon Communications, LLC (Netgate). All Rights 
Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#if defined(ENABLE_DCO) && defined(TARGET_FREEBSD)
+
+#include "syshead.h"
+
+#include 
+#include 
+#include 
+#include 
+
+#include "dco_freebsd.h"
+#include "dco.h"
+#include "tun.h"
+#include "crypto.h"
+#include "ssl_common.h"
+
+static nvlist_t *
+sockaddr_to_nvlist(const struct sockaddr *sa)
+{
+nvlist_t *nvl = nvlist_create(0);
+
+nvlist_add_number(nvl, "af", sa->sa_family);
+
+switch (sa->sa_family)
+{
+case AF_INET:
+{
+const struct sockaddr_in *in = (const struct sockaddr_in *)sa;
+nvlist_add_binary(nvl, "address", >sin_addr, 
sizeof(in->sin_addr));
+nvlist_add_number(nvl, "port", in->sin_port);
+break;
+}
+
+case AF_INET6:
+{
+const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *)sa;
+nvlist_add_binary(nvl, "address", >sin6_addr, 
sizeof(in6->sin6_addr));
+nvlist_add_number(nvl, "port", in6->sin6_port);
+break;
+}
+
+default:
+abort();
+}
+
+return (nvl);
+}
+
+int
+dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
+ struct sockaddr *localaddr, struct sockaddr *remoteaddr,
+ struct in_addr *remote_in4, struct in6_addr *remote_in6)
+{
+struct ifdrv drv;
+nvlist_t *nvl;
+int ret;
+
+nvl = nvlist_create(0);
+
+msg(D_DCO_DEBUG, "%s: peer-id %d, fd %d", __func__, peerid, sd);
+
+if (localaddr)
+{
+nvlist_add_nvlist(nvl, "local", sockaddr_to_nvlist(localaddr));
+}
+
+if (remoteaddr)
+{
+nvlist_add_nvlist(nvl, "remote", sockaddr_to_nvlist(remoteaddr));
+}
+
+if 

[Openvpn-devel] [PATCH] Handle exceeding 'max-clients'

2022-07-13 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

If 'max-clients' is set multi_create_instance() can return NULL (for any
client that would take us over the client limit).

If mi is NULL we don't add it to the hash map, but we do potentially
dereference it to increment the session count.
Do not attempt to do so if 'mi == NULL'.

Signed-off-by: Kristof Provost 
---
 src/openvpn/mudp.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c
index 0810fada..0cbca1a9 100644
--- a/src/openvpn/mudp.c
+++ b/src/openvpn/mudp.c
@@ -241,15 +241,16 @@ multi_get_create_instance_udp(struct multi_context *m, 
bool *floated)
 hash_add_fast(hash, bucket, >real, hv, mi);
 mi->did_real_hash = true;
 multi_assign_peer_id(m, mi);
-}
-/* If we have a session id already, ensure that the
- * state is using the same */
-if (session_id_defined(_session_id)
-&& session_id_defined((_session_id)))
-{
-mi->context.c2.tls_multi->n_sessions++;
-struct tls_session *session = 
>context.c2.tls_multi->session[TM_ACTIVE];
-session_skip_to_pre_start(session, , 
>top.c2.from);
+
+/* If we have a session id already, ensure that the
+ * state is using the same */
+if (session_id_defined(_session_id)
+&& session_id_defined((_session_id)))
+{
+mi->context.c2.tls_multi->n_sessions++;
+struct tls_session *session = 
>context.c2.tls_multi->session[TM_ACTIVE];
+session_skip_to_pre_start(session, , 
>top.c2.from);
+}
 }
 }
 else
-- 
2.37.0



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH]: Handle exceeding max-clients

2022-07-13 Thread Kristof Provost via Openvpn-devel
This patch fixes a crash we've seen on server instances when one more
client than 'max-clients' connects.

I believe this affects both master and DCO branches, and I think it was
introduced with this commit:

commit b364711486dc6371ad2659a5aa190941136f4f04
Author: Arne Schwabe 
Date:   Mon May 2 17:43:10 2022 +0200

Implement stateless HMAC-based sesssion-id three-way-handshake

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH DCO]: FreeBSD DCO support

2022-06-29 Thread Kristof Provost via Openvpn-devel
On 29 Jun 2022, at 21:08, Arne Schwabe wrote:
> Am 29.06.2022 um 19:40 schrieb Kristof Provost:
>> On 29 Jun 2022, at 17:15, Arne Schwabe wrote:
>>> Am 28.06.22 um 18:28 schrieb Kristof Provost via Openvpn-devel:
>>>> Hi,
>>>>
>>>> Here's the most recent version of the FreeBSD DCO patch.
>>>> This is based on top of the dco branch, at
>>>> 480fa1c983aba9b0790ea94df209e1686f08336b.
>>>>
>>>> Relatedly, the kernel side of that support has just landed in FreeBSD's
>>>> repo: 
>>>> https://cgit.freebsd.org/src/commit/?id=ab91feabcc6f9da21d5c75028153af16d06e679a
>>> I tested this on top of Antonios branch but got an error when connecting 
>>> from a test client:
>>>
>>> 2022-06-29 17:10:57 us=506086 lethe/192.168.188.134:61923 dco_new_peer: 
>>> peer-id 0, fd 7
>>> 2022-06-29 17:10:57 us=506125 lethe/192.168.188.134:61923 Failed to create 
>>> new peer 51
>>> 2022-06-29 17:10:57 us=506137 lethe/192.168.188.134:61923 Cannot add peer 
>>> to DCO: Operation not permitted
>>>
>>>
>>> Any idea why I might get a permission denied from the kernel there?
>>>
>> The first thing to note here is that the ‘Operation not permitted’ error is 
>> misleading. That’s produced based on the return value of dco_new_peer(), 
>> which is going to be -1. The line above it has the errno, which is 51 or 
>> ENETUNREACH.
>>
>> I suspect this is happening because you’re using ipv6_ipv4mapping (or sysctl 
>> net.inet6.ip6.v6only=0). Presumably that indicates a bug on my side, but can 
>> you see if disabling that helps?
> Yes. That is the default that OpenVPN uses. It will ignore the sysctl since 
> we use the socket option per default on v6 sockets. (search the man page for 
> ipv6only). Adding --proto udp4 fixes the problem but that is something at 
> least needs a better error mesage.
>
I’ll do some digging in the next couple of days. I’m hopeful it can just be 
made to work.

Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH DCO]: FreeBSD DCO support

2022-06-29 Thread Kristof Provost via Openvpn-devel
On 29 Jun 2022, at 17:15, Arne Schwabe wrote:
> Am 28.06.22 um 18:28 schrieb Kristof Provost via Openvpn-devel:
>> Hi,
>>
>> Here's the most recent version of the FreeBSD DCO patch.
>> This is based on top of the dco branch, at
>> 480fa1c983aba9b0790ea94df209e1686f08336b.
>>
>> Relatedly, the kernel side of that support has just landed in FreeBSD's
>> repo: 
>> https://cgit.freebsd.org/src/commit/?id=ab91feabcc6f9da21d5c75028153af16d06e679a
>
> I tested this on top of Antonios branch but got an error when connecting from 
> a test client:
>
> 2022-06-29 17:10:57 us=506086 lethe/192.168.188.134:61923 dco_new_peer: 
> peer-id 0, fd 7
> 2022-06-29 17:10:57 us=506125 lethe/192.168.188.134:61923 Failed to create 
> new peer 51
> 2022-06-29 17:10:57 us=506137 lethe/192.168.188.134:61923 Cannot add peer to 
> DCO: Operation not permitted
>
>
> Any idea why I might get a permission denied from the kernel there?
>
The first thing to note here is that the ‘Operation not permitted’ error is 
misleading. That’s produced based on the return value of dco_new_peer(), which 
is going to be -1. The line above it has the errno, which is 51 or ENETUNREACH.

I suspect this is happening because you’re using ipv6_ipv4mapping (or sysctl 
net.inet6.ip6.v6only=0). Presumably that indicates a bug on my side, but can 
you see if disabling that helps?

Br,
Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH DCO]: FreeBSD DCO support

2022-06-28 Thread Kristof Provost via Openvpn-devel
On 28 Jun 2022, at 21:05, Antonio Quartulli wrote:
> On 28/06/2022 18:28, Kristof Provost via Openvpn-devel wrote:
>> Hi,
>>
>> Here's the most recent version of the FreeBSD DCO patch.
>> This is based on top of the dco branch, at
>> 480fa1c983aba9b0790ea94df209e1686f08336b.
>>
>
> Thanks! DCO patches may still change a bit due to review, but their 
> converging :-)
> Thanks a lot for bearing with us.
>
I figured, but I mostly wanted to remind you all that there are FreeBSD patches 
and that I haven’t forgotten about you yet.

I’ve been happy working with you (and the other openvpn devs). I’m not worried 
about a little churn and patch rebase work.

>> Relatedly, the kernel side of that support has just landed in FreeBSD's
>> repo: 
>> https://cgit.freebsd.org/src/commit/?id=ab91feabcc6f9da21d5c75028153af16d06e679a
>>
>
> Wonderful news! Congratulations!!
>
Also, the recent pfSense plus 22.05 release includes DCO support. So far there 
don’t seem to be major issues. It’s only been out for about a day, so maybe I 
should stop taunting Murphy.

Best regards,
Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH DCO]: FreeBSD DCO support

2022-06-28 Thread Kristof Provost via Openvpn-devel
Hi,

Here's the most recent version of the FreeBSD DCO patch.
This is based on top of the dco branch, at
480fa1c983aba9b0790ea94df209e1686f08336b.

Relatedly, the kernel side of that support has just landed in FreeBSD's
repo: 
https://cgit.freebsd.org/src/commit/?id=ab91feabcc6f9da21d5c75028153af16d06e679a

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] ovpn-dco: introduce FreeBSD data-channel offload support

2022-06-28 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Implement data-channel offload for FreeBSD. The implementation and flow
is very similar to that of the Linux DCO support.

Signed-off-by: Kristof Provost 
---
 configure.ac   |   5 +
 src/openvpn/Makefile.am|   1 +
 src/openvpn/dco_freebsd.c  | 636 +
 src/openvpn/dco_freebsd.h  |  59 +++
 src/openvpn/dco_internal.h |   1 +
 src/openvpn/forward.c  |   6 +-
 src/openvpn/mtcp.c |   4 +-
 src/openvpn/mudp.c |   2 +-
 src/openvpn/multi.c|   2 +-
 src/openvpn/options.c  |   8 +-
 src/openvpn/ovpn_dco_freebsd.h |  64 
 src/openvpn/tun.c  |   8 +-
 src/openvpn/tun.h  |   6 +
 13 files changed, 787 insertions(+), 15 deletions(-)
 create mode 100644 src/openvpn/dco_freebsd.c
 create mode 100644 src/openvpn/dco_freebsd.h
 create mode 100644 src/openvpn/ovpn_dco_freebsd.h

diff --git a/configure.ac b/configure.ac
index bebed1ac..9ce5f00b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -787,6 +787,11 @@ dnl
AC_DEFINE(ENABLE_DCO, 1, [Enable shared data channel 
offload])
AC_MSG_NOTICE([Enabled ovpn-dco support for Linux])
;;
+   *-*-freebsd*)
+   LIBS="${LIBS} -lnv"
+   AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
for FreeBSD])
+   AC_MSG_NOTICE([Enabled ovpn-dco support for FreeBSD])
+   ;;
*-mingw*)
AC_MSG_NOTICE([NOTE: --enable-dco ignored on Windows 
because it's always enabled])
;;
diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 8d0e66b4..458d7f1c 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -54,6 +54,7 @@ openvpn_SOURCES = \
crypto_openssl.c crypto_openssl.h \
crypto_mbedtls.c crypto_mbedtls.h \
dco.c dco.h dco_internal.h \
+   dco_freebsd.c dco_freebsd.h \
dco_linux.c dco_linux.h \
dco_win.c dco_win.h \
dhcp.c dhcp.h \
diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
new file mode 100644
index ..a14f3833
--- /dev/null
+++ b/src/openvpn/dco_freebsd.c
@@ -0,0 +1,636 @@
+/*
+ *  Interface to FreeBSD dco networking code
+ *
+ *  Copyright (C) 2022 Rubicon Communications, LLC (Netgate). All Rights 
Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#if defined(ENABLE_DCO) && defined(TARGET_FREEBSD)
+
+#include "syshead.h"
+
+#include 
+#include 
+#include 
+#include 
+
+#include "dco_freebsd.h"
+#include "dco.h"
+#include "tun.h"
+#include "crypto.h"
+#include "ssl_common.h"
+
+static nvlist_t *
+sockaddr_to_nvlist(const struct sockaddr *sa)
+{
+nvlist_t *nvl = nvlist_create(0);
+
+nvlist_add_number(nvl, "af", sa->sa_family);
+
+switch (sa->sa_family)
+{
+case AF_INET:
+{
+const struct sockaddr_in *in = (const struct sockaddr_in *)sa;
+nvlist_add_binary(nvl, "address", >sin_addr, 
sizeof(in->sin_addr));
+nvlist_add_number(nvl, "port", in->sin_port);
+break;
+}
+
+case AF_INET6:
+{
+const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *)sa;
+nvlist_add_binary(nvl, "address", >sin6_addr, 
sizeof(in6->sin6_addr));
+nvlist_add_number(nvl, "port", in6->sin6_port);
+break;
+}
+
+default:
+abort();
+}
+
+return (nvl);
+}
+
+int
+dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
+ struct sockaddr *localaddr, struct sockaddr *remoteaddr,
+ struct in_addr *remote_in4, struct in6_addr *remote_in6)
+{
+struct ifdrv drv;
+nvlist_t *nvl;
+int ret;
+
+nvl = nvlist_create(0);
+
+msg(D_DCO_DEBUG, "%s: peer-id %d, fd %d", __func__, peerid, sd);
+
+if (localaddr)
+{
+nvlist_add_nvlist(nvl, "local", sockaddr_to_nvlist(localaddr));
+}
+
+if (remoteaddr)
+{
+nvlist_add_nvlist(nvl, "remote", sockaddr_to_nvlist(remoteaddr));
+}
+
+if 

Re: [Openvpn-devel] [PATCH 4/4] Set (DCO) timeouts as well for p2p mode

2022-05-17 Thread Kristof Provost via Openvpn-devel
On 17 May 2022, at 15:25, Antonio Quartulli wrote:
> Hi,
>
> On 16/05/2022 20:56, Kristof Provost via Openvpn-devel wrote:
>> From: Kristof Provost 
>>
>> Signed-off-by: Kristof Provost 
>> ---
>>   src/openvpn/init.c | 15 +++
>>   1 file changed, 15 insertions(+)
>>
>> diff --git a/src/openvpn/init.c b/src/openvpn/init.c
>> index 0d991ba4..701749cd 100644
>> --- a/src/openvpn/init.c
>> +++ b/src/openvpn/init.c
>> @@ -2232,6 +2232,21 @@ do_deferred_p2p_ncp(struct context *c)
>>   msg(D_TLS_ERRORS, "ERROR: failed to set crypto cipher");
>>   return false;
>>   }
>> +
>> +if (dco_enabled(>options) && (c->options.ping_send_timeout || 
>> c->c2.frame.mss_fix))
>> +{
>> +int ret = dco_set_peer(>c1.tuntap->dco,
>> +c->c2.tls_multi->peer_id,
>> +c->options.ping_send_timeout,
>> +c->options.ping_rec_timeout,
>> +c->c2.frame.mss_fix);
>> +if (ret < 0)
>> +{
>> +msg(D_DCO, "Cannot set DCO peer: %s", strerror(-ret));
>> +return false;
>> +}
>> +}
>> +
>
> unless I am missing something, I don't think we need another dco_set_peer 
> call.
>
> It should be enough to move the invocation of dco_set_peer in finish_options 
> at the very top, before any attempt of bailing out.
>
Good point. I’ll update my patchset and include this in the next update.

Br,
Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH 2/4] rework do_up() for correct order of DCO operations

2022-05-17 Thread Kristof Provost via Openvpn-devel
On 17 May 2022, at 15:28, Antonio Quartulli wrote:
> On 16/05/2022 20:56, Kristof Provost via Openvpn-devel wrote:
>> From: Kristof Provost 
>>
>> We must create the peer before we can dco_set_peer or dco_new_key.
>> On the other hand, we must first process options, because those may
>> change our peer id and we should create the peer with the correct id.
>>
>> Split up do_deferred_options() in do_deferred_options() and
>> finish_options(). Call any DCO configuration operations (i.e.
>> dco_set_peer()/dco_new_key()) after we've created the peer (i.e.
>> dco_new_peer()).
>>
>> Signed-off-by: Kristof Provost 
>
> I am including this patch in the dco branch as well.
>
> Please note that this change has been reworked a little bit.
>
Thanks!

Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 4/4] Set (DCO) timeouts as well for p2p mode

2022-05-16 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Signed-off-by: Kristof Provost 
---
 src/openvpn/init.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 0d991ba4..701749cd 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -2232,6 +2232,21 @@ do_deferred_p2p_ncp(struct context *c)
 msg(D_TLS_ERRORS, "ERROR: failed to set crypto cipher");
 return false;
 }
+
+if (dco_enabled(>options) && (c->options.ping_send_timeout || 
c->c2.frame.mss_fix))
+{
+int ret = dco_set_peer(>c1.tuntap->dco,
+c->c2.tls_multi->peer_id,
+c->options.ping_send_timeout,
+c->options.ping_rec_timeout,
+c->c2.frame.mss_fix);
+if (ret < 0)
+{
+msg(D_DCO, "Cannot set DCO peer: %s", strerror(-ret));
+return false;
+}
+}
+
 return true;
 }
 
-- 
2.36.1



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 2/4] rework do_up() for correct order of DCO operations

2022-05-16 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

We must create the peer before we can dco_set_peer or dco_new_key.
On the other hand, we must first process options, because those may
change our peer id and we should create the peer with the correct id.

Split up do_deferred_options() in do_deferred_options() and
finish_options(). Call any DCO configuration operations (i.e.
dco_set_peer()/dco_new_key()) after we've created the peer (i.e.
dco_new_peer()).

Signed-off-by: Kristof Provost 
---
 src/openvpn/init.c  | 112 +---
 src/openvpn/init.h  |   2 +
 src/openvpn/multi.c |   2 +
 3 files changed, 68 insertions(+), 48 deletions(-)

diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index a6c93038..0d991ba4 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -2093,26 +2093,26 @@ do_up(struct context *c, bool pulled_options, unsigned 
int option_types_found)
 }
 }
 
-if ((c->mode == MODE_POINT_TO_POINT) && c->c2.did_open_tun)
+if (pulled_options)
 {
-/* ovpn-dco requires adding the peer now, before any option can be 
set */
-int ret = dco_p2p_add_new_peer(c);
-if (ret < 0)
+if (!do_deferred_options(c, option_types_found))
 {
-msg(D_DCO, "Cannot add peer to DCO: %s", strerror(-ret));
+msg(D_PUSH_ERRORS, "ERROR: Failed to apply push options");
 return false;
 }
 }
-
-if (pulled_options)
+if (c->mode == MODE_POINT_TO_POINT)
 {
-if (!do_deferred_options(c, option_types_found))
+/* ovpn-dco requires adding the peer now, before any option can be 
set */
+int ret = dco_p2p_add_new_peer(c);
+if (ret < 0)
 {
-msg(D_PUSH_ERRORS, "ERROR: Failed to apply push options");
+msg(D_DCO, "Cannot add peer to DCO: %s", strerror(-ret));
 return false;
 }
 }
-else if (c->mode == MODE_POINT_TO_POINT)
+
+if (!pulled_options && c->mode == MODE_POINT_TO_POINT)
 {
 if (!do_deferred_p2p_ncp(c))
 {
@@ -2121,6 +2121,13 @@ do_up(struct context *c, bool pulled_options, unsigned 
int option_types_found)
 }
 }
 
+
+if (!finish_options(c))
+{
+msg(D_TLS_ERRORS, "ERROR: Failed to finish option processing");
+return false;
+}
+
 if (c->c2.did_open_tun)
 {
 c->c1.pulled_options_digest_save = c->c2.pulled_options_digest;
@@ -2337,49 +2344,58 @@ do_deferred_options(struct context *c, const unsigned 
int found)
 {
 return false;
 }
-struct frame *frame_fragment = NULL;
+}
+
+return true;
+}
+
+bool
+finish_options(struct context *c)
+{
+if (!c->options.pull || !dco_enabled(>options))
+{
+return true;
+}
+
+struct frame *frame_fragment = NULL;
 #ifdef ENABLE_FRAGMENT
-if (c->options.ce.fragment)
-{
-frame_fragment = >c2.frame_fragment;
-}
+if (c->options.ce.fragment)
+{
+frame_fragment = >c2.frame_fragment;
+}
 #endif
 
-struct tls_session *session = >c2.tls_multi->session[TM_ACTIVE];
-if (!tls_session_update_crypto_params(c->c2.tls_multi, session,
-  >options, >c2.frame,
-  frame_fragment,
-  get_link_socket_info(c)))
-{
-msg(D_TLS_ERRORS, "OPTIONS ERROR: failed to import crypto 
options");
-return false;
-}
+struct tls_session *session = >c2.tls_multi->session[TM_ACTIVE];
+if (!tls_session_update_crypto_params(c->c2.tls_multi, session,
+  >options, >c2.frame,
+  frame_fragment,
+  get_link_socket_info(c)))
+{
+msg(D_TLS_ERRORS, "OPTIONS ERROR: failed to import crypto options");
+return false;
+}
 
-if (dco_enabled(>options))
-{
-/* Check if the pushed options are compatible with DCO if we have
- * DCO enabled */
-if (!check_dco_pull_options(>options))
-{
-msg(D_TLS_ERRORS, "OPTIONS ERROR: pushed options are 
incompatible with "
-"data channel offload. Use --disable-dco to connect"
-"to this server");
-return false;
-}
+/* Check if the pushed options are compatible with DCO if we have
+ * DCO enabled */
+if (!check_dco_pull_options(>options))
+{
+msg(D_TLS_ERRORS, "OPTIONS ERROR: pushed options are incompatible with 
"
+"data channel offload. Use --disable-dco to connect"
+"to this server");
+return false;
+   

[Openvpn-devel] [PATCH DCO]: FreeBSD DCO support

2022-05-16 Thread Kristof Provost via Openvpn-devel
Hi,

Here's an updated version for the FreeBSD DCO support, as well as a few
generic bugfixes.

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 3/4] ovpn-dco: introduce FreeBSD data-channel offload support

2022-05-16 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Implement data-channel offload for FreeBSD. The implementation and flow
is very similar to that of the Linux DCO support.

Signed-off-by: Kristof Provost 
---
 configure.ac   |   6 +-
 src/openvpn/Makefile.am|   1 +
 src/openvpn/dco_freebsd.c  | 636 +
 src/openvpn/dco_freebsd.h  |  59 +++
 src/openvpn/dco_internal.h |   1 +
 src/openvpn/forward.c  |   8 +-
 src/openvpn/mtcp.c |   6 +-
 src/openvpn/mudp.c |   2 +-
 src/openvpn/multi.c|   2 +-
 src/openvpn/options.c  |   8 +-
 src/openvpn/ovpn_dco_freebsd.h |  64 
 src/openvpn/tun.c  |   8 +-
 src/openvpn/tun.h  |   6 +
 13 files changed, 789 insertions(+), 18 deletions(-)
 create mode 100644 src/openvpn/dco_freebsd.c
 create mode 100644 src/openvpn/dco_freebsd.h
 create mode 100644 src/openvpn/ovpn_dco_freebsd.h

diff --git a/configure.ac b/configure.ac
index 85921ddb..c5b30d47 100644
--- a/configure.ac
+++ b/configure.ac
@@ -787,7 +787,11 @@ dnl
AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
for Linux])
AC_MSG_NOTICE([Enabled ovpn-dco support for Linux])
;;
-
+   *-*-freebsd*)
+   LIBS="${LIBS} -lnv"
+   AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
for FreeBSD])
+   AC_MSG_NOTICE([Enabled ovpn-dco support for FreeBSD])
+   ;;
*-mingw*)
AC_MSG_NOTICE([NOTE: --enable-dco ignored on Windows 
because it's always enabled])
;;
diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 9cadbcb2..a04f371a 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -54,6 +54,7 @@ openvpn_SOURCES = \
crypto_openssl.c crypto_openssl.h \
crypto_mbedtls.c crypto_mbedtls.h \
dco.c dco.h dco_internal.h \
+   dco_freebsd.c dco_freebsd.h \
dco_linux.c dco_linux.h \
dco_win.c dco_win.h \
dhcp.c dhcp.h \
diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
new file mode 100644
index ..a14f3833
--- /dev/null
+++ b/src/openvpn/dco_freebsd.c
@@ -0,0 +1,636 @@
+/*
+ *  Interface to FreeBSD dco networking code
+ *
+ *  Copyright (C) 2022 Rubicon Communications, LLC (Netgate). All Rights 
Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#if defined(ENABLE_DCO) && defined(TARGET_FREEBSD)
+
+#include "syshead.h"
+
+#include 
+#include 
+#include 
+#include 
+
+#include "dco_freebsd.h"
+#include "dco.h"
+#include "tun.h"
+#include "crypto.h"
+#include "ssl_common.h"
+
+static nvlist_t *
+sockaddr_to_nvlist(const struct sockaddr *sa)
+{
+nvlist_t *nvl = nvlist_create(0);
+
+nvlist_add_number(nvl, "af", sa->sa_family);
+
+switch (sa->sa_family)
+{
+case AF_INET:
+{
+const struct sockaddr_in *in = (const struct sockaddr_in *)sa;
+nvlist_add_binary(nvl, "address", >sin_addr, 
sizeof(in->sin_addr));
+nvlist_add_number(nvl, "port", in->sin_port);
+break;
+}
+
+case AF_INET6:
+{
+const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *)sa;
+nvlist_add_binary(nvl, "address", >sin6_addr, 
sizeof(in6->sin6_addr));
+nvlist_add_number(nvl, "port", in6->sin6_port);
+break;
+}
+
+default:
+abort();
+}
+
+return (nvl);
+}
+
+int
+dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
+ struct sockaddr *localaddr, struct sockaddr *remoteaddr,
+ struct in_addr *remote_in4, struct in6_addr *remote_in6)
+{
+struct ifdrv drv;
+nvlist_t *nvl;
+int ret;
+
+nvl = nvlist_create(0);
+
+msg(D_DCO_DEBUG, "%s: peer-id %d, fd %d", __func__, peerid, sd);
+
+if (localaddr)
+{
+nvlist_add_nvlist(nvl, "local", sockaddr_to_nvlist(localaddr));
+}
+
+if (remoteaddr)
+{
+nvlist_add_nvlist(nvl, "remote", sockaddr_to_nvlist(remoteaddr));
+}
+
+if (remote_in4)
+{
+  

[Openvpn-devel] [PATCH 1/4] mtcp: Handle multi_create_instance() returning NULL

2022-05-16 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

multi_create_instance() can fail (i.e. return NULL).
multi_create_instance_tcp() is ready for this, but called
multi_assign_peer_id() without first checking if mi was non-NULL.
multi_assign_peer_id() assumed that mi is non-NULL, dereferencing it and
causing a crash.

Move the call to multi_assign_peer_id() after the mi NULL check.

Signed-off-by: Kristof Provost 
---
 src/openvpn/mtcp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/openvpn/mtcp.c b/src/openvpn/mtcp.c
index b4445dbe..414a5676 100644
--- a/src/openvpn/mtcp.c
+++ b/src/openvpn/mtcp.c
@@ -124,7 +124,6 @@ multi_create_instance_tcp(struct multi_context *m)
 struct hash *hash = m->hash;
 
 mi = multi_create_instance(m, NULL);
-multi_assign_peer_id(m, mi);
 
 if (mi)
 {
@@ -132,6 +131,8 @@ multi_create_instance_tcp(struct multi_context *m)
 const uint32_t hv = hash_value(hash, >real);
 struct hash_bucket *bucket = hash_bucket(hash, hv);
 
+multi_assign_peer_id(m, mi);
+
 he = hash_lookup_fast(hash, bucket, >real, hv);
 
 if (he)
-- 
2.36.1



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH 2/4] rework do_up() for correct order of DCO operations

2022-05-06 Thread Kristof Provost via Openvpn-devel

On 29 Apr 2022, at 19:02, Kristof Provost wrote:

From: Kristof Provost 

We must create the peer before we can dco_set_peer or dco_new_key.
On the other hand, we must first process options, because those may
change our peer id and we should create the peer with the correct id.

Split up do_deferred_options() in do_deferred_options() and
finish_options(). Call any DCO configuration operations (i.e.
dco_set_peer()/dco_new_key()) after we've created the peer (i.e.
dco_new_peer()).

Signed-off-by: Kristof Provost 
---
 src/openvpn/init.c  | 112 
+---

 src/openvpn/init.h  |   2 +
 src/openvpn/multi.c |   2 +
 3 files changed, 68 insertions(+), 48 deletions(-)

diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 8496e21f..5d53cf7e 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -2100,26 +2100,26 @@ do_up(struct context *c, bool pulled_options, 
unsigned int option_types_found)

 }
 }

-if ((c->mode == MODE_POINT_TO_POINT) && c->c2.did_open_tun)
+if (pulled_options)
 {
-/* If we are in DCO mode we need to set the new peer 
options now */

-int ret = dco_p2p_add_new_peer(c);
-if (ret < 0)
+if (!do_deferred_options(c, option_types_found))
 {
-msg(D_DCO, "Cannot add peer to DCO: %s", 
strerror(-ret));
+msg(D_PUSH_ERRORS, "ERROR: Failed to apply push 
options");

 return false;
 }
 }
-
-if (pulled_options)
+if (c->mode == MODE_POINT_TO_POINT)
 {
-if (!do_deferred_options(c, option_types_found))
+/* If we are in DCO mode we need to set the new peer 
options now */

+int ret = dco_p2p_add_new_peer(c);
+if (ret < 0)
 {
-msg(D_PUSH_ERRORS, "ERROR: Failed to apply push 
options");
+msg(D_DCO, "Cannot add peer to DCO: %s", 
strerror(-ret));

 return false;
 }
 }
-else if (c->mode == MODE_POINT_TO_POINT)
+
+if (!pulled_options && c->mode == MODE_POINT_TO_POINT)
 {
 if (!do_deferred_p2p_ncp(c))
 {
@@ -2128,6 +2128,13 @@ do_up(struct context *c, bool pulled_options, 
unsigned int option_types_found)

 }
 }

+
+if (!finish_options(c))
+{
+msg(D_TLS_ERRORS, "ERROR: Failed to finish option 
processing");

+return false;
+}
+
 if (c->c2.did_open_tun)
 {
 c->c1.pulled_options_digest_save = 
c->c2.pulled_options_digest;
@@ -2344,49 +2351,58 @@ do_deferred_options(struct context *c, const 
unsigned int found)

 {
 return false;
 }
-struct frame *frame_fragment = NULL;
+}
+
+return true;
+}
+
+bool
+finish_options(struct context *c)
+{
+if (!c->options.pull || !dco_enabled(>options))
+{
+return true;
+}
+
+struct frame *frame_fragment = NULL;
 #ifdef ENABLE_FRAGMENT
-if (c->options.ce.fragment)
-{
-frame_fragment = >c2.frame_fragment;
-}
+if (c->options.ce.fragment)
+{
+frame_fragment = >c2.frame_fragment;
+}
 #endif

-struct tls_session *session = 
>c2.tls_multi->session[TM_ACTIVE];
-if (!tls_session_update_crypto_params(c->c2.tls_multi, 
session,
-  >options, 
>c2.frame,

-  frame_fragment,
-  
get_link_socket_info(c)))

-{
-msg(D_TLS_ERRORS, "OPTIONS ERROR: failed to import crypto 
options");

-return false;
-}
+struct tls_session *session = 
>c2.tls_multi->session[TM_ACTIVE];

+if (!tls_session_update_crypto_params(c->c2.tls_multi, session,
+  >options, >c2.frame,
+  frame_fragment,
+  get_link_socket_info(c)))
+{
+msg(D_TLS_ERRORS, "OPTIONS ERROR: failed to import crypto 
options");

+return false;
+}

-if (dco_enabled(>options))
-{
-/* Check if the pushed options are compatible with DCO if 
we have

- * DCO enabled */
-if (!check_dco_pull_options(>options))
-{
-msg(D_TLS_ERRORS, "OPTIONS ERROR: pushed options are 
incompatible with "
-"data channel offload. Use --disable-dco to 
connect"

-"to this server");
-return false;
-}
+/* Check if the pushed options are compatible with DCO if we have
+ * DCO enabled */
+if (!check_dco_pull_options(>options))
+{
+msg(D_TLS_ERRORS, "OPTIONS ERROR: pushed options are 
incompatible with "

+"data channel offload. Use --disable-dco to 

[Openvpn-devel] [PATCH 4/4] ovpn-dco: introduce FreeBSD data-channel offload support

2022-04-29 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Implement data-channel offload for FreeBSD. The implementation and flow
is very similar to that of the Linux DCO support.

Signed-off-by: Kristof Provost 
---
 configure.ac   |   6 +-
 src/openvpn/Makefile.am|   1 +
 src/openvpn/dco_freebsd.c  | 636 +
 src/openvpn/dco_freebsd.h  |  59 +++
 src/openvpn/dco_internal.h |   1 +
 src/openvpn/forward.c  |   8 +-
 src/openvpn/mtcp.c |   6 +-
 src/openvpn/mudp.c |   2 +-
 src/openvpn/multi.c|   2 +-
 src/openvpn/options.c  |   8 +-
 src/openvpn/ovpn_dco_freebsd.h |  64 
 src/openvpn/tun.c  |   8 +-
 src/openvpn/tun.h  |   6 +
 13 files changed, 789 insertions(+), 18 deletions(-)
 create mode 100644 src/openvpn/dco_freebsd.c
 create mode 100644 src/openvpn/dco_freebsd.h
 create mode 100644 src/openvpn/ovpn_dco_freebsd.h

diff --git a/configure.ac b/configure.ac
index 85921ddb..c5b30d47 100644
--- a/configure.ac
+++ b/configure.ac
@@ -787,7 +787,11 @@ dnl
AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
for Linux])
AC_MSG_NOTICE([Enabled ovpn-dco support for Linux])
;;
-
+   *-*-freebsd*)
+   LIBS="${LIBS} -lnv"
+   AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
for FreeBSD])
+   AC_MSG_NOTICE([Enabled ovpn-dco support for FreeBSD])
+   ;;
*-mingw*)
AC_MSG_NOTICE([NOTE: --enable-dco ignored on Windows 
because it's always enabled])
;;
diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 2c7c95f9..ed23f39c 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -54,6 +54,7 @@ openvpn_SOURCES = \
crypto_openssl.c crypto_openssl.h \
crypto_mbedtls.c crypto_mbedtls.h \
dco.c dco.h dco_internal.h \
+   dco_freebsd.c dco_freebsd.h \
dco_linux.c dco_linux.h \
dco_win.c dco_win.h \
dhcp.c dhcp.h \
diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
new file mode 100644
index ..a14f3833
--- /dev/null
+++ b/src/openvpn/dco_freebsd.c
@@ -0,0 +1,636 @@
+/*
+ *  Interface to FreeBSD dco networking code
+ *
+ *  Copyright (C) 2022 Rubicon Communications, LLC (Netgate). All Rights 
Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#if defined(ENABLE_DCO) && defined(TARGET_FREEBSD)
+
+#include "syshead.h"
+
+#include 
+#include 
+#include 
+#include 
+
+#include "dco_freebsd.h"
+#include "dco.h"
+#include "tun.h"
+#include "crypto.h"
+#include "ssl_common.h"
+
+static nvlist_t *
+sockaddr_to_nvlist(const struct sockaddr *sa)
+{
+nvlist_t *nvl = nvlist_create(0);
+
+nvlist_add_number(nvl, "af", sa->sa_family);
+
+switch (sa->sa_family)
+{
+case AF_INET:
+{
+const struct sockaddr_in *in = (const struct sockaddr_in *)sa;
+nvlist_add_binary(nvl, "address", >sin_addr, 
sizeof(in->sin_addr));
+nvlist_add_number(nvl, "port", in->sin_port);
+break;
+}
+
+case AF_INET6:
+{
+const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *)sa;
+nvlist_add_binary(nvl, "address", >sin6_addr, 
sizeof(in6->sin6_addr));
+nvlist_add_number(nvl, "port", in6->sin6_port);
+break;
+}
+
+default:
+abort();
+}
+
+return (nvl);
+}
+
+int
+dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
+ struct sockaddr *localaddr, struct sockaddr *remoteaddr,
+ struct in_addr *remote_in4, struct in6_addr *remote_in6)
+{
+struct ifdrv drv;
+nvlist_t *nvl;
+int ret;
+
+nvl = nvlist_create(0);
+
+msg(D_DCO_DEBUG, "%s: peer-id %d, fd %d", __func__, peerid, sd);
+
+if (localaddr)
+{
+nvlist_add_nvlist(nvl, "local", sockaddr_to_nvlist(localaddr));
+}
+
+if (remoteaddr)
+{
+nvlist_add_nvlist(nvl, "remote", sockaddr_to_nvlist(remoteaddr));
+}
+
+if (remote_in4)
+{
+  

[Openvpn-devel] [PATCH DCO]: FreeBSD DCO support

2022-04-29 Thread Kristof Provost via Openvpn-devel
Hi,

Here's the latest revision of the FreeBSD DCO patch, as well as three
DCO-related fixes.

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 3/4] Ensure dynamic_name is always populated

2022-04-29 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

It's always used for open_tun_dco(), so we must ensure it's populated,
even if 'dev_node' is set.

Signed-off-by: Kristof Provost 
---
 src/openvpn/tun.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c
index 245a6507..7976ad11 100644
--- a/src/openvpn/tun.c
+++ b/src/openvpn/tun.c
@@ -1755,6 +1755,7 @@ open_tun_generic(const char *dev, const char *dev_type, 
const char *dev_node,
 if (dev_node)
 {
 openvpn_snprintf(tunname, sizeof(tunname), "%s", dev_node);
+strncpynt(dynamic_name, dev, sizeof(dynamic_name));
 }
 else
 {
-- 
2.36.0



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 2/4] rework do_up() for correct order of DCO operations

2022-04-29 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

We must create the peer before we can dco_set_peer or dco_new_key.
On the other hand, we must first process options, because those may
change our peer id and we should create the peer with the correct id.

Split up do_deferred_options() in do_deferred_options() and
finish_options(). Call any DCO configuration operations (i.e.
dco_set_peer()/dco_new_key()) after we've created the peer (i.e.
dco_new_peer()).

Signed-off-by: Kristof Provost 
---
 src/openvpn/init.c  | 112 +---
 src/openvpn/init.h  |   2 +
 src/openvpn/multi.c |   2 +
 3 files changed, 68 insertions(+), 48 deletions(-)

diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 8496e21f..5d53cf7e 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -2100,26 +2100,26 @@ do_up(struct context *c, bool pulled_options, unsigned 
int option_types_found)
 }
 }
 
-if ((c->mode == MODE_POINT_TO_POINT) && c->c2.did_open_tun)
+if (pulled_options)
 {
-/* If we are in DCO mode we need to set the new peer options now */
-int ret = dco_p2p_add_new_peer(c);
-if (ret < 0)
+if (!do_deferred_options(c, option_types_found))
 {
-msg(D_DCO, "Cannot add peer to DCO: %s", strerror(-ret));
+msg(D_PUSH_ERRORS, "ERROR: Failed to apply push options");
 return false;
 }
 }
-
-if (pulled_options)
+if (c->mode == MODE_POINT_TO_POINT)
 {
-if (!do_deferred_options(c, option_types_found))
+/* If we are in DCO mode we need to set the new peer options now */
+int ret = dco_p2p_add_new_peer(c);
+if (ret < 0)
 {
-msg(D_PUSH_ERRORS, "ERROR: Failed to apply push options");
+msg(D_DCO, "Cannot add peer to DCO: %s", strerror(-ret));
 return false;
 }
 }
-else if (c->mode == MODE_POINT_TO_POINT)
+
+if (!pulled_options && c->mode == MODE_POINT_TO_POINT)
 {
 if (!do_deferred_p2p_ncp(c))
 {
@@ -2128,6 +2128,13 @@ do_up(struct context *c, bool pulled_options, unsigned 
int option_types_found)
 }
 }
 
+
+if (!finish_options(c))
+{
+msg(D_TLS_ERRORS, "ERROR: Failed to finish option processing");
+return false;
+}
+
 if (c->c2.did_open_tun)
 {
 c->c1.pulled_options_digest_save = c->c2.pulled_options_digest;
@@ -2344,49 +2351,58 @@ do_deferred_options(struct context *c, const unsigned 
int found)
 {
 return false;
 }
-struct frame *frame_fragment = NULL;
+}
+
+return true;
+}
+
+bool
+finish_options(struct context *c)
+{
+if (!c->options.pull || !dco_enabled(>options))
+{
+return true;
+}
+
+struct frame *frame_fragment = NULL;
 #ifdef ENABLE_FRAGMENT
-if (c->options.ce.fragment)
-{
-frame_fragment = >c2.frame_fragment;
-}
+if (c->options.ce.fragment)
+{
+frame_fragment = >c2.frame_fragment;
+}
 #endif
 
-struct tls_session *session = >c2.tls_multi->session[TM_ACTIVE];
-if (!tls_session_update_crypto_params(c->c2.tls_multi, session,
-  >options, >c2.frame,
-  frame_fragment,
-  get_link_socket_info(c)))
-{
-msg(D_TLS_ERRORS, "OPTIONS ERROR: failed to import crypto 
options");
-return false;
-}
+struct tls_session *session = >c2.tls_multi->session[TM_ACTIVE];
+if (!tls_session_update_crypto_params(c->c2.tls_multi, session,
+  >options, >c2.frame,
+  frame_fragment,
+  get_link_socket_info(c)))
+{
+msg(D_TLS_ERRORS, "OPTIONS ERROR: failed to import crypto options");
+return false;
+}
 
-if (dco_enabled(>options))
-{
-/* Check if the pushed options are compatible with DCO if we have
- * DCO enabled */
-if (!check_dco_pull_options(>options))
-{
-msg(D_TLS_ERRORS, "OPTIONS ERROR: pushed options are 
incompatible with "
-"data channel offload. Use --disable-dco to connect"
-"to this server");
-return false;
-}
+/* Check if the pushed options are compatible with DCO if we have
+ * DCO enabled */
+if (!check_dco_pull_options(>options))
+{
+msg(D_TLS_ERRORS, "OPTIONS ERROR: pushed options are incompatible with 
"
+"data channel offload. Use --disable-dco to connect"
+"to this server");
+return false;
+}
 
-

[Openvpn-devel] [PATCH 1/4] Handle (DCO) timeouts in client mode

2022-04-29 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Handle the DCO driver telling us that the peer went away, even if we're
not running in multi-instance mode.

Signed-off-by:  Kristof Provost 
---
 src/openvpn/forward.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c
index 9ddea439..e4215b70 100644
--- a/src/openvpn/forward.c
+++ b/src/openvpn/forward.c
@@ -,6 +,12 @@ process_incoming_dco(struct context *c)
 
 dco_do_read(dco);
 
+if (dco->dco_message_type == OVPN_CMD_DEL_PEER)
+{
+trigger_ping_timeout_signal(c);
+return;
+}
+
 if (dco->dco_message_type != OVPN_CMD_PACKET)
 {
 msg(D_DCO_DEBUG, "%s: received message of type %u - ignoring", 
__func__,
-- 
2.36.0



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH] Handle (DCO) timeouts in client mode

2022-04-27 Thread Kristof Provost via Openvpn-devel
On 27 Apr 2022, at 9:55, Antonio Quartulli wrote:
> Hi Kristof,
>
> On 27/04/2022 09:48, Kristof Provost via Openvpn-devel wrote:
>> From: Kristof Provost 
>>
>> Handle the DCO driver telling us that the peer went away, even if we're
>> not running in multi-instance mode.
>
> thanks for catching and fixing this. It was indeed on the todo list, but well 
> hidden under the rest :-D
>
I know how todo piles work all too well.

>>
>> Signed-off-by:   Kristof Provost 
>> ---
>>   src/openvpn/forward.c | 6 ++
>>   1 file changed, 6 insertions(+)
>>
>> diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c
>> index 9ddea439..f60c56a8 100644
>> --- a/src/openvpn/forward.c
>> +++ b/src/openvpn/forward.c
>> @@ -,6 +,12 @@ process_incoming_dco(struct context *c)
>>dco_do_read(dco);
>>  +if (dco->dco_message_type == OVPN_NOTIF_DEL_PEER)
>
> Not sure where this constant is coming from, but on ovpn_dco_linux.h we have 
> OVPN_CMD_DEL_PEER (similar format as the following OVPN_CMD_PACKET).
>
> Is that a format we can adhere to on BSD as well?
>
Good catch. OVPN_NOTIF_DEL_PEER  is specific to the FreeBSD DCO interface and 
shouldn’t be used in the generic openvpn code. It worked accidentally because 
it has the same value as OVPN_CMD_DEL_PEER. We should indeed be using 
OVPN_CMD_DEL_PEER here.

I’ll update the patch and probably submit both the freebsd dco patch and this 
together in a few hours.

Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] Handle (DCO) timeouts in client mode

2022-04-27 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Handle the DCO driver telling us that the peer went away, even if we're
not running in multi-instance mode.

Signed-off-by:  Kristof Provost 
---
 src/openvpn/forward.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c
index 9ddea439..f60c56a8 100644
--- a/src/openvpn/forward.c
+++ b/src/openvpn/forward.c
@@ -,6 +,12 @@ process_incoming_dco(struct context *c)
 
 dco_do_read(dco);
 
+if (dco->dco_message_type == OVPN_NOTIF_DEL_PEER)
+{
+trigger_ping_timeout_signal(c);
+return;
+}
+
 if (dco->dco_message_type != OVPN_CMD_PACKET)
 {
 msg(D_DCO_DEBUG, "%s: received message of type %u - ignoring", 
__func__,
-- 
2.36.0



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCHv2 DCO]: Handle (DCO) timeouts in client mode

2022-04-27 Thread Kristof Provost via Openvpn-devel
Updated version of the timeout fix for client mode.
This time with trigger_ping_timeout_signal() as suggested by Arne.

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] Handle (DCO) timeouts in client mode

2022-04-26 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Handle the DCO driver telling us that the peer went away, even if we're
not running in multi-instance mode.

Signed-off-by:  Kristof Provost 
---
 src/openvpn/forward.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c
index 9ddea439..25fa300f 100644
--- a/src/openvpn/forward.c
+++ b/src/openvpn/forward.c
@@ -,6 +,12 @@ process_incoming_dco(struct context *c)
 
 dco_do_read(dco);
 
+if (dco->dco_message_type == OVPN_NOTIF_DEL_PEER)
+{
+register_signal(c, SIGTERM, "ping timeout");
+return;
+}
+
 if (dco->dco_message_type != OVPN_CMD_PACKET)
 {
 msg(D_DCO_DEBUG, "%s: received message of type %u - ignoring", 
__func__,
-- 
2.36.0



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH DCO]: Handle (DCO) timeouts in client mode

2022-04-26 Thread Kristof Provost via Openvpn-devel
Hi,

During testing of FreeBSD DCO support we discovered that a DCO enabled
client does not detect that the server has gone away, even if
'keepalive' is set.

This turns out to be because we only handle DCO notification messages in
the multi-instance (i.e. server) code path.
I'm not 100% sure this patch does the correct thing, but we do need to
do something at the point it changes.

Br,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH DCO]: FreeBSD DCO support

2022-04-13 Thread Kristof Provost via Openvpn-devel
Hi,

This is my second attempt at sending in the updated FreeBSD DCO support
patch. (The previous version had a cleanup patch but nothing else).

The main difference to the previous version is that is passes the
peer_id in most calls. There have been some changes on the driver side
to improve server mode support, which required this information.

This requires the FreeBSD driver in https://reviews.freebsd.org/D34340

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] ovpn-dco: introduce FreeBSD data-channel offload support

2022-04-13 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Implement data-channel offload for FreeBSD. The implementation and flow
is very similar to that of the Linux DCO support.

Signed-off-by: Kristof Provost 
---
 configure.ac   |   6 +-
 src/openvpn/Makefile.am|   1 +
 src/openvpn/dco_freebsd.c  | 621 +
 src/openvpn/dco_freebsd.h  |  58 +++
 src/openvpn/dco_internal.h |   1 +
 src/openvpn/forward.c  |   8 +-
 src/openvpn/mtcp.c |   6 +-
 src/openvpn/mudp.c |   2 +-
 src/openvpn/multi.c|   2 +-
 src/openvpn/options.c  |   8 +-
 src/openvpn/ovpn_dco_freebsd.h |  64 
 src/openvpn/tun.c  |   8 +-
 src/openvpn/tun.h  |   6 +
 13 files changed, 773 insertions(+), 18 deletions(-)
 create mode 100644 src/openvpn/dco_freebsd.c
 create mode 100644 src/openvpn/dco_freebsd.h
 create mode 100644 src/openvpn/ovpn_dco_freebsd.h

diff --git a/configure.ac b/configure.ac
index 85921ddb..c5b30d47 100644
--- a/configure.ac
+++ b/configure.ac
@@ -787,7 +787,11 @@ dnl
AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
for Linux])
AC_MSG_NOTICE([Enabled ovpn-dco support for Linux])
;;
-
+   *-*-freebsd*)
+   LIBS="${LIBS} -lnv"
+   AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
for FreeBSD])
+   AC_MSG_NOTICE([Enabled ovpn-dco support for FreeBSD])
+   ;;
*-mingw*)
AC_MSG_NOTICE([NOTE: --enable-dco ignored on Windows 
because it's always enabled])
;;
diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 2c7c95f9..ed23f39c 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -54,6 +54,7 @@ openvpn_SOURCES = \
crypto_openssl.c crypto_openssl.h \
crypto_mbedtls.c crypto_mbedtls.h \
dco.c dco.h dco_internal.h \
+   dco_freebsd.c dco_freebsd.h \
dco_linux.c dco_linux.h \
dco_win.c dco_win.h \
dhcp.c dhcp.h \
diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
new file mode 100644
index ..8c300639
--- /dev/null
+++ b/src/openvpn/dco_freebsd.c
@@ -0,0 +1,621 @@
+/*
+ *  Interface to FreeBSD dco networking code
+ *
+ *  Copyright (C) 2022 Rubicon Communications, LLC (Netgate). All Rights 
Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#if defined(ENABLE_DCO) && defined(TARGET_FREEBSD)
+
+#include "syshead.h"
+
+#include 
+#include 
+#include 
+#include 
+
+#include "dco_freebsd.h"
+#include "dco.h"
+#include "tun.h"
+#include "crypto.h"
+#include "ssl_common.h"
+
+static nvlist_t *
+sockaddr_to_nvlist(const struct sockaddr *sa)
+{
+nvlist_t *nvl = nvlist_create(0);
+
+nvlist_add_number(nvl, "af", sa->sa_family);
+
+switch (sa->sa_family) {
+case AF_INET:
+{
+const struct sockaddr_in *in = (const struct sockaddr_in*)sa;
+nvlist_add_binary(nvl, "address", >sin_addr, sizeof(in->sin_addr));
+nvlist_add_number(nvl, "port", in->sin_port);
+break;
+}
+case AF_INET6:
+{
+const struct sockaddr_in6 *in6 = (const struct sockaddr_in6*)sa;
+nvlist_add_binary(nvl, "address", >sin6_addr, 
sizeof(in6->sin6_addr));
+nvlist_add_number(nvl, "port", in6->sin6_port);
+break;
+}
+default:
+abort();
+}
+
+return (nvl);
+}
+
+int
+dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
+ struct sockaddr *localaddr, struct sockaddr *remoteaddr,
+ struct in_addr *remote_in4, struct in6_addr *remote_in6)
+{
+struct ifdrv drv;
+nvlist_t *nvl;
+int ret;
+
+nvl = nvlist_create(0);
+
+msg(D_DCO_DEBUG, "%s: peer-id %d, fd %d", __func__, peerid, sd);
+
+if (localaddr)
+{
+nvlist_add_nvlist(nvl, "local", sockaddr_to_nvlist(localaddr));
+}
+
+if (remoteaddr)
+{
+nvlist_add_nvlist(nvl, "remote", sockaddr_to_nvlist(remoteaddr));
+}
+
+if (remote_in4)
+{
+nvlist_add_binary(nvl, "vpn_ipv4", _in4->s_addr,
+

[Openvpn-devel] [PATCH] pass vpn addresses to the kernel

2022-04-13 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

---
 src/openvpn/dco_freebsd.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index 3f8b39e0..8c300639 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -91,6 +91,17 @@ dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
 nvlist_add_nvlist(nvl, "remote", sockaddr_to_nvlist(remoteaddr));
 }
 
+if (remote_in4)
+{
+nvlist_add_binary(nvl, "vpn_ipv4", _in4->s_addr,
+sizeof(remote_in4->s_addr));
+}
+
+if (remote_in6)
+{
+nvlist_add_binary(nvl, "vpn_ipv6", remote_in6, sizeof(*remote_in6));
+}
+
 nvlist_add_number(nvl, "fd", sd);
 nvlist_add_number(nvl, "peerid", peerid);
 
-- 
2.35.1



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH DCO]: FreeBSD DCO support

2022-04-13 Thread Kristof Provost via Openvpn-devel
Hi,

Here's an updated and rebased patch for FreeBSD DCO support.
The main difference to the previous version is that is passes the
peer_id in most calls. There's been some changes on the driver side to
improve server mode support, which required this information.

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH DCO]: FreeBSD DCO support

2022-04-01 Thread Kristof Provost via Openvpn-devel
Hi,

Here's an updated version of the FreeBSD DCO patch.
It rebases on top of the latest dco branch version (mostly trivial
changes) and adds support for timing out peers.
That requires the latest version of the kernel driver:
https://reviews.freebsd.org/D34340

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] ovpn-dco: introduce FreeBSD data-channel offload support

2022-04-01 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Implement data-channel offload for FreeBSD. The implementation and flow
is very similar to that of the Linux DCO support.

Signed-off-by: Kristof Provost 
---
 configure.ac   |   6 +-
 src/openvpn/Makefile.am|   1 +
 src/openvpn/dco_freebsd.c  | 594 +
 src/openvpn/dco_freebsd.h  |  58 
 src/openvpn/dco_internal.h |   1 +
 src/openvpn/forward.c  |   8 +-
 src/openvpn/mtcp.c |   6 +-
 src/openvpn/mudp.c |   2 +-
 src/openvpn/multi.c|   2 +-
 src/openvpn/options.c  |   8 +-
 src/openvpn/ovpn_dco_freebsd.h |  64 
 src/openvpn/tun.c  |   8 +-
 src/openvpn/tun.h  |   6 +
 13 files changed, 746 insertions(+), 18 deletions(-)
 create mode 100644 src/openvpn/dco_freebsd.c
 create mode 100644 src/openvpn/dco_freebsd.h
 create mode 100644 src/openvpn/ovpn_dco_freebsd.h

diff --git a/configure.ac b/configure.ac
index 7199483a..d3ebc932 100644
--- a/configure.ac
+++ b/configure.ac
@@ -787,7 +787,11 @@ dnl
AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
for Linux])
AC_MSG_NOTICE([Enabled ovpn-dco support for Linux])
;;
-
+   *-*-freebsd*)
+   LIBS="${LIBS} -lnv"
+   AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
for FreeBSD])
+   AC_MSG_NOTICE([Enabled ovpn-dco support for FreeBSD])
+   ;;
*-mingw*)
AC_MSG_NOTICE([NOTE: --enable-dco ignored on Windows 
because it's always enabled])
;;
diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 84fd3202..4515935e 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -54,6 +54,7 @@ openvpn_SOURCES = \
crypto_openssl.c crypto_openssl.h \
crypto_mbedtls.c crypto_mbedtls.h \
dco.c dco.h dco_internal.h \
+   dco_freebsd.c dco_freebsd.h \
dco_linux.c dco_linux.h \
dco_win.c dco_win.h \
dhcp.c dhcp.h \
diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
new file mode 100644
index ..508137e0
--- /dev/null
+++ b/src/openvpn/dco_freebsd.c
@@ -0,0 +1,594 @@
+/*
+ *  Interface to FreeBSD dco networking code
+ *
+ *  Copyright (C) 2022 Rubicon Communications, LLC (Netgate). All Rights 
Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#if defined(ENABLE_DCO) && defined(TARGET_FREEBSD)
+
+#include "syshead.h"
+
+#include 
+#include 
+#include 
+#include 
+
+#include "dco_freebsd.h"
+#include "dco.h"
+#include "tun.h"
+#include "crypto.h"
+#include "ssl_common.h"
+
+static nvlist_t *
+sockaddr_to_nvlist(const struct sockaddr *sa)
+{
+nvlist_t *nvl = nvlist_create(0);
+
+nvlist_add_number(nvl, "af", sa->sa_family);
+
+switch (sa->sa_family) {
+case AF_INET:
+{
+const struct sockaddr_in *in = (const struct sockaddr_in*)sa;
+nvlist_add_binary(nvl, "address", >sin_addr, sizeof(in->sin_addr));
+nvlist_add_number(nvl, "port", in->sin_port);
+break;
+}
+case AF_INET6:
+{
+const struct sockaddr_in6 *in6 = (const struct sockaddr_in6*)sa;
+nvlist_add_binary(nvl, "address", >sin6_addr, 
sizeof(in6->sin6_addr));
+nvlist_add_number(nvl, "port", in6->sin6_port);
+break;
+}
+default:
+abort();
+}
+
+return (nvl);
+}
+
+int
+dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
+ struct sockaddr *localaddr, struct sockaddr *remoteaddr,
+ struct in_addr *remote_in4, struct in6_addr *remote_in6)
+{
+struct ifdrv drv;
+nvlist_t *nvl;
+int ret;
+
+nvl = nvlist_create(0);
+
+msg(D_DCO_DEBUG, "%s: peer-id %d, fd %d", __func__, peerid, sd);
+
+if (localaddr)
+{
+nvlist_add_nvlist(nvl, "local", sockaddr_to_nvlist(localaddr));
+}
+
+if (remoteaddr)
+{
+nvlist_add_nvlist(nvl, "remote", sockaddr_to_nvlist(remoteaddr));
+}
+
+nvlist_add_number(nvl, "fd", sd);
+
+bzero(, sizeof(drv));
+snprintf(drv.ifd_name, IFNAMSIZ, 

[Openvpn-devel] [PATCH DCO]: FreeBSD DCO support

2022-03-10 Thread Kristof Provost via Openvpn-devel
Hi,

Here's an updated version of the FreeBSD DCO patch. It addresses a few
code style issues, moves the if_ovpn.h header into the tree and is
rebased on top of the latest DCO branch version.

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH] ovpn-dco: introduce FreeBSD data-channel offload support

2022-03-10 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Implement data-channel offload for FreeBSD. The implementation and flow
is very similar to that of the Linux DCO support.

Signed-off-by: Kristof Provost 
---
 configure.ac   |   6 +-
 src/openvpn/Makefile.am|   1 +
 src/openvpn/dco_freebsd.c  | 584 +
 src/openvpn/dco_freebsd.h  |  46 +++
 src/openvpn/dco_internal.h |   1 +
 src/openvpn/forward.c  |   6 +-
 src/openvpn/mtcp.c |   6 +-
 src/openvpn/multi.c|  32 +-
 src/openvpn/options.c  |   4 +-
 src/openvpn/ovpn_dco_freebsd.h |  60 
 src/openvpn/tun.c  |   8 +-
 src/openvpn/tun.h  |   6 +
 12 files changed, 746 insertions(+), 14 deletions(-)
 create mode 100644 src/openvpn/dco_freebsd.c
 create mode 100644 src/openvpn/dco_freebsd.h
 create mode 100644 src/openvpn/ovpn_dco_freebsd.h

diff --git a/configure.ac b/configure.ac
index cdfb198e..18840ae7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -787,7 +787,11 @@ dnl
AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
for Linux])
AC_MSG_NOTICE([Enabled ovpn-dco support for Linux])
;;
-
+   *-*-freebsd*)
+   LIBS="${LIBS} -lnv"
+   AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
for FreeBSD])
+   AC_MSG_NOTICE([Enabled ovpn-dco support for FreeBSD])
+   ;;
*-mingw*)
AC_MSG_NOTICE([NOTE: --enable-dco ignored on Windows 
because it's always enabled])
;;
diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 84fd3202..4515935e 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -54,6 +54,7 @@ openvpn_SOURCES = \
crypto_openssl.c crypto_openssl.h \
crypto_mbedtls.c crypto_mbedtls.h \
dco.c dco.h dco_internal.h \
+   dco_freebsd.c dco_freebsd.h \
dco_linux.c dco_linux.h \
dco_win.c dco_win.h \
dhcp.c dhcp.h \
diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
new file mode 100644
index ..fbbe22c8
--- /dev/null
+++ b/src/openvpn/dco_freebsd.c
@@ -0,0 +1,584 @@
+/*
+ *  Interface to FreeBSD dco networking code
+ *
+ *  Copyright (C) 2022 Rubicon Communications, LLC (Netgate). All Rights 
Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#if defined(ENABLE_DCO) && defined(TARGET_FREEBSD)
+
+#include "syshead.h"
+
+#include 
+#include 
+#include 
+#include 
+
+#include "dco_freebsd.h"
+#include "dco.h"
+#include "tun.h"
+#include "crypto.h"
+#include "ssl_common.h"
+
+static nvlist_t *
+sockaddr_to_nvlist(const struct sockaddr *sa)
+{
+nvlist_t *nvl = nvlist_create(0);
+
+nvlist_add_number(nvl, "af", sa->sa_family);
+
+switch (sa->sa_family) {
+case AF_INET:
+{
+const struct sockaddr_in *in = (const struct sockaddr_in*)sa;
+nvlist_add_binary(nvl, "address", >sin_addr, sizeof(in->sin_addr));
+nvlist_add_number(nvl, "port", in->sin_port);
+break;
+}
+case AF_INET6:
+{
+const struct sockaddr_in6 *in6 = (const struct sockaddr_in6*)sa;
+nvlist_add_binary(nvl, "address", >sin6_addr, 
sizeof(in6->sin6_addr));
+nvlist_add_number(nvl, "port", in6->sin6_port);
+break;
+}
+default:
+abort();
+}
+
+return (nvl);
+}
+
+int
+dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
+ struct sockaddr *localaddr, struct sockaddr *remoteaddr,
+ struct in_addr *remote_in4, struct in6_addr *remote_in6)
+{
+struct ifdrv drv;
+nvlist_t *nvl;
+int ret;
+
+nvl = nvlist_create(0);
+
+msg(D_DCO_DEBUG, "%s: peer-id %d, fd %d", __func__, peerid, sd);
+
+if (localaddr)
+{
+nvlist_add_nvlist(nvl, "local", sockaddr_to_nvlist(localaddr));
+}
+
+if (remoteaddr)
+{
+nvlist_add_nvlist(nvl, "remote", sockaddr_to_nvlist(remoteaddr));
+}
+
+nvlist_add_number(nvl, "fd", sd);
+
+bzero(, sizeof(drv));
+snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
+drv.ifd_cmd = 

Re: [Openvpn-devel] [PATCH 2/2] ovpn-dco: introduce FreeBSD data-channel offload support

2022-03-08 Thread Kristof Provost via Openvpn-devel
On 8 Mar 2022, at 15:36, Antonio Quartulli wrote:
> On 08/03/2022 15:29, Kristof Provost wrote:
>> Theoretically I’d prefer to use the OS header, but I can certainly see the 
>> upside of not having that dependency. We’ll always have to do the runtime 
>> check (dco_available()) anyway, so I can certainly live with that.
>>
>>> p.s. as a side note, the rest of the code contains some "code style" 
>>> issues. Nothing major, but wanted to mention it (we can discuss on IRC if 
>>> you want).
>>>
>> I’m happy to fix that. Do you have a rough list of what’s wrong?
>> https://community.openvpn.net/openvpn/wiki/CodeStyle is the authoritative 
>> style guide, right?
>
> Correct. Not everything might be there, so feel free to ask for any 
> clarification on IRC. Your code is already pretty clean actually.
> Some things I have seen:
> - We tend to avoid "if (a == NULL)" (or "!= 0") in favor of just "if (a)";
> - We avoid spaces after the cast operator;
> - we always use brackets {} for one-line blocks;
>
Thanks!

Most of those are probably because I’m used to FreeBSD’s style 
(https://www.freebsd.org/cgi/man.cgi?query=style=0=0=FreeBSD+13.0-RELEASE+and+Ports=default=html),
 but consistency is important.

I’ll update the patch (and also address the SET_TIMEOUT thing) soon. I’ve got a 
bit of travel coming up, so I’m not quite sure when it’ll be though.

Best regards,
Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH DCO]: FreeBSD DCO support

2022-03-08 Thread Kristof Provost via Openvpn-devel
On 8 Mar 2022, at 15:23, Antonio Quartulli wrote:
> On 24/02/2022 17:55, Kristof Provost via Openvpn-devel wrote:
>> I've had to add a lot of '|| defined(TARGET_FREEBSD)', and I think the
>> code could be a bit cleaner if we'd make these calls conditional only on
>> defined(ENABLE_DCO), and instead expect every DCO implementation to
>> provide them, if only as stubs. I've not done that here.
>
> Can you name what new internal APIs would you want to add?
> I am also in favor of less ifdefs and have APIs that can be defined as stub 
> or not based on the platform.
>
We’ve got a significant number of cases where we call DCO functions for Linux & 
FreeBSD but not for Windows.
One example is the call to dco_event_state() in multi_tcp_wait() and 
io_wait_doword().
If windows provided an implementation for that, even if it did no work, we 
could replace ‘#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)’ with an 
‘#ifdef ENABLE_DCO’. If we provided a stub implementation for the DCO functions 
even for non-DCO builds we wouldn’t need any ‘#ifdef’ at all.

> A comment for your kernel API:
> I have seen you created an API named "OVPN_SET_TIMEOUT", however I'd suggest 
> to name it "OVPN_SET_PEER" (like on Linux and Windows), because the idea is 
> that this call will be used to set any additional/optional per-peer param.
>
> For example, we have been recently working on mssfix, which we may want to 
> set on a per-peer basis (more params may come later).
>
> The SET_PEER call will allow to set all these params (if specified).
>
> What do you think?
>
I think I renamed it because I found the ‘SET_PEER’ name to be easy to confuse 
with ‘NEW_PEER’, but I’m happy to align to other platforms.

Best regards,
Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


Re: [Openvpn-devel] [PATCH 2/2] ovpn-dco: introduce FreeBSD data-channel offload support

2022-03-08 Thread Kristof Provost via Openvpn-devel
On 8 Mar 2022, at 15:16, Antonio Quartulli wrote:
> Hi Kristof,
>
> A quick question for you, see below
>
> On 24/02/2022 17:55, Kristof Provost via Openvpn-devel wrote:
>> --- a/configure.ac
>> +++ b/configure.ac
>> @@ -787,7 +787,20 @@ dnl
>>  AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
>> for Linux])
>>  AC_MSG_NOTICE([Enabled ovpn-dco support for Linux])
>>  ;;
>> -
>> +*-*-freebsd*)
>> +DCO_CFLAGS="-I${DCO_SOURCEDIR}"
>> +saved_CFLAGS="${CFLAGS}"
>> +CFLAGS="${CFLAGS} ${DCO_CFLAGS}"
>> +AC_CHECK_HEADERS(
>> + [if_ovpn.h],
>> + ,
>> + [AC_MSG_ERROR([if_ovpn.h is missing 
>> (use DCO_SOURCEDIR to set path to it, CFLAGS=${CFLAGS})])]
>> + )
>> +CFLAGS=${saved_CFLAGS}
>> +LIBS="${LIBS} -lnv"
>> +AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
>> for FreeBSD])
>> +AC_MSG_NOTICE([Enabled ovpn-dco support for FreeBSD])
>> +;;
>
> If you double check the latest dco branch, you will see that I have dropped 
> the DCO_SOURCEDIR variable and I have rather switched to "let's include the 
> kernel API header in the openvpn repository all the time and be happy with 
> it".
>
> The idea is that the kernel API will always be backwards compatible, 
> therefore having a stale header will never be a problem. It can be updated 
> when a new feature is implemented in openvpn itself. (a similar approach is 
> taken by hostapd or iw on Linux, where they ship a copy of nl80211.h)
>
> On the other hand, we drastically simplify the configure logic and avoid 
> having to deal with this variable which may have different pitfalls on 
> different platforms.
>
> Do you have any opinion about the above? or shipping a copy of the header 
> with openvpn source code is fine with you?
>
It’s not really too relevant either way for FreeBSD, because the header 
contains very little information. It’s mostly only the ioctl numbers. There are 
no structures shared between the kernel and user land. Instead we use nvlists 
(name/value pair serialisation).

Theoretically I’d prefer to use the OS header, but I can certainly see the 
upside of not having that dependency. We’ll always have to do the runtime check 
(dco_available()) anyway, so I can certainly live with that.

> p.s. as a side note, the rest of the code contains some "code style" issues. 
> Nothing major, but wanted to mention it (we can discuss on IRC if you want).
>
I’m happy to fix that. Do you have a rough list of what’s wrong?
https://community.openvpn.net/openvpn/wiki/CodeStyle is the authoritative style 
guide, right?

Best regards,
Kristof


___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 2/2] ovpn-dco: introduce FreeBSD data-channel offload support

2022-02-24 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Implement data-channel offload for FreeBSD. The implementation and flow
is very similar to that of the Linux DCO support.

Signed-off-by: Kristof Provost 
---
 configure.ac   |  15 +-
 src/openvpn/Makefile.am|   1 +
 src/openvpn/dco_freebsd.c  | 559 +
 src/openvpn/dco_freebsd.h  |  47 
 src/openvpn/dco_internal.h |   1 +
 src/openvpn/forward.c  |   6 +-
 src/openvpn/mtcp.c |   6 +-
 src/openvpn/multi.c|  32 ++-
 src/openvpn/options.c  |   4 +-
 src/openvpn/tun.c  |   8 +-
 src/openvpn/tun.h  |   6 +
 11 files changed, 671 insertions(+), 14 deletions(-)
 create mode 100644 src/openvpn/dco_freebsd.c
 create mode 100644 src/openvpn/dco_freebsd.h

diff --git a/configure.ac b/configure.ac
index cdfb198e..bf1013cc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -787,7 +787,20 @@ dnl
AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
for Linux])
AC_MSG_NOTICE([Enabled ovpn-dco support for Linux])
;;
-
+   *-*-freebsd*)
+   DCO_CFLAGS="-I${DCO_SOURCEDIR}"
+   saved_CFLAGS="${CFLAGS}"
+   CFLAGS="${CFLAGS} ${DCO_CFLAGS}"
+   AC_CHECK_HEADERS(
+[if_ovpn.h],
+,
+[AC_MSG_ERROR([if_ovpn.h is missing 
(use DCO_SOURCEDIR to set path to it, CFLAGS=${CFLAGS})])]
+)
+   CFLAGS=${saved_CFLAGS}
+   LIBS="${LIBS} -lnv"
+   AC_DEFINE(ENABLE_DCO, 1, [Enable data channel offload 
for FreeBSD])
+   AC_MSG_NOTICE([Enabled ovpn-dco support for FreeBSD])
+   ;;
*-mingw*)
AC_MSG_NOTICE([NOTE: --enable-dco ignored on Windows 
because it's always enabled])
;;
diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index b11c3f9e..c4dbf706 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -54,6 +54,7 @@ openvpn_SOURCES = \
crypto_openssl.c crypto_openssl.h \
crypto_mbedtls.c crypto_mbedtls.h \
dco.c dco.h dco_internal.h \
+   dco_freebsd.c dco_freebsd.h \
dco_linux.c dco_linux.h \
dco_win.c dco_win.h \
dhcp.c dhcp.h \
diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
new file mode 100644
index ..8e048d74
--- /dev/null
+++ b/src/openvpn/dco_freebsd.c
@@ -0,0 +1,559 @@
+/*
+ *  Interface to FreeBSD dco networking code
+ *
+ *  Copyright (C) 2022 Rubicon Communications, LLC (Netgate). All Rights 
Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#if defined(ENABLE_DCO) && defined(TARGET_FREEBSD)
+
+#include "syshead.h"
+
+#include 
+#include 
+#include 
+#include 
+
+#include "dco_freebsd.h"
+#include "dco.h"
+#include "tun.h"
+#include "crypto.h"
+#include "ssl_common.h"
+
+static nvlist_t *
+sockaddr_to_nvlist(const struct sockaddr *sa)
+{
+nvlist_t *nvl = nvlist_create(0);
+
+nvlist_add_number(nvl, "af", sa->sa_family);
+
+switch (sa->sa_family) {
+case AF_INET:
+{
+const struct sockaddr_in *in = (const struct sockaddr_in *)sa;
+nvlist_add_binary(nvl, "address", >sin_addr, sizeof(in->sin_addr));
+nvlist_add_number(nvl, "port", in->sin_port);
+break;
+}
+case AF_INET6:
+{
+const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *)sa;
+nvlist_add_binary(nvl, "address", >sin6_addr, 
sizeof(in6->sin6_addr));
+nvlist_add_number(nvl, "port", in6->sin6_port);
+break;
+}
+default:
+abort();
+}
+
+return (nvl);
+}
+
+int
+dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
+struct sockaddr *localaddr, struct sockaddr *remoteaddr,
+struct in_addr *remote_in4, struct in6_addr *remote_in6)
+{
+struct ifdrv drv;
+nvlist_t *nvl;
+int ret;
+
+nvl = nvlist_create(0);
+
+msg(D_DCO_DEBUG, "%s: peer-id %d, fd %d", __func__, 

[Openvpn-devel] [PATCH 1/2] dco: process DCO control packets

2022-02-24 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

If control packets come in through the DCO interface (i.e. via
dco_do_read()) we must process them through process_incoming_link().
This doesn't currently manifest, because Linux passes control packets
through the regular socket, not via the DCO netlink interface, but other
platforms will not.

Signed-off-by: Kristof Provost 
---
 src/openvpn/forward.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c
index cd956cb3..c16f32fc 100644
--- a/src/openvpn/forward.c
+++ b/src/openvpn/forward.c
@@ -1104,8 +1104,16 @@ process_incoming_link(struct context *c)
 static void
 process_incoming_dco(struct context *c)
 {
+struct link_socket_info *lsi = get_link_socket_info(c);
+
 msg(M_INFO, __func__);
 dco_do_read(>c1.tuntap->dco);
+
+c->c2.buf = c->c1.tuntap->dco.dco_packet_in;
+c->c2.from = lsi->lsa->actual;
+
+process_incoming_link(c);
+buf_init(>c1.tuntap->dco.dco_packet_in, 0);
 }
 
 /*
-- 
2.35.1



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH DCO]: FreeBSD DCO support

2022-02-24 Thread Kristof Provost via Openvpn-devel
Hi,

Here's the current version of the patch to add FreeBSD DCO support.

The first patch isn't strictly related to FreeBSD, but fixes what I
think is a generic issue. It doesn't manifest with Linux because the
Linux DCO driver allows control packets to continue through normal UDP
processing. We don't do that in FreeBSD, so it manifests there.

I've had to add a lot of '|| defined(TARGET_FREEBSD)', and I think the
code could be a bit cleaner if we'd make these calls conditional only on
defined(ENABLE_DCO), and instead expect every DCO implementation to
provide them, if only as stubs. I've not done that here.

For those interested in testing, the kernel side of things is under
review here: https://reviews.freebsd.org/D34340

Best,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 1/3] dco: dco_meesage_peer_id -> dco_message_peer_id

2022-02-22 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Fix typo in variable name.

Signed-off-by: Kristof Provost 
---
 src/openvpn/dco_linux.c | 6 +++---
 src/openvpn/dco_linux.h | 2 +-
 src/openvpn/multi.c | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/openvpn/dco_linux.c b/src/openvpn/dco_linux.c
index 9fddb788..341e9ae7 100644
--- a/src/openvpn/dco_linux.c
+++ b/src/openvpn/dco_linux.c
@@ -436,7 +436,7 @@ open_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx, 
const char *dev)
 tt->actual_name = string_alloc(dev, NULL);
 uint8_t *dcobuf = malloc(65536);
 buf_set_write(>dco.dco_packet_in, dcobuf, 65536);
-tt->dco.dco_meesage_peer_id = -1;
+tt->dco.dco_message_peer_id = -1;
 
 ovpn_dco_register(>dco);
 
@@ -742,7 +742,7 @@ static int ovpn_handle_msg(struct nl_msg *msg, void *arg)
 
 msg(D_DCO_DEBUG, "ovpn-dco: received CMD_DEL_PEER, ifindex: %d, 
peer-id %d, reason: %d",
 ifindex, peerid, reason);
-dco->dco_meesage_peer_id = peerid;
+dco->dco_message_peer_id = peerid;
 dco->dco_del_peer_reason = reason;
 dco->dco_message_type = OVPN_CMD_DEL_PEER;
 
@@ -788,7 +788,7 @@ static int ovpn_handle_msg(struct nl_msg *msg, void *arg)
 }
 buf_init(>dco_packet_in, 0);
 buf_write(>dco_packet_in, data, len);
-dco->dco_meesage_peer_id = peerid;
+dco->dco_message_peer_id = peerid;
 dco->dco_message_type = OVPN_CMD_PACKET;
 break;
 }
diff --git a/src/openvpn/dco_linux.h b/src/openvpn/dco_linux.h
index 94e1a522..61d07a55 100644
--- a/src/openvpn/dco_linux.h
+++ b/src/openvpn/dco_linux.h
@@ -51,7 +51,7 @@ typedef struct
 struct buffer dco_packet_in;
 
 int dco_message_type;
-int dco_meesage_peer_id;
+int dco_message_peer_id;
 int dco_del_peer_reason;
 
 } dco_context_t;
diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c
index cf44dd58..30489038 100644
--- a/src/openvpn/multi.c
+++ b/src/openvpn/multi.c
@@ -3124,7 +3124,7 @@ static void
 process_incoming_dco_packet(struct multi_context *m, struct multi_instance 
*mi,  dco_context_t *dco)
 {
 struct buffer orig_buf = mi->context.c2.buf;
-int peer_id = dco->dco_meesage_peer_id;
+int peer_id = dco->dco_message_peer_id;
 
 mi->context.c2.buf = dco->dco_packet_in;
 
@@ -3184,7 +3184,7 @@ multi_process_incoming_dco(struct multi_context *m)
 
 int ret = dco_do_read(>top.c1.tuntap->dco);
 
-int peer_id = dco->dco_meesage_peer_id;
+int peer_id = dco->dco_message_peer_id;
 
 if ((peer_id >= 0) && (peer_id < m->max_clients) && 
(m->instances[peer_id]))
 {
@@ -3204,7 +3204,7 @@ multi_process_incoming_dco(struct multi_context *m)
 }
 
 dco->dco_message_type = 0;
-dco->dco_meesage_peer_id = -1;
+dco->dco_message_peer_id = -1;
 return ret > 0;
 }
 #endif
-- 
2.35.1



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH DCO]: cleanups prior to FreeBSD DCO support

2022-02-22 Thread Kristof Provost via Openvpn-devel
Hi,

As said in my e-mail (from k...@freebsd.org, Feb 17th), I'm working on
adding DCO support for FreeBSD.
I ran into a few minor issues that are not directly related, but should
be addressed anyway.

These patches are all against https://github.com/OpenVPN/ovpn-dco

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 3/3] dco: Check for ipi_addr before using it

2022-02-22 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

If IP_RECVDSTADDR exists we'll define ENABLE_IP_PKTINFO, but that
doesn't actually mean we have struct in_pktinfo. We need to check
HAVE_IN_PKTINFO for that.

This fixes DCO builds on FreeBSD.

Signed-off-by: Kristof Provost 
---
 src/openvpn/dco.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/openvpn/dco.c b/src/openvpn/dco.c
index 0ce03664..4234bb22 100644
--- a/src/openvpn/dco.c
+++ b/src/openvpn/dco.c
@@ -44,7 +44,7 @@ static bool
 dco_multi_get_localaddr(struct multi_context *m, struct multi_instance *mi,
 struct sockaddr_storage *local)
 {
-#if ENABLE_IP_PKTINFO
+#if ENABLE_IP_PKTINFO && defined(HAVE_IN_PKTINFO)
 struct context *c = >context;
 
 if (!(c->options.sockflags & SF_USE_IP_PKTINFO))
-- 
2.35.1



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 2/3] open_tun_generic(): Do not consider open_tun_dco() returning 0 to be an error

2022-02-22 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

It seems clear that the intent here is to special case the EEXIST error,
not the consider anything else (i.e. 0) to also be an error.

Signed-off-by: Kristof Provost 
---
 src/openvpn/tun.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c
index f9ba3858..d8f2dea7 100644
--- a/src/openvpn/tun.c
+++ b/src/openvpn/tun.c
@@ -1841,7 +1841,7 @@ open_tun_generic(const char *dev, const char *dev_type, 
const char *dev_node,
 dynamic_name);
 tt->persistent_if = true;
 }
-else
+else if (ret != 0)
 {
 msg(M_ERR, "Cannot open TUN/TAP dev %s: %d", dynamic_name, 
ret);
 }
-- 
2.35.1



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 1/3] dco: dco_meesage_peer_id -> dco_message_peer_id

2022-02-22 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

Fix typo in variable name.

Signed-off-by: Kristof Provost 
---
 src/openvpn/dco_linux.c | 6 +++---
 src/openvpn/dco_linux.h | 2 +-
 src/openvpn/multi.c | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/openvpn/dco_linux.c b/src/openvpn/dco_linux.c
index 9fddb788..341e9ae7 100644
--- a/src/openvpn/dco_linux.c
+++ b/src/openvpn/dco_linux.c
@@ -436,7 +436,7 @@ open_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx, 
const char *dev)
 tt->actual_name = string_alloc(dev, NULL);
 uint8_t *dcobuf = malloc(65536);
 buf_set_write(>dco.dco_packet_in, dcobuf, 65536);
-tt->dco.dco_meesage_peer_id = -1;
+tt->dco.dco_message_peer_id = -1;
 
 ovpn_dco_register(>dco);
 
@@ -742,7 +742,7 @@ static int ovpn_handle_msg(struct nl_msg *msg, void *arg)
 
 msg(D_DCO_DEBUG, "ovpn-dco: received CMD_DEL_PEER, ifindex: %d, 
peer-id %d, reason: %d",
 ifindex, peerid, reason);
-dco->dco_meesage_peer_id = peerid;
+dco->dco_message_peer_id = peerid;
 dco->dco_del_peer_reason = reason;
 dco->dco_message_type = OVPN_CMD_DEL_PEER;
 
@@ -788,7 +788,7 @@ static int ovpn_handle_msg(struct nl_msg *msg, void *arg)
 }
 buf_init(>dco_packet_in, 0);
 buf_write(>dco_packet_in, data, len);
-dco->dco_meesage_peer_id = peerid;
+dco->dco_message_peer_id = peerid;
 dco->dco_message_type = OVPN_CMD_PACKET;
 break;
 }
diff --git a/src/openvpn/dco_linux.h b/src/openvpn/dco_linux.h
index 94e1a522..61d07a55 100644
--- a/src/openvpn/dco_linux.h
+++ b/src/openvpn/dco_linux.h
@@ -51,7 +51,7 @@ typedef struct
 struct buffer dco_packet_in;
 
 int dco_message_type;
-int dco_meesage_peer_id;
+int dco_message_peer_id;
 int dco_del_peer_reason;
 
 } dco_context_t;
diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c
index cf44dd58..30489038 100644
--- a/src/openvpn/multi.c
+++ b/src/openvpn/multi.c
@@ -3124,7 +3124,7 @@ static void
 process_incoming_dco_packet(struct multi_context *m, struct multi_instance 
*mi,  dco_context_t *dco)
 {
 struct buffer orig_buf = mi->context.c2.buf;
-int peer_id = dco->dco_meesage_peer_id;
+int peer_id = dco->dco_message_peer_id;
 
 mi->context.c2.buf = dco->dco_packet_in;
 
@@ -3184,7 +3184,7 @@ multi_process_incoming_dco(struct multi_context *m)
 
 int ret = dco_do_read(>top.c1.tuntap->dco);
 
-int peer_id = dco->dco_meesage_peer_id;
+int peer_id = dco->dco_message_peer_id;
 
 if ((peer_id >= 0) && (peer_id < m->max_clients) && 
(m->instances[peer_id]))
 {
@@ -3204,7 +3204,7 @@ multi_process_incoming_dco(struct multi_context *m)
 }
 
 dco->dco_message_type = 0;
-dco->dco_meesage_peer_id = -1;
+dco->dco_message_peer_id = -1;
 return ret > 0;
 }
 #endif
-- 
2.35.1



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 2/3] open_tun_generic(): Do not consider open_tun_dco() returning 0 to be an error

2022-02-22 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

It seems clear that the intent here is to special case the EEXIST error,
not the consider anything else (i.e. 0) to also be an error.

Signed-off-by: Kristof Provost 
---
 src/openvpn/tun.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c
index f9ba3858..d8f2dea7 100644
--- a/src/openvpn/tun.c
+++ b/src/openvpn/tun.c
@@ -1841,7 +1841,7 @@ open_tun_generic(const char *dev, const char *dev_type, 
const char *dev_node,
 dynamic_name);
 tt->persistent_if = true;
 }
-else
+else if (ret != 0)
 {
 msg(M_ERR, "Cannot open TUN/TAP dev %s: %d", dynamic_name, 
ret);
 }
-- 
2.35.1



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH 3/3] dco: Check for ipi_addr before using it

2022-02-22 Thread Kristof Provost via Openvpn-devel
From: Kristof Provost 

If IP_RECVDSTADDR exists we'll define ENABLE_IP_PKTINFO, but that
doesn't actually mean we have struct in_pktinfo. We need to check
HAVE_IN_PKTINFO for that.

This fixes DCO builds on FreeBSD.

Signed-off-by: Kristof Provost 
---
 src/openvpn/dco.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/openvpn/dco.c b/src/openvpn/dco.c
index 0ce03664..4234bb22 100644
--- a/src/openvpn/dco.c
+++ b/src/openvpn/dco.c
@@ -44,7 +44,7 @@ static bool
 dco_multi_get_localaddr(struct multi_context *m, struct multi_instance *mi,
 struct sockaddr_storage *local)
 {
-#if ENABLE_IP_PKTINFO
+#if ENABLE_IP_PKTINFO && defined(HAVE_IN_PKTINFO)
 struct context *c = >context;
 
 if (!(c->options.sockflags & SF_USE_IP_PKTINFO))
-- 
2.35.1



___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [PATCH DCO]: cleanups prior to FreeBSD DCO support

2022-02-22 Thread Kristof Provost via Openvpn-devel
Hi,

As said in my e-mail (from k...@freebsd.org, Feb 17th), I'm working on
adding DCO support for FreeBSD.
I ran into a few minor issues that are not directly related, but should
be addressed anyway.

These patches are all against https://github.com/OpenVPN/ovpn-dco

Best regards,
Kristof




___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel