gtphub: add more detailed I/O rate counters.
Count bytes and packets per peer port, as well es per tunnel enpoint, which adds two more levels of detail. Sponsored-by: On-Waves ehi
This commit is contained in:
parent
956d856b61
commit
e38fb66f4b
|
@ -391,12 +391,16 @@ struct gtphub_peer_port {
|
|||
unsigned int ref_count; /* references from other peers' seq_maps */
|
||||
struct osmo_sockaddr sa; /* a "cache" for (peer_addr->addr, port) */
|
||||
int last_restart_count; /* 0..255 = valid, all else means unknown */
|
||||
|
||||
struct rate_ctr_group *counters_io;
|
||||
};
|
||||
|
||||
struct gtphub_tunnel_endpoint {
|
||||
struct gtphub_peer_port *peer;
|
||||
uint32_t tei_orig; /* from/to peer */
|
||||
uint32_t tei_repl; /* from/to the other tunnel endpoint */
|
||||
|
||||
struct rate_ctr_group *counters_io;
|
||||
};
|
||||
|
||||
struct gtphub_tunnel {
|
||||
|
|
|
@ -783,6 +783,7 @@ static void gtphub_peer_port_del(struct gtphub_peer_port *pp)
|
|||
{
|
||||
OSMO_ASSERT(pp->ref_count == 0);
|
||||
llist_del(&pp->entry);
|
||||
rate_ctr_group_free(pp->counters_io);
|
||||
talloc_free(pp);
|
||||
}
|
||||
|
||||
|
@ -1056,9 +1057,12 @@ static void gtphub_tunnel_del_cb(struct expiring_item *expi)
|
|||
int side_idx;
|
||||
int plane_idx;
|
||||
for_each_side_and_plane(side_idx, plane_idx) {
|
||||
struct gtphub_tunnel_endpoint *te = &tun->endpoint[side_idx][plane_idx];
|
||||
|
||||
/* clear ref count */
|
||||
gtphub_tunnel_endpoint_set_peer(&tun->endpoint[side_idx][plane_idx],
|
||||
NULL);
|
||||
gtphub_tunnel_endpoint_set_peer(te, NULL);
|
||||
|
||||
rate_ctr_group_free(te->counters_io);
|
||||
}
|
||||
|
||||
talloc_free(tun);
|
||||
|
@ -1073,6 +1077,15 @@ static struct gtphub_tunnel *gtphub_tunnel_new()
|
|||
INIT_LLIST_HEAD(&tun->entry);
|
||||
expiring_item_init(&tun->expiry_entry);
|
||||
|
||||
int side_idx, plane_idx;
|
||||
for_each_side_and_plane(side_idx, plane_idx) {
|
||||
struct gtphub_tunnel_endpoint *te = &tun->endpoint[side_idx][plane_idx];
|
||||
te->counters_io = rate_ctr_group_alloc(osmo_gtphub_ctx,
|
||||
>phub_ctrg_io_desc,
|
||||
0);
|
||||
OSMO_ASSERT(te->counters_io);
|
||||
}
|
||||
|
||||
tun->expiry_entry.del_cb = gtphub_tunnel_del_cb;
|
||||
return tun;
|
||||
}
|
||||
|
@ -2162,6 +2175,10 @@ int gtphub_handle_buf(struct gtphub *hub,
|
|||
return -1;
|
||||
}
|
||||
|
||||
rate_ctr_add(&from_peer->counters_io->ctr[GTPH_CTR_BYTES_IN],
|
||||
received);
|
||||
rate_ctr_inc(&from_peer->counters_io->ctr[GTPH_CTR_PKTS_IN]);
|
||||
|
||||
LOG(LOGL_DEBUG, "from %s peer: %s\n", gtphub_side_idx_names[side_idx],
|
||||
gtphub_port_str(from_peer));
|
||||
|
||||
|
@ -2174,6 +2191,13 @@ int gtphub_handle_buf(struct gtphub *hub,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (p.tun) {
|
||||
struct gtphub_tunnel_endpoint *te = &p.tun->endpoint[p.side_idx][p.plane_idx];
|
||||
rate_ctr_add(&te->counters_io->ctr[GTPH_CTR_BYTES_IN],
|
||||
received);
|
||||
rate_ctr_inc(&te->counters_io->ctr[GTPH_CTR_PKTS_IN]);
|
||||
}
|
||||
|
||||
if ((!to_peer) && (side_idx == GTPH_SIDE_SGSN)) {
|
||||
if (gtphub_resolve_ggsn(hub, &p, &to_peer) < 0)
|
||||
return -1;
|
||||
|
@ -2216,7 +2240,19 @@ int gtphub_handle_buf(struct gtphub *hub,
|
|||
rate_ctr_inc(&to_bind->counters_io->ctr[GTPH_CTR_PKTS_OUT]);
|
||||
rate_ctr_add(&to_bind->counters_io->ctr[GTPH_CTR_BYTES_OUT],
|
||||
received);
|
||||
|
||||
rate_ctr_inc(&to_peer->counters_io->ctr[GTPH_CTR_PKTS_OUT]);
|
||||
rate_ctr_add(&to_peer->counters_io->ctr[GTPH_CTR_BYTES_OUT],
|
||||
received);
|
||||
}
|
||||
|
||||
if (p.tun) {
|
||||
struct gtphub_tunnel_endpoint *te = &p.tun->endpoint[other_side_idx(p.side_idx)][p.plane_idx];
|
||||
rate_ctr_inc(&te->counters_io->ctr[GTPH_CTR_PKTS_OUT]);
|
||||
rate_ctr_add(&te->counters_io->ctr[GTPH_CTR_BYTES_OUT],
|
||||
received);
|
||||
}
|
||||
|
||||
LOG(LOGL_DEBUG, "%s Forward to %s: %d bytes to %s\n",
|
||||
(side_idx == GTPH_SIDE_SGSN)? "-->" : "<--",
|
||||
gtphub_side_idx_names[other_side_idx(side_idx)],
|
||||
|
@ -2614,6 +2650,9 @@ static struct gtphub_peer_port *gtphub_addr_add_port(struct gtphub_peer_addr *a,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
pp->counters_io = rate_ctr_group_alloc(osmo_gtphub_ctx,
|
||||
>phub_ctrg_io_desc, 0);
|
||||
|
||||
llist_add(&pp->entry, &a->ports);
|
||||
|
||||
LOG(LOGL_DEBUG, "New peer port: %s port %d\n",
|
||||
|
|
|
@ -278,11 +278,6 @@ DEFUN(cfg_grx_ggsn, cfg_grx_ggsn_cmd,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
(show gtphub all, show gtphub stats, show gtphub teidmap,
|
||||
show gtphub peers, ...)
|
||||
*/
|
||||
|
||||
static void show_bind_stats_all(struct vty *vty)
|
||||
{
|
||||
int plane_idx;
|
||||
|
@ -302,6 +297,24 @@ static void show_bind_stats_all(struct vty *vty)
|
|||
}
|
||||
}
|
||||
|
||||
static void show_tunnel_stats(struct vty *vty, struct gtphub_tunnel *tun)
|
||||
{
|
||||
int plane_idx;
|
||||
for_each_plane(plane_idx) {
|
||||
vty_out(vty, "- %s Plane:%s",
|
||||
gtphub_plane_idx_names[plane_idx], VTY_NEWLINE);
|
||||
|
||||
int side_idx;
|
||||
for_each_side(side_idx) {
|
||||
struct gtphub_tunnel_endpoint *te = &tun->endpoint[side_idx][plane_idx];
|
||||
vty_out(vty, " - to/from %s:%s",
|
||||
gtphub_side_idx_names[side_idx],
|
||||
VTY_NEWLINE);
|
||||
vty_out_rate_ctr_group(vty, " ", te->counters_io);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
static void show_peers_summary(struct vty *vty)
|
||||
{
|
||||
|
@ -380,29 +393,33 @@ static void show_tunnels_summary(struct vty *vty)
|
|||
VTY_NEWLINE);
|
||||
}
|
||||
|
||||
static void show_tunnels_all(struct vty *vty)
|
||||
static void show_tunnels_all(struct vty *vty, int with_io_stats)
|
||||
{
|
||||
time_t now = gtphub_now();
|
||||
|
||||
vty_out(vty, "All tunnels:%s"
|
||||
vty_out(vty, "All tunnels%s:%s"
|
||||
"Legend: (expiry in minutes) SGSN <-> GGSN, with each:%s"
|
||||
" <IP-Ctrl>[/<IP-User>] (<TEI-Ctrl>=<mapped>/<TEI-User>=<mapped>)%s",
|
||||
with_io_stats? "with I/O stats" : "",
|
||||
VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
|
||||
|
||||
unsigned int count = 0;
|
||||
unsigned int incomplete = 0;
|
||||
struct gtphub_tunnel *t;
|
||||
llist_for_each_entry(t, &g_hub->tunnels, entry) {
|
||||
struct gtphub_tunnel *tun;
|
||||
llist_for_each_entry(tun, &g_hub->tunnels, entry) {
|
||||
vty_out(vty,
|
||||
"(%4dm) %s%s",
|
||||
(int)((t->expiry_entry.expiry - now) / 60),
|
||||
gtphub_tunnel_str(t),
|
||||
(int)((tun->expiry_entry.expiry - now) / 60),
|
||||
gtphub_tunnel_str(tun),
|
||||
VTY_NEWLINE);
|
||||
count ++;
|
||||
if (!gtphub_tunnel_complete(t))
|
||||
if (!gtphub_tunnel_complete(tun))
|
||||
incomplete ++;
|
||||
if (with_io_stats)
|
||||
show_tunnel_stats(vty, tun);
|
||||
}
|
||||
vty_out(vty, "Total: %u tunnels%s", count, VTY_NEWLINE);
|
||||
vty_out(vty, "Total: %u tunnels (of which %u incomplete)%s",
|
||||
count, incomplete, VTY_NEWLINE);
|
||||
}
|
||||
|
||||
DEFUN(show_gtphub_tunnels_summary, show_gtphub_tunnels_summary_cmd, "show gtphub tunnels summary",
|
||||
|
@ -415,7 +432,14 @@ DEFUN(show_gtphub_tunnels_summary, show_gtphub_tunnels_summary_cmd, "show gtphub
|
|||
DEFUN(show_gtphub_tunnels_list, show_gtphub_tunnels_list_cmd, "show gtphub tunnels list",
|
||||
SHOW_STR "List all tunnels")
|
||||
{
|
||||
show_tunnels_all(vty);
|
||||
show_tunnels_all(vty, 0);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(show_gtphub_tunnels_stats, show_gtphub_tunnels_stats_cmd, "show gtphub tunnels stats",
|
||||
SHOW_STR "List all tunnels with I/O stats")
|
||||
{
|
||||
show_tunnels_all(vty, 1);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -436,6 +460,7 @@ int gtphub_vty_init(struct gtphub *global_hub, struct gtphub_cfg *global_cfg)
|
|||
install_element_ve(&show_gtphub_cmd);
|
||||
install_element_ve(&show_gtphub_tunnels_summary_cmd);
|
||||
install_element_ve(&show_gtphub_tunnels_list_cmd);
|
||||
install_element_ve(&show_gtphub_tunnels_stats_cmd);
|
||||
|
||||
install_element(CONFIG_NODE, &cfg_gtphub_cmd);
|
||||
install_node(>phub_node, config_write_gtphub);
|
||||
|
|
Loading…
Reference in New Issue