diff options
| author | songyanchao <[email protected]> | 2023-03-02 08:04:21 +0000 |
|---|---|---|
| committer | songyanchao <[email protected]> | 2023-03-02 08:04:21 +0000 |
| commit | 0c6d487e64f64a19dc3ccf14afdcc6c1ecad497e (patch) | |
| tree | 58dc919815a145775860020f2fb95e2d0664765b /tools/tcpdump | |
| parent | 5cae3ca875f7fd8b3f7885bd1f44e274a571f0f1 (diff) | |
✨ feat(DPISDN-2): 优化 mrpdump 适配 phydev 设备
优化 mrpdump 适配 phydev 设备
Diffstat (limited to 'tools/tcpdump')
| -rw-r--r-- | tools/tcpdump/pcapng_proto.h | 142 | ||||
| -rw-r--r-- | tools/tcpdump/pdump.c | 992 |
2 files changed, 629 insertions, 505 deletions
diff --git a/tools/tcpdump/pcapng_proto.h b/tools/tcpdump/pcapng_proto.h new file mode 100644 index 0000000..353af3b --- /dev/null +++ b/tools/tcpdump/pcapng_proto.h @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019-2020 Microsoft Corporation + * + * PCAP Next Generation Capture File writer + * + * See: https://github.com/pcapng/pcapng/ for the file format. + */ + +enum pcapng_block_types +{ + PCAPNG_INTERFACE_BLOCK = 1, + PCAPNG_PACKET_BLOCK, /* Obsolete */ + PCAPNG_SIMPLE_PACKET_BLOCK, + PCAPNG_NAME_RESOLUTION_BLOCK, + PCAPNG_INTERFACE_STATS_BLOCK, + PCAPNG_ENHANCED_PACKET_BLOCK, + + PCAPNG_SECTION_BLOCK = 0x0A0D0D0A, +}; + +struct pcapng_option +{ + uint16_t code; + uint16_t length; + uint8_t data[]; +}; + +#define PCAPNG_BYTE_ORDER_MAGIC 0x1A2B3C4D +#define PCAPNG_MAJOR_VERS 1 +#define PCAPNG_MINOR_VERS 0 + +enum pcapng_opt +{ + PCAPNG_OPT_END = 0, + PCAPNG_OPT_COMMENT = 1, +}; + +struct pcapng_section_header +{ + uint32_t block_type; + uint32_t block_length; + uint32_t byte_order_magic; + uint16_t major_version; + uint16_t minor_version; + uint64_t section_length; +}; + +enum pcapng_section_opt +{ + PCAPNG_SHB_HARDWARE = 2, + PCAPNG_SHB_OS = 3, + PCAPNG_SHB_USERAPPL = 4, +}; + +struct pcapng_interface_block +{ + uint32_t block_type; /* 1 */ + uint32_t block_length; + uint16_t link_type; + uint16_t reserved; + uint32_t snap_len; +}; + +enum pcapng_interface_options +{ + PCAPNG_IFB_NAME = 2, + PCAPNG_IFB_DESCRIPTION, + PCAPNG_IFB_IPV4ADDR, + PCAPNG_IFB_IPV6ADDR, + PCAPNG_IFB_MACADDR, + PCAPNG_IFB_EUIADDR, + PCAPNG_IFB_SPEED, + PCAPNG_IFB_TSRESOL, + PCAPNG_IFB_TZONE, + PCAPNG_IFB_FILTER, + PCAPNG_IFB_OS, + PCAPNG_IFB_FCSLEN, + PCAPNG_IFB_TSOFFSET, + PCAPNG_IFB_HARDWARE, +}; + +struct pcapng_enhance_packet_block +{ + uint32_t block_type; /* 6 */ + uint32_t block_length; + uint32_t interface_id; + uint32_t timestamp_hi; + uint32_t timestamp_lo; + uint32_t capture_length; + uint32_t original_length; +}; + +/* Flags values */ +#define PCAPNG_IFB_INBOUND 0b01 +#define PCAPNG_IFB_OUTBOUND 0b10 + +enum pcapng_epb_options +{ + PCAPNG_EPB_FLAGS = 2, + PCAPNG_EPB_HASH, + PCAPNG_EPB_DROPCOUNT, + PCAPNG_EPB_PACKETID, + PCAPNG_EPB_QUEUE, + PCAPNG_EPB_VERDICT, +}; + +enum pcapng_epb_hash +{ + PCAPNG_HASH_2COMP = 0, + PCAPNG_HASH_XOR, + PCAPNG_HASH_CRC32, + PCAPNG_HASH_MD5, + PCAPNG_HASH_SHA1, + PCAPNG_HASH_TOEPLITZ, +}; + +struct pcapng_simple_packet +{ + uint32_t block_type; /* 3 */ + uint32_t block_length; + uint32_t packet_length; +}; + +struct pcapng_statistics +{ + uint32_t block_type; /* 5 */ + uint32_t block_length; + uint32_t interface_id; + uint32_t timestamp_hi; + uint32_t timestamp_lo; +}; + +enum pcapng_isb_options +{ + PCAPNG_ISB_STARTTIME = 2, + PCAPNG_ISB_ENDTIME, + PCAPNG_ISB_IFRECV, + PCAPNG_ISB_IFDROP, + PCAPNG_ISB_FILTERACCEPT, + PCAPNG_ISB_OSDROP, + PCAPNG_ISB_USRDELIV, +}; diff --git a/tools/tcpdump/pdump.c b/tools/tcpdump/pdump.c index 1ea4edb..93ba601 100644 --- a/tools/tcpdump/pdump.c +++ b/tools/tcpdump/pdump.c @@ -30,37 +30,43 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -#include <stdio.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> -#include <stdlib.h> +#include <fcntl.h> #include <getopt.h> +#include <inttypes.h> +#include <net/if.h> #include <signal.h> #include <stdbool.h> -#include <net/if.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/utsname.h> +#include <unistd.h> -#include <rte_eal.h> +#include "common.h" +#include "mr_pcapng_proto.h" +#include <mrb_define.h> +#include <pcap/bpf.h> +#include <pcap/pcap.h> +#include <rte_branch_prediction.h> #include <rte_common.h> #include <rte_debug.h> -#include <rte_ethdev.h> -#include <rte_memory.h> -#include <rte_lcore.h> -#include <rte_branch_prediction.h> -#include <rte_errno.h> #include <rte_dev.h> +#include <rte_eal.h> +#include <rte_errno.h> +#include <rte_ethdev.h> #include <rte_kvargs.h> +#include <rte_lcore.h> +#include <rte_memory.h> #include <rte_mempool.h> -#include <rte_ring.h> +#include <rte_pcapng.h> #include <rte_pdump.h> -#include <pcap/pcap.h> -#include <pcap/bpf.h> -#include <sc_common.h> +#include <rte_ring.h> +#include <rte_time.h> +#include <sc_pdump.h> #define CMD_LINE_OPT_PDUMP "pdump" -#define PDUMP_PORT_ARG "port" -#define PDUMP_PCI_ARG "device_id" +#define PDUMP_DEV_ARG "dev" #define PDUMP_QUEUE_ARG "queue" #define PDUMP_RX_ARG "rx" #define PDUMP_TX_ARG "tx" @@ -72,18 +78,9 @@ #define CMD_LINE_OPT_DUMPFILE_PATH "dumpfile-path" #define CMD_LINE_OPT_DUMPFILE_COUNT "dumpfile-count" #define CMD_LINE_OPT_BPF_RULE "bpf-rule" -#define CMD_LINE_OPT_USE_PPI_HEADER "use-ppi-header" #define TX_STREAM_SIZE 64 -#define MP_NAME "pdump_pool_%d" - -#define RX_RING "rx_ring_%d" -#define TX_RING "tx_ring_%d" - -#define RX_STR "rx" -#define TX_STR "tx" - /* Maximum long option length for option parsing. */ #define APP_ARG_TCPDUMP_MAX_TUPLES 54 #define MBUF_POOL_CACHE_SIZE 250 @@ -99,11 +96,11 @@ /* true if x is a power of 2 */ #define POWEROF2(x) ((((x)-1) & (x)) == 0) -enum pdump_en_dis -{ - DISABLE = 1, - ENABLE = 2 -}; +#define METADATA_MAX_SIZE 256 +#define METADATA_INFO \ + " 'dir:%u', 'nf create:%u','link id:%u', 'is ctrlbuf:%u', 'payload offset:%u', 'session id:%lu', 'start " \ + "sid:%u', 'nr sid:%u', 'cur sid:%u', 'sids:[%u],[%u],[%u],[%u],[%u],[%u],[%u],[%u]', 'port_id ingress:%u', " \ + "'port_id egress:%u', 'link db index:%u' " enum pcap_stream { @@ -117,20 +114,13 @@ enum pdump_by DEVICE_ID = 2 }; -const char *valid_pdump_arguments[] = { - PDUMP_PORT_ARG, - PDUMP_PCI_ARG, - PDUMP_QUEUE_ARG, - PDUMP_RX_ARG, - PDUMP_TX_ARG, - PDUMP_RING_SIZE_ARG, - PDUMP_MSIZE_ARG, - PDUMP_NUM_MBUFS_ARG, - NULL}; +const char * valid_pdump_arguments[] = {PDUMP_DEV_ARG, PDUMP_QUEUE_ARG, PDUMP_RX_ARG, PDUMP_TX_ARG, + PDUMP_RING_SIZE_ARG, PDUMP_MSIZE_ARG, PDUMP_NUM_MBUFS_ARG, NULL}; struct pdump_stats { uint64_t dequeue_pkts; + uint64_t rx_pkts; uint64_t tx_pkts; uint64_t freed_pkts; }; @@ -138,8 +128,10 @@ struct pdump_stats struct pdump_tuples { /* cli params */ - uint16_t port; - char *device_id; + uint16_t port_id; + enum mr_dev_driver drv_type; + char dev_symbol[MR_SYMBOL_MAX]; + char * device_id; uint16_t queue; char rx_dev[TX_STREAM_SIZE]; char tx_dev[TX_STREAM_SIZE]; @@ -149,9 +141,9 @@ struct pdump_tuples /* params for library API call */ uint32_t dir; - struct rte_mempool *mp; - struct rte_ring *rx_ring; - struct rte_ring *tx_ring; + struct rte_mempool * mp; + struct rte_ring * rx_ring; + struct rte_ring * tx_ring; /* params for packet dumping */ enum pdump_by dump_by_type; @@ -181,67 +173,55 @@ struct ppi_packetheader uint32_t pph_dlt; // libpcap Data Link Type of the captured packet data. }; -struct ppi_fieldheader +/* For converting TSC cycles to PCAPNG ns format */ +struct pcapng_time { - uint16_t pfh_type; // Type - uint16_t pfh_datalen; // Length of data -}; + uint64_t ns; + uint64_t cycles; +} pcapng_time; int num_tuples; volatile uint8_t quit_signal; static char server_socket_path[PATH_MAX]; static char client_socket_path[PATH_MAX]; -static char dumpfile_path[PATH_MAX] = "dumpfile.pcap"; +static char dumpfile_path[PATH_MAX] = "dumpfile.pcapng"; static bool dumpfile_count_set = false; static unsigned long long dumpfile_count = 0; -static pcap_t *pcap_handle_dead = NULL; static struct bpf_program bpf_prog; -static pcap_dumper_t *pcap_dumper = NULL; static char str_bpf_expr[4096] = {}; -static bool is_str_bpf_expr_set = false; -static bool is_use_ppi_header = false; +static bool is_str_bpf_expr_set = false; /* */ + +/* Pcapng */ +static int pcapng_fd = 0; +static rte_pcapng_t * _pcapng_item = NULL; /**< display usage */ -static void -pdump_usage(const char *prgname) +static void pdump_usage(const char * prgname) { - fprintf(stderr, "usage: %s [EAL options] -- --pdump " - "'(port=<port id> | device_id=<pci id or vdev name>)," - "(queue=<queue_id>)," - "(rx-dev=<iface or pcap file> |" - " tx-dev=<iface or pcap file>," - "[ring-size=<ring size>default:16384]," - "[mbuf-size=<mbuf data size>default:2176]," - "[total-num-mbufs=<number of mbufs>default:65535]'\n" - "[--server-socket-path=<server socket dir>" - "default:/var/run/.dpdk/ (or) ~/.dpdk/]\n" - "[--client-socket-path=<client socket dir>" - "default:/var/run/.dpdk/ (or) ~/.dpdk/]\n" - "[--dumpfile-path=<dumpfile>]" - "default:dumpfile.pcap\n" - "[--bpf-rule=<bpf-rule>]" - "default:<None>\n" - "[--use-ppi-header]", + fprintf(stderr, + "usage: %s [EAL options] -- --pdump " + "'(port_id=<port_id id> | device_id=<pci id or vdev name>)," + "(queue=<queue_id>)," + "(rx-dev=<iface or pcap file> |" + " tx-dev=<iface or pcap file>," + "[ring-size=<ring size>default:16384]," + "[mbuf-size=<mbuf data size>default:2176]," + "[total-num-mbufs=<number of mbufs>default:65535]'\n" + "[--server-socket-path=<server socket dir>" + "default:/var/run/.dpdk/ (or) ~/.dpdk/]\n" + "[--client-socket-path=<client socket dir>" + "default:/var/run/.dpdk/ (or) ~/.dpdk/]\n" + "[--dumpfile-path=<dumpfile>]" + "default:dumpfile.pcap\n" + "[--bpf-rule=<bpf-rule>]" + "default:<None>\n", prgname); } -static int -parse_device_id(const char *key __rte_unused, const char *value, - void *extra_args) -{ - struct pdump_tuples *pt = extra_args; - - pt->device_id = strdup(value); - pt->dump_by_type = DEVICE_ID; - - return 0; -} - -static int -parse_queue(const char *key __rte_unused, const char *value, void *extra_args) +static int parse_queue(const char * key __rte_unused, const char * value, void * extra_args) { unsigned long n; - struct pdump_tuples *pt = extra_args; + struct pdump_tuples * pt = extra_args; if (!strcmp(value, "*")) pt->queue = RTE_PDUMP_ALL_QUEUES; @@ -253,12 +233,11 @@ parse_queue(const char *key __rte_unused, const char *value, void *extra_args) return 0; } -static int -parse_uint_value(const char *key, const char *value, void *extra_args) +static int parse_uint_value(const char * key, const char * value, void * extra_args) { - struct parse_val *v; + struct parse_val * v; unsigned long t; - char *end; + char * end; int ret = 0; errno = 0; @@ -267,15 +246,17 @@ parse_uint_value(const char *key, const char *value, void *extra_args) if (errno != 0 || end[0] != 0 || t < v->min || t > v->max) { - fprintf(stderr, "invalid value:\"%s\" for key:\"%s\", " - "value must be >= %" PRIu64 " and <= %" PRIu64 "\n", + fprintf(stderr, + "invalid value:\"%s\" for key:\"%s\", " + "value must be >= %" PRIu64 " and <= %" PRIu64 "\n", value, key, v->min, v->max); ret = -EINVAL; } if (!strcmp(key, PDUMP_RING_SIZE_ARG) && !POWEROF2(t)) { - fprintf(stderr, "invalid value:\"%s\" for key:\"%s\", " - "value must be power of 2\n", + fprintf(stderr, + "invalid value:\"%s\" for key:\"%s\", " + "value must be power of 2\n", value, key); ret = -EINVAL; } @@ -287,12 +268,19 @@ parse_uint_value(const char *key, const char *value, void *extra_args) return 0; } -static int -parse_pdump(const char *optarg) +static int parse_device_name(const char * key __rte_unused, const char * value, void * extra_args) { - struct rte_kvargs *kvlist; + struct pdump_tuples * pt = &pdump_t[num_tuples]; + memcpy(pt->dev_symbol, strdup(value), sizeof(pt->dev_symbol)); + + return 0; +} + +static int parse_pdump(const char * optarg) +{ + struct rte_kvargs * kvlist; int ret = 0, cnt1, cnt2; - struct pdump_tuples *pt; + struct pdump_tuples * pt; struct parse_val v = {0}; pt = &pdump_t[num_tuples]; @@ -305,34 +293,19 @@ parse_pdump(const char *optarg) return -1; } - /* port/device_id parsing and validation */ - cnt1 = rte_kvargs_count(kvlist, PDUMP_PORT_ARG); - cnt2 = rte_kvargs_count(kvlist, PDUMP_PCI_ARG); - if (!((cnt1 == 1 && cnt2 == 0) || (cnt1 == 0 && cnt2 == 1))) - { - fprintf(stderr, "--pdump=\"%s\": must have either port or " - "device_id argument\n", - optarg); - ret = -1; - goto free_kvlist; - } - else if (cnt1 == 1) + /* port_id/device_id parsing and validation */ + cnt1 = rte_kvargs_count(kvlist, PDUMP_DEV_ARG); + if (cnt1 == 1) { - v.min = 0; - v.max = RTE_MAX_ETHPORTS - 1; - ret = rte_kvargs_process(kvlist, PDUMP_PORT_ARG, - &parse_uint_value, &v); + ret = rte_kvargs_process(kvlist, PDUMP_DEV_ARG, &parse_device_name, NULL); if (ret < 0) goto free_kvlist; - pt->port = (uint16_t)v.val; - pt->dump_by_type = PORT_ID; } - else if (cnt2 == 1) + else { - ret = rte_kvargs_process(kvlist, PDUMP_PCI_ARG, - &parse_device_id, pt); - if (ret < 0) - goto free_kvlist; + fprintf(stderr, "--pdump=\"%s\": must have dev argument\n", optarg); + ret = -1; + goto free_kvlist; } /* queue parsing and validation */ @@ -376,8 +349,7 @@ parse_pdump(const char *optarg) { v.min = 2; v.max = RTE_RING_SZ_MASK - 1; - ret = rte_kvargs_process(kvlist, PDUMP_RING_SIZE_ARG, - &parse_uint_value, &v); + ret = rte_kvargs_process(kvlist, PDUMP_RING_SIZE_ARG, &parse_uint_value, &v); if (ret < 0) goto free_kvlist; pt->ring_size = (uint32_t)v.val; @@ -391,11 +363,10 @@ parse_pdump(const char *optarg) { v.min = 1; v.max = UINT16_MAX; - ret = rte_kvargs_process(kvlist, PDUMP_MSIZE_ARG, - &parse_uint_value, &v); + ret = rte_kvargs_process(kvlist, PDUMP_MSIZE_ARG, &parse_uint_value, &v); if (ret < 0) goto free_kvlist; - //pt->mbuf_data_size = (uint16_t)v.val; + // pt->mbuf_data_size = (uint16_t)v.val; /* Current Only Support Specify 'RTE_MBUF_DEFAULT_BUF_SIZE'*/ pt->mbuf_data_size = RTE_MBUF_DEFAULT_BUF_SIZE; } @@ -408,11 +379,10 @@ parse_pdump(const char *optarg) { v.min = 1025; v.max = UINT16_MAX; - ret = rte_kvargs_process(kvlist, PDUMP_NUM_MBUFS_ARG, - &parse_uint_value, &v); + ret = rte_kvargs_process(kvlist, PDUMP_NUM_MBUFS_ARG, &parse_uint_value, &v); if (ret < 0) goto free_kvlist; - //pt->total_num_mbufs = (uint16_t)v.val; + // pt->total_num_mbufs = (uint16_t)v.val; /* Current Only Support Specify 'MBUFS_PER_POOL'*/ pt->total_num_mbufs = MBUFS_PER_POOL; } @@ -432,34 +402,29 @@ free_kvlist: } /* Parse the argument given in the command line of the application */ -static int -launch_args_parse(int argc, char **argv, char *prgname) +static int launch_args_parse(int argc, char ** argv, char * prgname) { int opt, ret; int option_index; - static struct option long_option[] = { - {"pdump", 1, 0, 0}, - {"server-socket-path", 1, 0, 0}, - {"client-socket-path", 1, 0, 0}, - {"dumpfile-path", 1, 0, 0}, - {"dumpfile-count", 1, 0, 0}, - {"bpf-rule", 1, 0, 0}, - {"use-ppi-header", 0, 0, 0}, - {NULL, 0, 0, 0}}; + static struct option long_option[] = {{"pdump", 1, 0, 0}, + {"server-socket-path", 1, 0, 0}, + {"client-socket-path", 1, 0, 0}, + {"dumpfile-path", 1, 0, 0}, + {"dumpfile-count", 1, 0, 0}, + {"bpf-rule", 1, 0, 0}, + {"use-ppi-header", 0, 0, 0}, + {NULL, 0, 0, 0}}; if (argc == 1) pdump_usage(prgname); /* Parse command line */ - while ((opt = getopt_long(argc, argv, " ", - long_option, &option_index)) != EOF) + while ((opt = getopt_long(argc, argv, " ", long_option, &option_index)) != EOF) { switch (opt) { case 0: - if (!strncmp(long_option[option_index].name, - CMD_LINE_OPT_PDUMP, - sizeof(CMD_LINE_OPT_PDUMP))) + if (!strncmp(long_option[option_index].name, CMD_LINE_OPT_PDUMP, sizeof(CMD_LINE_OPT_PDUMP))) { ret = parse_pdump(optarg); if (ret) @@ -469,56 +434,37 @@ launch_args_parse(int argc, char **argv, char *prgname) } } - if (!strncmp(long_option[option_index].name, - CMD_LINE_OPT_SER_SOCK_PATH, + if (!strncmp(long_option[option_index].name, CMD_LINE_OPT_SER_SOCK_PATH, sizeof(CMD_LINE_OPT_SER_SOCK_PATH))) { - snprintf(server_socket_path, - sizeof(server_socket_path), "%s", - optarg); + snprintf(server_socket_path, sizeof(server_socket_path), "%s", optarg); } - if (!strncmp(long_option[option_index].name, - CMD_LINE_OPT_CLI_SOCK_PATH, + if (!strncmp(long_option[option_index].name, CMD_LINE_OPT_CLI_SOCK_PATH, sizeof(CMD_LINE_OPT_CLI_SOCK_PATH))) { - snprintf(client_socket_path, - sizeof(client_socket_path), "%s", - optarg); + snprintf(client_socket_path, sizeof(client_socket_path), "%s", optarg); } - if (!strncmp(long_option[option_index].name, - CMD_LINE_OPT_DUMPFILE_PATH, + if (!strncmp(long_option[option_index].name, CMD_LINE_OPT_DUMPFILE_PATH, sizeof(CMD_LINE_OPT_DUMPFILE_PATH))) { - snprintf(dumpfile_path, - sizeof(dumpfile_path), "%s", - optarg); + snprintf(dumpfile_path, sizeof(dumpfile_path), "%s", optarg); } - if (!strncmp(long_option[option_index].name, - CMD_LINE_OPT_DUMPFILE_COUNT, + if (!strncmp(long_option[option_index].name, CMD_LINE_OPT_DUMPFILE_COUNT, sizeof(CMD_LINE_OPT_DUMPFILE_COUNT))) { dumpfile_count_set = true; sscanf(optarg, "%llu", &dumpfile_count); } - if (!strncmp(long_option[option_index].name, - CMD_LINE_OPT_BPF_RULE, - sizeof(CMD_LINE_OPT_BPF_RULE))) + if (!strncmp(long_option[option_index].name, CMD_LINE_OPT_BPF_RULE, sizeof(CMD_LINE_OPT_BPF_RULE))) { is_str_bpf_expr_set = true; snprintf(str_bpf_expr, sizeof(str_bpf_expr), "%s", optarg); } - if (!strncmp(long_option[option_index].name, - CMD_LINE_OPT_USE_PPI_HEADER, - sizeof(CMD_LINE_OPT_USE_PPI_HEADER))) - { - is_use_ppi_header = true; - } - break; default: @@ -530,149 +476,173 @@ launch_args_parse(int argc, char **argv, char *prgname) return 0; } -static void -print_pdump_stats(void) +static void print_pdump_stats(void) { int i; - struct pdump_tuples *pt; + struct pdump_tuples * pt; for (i = 0; i < num_tuples; i++) { fprintf(stderr, "##### PDUMP DEBUG STATS #####\n"); pt = &pdump_t[i]; - fprintf(stderr, " -packets dequeued: %" PRIu64 "\n", - pt->stats.dequeue_pkts); - fprintf(stderr, " -packets transmitted to vdev: %" PRIu64 "\n", - pt->stats.tx_pkts); - fprintf(stderr, " -packets freed: %" PRIu64 "\n", - pt->stats.freed_pkts); + fprintf(stderr, " -packets dequeued: %" PRIu64 "\n", pt->stats.dequeue_pkts); + fprintf(stderr, " -packets rx: %" PRIu64 "\n", pt->stats.rx_pkts); + fprintf(stderr, " -packets tx: %" PRIu64 "\n", pt->stats.tx_pkts); + fprintf(stderr, " -packets freed: %" PRIu64 "\n", pt->stats.freed_pkts); } } -static inline void -disable_pdump(struct pdump_tuples *pt) +/* length of option including padding */ +static uint16_t pcapng_optlen(uint16_t len) { - if (pt->dump_by_type == DEVICE_ID) - rte_pdump_disable_by_deviceid(pt->device_id, pt->queue, - pt->dir); - else if (pt->dump_by_type == PORT_ID) - rte_pdump_disable(pt->port, pt->queue, pt->dir); + return RTE_ALIGN(sizeof(struct pcapng_option) + len, sizeof(uint32_t)); } -static char ppi_packet_buffer[128 * 1024 * 1024]; - -struct pfh_data +static struct pcapng_option * pcapng_add_option(struct pcapng_option * popt, uint16_t code, const void * data, + uint16_t len) { - uint16_t vlan_tci; - uint16_t vlan_tci_outer; -}; + popt->code = code; + popt->length = len; + memcpy(popt->data, data, len); -static int ppi_packet_encap(char *buf, unsigned buflen, struct rte_mbuf *mbuf, const char *pkt, unsigned int pktlen) + return (struct pcapng_option *)((uint8_t *)popt + pcapng_optlen(len)); +} + +/* Count how many segments are in this array of mbufs */ +static unsigned int mbuf_burst_segs(struct rte_mbuf * pkts[], unsigned int n) { - char *buf_to_write = buf; - unsigned int write_len = 0; - - /* SECTION A */ - struct ppi_packetheader *ppi_hdr = (struct ppi_packetheader *)buf_to_write; - /* PPI version must be zero */ - ppi_hdr->pph_version = 0; - /* Flags is zero, non-aligned */ - ppi_hdr->pph_flags = 0; - /* Length of entire message, including this header and TLV payload */ - ppi_hdr->pph_len = sizeof(struct ppi_packetheader) + sizeof(struct ppi_fieldheader) + sizeof(struct pfh_data); - /* DLT */ - ppi_hdr->pph_dlt = DLT_EN10MB; - - buf_to_write += sizeof(struct ppi_packetheader); - write_len += sizeof(struct ppi_packetheader); - - /* SECTION B */ - struct ppi_fieldheader *field_hdr = (struct ppi_fieldheader *)buf_to_write; - field_hdr->pfh_type = 30000; - field_hdr->pfh_datalen = sizeof(struct pfh_data); - - buf_to_write += sizeof(struct ppi_fieldheader); - write_len += sizeof(struct ppi_fieldheader); - - /* SECTION C */ - struct pfh_data *phf_data = (struct pfh_data *)buf_to_write; - - if (mbuf->ol_flags & RTE_MBUF_F_RX_VLAN || mbuf->ol_flags & RTE_MBUF_F_TX_VLAN) + unsigned int i, iovcnt; + + for (iovcnt = 0, i = 0; i < n; i++) { - phf_data->vlan_tci = mbuf->vlan_tci; + const struct rte_mbuf * m = pkts[i]; + + __rte_mbuf_sanity_check(m, 1); + + iovcnt += m->nb_segs; } - else + return iovcnt; +} + +/* PCAPNG timestamps are in nanoseconds */ +static uint64_t pcapng_tsc_to_ns(uint64_t cycles) +{ + uint64_t delta; + + delta = cycles - pcapng_time.cycles; + return pcapng_time.ns + (delta * NSEC_PER_SEC) / rte_get_tsc_hz(); +} + +int mr_pcapng_set_opt(struct rte_mbuf * mbuf, uint16_t port_id) +{ + /* pad the packet to 32 bit boundary */ + uint32_t data_len = rte_pktmbuf_data_len(mbuf); + uint32_t padding = RTE_ALIGN(data_len, sizeof(uint32_t)) - data_len; + if (padding > 0) { - phf_data->vlan_tci = 0; + void * tail = rte_pktmbuf_append(mbuf, padding); + if (tail == NULL) + { + printf("Mbuf padding err.\n"); + return RT_ERR; + } + + memset(tail, 0, padding); } - if (mbuf->ol_flags & RTE_MBUF_F_RX_QINQ || - mbuf->tx_offload & RTE_MBUF_F_TX_QINQ) + /* reserve trailing options and block length */ + char str_metadata[METADATA_MAX_SIZE] = {}; + struct mrb_metadata * mrb_metadata = mrbuf_cz_data(mbuf, MR_NODE_CTRLZONE_ID); + sprintf(str_metadata, METADATA_INFO, mrb_metadata->dir, mrb_metadata->packet_create_from_nf, mrb_metadata->link_id, + mrb_metadata->is_ctrlbuf, mrb_metadata->payload_offset, mrb_metadata->session_id, mrb_metadata->start_sid, + mrb_metadata->nr_sid, mrb_metadata->cur_sid, mrb_metadata->sids[0], mrb_metadata->sids[1], + mrb_metadata->sids[2], mrb_metadata->sids[3], mrb_metadata->sids[4], mrb_metadata->sids[5], + mrb_metadata->sids[6], mrb_metadata->sids[7], mrb_metadata->port_ingress, mrb_metadata->port_egress, + mrb_metadata->link_db_index); + const uint16_t optlen = pcapng_optlen(strlen(str_metadata)); + struct pcapng_option * opt = (struct pcapng_option *)rte_pktmbuf_append(mbuf, optlen + sizeof(uint32_t)); + if (unlikely(opt == NULL)) { - phf_data->vlan_tci_outer = mbuf->vlan_tci_outer; + printf("Mbuf append opt err.\n"); + return RT_ERR; } - else + + /* Note: END_OPT necessary here. Wireshark doesn't do it. */ + /* Add PCAPNG packet header */ + struct pcapng_enhance_packet_block * epb = + (struct pcapng_enhance_packet_block *)rte_pktmbuf_prepend(mbuf, sizeof(*epb)); + if (unlikely(epb == NULL)) { - phf_data->vlan_tci_outer = 0; + printf("Mbuf prepend epb err.\n"); + return RT_ERR; } - buf_to_write += sizeof(struct pfh_data); - write_len += sizeof(struct pfh_data); + uint64_t ns = pcapng_tsc_to_ns(rte_get_tsc_cycles()); + epb->block_type = PCAPNG_ENHANCED_PACKET_BLOCK; + epb->block_length = rte_pktmbuf_data_len(mbuf); + epb->interface_id = port_id; + epb->timestamp_hi = ns >> 32; + epb->timestamp_lo = (uint32_t)ns; + epb->capture_length = data_len; + epb->original_length = data_len; - /* SECTION D */ - rte_memcpy(buf_to_write, pkt, pktlen); - buf_to_write += pktlen; - write_len += pktlen; + /* set trailer of block length */ + struct pcapng_option * opt_new = pcapng_add_option(opt, PCAPNG_OPT_COMMENT, str_metadata, strlen(str_metadata)); + *(uint32_t *)opt_new = epb->block_length; - return write_len; + return RT_SUCCESS; } -static inline void -pdump_rxtx(struct rte_ring *ring, uint16_t vdev_id, struct pdump_stats *stats) +static inline void pdump_rxtx(uint16_t port_id, struct rte_ring * ring, struct pdump_stats * stats, uint32_t flags) { - /* write input packets of port to vdev for pdump */ - struct rte_mbuf *rxtx_bufs[BURST_SIZE]; + /* write input packets of port_id to vdev for pdump */ + struct rte_mbuf * rxtx_bufs[BURST_SIZE]; + uint64_t * rxtx_pkts = NULL; + + if (flags == RTE_PDUMP_FLAG_RX) + rxtx_pkts = &stats->rx_pkts; + else + rxtx_pkts = &stats->tx_pkts; /* first dequeue packets from ring of primary process */ const uint16_t nb_in_deq = rte_ring_dequeue_burst(ring, (void *)rxtx_bufs, BURST_SIZE, NULL); stats->dequeue_pkts += nb_in_deq; + int iovcnt = mbuf_burst_segs(rxtx_bufs, nb_in_deq); + struct iovec iov[iovcnt]; + unsigned int cnt = 0; for (int i = 0; i < nb_in_deq; i++) { - const char *pkt_ptr = rte_pktmbuf_mtod(rxtx_bufs[i], const char *); - unsigned int pkt_len = rte_pktmbuf_data_len(rxtx_bufs[i]); + struct rte_mbuf * mbuf = rxtx_bufs[i]; if (is_str_bpf_expr_set) { + const char * pkt_ptr = rte_pktmbuf_mtod(mbuf, const char *); + unsigned int pkt_len = rte_pktmbuf_data_len(mbuf); if (bpf_filter(bpf_prog.bf_insns, (const u_char *)pkt_ptr, pkt_len, pkt_len) == 0 || pkt_len > 65535) continue; } - struct pcap_pkthdr pcap_pkthdr; - gettimeofday(&pcap_pkthdr.ts, NULL); - const char *to_write_ptr = NULL; - - if (is_use_ppi_header) + int ret = mr_pcapng_set_opt(mbuf, port_id); + if (ret == RT_SUCCESS) { - int ppi_pktlen = ppi_packet_encap(ppi_packet_buffer, sizeof(ppi_packet_buffer), - rxtx_bufs[i], pkt_ptr, pkt_len); + do + { + iov[cnt].iov_base = rte_pktmbuf_mtod(mbuf, void *); + iov[cnt].iov_len = rte_pktmbuf_data_len(mbuf); + ++cnt; + } while ((mbuf = mbuf->next)); - pcap_pkthdr.caplen = ppi_pktlen; - pcap_pkthdr.len = ppi_pktlen; - to_write_ptr = ppi_packet_buffer; - } - else - { - pcap_pkthdr.caplen = pkt_len; - pcap_pkthdr.len = pkt_len; - to_write_ptr = pkt_ptr; + *rxtx_pkts += 1; } + } - /* 写DUMPFILE */ - pcap_dump((u_char *)pcap_dumper, &pcap_pkthdr, (const u_char *)to_write_ptr); - stats->tx_pkts += 1; + if (!is_str_bpf_expr_set) + { + writev(pcapng_fd, iov, iovcnt); } + /* Pkt free */ for (int i = 0; i < nb_in_deq; i++) { rte_pktmbuf_free(rxtx_bufs[i]); @@ -682,258 +652,277 @@ pdump_rxtx(struct rte_ring *ring, uint16_t vdev_id, struct pdump_stats *stats) return; } -static void -free_ring_data(struct rte_ring *ring, uint16_t vdev_id, - struct pdump_stats *stats) -{ - while (rte_ring_count(ring)) - pdump_rxtx(ring, vdev_id, stats); -} - -static void -cleanup_rings(void) -{ - int i; - struct pdump_tuples *pt; - - for (i = 0; i < num_tuples; i++) - { - pt = &pdump_t[i]; - - if (pt->device_id) - free(pt->device_id); - - /* free the rings */ - if (pt->rx_ring) - rte_ring_free(pt->rx_ring); - if (pt->tx_ring) - rte_ring_free(pt->tx_ring); - } -} - -static void -cleanup_pdump_resources(void) +static void signal_handler(int sig_num) { - int i; - struct pdump_tuples *pt; - - /* disable pdump and free the pdump_tuple resources */ - for (i = 0; i < num_tuples; i++) + if (sig_num == SIGINT) { - pt = &pdump_t[i]; - - /* remove callbacks */ - disable_pdump(pt); - - /* - * transmit rest of the enqueued packets of the rings on to - * the vdev, in order to release mbufs to the mepool. - **/ - if (pt->dir & RTE_PDUMP_FLAG_RX) - free_ring_data(pt->rx_ring, pt->rx_vdev_id, &pt->stats); - if (pt->dir & RTE_PDUMP_FLAG_TX) - free_ring_data(pt->tx_ring, pt->tx_vdev_id, &pt->stats); + fprintf(stderr, "\n\nSignal %d received, preparing to exit...\n", sig_num); + quit_signal = 1; } - cleanup_rings(); } -static void -signal_handler(int sig_num) +static void err_value_dump(int32_t err_value) { - if (sig_num == SIGINT) + switch (err_value) { - fprintf(stderr, "\n\nSignal %d received, preparing to exit...\n", - sig_num); - quit_signal = 1; + case MR_PDUMP_ERR_FOR_MESSAGE_INVALID: + printf("Message err info : Mess arg invalid.\n"); + break; + case MR_PDUMP_ERR_FOR_PORT_INVALID: + printf("Message err info : Port invalid.\n"); + break; + case MR_PDUMP_ERR_FOR_MEMPOOL_CREATE: + printf("Message err info : Mempool create err.\n"); + break; + case MR_PDUMP_ERR_FOR_RX_RING_CREATE: + printf("Message err info : Rx ring create err.\n"); + break; + case MR_PDUMP_ERR_FOR_TX_RING_CREATE: + printf("Message err info : Tx ring create err.\n"); + break; + case MR_PDUMP_ERR_FOR_RX_RING_FREE: + printf("Message err info : Rx ring free err.\n"); + break; + case MR_PDUMP_ERR_FOR_TX_RING_FREE: + printf("Message err info : Tx ring free err.\n"); + break; + case MR_PDUMP_ERR_FOR_RX_ENABLE: + printf("Message err info : Rx enable err.\n"); + break; + case MR_PDUMP_ERR_FOR_TX_ENABLE: + printf("Message err info : Tx enable err.\n"); + break; + case MR_PDUMP_ERR_FOR_RX_DISABLE: + printf("Message err info : Rx disable err.\n"); + break; + case MR_PDUMP_ERR_FOR_TX_DISABLE: + printf("Message err info : Tx disable err.\n"); + break; + case MR_PDUMP_ERR_FOR_MEMPOOL_FREE: + printf("Message err info : Mempool free err.\n"); + break; } } -static void -create_mp_ring_vdev(void) +static void enable_pdump(void) { - int i; - struct pdump_tuples *pt = NULL; - struct rte_mempool *mbuf_pool = NULL; - char ring_name[SIZE]; - char mempool_name[SIZE]; - - for (i = 0; i < num_tuples; i++) + for (int i = 0; i < num_tuples; i++) { - pt = &pdump_t[i]; - snprintf(mempool_name, SIZE, MP_NAME, i); - mbuf_pool = rte_mempool_lookup(mempool_name); - if (mbuf_pool == NULL) - { - /* create mempool */ - mbuf_pool = rte_pktmbuf_pool_create(mempool_name, - pt->total_num_mbufs, - MBUF_POOL_CACHE_SIZE, 0, - pt->mbuf_data_size, - rte_socket_id()); - if (mbuf_pool == NULL) - { - cleanup_rings(); - rte_exit(EXIT_FAILURE, - "Mempool creation failed: %s\n", - rte_strerror(rte_errno)); - } - } - pt->mp = mbuf_pool; - - if (pt->dir == RTE_PDUMP_FLAG_RXTX) + struct pdump_tuples * pt = &pdump_t[i]; + if (pt->dir & RTE_PDUMP_FLAG_RX) { - /* if captured packets has to send to the same vdev */ - /* create rx_ring */ - snprintf(ring_name, SIZE, RX_RING, i); - pt->rx_ring = rte_ring_lookup(ring_name); - if (pt->rx_ring == NULL) + struct rte_mp_msg mp_req = {}; + struct mr_pdump_request * req = (struct mr_pdump_request *)mp_req.param; + + memset(req, 0, sizeof(*req)); + + req->op = ENABLE; + req->queue = pt->queue; + req->mbuf_data_size = pt->mbuf_data_size; + req->total_num_mbufs = pt->total_num_mbufs; + req->flags = RTE_PDUMP_FLAG_RX; + req->ring_size = pt->ring_size; + memcpy(req->dev_symbol, pt->dev_symbol, sizeof(pt->dev_symbol)); + + struct rte_mp_reply mp_reply = {}; + struct timespec ts = {.tv_sec = 5, .tv_nsec = 0}; + rte_strscpy(mp_req.name, MR_PDUMP_MP, RTE_MP_MAX_NAME_LEN); + mp_req.len_param = sizeof(*req); + mp_req.num_fds = 0; + if (rte_mp_request_sync(&mp_req, &mp_reply, &ts) == 0) { - pt->rx_ring = rte_ring_create(ring_name, pt->ring_size, - rte_socket_id(), 0); - - if (pt->rx_ring == NULL) + struct rte_mp_msg * mp_rep = &mp_reply.msgs[0]; + struct mr_pdump_response * resp = (struct mr_pdump_response *)mp_rep->param; + int32_t err_value = resp->err_value; + if (err_value == MR_PDUMP_SUCESS) + { + pt->rx_ring = resp->rx_ring; + pt->mp = resp->mp; + pt->port_id = resp->port_id; + pt->drv_type = resp->drv_type; + free(mp_reply.msgs); + } + else { - cleanup_rings(); - rte_exit(EXIT_FAILURE, "%s:%s:%d\n", - rte_strerror(rte_errno), - __func__, __LINE__); + /* Dump error info */ + err_value_dump(resp->err_value); + free(mp_reply.msgs); + rte_exit(EXIT_FAILURE, "Device:%s, rx enable err.\n", pt->dev_symbol); } } - /* create tx_ring */ - snprintf(ring_name, SIZE, TX_RING, i); - pt->tx_ring = rte_ring_lookup(ring_name); - if (pt->tx_ring == NULL) + if (pt->drv_type != MR_DEV_DRV_TYPE_SHMDEV) { - pt->tx_ring = rte_ring_create(ring_name, pt->ring_size, - rte_socket_id(), 0); - - if (pt->tx_ring == NULL) + /* Phydev */ + int ret = rte_pdump_enable(pt->port_id, pt->queue, RTE_PDUMP_FLAG_RX, pt->rx_ring, pt->mp, NULL); + if (ret < 0) { - cleanup_rings(); - rte_exit(EXIT_FAILURE, "%s:%s:%d\n", - rte_strerror(rte_errno), - __func__, __LINE__); + rte_exit(EXIT_FAILURE, "Phydev :%s, rx enable err.\n", pt->dev_symbol); } } } - else if (pt->dir == RTE_PDUMP_FLAG_RX) - { - /* create rx_ring */ - snprintf(ring_name, SIZE, RX_RING, i); - pt->rx_ring = rte_ring_lookup(ring_name); - if (pt->rx_ring == NULL) + if (pt->dir & RTE_PDUMP_FLAG_TX) + { + struct rte_mp_msg mp_req = {}; + struct mr_pdump_request * req = (struct mr_pdump_request *)mp_req.param; + + memset(req, 0, sizeof(*req)); + + req->op = ENABLE; + req->queue = pt->queue; + req->mbuf_data_size = pt->mbuf_data_size; + req->total_num_mbufs = pt->total_num_mbufs; + req->flags = RTE_PDUMP_FLAG_TX; + req->ring_size = pt->ring_size; + memcpy(req->dev_symbol, pt->dev_symbol, sizeof(pt->dev_symbol)); + + struct timespec ts = {.tv_sec = 5, .tv_nsec = 0}; + struct rte_mp_reply mp_reply = {}; + rte_strscpy(mp_req.name, MR_PDUMP_MP, RTE_MP_MAX_NAME_LEN); + mp_req.len_param = sizeof(*req); + mp_req.num_fds = 0; + if (rte_mp_request_sync(&mp_req, &mp_reply, &ts) == 0) { - pt->rx_ring = rte_ring_create(ring_name, pt->ring_size, - rte_socket_id(), 0); - - if (pt->rx_ring == NULL) + struct rte_mp_msg * mp_rep = &mp_reply.msgs[0]; + struct mr_pdump_response * resp = (struct mr_pdump_response *)mp_rep->param; + rte_errno = resp->err_value; + if (resp->err_value == MR_PDUMP_SUCESS) { - cleanup_rings(); - rte_exit(EXIT_FAILURE, "%s\n", - rte_strerror(rte_errno)); + pt->tx_ring = resp->tx_ring; + pt->mp = resp->mp; + pt->port_id = resp->port_id; + pt->drv_type = resp->drv_type; + free(mp_reply.msgs); + } + else + { + /* Dump error info */ + err_value_dump(resp->err_value); + free(mp_reply.msgs); + rte_exit(EXIT_FAILURE, "Devices:%s, tx enable err.\n", pt->dev_symbol); } } - } - else if (pt->dir == RTE_PDUMP_FLAG_TX) - { - /* create tx_ring */ - snprintf(ring_name, SIZE, TX_RING, i); - pt->tx_ring = rte_ring_lookup(ring_name); - if (pt->tx_ring == NULL) + if (pt->drv_type != MR_DEV_DRV_TYPE_SHMDEV) { - pt->tx_ring = rte_ring_create(ring_name, pt->ring_size, - rte_socket_id(), 0); - - if (pt->tx_ring == NULL) + /* Phydev */ + int ret = rte_pdump_enable(pt->port_id, pt->queue, RTE_PDUMP_FLAG_TX, pt->tx_ring, pt->mp, NULL); + if (ret < 0) { - cleanup_rings(); - rte_exit(EXIT_FAILURE, "%s\n", - rte_strerror(rte_errno)); + rte_exit(EXIT_FAILURE, "Phydev:%s, tx enable err.\n", pt->dev_symbol); } } } } } -static void -enable_pdump(void) +static void disable_pdump(void) { - int i; - struct pdump_tuples *pt; - int ret = 0, ret1 = 0; - - for (i = 0; i < num_tuples; i++) + for (int i = 0; i < num_tuples; i++) { - pt = &pdump_t[i]; - if (pt->dir == RTE_PDUMP_FLAG_RXTX) + struct pdump_tuples * pt = &pdump_t[i]; + if (pt->dir & RTE_PDUMP_FLAG_RX) { - if (pt->dump_by_type == DEVICE_ID) + if (pt->drv_type != MR_DEV_DRV_TYPE_SHMDEV) { - ret = rte_pdump_enable_by_deviceid( - pt->device_id, - pt->queue, - RTE_PDUMP_FLAG_RX, - pt->rx_ring, - pt->mp, NULL); - ret1 = rte_pdump_enable_by_deviceid( - pt->device_id, - pt->queue, - RTE_PDUMP_FLAG_TX, - pt->tx_ring, - pt->mp, NULL); + int ret = rte_pdump_disable(pt->port_id, pt->queue, RTE_PDUMP_FLAG_RX); + if (ret < 0) + { + rte_exit(EXIT_FAILURE, "Phydev:%s, rx disable err.\n", pt->dev_symbol); + } } - else if (pt->dump_by_type == PORT_ID) + + struct rte_mp_msg mp_req, *mp_rep; + struct rte_mp_reply mp_reply; + struct timespec ts = {.tv_sec = 5, .tv_nsec = 0}; + struct mr_pdump_request * req = (struct mr_pdump_request *)mp_req.param; + struct mr_pdump_response * resp; + + memset(req, 0, sizeof(*req)); + + req->op = DISABLE; + req->flags = RTE_PDUMP_FLAG_RX; + memcpy(req->dev_symbol, pt->dev_symbol, sizeof(pt->dev_symbol)); + + rte_strscpy(mp_req.name, MR_PDUMP_MP, RTE_MP_MAX_NAME_LEN); + mp_req.len_param = sizeof(*req); + mp_req.num_fds = 0; + if (rte_mp_request_sync(&mp_req, &mp_reply, &ts) == 0) { - ret = rte_pdump_enable(pt->port, pt->queue, - RTE_PDUMP_FLAG_RX, - pt->rx_ring, pt->mp, NULL); - ret1 = rte_pdump_enable(pt->port, pt->queue, - RTE_PDUMP_FLAG_TX, - pt->tx_ring, pt->mp, NULL); + mp_rep = &mp_reply.msgs[0]; + resp = (struct mr_pdump_response *)mp_rep->param; + int32_t err_value = resp->err_value; + if (err_value == MR_PDUMP_SUCESS) + { + pt->rx_ring = NULL; + pt->mp = NULL; + free(mp_reply.msgs); + } + else + { + /* Dump error info */ + err_value_dump(resp->err_value); + free(mp_reply.msgs); + rte_exit(EXIT_FAILURE, "Device:%s, disable err.\n", pt->dev_symbol); + } } } - else if (pt->dir == RTE_PDUMP_FLAG_RX) - { - if (pt->dump_by_type == DEVICE_ID) - ret = rte_pdump_enable_by_deviceid( - pt->device_id, - pt->queue, - pt->dir, pt->rx_ring, - pt->mp, NULL); - else if (pt->dump_by_type == PORT_ID) - ret = rte_pdump_enable(pt->port, pt->queue, - pt->dir, - pt->rx_ring, pt->mp, NULL); - } - else if (pt->dir == RTE_PDUMP_FLAG_TX) - { - if (pt->dump_by_type == DEVICE_ID) - ret = rte_pdump_enable_by_deviceid( - pt->device_id, - pt->queue, - pt->dir, - pt->tx_ring, pt->mp, NULL); - else if (pt->dump_by_type == PORT_ID) - ret = rte_pdump_enable(pt->port, pt->queue, - pt->dir, - pt->tx_ring, pt->mp, NULL); - } - if (ret < 0 || ret1 < 0) + + if (pt->dir & RTE_PDUMP_FLAG_TX) { - cleanup_pdump_resources(); - rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno)); + if (pt->drv_type != MR_DEV_DRV_TYPE_SHMDEV) + { + int ret = rte_pdump_disable(pt->port_id, pt->queue, RTE_PDUMP_FLAG_TX); + if (ret < 0) + { + rte_exit(EXIT_FAILURE, "Phydev:%s, tx disable err.\n", pt->dev_symbol); + } + } + + struct rte_mp_msg mp_req, *mp_rep; + struct rte_mp_reply mp_reply; + struct timespec ts = {.tv_sec = 5, .tv_nsec = 0}; + struct mr_pdump_request * req = (struct mr_pdump_request *)mp_req.param; + struct mr_pdump_response * resp; + + memset(req, 0, sizeof(*req)); + + req->op = DISABLE; + req->flags = RTE_PDUMP_FLAG_TX; + memcpy(req->dev_symbol, pt->dev_symbol, sizeof(pt->dev_symbol)); + + rte_strscpy(mp_req.name, MR_PDUMP_MP, RTE_MP_MAX_NAME_LEN); + mp_req.len_param = sizeof(*req); + mp_req.num_fds = 0; + if (rte_mp_request_sync(&mp_req, &mp_reply, &ts) == 0) + { + mp_rep = &mp_reply.msgs[0]; + resp = (struct mr_pdump_response *)mp_rep->param; + rte_errno = resp->err_value; + if (resp->err_value == MR_PDUMP_SUCESS) + { + pt->tx_ring = NULL; + pt->mp = NULL; + free(mp_reply.msgs); + } + else + { + /* Dump error info */ + err_value_dump(resp->err_value); + free(mp_reply.msgs); + rte_exit(EXIT_FAILURE, "Device:%s, disable err.\n", pt->dev_symbol); + } + } } } + close(pcapng_fd); } -static inline void -dump_packets(void) +static inline void dump_packets(void) { int i; - struct pdump_tuples *pt; + struct pdump_tuples * pt; while (!quit_signal) { @@ -941,53 +930,49 @@ dump_packets(void) { pt = &pdump_t[i]; if (pt->dir & RTE_PDUMP_FLAG_RX) - pdump_rxtx(pt->rx_ring, pt->rx_vdev_id, - &pt->stats); + pdump_rxtx(pt->port_id, pt->rx_ring, &pt->stats, RTE_PDUMP_FLAG_RX); + if (pt->dir & RTE_PDUMP_FLAG_TX) - pdump_rxtx(pt->tx_ring, pt->tx_vdev_id, - &pt->stats); + pdump_rxtx(pt->port_id, pt->tx_ring, &pt->stats, RTE_PDUMP_FLAG_TX); } } } -static inline void create_pcap_dumper() +static char * get_os_info(void) { - if (is_use_ppi_header) - { - pcap_handle_dead = pcap_open_dead(DLT_PPI, 65535); - } - else - { - pcap_handle_dead = pcap_open_dead(DLT_EN10MB, 65535); - } + struct utsname uts; + char * osname = NULL; - if (pcap_handle_dead == NULL) - { - cleanup_pdump_resources(); - rte_exit(EXIT_FAILURE, "Cannot open pcap handle: %s.\n", strerror(errno)); - } + if (uname(&uts) < 0) + return NULL; - pcap_dumper = pcap_dump_open(pcap_handle_dead, dumpfile_path); - if (pcap_dumper == NULL) - { - cleanup_pdump_resources(); + if (asprintf(&osname, "%s %s", uts.sysname, uts.release) == -1) + return NULL; + + return osname; +} + +static inline void create_pcap_dumper() +{ + pcapng_fd = open(dumpfile_path, O_WRONLY | O_CREAT, 0640); + char * os = get_os_info(); + _pcapng_item = rte_pcapng_fdopen(pcapng_fd, os, NULL, "Mrpdump v1.0", NULL); + if (_pcapng_item == NULL) rte_exit(EXIT_FAILURE, "Cannot open pcap dumper for %s\n", dumpfile_path); - } if (is_str_bpf_expr_set) { int ret = pcap_compile_nopcap(65535, DLT_EN10MB, &bpf_prog, str_bpf_expr, 1, PCAP_NETMASK_UNKNOWN); if (ret < 0) { - cleanup_pdump_resources(); - rte_exit(EXIT_FAILURE, "Cannot compile bpf rule %s:%s\n", str_bpf_expr, pcap_geterr(pcap_handle_dead)); + rte_exit(EXIT_FAILURE, "Cannot compile bpf rule %s\n", str_bpf_expr); } } return; } -int main(int argc, char **argv) +int main(int argc, char ** argv) { int diag; int ret; @@ -996,7 +981,7 @@ int main(int argc, char **argv) char c_flag[] = "-c1"; char n_flag[] = "-n4"; char mp_flag[] = "--proc-type=secondary"; - char *argp[argc + 3]; + char * argp[argc + 3]; /* catch ctrl-c so we can print on exit */ signal(SIGINT, signal_handler); @@ -1026,21 +1011,18 @@ int main(int argc, char **argv) rte_exit(EXIT_FAILURE, "Invalid argument\n"); } - for (i = 0; i < num_tuples; i++) - { - struct pdump_tuples *pt = &pdump_t[i]; - disable_pdump(pt); - } - /* create dumpfile writter */ create_pcap_dumper(); - /* create mempool, ring and vdevs info */ - create_mp_ring_vdev(); + /* device enable */ enable_pdump(); + + /* dump packets */ dump_packets(); - cleanup_pdump_resources(); + /* device disable */ + disable_pdump(); + /* dump debug stats */ print_pdump_stats(); |
