Skip to content

Commit 04ca149

Browse files
ordexPaolo Abeni
authored and
Paolo Abeni
committed
ovpn: store tunnel and transport statistics
Byte/packet counters for in-tunnel and transport streams are now initialized and updated as needed. To be exported via netlink. Signed-off-by: Antonio Quartulli <[email protected]> Link: https://patch.msgid.link/[email protected] Reviewed-by: Sabrina Dubroca <[email protected]> Tested-by: Oleksandr Natalenko <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 8534731 commit 04ca149

File tree

6 files changed

+87
-1
lines changed

6 files changed

+87
-1
lines changed

drivers/net/ovpn/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ ovpn-y += netlink-gen.o
1717
ovpn-y += peer.o
1818
ovpn-y += pktid.o
1919
ovpn-y += socket.o
20+
ovpn-y += stats.o
2021
ovpn-y += udp.o

drivers/net/ovpn/io.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/skbuff.h>
1313
#include <net/gro_cells.h>
1414
#include <net/gso.h>
15+
#include <net/ip.h>
1516

1617
#include "ovpnpriv.h"
1718
#include "peer.h"
@@ -55,9 +56,11 @@ static void ovpn_netdev_write(struct ovpn_peer *peer, struct sk_buff *skb)
5556
/* cause packet to be "received" by the interface */
5657
pkt_len = skb->len;
5758
ret = gro_cells_receive(&peer->ovpn->gro_cells, skb);
58-
if (likely(ret == NET_RX_SUCCESS))
59+
if (likely(ret == NET_RX_SUCCESS)) {
5960
/* update RX stats with the size of decrypted packet */
61+
ovpn_peer_stats_increment_rx(&peer->vpn_stats, pkt_len);
6062
dev_dstats_rx_add(peer->ovpn->dev, pkt_len);
63+
}
6164
}
6265

6366
void ovpn_decrypt_post(void *data, int ret)
@@ -152,6 +155,8 @@ void ovpn_recv(struct ovpn_peer *peer, struct sk_buff *skb)
152155
struct ovpn_crypto_key_slot *ks;
153156
u8 key_id;
154157

158+
ovpn_peer_stats_increment_rx(&peer->link_stats, skb->len);
159+
155160
/* get the key slot matching the key ID in the received packet */
156161
key_id = ovpn_key_id_from_skb(skb);
157162
ks = ovpn_crypto_key_id_to_slot(&peer->crypto, key_id);
@@ -175,6 +180,7 @@ void ovpn_encrypt_post(void *data, int ret)
175180
struct sk_buff *skb = data;
176181
struct ovpn_socket *sock;
177182
struct ovpn_peer *peer;
183+
unsigned int orig_len;
178184

179185
/* encryption is happening asynchronously. This function will be
180186
* called later by the crypto callback with a proper return value
@@ -194,6 +200,7 @@ void ovpn_encrypt_post(void *data, int ret)
194200
goto err;
195201

196202
skb_mark_not_on_list(skb);
203+
orig_len = skb->len;
197204

198205
rcu_read_lock();
199206
sock = rcu_dereference(peer->sock);
@@ -208,6 +215,8 @@ void ovpn_encrypt_post(void *data, int ret)
208215
/* no transport configured yet */
209216
goto err_unlock;
210217
}
218+
219+
ovpn_peer_stats_increment_tx(&peer->link_stats, orig_len);
211220
/* skb passed down the stack - don't free it */
212221
skb = NULL;
213222
err_unlock:
@@ -322,6 +331,7 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev)
322331
goto drop;
323332
}
324333

334+
ovpn_peer_stats_increment_tx(&peer->vpn_stats, skb->len);
325335
ovpn_send(ovpn, skb_list.next, peer);
326336

327337
return NETDEV_TX_OK;

drivers/net/ovpn/peer.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ struct ovpn_peer *ovpn_peer_new(struct ovpn_priv *ovpn, u32 id)
6161
ovpn_crypto_state_init(&peer->crypto);
6262
spin_lock_init(&peer->lock);
6363
kref_init(&peer->refcount);
64+
ovpn_peer_stats_init(&peer->vpn_stats);
65+
ovpn_peer_stats_init(&peer->link_stats);
6466

