OpenVPN
dco_linux.c
Go to the documentation of this file.
1/*
2 * Interface to linux dco networking code
3 *
4 * Copyright (C) 2020-2026 Antonio Quartulli <a@unstable.cc>
5 * Copyright (C) 2020-2026 Arne Schwabe <arne@rfc2549.org>
6 * Copyright (C) 2020-2026 OpenVPN Inc <sales@openvpn.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program (see the file COPYING included with this
19 * distribution); if not, see <https://www.gnu.org/licenses/>.
20 */
21
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#if defined(ENABLE_DCO) && defined(TARGET_LINUX)
28
29#include "syshead.h"
30
31#include "dco_linux.h"
32#include "errlevel.h"
33#include "buffer.h"
34#include "networking.h"
35#include "openvpn.h"
36
37#include "socket.h"
38#include "tun.h"
39#include "ssl.h"
40#include "fdmisc.h"
41#include "multi.h"
42#include "ssl_verify.h"
43
44#include "ovpn_dco_linux.h"
45
46#include <netlink/socket.h>
47#include <netlink/netlink.h>
48#include <netlink/genl/genl.h>
49#include <netlink/genl/family.h>
50#include <netlink/genl/ctrl.h>
51
52/* libnl < 3.5.0 does not set the NLA_F_NESTED on its own, therefore we
53 * have to explicitly do it to prevent the kernel from failing upon
54 * parsing of the message
55 */
56#define nla_nest_start(_msg, _type) nla_nest_start(_msg, (_type) | NLA_F_NESTED)
57
58static int ovpn_get_mcast_id(dco_context_t *dco);
59
60void dco_check_key_ctx(const struct key_ctx_bi *key);
61
62typedef int (*ovpn_nl_cb)(struct nl_msg *msg, void *arg);
63
75static int
76resolve_ovpn_netlink_id(msglvl_t msglevel)
77{
78 int ret;
79 struct nl_sock *nl_sock = nl_socket_alloc();
80
81 if (!nl_sock)
82 {
83 msg(msglevel, "Allocating net link socket failed");
84 return -ENOMEM;
85 }
86
87 ret = genl_connect(nl_sock);
88 if (ret)
89 {
90 msg(msglevel, "Cannot connect to generic netlink: %s", nl_geterror(ret));
91 goto err_sock;
92 }
93 set_cloexec(nl_socket_get_fd(nl_sock));
94
95 ret = genl_ctrl_resolve(nl_sock, OVPN_FAMILY_NAME);
96 if (ret < 0)
97 {
98 msg(msglevel, "Cannot find ovpn_dco netlink component: %s", nl_geterror(ret));
99 }
100
101err_sock:
102 nl_socket_free(nl_sock);
103 return ret;
104}
105
106static struct nl_msg *
107ovpn_dco_nlmsg_create(dco_context_t *dco, uint8_t cmd)
108{
109 struct nl_msg *nl_msg = nlmsg_alloc();
110 if (!nl_msg)
111 {
112 msg(M_FATAL, "cannot allocate netlink message");
113 return NULL;
114 }
115
116 genlmsg_put(nl_msg, 0, 0, dco->ovpn_dco_id, 0, 0, cmd, 0);
117 NLA_PUT_U32(nl_msg, OVPN_A_IFINDEX, dco->ifindex);
118
119 return nl_msg;
120nla_put_failure:
121 nlmsg_free(nl_msg);
122 msg(M_INFO, "cannot put into netlink message");
123 return NULL;
124}
125
126static int
127ovpn_nl_recvmsgs_report(int ret, const char *prefix)
128{
129 switch (ret)
130 {
131 case -NLE_INTR:
132 msg(M_WARN, "%s: netlink received interrupt due to signal - ignoring", prefix);
133 break;
134
135 case -NLE_NOMEM:
136 msg(M_FATAL, "%s: netlink out of memory error", prefix);
137 break;
138
139 case -NLE_AGAIN:
140 msg(M_WARN, "%s: netlink reports blocking read - aborting wait", prefix);
141 break;
142
143 case -NLE_NODEV:
144 msg(M_FATAL, "%s: netlink reports device not found:", prefix);
145 break;
146
147 case -NLE_OBJ_NOTFOUND:
148 msg(M_INFO, "%s: netlink reports object not found, ovpn kernel module unloaded?", prefix);
149 break;
150
151 default:
152 if (ret)
153 {
154 msg(M_NONFATAL, "%s: netlink reports error (%d): %s", prefix, ret,
155 nl_geterror(-ret));
156 }
157 break;
158 }
159
160 return ret;
161}
162
169static int
170ovpn_nl_recvmsgs(dco_context_t *dco, const char *prefix)
171{
172 int ret = nl_recvmsgs(dco->nl_sock, dco->nl_cb);
173
174 return ovpn_nl_recvmsgs_report(ret, prefix);
175}
176
186static int
187ovpn_nl_msg_send(dco_context_t *dco, struct nl_msg *nl_msg, const char *prefix)
188{
189 dco->status = 1;
190
191 nl_send_auto(dco->nl_sock, nl_msg);
192
193 while (dco->status == 1)
194 {
195 ovpn_nl_recvmsgs(dco, prefix);
196 }
197
198 if (dco->status < 0)
199 {
200 msg(M_INFO, "%s: failed to send netlink message: %s (%d)", prefix, strerror(-dco->status),
201 dco->status);
202 }
203
204 return dco->status;
205}
206
207struct sockaddr *
208mapped_v4_to_v6(struct sockaddr *sock, struct gc_arena *gc)
209{
210 struct sockaddr_in6 *sock6 = (struct sockaddr_in6 *)sock;
211 if (sock->sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sock6->sin6_addr))
212 {
213 struct sockaddr_in *sock4;
214 ALLOC_OBJ_CLEAR_GC(sock4, struct sockaddr_in, gc);
215 memcpy(&sock4->sin_addr, sock6->sin6_addr.s6_addr + 12, 4);
216 sock4->sin_port = sock6->sin6_port;
217 sock4->sin_family = AF_INET;
218 return (struct sockaddr *)sock4;
219 }
220 return sock;
221}
222
223int
224dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd, struct sockaddr *localaddr,
225 struct sockaddr *remoteaddr, const struct in_addr *vpn_ipv4,
226 const struct in6_addr *vpn_ipv6)
227{
228 struct gc_arena gc = gc_new();
229 const char *remotestr = "[undefined]";
230 if (remoteaddr)
231 {
232 remotestr = print_sockaddr(remoteaddr, &gc);
233 }
234 msg(D_DCO_DEBUG, "%s: peer-id %u, fd %d, remote addr: %s", __func__, peerid, sd, remotestr);
235
236 struct nl_msg *nl_msg = ovpn_dco_nlmsg_create(dco, OVPN_CMD_PEER_NEW);
237 struct nlattr *attr = nla_nest_start(nl_msg, OVPN_A_PEER);
238 int ret = -EMSGSIZE;
239
240 NLA_PUT_U32(nl_msg, OVPN_A_PEER_ID, peerid);
241 NLA_PUT_U32(nl_msg, OVPN_A_PEER_SOCKET, sd);
242
243 /* Set the remote endpoint if defined (for UDP) */
244 if (remoteaddr)
245 {
246 remoteaddr = mapped_v4_to_v6(remoteaddr, &gc);
247
248 if (remoteaddr->sa_family == AF_INET)
249 {
250 NLA_PUT(nl_msg, OVPN_A_PEER_REMOTE_IPV4, sizeof(struct in_addr),
251 &((struct sockaddr_in *)remoteaddr)->sin_addr);
252 NLA_PUT_U16(nl_msg, OVPN_A_PEER_REMOTE_PORT,
253 ((struct sockaddr_in *)remoteaddr)->sin_port);
254 }
255 else if (remoteaddr->sa_family == AF_INET6)
256 {
257 NLA_PUT(nl_msg, OVPN_A_PEER_REMOTE_IPV6, sizeof(struct in6_addr),
258 &((struct sockaddr_in6 *)remoteaddr)->sin6_addr);
259 NLA_PUT_U16(nl_msg, OVPN_A_PEER_REMOTE_PORT,
260 ((struct sockaddr_in6 *)remoteaddr)->sin6_port);
261 NLA_PUT_U32(nl_msg, OVPN_A_PEER_REMOTE_IPV6_SCOPE_ID,
262 ((struct sockaddr_in6 *)remoteaddr)->sin6_scope_id);
263 }
264 }
265
266 if (localaddr)
267 {
268 localaddr = mapped_v4_to_v6(localaddr, &gc);
269 if (localaddr->sa_family == AF_INET)
270 {
271 NLA_PUT(nl_msg, OVPN_A_PEER_LOCAL_IPV4, sizeof(struct in_addr),
272 &((struct sockaddr_in *)localaddr)->sin_addr);
273 }
274 else if (localaddr->sa_family == AF_INET6)
275 {
276 NLA_PUT(nl_msg, OVPN_A_PEER_LOCAL_IPV6, sizeof(struct in6_addr),
277 &((struct sockaddr_in6 *)localaddr)->sin6_addr);
278 }
279 }
280
281 /* Set the primary VPN IP addresses of the peer */
282 if (vpn_ipv4)
283 {
284 NLA_PUT_U32(nl_msg, OVPN_A_PEER_VPN_IPV4, vpn_ipv4->s_addr);
285 }
286 if (vpn_ipv6)
287 {
288 NLA_PUT(nl_msg, OVPN_A_PEER_VPN_IPV6, sizeof(struct in6_addr), vpn_ipv6);
289 }
290 nla_nest_end(nl_msg, attr);
291
292 ret = ovpn_nl_msg_send(dco, nl_msg, __func__);
293
294nla_put_failure:
295 nlmsg_free(nl_msg);
296 gc_free(&gc);
297 return ret;
298}
299
300static int
301ovpn_nl_cb_finish(struct nl_msg(*msg) __attribute__((unused)), void *arg)
302{
303 int *status = arg;
304
305 *status = 0;
306 return NL_SKIP;
307}
308
309/* The following enum members exist in netlink.h since linux-6.1.
310 * However, some distro we support still ship an old header, thus
311 * failing the OpenVPN compilation.
312 *
313 * For the time being we add the needed defines manually.
314 * We will drop this definition once we stop supporting those old
315 * distros.
316 *
317 * @NLMSGERR_ATTR_MISS_TYPE: type of a missing required attribute,
318 * %NLMSGERR_ATTR_MISS_NEST will not be present if the attribute was
319 * missing at the message level
320 * @NLMSGERR_ATTR_MISS_NEST: offset of the nest where attribute was missing
321 */
322enum ovpn_nlmsgerr_attrs
323{
324 OVPN_NLMSGERR_ATTR_MISS_TYPE = 5,
325 OVPN_NLMSGERR_ATTR_MISS_NEST = 6,
326 OVPN_NLMSGERR_ATTR_MAX = 6,
327};
328
329/* This function is used as error callback on the netlink socket.
330 * When something goes wrong and the kernel returns an error, this function is
331 * invoked.
332 *
333 * We pass the error code to the user by means of a variable pointed by *arg
334 * (supplied by the user when setting this callback) and we parse the kernel
335 * reply to see if it contains a human-readable error. If found, it is printed.
336 */
337static int
338ovpn_nl_cb_error(struct sockaddr_nl(*nla) __attribute__((unused)), struct nlmsgerr *err, void *arg)
339{
340 struct nlmsghdr *nlh = (struct nlmsghdr *)err - 1;
341 struct nlattr *tb_msg[OVPN_NLMSGERR_ATTR_MAX + 1];
342 int len = nlh->nlmsg_len;
343 struct nlattr *attrs;
344 int *ret = arg;
345 int ack_len = sizeof(*nlh) + sizeof(int) + sizeof(*nlh);
346
347 *ret = err->error;
348
349 if (!(nlh->nlmsg_flags & NLM_F_ACK_TLVS))
350 {
351 return NL_STOP;
352 }
353
354 if (!(nlh->nlmsg_flags & NLM_F_CAPPED))
355 {
356 ack_len += err->msg.nlmsg_len - (int)sizeof(*nlh);
357 }
358
359 if (len <= ack_len)
360 {
361 return NL_STOP;
362 }
363
364 attrs = (void *)((unsigned char *)nlh + ack_len);
365 len -= ack_len;
366
367 nla_parse(tb_msg, OVPN_NLMSGERR_ATTR_MAX, attrs, len, NULL);
368 if (tb_msg[NLMSGERR_ATTR_MSG])
369 {
370 len = (int)strnlen((char *)nla_data(tb_msg[NLMSGERR_ATTR_MSG]),
371 nla_len(tb_msg[NLMSGERR_ATTR_MSG]));
372 msg(M_WARN, "kernel error: %*s", len, (char *)nla_data(tb_msg[NLMSGERR_ATTR_MSG]));
373 }
374
375 if (tb_msg[OVPN_NLMSGERR_ATTR_MISS_NEST])
376 {
377 msg(M_WARN, "kernel error: missing required nesting type %u",
378 nla_get_u32(tb_msg[OVPN_NLMSGERR_ATTR_MISS_NEST]));
379 }
380
381 if (tb_msg[OVPN_NLMSGERR_ATTR_MISS_TYPE])
382 {
383 msg(M_WARN, "kernel error: missing required attribute type %u",
384 nla_get_u32(tb_msg[OVPN_NLMSGERR_ATTR_MISS_TYPE]));
385 }
386
387 return NL_STOP;
388}
389
390static void
391ovpn_dco_register(dco_context_t *dco)
392{
393 msg(D_DCO_DEBUG, __func__);
394 ovpn_get_mcast_id(dco);
395
396 if (dco->ovpn_dco_mcast_id < 0)
397 {
398 msg(M_FATAL, "cannot get mcast group: %s", nl_geterror(dco->ovpn_dco_mcast_id));
399 }
400
401 /* Register for ovpn-dco specific multicast messages that the kernel may
402 * send. These are subscribed on the dedicated notification socket only, so
403 * that they are never delivered while a request/reply transaction on
404 * dco->nl_sock is being parsed.
405 */
406 int ret = nl_socket_add_membership(dco->nl_sock_notify, dco->ovpn_dco_mcast_id);
407 if (ret)
408 {
409 msg(M_FATAL, "%s: failed to join groups: %d", __func__, ret);
410 }
411}
412
413static int ovpn_handle_msg(struct nl_msg *msg, void *arg);
414
415static void
416ovpn_dco_init_netlink(dco_context_t *dco)
417{
418 dco->ovpn_dco_id = resolve_ovpn_netlink_id(M_FATAL);
419
420 dco->nl_sock = nl_socket_alloc();
421
422 if (!dco->nl_sock)
423 {
424 msg(M_FATAL, "Cannot create netlink socket");
425 }
426
427 int ret = genl_connect(dco->nl_sock);
428 if (ret)
429 {
430 msg(M_FATAL, "Cannot connect to generic netlink: %s", nl_geterror(ret));
431 }
432
433 /* enable Extended ACK for detailed error reporting */
434 ret = 1;
435 setsockopt(nl_socket_get_fd(dco->nl_sock), SOL_NETLINK, NETLINK_EXT_ACK, &ret, sizeof(ret));
436
437 /* set close on exec and non-block on the netlink socket */
438 set_cloexec(nl_socket_get_fd(dco->nl_sock));
439 set_nonblock(nl_socket_get_fd(dco->nl_sock));
440
441 dco->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
442 if (!dco->nl_cb)
443 {
444 msg(M_FATAL, "failed to allocate netlink callback");
445 }
446
447 nl_socket_set_cb(dco->nl_sock, dco->nl_cb);
448
449 dco->dco_message_peer_id = -1;
450 nl_cb_err(dco->nl_cb, NL_CB_CUSTOM, ovpn_nl_cb_error, &dco->status);
451 nl_cb_set(dco->nl_cb, NL_CB_FINISH, NL_CB_CUSTOM, ovpn_nl_cb_finish, &dco->status);
452 nl_cb_set(dco->nl_cb, NL_CB_ACK, NL_CB_CUSTOM, ovpn_nl_cb_finish, &dco->status);
453 nl_cb_set(dco->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, ovpn_handle_msg, dco);
454
455 /* Set up the dedicated multicast notification socket. It shares the message
456 * handler (ovpn_handle_msg) with the request/reply socket, but is read only
457 * from dco_read_and_process() in the event loop, so notifications never
458 * fire while a request/reply transaction is being parsed. */
459 dco->nl_sock_notify = nl_socket_alloc();
460 if (!dco->nl_sock_notify)
461 {
462 msg(M_FATAL, "Cannot create netlink notification socket");
463 }
464
465 ret = genl_connect(dco->nl_sock_notify);
466 if (ret)
467 {
468 msg(M_FATAL, "Cannot connect to generic netlink (notify): %s", nl_geterror(ret));
469 }
470
471 set_cloexec(nl_socket_get_fd(dco->nl_sock_notify));
472 set_nonblock(nl_socket_get_fd(dco->nl_sock_notify));
473
474 dco->nl_cb_notify = nl_cb_alloc(NL_CB_DEFAULT);
475 if (!dco->nl_cb_notify)
476 {
477 msg(M_FATAL, "failed to allocate netlink notification callback");
478 }
479
480 nl_socket_set_cb(dco->nl_sock_notify, dco->nl_cb_notify);
481 nl_cb_err(dco->nl_cb_notify, NL_CB_CUSTOM, ovpn_nl_cb_error, &dco->status);
482 nl_cb_set(dco->nl_cb_notify, NL_CB_VALID, NL_CB_CUSTOM, ovpn_handle_msg, dco);
483
484 ovpn_dco_register(dco);
485
486 /* The async PACKET messages confuse libnl and it will drop them with
487 * wrong sequence numbers (NLE_SEQ_MISMATCH), so disable libnl's sequence
488 * number check. Multicast notifications are unsolicited and likewise carry
489 * no matching sequence number, so disable the check on both sockets. */
490 nl_socket_disable_seq_check(dco->nl_sock);
491 nl_socket_disable_seq_check(dco->nl_sock_notify);
492
493 /* nl library sets the buffer size to 32k/32k by default which is sometimes
494 * overrun with very fast connecting/disconnecting clients.
495 * TODO: fix this in a better and more reliable way */
496 ASSERT(!nl_socket_set_buffer_size(dco->nl_sock, 1024 * 1024, 1024 * 1024));
497 ASSERT(!nl_socket_set_buffer_size(dco->nl_sock_notify, 1024 * 1024, 1024 * 1024));
498}
499
500bool
501ovpn_dco_init(struct context *c)
502{
503 dco_context_t *dco = &c->c1.tuntap->dco;
504
505 switch (c->mode)
506 {
507 case CM_TOP:
508 dco->ifmode = OVPN_MODE_MP;
509 break;
510
511 case CM_P2P:
512 dco->ifmode = OVPN_MODE_P2P;
513 break;
514
515 default:
516 ASSERT(false);
517 }
518
519 /* store pointer to context as it may be required by message
520 * parsing routines
521 */
522 dco->c = c;
523 ovpn_dco_init_netlink(dco);
524 return true;
525}
526
527static void
528ovpn_dco_uninit_netlink(dco_context_t *dco)
529{
530 nl_socket_free(dco->nl_sock);
531 dco->nl_sock = NULL;
532
533 nl_socket_free(dco->nl_sock_notify);
534 dco->nl_sock_notify = NULL;
535
536 /* Decrease reference count */
537 nl_cb_put(dco->nl_cb);
538 nl_cb_put(dco->nl_cb_notify);
539
540 CLEAR(dco);
541}
542
543int
544open_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx, const char *dev)
545{
546 msg(D_DCO_DEBUG, "%s: %s", __func__, dev);
547 ASSERT(tt->type == DEV_TYPE_TUN);
548
549 int ret = net_iface_new(ctx, dev, OVPN_FAMILY_NAME, &tt->dco);
550 if (ret < 0)
551 {
552 msg(D_DCO_DEBUG, "Cannot create DCO interface %s: %d", dev, ret);
553 return ret;
554 }
555
556 tt->dco.ifindex = if_nametoindex(dev);
557 if (!tt->dco.ifindex)
558 {
559 msg(M_FATAL, "DCO: cannot retrieve ifindex for interface %s", dev);
560 }
561
562 return 0;
563}
564
565void
566close_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx)
567{
568 msg(D_DCO_DEBUG, __func__);
569
570 net_iface_del(ctx, tt->actual_name);
571 ovpn_dco_uninit_netlink(&tt->dco);
572}
573
574int
575dco_swap_keys(dco_context_t *dco, unsigned int peerid)
576{
577 msg(D_DCO_DEBUG, "%s: peer-id %u", __func__, peerid);
578
579 struct nl_msg *nl_msg = ovpn_dco_nlmsg_create(dco, OVPN_CMD_KEY_SWAP);
580 if (!nl_msg)
581 {
582 return -ENOMEM;
583 }
584
585 struct nlattr *attr = nla_nest_start(nl_msg, OVPN_A_KEYCONF);
586 int ret = -EMSGSIZE;
587 NLA_PUT_U32(nl_msg, OVPN_A_KEYCONF_PEER_ID, peerid);
588 nla_nest_end(nl_msg, attr);
589
590 ret = ovpn_nl_msg_send(dco, nl_msg, __func__);
591
592nla_put_failure:
593 nlmsg_free(nl_msg);
594 return ret;
595}
596
597
598int
599dco_del_peer(dco_context_t *dco, unsigned int peerid)
600{
601 msg(D_DCO_DEBUG | M_NOIPREFIX, "%s: peer-id %u", __func__, peerid);
602
603 struct nl_msg *nl_msg = ovpn_dco_nlmsg_create(dco, OVPN_CMD_PEER_DEL);
604 if (!nl_msg)
605 {
606 return -ENOMEM;
607 }
608
609 struct nlattr *attr = nla_nest_start(nl_msg, OVPN_A_PEER);
610 int ret = -EMSGSIZE;
611 NLA_PUT_U32(nl_msg, OVPN_A_PEER_ID, peerid);
612 nla_nest_end(nl_msg, attr);
613
614 ret = ovpn_nl_msg_send(dco, nl_msg, __func__);
615
616nla_put_failure:
617 nlmsg_free(nl_msg);
618 return ret;
619}
620
621
622int
623dco_del_key(dco_context_t *dco, unsigned int peerid, dco_key_slot_t slot)
624{
625 int ret = -EMSGSIZE;
626 msg(D_DCO_DEBUG, "%s: peer-id %u, slot %d", __func__, peerid, slot);
627
628 struct nl_msg *nl_msg = ovpn_dco_nlmsg_create(dco, OVPN_CMD_KEY_DEL);
629 if (!nl_msg)
630 {
631 return -ENOMEM;
632 }
633
634 struct nlattr *keyconf = nla_nest_start(nl_msg, OVPN_A_KEYCONF);
635 NLA_PUT_U32(nl_msg, OVPN_A_KEYCONF_PEER_ID, peerid);
636 NLA_PUT_U32(nl_msg, OVPN_A_KEYCONF_SLOT, slot);
637 nla_nest_end(nl_msg, keyconf);
638
639 ret = ovpn_nl_msg_send(dco, nl_msg, __func__);
640
641nla_put_failure:
642 nlmsg_free(nl_msg);
643 return ret;
644}
645
646int
647dco_new_key(dco_context_t *dco, unsigned int peerid, int keyid, dco_key_slot_t slot,
648 const uint8_t *encrypt_key, const uint8_t *encrypt_iv, const uint8_t *decrypt_key,
649 const uint8_t *decrypt_iv, const char *ciphername, bool epoch)
650{
651 msg(D_DCO_DEBUG, "%s: slot %d, key-id %d, peer-id %u, cipher %s, epoch %d", __func__, slot, keyid, peerid,
652 ciphername, epoch);
653
654 const size_t key_len = cipher_kt_key_size(ciphername);
655 ASSERT(key_len <= INT_MAX);
656 const int nonce_tail_len = 8;
657
658 struct nl_msg *nl_msg = ovpn_dco_nlmsg_create(dco, OVPN_CMD_KEY_NEW);
659 if (!nl_msg)
660 {
661 return -ENOMEM;
662 }
663
664 dco_cipher_t dco_cipher = dco_get_cipher(ciphername);
665
666 int ret = -EMSGSIZE;
667
668 struct nlattr *key_conf = nla_nest_start(nl_msg, OVPN_A_KEYCONF);
669 NLA_PUT_U32(nl_msg, OVPN_A_KEYCONF_PEER_ID, peerid);
670 NLA_PUT_U32(nl_msg, OVPN_A_KEYCONF_SLOT, slot);
671 NLA_PUT_U32(nl_msg, OVPN_A_KEYCONF_KEY_ID, keyid);
672 NLA_PUT_U32(nl_msg, OVPN_A_KEYCONF_CIPHER_ALG, dco_cipher);
673
674 struct nlattr *key_enc = nla_nest_start(nl_msg, OVPN_A_KEYCONF_ENCRYPT_DIR);
675 if (dco_cipher != OVPN_CIPHER_ALG_NONE)
676 {
677 NLA_PUT(nl_msg, OVPN_A_KEYDIR_CIPHER_KEY, (int)key_len, encrypt_key);
678 NLA_PUT(nl_msg, OVPN_A_KEYDIR_NONCE_TAIL, nonce_tail_len, encrypt_iv);
679 }
680 nla_nest_end(nl_msg, key_enc);
681
682 struct nlattr *key_dec = nla_nest_start(nl_msg, OVPN_A_KEYCONF_DECRYPT_DIR);
683 if (dco_cipher != OVPN_CIPHER_ALG_NONE)
684 {
685 NLA_PUT(nl_msg, OVPN_A_KEYDIR_CIPHER_KEY, (int)key_len, decrypt_key);
686 NLA_PUT(nl_msg, OVPN_A_KEYDIR_NONCE_TAIL, nonce_tail_len, decrypt_iv);
687 }
688 nla_nest_end(nl_msg, key_dec);
689
690 nla_nest_end(nl_msg, key_conf);
691
692
693 ret = ovpn_nl_msg_send(dco, nl_msg, __func__);
694
695nla_put_failure:
696 nlmsg_free(nl_msg);
697 return ret;
698}
699
700int
701dco_set_peer(dco_context_t *dco, unsigned int peerid, int keepalive_interval, int keepalive_timeout,
702 int mss)
703{
704 msg(D_DCO_DEBUG, "%s: peer-id %u, keepalive %d/%d, mss %d", __func__, peerid,
705 keepalive_interval, keepalive_timeout, mss);
706
707 struct nl_msg *nl_msg = ovpn_dco_nlmsg_create(dco, OVPN_CMD_PEER_SET);
708 if (!nl_msg)
709 {
710 return -ENOMEM;
711 }
712
713 struct nlattr *attr = nla_nest_start(nl_msg, OVPN_A_PEER);
714 int ret = -EMSGSIZE;
715 NLA_PUT_U32(nl_msg, OVPN_A_PEER_ID, peerid);
716 NLA_PUT_U32(nl_msg, OVPN_A_PEER_KEEPALIVE_INTERVAL, keepalive_interval);
717 NLA_PUT_U32(nl_msg, OVPN_A_PEER_KEEPALIVE_TIMEOUT, keepalive_timeout);
718 nla_nest_end(nl_msg, attr);
719
720 ret = ovpn_nl_msg_send(dco, nl_msg, __func__);
721
722nla_put_failure:
723 nlmsg_free(nl_msg);
724 return ret;
725}
726
727/* This function parses the reply provided by the kernel to the CTRL_CMD_GETFAMILY
728 * message. We parse the reply and we retrieve the multicast group ID associated
729 * with the "ovpn-dco" netlink family.
730 *
731 * The ID is later used to subscribe to the multicast group and be notified
732 * about any multicast message sent by the ovpn-dco kernel module.
733 */
734static int
735mcast_family_handler(struct nl_msg *msg, void *arg)
736{
737 dco_context_t *dco = arg;
738 struct nlattr *tb[CTRL_ATTR_MAX + 1];
739 const struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
740
741 nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
742
743 if (!tb[CTRL_ATTR_MCAST_GROUPS])
744 {
745 return NL_SKIP;
746 }
747
748 const struct nlattr *mcgrp;
749 int rem_mcgrp;
750 nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], rem_mcgrp)
751 {
752 struct nlattr *tb_mcgrp[CTRL_ATTR_MCAST_GRP_MAX + 1];
753
754 nla_parse(tb_mcgrp, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcgrp), nla_len(mcgrp), NULL);
755
756 if (!tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME] || !tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID])
757 {
758 continue;
759 }
760
761 if (strncmp(nla_data(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME]), OVPN_MCGRP_PEERS,
762 nla_len(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME]))
763 != 0)
764 {
765 continue;
766 }
767 dco->ovpn_dco_mcast_id = nla_get_u32(tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID]);
768 break;
769 }
770
771 return NL_SKIP;
772}
778static int
779ovpn_get_mcast_id(dco_context_t *dco)
780{
781 dco->ovpn_dco_mcast_id = -ENOENT;
782
783 /* Even though 'nlctrl' is a constant, there seem to be no library
784 * provided define for it */
785 dco->ctrlid = genl_ctrl_resolve(dco->nl_sock, "nlctrl");
786
787 struct nl_msg *nl_msg = nlmsg_alloc();
788 if (!nl_msg)
789 {
790 return -ENOMEM;
791 }
792
793 genlmsg_put(nl_msg, 0, 0, dco->ctrlid, 0, 0, CTRL_CMD_GETFAMILY, 0);
794
795 int ret = -EMSGSIZE;
796 NLA_PUT_STRING(nl_msg, CTRL_ATTR_FAMILY_NAME, OVPN_FAMILY_NAME);
797
798 ret = ovpn_nl_msg_send(dco, nl_msg, __func__);
799
800nla_put_failure:
801 nlmsg_free(nl_msg);
802 return ret;
803}
804
805static bool
806ovpn_parse_float_addr(struct nlattr **attrs, struct sockaddr *out)
807{
808 if (!attrs[OVPN_A_PEER_REMOTE_PORT])
809 {
810 msg(D_DCO, "ovpn-dco: no remote port in PEER_FLOAT_NTF message");
811 return false;
812 }
813
814 if (attrs[OVPN_A_PEER_REMOTE_IPV4])
815 {
816 struct sockaddr_in *addr4 = (struct sockaddr_in *)out;
817 CLEAR(*addr4);
818 addr4->sin_family = AF_INET;
819 addr4->sin_port = nla_get_u16(attrs[OVPN_A_PEER_REMOTE_PORT]);
820 addr4->sin_addr.s_addr = nla_get_u32(attrs[OVPN_A_PEER_REMOTE_IPV4]);
821 return true;
822 }
823 else if (attrs[OVPN_A_PEER_REMOTE_IPV6]
824 && nla_len(attrs[OVPN_A_PEER_REMOTE_IPV6]) == sizeof(struct in6_addr))
825 {
826 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)out;
827 CLEAR(*addr6);
828 addr6->sin6_family = AF_INET6;
829 addr6->sin6_port = nla_get_u16(attrs[OVPN_A_PEER_REMOTE_PORT]);
830 memcpy(&addr6->sin6_addr, nla_data(attrs[OVPN_A_PEER_REMOTE_IPV6]),
831 sizeof(addr6->sin6_addr));
833 {
834 addr6->sin6_scope_id = nla_get_u32(attrs[OVPN_A_PEER_REMOTE_IPV6_SCOPE_ID]);
835 }
836 return true;
837 }
838
839 msg(D_DCO, "ovpn-dco: no valid remote IP address in PEER_FLOAT_NTF message");
840 return false;
841}
842
843/* libnl < 3.11.0 does not implement nla_get_uint() */
844static uint64_t
845ovpn_nla_get_uint(struct nlattr *attr)
846{
847 if (nla_len(attr) == sizeof(uint32_t))
848 {
849 return nla_get_u32(attr);
850 }
851 else
852 {
853 return nla_get_u64(attr);
854 }
855}
856
857static void
858dco_update_peer_stat(struct context_2 *c2, struct nlattr *tb[], uint32_t id)
859{
861 {
862 c2->dco_read_bytes = ovpn_nla_get_uint(tb[OVPN_A_PEER_LINK_RX_BYTES]);
863 msg(D_DCO_DEBUG, "%s / dco_read_bytes: " counter_format, __func__, c2->dco_read_bytes);
864 }
865 else
866 {
867 msg(M_WARN, "%s: no link RX bytes provided in reply for peer %u", __func__, id);
868 }
869
871 {
872 c2->dco_write_bytes = ovpn_nla_get_uint(tb[OVPN_A_PEER_LINK_TX_BYTES]);
873 msg(D_DCO_DEBUG, "%s / dco_write_bytes: " counter_format, __func__, c2->dco_write_bytes);
874 }
875 else
876 {
877 msg(M_WARN, "%s: no link TX bytes provided in reply for peer %u", __func__, id);
878 }
879
881 {
882 c2->tun_read_bytes = ovpn_nla_get_uint(tb[OVPN_A_PEER_VPN_RX_BYTES]);
883 msg(D_DCO_DEBUG, "%s / tun_read_bytes: " counter_format, __func__, c2->tun_read_bytes);
884 }
885 else
886 {
887 msg(M_WARN, "%s: no VPN RX bytes provided in reply for peer %u", __func__, id);
888 }
889
891 {
892 c2->tun_write_bytes = ovpn_nla_get_uint(tb[OVPN_A_PEER_VPN_TX_BYTES]);
893 msg(D_DCO_DEBUG, "%s / tun_write_bytes: " counter_format, __func__, c2->tun_write_bytes);
894 }
895 else
896 {
897 msg(M_WARN, "%s: no VPN TX bytes provided in reply for peer %u", __func__, id);
898 }
899}
900
901static int
902ovpn_handle_peer(dco_context_t *dco, struct nlattr *attrs[])
903{
904 if (!attrs[OVPN_A_PEER])
905 {
906 msg(D_DCO_DEBUG, "%s: malformed reply", __func__);
907 return NL_SKIP;
908 }
909
910 struct nlattr *tb_peer[OVPN_A_PEER_MAX + 1];
911 nla_parse_nested(tb_peer, OVPN_A_PEER_MAX, attrs[OVPN_A_PEER], NULL);
912
913 if (!tb_peer[OVPN_A_PEER_ID])
914 {
915 msg(M_WARN, "ovpn-dco: no peer-id provided in PEER_GET reply");
916 return NL_SKIP;
917 }
918
919 uint32_t peer_id = nla_get_u32(tb_peer[OVPN_A_PEER_ID]);
920 struct context_2 *c2;
921
922 msg(D_DCO_DEBUG | M_NOIPREFIX, "%s: parsing message for peer %u...", __func__, peer_id);
923
924 if (dco->ifmode == OVPN_MODE_P2P)
925 {
926 c2 = &dco->c->c2;
927 if (c2->tls_multi->dco_peer_id != (int)peer_id)
928 {
929 return NL_SKIP;
930 }
931 }
932 else
933 {
934 if (peer_id >= dco->c->multi->max_clients)
935 {
936 msg(M_WARN, "%s: received out of bound peer_id %u (max=%u)", __func__, peer_id,
937 dco->c->multi->max_clients);
938 return NL_SKIP;
939 }
940
941 struct multi_instance *mi = dco->c->multi->instances[peer_id];
942 if (!mi)
943 {
944 msg(M_WARN | M_NOIPREFIX, "%s: received data for a non-existing peer %u", __func__, peer_id);
945 return NL_SKIP;
946 }
947
948 c2 = &mi->context.c2;
949 }
950
951 dco_update_peer_stat(c2, tb_peer, peer_id);
952
953 return NL_OK;
954}
955
956static bool
957ovpn_iface_check(dco_context_t *dco, struct nlattr *attrs[])
958{
959 /* we must know which interface this message is referring to in order to
960 * avoid mixing messages for other instances
961 */
962 if (!attrs[OVPN_A_IFINDEX])
963 {
964 msg(D_DCO, "ovpn-dco: Received message without ifindex");
965 return false;
966 }
967
968 uint32_t ifindex = nla_get_u32(attrs[OVPN_A_IFINDEX]);
969 if (ifindex != dco->ifindex)
970 {
971 msg(D_DCO_DEBUG, "ovpn-dco: ignoring message for foreign ifindex %u", ifindex);
972 return false;
973 }
974
975 return true;
976}
977
978static int
979ovpn_handle_peer_del_ntf(dco_context_t *dco, struct nlattr *attrs[])
980{
981 if (!ovpn_iface_check(dco, attrs))
982 {
983 return NL_STOP;
984 }
985
986 if (!attrs[OVPN_A_PEER])
987 {
988 msg(D_DCO | M_NOIPREFIX, "ovpn-dco: no peer in PEER_DEL_NTF message");
989 return NL_STOP;
990 }
991
992 struct nlattr *dp_attrs[OVPN_A_PEER_MAX + 1];
993 if (nla_parse_nested(dp_attrs, OVPN_A_PEER_MAX, attrs[OVPN_A_PEER], NULL))
994 {
995 msg(D_DCO | M_NOIPREFIX, "ovpn-dco: can't parse peer in PEER_DEL_NTF messsage");
996 return NL_STOP;
997 }
998
999 if (!dp_attrs[OVPN_A_PEER_DEL_REASON])
1000 {
1001 msg(D_DCO | M_NOIPREFIX, "ovpn-dco: no reason in PEER_DEL_NTF message");
1002 return NL_STOP;
1003 }
1004 if (!dp_attrs[OVPN_A_PEER_ID])
1005 {
1006 msg(D_DCO | M_NOIPREFIX, "ovpn-dco: no peer-id in PEER_DEL_NTF message");
1007 return NL_STOP;
1008 }
1009
1010 int reason = nla_get_u32(dp_attrs[OVPN_A_PEER_DEL_REASON]);
1011 unsigned int peerid = nla_get_u32(dp_attrs[OVPN_A_PEER_ID]);
1012
1013 msg(D_DCO_DEBUG | M_NOIPREFIX, "ovpn-dco: received CMD_PEER_DEL_NTF, ifindex: %u, peer-id %u, reason: %d",
1014 dco->ifindex, peerid, reason);
1015 dco->dco_message_peer_id = peerid;
1016 dco->dco_del_peer_reason = reason;
1017 dco->dco_message_type = OVPN_CMD_PEER_DEL_NTF;
1018
1019 return NL_OK;
1020}
1021
1022static int
1023ovpn_handle_peer_float_ntf(dco_context_t *dco, struct nlattr *attrs[])
1024{
1025 if (!ovpn_iface_check(dco, attrs))
1026 {
1027 return NL_STOP;
1028 }
1029
1030 if (!attrs[OVPN_A_PEER])
1031 {
1032 msg(D_DCO, "ovpn-dco: no peer in PEER_FLOAT_NTF message");
1033 return NL_STOP;
1034 }
1035
1036 struct nlattr *fp_attrs[OVPN_A_PEER_MAX + 1];
1037 if (nla_parse_nested(fp_attrs, OVPN_A_PEER_MAX, attrs[OVPN_A_PEER], NULL))
1038 {
1039 msg(D_DCO, "ovpn-dco: can't parse peer in PEER_FLOAT_NTF messsage");
1040 return NL_STOP;
1041 }
1042
1043 if (!fp_attrs[OVPN_A_PEER_ID])
1044 {
1045 msg(D_DCO, "ovpn-dco: no peer-id in PEER_FLOAT_NTF message");
1046 return NL_STOP;
1047 }
1048 uint32_t peerid = nla_get_u32(fp_attrs[OVPN_A_PEER_ID]);
1049
1050 if (!ovpn_parse_float_addr(fp_attrs, (struct sockaddr *)&dco->dco_float_peer_ss))
1051 {
1052 return NL_STOP;
1053 }
1054
1055 struct gc_arena gc = gc_new();
1056 msg(D_DCO_DEBUG, "ovpn-dco: received CMD_PEER_FLOAT_NTF, ifindex: %u, peer-id %u, address: %s",
1057 dco->ifindex, peerid, print_sockaddr((struct sockaddr *)&dco->dco_float_peer_ss, &gc));
1058 dco->dco_message_peer_id = (int)peerid;
1059 dco->dco_message_type = OVPN_CMD_PEER_FLOAT_NTF;
1060
1061 gc_free(&gc);
1062
1063 return NL_OK;
1064}
1065
1066static int
1067ovpn_handle_key_swap_ntf(dco_context_t *dco, struct nlattr *attrs[])
1068{
1069 if (!ovpn_iface_check(dco, attrs))
1070 {
1071 return NL_STOP;
1072 }
1073
1074 if (!attrs[OVPN_A_KEYCONF])
1075 {
1076 msg(D_DCO, "ovpn-dco: no keyconf in KEY_SWAP_NTF message");
1077 return NL_STOP;
1078 }
1079
1080 struct nlattr *dp_attrs[OVPN_A_KEYCONF_MAX + 1];
1081 if (nla_parse_nested(dp_attrs, OVPN_A_KEYCONF_MAX, attrs[OVPN_A_KEYCONF], NULL))
1082 {
1083 msg(D_DCO, "ovpn-dco: can't parse keyconf in KEY_SWAP_NTF message");
1084 return NL_STOP;
1085 }
1086 if (!dp_attrs[OVPN_A_KEYCONF_PEER_ID])
1087 {
1088 msg(D_DCO, "ovpn-dco: no peer-id in KEY_SWAP_NTF message");
1089 return NL_STOP;
1090 }
1091 if (!dp_attrs[OVPN_A_KEYCONF_KEY_ID])
1092 {
1093 msg(D_DCO, "ovpn-dco: no key-id in KEY_SWAP_NTF message");
1094 return NL_STOP;
1095 }
1096
1097 int key_id = nla_get_u16(dp_attrs[OVPN_A_KEYCONF_KEY_ID]);
1098 unsigned int peer_id = nla_get_u32(dp_attrs[OVPN_A_KEYCONF_PEER_ID]);
1099
1100 msg(D_DCO_DEBUG, "ovpn-dco: received CMD_KEY_SWAP_NTF, ifindex: %u, peer-id %u, key-id: %d",
1101 dco->ifindex, peer_id, key_id);
1102 dco->dco_message_peer_id = peer_id;
1103 dco->dco_message_key_id = key_id;
1104 dco->dco_message_type = OVPN_CMD_KEY_SWAP_NTF;
1105
1106 return NL_OK;
1107}
1108
1109/* This function parses any netlink message sent by ovpn-dco to userspace */
1110static int
1111ovpn_handle_msg(struct nl_msg *msg, void *arg)
1112{
1113 dco_context_t *dco = arg;
1114
1115 struct nlattr *attrs[OVPN_A_MAX + 1];
1116 struct nlmsghdr *nlh = nlmsg_hdr(msg);
1117 struct genlmsghdr *gnlh = genlmsg_hdr(nlh);
1118
1119 msg(D_DCO_DEBUG | M_NOIPREFIX, "ovpn-dco: received netlink message type=%u cmd=%u flags=%#.4x",
1120 nlh->nlmsg_type, gnlh->cmd, nlh->nlmsg_flags);
1121
1122 /* if we get a message from the NLCTRL family, it means
1123 * this is the reply to the mcast ID resolution request
1124 * and we parse it accordingly.
1125 */
1126 if (nlh->nlmsg_type == dco->ctrlid)
1127 {
1128 msg(D_DCO_DEBUG, "ovpn-dco: received CTRLID message");
1129 return mcast_family_handler(msg, dco);
1130 }
1131
1132 if (!genlmsg_valid_hdr(nlh, 0))
1133 {
1134 msg(D_DCO, "ovpn-dco: invalid header");
1135 return NL_STOP;
1136 }
1137
1138 if (nla_parse(attrs, OVPN_A_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL))
1139 {
1140 msg(D_DCO, "received bogus data from ovpn-dco");
1141 return NL_STOP;
1142 }
1143
1144 /* based on the message type, we parse the subobject contained in the
1145 * message, that stores the type-specific attributes.
1146 *
1147 * the "dco" object is then filled accordingly with the information
1148 * retrieved from the message, so that *process_incoming_dco can react
1149 * as need be.
1150 */
1151 int ret;
1152 switch (gnlh->cmd)
1153 {
1154 case OVPN_CMD_PEER_GET:
1155 {
1156 /* return directly, there are no messages to pass to *process_incoming_dco() */
1157 return ovpn_handle_peer(dco, attrs);
1158 }
1159
1161 {
1162 ret = ovpn_handle_peer_del_ntf(dco, attrs);
1163 break;
1164 }
1165
1167 {
1168 ret = ovpn_handle_peer_float_ntf(dco, attrs);
1169 break;
1170 }
1171
1173 {
1174 ret = ovpn_handle_key_swap_ntf(dco, attrs);
1175 break;
1176 }
1177
1178 default:
1179 msg(D_DCO, "ovpn-dco: received unknown command: %d", gnlh->cmd);
1180 dco->dco_message_type = 0;
1181 return NL_STOP;
1182 }
1183
1184 if (ret != NL_OK)
1185 {
1186 return ret;
1187 }
1188
1189 if (dco->c->mode == CM_TOP)
1190 {
1192 }
1193 else
1194 {
1196 }
1197
1198 return NL_OK;
1199}
1200
1201int
1203{
1204 msg(D_DCO_DEBUG, __func__);
1205
1206 /* Drain the multicast notification socket. This is the only place where
1207 * asynchronous notifications (peer del/float, key swap) are processed, so
1208 * the multi_close_instance() they may trigger happens at a safe point in
1209 * the event loop rather than re-entrantly inside a request/reply. */
1210 int ret = nl_recvmsgs(dco->nl_sock_notify, dco->nl_cb_notify);
1211
1212 return ovpn_nl_recvmsgs_report(ret, __func__);
1213}
1214
1215static int
1216dco_get_peer(dco_context_t *dco, int peer_id, const bool raise_sigusr1_on_err)
1217{
1218 ASSERT(dco);
1219
1220 /* peer_id == -1 means "dump all peers", but this is allowed in MP mode only.
1221 * If it happens in P2P mode it means that the DCO peer was deleted and we
1222 * can simply bail out
1223 */
1224 if (peer_id == -1 && dco->ifmode == OVPN_MODE_P2P)
1225 {
1226 return 0;
1227 }
1228
1229 msg(D_DCO_DEBUG | M_NOIPREFIX, "%s: peer-id %d", __func__, peer_id);
1230
1231 struct nl_msg *nl_msg = ovpn_dco_nlmsg_create(dco, OVPN_CMD_PEER_GET);
1232 struct nlattr *attr = nla_nest_start(nl_msg, OVPN_A_PEER);
1233 int ret = -EMSGSIZE;
1234
1235 if (peer_id != -1)
1236 {
1237 NLA_PUT_U32(nl_msg, OVPN_A_PEER_ID, peer_id);
1238 }
1239 else
1240 {
1241 nlmsg_hdr(nl_msg)->nlmsg_flags |= NLM_F_DUMP;
1242 }
1243 nla_nest_end(nl_msg, attr);
1244
1245 ret = ovpn_nl_msg_send(dco, nl_msg, __func__);
1246
1247nla_put_failure:
1248 nlmsg_free(nl_msg);
1249
1250 if (raise_sigusr1_on_err && ret < 0)
1251 {
1252 msg(M_WARN, "Error retrieving DCO peer stats: the underlying DCO peer"
1253 "may have been deleted from the kernel without notifying "
1254 "userspace. Restarting the session");
1255 register_signal(dco->c->sig, SIGUSR1, "dco peer stats error");
1256 }
1257 return ret;
1258}
1259
1260int
1261dco_get_peer_stats(struct context *c, const bool raise_sigusr1_on_err)
1262{
1263 if (!c->c1.tuntap || c->c1.tuntap->dco.ifindex == 0)
1264 {
1265 return -1;
1266 }
1267
1268 return dco_get_peer(&c->c1.tuntap->dco, c->c2.tls_multi->dco_peer_id, raise_sigusr1_on_err);
1269}
1270
1271int
1272dco_get_peer_stats_multi(dco_context_t *dco, const bool raise_sigusr1_on_err)
1273{
1274 return dco_get_peer(dco, -1, raise_sigusr1_on_err);
1275}
1276
1277bool
1278dco_available(msglvl_t msglevel)
1279{
1280 if (resolve_ovpn_netlink_id(D_DCO_DEBUG) < 0)
1281 {
1282 msg(msglevel, "Note: Kernel support for ovpn interfaces missing, "
1283 "disabling data channel offload. Use Linux 6.16.0 or "
1284 "newer with ovpn support or use ovpn-backports for "
1285 "interface support.");
1286 return false;
1287 }
1288
1289 return true;
1290}
1291
1296static const char *
1297dco_version_string_in_tree(struct gc_arena *gc)
1298{
1299 struct buffer buf = alloc_buf_gc(256, gc);
1300 struct utsname system;
1301
1302 if (uname(&system))
1303 {
1304 return "ERR";
1305 }
1306
1307 buf_puts(&buf, system.release);
1308 buf_puts(&buf, " ");
1309 buf_puts(&buf, system.version);
1310 return BSTR(&buf);
1311}
1312
1319static const char *
1320dco_version_string_backports(FILE *fp, struct gc_arena *gc)
1321{
1322 char *str = gc_malloc(PATH_MAX, false, gc);
1323
1324 if (!fgets(str, PATH_MAX, fp))
1325 {
1326 return "ERR";
1327 }
1328
1329 /* remove potential newline at the end of the string */
1330 char *nl = strchr(str, '\n');
1331 if (nl)
1332 {
1333 *nl = '\0';
1334 }
1335
1336 return str;
1337}
1338
1339const char *
1341{
1342 const char *version;
1343 struct stat sb;
1344 FILE *fp;
1345
1346 if (stat("/sys/module/ovpn", &sb) != 0 || !S_ISDIR(sb.st_mode))
1347 {
1348 return "N/A";
1349 }
1350
1351 /* now that we know for sure that the module is loaded, if there's no
1352 * version file it means we're dealing with the in-tree version, otherwise
1353 * it's backports */
1354 fp = fopen("/sys/module/ovpn/version", "r");
1355 if (!fp)
1356 {
1357 return dco_version_string_in_tree(gc);
1358 }
1359 version = dco_version_string_backports(fp, gc);
1360
1361 fclose(fp);
1362 return version;
1363}
1364
1365void
1366dco_event_set(dco_context_t *dco, struct event_set *es, void *arg)
1367{
1368 if (dco && dco->nl_sock_notify)
1369 {
1370 /* Only the notification socket is monitored by the event loop. The
1371 * request/reply socket (dco->nl_sock) is drained synchronously by
1372 * ovpn_nl_msg_send(). */
1373 event_ctl(es, nl_socket_get_fd(dco->nl_sock_notify), EVENT_READ, arg);
1374 }
1375}
1376
1377const char *
1379{
1380 return "AES-128-GCM:AES-256-GCM:AES-192-GCM:CHACHA20-POLY1305";
1381}
1382
1383bool
1385{
1386 return false;
1387}
1388
1389#endif /* defined(ENABLE_DCO) && defined(TARGET_LINUX) */
bool buf_puts(struct buffer *buf, const char *str)
Append a string to a buffer with overflow check.
Definition buffer.c:253
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Allocate memory and, optionally, zero it.
Definition buffer.c:318
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Allocate a buffer of the given size under garbage collection.
Definition buffer.c:77
Buffer management functions and garbage collection.
#define BSTR(buf)
Return the buffer content pointer cast to char *.
Definition buffer.h:157
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Allocate and zero-initialise a garbage-collected object of the given type.
Definition buffer.h:2134
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
Definition buffer.h:1976
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
Definition buffer.h:1960
#define counter_format
Definition common.h:32
unsigned int cipher_kt_key_size(const char *ciphername)
Returns the size of keys used by the cipher, in bytes.
static int dco_get_peer_stats_multi(dco_context_t *dco, const bool raise_sigusr1_on_err)
Definition dco.h:369
static int dco_set_peer(dco_context_t *dco, unsigned int peerid, int keepalive_interval, int keepalive_timeout, int mss)
Definition dco.h:341
static const char * dco_get_supported_ciphers(void)
Definition dco.h:381
static bool dco_supports_epoch_data(struct context *c)
Definition dco.h:387
static void dco_event_set(dco_context_t *dco, struct event_set *es, void *arg)
Definition dco.h:316
static int open_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx, const char *dev)
Definition dco.h:298
static int dco_read_and_process(dco_context_t *dco)
Definition dco.h:309
static bool dco_available(msglvl_t msglevel)
Definition dco.h:262
static bool ovpn_dco_init(struct context *c)
Definition dco.h:292
void * dco_context_t
Definition dco.h:259
static const char * dco_version_string(struct gc_arena *gc)
Definition dco.h:268
static void close_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx)
Definition dco.h:304
static int dco_get_peer_stats(struct context *c, const bool raise_sigusr1_on_err)
Definition dco.h:375
int dco_del_key(dco_context_t *dco, unsigned int peerid, dco_key_slot_t slot)
Definition dco_win.c:576
int dco_del_peer(dco_context_t *dco, unsigned int peerid)
Definition dco_win.c:461
int dco_swap_keys(dco_context_t *dco, unsigned int peer_id)
Definition dco_win.c:584
int dco_new_peer(dco_context_t *dco, unsigned int peerid, socket_descriptor_t sd, struct sockaddr *localaddr, struct sockaddr *remoteaddr, const struct in_addr *vpn_ipv4, const struct in6_addr *vpn_ipv6)
Definition dco_win.c:408
int dco_new_key(dco_context_t *dco, unsigned int peerid, int keyid, dco_key_slot_t slot, const uint8_t *encrypt_key, const uint8_t *encrypt_iv, const uint8_t *decrypt_key, const uint8_t *decrypt_iv, const char *ciphername, bool epoch)
Definition dco_win.c:521
#define D_DCO
Definition errlevel.h:93
#define D_DCO_DEBUG
Definition errlevel.h:117
#define M_INFO
Definition errlevel.h:54
#define EVENT_READ
Definition event.h:37
static void event_ctl(struct event_set *es, event_t event, unsigned int rwflags, void *arg)
Definition event.h:180
void set_nonblock(socket_descriptor_t fd)
Definition fdmisc.c:68
void set_cloexec(socket_descriptor_t fd)
Definition fdmisc.c:78
void process_incoming_dco(dco_context_t *dco)
Process an incoming DCO message (from kernel space).
Definition forward.c:1268
static SERVICE_STATUS status
Definition interactive.c:52
Header file for server-mode related structures and functions.
void multi_process_incoming_dco(dco_context_t *dco)
Process an incoming DCO message (from kernel space).
void * openvpn_net_ctx_t
Definition networking.h:38
#define CLEAR(x)
Definition basic.h:32
#define M_NOIPREFIX
Definition error.h:103
#define M_FATAL
Definition error.h:90
#define M_NONFATAL
Definition error.h:91
#define msg(flags,...)
Definition error.h:152
unsigned int msglvl_t
Definition error.h:77
#define ASSERT(x)
Definition error.h:221
#define M_WARN
Definition error.h:92
#define CM_P2P
Definition openvpn.h:479
#define CM_TOP
Definition openvpn.h:480
@ OVPN_CIPHER_ALG_NONE
@ OVPN_A_KEYCONF
@ OVPN_A_MAX
@ OVPN_A_PEER
@ OVPN_A_IFINDEX
@ OVPN_CMD_PEER_FLOAT_NTF
@ OVPN_CMD_KEY_DEL
@ OVPN_CMD_PEER_NEW
@ OVPN_CMD_PEER_GET
@ OVPN_CMD_KEY_SWAP
@ OVPN_CMD_KEY_SWAP_NTF
@ OVPN_CMD_PEER_DEL_NTF
@ OVPN_CMD_PEER_SET
@ OVPN_CMD_KEY_NEW
@ OVPN_CMD_PEER_DEL
@ OVPN_A_PEER_LINK_RX_BYTES
@ OVPN_A_PEER_VPN_IPV6
@ OVPN_A_PEER_LINK_TX_BYTES
@ OVPN_A_PEER_VPN_IPV4
@ OVPN_A_PEER_KEEPALIVE_TIMEOUT
@ OVPN_A_PEER_VPN_TX_BYTES
@ OVPN_A_PEER_LOCAL_IPV6
@ OVPN_A_PEER_REMOTE_IPV6
@ OVPN_A_PEER_VPN_RX_BYTES
@ OVPN_A_PEER_MAX
@ OVPN_A_PEER_LOCAL_IPV4
@ OVPN_A_PEER_DEL_REASON
@ OVPN_A_PEER_ID
@ OVPN_A_PEER_SOCKET
@ OVPN_A_PEER_REMOTE_IPV4
@ OVPN_A_PEER_KEEPALIVE_INTERVAL
@ OVPN_A_PEER_REMOTE_IPV6_SCOPE_ID
@ OVPN_A_PEER_REMOTE_PORT
#define OVPN_FAMILY_NAME
#define OVPN_MCGRP_PEERS
@ OVPN_A_KEYCONF_SLOT
@ OVPN_A_KEYCONF_PEER_ID
@ OVPN_A_KEYCONF_MAX
@ OVPN_A_KEYCONF_DECRYPT_DIR
@ OVPN_A_KEYCONF_CIPHER_ALG
@ OVPN_A_KEYCONF_ENCRYPT_DIR
@ OVPN_A_KEYCONF_KEY_ID
@ OVPN_A_KEYDIR_CIPHER_KEY
@ OVPN_A_KEYDIR_NONCE_TAIL
@ OVPN_MODE_MP
@ OVPN_MODE_P2P
#define DEV_TYPE_TUN
Definition proto.h:35
void register_signal(struct signal_info *si, int signum, const char *signal_text)
Register a soft signal in the signal_info struct si respecting priority.
Definition sig.c:228
static const char * print_sockaddr(const struct sockaddr *addr, struct gc_arena *gc)
Definition socket_util.h:77
Control Channel SSL/Data channel negotiation module.
Control Channel Verification Module.
Wrapper structure for dynamically allocated memory.
Definition buffer.h:71
struct tuntap * tuntap
Tun/tap virtual network interface.
Definition openvpn.h:173
Level 2 context containing state that is reset on both SIGHUP and SIGUSR1 restarts.
Definition openvpn.h:225
counter_type dco_read_bytes
Definition openvpn.h:268
counter_type tun_read_bytes
Definition openvpn.h:265
counter_type dco_write_bytes
Definition openvpn.h:271
struct tls_multi * tls_multi
TLS state structure for this VPN tunnel.
Definition openvpn.h:324
counter_type tun_write_bytes
Definition openvpn.h:266
Contains all state information for one tunnel.
Definition openvpn.h:471
int mode
Role of this context within the OpenVPN process.
Definition openvpn.h:484
struct context_2 c2
Level 2 context.
Definition openvpn.h:516
struct context_1 c1
Level 1 context.
Definition openvpn.h:515
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:127
Container for two sets of OpenSSL cipher and/or HMAC contexts for both sending and receiving directio...
Definition crypto.h:280
Container for unidirectional cipher and HMAC key material.
Definition crypto.h:152
Server-mode state structure for one single VPN tunnel.
Definition multi.h:102
struct context context
The context structure storing state for this VPN tunnel.
Definition multi.h:142
int dco_peer_id
This is the handle that DCO uses to identify this session with the kernel.
Definition ssl_common.h:725
Definition tun.h:181
int type
Definition tun.h:183
dco_context_t dco
Definition tun.h:247
char * actual_name
Definition tun.h:205
#define SIGUSR1
Definition syshead.h:57
__attribute__((unused))
Definition test.c:42
struct gc_arena gc
Definition test_ssl.c:122