diff --git a/lib/ff_dpdk_if.c b/lib/ff_dpdk_if.c index 21691fc9..fa6cf0ce 100644 --- a/lib/ff_dpdk_if.c +++ b/lib/ff_dpdk_if.c @@ -188,6 +188,9 @@ struct ff_dpdk_if_context { static struct ff_dpdk_if_context *veth_ctx[RTE_MAX_ETHPORTS]; +static struct ff_top_args ff_top_status; +static struct ff_traffic_args ff_traffic; + extern void ff_hardclock(void); static void @@ -994,6 +997,11 @@ process_packets(uint16_t port_id, uint16_t queue_id, struct rte_mbuf **bufs, void *data = rte_pktmbuf_mtod(rtem, void*); uint16_t len = rte_pktmbuf_data_len(rtem); + if (!pkts_from_ring) { + ff_traffic.rx_packets++; + ff_traffic.rx_bytes += len; + } + if (!pkts_from_ring && packet_dispatcher) { int ret = (*packet_dispatcher)(data, len, queue_id, nb_queues); if (ret < 0 || ret >= nb_queues) { @@ -1183,6 +1191,13 @@ done: } #endif +static inline void +handle_traffic_msg(struct ff_msg *msg) +{ + msg->traffic = ff_traffic; + msg->result = 0; +} + static inline void handle_default_msg(struct ff_msg *msg) { @@ -1215,6 +1230,9 @@ handle_msg(struct ff_msg *msg, uint16_t proc_id) handle_ipfw_msg(msg); break; #endif + case FF_TRAFFIC: + handle_traffic_msg(msg); + break; default: handle_default_msg(msg); break; @@ -1253,6 +1271,12 @@ send_burst(struct lcore_conf *qconf, uint16_t n, uint8_t port) } } + ff_traffic.tx_packets += n; + uint16_t i; + for (i = 0; i < n; i++) { + ff_traffic.tx_bytes += rte_pktmbuf_data_len(m_table[i]); + } + ret = rte_eth_tx_burst(port, queueid, m_table, n); if (unlikely(ret < n)) { do { @@ -1509,14 +1533,14 @@ main_loop(void *arg) if (!idle) { sys_tsc = div_tsc - cur_tsc; - ff_status.sys_tsc += sys_tsc; + ff_top_status.sys_tsc += sys_tsc; } - ff_status.usr_tsc += usr_tsc; - ff_status.work_tsc += end_tsc - cur_tsc; - ff_status.idle_tsc += end_tsc - cur_tsc - usr_tsc - sys_tsc; + ff_top_status.usr_tsc += usr_tsc; + ff_top_status.work_tsc += end_tsc - cur_tsc; + ff_top_status.idle_tsc += end_tsc - cur_tsc - usr_tsc - sys_tsc; - ff_status.loops++; + ff_top_status.loops++; } return 0; diff --git a/lib/ff_msg.h b/lib/ff_msg.h index 7e91b711..fac8bc6d 100644 --- a/lib/ff_msg.h +++ b/lib/ff_msg.h @@ -42,6 +42,7 @@ enum FF_MSG_TYPE { FF_TOP, FF_NGCTL, FF_IPFW_CTL, + FF_TRAFFIC, }; struct ff_sysctl_args { @@ -92,6 +93,13 @@ struct ff_ipfw_args { socklen_t *optlen; }; +struct ff_traffic_args { + uint64_t rx_packets; + uint64_t rx_bytes; + uint64_t tx_packets; + uint64_t tx_bytes; +}; + #define MAX_MSG_BUF_SIZE 10240 /* structure of ipc msg */ @@ -111,6 +119,7 @@ struct ff_msg { struct ff_top_args top; struct ff_ngctl_args ngctl; struct ff_ipfw_args ipfw; + struct ff_traffic_args traffic; }; } __attribute__((packed)) __rte_cache_aligned; diff --git a/tools/Makefile b/tools/Makefile index 02af1ee4..ecf388b0 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,4 +1,4 @@ -SUBDIRS=compat libutil libmemstat libxo libnetgraph sysctl ifconfig route top netstat ngctl ipfw arp +SUBDIRS=compat libutil libmemstat libxo libnetgraph sysctl ifconfig route top netstat ngctl ipfw arp traffic all: for d in $(SUBDIRS); do ( cd $$d; $(MAKE) all ) ; done diff --git a/tools/README.md b/tools/README.md index c781cbfe..060340b4 100644 --- a/tools/README.md +++ b/tools/README.md @@ -212,6 +212,34 @@ usage: arp -p [-n] [-i interface] hostname For more details, see [Manual page](https://www.freebsd.org/cgi/man.cgi?arp). +# traffic +Usage: +``` +traffic [-p ] [-d ] [-n num] +``` +Examples: +``` +./tools/traffic/traffic + +|--------------------|--------------------|--------------------|--------------------| +| rx packets| rx bytes| tx packets| tx bytes| +|--------------------|--------------------|--------------------|--------------------| +| 0| 0| 0| 0| +| 298017| 30590860| 590912| 230712836| +| 475808| 49008224| 951616| 372081856| +| 474720| 48896160| 949440| 371231040| +| 475296| 48955488| 950592| 371681472| +| 475040| 48929120| 950080| 371481280| +| 474368| 48859904| 948736| 370955776| +| 475616| 48988448| 951232| 371931712| +| 475552| 48981856| 951104| 371881664| +| 476128| 49041184| 952256| 372332096| +| 475680| 48995040| 951360| 371981760| +| 475552| 48981856| 951104| 371881664| +| 475488| 48975264| 950976| 371831616| +| 473440| 48764320| 946880| 370230080| +``` + # how to implement a custom tool for communicating with F-Stack process Add a new FF_MSG_TYPE in ff_msg.h: diff --git a/tools/traffic/Makefile b/tools/traffic/Makefile new file mode 100644 index 00000000..e03f2beb --- /dev/null +++ b/tools/traffic/Makefile @@ -0,0 +1,9 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 +# $FreeBSD$ + + +TOPDIR?=${CURDIR}/../.. + +PROG=traffic + +include ${TOPDIR}/tools/prog.mk diff --git a/tools/traffic/traffic.c b/tools/traffic/traffic.c new file mode 100644 index 00000000..e306f7ed --- /dev/null +++ b/tools/traffic/traffic.c @@ -0,0 +1,126 @@ +#include +#include "ff_ipc.h" + +void +usage(void) +{ + printf("Usage:\n"); + printf(" top [-p ] [-d ] [-n num] [-s]\n"); +} + +int traffic_status(struct ff_traffic_args *traffic) +{ + int ret; + struct ff_msg *msg, *retmsg = NULL; + + msg = ff_ipc_msg_alloc(); + if (msg == NULL) { + errno = ENOMEM; + return -1; + } + + msg->msg_type = FF_TRAFFIC; + ret = ff_ipc_send(msg); + if (ret < 0) { + errno = EPIPE; + ff_ipc_msg_free(msg); + return -1; + } + + do { + if (retmsg != NULL) { + ff_ipc_msg_free(retmsg); + } + + ret = ff_ipc_recv(&retmsg); + if (ret < 0) { + errno = EPIPE; + ff_ipc_msg_free(msg); + return -1; + } + } while (msg != retmsg); + + *traffic = retmsg->traffic; + + ff_ipc_msg_free(msg); + + return 0; +} + +int main(int argc, char **argv) +{ + int ch, delay = 1, n = 0; + int single = 0; + unsigned int i; + struct ff_traffic_args traffic, otr; + + ff_ipc_init(); + + while ((ch = getopt(argc, argv, "hp:d:n:s")) != -1) { + switch(ch) { + case 'p': + ff_set_proc_id(atoi(optarg)); + break; + case 'd': + delay = atoi(optarg) ?: 1; + break; + case 'n': + n = atoi(optarg); + break; + case 's': + single = 1; + break; + case 'h': + default: + usage(); + return -1; + } + } + + if (single) { + if (traffic_status(&traffic)) { + printf("fstack ipc message error !\n"); + return -1; + } + + printf("%lu,%lu,%lu,%lu\n", traffic.rx_packets, traffic.rx_bytes, + traffic.tx_packets, traffic.tx_bytes); + return 0; + } + + #define DIFF(member) (traffic.member - otr.member) + + for (i = 0; ; i++) { + if (traffic_status(&traffic)) { + printf("fstack ipc message error !\n"); + return -1; + } + + if (i % 40 == 0) { + printf("|--------------------|--------------------|"); + printf("--------------------|--------------------|\n"); + printf("|%20s|%20s|%20s|%20s|\n", "rx packets", "rx bytes", + "tx packets", "tx bytes"); + printf("|--------------------|--------------------|"); + printf("--------------------|--------------------|\n"); + } + + if (i) { + uint64_t rxp = DIFF(rx_packets); + uint64_t rxb = DIFF(rx_bytes); + uint64_t txp = DIFF(tx_packets); + uint64_t txb = DIFF(tx_bytes); + + printf("|%20lu|%20lu|%20lu|%20lu|\n", rxp, rxb, txp, txb); + } + + if (n && i >= n) { + break; + } + + otr = traffic; + sleep(delay); + } + + return 0; +}