From patchwork Mon Mar 7 20:30:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tianli Lai X-Patchwork-Id: 108572 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 5C00CA0093; Mon, 7 Mar 2022 13:31:05 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 49FA84068F; Mon, 7 Mar 2022 13:31:05 +0100 (CET) Received: from smtp.tom.com (smtprz14.163.net [106.3.154.247]) by mails.dpdk.org (Postfix) with ESMTP id 422F14014E for ; Mon, 7 Mar 2022 13:31:01 +0100 (CET) Received: from my-app01.tom.com (my-app01.tom.com [127.0.0.1]) by freemail01.tom.com (Postfix) with ESMTP id 7911E1E8C026 for ; Mon, 7 Mar 2022 20:30:59 +0800 (CST) Received: from my-app01.tom.com (HELO smtp.tom.com) ([127.0.0.1]) by my-app01 (TOM SMTP Server) with SMTP ID -368707468 for ; Mon, 07 Mar 2022 20:30:59 +0800 (CST) Received: from antispam3.tom.com (unknown [172.25.16.54]) by freemail01.tom.com (Postfix) with ESMTP id 655131E8B8BF for ; Mon, 7 Mar 2022 20:30:59 +0800 (CST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tom.com; s=201807; t=1646656259; bh=FzOFHZDO278vGyhc2lgu/JmzIh/s8jptW9wrz9xj5Gk=; h=From:To:Cc:Subject:Date:From; b=zeGV1Z0eiLSLVnZ9GRSNPY7O9DFcq4rxwZ+5kTy7KCP9Gl3+sfKb0V5G/0M4VYQbG swZl/vpAWCB6w6Qo+nF/kY82O8fM1MrPi3ZmKzTpMBGL4TSfaurhRKdbs4qssU9enN NdIu7AnqODkyufXPDlPA5wZmA1wrryKGREt1Dm4o= Received: from antispam3.tom.com (antispam3.tom.com [127.0.0.1]) by antispam3.tom.com (Postfix) with ESMTP id 54F3A9C1A9B for ; Mon, 7 Mar 2022 20:30:59 +0800 (CST) X-Virus-Scanned: Debian amavisd-new at antispam3.tom.com Received: from antispam3.tom.com ([127.0.0.1]) by antispam3.tom.com (antispam3.tom.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id J34fmoiGj-kM for ; Mon, 7 Mar 2022 20:30:57 +0800 (CST) Received: from localhost.localdomain (unknown [119.131.46.189]) by antispam3.tom.com (Postfix) with ESMTPA id A00299C197B; Mon, 7 Mar 2022 20:30:57 +0800 (CST) From: Tianli Lai To: dev@dpdk.org Cc: Reshma Pattan , Stephen Hemminger Subject: [PATCH 2/2] app/pdump: add filter argument Date: Tue, 8 Mar 2022 04:30:41 +0800 Message-Id: <20220307203041.33765-1-laitianli@tom.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org filter argument contain size and snaplen argument. size argument set the pcap file size, if the total packet length over this value, pdump process will exist. snaplen argument set each packet length to save pcap file. Signed-off-by: Tianli Lai --- app/pdump/main.c | 213 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 190 insertions(+), 23 deletions(-) diff --git a/app/pdump/main.c b/app/pdump/main.c index 04a38e8911..664a336098 100644 --- a/app/pdump/main.c +++ b/app/pdump/main.c @@ -32,6 +32,8 @@ #define CMD_LINE_OPT_PDUMP_NUM 256 #define CMD_LINE_OPT_MULTI "multi" #define CMD_LINE_OPT_MULTI_NUM 257 +#define CMD_LINE_OPT_FILTER "filter" +#define CMD_LINE_OPT_FILTER_NUM 258 #define PDUMP_PORT_ARG "port" #define PDUMP_PCI_ARG "device_id" #define PDUMP_QUEUE_ARG "queue" @@ -42,10 +44,16 @@ #define PDUMP_MSIZE_ARG "mbuf-size" #define PDUMP_NUM_MBUFS_ARG "total-num-mbufs" +#define FILTER_PCAP_FILE_SIZE_ARG "size" +#define FILTER_PCAP_FILE_SIZE_FLAGS (1 << 0) +#define FILTER_SNAPLEN_ARG "snaplen" +#define FILTER_SNAPLEN_FLAGS (1 << 1) + #define VDEV_NAME_FMT "net_pcap_%s_%d" #define VDEV_PCAP_ARGS_FMT "tx_pcap=%s" #define VDEV_IFACE_ARGS_FMT "tx_iface=%s" #define TX_STREAM_SIZE 64 +#define PCAP_MIN_SNAPLEN 64 #define MP_NAME "pdump_pool_%d" @@ -64,6 +72,7 @@ #define MAX_LONG_OPT_SZ 64 #define RING_SIZE 16384 #define SIZE 256 +#define VDEV_ARGS_SIZE 1024 #define BURST_SIZE 32 #define NUM_VDEVS 2 /* Maximum delay for exiting after primary process. */ @@ -100,6 +109,12 @@ static const char * const valid_pdump_arguments[] = { NULL }; +static const char * const valid_filter_arguments[] = { + FILTER_PCAP_FILE_SIZE_ARG, + FILTER_SNAPLEN_ARG, + NULL +}; + struct pdump_stats { uint64_t dequeue_pkts; uint64_t tx_pkts; @@ -136,6 +151,14 @@ struct pdump_tuples { } __rte_cache_aligned; static struct pdump_tuples pdump_t[APP_ARG_TCPDUMP_MAX_TUPLES]; +struct pdump_filter { + uint64_t filter_flags; + uint32_t pcap_file_size; + uint16_t snaplen; +} __rte_cache_aligned; +static struct pdump_filter filter_t; + +static uint32_t pcap_data_size; struct parse_val { uint64_t min; uint64_t max; @@ -160,7 +183,9 @@ pdump_usage(const char *prgname) " tx-dev=," "[ring-size=default:16384]," "[mbuf-size=default:2176]," - "[total-num-mbufs=default:65535]'\n", + "[total-num-mbufs=default:65535]'" + " --"CMD_LINE_OPT_FILTER" " + "'[size=],[snaplen=]'\n", prgname); } @@ -243,6 +268,39 @@ parse_uint_value(const char *key, const char *value, void *extra_args) return 0; } +static int +__parse_size(const char *key __rte_unused, const char *value, + void *extra_args) +{ + const char *str_size = NULL; + char *p1, *p2; + char *end; + int *val = extra_args; + int size = 0; + + str_size = strdup(value); + p1 = strchr(str_size, 'K'); + p2 = strchr(str_size, 'k'); + if (p1 || p2) + size = strtoul(str_size, &end, 10) * 1024; + else { + p1 = strchr(str_size, 'M'); + p2 = strchr(str_size, 'm'); + if (p1 || p2) + size = strtoul(str_size, &end, 10) * 1024 * 1024; + else { + p1 = strchr(str_size, 'G'); + p2 = strchr(str_size, 'g'); + if (p1 || p2) + size = strtoul(str_size, &end, 10) * 1024 * 1024 * 1024; + else + size = strtoul(str_size, &end, 10); + } + } + *val = (uint32_t)size; + return 0; +} + static int parse_pdump(const char *optarg) { @@ -377,6 +435,46 @@ parse_pdump(const char *optarg) return ret; } +static int +parse_filter(const char *optarg) +{ + int ret = 0, cnt; + struct parse_val v = {0}; + struct rte_kvargs *kvlist; + struct pdump_filter *ft = &filter_t; + /* initial check for invalid arguments */ + kvlist = rte_kvargs_parse(optarg, valid_filter_arguments); + if (kvlist == NULL) { + printf("--filter=\"%s\": invalid argument passed\n", optarg); + return -1; + } + cnt = rte_kvargs_count(kvlist, FILTER_PCAP_FILE_SIZE_ARG); + if (cnt == 1) { + ret = rte_kvargs_process(kvlist, FILTER_PCAP_FILE_SIZE_ARG, + &__parse_size, &ft->pcap_file_size); + if (ret < 0) + goto free_kvlist; + + ft->filter_flags |= FILTER_PCAP_FILE_SIZE_FLAGS; + } + + cnt = rte_kvargs_count(kvlist, FILTER_SNAPLEN_ARG); + if (cnt == 1) { + v.min = PCAP_MIN_SNAPLEN; + v.max = 65535; + ret = rte_kvargs_process(kvlist, FILTER_SNAPLEN_ARG, + &parse_uint_value, &v); + if (ret < 0) + goto free_kvlist; + ft->snaplen = (uint32_t)v.val; + ft->filter_flags |= FILTER_SNAPLEN_FLAGS; + } +free_kvlist: + rte_kvargs_free(kvlist); + return ret; +} + + /* Parse the argument given in the command line of the application */ static int launch_args_parse(int argc, char **argv, char *prgname) @@ -386,6 +484,7 @@ launch_args_parse(int argc, char **argv, char *prgname) static struct option long_option[] = { {CMD_LINE_OPT_PDUMP, 1, 0, CMD_LINE_OPT_PDUMP_NUM}, {CMD_LINE_OPT_MULTI, 0, 0, CMD_LINE_OPT_MULTI_NUM}, + {CMD_LINE_OPT_FILTER, 1, 0, CMD_LINE_OPT_FILTER_NUM}, {NULL, 0, 0, 0} }; @@ -406,6 +505,13 @@ launch_args_parse(int argc, char **argv, char *prgname) case CMD_LINE_OPT_MULTI_NUM: multiple_core_capture = 1; break; + case CMD_LINE_OPT_FILTER_NUM: + ret = parse_filter(optarg); + if (ret) { + pdump_usage(prgname); + return -1; + } + break; default: pdump_usage(prgname); return -1; @@ -458,9 +564,38 @@ disable_pdump(struct pdump_tuples *pt) rte_pdump_disable(pt->port, pt->queue, pt->dir); } +static inline int pdump_filter_pcap_size(struct rte_mbuf **pkts, uint16_t nb_in_deq) +{ + int ret = 1; + int i = 0; + uint32_t data_len = 0; + + if (likely(!(filter_t.filter_flags & FILTER_PCAP_FILE_SIZE_FLAGS))) + return 1; + + if (filter_t.filter_flags & FILTER_PCAP_FILE_SIZE_FLAGS) { + for (i = 0; i < nb_in_deq; i++) { + data_len = rte_pktmbuf_pkt_len(pkts[i]); + if (filter_t.filter_flags & FILTER_SNAPLEN_FLAGS) { + if (data_len > filter_t.snaplen) + data_len = filter_t.snaplen; + } + pcap_data_size += data_len; + } + if (pcap_data_size >= filter_t.pcap_file_size) { + printf("recv packet total size: %u, will exit...\n", + pcap_data_size); + ret = 0; + } + } + return ret; +} + + static inline void pdump_rxtx(struct rte_ring *ring, uint16_t vdev_id, struct pdump_stats *stats) { + int ret = 0; /* write input packets of port to vdev for pdump */ struct rte_mbuf *rxtx_bufs[BURST_SIZE]; @@ -468,7 +603,7 @@ pdump_rxtx(struct rte_ring *ring, uint16_t vdev_id, struct pdump_stats *stats) const uint16_t nb_in_deq = rte_ring_dequeue_burst(ring, (void *)rxtx_bufs, BURST_SIZE, NULL); stats->dequeue_pkts += nb_in_deq; - + ret = pdump_filter_pcap_size(rxtx_bufs, nb_in_deq); if (nb_in_deq) { /* then sent on vdev */ uint16_t nb_in_txd = rte_eth_tx_burst( @@ -483,6 +618,8 @@ pdump_rxtx(struct rte_ring *ring, uint16_t vdev_id, struct pdump_stats *stats) stats->freed_pkts += drops; } } + if (!ret) + quit_signal = 1; } static void @@ -622,6 +759,52 @@ configure_vdev(uint16_t port_id) return 0; } +static int +get_vdev_rx_args(char *vdev_args, int size, struct pdump_tuples *pt) +{ + int args_len = 0; + if (!vdev_args || size < 0) + return -1; + char *str = pt->rx_dev; + + if (pt->rx_vdev_stream_type == IFACE) { + args_len += snprintf(vdev_args + args_len, size - args_len, + VDEV_IFACE_ARGS_FMT, str); + } else { + args_len += snprintf(vdev_args + args_len, size - args_len, + VDEV_PCAP_ARGS_FMT, str); + } + if ((filter_t.filter_flags & FILTER_SNAPLEN_FLAGS) && + filter_t.snaplen >= PCAP_MIN_SNAPLEN) { + args_len += snprintf(vdev_args + args_len, size - args_len, + ","FILTER_SNAPLEN_ARG"=%d", filter_t.snaplen); + } + return args_len; +} + + +static int +get_vdev_tx_args(char *vdev_args, int size, struct pdump_tuples *pt) +{ + int args_len = 0; + if (!vdev_args || size < 0) + return -1; + char *str = pt->tx_dev; + if (pt->tx_vdev_stream_type == IFACE) { + args_len += snprintf(vdev_args + args_len, size - args_len, + VDEV_IFACE_ARGS_FMT, str); + } else { + args_len += snprintf(vdev_args + args_len, size - args_len, + VDEV_PCAP_ARGS_FMT, str); + } + if ((filter_t.filter_flags & FILTER_SNAPLEN_FLAGS) && + filter_t.snaplen >= PCAP_MIN_SNAPLEN) { + args_len += snprintf(vdev_args + args_len, size - args_len, + ","FILTER_SNAPLEN_ARG"=%d", filter_t.snaplen); + } + return args_len; +} + static void create_mp_ring_vdev(void) { @@ -630,7 +813,7 @@ create_mp_ring_vdev(void) struct pdump_tuples *pt = NULL; struct rte_mempool *mbuf_pool = NULL; char vdev_name[SIZE]; - char vdev_args[SIZE]; + char vdev_args[VDEV_ARGS_SIZE]; char ring_name[SIZE]; char mempool_name[SIZE]; @@ -681,11 +864,7 @@ create_mp_ring_vdev(void) /* create vdevs */ snprintf(vdev_name, sizeof(vdev_name), VDEV_NAME_FMT, RX_STR, i); - (pt->rx_vdev_stream_type == IFACE) ? - snprintf(vdev_args, sizeof(vdev_args), - VDEV_IFACE_ARGS_FMT, pt->rx_dev) : - snprintf(vdev_args, sizeof(vdev_args), - VDEV_PCAP_ARGS_FMT, pt->rx_dev); + get_vdev_rx_args(vdev_args, sizeof(vdev_args), pt); if (rte_eal_hotplug_add("vdev", vdev_name, vdev_args) < 0) { cleanup_rings(); @@ -711,11 +890,7 @@ create_mp_ring_vdev(void) else { snprintf(vdev_name, sizeof(vdev_name), VDEV_NAME_FMT, TX_STR, i); - (pt->rx_vdev_stream_type == IFACE) ? - snprintf(vdev_args, sizeof(vdev_args), - VDEV_IFACE_ARGS_FMT, pt->tx_dev) : - snprintf(vdev_args, sizeof(vdev_args), - VDEV_PCAP_ARGS_FMT, pt->tx_dev); + get_vdev_tx_args(vdev_args, sizeof(vdev_args), pt); if (rte_eal_hotplug_add("vdev", vdev_name, vdev_args) < 0) { cleanup_rings(); @@ -751,11 +926,7 @@ create_mp_ring_vdev(void) snprintf(vdev_name, sizeof(vdev_name), VDEV_NAME_FMT, RX_STR, i); - (pt->rx_vdev_stream_type == IFACE) ? - snprintf(vdev_args, sizeof(vdev_args), - VDEV_IFACE_ARGS_FMT, pt->rx_dev) : - snprintf(vdev_args, sizeof(vdev_args), - VDEV_PCAP_ARGS_FMT, pt->rx_dev); + get_vdev_rx_args(vdev_args, sizeof(vdev_args), pt); if (rte_eal_hotplug_add("vdev", vdev_name, vdev_args) < 0) { cleanup_rings(); @@ -788,11 +959,7 @@ create_mp_ring_vdev(void) snprintf(vdev_name, sizeof(vdev_name), VDEV_NAME_FMT, TX_STR, i); - (pt->tx_vdev_stream_type == IFACE) ? - snprintf(vdev_args, sizeof(vdev_args), - VDEV_IFACE_ARGS_FMT, pt->tx_dev) : - snprintf(vdev_args, sizeof(vdev_args), - VDEV_PCAP_ARGS_FMT, pt->tx_dev); + get_vdev_tx_args(vdev_args, sizeof(vdev_args), pt); if (rte_eal_hotplug_add("vdev", vdev_name, vdev_args) < 0) { cleanup_rings();