git: 1b7a44fbc553 - stable/15 - if_ovpn: add interface counters
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 28 Jan 2026 19:20:23 UTC
The branch stable/15 has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=1b7a44fbc5532c9c3295d360e40e28dc0be97efb
commit 1b7a44fbc5532c9c3295d360e40e28dc0be97efb
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2026-01-15 14:15:12 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2026-01-28 09:09:10 +0000
if_ovpn: add interface counters
Count input/output packets and bytes on the interface as well, not just
in openvpn-specific counters.
PR: 292464
MFC after: 2 weeks
Sponsored by: Rubicon Communications, LLC ("Netgate")
(cherry picked from commit 21d666a19331f31fb6dfa1e370de5a84a1a5cb46)
---
sys/net/if_ovpn.c | 32 ++++++++++++++++++++++++++++++++
tests/sys/net/if_ovpn/if_ovpn.sh | 25 +++++++++++++++++++++++++
2 files changed, 57 insertions(+)
diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c
index 5be05667857b..99c99369d22a 100644
--- a/sys/net/if_ovpn.c
+++ b/sys/net/if_ovpn.c
@@ -1667,6 +1667,7 @@ ovpn_encrypt_tx_cb(struct cryptop *crp)
NET_EPOCH_EXIT(et);
CURVNET_RESTORE();
OVPN_COUNTER_ADD(sc, lost_data_pkts_out, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
m_freem(m);
return (0);
}
@@ -1678,6 +1679,8 @@ ovpn_encrypt_tx_cb(struct cryptop *crp)
if (ret == 0) {
OVPN_COUNTER_ADD(sc, sent_data_pkts, 1);
OVPN_COUNTER_ADD(sc, tunnel_bytes_sent, tunnel_len);
+ if_inc_counter(sc->ifp, IFCOUNTER_OPACKETS, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_OBYTES, tunnel_len);
}
crypto_freereq(crp);
@@ -1704,6 +1707,7 @@ ovpn_finish_rx(struct ovpn_softc *sc, struct mbuf *m,
if (V_replay_protection && ! ovpn_check_replay(key->decrypt, seq)) {
OVPN_RUNLOCK(sc);
OVPN_COUNTER_ADD(sc, lost_data_pkts_in, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
m_freem(m);
return;
}
@@ -1765,6 +1769,7 @@ skip_float:
m = m_pullup(m, 1);
if (m == NULL) {
OVPN_COUNTER_ADD(sc, nomem_data_pkts_in, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
return;
}
@@ -1781,6 +1786,7 @@ skip_float:
netisr_dispatch(af == AF_INET ? NETISR_IP : NETISR_IPV6, m);
} else {
OVPN_COUNTER_ADD(sc, lost_data_pkts_in, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
m_freem(m);
}
}
@@ -1825,6 +1831,7 @@ ovpn_decrypt_rx_cb(struct cryptop *crp)
crypto_freereq(crp);
atomic_add_int(&sc->refcount, -1);
OVPN_COUNTER_ADD(sc, lost_data_pkts_in, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
OVPN_RUNLOCK(sc);
m_freem(m);
return (0);
@@ -1842,6 +1849,7 @@ ovpn_decrypt_rx_cb(struct cryptop *crp)
atomic_add_int(&sc->refcount, -1);
OVPN_RUNLOCK(sc);
OVPN_COUNTER_ADD(sc, lost_data_pkts_in, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
m_freem(m);
CURVNET_RESTORE();
return (0);
@@ -1857,6 +1865,7 @@ ovpn_decrypt_rx_cb(struct cryptop *crp)
*/
OVPN_RUNLOCK(sc);
OVPN_COUNTER_ADD(sc, lost_data_pkts_in, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
m_freem(m);
CURVNET_RESTORE();
return (0);
@@ -2071,6 +2080,7 @@ ovpn_transmit_to_peer(struct ifnet *ifp, struct mbuf *m,
if (_ovpn_lock_trackerp != NULL)
OVPN_RUNLOCK(sc);
OVPN_COUNTER_ADD(sc, lost_data_pkts_out, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
m_freem(m);
return (ELOOP);
}
@@ -2087,6 +2097,7 @@ ovpn_transmit_to_peer(struct ifnet *ifp, struct mbuf *m,
if (_ovpn_lock_trackerp != NULL)
OVPN_RUNLOCK(sc);
OVPN_COUNTER_ADD(sc, nomem_data_pkts_out, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
return (ENOBUFS);
}
ohdr = mtod(m, struct ovpn_wire_header *);
@@ -2103,6 +2114,7 @@ ovpn_transmit_to_peer(struct ifnet *ifp, struct mbuf *m,
if (_ovpn_lock_trackerp != NULL)
OVPN_RUNLOCK(sc);
OVPN_COUNTER_ADD(sc, nomem_data_pkts_out, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
/* Let's avoid (very unlikely, but still) wraparounds of the
* 64-bit counter taking us back to 0. */
@@ -2125,6 +2137,8 @@ ovpn_transmit_to_peer(struct ifnet *ifp, struct mbuf *m,
if (ret == 0) {
OVPN_COUNTER_ADD(sc, sent_data_pkts, 1);
OVPN_COUNTER_ADD(sc, tunnel_bytes_sent, tunnel_len);
+ if_inc_counter(sc->ifp, IFCOUNTER_OPACKETS, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_OBYTES, tunnel_len);
}
return (ret);
}
@@ -2134,6 +2148,7 @@ ovpn_transmit_to_peer(struct ifnet *ifp, struct mbuf *m,
if (_ovpn_lock_trackerp != NULL)
OVPN_RUNLOCK(sc);
OVPN_COUNTER_ADD(sc, nomem_data_pkts_out, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
m_freem(m);
return (ENOBUFS);
}
@@ -2172,6 +2187,7 @@ ovpn_transmit_to_peer(struct ifnet *ifp, struct mbuf *m,
ret = crypto_dispatch(crp);
if (ret) {
OVPN_COUNTER_ADD(sc, lost_data_pkts_out, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
}
return (ret);
@@ -2196,6 +2212,7 @@ ovpn_encap(struct ovpn_softc *sc, uint32_t peerid, struct mbuf *m)
if (peer == NULL || sc->ifp->if_link_state != LINK_STATE_UP) {
OVPN_RUNLOCK(sc);
OVPN_COUNTER_ADD(sc, lost_data_pkts_out, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
m_freem(m);
return (ENETDOWN);
}
@@ -2206,6 +2223,7 @@ ovpn_encap(struct ovpn_softc *sc, uint32_t peerid, struct mbuf *m)
if (m == NULL) {
OVPN_RUNLOCK(sc);
OVPN_COUNTER_ADD(sc, nomem_data_pkts_out, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
m_freem(m);
return (ENOBUFS);
}
@@ -2239,6 +2257,7 @@ ovpn_encap(struct ovpn_softc *sc, uint32_t peerid, struct mbuf *m)
if (m == NULL) {
OVPN_RUNLOCK(sc);
OVPN_COUNTER_ADD(sc, nomem_data_pkts_out, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
return (ENOBUFS);
}
ip = mtod(m, struct ip *);
@@ -2272,12 +2291,14 @@ ovpn_encap(struct ovpn_softc *sc, uint32_t peerid, struct mbuf *m)
if (m == NULL) {
OVPN_RUNLOCK(sc);
OVPN_COUNTER_ADD(sc, nomem_data_pkts_out, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
return (ENOBUFS);
}
m = m_pullup(m, sizeof(*ip6) + sizeof(*udp));
if (m == NULL) {
OVPN_RUNLOCK(sc);
OVPN_COUNTER_ADD(sc, nomem_data_pkts_out, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
return (ENOBUFS);
}
@@ -2339,6 +2360,7 @@ ovpn_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
m = m_unshare(m, M_NOWAIT);
if (m == NULL) {
OVPN_COUNTER_ADD(sc, lost_data_pkts_out, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
return (ENOBUFS);
}
@@ -2348,6 +2370,7 @@ ovpn_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
if (__predict_false(ifp->if_link_state != LINK_STATE_UP)) {
OVPN_COUNTER_ADD(sc, lost_data_pkts_out, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
OVPN_RUNLOCK(sc);
m_freem(m);
return (ENETDOWN);
@@ -2366,6 +2389,7 @@ ovpn_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
if (peer == NULL) {
/* No destination. */
OVPN_COUNTER_ADD(sc, lost_data_pkts_out, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
OVPN_RUNLOCK(sc);
m_freem(m);
return (ENETDOWN);
@@ -2461,6 +2485,8 @@ ovpn_udp_input(struct mbuf *m, int off, struct inpcb *inp,
M_ASSERTPKTHDR(m);
OVPN_COUNTER_ADD(sc, transport_bytes_received, m->m_pkthdr.len - off);
+ if_inc_counter(sc->ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len - off);
+ if_inc_counter(sc->ifp, IFCOUNTER_IPACKETS, 1);
ohdrlen = sizeof(*ohdr) - sizeof(ohdr->auth_tag);
@@ -2490,6 +2516,7 @@ ovpn_udp_input(struct mbuf *m, int off, struct inpcb *inp,
m = m_unshare(m, M_NOWAIT);
if (m == NULL) {
OVPN_COUNTER_ADD(sc, nomem_data_pkts_in, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
return (true);
}
@@ -2497,6 +2524,7 @@ ovpn_udp_input(struct mbuf *m, int off, struct inpcb *inp,
if (m == NULL) {
OVPN_RUNLOCK(sc);
OVPN_COUNTER_ADD(sc, nomem_data_pkts_in, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
return (true);
}
@@ -2513,6 +2541,7 @@ ovpn_udp_input(struct mbuf *m, int off, struct inpcb *inp,
if (key == NULL || key->decrypt == NULL) {
OVPN_RUNLOCK(sc);
OVPN_COUNTER_ADD(sc, lost_data_pkts_in, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
m_freem(m);
return (true);
}
@@ -2558,6 +2587,7 @@ ovpn_udp_input(struct mbuf *m, int off, struct inpcb *inp,
if (m == NULL) {
OVPN_RUNLOCK(sc);
OVPN_COUNTER_ADD(sc, nomem_data_pkts_in, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
return (true);
}
uhdr = mtodo(m, 0);
@@ -2567,6 +2597,7 @@ ovpn_udp_input(struct mbuf *m, int off, struct inpcb *inp,
crp = crypto_getreq(key->decrypt->cryptoid, M_NOWAIT);
if (crp == NULL) {
OVPN_COUNTER_ADD(sc, nomem_data_pkts_in, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
OVPN_RUNLOCK(sc);
m_freem(m);
return (true);
@@ -2603,6 +2634,7 @@ ovpn_udp_input(struct mbuf *m, int off, struct inpcb *inp,
ret = crypto_dispatch(crp);
if (ret != 0) {
OVPN_COUNTER_ADD(sc, lost_data_pkts_in, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
}
return (true);
diff --git a/tests/sys/net/if_ovpn/if_ovpn.sh b/tests/sys/net/if_ovpn/if_ovpn.sh
index 9dafce2242d8..6fe0393dd2b2 100644
--- a/tests/sys/net/if_ovpn/if_ovpn.sh
+++ b/tests/sys/net/if_ovpn/if_ovpn.sh
@@ -99,6 +99,31 @@ atf_test_case "4in4" "cleanup"
# Test routing loop protection
jexec b route add 192.0.2.1 198.51.100.1
atf_check -s exit:2 -o ignore jexec b ping -t 1 -c 1 198.51.100.1
+
+ jexec a netstat -I ovpn0 -n -b
+ ipkts=$(jexec a netstat -I ovpn0 -n -b | awk 'NR == 2 { print($5); }')
+ echo "$ipkts input packets"
+ if [ $ipkts -eq 0 ]; then
+ atf_fail "Input packets were not counted"
+ fi
+
+ ibytes=$(jexec a netstat -I ovpn0 -n -b | awk 'NR == 2 { print($8); }')
+ echo "$ibytes input bytes"
+ if [ $ibytes -eq 0 ]; then
+ atf_fail "Input bytes were not counted"
+ fi
+
+ opkts=$(jexec a netstat -I ovpn0 -n -b | awk 'NR == 2 { print($9); }')
+ echo "$opkts output packets"
+ if [ $obytes -eq 0 ]; then
+ atf_fail "Output packets were not counted"
+ fi
+
+ obytes=$(jexec a netstat -I ovpn0 -n -b | awk 'NR == 2 { print($11); }')
+ echo "$obytes output bytes"
+ if [ $obytes -eq 0 ]; then
+ atf_fail "Output bytes were not counted"
+ fi
}
4in4_cleanup()