From 876a8cf5fd6166a22bfe6b6f37889d3cff3a17c6 Mon Sep 17 00:00:00 2001 From: Ralf Lici Date: Mon, 20 Apr 2026 18:59:17 +0200 Subject: [PATCH] dco: port core/context infrastructure needed for backport of commit 7791f53 Change ovpn_dco_init() to take a reference to struct context, add a backlink from the platform DCO contexts to the owning openvpn context, and store the top multi context in struct context for server mode. This prepares the tree for the follow-up backend changes from commit 7791f53 ("dco: process messages immediately after read") where Linux and FreeBSD process DCO notifications directly from their backend read paths. It is part of a reworked backport of PR #945 originally proposed by Nikolai Shelekhov . The original commits in master are commit a699681bb86c6e9a2c9f205543f60400208aea4b Author: Antonio Quartulli Date: Wed Jul 23 15:39:11 2025 +0200 dco: only pass struct context to init function commit 7f5a6deae33a338a23d7e8ff8526db8fdddf4bc2 Author: Antonio Quartulli Date: Wed Jul 23 08:10:25 2025 +0200 multi: store multi_context address inside top instance Change-Id: I974e10ec91a0b63f52387f1406ce1b49145eb0be Signed-off-by: Ralf Lici Acked-by: Gert Doering Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1631 Message-Id: <20260420165923.14226-1-gert@greenie.muc.de> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg36691.html Signed-off-by: Gert Doering --- src/openvpn/dco.h | 7 +++---- src/openvpn/dco_freebsd.c | 6 ++++-- src/openvpn/dco_freebsd.h | 1 + src/openvpn/dco_linux.c | 10 ++++++++-- src/openvpn/dco_linux.h | 2 ++ src/openvpn/dco_win.c | 2 +- src/openvpn/init.c | 2 +- src/openvpn/mtcp.c | 1 + src/openvpn/mudp.c | 1 + src/openvpn/openvpn.h | 3 +++ 10 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/openvpn/dco.h b/src/openvpn/dco.h index 50ebb359..334d4684 100644 --- a/src/openvpn/dco.h +++ b/src/openvpn/dco.h @@ -104,11 +104,10 @@ bool dco_check_pull_options(int msglevel, const struct options *o); /** * Initialize the DCO context * - * @param mode the instance operating mode (P2P or multi-peer) - * @param dco the context to initialize + * @param c the main instance context * @return true on success, false otherwise */ -bool ovpn_dco_init(int mode, dco_context_t *dco); +bool ovpn_dco_init(struct context *c); /** * Open/create a DCO interface @@ -284,7 +283,7 @@ dco_check_pull_options(int msglevel, const struct options *o) } static inline bool -ovpn_dco_init(int mode, dco_context_t *dco) +ovpn_dco_init(struct context *c) { return true; } diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c index 15add74a..b164bd37 100644 --- a/src/openvpn/dco_freebsd.c +++ b/src/openvpn/dco_freebsd.c @@ -220,9 +220,11 @@ close_fd(dco_context_t *dco) } bool -ovpn_dco_init(int mode, dco_context_t *dco) +ovpn_dco_init(struct context *c) { - if (open_fd(dco) < 0) + c->c1.tuntap->dco.c = c; + + if (open_fd(&c->c1.tuntap->dco) < 0) { msg(M_ERR, "Failed to open socket"); return false; diff --git a/src/openvpn/dco_freebsd.h b/src/openvpn/dco_freebsd.h index ab5891e8..e8f723ed 100644 --- a/src/openvpn/dco_freebsd.h +++ b/src/openvpn/dco_freebsd.h @@ -57,6 +57,7 @@ typedef struct dco_context { int dco_message_peer_id; int dco_del_peer_reason; struct sockaddr_storage dco_float_peer_ss; + struct context *c; uint64_t dco_read_bytes; uint64_t dco_write_bytes; } dco_context_t; diff --git a/src/openvpn/dco_linux.c b/src/openvpn/dco_linux.c index b2584b97..493fce6f 100644 --- a/src/openvpn/dco_linux.c +++ b/src/openvpn/dco_linux.c @@ -391,9 +391,11 @@ ovpn_dco_init_netlink(dco_context_t *dco) } bool -ovpn_dco_init(int mode, dco_context_t *dco) +ovpn_dco_init(struct context *c) { - switch (mode) + dco_context_t *dco = &c->c1.tuntap->dco; + + switch (c->mode) { case CM_TOP: dco->ifmode = OVPN_MODE_MP; @@ -407,6 +409,10 @@ ovpn_dco_init(int mode, dco_context_t *dco) ASSERT(false); } + /* store pointer to context as it may be required by message + * parsing routines + */ + dco->c = c; ovpn_dco_init_netlink(dco); return true; } diff --git a/src/openvpn/dco_linux.h b/src/openvpn/dco_linux.h index 5179912b..cf6bdd4a 100644 --- a/src/openvpn/dco_linux.h +++ b/src/openvpn/dco_linux.h @@ -43,6 +43,8 @@ typedef struct struct nl_cb *nl_cb; int status; + struct context *c; + enum ovpn_mode ifmode; int ovpn_dco_id; diff --git a/src/openvpn/dco_win.c b/src/openvpn/dco_win.c index 0b8f8319..bc465db6 100644 --- a/src/openvpn/dco_win.c +++ b/src/openvpn/dco_win.c @@ -53,7 +53,7 @@ create_dco_handle(const char *devname, struct gc_arena *gc) } bool -ovpn_dco_init(int mode, dco_context_t *dco) +ovpn_dco_init(struct context *c) { return true; } diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 1476737e..c2cfd240 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1882,7 +1882,7 @@ do_open_tun(struct context *c, int *error_flags) #endif if (dco_enabled(&c->options)) { - ovpn_dco_init(c->mode, &c->c1.tuntap->dco); + ovpn_dco_init(c); } /* open the tun device */ diff --git a/src/openvpn/mtcp.c b/src/openvpn/mtcp.c index 3e33b158..38c938e6 100644 --- a/src/openvpn/mtcp.c +++ b/src/openvpn/mtcp.c @@ -792,6 +792,7 @@ tunnel_server_tcp(struct context *top) int status; top->mode = CM_TOP; + top->multi = &multi; context_clear_2(top); /* initialize top-tunnel instance */ diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c index f7c9ffd7..8cc717b1 100644 --- a/src/openvpn/mudp.c +++ b/src/openvpn/mudp.c @@ -466,6 +466,7 @@ tunnel_server_udp(struct context *top) struct multi_context multi; top->mode = CM_TOP; + top->multi = &multi; context_clear_2(top); /* initialize top-tunnel instance */ diff --git a/src/openvpn/openvpn.h b/src/openvpn/openvpn.h index 9cba1c5a..38797726 100644 --- a/src/openvpn/openvpn.h +++ b/src/openvpn/openvpn.h @@ -492,6 +492,9 @@ struct context * CM_P2P, \c CM_TOP, \c CM_TOP_CLONE, * \c CM_CHILD_UDP, and \c CM_CHILD_TCP. */ + struct multi_context *multi; /**< Pointer to the main P2MP context. + * Non-NULL only when mode == CM_TOP. */ + struct gc_arena gc; /**< Garbage collection arena for * allocations done in the scope of this * context structure. */