From fa5572e2afc01903b2e5dd260f475d1f73ded74a Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Fri, 19 Aug 2016 20:27:35 +0200 Subject: client: Use pcap_stats and export them as statistics Attempt to write code that detects the wrap and is doing the right thing when it happens. Change-Id: I501ebc49d3e86b0605ec1fbe2f62aee3f362aa36 --- include/osmo-pcap/osmo_pcap_client.h | 8 ++++++ src/osmo_client_core.c | 55 ++++++++++++++++++++++++++++++++++++ src/osmo_client_main.c | 3 ++ 3 files changed, 66 insertions(+) diff --git a/include/osmo-pcap/osmo_pcap_client.h b/include/osmo-pcap/osmo_pcap_client.h index 90cd5ad..ee81e50 100644 --- a/include/osmo-pcap/osmo_pcap_client.h +++ b/include/osmo-pcap/osmo_pcap_client.h @@ -38,6 +38,9 @@ enum { CLIENT_CTR_QERR, CLIENT_CTR_PERR, CLIENT_CTR_WERR, + CLIENT_CTR_P_RECV, + CLIENT_CTR_P_DROP, + CLIENT_CTR_P_IFDROP, }; struct osmo_pcap_client { @@ -45,6 +48,11 @@ struct osmo_pcap_client { pcap_t *handle; char errbuf[PCAP_ERRBUF_SIZE]; + u_int last_ps_recv; + u_int last_ps_drop; + u_int last_ps_ifdrop; + struct osmo_timer_list pcap_stat_timer; + struct bpf_program bpf; char *filter_string; int filter_itself; diff --git a/src/osmo_client_core.c b/src/osmo_client_core.c index 4455c95..abef787 100644 --- a/src/osmo_client_core.c +++ b/src/osmo_client_core.c @@ -171,6 +171,56 @@ static int pcap_read_cb(struct osmo_fd *fd, unsigned int what) return 0; } +static inline u_int P_CAP_UINT_MAX() +{ + u_int val = 0; + return ~val; +} + +static void add_psbl_wrapped_ctr(struct osmo_pcap_client *client, + u_int *old_val, u_int new_val, int ctr) +{ + /* + * Wrapped.. + * So let's at from N to XYZ_MAX + * and then from 0 to new_val + * Only issue is we don't know sizeof(u_int) + */ + if (*old_val > new_val) { + rate_ctr_add(&client->ctrg->ctr[ctr], P_CAP_UINT_MAX() - *old_val); + rate_ctr_add(&client->ctrg->ctr[ctr], new_val); + *old_val = new_val; + return; + } + + /* Just increment it */ + rate_ctr_add(&client->ctrg->ctr[ctr], new_val - *old_val); + *old_val = new_val; +} + +static void pcap_check_stats_cb(void *_client) +{ + struct pcap_stat stat; + struct osmo_pcap_client *client = _client; + int rc; + + /* reschedule */ + osmo_timer_schedule(&client->pcap_stat_timer, 10, 0); + + memset(&stat, 0, sizeof(stat)); + rc = pcap_stats(client->handle, &stat); + if (rc != 0) { + LOGP(DCLIENT, LOGL_ERROR, "Failed to query pcap stats: %s\n", + pcap_geterr(client->handle)); + rate_ctr_inc(&client->ctrg->ctr[CLIENT_CTR_PERR]); + return; + } + + add_psbl_wrapped_ctr(client, &client->last_ps_recv, stat.ps_recv, CLIENT_CTR_P_RECV); + add_psbl_wrapped_ctr(client, &client->last_ps_drop, stat.ps_drop, CLIENT_CTR_P_DROP); + add_psbl_wrapped_ctr(client, &client->last_ps_ifdrop, stat.ps_ifdrop, CLIENT_CTR_P_IFDROP); +} + static int osmo_install_filter(struct osmo_pcap_client *client) { int rc; @@ -216,6 +266,7 @@ static void free_all(struct osmo_pcap_client *client) } pcap_close(client->handle); + osmo_timer_del(&client->pcap_stat_timer); client->handle = NULL; } @@ -260,6 +311,10 @@ int osmo_client_capture(struct osmo_pcap_client *client, const char *device) return 4; } + client->pcap_stat_timer.data = client; + client->pcap_stat_timer.cb = pcap_check_stats_cb; + pcap_check_stats_cb(client); + osmo_client_send_link(client); if (client->filter_string) { diff --git a/src/osmo_client_main.c b/src/osmo_client_main.c index 0b53939..f5ba41a 100644 --- a/src/osmo_client_main.c +++ b/src/osmo_client_main.c @@ -62,6 +62,9 @@ static const struct rate_ctr_desc pcap_client_ctr_desc[] = { [CLIENT_CTR_QERR] = { "client.queue_err", "Can not queue data " }, [CLIENT_CTR_PERR] = { "client.pcap_err", "libpcap error " }, [CLIENT_CTR_WERR] = { "client.write_err", "Write error " }, + [CLIENT_CTR_P_RECV] = { "pcap.recv", "PCAP received packets " }, + [CLIENT_CTR_P_DROP] = { "pcap.drop", "PCAP dropped packets " }, + [CLIENT_CTR_P_IFDROP] = { "pcap.ifdrop", "iface dropped packets " }, }; static const struct rate_ctr_group_desc pcap_client_ctr_group_desc = { -- cgit v1.2.3