6567
ret = dst_cache_init(&peer->dst_cache, GFP_KERNEL);
6668
if (ret < 0) {

drivers/net/ovpn/peer.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "crypto.h"
1616
#include "socket.h"
17+
#include "stats.h"
1718

1819
/**
1920
* struct ovpn_peer - the main remote peer object
@@ -27,6 +28,8 @@
2728
* @crypto: the crypto configuration (ciphers, keys, etc..)
2829
* @dst_cache: cache for dst_entry used to send to peer
2930
* @bind: remote peer binding
31+
* @vpn_stats: per-peer in-VPN TX/RX stats
32+
* @link_stats: per-peer link/transport TX/RX stats
3033
* @delete_reason: why peer was deleted (i.e. timeout, transport error, ..)
3134
* @lock: protects binding to peer (bind)
3235
* @refcount: reference counter
@@ -45,6 +48,8 @@ struct ovpn_peer {
4548
struct ovpn_crypto_state crypto;
4649
struct dst_cache dst_cache;
4750
struct ovpn_bind __rcu *bind;
51+
struct ovpn_peer_stats vpn_stats;
52+
struct ovpn_peer_stats link_stats;
4853
enum ovpn_del_peer_reason delete_reason;
4954
spinlock_t lock; /* protects bind */
5055
struct kref refcount;

drivers/net/ovpn/stats.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* OpenVPN data channel offload
3+
*
4+
* Copyright (C) 2020-2025 OpenVPN, Inc.
5+
*
6+
* Author: James Yonan <[email protected]>
7+
* Antonio Quartulli <[email protected]>
8+
*/
9+
10+
#include <linux/atomic.h>
11+
12+
#include "stats.h"
13+
14+
void ovpn_peer_stats_init(struct ovpn_peer_stats *ps)
15+
{
16+
atomic64_set(&ps->rx.bytes, 0);
17+
atomic64_set(&ps->rx.packets, 0);
18+
19+
atomic64_set(&ps->tx.bytes, 0);
20+
atomic64_set(&ps->tx.packets, 0);
21+
}

drivers/net/ovpn/stats.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/* OpenVPN data channel offload
3+
*
4+
* Copyright (C) 2020-2025 OpenVPN, Inc.
5+
*
6+
* Author: James Yonan <[email protected]>
7+
* Antonio Quartulli <[email protected]>
8+
* Lev Stipakov <[email protected]>
9+
*/
10+
11+
#ifndef _NET_OVPN_OVPNSTATS_H_
12+
#define _NET_OVPN_OVPNSTATS_H_
13+
14+
/* one stat */
15+
struct ovpn_peer_stat {
16+
atomic64_t bytes;
17+
atomic64_t packets;
18+
};
19+
20+
/* rx and tx stats combined */
21+
struct ovpn_peer_stats {
22+
struct ovpn_peer_stat rx;
23+
struct ovpn_peer_stat tx;
24+
};
25+
26+
void ovpn_peer_stats_init(struct ovpn_peer_stats *ps);
27+
28+
static inline void ovpn_peer_stats_increment(struct ovpn_peer_stat *stat,
29+
const unsigned int n)
30+
{
31+
atomic64_add(n, &stat->bytes);
32+
atomic64_inc(&stat->packets);
33+
}
34+
35+
static inline void ovpn_peer_stats_increment_rx(struct ovpn_peer_stats *stats,
36+
const unsigned int n)
37+
{
38+
ovpn_peer_stats_increment(&stats->rx, n);
39+
}
40+
41+
static inline void ovpn_peer_stats_increment_tx(struct ovpn_peer_stats *stats,
42+
const unsigned int n)
43+
{
44+
ovpn_peer_stats_increment(&stats->tx, n);
45+
}
46+
47+
#endif /* _NET_OVPN_OVPNSTATS_H_ */

0 commit comments

Comments
 (0)