--- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -398,6 +398,31 @@ err_tlock: } EXPORT_SYMBOL_GPL(l2tp_session_register); +void l2tp_stats_update(struct l2tp_tunnel *tunnel, + struct l2tp_session *session, + struct l2tp_stats *stats) +{ + atomic_long_add(atomic_long_read(&stats->rx_packets), + &tunnel->stats.rx_packets); + atomic_long_add(atomic_long_read(&stats->rx_bytes), + &tunnel->stats.rx_bytes); + atomic_long_add(atomic_long_read(&stats->tx_packets), + &tunnel->stats.tx_packets); + atomic_long_add(atomic_long_read(&stats->tx_bytes), + &tunnel->stats.tx_bytes); + + atomic_long_add(atomic_long_read(&stats->rx_packets), + &session->stats.rx_packets); + atomic_long_add(atomic_long_read(&stats->rx_bytes), + &session->stats.rx_bytes); + atomic_long_add(atomic_long_read(&stats->tx_packets), + &session->stats.tx_packets); + atomic_long_add(atomic_long_read(&stats->tx_bytes), + &session->stats.tx_bytes); +} +EXPORT_SYMBOL_GPL(l2tp_stats_update); + + /***************************************************************************** * Receive data handling *****************************************************************************/ --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -232,6 +232,9 @@ struct l2tp_session *l2tp_session_get_nt struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net, const char *ifname); +void l2tp_stats_update(struct l2tp_tunnel *tunnel, struct l2tp_session *session, + struct l2tp_stats *stats); + /* Tunnel and session lifetime management. * Creation of a new instance is a two-step process: create, then register. * Destruction is triggered using the *_delete functions, and completes asynchronously.