if_ovpn: start tracking per-peer packets/bytes in/out
OpenVPN will introduce a mechanism to retrieve per-peer statistics. Start tracking those so we can return them to userspace when queried. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D37603
This commit is contained in:
parent
66de89d4c2
commit
18a30fd39b
@ -122,6 +122,14 @@ struct ovpn_notification {
|
|||||||
|
|
||||||
struct ovpn_softc;
|
struct ovpn_softc;
|
||||||
|
|
||||||
|
struct ovpn_peer_counters {
|
||||||
|
uint64_t pkt_in;
|
||||||
|
uint64_t pkt_out;
|
||||||
|
uint64_t bytes_in;
|
||||||
|
uint64_t bytes_out;
|
||||||
|
};
|
||||||
|
#define OVPN_PEER_COUNTER_SIZE (sizeof(struct ovpn_peer_counters)/sizeof(uint64_t))
|
||||||
|
|
||||||
struct ovpn_kpeer {
|
struct ovpn_kpeer {
|
||||||
RB_ENTRY(ovpn_kpeer) tree;
|
RB_ENTRY(ovpn_kpeer) tree;
|
||||||
int refcount;
|
int refcount;
|
||||||
@ -142,6 +150,8 @@ struct ovpn_kpeer {
|
|||||||
uint32_t *last_active;
|
uint32_t *last_active;
|
||||||
struct callout ping_send;
|
struct callout ping_send;
|
||||||
struct callout ping_rcv;
|
struct callout ping_rcv;
|
||||||
|
|
||||||
|
counter_u64_t counters[OVPN_PEER_COUNTER_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ovpn_counters {
|
struct ovpn_counters {
|
||||||
@ -219,6 +229,9 @@ VNET_DEFINE_STATIC(struct if_clone *, ovpn_cloner);
|
|||||||
#define OVPN_COUNTER_ADD(sc, name, val) \
|
#define OVPN_COUNTER_ADD(sc, name, val) \
|
||||||
counter_u64_add(sc->counters[offsetof(struct ovpn_counters, name) / \
|
counter_u64_add(sc->counters[offsetof(struct ovpn_counters, name) / \
|
||||||
sizeof(uint64_t)], val)
|
sizeof(uint64_t)], val)
|
||||||
|
#define OVPN_PEER_COUNTER_ADD(p, name, val) \
|
||||||
|
counter_u64_add(p->counters[offsetof(struct ovpn_peer_counters, name) / \
|
||||||
|
sizeof(uint64_t)], val)
|
||||||
|
|
||||||
#define TO_IN(x) ((struct sockaddr_in *)(x))
|
#define TO_IN(x) ((struct sockaddr_in *)(x))
|
||||||
#define TO_IN6(x) ((struct sockaddr_in6 *)(x))
|
#define TO_IN6(x) ((struct sockaddr_in6 *)(x))
|
||||||
@ -499,6 +512,7 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl)
|
|||||||
peer->tx_seq = 1;
|
peer->tx_seq = 1;
|
||||||
peer->refcount = 1;
|
peer->refcount = 1;
|
||||||
peer->last_active = uma_zalloc_pcpu(pcpu_zone_4, M_WAITOK | M_ZERO);
|
peer->last_active = uma_zalloc_pcpu(pcpu_zone_4, M_WAITOK | M_ZERO);
|
||||||
|
COUNTER_ARRAY_ALLOC(peer->counters, OVPN_PEER_COUNTER_SIZE, M_WAITOK);
|
||||||
|
|
||||||
if (nvlist_exists_binary(nvl, "vpn_ipv4")) {
|
if (nvlist_exists_binary(nvl, "vpn_ipv4")) {
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -606,6 +620,7 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl)
|
|||||||
OVPN_WUNLOCK(sc);
|
OVPN_WUNLOCK(sc);
|
||||||
error:
|
error:
|
||||||
free(name, M_SONAME);
|
free(name, M_SONAME);
|
||||||
|
COUNTER_ARRAY_FREE(peer->counters, OVPN_PEER_COUNTER_SIZE);
|
||||||
uma_zfree_pcpu(pcpu_zone_4, peer->last_active);
|
uma_zfree_pcpu(pcpu_zone_4, peer->last_active);
|
||||||
free(peer, M_OVPN);
|
free(peer, M_OVPN);
|
||||||
done:
|
done:
|
||||||
@ -1404,6 +1419,8 @@ ovpn_finish_rx(struct ovpn_softc *sc, struct mbuf *m,
|
|||||||
|
|
||||||
OVPN_COUNTER_ADD(sc, received_data_pkts, 1);
|
OVPN_COUNTER_ADD(sc, received_data_pkts, 1);
|
||||||
OVPN_COUNTER_ADD(sc, tunnel_bytes_received, m->m_pkthdr.len);
|
OVPN_COUNTER_ADD(sc, tunnel_bytes_received, m->m_pkthdr.len);
|
||||||
|
OVPN_PEER_COUNTER_ADD(peer, pkt_in, 1);
|
||||||
|
OVPN_PEER_COUNTER_ADD(peer, bytes_in, m->m_pkthdr.len);
|
||||||
|
|
||||||
/* Receive the packet on our interface. */
|
/* Receive the packet on our interface. */
|
||||||
m->m_pkthdr.rcvif = sc->ifp;
|
m->m_pkthdr.rcvif = sc->ifp;
|
||||||
@ -1740,6 +1757,9 @@ ovpn_transmit_to_peer(struct ifnet *ifp, struct mbuf *m,
|
|||||||
seq = htonl(seq);
|
seq = htonl(seq);
|
||||||
ohdr->seq = seq;
|
ohdr->seq = seq;
|
||||||
|
|
||||||
|
OVPN_PEER_COUNTER_ADD(peer, pkt_out, 1);
|
||||||
|
OVPN_PEER_COUNTER_ADD(peer, bytes_out, len);
|
||||||
|
|
||||||
if (key->encrypt->cipher == OVPN_CIPHER_ALG_NONE) {
|
if (key->encrypt->cipher == OVPN_CIPHER_ALG_NONE) {
|
||||||
ret = ovpn_encap(sc, peer->peerid, m);
|
ret = ovpn_encap(sc, peer->peerid, m);
|
||||||
if (_ovpn_lock_trackerp != NULL)
|
if (_ovpn_lock_trackerp != NULL)
|
||||||
|
Loading…
Reference in New Issue
Block a user