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
This commit is contained in:
Kristof Provost 2022-11-27 12:58:40 +01:00
parent 18a30fd39b
commit 8b630fa9ef
2 changed files with 58 additions and 0 deletions

View File

@ -1212,6 +1212,60 @@ ovpn_get_stats(struct ovpn_softc *sc, nvlist_t **onvl)
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;

View File

@ -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