get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/98962/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 98962,
    "url": "https://patches.dpdk.org/api/patches/98962/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20210916001416.39998-2-stephen@networkplumber.org/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20210916001416.39998-2-stephen@networkplumber.org>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210916001416.39998-2-stephen@networkplumber.org",
    "date": "2021-09-16T00:14:05",
    "name": "[v9,01/12] librte_pcapng: add new library for writing pcapng files",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "097e4675882537bfa5292d37563e0d0ac5cd1933",
    "submitter": {
        "id": 27,
        "url": "https://patches.dpdk.org/api/people/27/?format=api",
        "name": "Stephen Hemminger",
        "email": "stephen@networkplumber.org"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20210916001416.39998-2-stephen@networkplumber.org/mbox/",
    "series": [
        {
            "id": 18954,
            "url": "https://patches.dpdk.org/api/series/18954/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=18954",
            "date": "2021-09-16T00:14:04",
            "name": "Packet capture framework enhancements",
            "version": 9,
            "mbox": "https://patches.dpdk.org/series/18954/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/98962/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/98962/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "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])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 48F29A0C41;\n\tThu, 16 Sep 2021 02:14:26 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 16BC3410E8;\n\tThu, 16 Sep 2021 02:14:25 +0200 (CEST)",
            "from mail-pf1-f174.google.com (mail-pf1-f174.google.com\n [209.85.210.174])\n by mails.dpdk.org (Postfix) with ESMTP id 1B5A8410E3\n for <dev@dpdk.org>; Thu, 16 Sep 2021 02:14:21 +0200 (CEST)",
            "by mail-pf1-f174.google.com with SMTP id y17so4198392pfl.13\n for <dev@dpdk.org>; Wed, 15 Sep 2021 17:14:21 -0700 (PDT)",
            "from hermes.local (204-195-33-123.wavecable.com. [204.195.33.123])\n by smtp.gmail.com with ESMTPSA id 26sm1082252pgx.72.2021.09.15.17.14.19\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Wed, 15 Sep 2021 17:14:19 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=networkplumber-org.20150623.gappssmtp.com; s=20150623;\n h=from:to:cc:subject:date:message-id:in-reply-to:references\n :mime-version:content-transfer-encoding;\n bh=mwHYb1APwVM1Hyv8Al/kX35q63aNi00KCIKEUaNDSnU=;\n b=MtzMgJ9GDfrjl3TvreS81XR0eOUNxh0lRKdo7/sblqLIZN7btm39d8PAjkcD/2ApuA\n icqWNGCwu2teVQNHzlfLO4AiPGcUK1hG+z4LHdfiqoBDyLof6ESNWdW5Mq4GiQxx+nj1\n n0USkfE9be8rkEOnFEzCmDjLzkWrSjWjeWBTaHaynRoIkUVg1vhxDCEHZW/XrGnpBcu2\n bSetBV6e3+ImxRQpKAGCVvPsWbvhUkYVdNJLrbd+lMSpCoZRDyEoMWfH6Zyram27xy1O\n zokfWRgNwT6rJQSGiFDt88+IqZn2KjYPxlZDQ8B7zujDpIoYNhTmPsvyBxggTfECDRnY\n toGA==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20210112;\n h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n :references:mime-version:content-transfer-encoding;\n bh=mwHYb1APwVM1Hyv8Al/kX35q63aNi00KCIKEUaNDSnU=;\n b=eKGmDx+2FtpAvjgNKzlr2pnMc0v5gB8G04he6SKQym/vU9fa/M9ePxhZIYwcrRWIY4\n xN2D2U9kzYx136cxC0vxRsij1QhdU1ly++Pq470OeNQMEzUH090UIOXvgvFDX0o21FFV\n bhIELeJ2TIBzv7YyRrnEA+UzvGhNA3AYaUs5Woat/x6AejC1jFUanePTBX4IgbuXOxGH\n Ud5KqhXhppaE7yumhzea86l7qDKdP3+d8ZPDOJ4dY+yvncWvwdR88W6lNG+J/FDgweFc\n skbARHm7rYmZcmtTehC1sk5nztl8kNpO+W62d5RG2j5IDdhDVz1mu+QhEviKgB51Hb5g\n Jscg==",
        "X-Gm-Message-State": "AOAM533hQ/XfJxm7NIgXDyiJVAJ9aqFPCDB1tSaewQlgbe04fI+Qqrax\n YK7UoHT6Qr78o1JGJOC3MPjhdNsDE66DYA==",
        "X-Google-Smtp-Source": "\n ABdhPJyPZs2ls813swNmgWdDrpmJZpfvqB/VbYjJAr2EIydRYajcKT7Vukf9hInL5w20JYSCFEvhPA==",
        "X-Received": "by 2002:a63:b54b:: with SMTP id u11mr2287842pgo.163.1631751260103;\n Wed, 15 Sep 2021 17:14:20 -0700 (PDT)",
        "From": "Stephen Hemminger <stephen@networkplumber.org>",
        "To": "dev@dpdk.org",
        "Cc": "Stephen Hemminger <stephen@networkplumber.org>",
        "Date": "Wed, 15 Sep 2021 17:14:05 -0700",
        "Message-Id": "<20210916001416.39998-2-stephen@networkplumber.org>",
        "X-Mailer": "git-send-email 2.30.2",
        "In-Reply-To": "<20210916001416.39998-1-stephen@networkplumber.org>",
        "References": "<20210903004732.109023-1-stephen@networkplumber.org>\n <20210916001416.39998-1-stephen@networkplumber.org>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v9 01/12] librte_pcapng: add new library for\n writing pcapng files",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This is utility library for writing pcapng format files\nused by Wireshark family of utilities. Older tcpdump\nalso knows how to read (but not write) this format.\n\nSee draft RFC\n  https://www.ietf.org/id/draft-tuexen-opsawg-pcapng-03.html\nand\n  https://github.com/pcapng/pcapng/\n\nSigned-off-by: Stephen Hemminger <stephen@networkplumber.org>\n---\n lib/meson.build           |   1 +\n lib/pcapng/meson.build    |   8 +\n lib/pcapng/pcapng_proto.h | 129 +++++++++\n lib/pcapng/rte_pcapng.c   | 574 ++++++++++++++++++++++++++++++++++++++\n lib/pcapng/rte_pcapng.h   | 194 +++++++++++++\n lib/pcapng/version.map    |  12 +\n 6 files changed, 918 insertions(+)\n create mode 100644 lib/pcapng/meson.build\n create mode 100644 lib/pcapng/pcapng_proto.h\n create mode 100644 lib/pcapng/rte_pcapng.c\n create mode 100644 lib/pcapng/rte_pcapng.h\n create mode 100644 lib/pcapng/version.map",
    "diff": "diff --git a/lib/meson.build b/lib/meson.build\nindex 1673ca4323c0..51bf9c2d11f0 100644\n--- a/lib/meson.build\n+++ b/lib/meson.build\n@@ -41,6 +41,7 @@ libraries = [\n         'latencystats',\n         'lpm',\n         'member',\n+        'pcapng',\n         'power',\n         'pdump',\n         'rawdev',\ndiff --git a/lib/pcapng/meson.build b/lib/pcapng/meson.build\nnew file mode 100644\nindex 000000000000..fe636bdf3c0b\n--- /dev/null\n+++ b/lib/pcapng/meson.build\n@@ -0,0 +1,8 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2019 Microsoft Corporation\n+\n+version = 1\n+sources = files('rte_pcapng.c')\n+headers = files('rte_pcapng.h')\n+\n+deps += ['ethdev']\ndiff --git a/lib/pcapng/pcapng_proto.h b/lib/pcapng/pcapng_proto.h\nnew file mode 100644\nindex 000000000000..47161d8a1213\n--- /dev/null\n+++ b/lib/pcapng/pcapng_proto.h\n@@ -0,0 +1,129 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2019-2020 Microsoft Corporation\n+ *\n+ * PCAP Next Generation Capture File writer\n+ *\n+ * See: https://github.com/pcapng/pcapng/ for the file format.\n+ */\n+\n+enum pcapng_block_types {\n+\tPCAPNG_INTERFACE_BLOCK\t\t= 1,\n+\tPCAPNG_PACKET_BLOCK,\t\t/* Obsolete */\n+\tPCAPNG_SIMPLE_PACKET_BLOCK,\n+\tPCAPNG_NAME_RESOLUTION_BLOCK,\n+\tPCAPNG_INTERFACE_STATS_BLOCK,\n+\tPCAPNG_ENHANCED_PACKET_BLOCK,\n+\n+\tPCAPNG_SECTION_BLOCK\t\t= 0x0A0D0D0A,\n+};\n+\n+struct pcapng_option {\n+\tuint16_t code;\n+\tuint16_t length;\n+\tuint8_t data[];\n+};\n+\n+#define PCAPNG_BYTE_ORDER_MAGIC 0x1A2B3C4D\n+#define PCAPNG_MAJOR_VERS 1\n+#define PCAPNG_MINOR_VERS 0\n+\n+enum pcapng_opt {\n+\tPCAPNG_OPT_END\t= 0,\n+\tPCAPNG_OPT_COMMENT = 1,\n+};\n+\n+struct pcapng_section_header {\n+\tuint32_t block_type;\n+\tuint32_t block_length;\n+\tuint32_t byte_order_magic;\n+\tuint16_t major_version;\n+\tuint16_t minor_version;\n+\tuint64_t section_length;\n+};\n+\n+enum pcapng_section_opt {\n+\tPCAPNG_SHB_HARDWARE = 2,\n+\tPCAPNG_SHB_OS\t    = 3,\n+\tPCAPNG_SHB_USERAPPL = 4,\n+};\n+\n+struct pcapng_interface_block {\n+\tuint32_t block_type;\t/* 1 */\n+\tuint32_t block_length;\n+\tuint16_t link_type;\n+\tuint16_t reserved;\n+\tuint32_t snap_len;\n+};\n+\n+enum pcapng_interface_options {\n+\tPCAPNG_IFB_NAME\t = 2,\n+\tPCAPNG_IFB_DESCRIPTION,\n+\tPCAPNG_IFB_IPV4ADDR,\n+\tPCAPNG_IFB_IPV6ADDR,\n+\tPCAPNG_IFB_MACADDR,\n+\tPCAPNG_IFB_EUIADDR,\n+\tPCAPNG_IFB_SPEED,\n+\tPCAPNG_IFB_TSRESOL,\n+\tPCAPNG_IFB_TZONE,\n+\tPCAPNG_IFB_FILTER,\n+\tPCAPNG_IFB_OS,\n+\tPCAPNG_IFB_FCSLEN,\n+\tPCAPNG_IFB_TSOFFSET,\n+\tPCAPNG_IFB_HARDWARE,\n+};\n+\n+struct pcapng_enhance_packet_block {\n+\tuint32_t block_type;\t/* 6 */\n+\tuint32_t block_length;\n+\tuint32_t interface_id;\n+\tuint32_t timestamp_hi;\n+\tuint32_t timestamp_lo;\n+\tuint32_t capture_length;\n+\tuint32_t original_length;\n+};\n+\n+/* Flags values */\n+#define PCAPNG_IFB_INBOUND   0b01\n+#define PCAPNG_IFB_OUTBOUND  0b10\n+\n+enum pcapng_epb_options {\n+\tPCAPNG_EPB_FLAGS = 2,\n+\tPCAPNG_EPB_HASH,\n+\tPCAPNG_EPB_DROPCOUNT,\n+\tPCAPNG_EPB_PACKETID,\n+\tPCAPNG_EPB_QUEUE,\n+\tPCAPNG_EPB_VERDICT,\n+};\n+\n+enum pcapng_epb_hash {\n+\tPCAPNG_HASH_2COMP = 0,\n+\tPCAPNG_HASH_XOR,\n+\tPCAPNG_HASH_CRC32,\n+\tPCAPNG_HASH_MD5,\n+\tPCAPNG_HASH_SHA1,\n+\tPCAPNG_HASH_TOEPLITZ,\n+};\n+\n+struct pcapng_simple_packet {\n+\tuint32_t block_type;\t/* 3 */\n+\tuint32_t block_length;\n+\tuint32_t packet_length;\n+};\n+\n+struct pcapng_statistics {\n+\tuint32_t block_type;\t/* 5 */\n+\tuint32_t block_length;\n+\tuint32_t interface_id;\n+\tuint32_t timestamp_hi;\n+\tuint32_t timestamp_lo;\n+};\n+\n+enum pcapng_isb_options {\n+\tPCAPNG_ISB_STARTTIME = 2,\n+\tPCAPNG_ISB_ENDTIME,\n+\tPCAPNG_ISB_IFRECV,\n+\tPCAPNG_ISB_IFDROP,\n+\tPCAPNG_ISB_FILTERACCEPT,\n+\tPCAPNG_ISB_OSDROP,\n+\tPCAPNG_ISB_USRDELIV,\n+};\ndiff --git a/lib/pcapng/rte_pcapng.c b/lib/pcapng/rte_pcapng.c\nnew file mode 100644\nindex 000000000000..f8280a8b01f4\n--- /dev/null\n+++ b/lib/pcapng/rte_pcapng.c\n@@ -0,0 +1,574 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2019 Microsoft Corporation\n+ */\n+\n+#include <errno.h>\n+#include <net/if.h>\n+#include <stdio.h>\n+#include <stdlib.h>\n+#include <string.h>\n+#include <sys/uio.h>\n+#include <sys/utsname.h>\n+#include <time.h>\n+#include <unistd.h>\n+\n+#include <rte_common.h>\n+#include <rte_cycles.h>\n+#include <rte_dev.h>\n+#include <rte_errno.h>\n+#include <rte_ethdev.h>\n+#include <rte_ether.h>\n+#include <rte_mbuf.h>\n+#include <rte_pcapng.h>\n+#include <rte_time.h>\n+\n+#include \"pcapng_proto.h\"\n+\n+/* conversion from DPDK speed to PCAPNG */\n+#define PCAPNG_MBPS_SPEED 1000000ull\n+\n+/* Format of the capture file handle */\n+struct rte_pcapng {\n+\tint  outfd;\t\t/* output file */\n+\t/* DPDK port id to interface index in file */\n+\tuint32_t port_index[RTE_MAX_ETHPORTS];\n+};\n+\n+/* For converting TSC cycles to PCAPNG ns format */\n+struct pcapng_time {\n+\tuint64_t ns;\n+\tuint64_t cycles;\n+} pcapng_time;\n+\n+RTE_INIT(pcapng_init)\n+{\n+\tstruct timespec ts;\n+\n+\tpcapng_time.cycles = rte_get_tsc_cycles();\n+\tclock_gettime(CLOCK_REALTIME, &ts);\n+\tpcapng_time.ns = rte_timespec_to_ns(&ts);\n+}\n+\n+/* PCAPNG timestamps are in nanoseconds */\n+static uint64_t pcapng_tsc_to_ns(uint64_t cycles)\n+{\n+\tuint64_t delta;\n+\n+\tdelta = cycles - pcapng_time.cycles;\n+\treturn pcapng_time.ns + (delta * NSEC_PER_SEC) / rte_get_tsc_hz();\n+}\n+\n+/* length of option including padding */\n+static uint16_t pcapng_optlen(uint16_t len)\n+{\n+\treturn RTE_ALIGN(sizeof(struct pcapng_option) + len,\n+\t\t\t sizeof(uint32_t));\n+}\n+\n+/* build TLV option and return location of next */\n+static struct pcapng_option *\n+pcapng_add_option(struct pcapng_option *popt, uint16_t code,\n+\t\t  const void *data, uint16_t len)\n+{\n+\tpopt->code = code;\n+\tpopt->length = len;\n+\tmemcpy(popt->data, data, len);\n+\n+\treturn (struct pcapng_option *)((uint8_t *)popt + pcapng_optlen(len));\n+}\n+\n+/*\n+ * Write required initial section header describing the capture\n+ */\n+static int\n+pcapng_section_block(rte_pcapng_t *self,\n+\t\t    const char *os, const char *hw,\n+\t\t    const char *app, const char *comment)\n+{\n+\tstruct pcapng_section_header *hdr;\n+\tstruct pcapng_option *opt;\n+\tvoid *buf;\n+\tuint32_t len;\n+\tssize_t cc;\n+\n+\tlen = sizeof(*hdr);\n+\tif (hw)\n+\t\tlen += pcapng_optlen(strlen(hw));\n+\tif (os)\n+\t\tlen += pcapng_optlen(strlen(os));\n+\tif (app)\n+\t\tlen += pcapng_optlen(strlen(app));\n+\tif (comment)\n+\t\tlen += pcapng_optlen(strlen(comment));\n+\n+\tlen += pcapng_optlen(0);\n+\tlen += sizeof(uint32_t);\n+\n+\tbuf = calloc(1, len);\n+\tif (!buf)\n+\t\treturn -1;\n+\n+\thdr = (struct pcapng_section_header *)buf;\n+\t*hdr = (struct pcapng_section_header) {\n+\t\t.block_type = PCAPNG_SECTION_BLOCK,\n+\t\t.block_length = len,\n+\t\t.byte_order_magic = PCAPNG_BYTE_ORDER_MAGIC,\n+\t\t.major_version = PCAPNG_MAJOR_VERS,\n+\t\t.minor_version = PCAPNG_MINOR_VERS,\n+\t\t.section_length = UINT64_MAX,\n+\t};\n+\thdr->block_length = len;\n+\n+\topt = (struct pcapng_option *)(hdr + 1);\n+\tif (comment)\n+\t\topt = pcapng_add_option(opt, PCAPNG_OPT_COMMENT,\n+\t\t\t\t\tcomment, strlen(comment));\n+\tif (hw)\n+\t\topt = pcapng_add_option(opt, PCAPNG_SHB_HARDWARE,\n+\t\t\t\t\thw, strlen(hw));\n+\tif (os)\n+\t\topt = pcapng_add_option(opt, PCAPNG_SHB_OS,\n+\t\t\t\t\tos, strlen(os));\n+\tif (app)\n+\t\topt = pcapng_add_option(opt, PCAPNG_SHB_USERAPPL,\n+\t\t\t\t\tapp, strlen(app));\n+\n+\topt = pcapng_add_option(opt, PCAPNG_OPT_END, NULL, 0);\n+\t/* clone block_length after option */\n+\tmemcpy(opt, &hdr->block_length, sizeof(uint32_t));\n+\n+\tcc = write(self->outfd, buf, len);\n+\tfree(buf);\n+\n+\treturn cc;\n+}\n+\n+/* Write the PCAPNG section header at start of file */\n+static ssize_t\n+pcapng_interface_block(rte_pcapng_t *self, const char *if_name,\n+\t\t      uint64_t if_speed, const uint8_t *mac_addr,\n+\t\t      const char *if_hw, const char *comment)\n+{\n+\tstruct pcapng_interface_block *hdr;\n+\tstruct pcapng_option *opt;\n+\tconst uint8_t tsresol = 9;\t/* nanosecond resolution */\n+\tuint32_t len = sizeof(*hdr);\n+\tssize_t cc;\n+\tvoid *buf;\n+\n+\tlen += pcapng_optlen(sizeof(tsresol));\n+\tif (if_name)\n+\t\tlen += pcapng_optlen(strlen(if_name));\n+\tif (mac_addr)\n+\t\tlen += pcapng_optlen(6);\n+\tif (if_speed)\n+\t\tlen += pcapng_optlen(sizeof(uint64_t));\n+\tif (if_hw)\n+\t\tlen += pcapng_optlen(strlen(if_hw));\n+\tif (comment)\n+\t\tlen += pcapng_optlen(strlen(comment));\n+\n+\tlen += pcapng_optlen(0);\n+\tlen += sizeof(uint32_t);\n+\tbuf = calloc(1, len);\n+\tif (!buf)\n+\t\treturn -ENOMEM;\n+\n+\thdr = (struct pcapng_interface_block *)buf;\n+\thdr->block_type = PCAPNG_INTERFACE_BLOCK;\n+\thdr->link_type = 1;\t/* Ethernet */\n+\thdr->block_length = len;\n+\n+\topt = (struct pcapng_option *)(hdr + 1);\n+\tif (if_name)\n+\t\topt = pcapng_add_option(opt, PCAPNG_IFB_NAME,\n+\t\t\t\t\t if_name, strlen(if_name));\n+\tif (mac_addr)\n+\t\topt = pcapng_add_option(opt, PCAPNG_IFB_MACADDR,\n+\t\t\t\t\tmac_addr, RTE_ETHER_ADDR_LEN);\n+\tif (if_speed)\n+\t\topt = pcapng_add_option(opt, PCAPNG_IFB_SPEED,\n+\t\t\t\t\t &if_speed, sizeof(uint64_t));\n+\topt = pcapng_add_option(opt, PCAPNG_IFB_TSRESOL,\n+\t\t\t\t&tsresol, sizeof(tsresol));\n+\tif (if_hw)\n+\t\topt = pcapng_add_option(opt, PCAPNG_IFB_HARDWARE,\n+\t\t\t\t\t if_hw, strlen(if_hw));\n+\tif (comment)\n+\t\topt = pcapng_add_option(opt, PCAPNG_OPT_COMMENT,\n+\t\t\t\t\tcomment, strlen(comment));\n+\n+\topt = pcapng_add_option(opt, PCAPNG_OPT_END, NULL, 0);\n+\n+\tmemcpy(opt, &hdr->block_length, sizeof(uint32_t));\n+\tcc = write(self->outfd, buf, len);\n+\tfree(buf);\n+\n+\treturn cc;\n+}\n+\n+static int\n+pcapng_add_interface(rte_pcapng_t *self, uint16_t port)\n+{\n+\tstruct rte_eth_dev_info dev_info;\n+\tstruct rte_ether_addr macaddr;\n+\tconst struct rte_device *dev;\n+\tstruct rte_eth_link link;\n+\tchar ifname[IF_NAMESIZE];\n+\tchar ifhw[256];\n+\tuint64_t speed = 0;\n+\n+\tif (rte_eth_dev_info_get(port, &dev_info) < 0)\n+\t\treturn -1;\n+\n+\t/* make something like an interface name */\n+\tif (if_indextoname(dev_info.if_index, ifname) == NULL)\n+\t\tsnprintf(ifname, IF_NAMESIZE, \"dpdk:%u\", port);\n+\n+\t/* make a useful device hardware string */\n+\tdev = dev_info.device;\n+\tif (dev)\n+\t\tsnprintf(ifhw, sizeof(ifhw),\n+\t\t\t \"%s-%s\", dev->bus->name, dev->name);\n+\n+\t/* DPDK reports in units of Mbps */\n+\trte_eth_link_get(port, &link);\n+\tif (link.link_status == ETH_LINK_UP)\n+\t\tspeed = link.link_speed * PCAPNG_MBPS_SPEED;\n+\n+\trte_eth_macaddr_get(port, &macaddr);\n+\n+\treturn pcapng_interface_block(self, ifname, speed,\n+\t\t\t\t      macaddr.addr_bytes,\n+\t\t\t\t      dev ? ifhw : NULL, NULL);\n+}\n+\n+/*\n+ * Write the list of possible interfaces at the start\n+ * of the file.\n+ */\n+static int\n+pcapng_interfaces(rte_pcapng_t *self)\n+{\n+\tuint16_t port_id;\n+\tuint16_t index = 0;\n+\n+\tRTE_ETH_FOREACH_DEV(port_id) {\n+\t\t/* The list if ports in pcapng needs to be contiguous */\n+\t\tself->port_index[port_id] = index++;\n+\t\tif (pcapng_add_interface(self, port_id) < 0)\n+\t\t\treturn -1;\n+\t}\n+\treturn 0;\n+}\n+\n+/*\n+ * Write an Interface statistics block at the end of capture.\n+ */\n+ssize_t\n+rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port_id,\n+\t\t       const char *comment,\n+\t\t       uint64_t start_time, uint64_t end_time,\n+\t\t       uint64_t ifrecv, uint64_t ifdrop)\n+{\n+\tstruct pcapng_statistics *hdr;\n+\tstruct pcapng_option *opt;\n+\tuint32_t optlen, len;\n+\tuint8_t *buf;\n+\tuint64_t ns;\n+\n+\tRTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);\n+\n+\toptlen = 0;\n+\n+\tif (ifrecv != UINT64_MAX)\n+\t\toptlen += pcapng_optlen(sizeof(ifrecv));\n+\tif (ifdrop != UINT64_MAX)\n+\t\toptlen += pcapng_optlen(sizeof(ifdrop));\n+\tif (start_time != 0)\n+\t\toptlen += pcapng_optlen(sizeof(start_time));\n+\tif (end_time != 0)\n+\t\toptlen += pcapng_optlen(sizeof(end_time));\n+\tif (comment)\n+\t\toptlen += pcapng_optlen(strlen(comment));\n+\tif (optlen != 0)\n+\t\toptlen += pcapng_optlen(0);\n+\n+\tlen = sizeof(*hdr) + optlen + sizeof(uint32_t);\n+\tbuf = alloca(len);\n+\tif (buf == NULL)\n+\t\treturn -1;\n+\n+\thdr = (struct pcapng_statistics *)buf;\n+\topt = (struct pcapng_option *)(hdr + 1);\n+\n+\tif (comment)\n+\t\topt = pcapng_add_option(opt, PCAPNG_OPT_COMMENT,\n+\t\t\t\t\tcomment, strlen(comment));\n+\tif (start_time != 0)\n+\t\topt = pcapng_add_option(opt, PCAPNG_ISB_STARTTIME,\n+\t\t\t\t\t &start_time, sizeof(start_time));\n+\tif (end_time != 0)\n+\t\topt = pcapng_add_option(opt, PCAPNG_ISB_ENDTIME,\n+\t\t\t\t\t &end_time, sizeof(end_time));\n+\tif (ifrecv != UINT64_MAX)\n+\t\topt = pcapng_add_option(opt, PCAPNG_ISB_IFRECV,\n+\t\t\t\t&ifrecv, sizeof(ifrecv));\n+\tif (ifdrop != UINT64_MAX)\n+\t\topt = pcapng_add_option(opt, PCAPNG_ISB_IFDROP,\n+\t\t\t\t&ifdrop, sizeof(ifdrop));\n+\tif (optlen != 0)\n+\t\topt = pcapng_add_option(opt, PCAPNG_OPT_END, NULL, 0);\n+\n+\thdr->block_type = PCAPNG_INTERFACE_STATS_BLOCK;\n+\thdr->block_length = len;\n+\thdr->interface_id = self->port_index[port_id];\n+\n+\tns = pcapng_tsc_to_ns(rte_get_tsc_cycles());\n+\thdr->timestamp_hi = ns >> 32;\n+\thdr->timestamp_lo = (uint32_t)ns;\n+\n+\t/* clone block_length after option */\n+\tmemcpy(opt, &len, sizeof(uint32_t));\n+\n+\treturn write(self->outfd, buf, len);\n+}\n+\n+uint32_t\n+rte_pcapng_mbuf_size(uint32_t length)\n+{\n+\t/* The VLAN and EPB header must fit in the mbuf headroom. */\n+\tRTE_ASSERT(sizeof(struct pcapng_enhance_packet_block) +\n+\t\t   sizeof(struct rte_vlan_hdr) <= RTE_PKTMBUF_HEADROOM);\n+\n+\t/* The flags and queue information are added at the end. */\n+\treturn sizeof(struct rte_mbuf)\n+\t\t+ RTE_ALIGN(length, sizeof(uint32_t))\n+\t\t+ pcapng_optlen(sizeof(uint32_t)) /* flag option */\n+\t\t+ pcapng_optlen(sizeof(uint32_t)) /* queue option */\n+\t\t+ sizeof(uint32_t);\t\t  /*  length */\n+}\n+\n+/*\n+ *   The mbufs created use the Pcapng standard enhanced packet  block.\n+ *\n+ *                         1                   2                   3\n+ *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ *  0 |                    Block Type = 0x00000006                    |\n+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ *  4 |                      Block Total Length                       |\n+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ *  8 |                         Interface ID                          |\n+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ * 12 |                        Timestamp (High)                       |\n+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ * 16 |                        Timestamp (Low)                        |\n+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ * 20 |                    Captured Packet Length                     |\n+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ * 24 |                    Original Packet Length                     |\n+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ * 28 /                                                               /\n+ *    /                          Packet Data                          /\n+ *    /              variable length, padded to 32 bits               /\n+ *    /                                                               /\n+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ *    |      Option Code = 0x0002     |     Option Length = 0x004     |\n+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ *    |              Flags (direction)                                |\n+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ *    |      Option Code = 0x0006     |     Option Length = 0x002     |\n+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ *    |              Queue id                                         |\n+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ *    |                      Block Total Length                       |\n+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n+ */\n+\n+/* Make a copy of original mbuf with pcapng header and options */\n+struct rte_mbuf *\n+rte_pcapng_copy(uint16_t port_id, uint32_t queue,\n+\t\tconst struct rte_mbuf *md,\n+\t\tstruct rte_mempool *mp,\n+\t\tuint32_t length, uint64_t cycles,\n+\t\tenum rte_pcapng_direction direction)\n+{\n+\tstruct pcapng_enhance_packet_block *epb;\n+\tuint32_t orig_len, data_len, padding, flags;\n+\tstruct pcapng_option *opt;\n+\tconst uint16_t optlen = pcapng_optlen(sizeof(flags)) + pcapng_optlen(sizeof(queue));\n+\tstruct rte_mbuf *mc;\n+\tuint64_t ns;\n+\n+#ifdef RTE_LIBRTE_ETHDEV_DEBUG\n+\tRTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL);\n+#endif\n+\tns = pcapng_tsc_to_ns(cycles);\n+\n+\torig_len = rte_pktmbuf_pkt_len(md);\n+\n+\t/* Take snapshot of the data */\n+\tmc = rte_pktmbuf_copy(md, mp, 0, length);\n+\tif (unlikely(mc == NULL))\n+\t\treturn NULL;\n+\n+\t/* If packet had offloaded VLAN, expand it */\n+\tif (md->ol_flags & ~(PKT_RX_VLAN_STRIPPED | PKT_TX_VLAN)) {\n+\t\tif (rte_vlan_insert(&mc) != 0)\n+\t\t\tgoto fail;\n+\n+\t\torig_len += sizeof(struct rte_vlan_hdr);\n+\t}\n+\n+\t/* pad the packet to 32 bit boundary */\n+\tdata_len = rte_pktmbuf_data_len(mc);\n+\tpadding = RTE_ALIGN(data_len, sizeof(uint32_t)) - data_len;\n+\tif (padding > 0) {\n+\t\tvoid *tail = rte_pktmbuf_append(mc, padding);\n+\n+\t\tif (tail == NULL)\n+\t\t\tgoto fail;\n+\t\tmemset(tail, 0, padding);\n+\t}\n+\n+\t/* reserve trailing options and block length */\n+\topt = (struct pcapng_option *)\n+\t\trte_pktmbuf_append(mc, optlen + sizeof(uint32_t));\n+\tif (unlikely(opt == NULL))\n+\t\tgoto fail;\n+\n+\tswitch (direction) {\n+\tcase RTE_PCAPNG_DIRECTION_IN:\n+\t\tflags = PCAPNG_IFB_INBOUND;\n+\t\tbreak;\n+\tcase RTE_PCAPNG_DIRECTION_OUT:\n+\t\tflags = PCAPNG_IFB_OUTBOUND;\n+\t\tbreak;\n+\tdefault:\n+\t\tflags = 0;\n+\t}\n+\n+\topt = pcapng_add_option(opt, PCAPNG_EPB_FLAGS,\n+\t\t\t\t&flags, sizeof(flags));\n+\n+\topt = pcapng_add_option(opt, PCAPNG_EPB_QUEUE,\n+\t\t\t\t&queue, sizeof(queue));\n+\n+\t/* Add PCAPNG packet header */\n+\tepb = (struct pcapng_enhance_packet_block *)\n+\t\trte_pktmbuf_prepend(mc, sizeof(*epb));\n+\tif (unlikely(epb == NULL))\n+\t\tgoto fail;\n+\n+\tepb->block_type = PCAPNG_ENHANCED_PACKET_BLOCK;\n+\tepb->block_length = rte_pktmbuf_data_len(mc);\n+\n+\t/* Interface index is filled in later during write */\n+\tmc->port = port_id;\n+\n+\tepb->timestamp_hi = ns >> 32;\n+\tepb->timestamp_lo = (uint32_t)ns;\n+\tepb->capture_length = data_len;\n+\tepb->original_length = orig_len;\n+\n+\t/* set trailer of block length */\n+\t*(uint32_t *)opt = epb->block_length;\n+\n+\treturn mc;\n+\n+fail:\n+\trte_pktmbuf_free(mc);\n+\treturn NULL;\n+}\n+\n+/* Count how many segments are in this array of mbufs */\n+static unsigned int\n+mbuf_burst_segs(struct rte_mbuf *pkts[], unsigned int n)\n+{\n+\tunsigned int i, iovcnt;\n+\n+\tfor (iovcnt = 0, i = 0; i < n; i++) {\n+\t\tconst struct rte_mbuf *m = pkts[i];\n+\n+\t\t__rte_mbuf_sanity_check(m, 1);\n+\n+\t\tiovcnt += m->nb_segs;\n+\t}\n+\treturn iovcnt;\n+}\n+\n+/* Write pre-formatted packets to file. */\n+ssize_t\n+rte_pcapng_write_packets(rte_pcapng_t *self,\n+\t\t\t struct rte_mbuf *pkts[], uint16_t nb_pkts)\n+{\n+\tint iovcnt = mbuf_burst_segs(pkts, nb_pkts);\n+\tstruct iovec iov[iovcnt];\n+\tunsigned int i, cnt;\n+\tssize_t ret;\n+\n+\tfor (i = cnt = 0; i < nb_pkts; i++) {\n+\t\tstruct rte_mbuf *m = pkts[i];\n+\t\tstruct pcapng_enhance_packet_block *epb;\n+\n+\t\t/* sanity check that is really a pcapng mbuf */\n+\t\tepb = rte_pktmbuf_mtod(m, struct pcapng_enhance_packet_block *);\n+\t\tif (unlikely(epb->block_type != PCAPNG_ENHANCED_PACKET_BLOCK ||\n+\t\t\t     epb->block_length != rte_pktmbuf_data_len(m))) {\n+\t\t\trte_errno = EINVAL;\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\t/*\n+\t\t * The DPDK port is recorded during pcapng_copy.\n+\t\t * Map that to PCAPNG interface in file.\n+\t\t */\n+\t\tepb->interface_id = self->port_index[m->port];\n+\t\tdo {\n+\t\t\tiov[cnt].iov_base = rte_pktmbuf_mtod(m, void *);\n+\t\t\tiov[cnt].iov_len = rte_pktmbuf_data_len(m);\n+\t\t\t++cnt;\n+\t\t} while ((m = m->next));\n+\t}\n+\n+\tret = writev(self->outfd, iov, iovcnt);\n+\tif (unlikely(ret < 0))\n+\t\trte_errno = errno;\n+\treturn ret;\n+}\n+\n+/* Create new pcapng writer handle */\n+rte_pcapng_t *\n+rte_pcapng_fdopen(int fd,\n+\t\t  const char *osname, const char *hardware,\n+\t\t  const char *appname, const char *comment)\n+{\n+\trte_pcapng_t *self;\n+\n+\tself = malloc(sizeof(*self));\n+\tif (!self) {\n+\t\trte_errno = ENOMEM;\n+\t\treturn NULL;\n+\t}\n+\n+\tself->outfd = fd;\n+\n+\tif (pcapng_section_block(self, osname, hardware, appname, comment) < 0)\n+\t\tgoto fail;\n+\n+\tif (pcapng_interfaces(self) < 0)\n+\t\tgoto fail;\n+\n+\treturn self;\n+fail:\n+\tfree(self);\n+\treturn NULL;\n+}\n+\n+void\n+rte_pcapng_close(rte_pcapng_t *self)\n+{\n+\tclose(self->outfd);\n+\tfree(self);\n+}\ndiff --git a/lib/pcapng/rte_pcapng.h b/lib/pcapng/rte_pcapng.h\nnew file mode 100644\nindex 000000000000..2f1bb073df08\n--- /dev/null\n+++ b/lib/pcapng/rte_pcapng.h\n@@ -0,0 +1,194 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2019 Microsoft Corporation\n+ */\n+\n+/**\n+ * @file\n+ * RTE pcapng\n+ *\n+ * @warning\n+ * @b EXPERIMENTAL:\n+ * All functions in this file may be changed or removed without prior notice.\n+ *\n+ * Pcapng is an evolution from the pcap format, created to address some of\n+ * its deficiencies. Namely, the lack of extensibility and inability to store\n+ * additional information.\n+ *\n+ * For details about the file format see RFC:\n+ *   https://www.ietf.org/id/draft-tuexen-opsawg-pcapng-03.html\n+ *  and\n+ *    https://github.com/pcapng/pcapng/\n+ */\n+\n+#ifndef _RTE_PCAPNG_H_\n+#define _RTE_PCAPNG_H_\n+\n+#include <stdint.h>\n+#include <sys/types.h>\n+#include <rte_compat.h>\n+#include <rte_common.h>\n+#include <rte_mempool.h>\n+#include <rte_ring.h>\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+/* Opaque handle used for functions in this library. */\n+typedef struct rte_pcapng rte_pcapng_t;\n+\n+/**\n+ * Write data to existing open file\n+ *\n+ * @param fd\n+ *   file descriptor\n+ * @param osname\n+ *   Optional description of the operating system.\n+ *   Examples: \"Debian 11\", \"Windows Server 22\"\n+ * @param hardware\n+ *   Optional description of the hardware used to create this file.\n+ *   Examples: \"x86 Virtual Machine\"\n+ * @param appname\n+ *   Optional: application name recorded in the pcapng file.\n+ *   Example: \"dpdk-dumpcap 1.0 (DPDK 20.11)\"\n+ * @param comment\n+ *   Optional comment to add to file header.\n+ * @return\n+ *   handle to library, or NULL in case of error (and rte_errno is set).\n+ */\n+__rte_experimental\n+rte_pcapng_t *\n+rte_pcapng_fdopen(int fd,\n+\t\t  const char *osname, const char *hardware,\n+\t\t  const char *appname, const char *comment);\n+\n+/**\n+ * Close capture file\n+ *\n+ * @param self\n+ *  handle to library\n+ */\n+__rte_experimental\n+void\n+rte_pcapng_close(rte_pcapng_t *self);\n+\n+/**\n+ * Direction flag\n+ * These should match Enhanced Packet Block flag bits\n+ */\n+enum rte_pcapng_direction {\n+\tRTE_PCAPNG_DIRECTION_UNKNOWN = 0,\n+\tRTE_PCAPNG_DIRECTION_IN  = 1,\n+\tRTE_PCAPNG_DIRECTION_OUT = 2,\n+};\n+\n+/**\n+ * Format an mbuf for writing to file.\n+ *\n+ * @param port_id\n+ *   The Ethernet port on which packet was received\n+ *   or is going to be transmitted.\n+ * @param queue\n+ *   The queue on the Ethernet port where packet was received\n+ *   or is going to be transmitted.\n+ * @param mp\n+ *   The mempool from which the \"clone\" mbufs are allocated.\n+ * @param m\n+ *   The mbuf to copy\n+ * @param length\n+ *   The upper limit on bytes to copy.  Passing UINT32_MAX\n+ *   means all data (after offset).\n+ * @param timestamp\n+ *   The timestamp in TSC cycles.\n+ * @param direction\n+ *   The direction of the packer: receive, transmit or unknown.\n+ *\n+ * @return\n+ *   - The pointer to the new mbuf formatted for pcapng_write\n+ *   - NULL if allocation fails.\n+ *\n+ */\n+__rte_experimental\n+struct rte_mbuf *\n+rte_pcapng_copy(uint16_t port_id, uint32_t queue,\n+\t\tconst struct rte_mbuf *m, struct rte_mempool *mp,\n+\t\tuint32_t length, uint64_t timestamp,\n+\t\tenum rte_pcapng_direction direction);\n+\n+\n+/**\n+ * Determine optimum mbuf data size.\n+ *\n+ * @param length\n+ *   The upper limit on bytes to copy.  Passing UINT32_MAX\n+ *   means all data (after offset).\n+ * @return\n+ *   The minimum size of mbuf data to handle packet with length bytes.\n+ *   Accounting for required header and trailer fields\n+ */\n+__rte_experimental\n+uint32_t\n+rte_pcapng_mbuf_size(uint32_t length);\n+\n+/**\n+ * Write packets to the capture file.\n+ *\n+ * Packets to be captured are copied by rte_pcapng_mbuf()\n+ * and then this function is called to write them to the file.\n+ * @warning\n+ * Do not pass original mbufs\n+ *\n+ * @param self\n+ *  The handle to the packet capture file\n+ * @param pkts\n+ *  The address of an array of *nb_pkts* pointers to *rte_mbuf* structures\n+ *  which contain the output packets\n+ * @param nb_pkts\n+ *  The number of packets to write to the file.\n+ * @return\n+ *  The number of bytes written to file, -1 on failure to write file.\n+ *  The mbuf's in *pkts* are always freed.\n+ */\n+__rte_experimental\n+ssize_t\n+rte_pcapng_write_packets(rte_pcapng_t *self,\n+\t\t\t struct rte_mbuf *pkts[], uint16_t nb_pkts);\n+\n+/**\n+ * Write an Interface statistics block.\n+ * For statistics, use 0 if don't know or care to report it.\n+ * Should be called before closing capture to report results.\n+ *\n+ * @param self\n+ *  The handle to the packet capture file\n+ * @param port\n+ *  The Ethernet port to report stats on.\n+ * @param comment\n+ *   Optional comment to add to statistics.\n+ * @param start_time\n+ *  The time when packet capture was started in nanoseconds.\n+ *  Optional: can be zero if not known.\n+ * @param end_time\n+ *  The time when packet capture was stopped in nanoseconds.\n+ *  Optional: can be zero if not finished;\n+ * @param ifrecv\n+ *  The number of packets received by capture.\n+ *  Optional: use UINT64_MAX if not known.\n+ * @param ifdrop\n+ *  The number of packets missed by the capture process.\n+ *  Optional: use UINT64_MAX if not known.\n+ * @return\n+ *  number of bytes written to file, -1 on failure to write file\n+ */\n+__rte_experimental\n+ssize_t\n+rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port,\n+\t\t       const char *comment,\n+\t\t       uint64_t start_time, uint64_t end_time,\n+\t\t       uint64_t ifrecv, uint64_t ifdrop);\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* _RTE_PCAPNG_H_ */\ndiff --git a/lib/pcapng/version.map b/lib/pcapng/version.map\nnew file mode 100644\nindex 000000000000..05a9c86a7d91\n--- /dev/null\n+++ b/lib/pcapng/version.map\n@@ -0,0 +1,12 @@\n+EXPERIMENTAL {\n+\tglobal:\n+\n+\trte_pcapng_close;\n+\trte_pcapng_copy;\n+\trte_pcapng_fdopen;\n+\trte_pcapng_mbuf_size;\n+\trte_pcapng_write_packets;\n+\trte_pcapng_write_stats;\n+\n+\tlocal: *;\n+};\n",
    "prefixes": [
        "v9",
        "01/12"
    ]
}