The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=21d666a19331f31fb6dfa1e370de5a84a1a5cb46
commit 21d666a19331f31fb6dfa1e370de5a84a1a5cb46 Author: Kristof Provost <[email protected]> AuthorDate: 2026-01-15 14:15:12 +0000 Commit: Kristof Provost <[email protected]> CommitDate: 2026-01-15 16:18:27 +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") --- 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 ae09a1ce9db8..7c416055e939 100644 --- a/sys/net/if_ovpn.c +++ b/sys/net/if_ovpn.c @@ -1669,6 +1669,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); } @@ -1680,6 +1681,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); @@ -1706,6 +1709,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; } @@ -1767,6 +1771,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; } @@ -1783,6 +1788,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); } } @@ -1827,6 +1833,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); @@ -1844,6 +1851,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); @@ -1859,6 +1867,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); @@ -2073,6 +2082,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); } @@ -2089,6 +2099,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 *); @@ -2105,6 +2116,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. */ @@ -2127,6 +2139,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); } @@ -2136,6 +2150,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); } @@ -2174,6 +2189,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); @@ -2198,6 +2214,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); } @@ -2208,6 +2225,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); } @@ -2241,6 +2259,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 *); @@ -2274,12 +2293,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); } @@ -2341,6 +2362,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); } @@ -2350,6 +2372,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); @@ -2368,6 +2391,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); @@ -2463,6 +2487,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); @@ -2492,6 +2518,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); } @@ -2499,6 +2526,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); } @@ -2515,6 +2543,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); } @@ -2560,6 +2589,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); @@ -2569,6 +2599,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); @@ -2605,6 +2636,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()
