git: 8b630fa9ef6e - main - if_ovpn: implement OVPN_GET_PEER_STATS
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 14 Dec 2022 05:49:44 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=8b630fa9ef6e2eecc8425e62ea31194c4d0e410e
commit 8b630fa9ef6e2eecc8425e62ea31194c4d0e410e
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2022-11-27 11:58:40 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2022-12-14 05:48:58 +0000
if_ovpn: implement OVPN_GET_PEER_STATS
Allow userspace to retrieve per-peer traffic stats.
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D37604
---
sys/net/if_ovpn.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
sys/net/if_ovpn.h | 1 +
2 files changed, 58 insertions(+)
diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c
index 6686315fbf01..2cfe55568348 100644
--- a/sys/net/if_ovpn.c
+++ b/sys/net/if_ovpn.c
@@ -1212,6 +1212,60 @@ error:
return (ret);
}
+static int
+ovpn_get_peer_stats(struct ovpn_softc *sc, nvlist_t **nvl)
+{
+ struct ovpn_kpeer *peer;
+ nvlist_t *nvpeer = NULL;
+ int ret;
+
+ OVPN_RLOCK_TRACKER;
+
+ *nvl = nvlist_create(0);
+ if (*nvl == NULL)
+ return (ENOMEM);
+
+#define OVPN_PEER_COUNTER_OUT(name, in, out) \
+ do { \
+ ret = ovpn_add_counters(nvpeer, name, \
+ peer->counters[offsetof(struct ovpn_peer_counters, in) / \
+ sizeof(uint64_t)], \
+ peer->counters[offsetof(struct ovpn_peer_counters, out) / \
+ sizeof(uint64_t)]); \
+ if (ret != 0) \
+ goto error; \
+ } while(0)
+
+ OVPN_RLOCK(sc);
+ RB_FOREACH(peer, ovpn_kpeers, &sc->peers) {
+ nvpeer = nvlist_create(0);
+ if (nvpeer == NULL) {
+ OVPN_RUNLOCK(sc);
+ nvlist_destroy(*nvl);
+ *nvl = NULL;
+ return (ENOMEM);
+ }
+
+ nvlist_add_number(nvpeer, "peerid", peer->peerid);
+
+ OVPN_PEER_COUNTER_OUT("packets", pkt_in, pkt_out);
+ OVPN_PEER_COUNTER_OUT("bytes", bytes_in, bytes_out);
+
+ nvlist_append_nvlist_array(*nvl, "peers", nvpeer);
+ nvlist_destroy(nvpeer);
+ }
+#undef OVPN_PEER_COUNTER_OUT
+ OVPN_RUNLOCK(sc);
+
+ return (0);
+
+error:
+ nvlist_destroy(nvpeer);
+ nvlist_destroy(*nvl);
+ *nvl = NULL;
+ return (ret);
+}
+
static int
ovpn_poll_pkt(struct ovpn_softc *sc, nvlist_t **onvl)
{
@@ -1266,6 +1320,9 @@ ovpn_ioctl_get(struct ifnet *ifp, struct ifdrv *ifd)
case OVPN_GET_STATS:
error = ovpn_get_stats(sc, &nvl);
break;
+ case OVPN_GET_PEER_STATS:
+ error = ovpn_get_peer_stats(sc, &nvl);
+ break;
case OVPN_POLL_PKT:
error = ovpn_poll_pkt(sc, &nvl);
break;
diff --git a/sys/net/if_ovpn.h b/sys/net/if_ovpn.h
index 5ea2ae6dd2ec..1c0299940c3e 100644
--- a/sys/net/if_ovpn.h
+++ b/sys/net/if_ovpn.h
@@ -66,5 +66,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