diff --git a/src/octoi/e1oip.c b/src/octoi/e1oip.c index cd07178..608a5e0 100644 --- a/src/octoi/e1oip.c +++ b/src/octoi/e1oip.c @@ -51,6 +51,10 @@ static const struct rate_ctr_desc iline_ctr_description[] = { [LINE_CTR_E1oIP_RX_OUT_OF_ORDER] = { "e1oip:rx:pkt_out_of_order", "Packets out-of-order in IP->E1 direction"}, [LINE_CTR_E1oIP_RX_OUT_OF_WIN] = { "e1oip:rx:pkt_out_of_win", "Packets out-of-rx-window in IP->E1 direction"}, [LINE_CTR_E1oIP_CONNECT_ACCEPT] = { "e1oip:connect_accepted", "OCTOI connections entering accepted state" }, + [LINE_CTR_E1oIP_RX_BYTES] = { "e1oip:rx:bytes", "Number of bytes received including UDP+IP header" }, + [LINE_CTR_E1oIP_RX_PACKETS] = { "e1oip:rx:packets", "Number of UDP packets received" }, + [LINE_CTR_E1oIP_TX_BYTES] = { "e1oip:tx:bytes", "Number of bytes transmitted including UDP+IP header" }, + [LINE_CTR_E1oIP_TX_PACKETS] = { "e1oip:tx:packets", "Number of UDP packets transmitted" }, }; static const struct rate_ctr_group_desc iline_ctrg_desc = { @@ -82,6 +86,7 @@ static const struct osmo_stat_item_group_desc iline_stats_desc = { static void fifo_threshold_cb(struct frame_fifo *fifo, unsigned int frames, void *priv) { struct e1oip_line *iline = priv; + struct octoi_peer *peer = iline->peer; struct msgb *msg; struct e1oip_tdm_hdr *eith; unsigned int n_frames = fifo->threshold; @@ -108,7 +113,7 @@ static void fifo_threshold_cb(struct frame_fifo *fifo, unsigned int frames, void /* this situation cannot really happen: The FIFO called us that * a certain threshold is reached, but now it cannot provide * frames? */ - LOGPEER(iline->peer, LOGL_ERROR, + LOGPEER(peer, LOGL_ERROR, "frame_fifo_out failure for frame %u/%u\n", iline->e1o.next_seq + i, i); } } @@ -146,7 +151,9 @@ static void fifo_threshold_cb(struct frame_fifo *fifo, unsigned int frames, void } /* send the packet to the peer */ - octoi_tx(iline->peer, E1OIP_MSGT_TDM_DATA, 0, msgb_data(msg), msgb_length(msg)); + octoi_tx(peer, E1OIP_MSGT_TDM_DATA, 0, msgb_data(msg), msgb_length(msg)); + iline_ctr_add(iline, LINE_CTR_E1oIP_TX_PACKETS, 1); + iline_ctr_add(iline, LINE_CTR_E1oIP_TX_BYTES, peer->sock->iph_udph_size + msgb_length(msg)); msgb_free(msg); /* update the local state */ diff --git a/src/octoi/e1oip.h b/src/octoi/e1oip.h index 3c5a478..da4716b 100644 --- a/src/octoi/e1oip.h +++ b/src/octoi/e1oip.h @@ -23,6 +23,10 @@ enum e1oip_line_ctr { LINE_CTR_E1oIP_RX_OUT_OF_ORDER, LINE_CTR_E1oIP_RX_OUT_OF_WIN, LINE_CTR_E1oIP_CONNECT_ACCEPT, + LINE_CTR_E1oIP_RX_BYTES, + LINE_CTR_E1oIP_RX_PACKETS, + LINE_CTR_E1oIP_TX_BYTES, + LINE_CTR_E1oIP_TX_PACKETS, }; enum e1oip_line_stat { diff --git a/src/octoi/octoi_fsm.c b/src/octoi/octoi_fsm.c index 3431587..37d0259 100644 --- a/src/octoi/octoi_fsm.c +++ b/src/octoi/octoi_fsm.c @@ -26,6 +26,7 @@ #include "octoi_sock.h" #include "octoi_fsm.h" +#include "e1oip.h" const struct value_string octoi_fsm_event_names[] = { @@ -158,6 +159,12 @@ int _octoi_fsm_rx_cb(struct octoi_peer *peer, struct msgb *msg) OSMO_ASSERT(msgb_l1(msg)); OSMO_ASSERT(msgb_l2(msg)); + if (peer->iline) { + iline_ctr_add(peer->iline, LINE_CTR_E1oIP_RX_PACKETS, 1); + iline_ctr_add(peer->iline, LINE_CTR_E1oIP_RX_BYTES, + peer->sock->iph_udph_size + msgb_length(msg)); + } + if (!octoi_msg_validate(fi, msg)) return -1; diff --git a/src/octoi/octoi_sock.c b/src/octoi/octoi_sock.c index 4805d7e..4245d80 100644 --- a/src/octoi/octoi_sock.c +++ b/src/octoi/octoi_sock.c @@ -40,6 +40,44 @@ #include "octoi_sock.h" #include "e1oip.h" +/* determine domain / AF of socket */ +static int sock_get_domain(int fd) +{ + int domain; + socklen_t dom_len = sizeof(domain); + int rc; + + rc = getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &domain, &dom_len); + if (rc < 0) + return rc; + + return domain; +} + +/* typical number of bytes in IP + UDP header for given socket */ +static int sock_get_iph_udph_overhead(int fd) +{ + int rc = sock_get_domain(fd); + if (rc < 0) { + LOGP(DLINP, LOGL_ERROR, "Unable to determine domain of socket %d: %s\n", + fd, strerror(errno)); + goto assume_ipv4; + } + + switch (rc) { + case AF_INET6: + return 40 + 8; + case AF_INET: + return 20 + 8; + default: + LOGP(DLINP, LOGL_ERROR, "Unknown domain %d of socket %d\n", rc, fd); + break; + } + +assume_ipv4: + return 20 + 8; +} + /*********************************************************************** * transmit to remote peer ***********************************************************************/ @@ -400,6 +438,8 @@ struct octoi_sock *octoi_sock_create_server(void *ctx, void *priv, const struct LOGP(DLINP, LOGL_NOTICE, "OCTOI server socket at "OSMO_SOCKADDR_STR_FMT"\n", OSMO_SOCKADDR_STR_FMT_ARGS(local)); + sock->iph_udph_size = sock_get_iph_udph_overhead(sock->ofd.fd); + return sock; } @@ -441,6 +481,8 @@ struct octoi_sock *octoi_sock_create_client(void *ctx, void *priv, const struct LOGP(DLINP, LOGL_NOTICE, "OCTOI client socket to "OSMO_SOCKADDR_STR_FMT"\n", OSMO_SOCKADDR_STR_FMT_ARGS(remote)); + sock->iph_udph_size = sock_get_iph_udph_overhead(sock->ofd.fd); + /* create [the only] peer */ peer = alloc_peer(sock, (struct sockaddr *) &sa_remote, sizeof(sa_remote)); peer->cfg.remote = *remote; diff --git a/src/octoi/octoi_sock.h b/src/octoi/octoi_sock.h index b251864..17385e1 100644 --- a/src/octoi/octoi_sock.h +++ b/src/octoi/octoi_sock.h @@ -31,6 +31,7 @@ struct octoi_sock { struct osmo_fd ofd; /* file descriptor */ struct llist_head peers; /* list of peers */ void *priv; + unsigned int iph_udph_size; /* size of IP + UDP header */ int (*rx_cb)(struct octoi_peer *peer, struct msgb *msg);