summaryrefslogtreecommitdiff
path: root/tools/tcpdump
diff options
context:
space:
mode:
authorsongyanchao <[email protected]>2023-03-02 08:04:21 +0000
committersongyanchao <[email protected]>2023-03-02 08:04:21 +0000
commit0c6d487e64f64a19dc3ccf14afdcc6c1ecad497e (patch)
tree58dc919815a145775860020f2fb95e2d0664765b /tools/tcpdump
parent5cae3ca875f7fd8b3f7885bd1f44e274a571f0f1 (diff)
✨ feat(DPISDN-2): 优化 mrpdump 适配 phydev 设备
优化 mrpdump 适配 phydev 设备
Diffstat (limited to 'tools/tcpdump')
-rw-r--r--tools/tcpdump/pcapng_proto.h142
-rw-r--r--tools/tcpdump/pdump.c992
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();