From 24e4aafaaa2fba1e073491627fe56e0e143ac956 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 29 Jan 2025 21:18:38 +0100 Subject: [PATCH] ubus: add detailed peer statistics Add idle time, tx/rx bytes, time since last handshake Signed-off-by: Felix Fietkau --- host.h | 3 ++- ubus.c | 5 +++++ wg-linux.c | 3 +++ wg-user.c | 7 +++++++ wg.c | 7 +++++++ wg.h | 2 ++ 6 files changed, 26 insertions(+), 1 deletion(-) diff --git a/host.h b/host.h index 536c24d..a63a60b 100644 --- a/host.h +++ b/host.h @@ -38,11 +38,12 @@ struct network_peer { union network_endpoint next_endpoint[__ENDPOINT_TYPE_MAX]; uint64_t last_ep_update; - uint64_t rx_bytes; + uint64_t rx_bytes, tx_bytes; uint64_t last_handshake; uint64_t last_request; uint64_t last_query_sent; + int last_handshake_diff; int idle; int num_net_queries; } state; diff --git a/ubus.c b/ubus.c index 11bacc2..011beaa 100644 --- a/ubus.c +++ b/ubus.c @@ -82,6 +82,11 @@ __network_dump(struct blob_buf *buf, struct network *net) snprintf(str + len, INET6_ADDRSTRLEN + 7 - len, ":%d", ntohs(ep->in.sin_port)); blobmsg_add_string_buffer(buf); + + blobmsg_add_u64(buf, "rx_bytes", peer->state.rx_bytes); + blobmsg_add_u64(buf, "tx_bytes", peer->state.tx_bytes); + blobmsg_add_u32(buf, "idle", peer->state.idle); + blobmsg_add_u32(buf, "last_handshake_sec", peer->state.last_handshake_diff); } blobmsg_close_table(buf, p); diff --git a/wg-linux.c b/wg-linux.c index 0a17c90..12f5c58 100644 --- a/wg-linux.c +++ b/wg-linux.c @@ -273,6 +273,9 @@ wg_linux_parse_peer(struct network *net, struct nlattr *data, time_t now) if ((cur = tb[WGPEER_A_RX_BYTES]) != NULL) wg_peer_set_rx_bytes(net, peer, nla_get_u64(cur)); + if ((cur = tb[WGPEER_A_TX_BYTES]) != NULL) + wg_peer_set_tx_bytes(net, peer, nla_get_u64(cur)); + if ((cur = tb[WGPEER_A_ENDPOINT]) != NULL) wg_peer_set_endpoint(net, peer, nla_data(cur), nla_len(cur)); diff --git a/wg-user.c b/wg-user.c index bf057e5..e90b715 100644 --- a/wg-user.c +++ b/wg-user.c @@ -390,6 +390,13 @@ wg_user_peer_refresh(struct network *net) continue; } + if (!strcmp(req.key, "tx_bytes")) { + uint64_t bytes = strtoull(req.value, NULL, 0); + + wg_peer_set_tx_bytes(net, peer, bytes); + continue; + } + if (!strcmp(req.key, "endpoint")) { struct addrinfo *resolved; struct addrinfo hints = { diff --git a/wg.c b/wg.c index 1f80e00..74e8aae 100644 --- a/wg.c +++ b/wg.c @@ -69,6 +69,7 @@ void wg_peer_update_done(struct network *net, struct network_peer *peer) void wg_peer_set_last_handshake(struct network *net, struct network_peer *peer, uint64_t now, uint64_t sec) { + peer->state.last_handshake_diff = now - sec; if (sec == peer->state.last_handshake) return; @@ -95,6 +96,12 @@ void wg_peer_set_rx_bytes(struct network *net, struct network_peer *peer, } } +void wg_peer_set_tx_bytes(struct network *net, struct network_peer *peer, + uint64_t bytes) +{ + peer->state.tx_bytes = bytes; +} + void wg_peer_set_endpoint(struct network *net, struct network_peer *peer, void *data, size_t len) { diff --git a/wg.h b/wg.h index 2060eaf..835dae5 100644 --- a/wg.h +++ b/wg.h @@ -55,6 +55,8 @@ void wg_peer_set_last_handshake(struct network *net, struct network_peer *peer, uint64_t now, uint64_t sec); void wg_peer_set_rx_bytes(struct network *net, struct network_peer *peer, uint64_t bytes); +void wg_peer_set_tx_bytes(struct network *net, struct network_peer *peer, + uint64_t bytes); void wg_peer_set_endpoint(struct network *net, struct network_peer *peer, void *data, size_t len); -- 2.30.2