1174a1631SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 2174a1631SBruce Richardson * Copyright(c) 2016 Intel Corporation 3caa70282SReshma Pattan */ 4caa70282SReshma Pattan 5caa70282SReshma Pattan #include <stdio.h> 6caa70282SReshma Pattan #include <string.h> 7caa70282SReshma Pattan #include <stdint.h> 8caa70282SReshma Pattan #include <inttypes.h> 9caa70282SReshma Pattan #include <stdlib.h> 10caa70282SReshma Pattan #include <getopt.h> 11caa70282SReshma Pattan #include <signal.h> 12caa70282SReshma Pattan #include <stdbool.h> 13caa70282SReshma Pattan #include <net/if.h> 14caa70282SReshma Pattan 15caa70282SReshma Pattan #include <rte_eal.h> 16a99a311bSSuanming Mou #include <rte_alarm.h> 17caa70282SReshma Pattan #include <rte_common.h> 18caa70282SReshma Pattan #include <rte_debug.h> 19caa70282SReshma Pattan #include <rte_ethdev.h> 20caa70282SReshma Pattan #include <rte_memory.h> 21caa70282SReshma Pattan #include <rte_lcore.h> 22caa70282SReshma Pattan #include <rte_branch_prediction.h> 23caa70282SReshma Pattan #include <rte_errno.h> 24caa70282SReshma Pattan #include <rte_dev.h> 25caa70282SReshma Pattan #include <rte_kvargs.h> 26caa70282SReshma Pattan #include <rte_mempool.h> 27caa70282SReshma Pattan #include <rte_ring.h> 28c022cb40SBruce Richardson #include <rte_string_fns.h> 29caa70282SReshma Pattan #include <rte_pdump.h> 30caa70282SReshma Pattan 31a5f51527SReshma Pattan #define CMD_LINE_OPT_PDUMP "pdump" 32b2854d53SVipin Varghese #define CMD_LINE_OPT_PDUMP_NUM 256 33b2854d53SVipin Varghese #define CMD_LINE_OPT_MULTI "multi" 34b2854d53SVipin Varghese #define CMD_LINE_OPT_MULTI_NUM 257 35caa70282SReshma Pattan #define PDUMP_PORT_ARG "port" 36caa70282SReshma Pattan #define PDUMP_PCI_ARG "device_id" 37caa70282SReshma Pattan #define PDUMP_QUEUE_ARG "queue" 38caa70282SReshma Pattan #define PDUMP_DIR_ARG "dir" 39caa70282SReshma Pattan #define PDUMP_RX_DEV_ARG "rx-dev" 40caa70282SReshma Pattan #define PDUMP_TX_DEV_ARG "tx-dev" 41caa70282SReshma Pattan #define PDUMP_RING_SIZE_ARG "ring-size" 42caa70282SReshma Pattan #define PDUMP_MSIZE_ARG "mbuf-size" 43caa70282SReshma Pattan #define PDUMP_NUM_MBUFS_ARG "total-num-mbufs" 44caa70282SReshma Pattan 456362f362SAndrew Rybchenko #define VDEV_NAME_FMT "net_pcap_%s_%d" 466362f362SAndrew Rybchenko #define VDEV_PCAP_ARGS_FMT "tx_pcap=%s" 476362f362SAndrew Rybchenko #define VDEV_IFACE_ARGS_FMT "tx_iface=%s" 48caa70282SReshma Pattan #define TX_STREAM_SIZE 64 49caa70282SReshma Pattan 50caa70282SReshma Pattan #define MP_NAME "pdump_pool_%d" 51caa70282SReshma Pattan 52caa70282SReshma Pattan #define RX_RING "rx_ring_%d" 53caa70282SReshma Pattan #define TX_RING "tx_ring_%d" 54caa70282SReshma Pattan 55caa70282SReshma Pattan #define RX_STR "rx" 56caa70282SReshma Pattan #define TX_STR "tx" 57caa70282SReshma Pattan 58caa70282SReshma Pattan /* Maximum long option length for option parsing. */ 59caa70282SReshma Pattan #define APP_ARG_TCPDUMP_MAX_TUPLES 54 60caa70282SReshma Pattan #define MBUF_POOL_CACHE_SIZE 250 61caa70282SReshma Pattan #define TX_DESC_PER_QUEUE 512 62caa70282SReshma Pattan #define RX_DESC_PER_QUEUE 128 63caa70282SReshma Pattan #define MBUFS_PER_POOL 65535 64caa70282SReshma Pattan #define MAX_LONG_OPT_SZ 64 65caa70282SReshma Pattan #define RING_SIZE 16384 66caa70282SReshma Pattan #define SIZE 256 67caa70282SReshma Pattan #define BURST_SIZE 32 68caa70282SReshma Pattan #define NUM_VDEVS 2 69a99a311bSSuanming Mou /* Maximum delay for exiting after primary process. */ 70a99a311bSSuanming Mou #define MONITOR_INTERVAL (500 * 1000) 71caa70282SReshma Pattan 72caa70282SReshma Pattan /* true if x is a power of 2 */ 73caa70282SReshma Pattan #define POWEROF2(x) ((((x)-1) & (x)) == 0) 74caa70282SReshma Pattan 75caa70282SReshma Pattan enum pdump_en_dis { 76caa70282SReshma Pattan DISABLE = 1, 77caa70282SReshma Pattan ENABLE = 2 78caa70282SReshma Pattan }; 79caa70282SReshma Pattan 80caa70282SReshma Pattan enum pcap_stream { 81caa70282SReshma Pattan IFACE = 1, 82caa70282SReshma Pattan PCAP = 2 83caa70282SReshma Pattan }; 84caa70282SReshma Pattan 85caa70282SReshma Pattan enum pdump_by { 86caa70282SReshma Pattan PORT_ID = 1, 87caa70282SReshma Pattan DEVICE_ID = 2 88caa70282SReshma Pattan }; 89caa70282SReshma Pattan 90b74fd6b8SFerruh Yigit static const char * const valid_pdump_arguments[] = { 91caa70282SReshma Pattan PDUMP_PORT_ARG, 92caa70282SReshma Pattan PDUMP_PCI_ARG, 93caa70282SReshma Pattan PDUMP_QUEUE_ARG, 94caa70282SReshma Pattan PDUMP_DIR_ARG, 95caa70282SReshma Pattan PDUMP_RX_DEV_ARG, 96caa70282SReshma Pattan PDUMP_TX_DEV_ARG, 97caa70282SReshma Pattan PDUMP_RING_SIZE_ARG, 98caa70282SReshma Pattan PDUMP_MSIZE_ARG, 99caa70282SReshma Pattan PDUMP_NUM_MBUFS_ARG, 100caa70282SReshma Pattan NULL 101caa70282SReshma Pattan }; 102caa70282SReshma Pattan 103caa70282SReshma Pattan struct pdump_stats { 104caa70282SReshma Pattan uint64_t dequeue_pkts; 105caa70282SReshma Pattan uint64_t tx_pkts; 106caa70282SReshma Pattan uint64_t freed_pkts; 107caa70282SReshma Pattan }; 108caa70282SReshma Pattan 1090efea35aSTyler Retzlaff struct __rte_cache_aligned pdump_tuples { 110caa70282SReshma Pattan /* cli params */ 111f14a210aSZhiyong Yang uint16_t port; 112caa70282SReshma Pattan char *device_id; 113caa70282SReshma Pattan uint16_t queue; 114caa70282SReshma Pattan char rx_dev[TX_STREAM_SIZE]; 115caa70282SReshma Pattan char tx_dev[TX_STREAM_SIZE]; 116caa70282SReshma Pattan uint32_t ring_size; 117caa70282SReshma Pattan uint16_t mbuf_data_size; 118caa70282SReshma Pattan uint32_t total_num_mbufs; 119caa70282SReshma Pattan 120caa70282SReshma Pattan /* params for library API call */ 121caa70282SReshma Pattan uint32_t dir; 122caa70282SReshma Pattan struct rte_mempool *mp; 123caa70282SReshma Pattan struct rte_ring *rx_ring; 124caa70282SReshma Pattan struct rte_ring *tx_ring; 125caa70282SReshma Pattan 126caa70282SReshma Pattan /* params for packet dumping */ 127caa70282SReshma Pattan enum pdump_by dump_by_type; 128e772cf1bSMarko Kovacevic uint16_t rx_vdev_id; 129e772cf1bSMarko Kovacevic uint16_t tx_vdev_id; 130caa70282SReshma Pattan enum pcap_stream rx_vdev_stream_type; 131caa70282SReshma Pattan enum pcap_stream tx_vdev_stream_type; 132caa70282SReshma Pattan bool single_pdump_dev; 133caa70282SReshma Pattan 134caa70282SReshma Pattan /* stats */ 135caa70282SReshma Pattan struct pdump_stats stats; 1360efea35aSTyler Retzlaff }; 137caa70282SReshma Pattan static struct pdump_tuples pdump_t[APP_ARG_TCPDUMP_MAX_TUPLES]; 138caa70282SReshma Pattan 139caa70282SReshma Pattan struct parse_val { 140caa70282SReshma Pattan uint64_t min; 141caa70282SReshma Pattan uint64_t max; 142caa70282SReshma Pattan uint64_t val; 143caa70282SReshma Pattan }; 144caa70282SReshma Pattan 145b74fd6b8SFerruh Yigit static int num_tuples; 146caa70282SReshma Pattan static struct rte_eth_conf port_conf_default; 147b74fd6b8SFerruh Yigit static volatile uint8_t quit_signal; 148b2854d53SVipin Varghese static uint8_t multiple_core_capture; 149caa70282SReshma Pattan 150caa70282SReshma Pattan /**< display usage */ 151caa70282SReshma Pattan static void 152caa70282SReshma Pattan pdump_usage(const char *prgname) 153caa70282SReshma Pattan { 154a658775cSThomas Monjalon printf("usage: %s [EAL options] --" 155b2854d53SVipin Varghese " --["CMD_LINE_OPT_MULTI"]\n" 156b2854d53SVipin Varghese " --"CMD_LINE_OPT_PDUMP" " 157caa70282SReshma Pattan "'(port=<port id> | device_id=<pci id or vdev name>)," 158caa70282SReshma Pattan "(queue=<queue_id>)," 159caa70282SReshma Pattan "(rx-dev=<iface or pcap file> |" 160caa70282SReshma Pattan " tx-dev=<iface or pcap file>," 161caa70282SReshma Pattan "[ring-size=<ring size>default:16384]," 162caa70282SReshma Pattan "[mbuf-size=<mbuf data size>default:2176]," 16309f4aa2bSThomas Monjalon "[total-num-mbufs=<number of mbufs>default:65535]'\n", 164caa70282SReshma Pattan prgname); 165caa70282SReshma Pattan } 166caa70282SReshma Pattan 167caa70282SReshma Pattan static int 168caa70282SReshma Pattan parse_device_id(const char *key __rte_unused, const char *value, 169caa70282SReshma Pattan void *extra_args) 170caa70282SReshma Pattan { 171caa70282SReshma Pattan struct pdump_tuples *pt = extra_args; 172caa70282SReshma Pattan 173caa70282SReshma Pattan pt->device_id = strdup(value); 17432e1cb91SChengwen Feng if (pt->device_id == NULL) 17532e1cb91SChengwen Feng return -1; 17632e1cb91SChengwen Feng 177caa70282SReshma Pattan pt->dump_by_type = DEVICE_ID; 178caa70282SReshma Pattan 179caa70282SReshma Pattan return 0; 180caa70282SReshma Pattan } 181caa70282SReshma Pattan 182caa70282SReshma Pattan static int 183caa70282SReshma Pattan parse_queue(const char *key __rte_unused, const char *value, void *extra_args) 184caa70282SReshma Pattan { 185caa70282SReshma Pattan unsigned long n; 186caa70282SReshma Pattan struct pdump_tuples *pt = extra_args; 187caa70282SReshma Pattan 188caa70282SReshma Pattan if (!strcmp(value, "*")) 189caa70282SReshma Pattan pt->queue = RTE_PDUMP_ALL_QUEUES; 190caa70282SReshma Pattan else { 191caa70282SReshma Pattan n = strtoul(value, NULL, 10); 192caa70282SReshma Pattan pt->queue = (uint16_t) n; 193caa70282SReshma Pattan } 194caa70282SReshma Pattan return 0; 195caa70282SReshma Pattan } 196caa70282SReshma Pattan 197caa70282SReshma Pattan static int 198caa70282SReshma Pattan parse_rxtxdev(const char *key, const char *value, void *extra_args) 199caa70282SReshma Pattan { 200caa70282SReshma Pattan 201caa70282SReshma Pattan struct pdump_tuples *pt = extra_args; 202caa70282SReshma Pattan 203caa70282SReshma Pattan if (!strcmp(key, PDUMP_RX_DEV_ARG)) { 204f9acaf84SBruce Richardson strlcpy(pt->rx_dev, value, sizeof(pt->rx_dev)); 205caa70282SReshma Pattan /* identify the tx stream type for pcap vdev */ 206caa70282SReshma Pattan if (if_nametoindex(pt->rx_dev)) 207caa70282SReshma Pattan pt->rx_vdev_stream_type = IFACE; 208caa70282SReshma Pattan } else if (!strcmp(key, PDUMP_TX_DEV_ARG)) { 209f9acaf84SBruce Richardson strlcpy(pt->tx_dev, value, sizeof(pt->tx_dev)); 210caa70282SReshma Pattan /* identify the tx stream type for pcap vdev */ 211caa70282SReshma Pattan if (if_nametoindex(pt->tx_dev)) 212caa70282SReshma Pattan pt->tx_vdev_stream_type = IFACE; 213caa70282SReshma Pattan } 214caa70282SReshma Pattan 215caa70282SReshma Pattan return 0; 216caa70282SReshma Pattan } 217caa70282SReshma Pattan 218caa70282SReshma Pattan static int 219caa70282SReshma Pattan parse_uint_value(const char *key, const char *value, void *extra_args) 220caa70282SReshma Pattan { 221caa70282SReshma Pattan struct parse_val *v; 222caa70282SReshma Pattan unsigned long t; 223caa70282SReshma Pattan char *end; 224caa70282SReshma Pattan int ret = 0; 225caa70282SReshma Pattan 226caa70282SReshma Pattan errno = 0; 227caa70282SReshma Pattan v = extra_args; 228caa70282SReshma Pattan t = strtoul(value, &end, 10); 229caa70282SReshma Pattan 230caa70282SReshma Pattan if (errno != 0 || end[0] != 0 || t < v->min || t > v->max) { 231caa70282SReshma Pattan printf("invalid value:\"%s\" for key:\"%s\", " 232caa70282SReshma Pattan "value must be >= %"PRIu64" and <= %"PRIu64"\n", 233caa70282SReshma Pattan value, key, v->min, v->max); 234caa70282SReshma Pattan ret = -EINVAL; 235caa70282SReshma Pattan } 236caa70282SReshma Pattan if (!strcmp(key, PDUMP_RING_SIZE_ARG) && !POWEROF2(t)) { 237caa70282SReshma Pattan printf("invalid value:\"%s\" for key:\"%s\", " 238caa70282SReshma Pattan "value must be power of 2\n", value, key); 239caa70282SReshma Pattan ret = -EINVAL; 240caa70282SReshma Pattan } 241caa70282SReshma Pattan 242caa70282SReshma Pattan if (ret != 0) 243caa70282SReshma Pattan return ret; 244caa70282SReshma Pattan 245caa70282SReshma Pattan v->val = t; 246caa70282SReshma Pattan return 0; 247caa70282SReshma Pattan } 248caa70282SReshma Pattan 249caa70282SReshma Pattan static int 250caa70282SReshma Pattan parse_pdump(const char *optarg) 251caa70282SReshma Pattan { 252caa70282SReshma Pattan struct rte_kvargs *kvlist; 253caa70282SReshma Pattan int ret = 0, cnt1, cnt2; 254caa70282SReshma Pattan struct pdump_tuples *pt; 255caa70282SReshma Pattan struct parse_val v = {0}; 256caa70282SReshma Pattan 257caa70282SReshma Pattan pt = &pdump_t[num_tuples]; 258caa70282SReshma Pattan 259caa70282SReshma Pattan /* initial check for invalid arguments */ 260caa70282SReshma Pattan kvlist = rte_kvargs_parse(optarg, valid_pdump_arguments); 261caa70282SReshma Pattan if (kvlist == NULL) { 262caa70282SReshma Pattan printf("--pdump=\"%s\": invalid argument passed\n", optarg); 263caa70282SReshma Pattan return -1; 264caa70282SReshma Pattan } 265caa70282SReshma Pattan 266caa70282SReshma Pattan /* port/device_id parsing and validation */ 267caa70282SReshma Pattan cnt1 = rte_kvargs_count(kvlist, PDUMP_PORT_ARG); 268caa70282SReshma Pattan cnt2 = rte_kvargs_count(kvlist, PDUMP_PCI_ARG); 269caa70282SReshma Pattan if (!((cnt1 == 1 && cnt2 == 0) || (cnt1 == 0 && cnt2 == 1))) { 270caa70282SReshma Pattan printf("--pdump=\"%s\": must have either port or " 271caa70282SReshma Pattan "device_id argument\n", optarg); 272caa70282SReshma Pattan ret = -1; 273caa70282SReshma Pattan goto free_kvlist; 274caa70282SReshma Pattan } else if (cnt1 == 1) { 275caa70282SReshma Pattan v.min = 0; 276caa70282SReshma Pattan v.max = RTE_MAX_ETHPORTS-1; 277caa70282SReshma Pattan ret = rte_kvargs_process(kvlist, PDUMP_PORT_ARG, 278caa70282SReshma Pattan &parse_uint_value, &v); 279caa70282SReshma Pattan if (ret < 0) 280caa70282SReshma Pattan goto free_kvlist; 281e772cf1bSMarko Kovacevic pt->port = (uint16_t) v.val; 282caa70282SReshma Pattan pt->dump_by_type = PORT_ID; 283caa70282SReshma Pattan } else if (cnt2 == 1) { 284caa70282SReshma Pattan ret = rte_kvargs_process(kvlist, PDUMP_PCI_ARG, 285caa70282SReshma Pattan &parse_device_id, pt); 286caa70282SReshma Pattan if (ret < 0) 287caa70282SReshma Pattan goto free_kvlist; 288caa70282SReshma Pattan } 289caa70282SReshma Pattan 290caa70282SReshma Pattan /* queue parsing and validation */ 291caa70282SReshma Pattan cnt1 = rte_kvargs_count(kvlist, PDUMP_QUEUE_ARG); 292caa70282SReshma Pattan if (cnt1 != 1) { 293caa70282SReshma Pattan printf("--pdump=\"%s\": must have queue argument\n", optarg); 294caa70282SReshma Pattan ret = -1; 295caa70282SReshma Pattan goto free_kvlist; 296caa70282SReshma Pattan } 297caa70282SReshma Pattan ret = rte_kvargs_process(kvlist, PDUMP_QUEUE_ARG, &parse_queue, pt); 298caa70282SReshma Pattan if (ret < 0) 299caa70282SReshma Pattan goto free_kvlist; 300caa70282SReshma Pattan 301caa70282SReshma Pattan /* rx-dev and tx-dev parsing and validation */ 302caa70282SReshma Pattan cnt1 = rte_kvargs_count(kvlist, PDUMP_RX_DEV_ARG); 303caa70282SReshma Pattan cnt2 = rte_kvargs_count(kvlist, PDUMP_TX_DEV_ARG); 304caa70282SReshma Pattan if (cnt1 == 0 && cnt2 == 0) { 305caa70282SReshma Pattan printf("--pdump=\"%s\": must have either rx-dev or " 306caa70282SReshma Pattan "tx-dev argument\n", optarg); 307caa70282SReshma Pattan ret = -1; 308caa70282SReshma Pattan goto free_kvlist; 309caa70282SReshma Pattan } else if (cnt1 == 1 && cnt2 == 1) { 310caa70282SReshma Pattan ret = rte_kvargs_process(kvlist, PDUMP_RX_DEV_ARG, 311caa70282SReshma Pattan &parse_rxtxdev, pt); 312caa70282SReshma Pattan if (ret < 0) 313caa70282SReshma Pattan goto free_kvlist; 314caa70282SReshma Pattan ret = rte_kvargs_process(kvlist, PDUMP_TX_DEV_ARG, 315caa70282SReshma Pattan &parse_rxtxdev, pt); 316caa70282SReshma Pattan if (ret < 0) 317caa70282SReshma Pattan goto free_kvlist; 318caa70282SReshma Pattan /* if captured packets has to send to the same vdev */ 319caa70282SReshma Pattan if (!strcmp(pt->rx_dev, pt->tx_dev)) 320caa70282SReshma Pattan pt->single_pdump_dev = true; 321caa70282SReshma Pattan pt->dir = RTE_PDUMP_FLAG_RXTX; 322caa70282SReshma Pattan } else if (cnt1 == 1) { 323caa70282SReshma Pattan ret = rte_kvargs_process(kvlist, PDUMP_RX_DEV_ARG, 324caa70282SReshma Pattan &parse_rxtxdev, pt); 325caa70282SReshma Pattan if (ret < 0) 326caa70282SReshma Pattan goto free_kvlist; 327caa70282SReshma Pattan pt->dir = RTE_PDUMP_FLAG_RX; 328caa70282SReshma Pattan } else if (cnt2 == 1) { 329caa70282SReshma Pattan ret = rte_kvargs_process(kvlist, PDUMP_TX_DEV_ARG, 330caa70282SReshma Pattan &parse_rxtxdev, pt); 331caa70282SReshma Pattan if (ret < 0) 332caa70282SReshma Pattan goto free_kvlist; 333caa70282SReshma Pattan pt->dir = RTE_PDUMP_FLAG_TX; 334caa70282SReshma Pattan } 335caa70282SReshma Pattan 336caa70282SReshma Pattan /* optional */ 337caa70282SReshma Pattan /* ring_size parsing and validation */ 338caa70282SReshma Pattan cnt1 = rte_kvargs_count(kvlist, PDUMP_RING_SIZE_ARG); 339caa70282SReshma Pattan if (cnt1 == 1) { 340caa70282SReshma Pattan v.min = 2; 341caa70282SReshma Pattan v.max = RTE_RING_SZ_MASK-1; 342caa70282SReshma Pattan ret = rte_kvargs_process(kvlist, PDUMP_RING_SIZE_ARG, 343caa70282SReshma Pattan &parse_uint_value, &v); 344caa70282SReshma Pattan if (ret < 0) 345caa70282SReshma Pattan goto free_kvlist; 3469115326dSReshma Pattan pt->ring_size = (uint32_t) v.val; 347caa70282SReshma Pattan } else 348caa70282SReshma Pattan pt->ring_size = RING_SIZE; 349caa70282SReshma Pattan 350caa70282SReshma Pattan /* mbuf_data_size parsing and validation */ 351caa70282SReshma Pattan cnt1 = rte_kvargs_count(kvlist, PDUMP_MSIZE_ARG); 352caa70282SReshma Pattan if (cnt1 == 1) { 353caa70282SReshma Pattan v.min = 1; 354caa70282SReshma Pattan v.max = UINT16_MAX; 355caa70282SReshma Pattan ret = rte_kvargs_process(kvlist, PDUMP_MSIZE_ARG, 356caa70282SReshma Pattan &parse_uint_value, &v); 357caa70282SReshma Pattan if (ret < 0) 358caa70282SReshma Pattan goto free_kvlist; 359caa70282SReshma Pattan pt->mbuf_data_size = (uint16_t) v.val; 360caa70282SReshma Pattan } else 361caa70282SReshma Pattan pt->mbuf_data_size = RTE_MBUF_DEFAULT_BUF_SIZE; 362caa70282SReshma Pattan 363caa70282SReshma Pattan /* total_num_mbufs parsing and validation */ 364caa70282SReshma Pattan cnt1 = rte_kvargs_count(kvlist, PDUMP_NUM_MBUFS_ARG); 365caa70282SReshma Pattan if (cnt1 == 1) { 366caa70282SReshma Pattan v.min = 1025; 367caa70282SReshma Pattan v.max = UINT16_MAX; 368caa70282SReshma Pattan ret = rte_kvargs_process(kvlist, PDUMP_NUM_MBUFS_ARG, 369caa70282SReshma Pattan &parse_uint_value, &v); 370caa70282SReshma Pattan if (ret < 0) 371caa70282SReshma Pattan goto free_kvlist; 372caa70282SReshma Pattan pt->total_num_mbufs = (uint16_t) v.val; 373caa70282SReshma Pattan } else 374caa70282SReshma Pattan pt->total_num_mbufs = MBUFS_PER_POOL; 375caa70282SReshma Pattan 376caa70282SReshma Pattan num_tuples++; 377caa70282SReshma Pattan 378caa70282SReshma Pattan free_kvlist: 379caa70282SReshma Pattan rte_kvargs_free(kvlist); 380caa70282SReshma Pattan return ret; 381caa70282SReshma Pattan } 382caa70282SReshma Pattan 383caa70282SReshma Pattan /* Parse the argument given in the command line of the application */ 384caa70282SReshma Pattan static int 385caa70282SReshma Pattan launch_args_parse(int argc, char **argv, char *prgname) 386caa70282SReshma Pattan { 387caa70282SReshma Pattan int opt, ret; 388caa70282SReshma Pattan int option_index; 389caa70282SReshma Pattan static struct option long_option[] = { 390b2854d53SVipin Varghese {CMD_LINE_OPT_PDUMP, 1, 0, CMD_LINE_OPT_PDUMP_NUM}, 391b2854d53SVipin Varghese {CMD_LINE_OPT_MULTI, 0, 0, CMD_LINE_OPT_MULTI_NUM}, 392caa70282SReshma Pattan {NULL, 0, 0, 0} 393caa70282SReshma Pattan }; 394caa70282SReshma Pattan 395caa70282SReshma Pattan if (argc == 1) 396caa70282SReshma Pattan pdump_usage(prgname); 397caa70282SReshma Pattan 398caa70282SReshma Pattan /* Parse command line */ 399caa70282SReshma Pattan while ((opt = getopt_long(argc, argv, " ", 400caa70282SReshma Pattan long_option, &option_index)) != EOF) { 401caa70282SReshma Pattan switch (opt) { 402b2854d53SVipin Varghese case CMD_LINE_OPT_PDUMP_NUM: 403caa70282SReshma Pattan ret = parse_pdump(optarg); 404caa70282SReshma Pattan if (ret) { 405caa70282SReshma Pattan pdump_usage(prgname); 406caa70282SReshma Pattan return -1; 407caa70282SReshma Pattan } 408b2854d53SVipin Varghese break; 409b2854d53SVipin Varghese case CMD_LINE_OPT_MULTI_NUM: 410b2854d53SVipin Varghese multiple_core_capture = 1; 411caa70282SReshma Pattan break; 412caa70282SReshma Pattan default: 413caa70282SReshma Pattan pdump_usage(prgname); 414caa70282SReshma Pattan return -1; 415caa70282SReshma Pattan } 416caa70282SReshma Pattan } 417caa70282SReshma Pattan 418caa70282SReshma Pattan return 0; 419caa70282SReshma Pattan } 420caa70282SReshma Pattan 421caa70282SReshma Pattan static void 422a99a311bSSuanming Mou monitor_primary(void *arg __rte_unused) 423a99a311bSSuanming Mou { 424a99a311bSSuanming Mou if (quit_signal) 425a99a311bSSuanming Mou return; 426a99a311bSSuanming Mou 427a99a311bSSuanming Mou if (rte_eal_primary_proc_alive(NULL)) { 428a99a311bSSuanming Mou rte_eal_alarm_set(MONITOR_INTERVAL, monitor_primary, NULL); 429a99a311bSSuanming Mou return; 430a99a311bSSuanming Mou } 431a99a311bSSuanming Mou 432a99a311bSSuanming Mou printf("Primary process is no longer active, exiting...\n"); 433a99a311bSSuanming Mou quit_signal = 1; 434a99a311bSSuanming Mou } 435a99a311bSSuanming Mou 436a99a311bSSuanming Mou static void 437caa70282SReshma Pattan print_pdump_stats(void) 438caa70282SReshma Pattan { 439caa70282SReshma Pattan int i; 440caa70282SReshma Pattan struct pdump_tuples *pt; 441caa70282SReshma Pattan 442caa70282SReshma Pattan for (i = 0; i < num_tuples; i++) { 443caa70282SReshma Pattan printf("##### PDUMP DEBUG STATS #####\n"); 444caa70282SReshma Pattan pt = &pdump_t[i]; 445caa70282SReshma Pattan printf(" -packets dequeued: %"PRIu64"\n", 446caa70282SReshma Pattan pt->stats.dequeue_pkts); 447caa70282SReshma Pattan printf(" -packets transmitted to vdev: %"PRIu64"\n", 448caa70282SReshma Pattan pt->stats.tx_pkts); 449caa70282SReshma Pattan printf(" -packets freed: %"PRIu64"\n", 450caa70282SReshma Pattan pt->stats.freed_pkts); 451caa70282SReshma Pattan } 452caa70282SReshma Pattan } 453caa70282SReshma Pattan 454caa70282SReshma Pattan static inline void 455caa70282SReshma Pattan disable_pdump(struct pdump_tuples *pt) 456caa70282SReshma Pattan { 457caa70282SReshma Pattan if (pt->dump_by_type == DEVICE_ID) 458caa70282SReshma Pattan rte_pdump_disable_by_deviceid(pt->device_id, pt->queue, 459caa70282SReshma Pattan pt->dir); 460caa70282SReshma Pattan else if (pt->dump_by_type == PORT_ID) 461caa70282SReshma Pattan rte_pdump_disable(pt->port, pt->queue, pt->dir); 462caa70282SReshma Pattan } 463caa70282SReshma Pattan 464caa70282SReshma Pattan static inline void 465e772cf1bSMarko Kovacevic pdump_rxtx(struct rte_ring *ring, uint16_t vdev_id, struct pdump_stats *stats) 466caa70282SReshma Pattan { 467caa70282SReshma Pattan /* write input packets of port to vdev for pdump */ 468caa70282SReshma Pattan struct rte_mbuf *rxtx_bufs[BURST_SIZE]; 469caa70282SReshma Pattan 470caa70282SReshma Pattan /* first dequeue packets from ring of primary process */ 471caa70282SReshma Pattan const uint16_t nb_in_deq = rte_ring_dequeue_burst(ring, 472ecaed092SBruce Richardson (void *)rxtx_bufs, BURST_SIZE, NULL); 473caa70282SReshma Pattan stats->dequeue_pkts += nb_in_deq; 474caa70282SReshma Pattan 475caa70282SReshma Pattan if (nb_in_deq) { 476caa70282SReshma Pattan /* then sent on vdev */ 477caa70282SReshma Pattan uint16_t nb_in_txd = rte_eth_tx_burst( 478caa70282SReshma Pattan vdev_id, 479caa70282SReshma Pattan 0, rxtx_bufs, nb_in_deq); 480caa70282SReshma Pattan stats->tx_pkts += nb_in_txd; 481caa70282SReshma Pattan 482caa70282SReshma Pattan if (unlikely(nb_in_txd < nb_in_deq)) { 483f82067c4SStephen Hemminger unsigned int drops = nb_in_deq - nb_in_txd; 484f82067c4SStephen Hemminger 485f82067c4SStephen Hemminger rte_pktmbuf_free_bulk(&rxtx_bufs[nb_in_txd], drops); 486f82067c4SStephen Hemminger stats->freed_pkts += drops; 487caa70282SReshma Pattan } 488caa70282SReshma Pattan } 489caa70282SReshma Pattan } 490caa70282SReshma Pattan 491caa70282SReshma Pattan static void 492e772cf1bSMarko Kovacevic free_ring_data(struct rte_ring *ring, uint16_t vdev_id, 493caa70282SReshma Pattan struct pdump_stats *stats) 494caa70282SReshma Pattan { 495caa70282SReshma Pattan while (rte_ring_count(ring)) 496caa70282SReshma Pattan pdump_rxtx(ring, vdev_id, stats); 497caa70282SReshma Pattan } 498caa70282SReshma Pattan 499caa70282SReshma Pattan static void 5001c4466cbSReshma Pattan cleanup_rings(void) 5011c4466cbSReshma Pattan { 5021c4466cbSReshma Pattan int i; 5031c4466cbSReshma Pattan struct pdump_tuples *pt; 5041c4466cbSReshma Pattan 5051c4466cbSReshma Pattan for (i = 0; i < num_tuples; i++) { 5061c4466cbSReshma Pattan pt = &pdump_t[i]; 5071c4466cbSReshma Pattan 5081c4466cbSReshma Pattan free(pt->device_id); 5091c4466cbSReshma Pattan 5101c4466cbSReshma Pattan /* free the rings */ 5111c4466cbSReshma Pattan rte_ring_free(pt->rx_ring); 5121c4466cbSReshma Pattan rte_ring_free(pt->tx_ring); 513a8a1c40bSTianli Lai rte_mempool_free(pt->mp); 5141c4466cbSReshma Pattan } 5151c4466cbSReshma Pattan } 5161c4466cbSReshma Pattan 5171c4466cbSReshma Pattan static void 518caa70282SReshma Pattan cleanup_pdump_resources(void) 519caa70282SReshma Pattan { 520caa70282SReshma Pattan int i; 521caa70282SReshma Pattan struct pdump_tuples *pt; 52235cb223aSReshma Pattan char name[RTE_ETH_NAME_MAX_LEN]; 523caa70282SReshma Pattan 524caa70282SReshma Pattan /* disable pdump and free the pdump_tuple resources */ 525caa70282SReshma Pattan for (i = 0; i < num_tuples; i++) { 526caa70282SReshma Pattan pt = &pdump_t[i]; 527caa70282SReshma Pattan 528caa70282SReshma Pattan /* remove callbacks */ 529caa70282SReshma Pattan disable_pdump(pt); 530caa70282SReshma Pattan 531caa70282SReshma Pattan /* 532caa70282SReshma Pattan * transmit rest of the enqueued packets of the rings on to 533caa70282SReshma Pattan * the vdev, in order to release mbufs to the mepool. 534caa70282SReshma Pattan **/ 535caa70282SReshma Pattan if (pt->dir & RTE_PDUMP_FLAG_RX) 536caa70282SReshma Pattan free_ring_data(pt->rx_ring, pt->rx_vdev_id, &pt->stats); 537caa70282SReshma Pattan if (pt->dir & RTE_PDUMP_FLAG_TX) 538caa70282SReshma Pattan free_ring_data(pt->tx_ring, pt->tx_vdev_id, &pt->stats); 53935cb223aSReshma Pattan 540499ca616SGage Eads /* Remove the vdev(s) created */ 541499ca616SGage Eads if (pt->dir & RTE_PDUMP_FLAG_RX) { 54235cb223aSReshma Pattan rte_eth_dev_get_name_by_port(pt->rx_vdev_id, name); 54335cb223aSReshma Pattan rte_eal_hotplug_remove("vdev", name); 544499ca616SGage Eads } 54535cb223aSReshma Pattan 546499ca616SGage Eads if (pt->single_pdump_dev) 547499ca616SGage Eads continue; 548499ca616SGage Eads 549499ca616SGage Eads if (pt->dir & RTE_PDUMP_FLAG_TX) { 55035cb223aSReshma Pattan rte_eth_dev_get_name_by_port(pt->tx_vdev_id, name); 55135cb223aSReshma Pattan rte_eal_hotplug_remove("vdev", name); 552499ca616SGage Eads } 55335cb223aSReshma Pattan 554caa70282SReshma Pattan } 5551c4466cbSReshma Pattan cleanup_rings(); 556caa70282SReshma Pattan } 557caa70282SReshma Pattan 558caa70282SReshma Pattan static void 559a99a311bSSuanming Mou disable_primary_monitor(void) 560a99a311bSSuanming Mou { 561a99a311bSSuanming Mou int ret; 562a99a311bSSuanming Mou 563a99a311bSSuanming Mou /* 564a99a311bSSuanming Mou * Cancel monitoring of primary process. 565a99a311bSSuanming Mou * There will be no error if no alarm is set 566a99a311bSSuanming Mou * (in case primary process kill was detected earlier). 567a99a311bSSuanming Mou */ 568a99a311bSSuanming Mou ret = rte_eal_alarm_cancel(monitor_primary, NULL); 569a99a311bSSuanming Mou if (ret < 0) 570a99a311bSSuanming Mou printf("Fail to disable monitor:%d\n", ret); 571a99a311bSSuanming Mou } 572a99a311bSSuanming Mou 573a99a311bSSuanming Mou static void 574*e1253df6SStephen Hemminger signal_handler(int sig_num __rte_unused) 575caa70282SReshma Pattan { 576caa70282SReshma Pattan quit_signal = 1; 577caa70282SReshma Pattan } 578caa70282SReshma Pattan 579caa70282SReshma Pattan static inline int 580bcfa5579SZhiyong Yang configure_vdev(uint16_t port_id) 581caa70282SReshma Pattan { 5826d13ea8eSOlivier Matz struct rte_ether_addr addr; 583caa70282SReshma Pattan const uint16_t rxRings = 0, txRings = 1; 584caa70282SReshma Pattan int ret; 585caa70282SReshma Pattan uint16_t q; 586caa70282SReshma Pattan 587a9dbe180SThomas Monjalon if (!rte_eth_dev_is_valid_port(port_id)) 588caa70282SReshma Pattan return -1; 589caa70282SReshma Pattan 590caa70282SReshma Pattan ret = rte_eth_dev_configure(port_id, rxRings, txRings, 591caa70282SReshma Pattan &port_conf_default); 592caa70282SReshma Pattan if (ret != 0) 593caa70282SReshma Pattan rte_exit(EXIT_FAILURE, "dev config failed\n"); 594caa70282SReshma Pattan 595caa70282SReshma Pattan for (q = 0; q < txRings; q++) { 596caa70282SReshma Pattan ret = rte_eth_tx_queue_setup(port_id, q, TX_DESC_PER_QUEUE, 597caa70282SReshma Pattan rte_eth_dev_socket_id(port_id), NULL); 598caa70282SReshma Pattan if (ret < 0) 599caa70282SReshma Pattan rte_exit(EXIT_FAILURE, "queue setup failed\n"); 600caa70282SReshma Pattan } 601caa70282SReshma Pattan 602caa70282SReshma Pattan ret = rte_eth_dev_start(port_id); 603caa70282SReshma Pattan if (ret < 0) 604caa70282SReshma Pattan rte_exit(EXIT_FAILURE, "dev start failed\n"); 605caa70282SReshma Pattan 6066fcf8586SIgor Romanov ret = rte_eth_macaddr_get(port_id, &addr); 6076fcf8586SIgor Romanov if (ret != 0) 6086fcf8586SIgor Romanov rte_exit(EXIT_FAILURE, "macaddr get failed\n"); 6096fcf8586SIgor Romanov 610caa70282SReshma Pattan printf("Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8 611caa70282SReshma Pattan " %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", 612a7db3afcSAman Deep Singh port_id, RTE_ETHER_ADDR_BYTES(&addr)); 613caa70282SReshma Pattan 61470e51a0eSIvan Ilchenko ret = rte_eth_promiscuous_enable(port_id); 61570e51a0eSIvan Ilchenko if (ret != 0) { 61670e51a0eSIvan Ilchenko rte_exit(EXIT_FAILURE, 61770e51a0eSIvan Ilchenko "promiscuous mode enable failed: %s\n", 61870e51a0eSIvan Ilchenko rte_strerror(-ret)); 61970e51a0eSIvan Ilchenko return ret; 62070e51a0eSIvan Ilchenko } 621caa70282SReshma Pattan 622caa70282SReshma Pattan return 0; 623caa70282SReshma Pattan } 624caa70282SReshma Pattan 625caa70282SReshma Pattan static void 626caa70282SReshma Pattan create_mp_ring_vdev(void) 627caa70282SReshma Pattan { 628caa70282SReshma Pattan int i; 629f8244c63SZhiyong Yang uint16_t portid; 630caa70282SReshma Pattan struct pdump_tuples *pt = NULL; 631caa70282SReshma Pattan struct rte_mempool *mbuf_pool = NULL; 6326362f362SAndrew Rybchenko char vdev_name[SIZE]; 633caa70282SReshma Pattan char vdev_args[SIZE]; 634caa70282SReshma Pattan char ring_name[SIZE]; 635caa70282SReshma Pattan char mempool_name[SIZE]; 636caa70282SReshma Pattan 637caa70282SReshma Pattan for (i = 0; i < num_tuples; i++) { 638caa70282SReshma Pattan pt = &pdump_t[i]; 639caa70282SReshma Pattan snprintf(mempool_name, SIZE, MP_NAME, i); 640caa70282SReshma Pattan mbuf_pool = rte_mempool_lookup(mempool_name); 641caa70282SReshma Pattan if (mbuf_pool == NULL) { 642caa70282SReshma Pattan /* create mempool */ 6430c4d3e42SHarman Kalra mbuf_pool = rte_pktmbuf_pool_create_by_ops(mempool_name, 644caa70282SReshma Pattan pt->total_num_mbufs, 645caa70282SReshma Pattan MBUF_POOL_CACHE_SIZE, 0, 646caa70282SReshma Pattan pt->mbuf_data_size, 6470c4d3e42SHarman Kalra rte_socket_id(), "ring_mp_mc"); 6481c4466cbSReshma Pattan if (mbuf_pool == NULL) { 6491c4466cbSReshma Pattan cleanup_rings(); 650caa70282SReshma Pattan rte_exit(EXIT_FAILURE, 651caa70282SReshma Pattan "Mempool creation failed: %s\n", 652caa70282SReshma Pattan rte_strerror(rte_errno)); 653caa70282SReshma Pattan } 6541c4466cbSReshma Pattan } 655caa70282SReshma Pattan pt->mp = mbuf_pool; 656caa70282SReshma Pattan 657caa70282SReshma Pattan if (pt->dir == RTE_PDUMP_FLAG_RXTX) { 658caa70282SReshma Pattan /* if captured packets has to send to the same vdev */ 659caa70282SReshma Pattan /* create rx_ring */ 660caa70282SReshma Pattan snprintf(ring_name, SIZE, RX_RING, i); 661caa70282SReshma Pattan pt->rx_ring = rte_ring_create(ring_name, pt->ring_size, 662caa70282SReshma Pattan rte_socket_id(), 0); 6631c4466cbSReshma Pattan if (pt->rx_ring == NULL) { 6641c4466cbSReshma Pattan cleanup_rings(); 665caa70282SReshma Pattan rte_exit(EXIT_FAILURE, "%s:%s:%d\n", 666caa70282SReshma Pattan rte_strerror(rte_errno), 667caa70282SReshma Pattan __func__, __LINE__); 6681c4466cbSReshma Pattan } 669caa70282SReshma Pattan 670caa70282SReshma Pattan /* create tx_ring */ 671caa70282SReshma Pattan snprintf(ring_name, SIZE, TX_RING, i); 672caa70282SReshma Pattan pt->tx_ring = rte_ring_create(ring_name, pt->ring_size, 673caa70282SReshma Pattan rte_socket_id(), 0); 6741c4466cbSReshma Pattan if (pt->tx_ring == NULL) { 6751c4466cbSReshma Pattan cleanup_rings(); 676caa70282SReshma Pattan rte_exit(EXIT_FAILURE, "%s:%s:%d\n", 677caa70282SReshma Pattan rte_strerror(rte_errno), 678caa70282SReshma Pattan __func__, __LINE__); 6791c4466cbSReshma Pattan } 680caa70282SReshma Pattan 681caa70282SReshma Pattan /* create vdevs */ 6826362f362SAndrew Rybchenko snprintf(vdev_name, sizeof(vdev_name), 6836362f362SAndrew Rybchenko VDEV_NAME_FMT, RX_STR, i); 684caa70282SReshma Pattan (pt->rx_vdev_stream_type == IFACE) ? 6856362f362SAndrew Rybchenko snprintf(vdev_args, sizeof(vdev_args), 6866362f362SAndrew Rybchenko VDEV_IFACE_ARGS_FMT, pt->rx_dev) : 6876362f362SAndrew Rybchenko snprintf(vdev_args, sizeof(vdev_args), 6886362f362SAndrew Rybchenko VDEV_PCAP_ARGS_FMT, pt->rx_dev); 6896362f362SAndrew Rybchenko if (rte_eal_hotplug_add("vdev", vdev_name, 6906362f362SAndrew Rybchenko vdev_args) < 0) { 6911c4466cbSReshma Pattan cleanup_rings(); 692caa70282SReshma Pattan rte_exit(EXIT_FAILURE, 693caa70282SReshma Pattan "vdev creation failed:%s:%d\n", 694caa70282SReshma Pattan __func__, __LINE__); 6951c4466cbSReshma Pattan } 6966362f362SAndrew Rybchenko if (rte_eth_dev_get_port_by_name(vdev_name, 6976362f362SAndrew Rybchenko &portid) != 0) { 6986362f362SAndrew Rybchenko rte_eal_hotplug_remove("vdev", vdev_name); 6996362f362SAndrew Rybchenko cleanup_rings(); 7006362f362SAndrew Rybchenko rte_exit(EXIT_FAILURE, 7016362f362SAndrew Rybchenko "cannot find added vdev %s:%s:%d\n", 7026362f362SAndrew Rybchenko vdev_name, __func__, __LINE__); 7036362f362SAndrew Rybchenko } 704caa70282SReshma Pattan pt->rx_vdev_id = portid; 705caa70282SReshma Pattan 706caa70282SReshma Pattan /* configure vdev */ 707caa70282SReshma Pattan configure_vdev(pt->rx_vdev_id); 708caa70282SReshma Pattan 709caa70282SReshma Pattan if (pt->single_pdump_dev) 710caa70282SReshma Pattan pt->tx_vdev_id = portid; 711caa70282SReshma Pattan else { 7126362f362SAndrew Rybchenko snprintf(vdev_name, sizeof(vdev_name), 7136362f362SAndrew Rybchenko VDEV_NAME_FMT, TX_STR, i); 7146362f362SAndrew Rybchenko (pt->rx_vdev_stream_type == IFACE) ? 7156362f362SAndrew Rybchenko snprintf(vdev_args, sizeof(vdev_args), 7166362f362SAndrew Rybchenko VDEV_IFACE_ARGS_FMT, pt->tx_dev) : 7176362f362SAndrew Rybchenko snprintf(vdev_args, sizeof(vdev_args), 7186362f362SAndrew Rybchenko VDEV_PCAP_ARGS_FMT, pt->tx_dev); 7196362f362SAndrew Rybchenko if (rte_eal_hotplug_add("vdev", vdev_name, 7206362f362SAndrew Rybchenko vdev_args) < 0) { 7211c4466cbSReshma Pattan cleanup_rings(); 722caa70282SReshma Pattan rte_exit(EXIT_FAILURE, 723caa70282SReshma Pattan "vdev creation failed:" 724caa70282SReshma Pattan "%s:%d\n", __func__, __LINE__); 7251c4466cbSReshma Pattan } 7266362f362SAndrew Rybchenko if (rte_eth_dev_get_port_by_name(vdev_name, 7276362f362SAndrew Rybchenko &portid) != 0) { 7286362f362SAndrew Rybchenko rte_eal_hotplug_remove("vdev", 7296362f362SAndrew Rybchenko vdev_name); 7306362f362SAndrew Rybchenko cleanup_rings(); 7316362f362SAndrew Rybchenko rte_exit(EXIT_FAILURE, 7326362f362SAndrew Rybchenko "cannot find added vdev %s:%s:%d\n", 7336362f362SAndrew Rybchenko vdev_name, __func__, __LINE__); 7346362f362SAndrew Rybchenko } 735caa70282SReshma Pattan pt->tx_vdev_id = portid; 736caa70282SReshma Pattan 737caa70282SReshma Pattan /* configure vdev */ 738caa70282SReshma Pattan configure_vdev(pt->tx_vdev_id); 739caa70282SReshma Pattan } 740caa70282SReshma Pattan } else if (pt->dir == RTE_PDUMP_FLAG_RX) { 741caa70282SReshma Pattan 742caa70282SReshma Pattan /* create rx_ring */ 743caa70282SReshma Pattan snprintf(ring_name, SIZE, RX_RING, i); 744caa70282SReshma Pattan pt->rx_ring = rte_ring_create(ring_name, pt->ring_size, 745caa70282SReshma Pattan rte_socket_id(), 0); 7461c4466cbSReshma Pattan if (pt->rx_ring == NULL) { 7471c4466cbSReshma Pattan cleanup_rings(); 748caa70282SReshma Pattan rte_exit(EXIT_FAILURE, "%s\n", 749caa70282SReshma Pattan rte_strerror(rte_errno)); 7501c4466cbSReshma Pattan } 751caa70282SReshma Pattan 7526362f362SAndrew Rybchenko snprintf(vdev_name, sizeof(vdev_name), 7536362f362SAndrew Rybchenko VDEV_NAME_FMT, RX_STR, i); 754caa70282SReshma Pattan (pt->rx_vdev_stream_type == IFACE) ? 7556362f362SAndrew Rybchenko snprintf(vdev_args, sizeof(vdev_args), 7566362f362SAndrew Rybchenko VDEV_IFACE_ARGS_FMT, pt->rx_dev) : 7576362f362SAndrew Rybchenko snprintf(vdev_args, sizeof(vdev_args), 7586362f362SAndrew Rybchenko VDEV_PCAP_ARGS_FMT, pt->rx_dev); 7596362f362SAndrew Rybchenko if (rte_eal_hotplug_add("vdev", vdev_name, 7606362f362SAndrew Rybchenko vdev_args) < 0) { 7611c4466cbSReshma Pattan cleanup_rings(); 762caa70282SReshma Pattan rte_exit(EXIT_FAILURE, 763caa70282SReshma Pattan "vdev creation failed:%s:%d\n", 764caa70282SReshma Pattan __func__, __LINE__); 7651c4466cbSReshma Pattan } 7666362f362SAndrew Rybchenko if (rte_eth_dev_get_port_by_name(vdev_name, 7676362f362SAndrew Rybchenko &portid) != 0) { 7686362f362SAndrew Rybchenko rte_eal_hotplug_remove("vdev", vdev_name); 7696362f362SAndrew Rybchenko cleanup_rings(); 7706362f362SAndrew Rybchenko rte_exit(EXIT_FAILURE, 7716362f362SAndrew Rybchenko "cannot find added vdev %s:%s:%d\n", 7726362f362SAndrew Rybchenko vdev_name, __func__, __LINE__); 7736362f362SAndrew Rybchenko } 774caa70282SReshma Pattan pt->rx_vdev_id = portid; 775caa70282SReshma Pattan /* configure vdev */ 776caa70282SReshma Pattan configure_vdev(pt->rx_vdev_id); 777caa70282SReshma Pattan } else if (pt->dir == RTE_PDUMP_FLAG_TX) { 778caa70282SReshma Pattan 779caa70282SReshma Pattan /* create tx_ring */ 780caa70282SReshma Pattan snprintf(ring_name, SIZE, TX_RING, i); 781caa70282SReshma Pattan pt->tx_ring = rte_ring_create(ring_name, pt->ring_size, 782caa70282SReshma Pattan rte_socket_id(), 0); 7831c4466cbSReshma Pattan if (pt->tx_ring == NULL) { 7841c4466cbSReshma Pattan cleanup_rings(); 785caa70282SReshma Pattan rte_exit(EXIT_FAILURE, "%s\n", 786caa70282SReshma Pattan rte_strerror(rte_errno)); 7871c4466cbSReshma Pattan } 788caa70282SReshma Pattan 7896362f362SAndrew Rybchenko snprintf(vdev_name, sizeof(vdev_name), 7906362f362SAndrew Rybchenko VDEV_NAME_FMT, TX_STR, i); 791caa70282SReshma Pattan (pt->tx_vdev_stream_type == IFACE) ? 7926362f362SAndrew Rybchenko snprintf(vdev_args, sizeof(vdev_args), 7936362f362SAndrew Rybchenko VDEV_IFACE_ARGS_FMT, pt->tx_dev) : 7946362f362SAndrew Rybchenko snprintf(vdev_args, sizeof(vdev_args), 7956362f362SAndrew Rybchenko VDEV_PCAP_ARGS_FMT, pt->tx_dev); 7966362f362SAndrew Rybchenko if (rte_eal_hotplug_add("vdev", vdev_name, 7976362f362SAndrew Rybchenko vdev_args) < 0) { 7981c4466cbSReshma Pattan cleanup_rings(); 799caa70282SReshma Pattan rte_exit(EXIT_FAILURE, 800caa70282SReshma Pattan "vdev creation failed\n"); 8011c4466cbSReshma Pattan } 8026362f362SAndrew Rybchenko if (rte_eth_dev_get_port_by_name(vdev_name, 8036362f362SAndrew Rybchenko &portid) != 0) { 8046362f362SAndrew Rybchenko rte_eal_hotplug_remove("vdev", vdev_name); 8056362f362SAndrew Rybchenko cleanup_rings(); 8066362f362SAndrew Rybchenko rte_exit(EXIT_FAILURE, 8076362f362SAndrew Rybchenko "cannot find added vdev %s:%s:%d\n", 8086362f362SAndrew Rybchenko vdev_name, __func__, __LINE__); 8096362f362SAndrew Rybchenko } 810caa70282SReshma Pattan pt->tx_vdev_id = portid; 811caa70282SReshma Pattan 812caa70282SReshma Pattan /* configure vdev */ 813caa70282SReshma Pattan configure_vdev(pt->tx_vdev_id); 814caa70282SReshma Pattan } 815caa70282SReshma Pattan } 816caa70282SReshma Pattan } 817caa70282SReshma Pattan 818caa70282SReshma Pattan static void 819caa70282SReshma Pattan enable_pdump(void) 820caa70282SReshma Pattan { 821caa70282SReshma Pattan int i; 822caa70282SReshma Pattan struct pdump_tuples *pt; 823caa70282SReshma Pattan int ret = 0, ret1 = 0; 824caa70282SReshma Pattan 825caa70282SReshma Pattan for (i = 0; i < num_tuples; i++) { 826caa70282SReshma Pattan pt = &pdump_t[i]; 827caa70282SReshma Pattan if (pt->dir == RTE_PDUMP_FLAG_RXTX) { 828caa70282SReshma Pattan if (pt->dump_by_type == DEVICE_ID) { 829caa70282SReshma Pattan ret = rte_pdump_enable_by_deviceid( 830caa70282SReshma Pattan pt->device_id, 831caa70282SReshma Pattan pt->queue, 832caa70282SReshma Pattan RTE_PDUMP_FLAG_RX, 833caa70282SReshma Pattan pt->rx_ring, 834caa70282SReshma Pattan pt->mp, NULL); 835a5f51527SReshma Pattan ret1 = rte_pdump_enable_by_deviceid( 836caa70282SReshma Pattan pt->device_id, 837caa70282SReshma Pattan pt->queue, 838caa70282SReshma Pattan RTE_PDUMP_FLAG_TX, 839caa70282SReshma Pattan pt->tx_ring, 840caa70282SReshma Pattan pt->mp, NULL); 841caa70282SReshma Pattan } else if (pt->dump_by_type == PORT_ID) { 842caa70282SReshma Pattan ret = rte_pdump_enable(pt->port, pt->queue, 843caa70282SReshma Pattan RTE_PDUMP_FLAG_RX, 844caa70282SReshma Pattan pt->rx_ring, pt->mp, NULL); 845caa70282SReshma Pattan ret1 = rte_pdump_enable(pt->port, pt->queue, 846caa70282SReshma Pattan RTE_PDUMP_FLAG_TX, 847caa70282SReshma Pattan pt->tx_ring, pt->mp, NULL); 848caa70282SReshma Pattan } 849caa70282SReshma Pattan } else if (pt->dir == RTE_PDUMP_FLAG_RX) { 850caa70282SReshma Pattan if (pt->dump_by_type == DEVICE_ID) 851caa70282SReshma Pattan ret = rte_pdump_enable_by_deviceid( 852caa70282SReshma Pattan pt->device_id, 853caa70282SReshma Pattan pt->queue, 854caa70282SReshma Pattan pt->dir, pt->rx_ring, 855caa70282SReshma Pattan pt->mp, NULL); 856caa70282SReshma Pattan else if (pt->dump_by_type == PORT_ID) 857caa70282SReshma Pattan ret = rte_pdump_enable(pt->port, pt->queue, 858caa70282SReshma Pattan pt->dir, 859caa70282SReshma Pattan pt->rx_ring, pt->mp, NULL); 860caa70282SReshma Pattan } else if (pt->dir == RTE_PDUMP_FLAG_TX) { 861caa70282SReshma Pattan if (pt->dump_by_type == DEVICE_ID) 862caa70282SReshma Pattan ret = rte_pdump_enable_by_deviceid( 863caa70282SReshma Pattan pt->device_id, 864caa70282SReshma Pattan pt->queue, 865caa70282SReshma Pattan pt->dir, 866caa70282SReshma Pattan pt->tx_ring, pt->mp, NULL); 867caa70282SReshma Pattan else if (pt->dump_by_type == PORT_ID) 868caa70282SReshma Pattan ret = rte_pdump_enable(pt->port, pt->queue, 869caa70282SReshma Pattan pt->dir, 870caa70282SReshma Pattan pt->tx_ring, pt->mp, NULL); 871caa70282SReshma Pattan } 872caa70282SReshma Pattan if (ret < 0 || ret1 < 0) { 873caa70282SReshma Pattan cleanup_pdump_resources(); 874caa70282SReshma Pattan rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno)); 875caa70282SReshma Pattan } 876caa70282SReshma Pattan } 877caa70282SReshma Pattan } 878caa70282SReshma Pattan 879caa70282SReshma Pattan static inline void 880b2854d53SVipin Varghese pdump_packets(struct pdump_tuples *pt) 881b2854d53SVipin Varghese { 882b2854d53SVipin Varghese if (pt->dir & RTE_PDUMP_FLAG_RX) 883b2854d53SVipin Varghese pdump_rxtx(pt->rx_ring, pt->rx_vdev_id, &pt->stats); 884b2854d53SVipin Varghese if (pt->dir & RTE_PDUMP_FLAG_TX) 885b2854d53SVipin Varghese pdump_rxtx(pt->tx_ring, pt->tx_vdev_id, &pt->stats); 886b2854d53SVipin Varghese } 887b2854d53SVipin Varghese 888b2854d53SVipin Varghese static int 889b2854d53SVipin Varghese dump_packets_core(void *arg) 890b2854d53SVipin Varghese { 891b2854d53SVipin Varghese struct pdump_tuples *pt = (struct pdump_tuples *) arg; 892b2854d53SVipin Varghese 893b2854d53SVipin Varghese printf(" core (%u); port %u device (%s) queue %u\n", 894b2854d53SVipin Varghese rte_lcore_id(), pt->port, pt->device_id, pt->queue); 895b2854d53SVipin Varghese fflush(stdout); 896b2854d53SVipin Varghese 897b2854d53SVipin Varghese while (!quit_signal) 898b2854d53SVipin Varghese pdump_packets(pt); 899b2854d53SVipin Varghese 900b2854d53SVipin Varghese return 0; 901b2854d53SVipin Varghese } 902b2854d53SVipin Varghese 9033ee04ebcSReshma Pattan static unsigned int 9043ee04ebcSReshma Pattan get_next_core(unsigned int lcore) 9053ee04ebcSReshma Pattan { 9063ee04ebcSReshma Pattan lcore = rte_get_next_lcore(lcore, 1, 0); 9073ee04ebcSReshma Pattan if (lcore == RTE_MAX_LCORE) 9083ee04ebcSReshma Pattan rte_exit(EXIT_FAILURE, 9093ee04ebcSReshma Pattan "Max core limit %u reached for packet capture", lcore); 9103ee04ebcSReshma Pattan return lcore; 9113ee04ebcSReshma Pattan } 9123ee04ebcSReshma Pattan 913b2854d53SVipin Varghese static inline void 914caa70282SReshma Pattan dump_packets(void) 915caa70282SReshma Pattan { 916caa70282SReshma Pattan int i; 9173ee04ebcSReshma Pattan unsigned int lcore_id = 0; 918b2854d53SVipin Varghese 9198751ab53SStephen Hemminger if (num_tuples == 0) 9208751ab53SStephen Hemminger rte_exit(EXIT_FAILURE, "No device specified for capture\n"); 9218751ab53SStephen Hemminger 922b2854d53SVipin Varghese if (!multiple_core_capture) { 923b2854d53SVipin Varghese printf(" core (%u), capture for (%d) tuples\n", 924b2854d53SVipin Varghese rte_lcore_id(), num_tuples); 925b2854d53SVipin Varghese 926b2854d53SVipin Varghese for (i = 0; i < num_tuples; i++) 927b2854d53SVipin Varghese printf(" - port %u device (%s) queue %u\n", 928b2854d53SVipin Varghese pdump_t[i].port, 929b2854d53SVipin Varghese pdump_t[i].device_id, 930b2854d53SVipin Varghese pdump_t[i].queue); 931caa70282SReshma Pattan 932caa70282SReshma Pattan while (!quit_signal) { 933b2854d53SVipin Varghese for (i = 0; i < num_tuples; i++) 934b2854d53SVipin Varghese pdump_packets(&pdump_t[i]); 935b2854d53SVipin Varghese } 936b2854d53SVipin Varghese 937b2854d53SVipin Varghese return; 938b2854d53SVipin Varghese } 939b2854d53SVipin Varghese 940b2854d53SVipin Varghese /* check if there enough core */ 941b2854d53SVipin Varghese if ((uint32_t)num_tuples >= rte_lcore_count()) { 942b2854d53SVipin Varghese printf("Insufficient cores to run parallel!\n"); 943b2854d53SVipin Varghese return; 944b2854d53SVipin Varghese } 945b2854d53SVipin Varghese 9463ee04ebcSReshma Pattan lcore_id = get_next_core(lcore_id); 947b2854d53SVipin Varghese 948caa70282SReshma Pattan for (i = 0; i < num_tuples; i++) { 949b2854d53SVipin Varghese rte_eal_remote_launch(dump_packets_core, 950b2854d53SVipin Varghese &pdump_t[i], lcore_id); 9513ee04ebcSReshma Pattan lcore_id = get_next_core(lcore_id); 952b2854d53SVipin Varghese 953b2854d53SVipin Varghese if (rte_eal_wait_lcore(lcore_id) < 0) 954b2854d53SVipin Varghese rte_exit(EXIT_FAILURE, "failed to wait\n"); 955caa70282SReshma Pattan } 956b2854d53SVipin Varghese 957cb056611SStephen Hemminger /* main core */ 958b2854d53SVipin Varghese while (!quit_signal) 959b2854d53SVipin Varghese ; 960caa70282SReshma Pattan } 961caa70282SReshma Pattan 962a99a311bSSuanming Mou static void 963a99a311bSSuanming Mou enable_primary_monitor(void) 964a99a311bSSuanming Mou { 965a99a311bSSuanming Mou int ret; 966a99a311bSSuanming Mou 967a99a311bSSuanming Mou /* Once primary exits, so will pdump. */ 968a99a311bSSuanming Mou ret = rte_eal_alarm_set(MONITOR_INTERVAL, monitor_primary, NULL); 969a99a311bSSuanming Mou if (ret < 0) 970a99a311bSSuanming Mou printf("Fail to enable monitor:%d\n", ret); 971a99a311bSSuanming Mou } 972a99a311bSSuanming Mou 973caa70282SReshma Pattan int 974caa70282SReshma Pattan main(int argc, char **argv) 975caa70282SReshma Pattan { 976*e1253df6SStephen Hemminger struct sigaction action = { 977*e1253df6SStephen Hemminger .sa_flags = SA_RESTART, 978*e1253df6SStephen Hemminger .sa_handler = signal_handler, 979*e1253df6SStephen Hemminger }; 980*e1253df6SStephen Hemminger struct sigaction origaction; 981caa70282SReshma Pattan int diag; 982caa70282SReshma Pattan int ret; 983caa70282SReshma Pattan int i; 984caa70282SReshma Pattan 985caa70282SReshma Pattan char n_flag[] = "-n4"; 986caa70282SReshma Pattan char mp_flag[] = "--proc-type=secondary"; 987e442df31SVipin Varghese char *argp[argc + 2]; 988caa70282SReshma Pattan 989*e1253df6SStephen Hemminger /* catch ctrl-c so we can cleanup on exit */ 990*e1253df6SStephen Hemminger sigemptyset(&action.sa_mask); 991*e1253df6SStephen Hemminger sigaction(SIGTERM, &action, NULL); 992*e1253df6SStephen Hemminger sigaction(SIGINT, &action, NULL); 993*e1253df6SStephen Hemminger sigaction(SIGPIPE, &action, NULL); 994*e1253df6SStephen Hemminger sigaction(SIGHUP, NULL, &origaction); 995*e1253df6SStephen Hemminger if (origaction.sa_handler == SIG_DFL) 996*e1253df6SStephen Hemminger sigaction(SIGHUP, &action, NULL); 997caa70282SReshma Pattan 998caa70282SReshma Pattan argp[0] = argv[0]; 999e442df31SVipin Varghese argp[1] = n_flag; 1000e442df31SVipin Varghese argp[2] = mp_flag; 1001caa70282SReshma Pattan 1002caa70282SReshma Pattan for (i = 1; i < argc; i++) 1003e442df31SVipin Varghese argp[i + 2] = argv[i]; 1004caa70282SReshma Pattan 1005e442df31SVipin Varghese argc += 2; 1006caa70282SReshma Pattan 1007caa70282SReshma Pattan diag = rte_eal_init(argc, argp); 1008caa70282SReshma Pattan if (diag < 0) 1009caa70282SReshma Pattan rte_panic("Cannot init EAL\n"); 1010caa70282SReshma Pattan 10114dbfce05SVipin Varghese if (rte_eth_dev_count_avail() == 0) 10124dbfce05SVipin Varghese rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n"); 10134dbfce05SVipin Varghese 1014caa70282SReshma Pattan argc -= diag; 1015e442df31SVipin Varghese argv += (diag - 2); 1016caa70282SReshma Pattan 1017caa70282SReshma Pattan /* parse app arguments */ 1018caa70282SReshma Pattan if (argc > 1) { 1019caa70282SReshma Pattan ret = launch_args_parse(argc, argv, argp[0]); 1020caa70282SReshma Pattan if (ret < 0) 1021caa70282SReshma Pattan rte_exit(EXIT_FAILURE, "Invalid argument\n"); 1022caa70282SReshma Pattan } 1023caa70282SReshma Pattan 1024caa70282SReshma Pattan /* create mempool, ring and vdevs info */ 1025caa70282SReshma Pattan create_mp_ring_vdev(); 1026caa70282SReshma Pattan enable_pdump(); 1027a99a311bSSuanming Mou enable_primary_monitor(); 1028caa70282SReshma Pattan dump_packets(); 1029caa70282SReshma Pattan 1030a99a311bSSuanming Mou disable_primary_monitor(); 1031caa70282SReshma Pattan cleanup_pdump_resources(); 1032caa70282SReshma Pattan /* dump debug stats */ 1033caa70282SReshma Pattan print_pdump_stats(); 1034caa70282SReshma Pattan 1035295d7109SHarry van Haaren ret = rte_eal_cleanup(); 1036295d7109SHarry van Haaren if (ret) 1037295d7109SHarry van Haaren printf("Error from rte_eal_cleanup(), %d\n", ret); 1038295d7109SHarry van Haaren 1039caa70282SReshma Pattan return 0; 1040caa70282SReshma Pattan } 1041