diff options
author | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2015-12-06 16:44:14 +0100 |
---|---|---|
committer | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2015-12-07 13:37:05 +0100 |
commit | e38fb66f4bfc3bbae9f5738e5b4e1f37fa0cef2f (patch) | |
tree | 55979d6f5076436dcd6b5f27d270c795b5c8758c | |
parent | 956d856b61ac222f2c5ec078495d60f71b1a6278 (diff) |
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
-rw-r--r-- | openbsc/include/openbsc/gtphub.h | 4 | ||||
-rw-r--r-- | openbsc/src/gprs/gtphub.c | 43 | ||||
-rw-r--r-- | openbsc/src/gprs/gtphub_vty.c | 53 |
3 files changed, 84 insertions, 16 deletions
diff --git a/openbsc/include/openbsc/gtphub.h b/openbsc/include/openbsc/gtphub.h index 1bff68127..97cfc60e9 100644 --- a/openbsc/include/openbsc/gtphub.h +++ b/openbsc/include/openbsc/gtphub.h @@ -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 { diff --git a/openbsc/src/gprs/gtphub.c b/openbsc/src/gprs/gtphub.c index eb463d7ed..e2f3a5482 100644 --- a/openbsc/src/gprs/gtphub.c +++ b/openbsc/src/gprs/gtphub.c @@ -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", diff --git a/openbsc/src/gprs/gtphub_vty.c b/openbsc/src/gprs/gtphub_vty.c index 0eb9261d3..5b9fc79b2 100644 --- a/openbsc/src/gprs/gtphub_vty.c +++ b/openbsc/src/gprs/gtphub_vty.c @@ -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); |