From patchwork Sun Nov 27 11:18:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kristof Provost X-Patchwork-Id: 2862 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director8.mail.ord1d.rsapps.net ([172.31.255.6]) by backend30.mail.ord1d.rsapps.net with LMTP id UBDvLcxHg2OrAgAAIUCqbw (envelope-from ) for ; Sun, 27 Nov 2022 06:19:40 -0500 Received: from proxy18.mail.iad3b.rsapps.net ([172.31.255.6]) by director8.mail.ord1d.rsapps.net with LMTP id aPDJLcxHg2P4MQAAfY0hYg (envelope-from ) for ; Sun, 27 Nov 2022 06:19:40 -0500 Received: from smtp20.gate.iad3b ([172.31.255.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy18.mail.iad3b.rsapps.net with LMTPS id +KaoJsxHg2OhDQAA3NpJmQ (envelope-from ) for ; Sun, 27 Nov 2022 06:19:40 -0500 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp20.gate.iad3b.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dkim=fail (signature verification failed) header.d=netgate.com; dmarc=pass (p=none; dis=none) header.from=lists.sourceforge.net X-Suspicious-Flag: YES X-Classification-ID: 61ffc68a-6e45-11ed-8cf2-525400497f28-1-1 Received: from [216.105.38.7] ([216.105.38.7:34668] helo=lists.sourceforge.net) by smtp20.gate.iad3b.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 1B/1F-24191-BC743836; Sun, 27 Nov 2022 06:19:40 -0500 Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1ozFgj-00029c-2Q; Sun, 27 Nov 2022 11:19:09 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1ozFgf-00029O-NF for openvpn-devel@lists.sourceforge.net; Sun, 27 Nov 2022 11:19:05 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=xoB8y8UJkeACzPqoV0bBTiQXObiLOkNUC9uJLrZyMxs=; b=Nrl2ZcgjuRcso8nP9wGi7Q1Yun BkQE9f8jFC9w1Xh7KWxndHkk5bbSwee1hVbu1N5kk/jjscIIjp3PJEgi/UtI2iSLakxGEzLWAUxUO ana0ahYKn9YGscv5FCow4dwil3/Hr2B2qIgk+NdQ6kcbFtj+h6UiTyigsJgmTPag+0TA=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=xoB8y8UJkeACzPqoV0bBTiQXObiLOkNUC9uJLrZyMxs=; b=d6DvilPfsPf6pxN77jSa0AEN1p G+cZ9cgbs4lFMJqJQvXEuAo6TOkyK4ipcQaV8wy5H0zTJ8CKc222kQVkbj844SDMHXERTgybQ8TqL onG2nY+Lu6VhxH6PbzvUGnDxStT+4IeY/waxlbo9l1BJxpjSdCDFS1w7wYnao3ACXIkA=; Received: from mail-ej1-f43.google.com ([209.85.218.43]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.95) id 1ozFga-00FS5d-DS for openvpn-devel@lists.sourceforge.net; Sun, 27 Nov 2022 11:19:05 +0000 Received: by mail-ej1-f43.google.com with SMTP id i10so19550092ejg.6 for ; Sun, 27 Nov 2022 03:19:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netgate.com; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=xoB8y8UJkeACzPqoV0bBTiQXObiLOkNUC9uJLrZyMxs=; b=YnKIKBUR4+cdsEruiEDNox7O6Dg3Vk4zWhDMSb1Vtw2gc8VPJ3qUMHNQeL5eMkndqN VyX0U15e8brPFL7oTMRqAoHUzBos9gnQLO+qW/7bXHsTawuDnxg8K1aJz139ItrCTxH7 FI9KgJDXsCyzGJf/pf2c2+zA05/Hv/FKR5f5M= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=xoB8y8UJkeACzPqoV0bBTiQXObiLOkNUC9uJLrZyMxs=; b=XeBP8lOL1jG5J522nfXHVxiyi5q4WXOdu2n09xsUJor3iQ/+DJi737rBoWMG8ZX59F gkOV/5kBbQQOtm6EOf1pqT/motMVw0Cx83zWV0br/WpMbY+qTCy3AIntBI44RIKXsNXp 7DpwP2AJLV0k84Mpfhlo1KKr26DW6qelQjqz0SR9AwbdjFxL8L2u7c5MuUIOO42sov68 K3VR+pTrwXW8hhLuk7tWGKWyLbIBgU9t1h6lmr7lWmg4t0lphZvatP4oV6IIZrjtrMkd qUXUk/BEi1AZZM/qd720blO0a7YS+nckYqtOrsB67eX3afmk42C8k11gFYkeOdscZmcd B74w== X-Gm-Message-State: ANoB5pn7v9DaFgb09vGZUoxF6ja5Zrdkkaauogd20cZkRJLeWb+IEbLq YGVrxnTQ12tQD12xDgAwTUDNDpk42zKjchBt X-Google-Smtp-Source: AA0mqf4r4ntsobf9+9wTXKvMA57styzkMl9R7HTht7P+l4hjCYXhreFQZWQWUgXq1O4tL3VpIXXV/w== X-Received: by 2002:a17:906:cc8f:b0:78b:8ce7:fe3c with SMTP id oq15-20020a170906cc8f00b0078b8ce7fe3cmr39241623ejb.557.1669547933646; Sun, 27 Nov 2022 03:18:53 -0800 (PST) Received: from nut.jupiter.sigsegv.be (ptr-8rfalzsse26o3oo9imw.18120a2.ip6.access.telenet.be. [2a02:1811:2402:bf00:f602:70ff:feae:6e98]) by smtp.googlemail.com with ESMTPSA id n3-20020a056402514300b0045d59e49acbsm3988364edd.7.2022.11.27.03.18.53 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 27 Nov 2022 03:18:53 -0800 (PST) To: openvpn-devel Date: Sun, 27 Nov 2022 12:18:45 +0100 Message-Id: <20221127111845.11310-2-kprovost@netgate.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221127111845.11310-1-kprovost@netgate.com> References: <20221127111845.11310-1-kprovost@netgate.com> MIME-Version: 1.0 X-Spam-Report: Spam detection software, running on the system "util-spamd-2.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: 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. Content analysis details: (-0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.218.43 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.218.43 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1ozFga-00FS5d-DS Subject: [Openvpn-devel] [PATCH] Read DCO traffic stats from the kernel X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Kristof Provost via Openvpn-devel From: Kristof Provost Reply-To: Kristof Provost Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox 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 m the 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, &hi); + + while ((he = hash_iterator_next(&hi))) + { + 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, &drv); + 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", &npeers); + 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(&m->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(&mi->context)); /* setenv stats */ - setenv_stats(&mi->context); + setenv_stats(m, &mi->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); + multi_client_disconnect_setenv(m, mi); if (plugin_defined(mi->context.plugins, OPENVPN_PLUGIN_CLIENT_DISCONNECT)) { @@ -667,7 +669,7 @@ multi_close_instance(struct multi_context *m, if (mi->context.c2.tls_multi->multi_state >= CAS_CONNECT_DONE) { - multi_client_disconnect_script(mi); + multi_client_disconnect_script(m, mi); } close_context(&mi->context, SIGTERM, CC_GC_FREE); @@ -837,6 +839,8 @@ multi_print_status(struct multi_context *m, struct status_output *so, const int status_reset(so); + dco_get_peer_stats(&m->top.c1.tuntap->dco, m); + if (version == 1) { /* @@ -856,8 +860,8 @@ multi_print_status(struct multi_context *m, struct status_output *so, const int status_printf(so, "%s,%s," counter_format "," counter_format ",%s", tls_common_name(mi->context.c2.tls_multi, false), mroute_addr_print(&mi->real, &gc), - mi->context.c2.link_read_bytes, - mi->context.c2.link_write_bytes, + mi->context.c2.link_read_bytes + mi->context.c2.dco_read_bytes, + mi->context.c2.link_write_bytes + mi->context.c2.dco_write_bytes, time_string(mi->created, 0, false, &gc)); } gc_free(&gc); @@ -932,8 +936,8 @@ multi_print_status(struct multi_context *m, struct status_output *so, const int sep, mroute_addr_print(&mi->real, &gc), sep, print_in_addr_t(mi->reporting_addr, IA_EMPTY_IF_UNDEF, &gc), sep, print_in6_addr(mi->reporting_addr_ipv6, IA_EMPTY_IF_UNDEF, &gc), - sep, mi->context.c2.link_read_bytes, - sep, mi->context.c2.link_write_bytes, + sep, mi->context.c2.link_read_bytes + mi->context.c2.dco_read_bytes, + sep, mi->context.c2.link_write_bytes + mi->context.c2.dco_write_bytes, sep, time_string(mi->created, 0, false, &gc), sep, (unsigned int)mi->created, sep, tls_username(mi->context.c2.tls_multi, false), @@ -2740,7 +2744,7 @@ multi_connection_established(struct multi_context *m, struct multi_instance *mi) * did not fail */ if (mi->context.c2.tls_multi->multi_state == CAS_PENDING_DEFERRED_PARTIAL) { - multi_client_disconnect_script(mi); + multi_client_disconnect_script(m, mi); } mi->context.c2.tls_multi->multi_state = CAS_FAILED; diff --git a/src/openvpn/openvpn.h b/src/openvpn/openvpn.h index c543cbf6..5981e4d5 100644 --- a/src/openvpn/openvpn.h +++ b/src/openvpn/openvpn.h @@ -267,8 +267,10 @@ struct context_2 counter_type tun_read_bytes; counter_type tun_write_bytes; counter_type link_read_bytes; + counter_type dco_read_bytes; counter_type link_read_bytes_auth; counter_type link_write_bytes; + counter_type dco_write_bytes; #ifdef PACKET_TRUNCATION_CHECK counter_type n_trunc_tun_read; counter_type n_trunc_tun_write; diff --git a/src/openvpn/ovpn_dco_freebsd.h b/src/openvpn/ovpn_dco_freebsd.h index cf92d597..cc90111e 100644 --- a/src/openvpn/ovpn_dco_freebsd.h +++ b/src/openvpn/ovpn_dco_freebsd.h @@ -61,5 +61,6 @@ enum ovpn_key_cipher { #define OVPN_POLL_PKT _IO('D', 10) #define OVPN_GET_PKT _IO('D', 11) #define OVPN_SET_IFMODE _IO('D', 12) +#define OVPN_GET_PEER_STATS _IO('D', 13) #endif /* ifndef _NET_IF_OVPN_H_ */