get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 109321,
    "url": "http://patches.dpdk.org/api/patches/109321/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20220406151903.2916254-22-juraj.linkes@pantheon.tech/",
    "project": {
        "id": 1,
        "url": "http://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": "<20220406151903.2916254-22-juraj.linkes@pantheon.tech>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220406151903.2916254-22-juraj.linkes@pantheon.tech",
    "date": "2022-04-06T15:19:01",
    "name": "[RFC,v1,21/23] dts: merge DTS framework/flow/flow_pattern_items.py to DPDK",
    "commit_ref": null,
    "pull_url": null,
    "state": "rfc",
    "archived": true,
    "hash": "e7311d5c3940469647af98de0c1e3cfb2106530e",
    "submitter": {
        "id": 1626,
        "url": "http://patches.dpdk.org/api/people/1626/?format=api",
        "name": "Juraj Linkeš",
        "email": "juraj.linkes@pantheon.tech"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20220406151903.2916254-22-juraj.linkes@pantheon.tech/mbox/",
    "series": [
        {
            "id": 22381,
            "url": "http://patches.dpdk.org/api/series/22381/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=22381",
            "date": "2022-04-06T15:18:40",
            "name": "merge DTS test resource files to DPDK",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/22381/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/109321/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/109321/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 0A61FA0509;\n\tWed,  6 Apr 2022 17:21:51 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 62EA842986;\n\tWed,  6 Apr 2022 17:19:33 +0200 (CEST)",
            "from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20])\n by mails.dpdk.org (Postfix) with ESMTP id 9CDF64296F\n for <dev@dpdk.org>; Wed,  6 Apr 2022 17:19:30 +0200 (CEST)",
            "from localhost (localhost [127.0.0.1])\n by lb.pantheon.sk (Postfix) with ESMTP id DFA17129C28;\n Wed,  6 Apr 2022 17:19:29 +0200 (CEST)",
            "from lb.pantheon.sk ([127.0.0.1])\n by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024)\n with ESMTP id YVfQ1xsocuRG; Wed,  6 Apr 2022 17:19:27 +0200 (CEST)",
            "from entguard.lab.pantheon.local (unknown [46.229.239.141])\n by lb.pantheon.sk (Postfix) with ESMTP id 140C1184FE9;\n Wed,  6 Apr 2022 17:19:17 +0200 (CEST)"
        ],
        "X-Virus-Scanned": "amavisd-new at siecit.sk",
        "From": "=?utf-8?q?Juraj_Linke=C5=A1?= <juraj.linkes@pantheon.tech>",
        "To": "thomas@monjalon.net, david.marchand@redhat.com,\n Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com",
        "Cc": "dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= <juraj.linkes@pantheon.tech>",
        "Subject": "[RFC PATCH v1 21/23] dts: merge DTS\n framework/flow/flow_pattern_items.py to DPDK",
        "Date": "Wed,  6 Apr 2022 15:19:01 +0000",
        "Message-Id": "<20220406151903.2916254-22-juraj.linkes@pantheon.tech>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20220406151903.2916254-1-juraj.linkes@pantheon.tech>",
        "References": "<20220406151903.2916254-1-juraj.linkes@pantheon.tech>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "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"
    },
    "content": "---\n dts/framework/flow/flow_pattern_items.py | 1219 ++++++++++++++++++++++\n 1 file changed, 1219 insertions(+)\n create mode 100644 dts/framework/flow/flow_pattern_items.py",
    "diff": "diff --git a/dts/framework/flow/flow_pattern_items.py b/dts/framework/flow/flow_pattern_items.py\nnew file mode 100644\nindex 0000000000..ccb019e765\n--- /dev/null\n+++ b/dts/framework/flow/flow_pattern_items.py\n@@ -0,0 +1,1219 @@\n+# BSD LICENSE\n+#\n+# Copyright(c) 2020 Intel Corporation. All rights reserved.\n+# Copyright © 2018[, 2019] The University of New Hampshire. All rights reserved.\n+# All rights reserved.\n+#\n+# Redistribution and use in source and binary forms, with or without\n+# modification, are permitted provided that the following conditions\n+# are met:\n+#\n+#   * Redistributions of source code must retain the above copyright\n+#     notice, this list of conditions and the following disclaimer.\n+#   * Redistributions in binary form must reproduce the above copyright\n+#     notice, this list of conditions and the following disclaimer in\n+#     the documentation and/or other materials provided with the\n+#     distribution.\n+#   * Neither the name of Intel Corporation nor the names of its\n+#     contributors may be used to endorse or promote products derived\n+#     from this software without specific prior written permission.\n+#\n+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+\n+# Allows the type system to handle referencing a class inside it's definition\n+from typing import Dict, FrozenSet, Iterable, List, Tuple\n+\n+from scapy.layers.inet import ICMP, IP, TCP, UDP\n+from scapy.layers.inet6 import IPv6\n+from scapy.layers.l2 import ARP, GRE, Dot1Q, Ether\n+from scapy.layers.sctp import SCTP\n+from scapy.layers.vxlan import VXLAN\n+from scapy.packet import Packet\n+\n+from .enums import FlowItemType\n+from .exceptions import InvalidFlowItemException\n+from .flow_items import FlowItem\n+\n+ALWAYS_ALLOWED_ITEMS = {FlowItemType.RAW, FlowItemType.VOID}\n+L3_FLOW_TYPES = {FlowItemType.IPV4, FlowItemType.IPV6}\n+L4_FLOW_ITEMS = {\n+    FlowItemType.UDP,\n+    FlowItemType.TCP,\n+    FlowItemType.SCTP,\n+    FlowItemType.GRE,\n+}\n+\n+PATTERN_OPERATION_TYPES = {\n+    FlowItemType.MARK,\n+    FlowItemType.META,\n+    FlowItemType.TAG,\n+    FlowItemType.FUZZY,\n+    FlowItemType.INVERT,\n+}\n+\n+TUNNELING_PROTOCOL_TYPES = {\n+    FlowItemType.VLAN,\n+    FlowItemType.VXLAN,\n+    FlowItemType.GRE,\n+    FlowItemType.VXLAN_GPE,\n+}\n+\n+\n+class PatternFlowItem(FlowItem):\n+    allowed_with: FrozenSet[FlowItemType] = frozenset({item for item in FlowItemType})\n+\n+    valid_next_items: List[FlowItemType] = [item for item in FlowItemType]\n+\n+    # Only used for building a tree upward\n+    valid_parent_items: List[FlowItemType] = [item for item in FlowItemType]\n+\n+    possible_properties: List[Tuple[str, Iterable, Iterable]] = {}\n+\n+    def __truediv__(self, other: FlowItem):\n+        \"\"\"\n+        Used in a similar way to scapy's packet composition.\n+        @param other: The other flow item.\n+        @return: A Flow containing both items\n+        \"\"\"\n+        if other.type in self.valid_next_items or other.type == FlowItemType.END:\n+            # This import is in here so there is no circular import\n+            from .flow import Flow\n+\n+            return Flow(pattern_items=[self, other])\n+        else:\n+            raise InvalidFlowItemException(self, other)\n+\n+    # def to_scapy_packet(self):\n+    #    scapy_class: type = ITEM_TYPE_SCAPY_CLASS_MAPPING[self.type]\n+\n+\n+class FlowItemEnd(PatternFlowItem):\n+    type = FlowItemType.END\n+    valid_next_items = list({})\n+\n+\n+class FlowItemVoid(PatternFlowItem):\n+    type = FlowItemType.VOID\n+\n+\n+class FlowItemInvert(PatternFlowItem):\n+    type = FlowItemType.INVERT\n+\n+\n+class FlowItemAny(PatternFlowItem):\n+    type = FlowItemType.ANY\n+\n+\n+class FlowItemRaw(PatternFlowItem):\n+    type = FlowItemType.RAW\n+\n+\n+class FlowItemArp_eth_ipv4(PatternFlowItem):\n+    type = FlowItemType.ARP_ETH_IPV4\n+    valid_next_items = list({FlowItemType.RAW, FlowItemType.VOID})\n+    valid_parent_items: List[FlowItemType] = [FlowItemType.IPV4]\n+    \"\"\"\n+    - ``hdr``: hardware type, normally 1. => hwtype\n+    - ``pro``: protocol type, normally 0x0800. => ptype = 2048\n+    - ``hln``: hardware address length, normally 6. => hwlen\n+    - ``pln``: protocol address length, normally 4. => plen\n+    - ``op``: opcode (1 for request, 2 for reply). => op\n+    - ``sha``: sender hardware address. => hwsrc\n+    - ``spa``: sender IPv4 address => psrc\n+    - ``tha``: target hardware address. => hwdst\n+    - ``tpa``: target IPv4 address. => pdst\n+    - Default ``mask`` matches SHA, SPA, THA and TPA.\n+    \"\"\"\n+    possible_properties = {\n+        # THE FOLLOWING PROPERTIES ARE UNSUPPORTED BY TESTPMD AT THE TIME OF WRITING.\n+        # THEY CAN BE ENABLED ONCE TESTPMD SUPPORTS THEM\n+        # 'hdr':\n+        #     ('arp_eth_ipv4 hdr is 1',\n+        #      frozenset({\"Ether() / ARP(hwtype=1) / Raw('\\\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() / ARP(hwtype=2) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ARP(hwtype=3) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ARP(hwtype=6) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ARP(hwtype-15) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # 'pro':\n+        #     ('arp_eth_ipv4 pro is 0x0800',\n+        #      frozenset({\"Ether() / ARP(ptype=0x0800) / Raw('\\\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() / ARP(ptype=0x0800) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ARP(ptype=0x0842) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ARP(ptype=0x6004) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ARP(ptype=0x809b) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        #\n+        # 'hln':\n+        #     ('arp_eth_ipv4 hln is 6',\n+        #      frozenset({\"Ether() / ARP(hwlen=6) / Raw('\\\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() / ARP(hwlen=12) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ARP(hwlen=2) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ARP(hwlen=8) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ARP(hwlen=4) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        #\n+        # 'pln':\n+        #     ('arp_eth_ipv4 pln is 4',\n+        #      frozenset({\"Ether() / ARP(plen=4) / Raw('\\\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() / ARP(plen=6) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ARP(plen=2) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ARP(plen=8) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ARP(plen=12) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        #\n+        # 'op':\n+        #     ('arp_eth_ipv4 op is 1',\n+        #      frozenset({\"Ether() / ARP(op=1) / Raw('\\\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() / ARP(op=2) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ARP(op=3) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ARP(op=4) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ARP(op=5) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # END UNSUPPORTED PROPERTIES\n+        \"sha\": (\n+            \"arp_eth_ipv4 sha is 90:61:ae:fd:41:43\",\n+            frozenset(\n+                {\"Ether() / ARP(hwsrc=\\\"90:61:ae:fd:41:43\\\") / Raw('\\\\x00' * 64)\"}\n+            ),\n+            frozenset(\n+                {\n+                    \"Ether() / ARP(hwsrc=\\\"90:61:ae:fd:41:44\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ARP(hwsrc=\\\"90:61:ae:fd:41:45\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ARP(hwsrc=\\\"90:61:ae:fd:41:46\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ARP(hwsrc=\\\"90:61:ae:fd:41:47\\\") / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"spa\": (\n+            \"arp_eth_ipv4 spa is 192.168.0.80\",\n+            frozenset({\"Ether() / ARP(psrc=\\\"192.168.0.80\\\") / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / ARP(psrc=\\\"10.0.30.10\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ARP(psrc=\\\"8.8.8.8\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ARP(psrc=\\\"132.177.0.5\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ARP(psrc=\\\"123.4.5.6\\\") / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"tha\": (\n+            \"arp_eth_ipv4 tha is 00:00:00:00:00:00\",\n+            frozenset({\"Ether() / ARP(hwdst=00:00:00:00:00:00) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / ARP(hwdst=90:61:ae:fd:41:45) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ARP(hwdst=90:61:ae:fd:41:46) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ARP(hwdst=90:61:ae:fd:41:47) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ARP(hwdst=90:61:ae:fd:41:48) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"tpa\": (\n+            \"arp_eth_ipv4 tpa is 192.168.0.1\",\n+            frozenset({\"Ether() / ARP(pdst=192.168.0.1) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / ARP(pdst=10.0.30.10) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ARP(pdst=8.8.8.8) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ARP(pdst=132.177.0.5) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ARP(pdst=123.4.5.6) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+    }\n+\n+\n+class FlowItemEth(PatternFlowItem):\n+    type = FlowItemType.ETH\n+    valid_next_items = list(\n+        ALWAYS_ALLOWED_ITEMS\n+        | L3_FLOW_TYPES\n+        | {FlowItemType.VLAN, FlowItemType.ARP_ETH_IPV4}\n+    )\n+    valid_parent_items: List[FlowItemType] = list({})\n+    # Matches an Ethernet header (not Ethernet frame).\n+\n+    \"\"\"\n+    - ``dst``: destination MAC.\n+    - ``src``: source MAC.\n+    - ``type``: EtherType or TPID. (TPID value is 0x8100, any others are normal EtherType)\n+    - Default ``mask`` matches destination and source addresses only.\n+    \"\"\"\n+    possible_properties = {\n+        \"dst\": (\n+            \"eth dst is 90:61:ae:fd:41:43\",\n+            frozenset({\"Ether(dst=\\\"90:61:ae:fd:41:43\\\") / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether(dst=\\\"90:61:ae:fd:41:44\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether(dst=\\\"90:61:ae:fd:41:45\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether(dst=\\\"90:61:ae:fd:41:46\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether(dst=\\\"91:61:ae:fd:41:43\\\") / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"src\": (\n+            \"eth src is 90:61:ae:fd:41:43\",\n+            frozenset({\"Ether(src=\\\"90:61:ae:fd:41:43\\\") / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether(src=\\\"90:61:ae:fd:41:44\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether(src=\\\"90:61:ae:fd:41:45\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether(src=\\\"90:61:ae:fd:41:46\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether(src=\\\"91:61:ae:fd:41:43\\\") / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"type\": (\n+            \"eth type is 0x0800\",  # IPv4 EtherType\n+            frozenset({\"Ether(type=0x0800) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether(type=0x0842) / Raw('\\\\x00' * 64)\",\n+                    \"Ether(type=0x8100) / Raw('\\\\x00' * 64)\",  # Possibly a special case? TPID/VLAN\n+                    \"Ether(type=0x9100) / Raw('\\\\x00' * 64)\",  # Possibly special, VLAN double tagging\n+                    \"Ether(type=0x8863) / Raw('\\\\x00' * 64)\",\n+                    \"Ether(type=0x9000) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+    }\n+\n+\n+class FlowItemGre(PatternFlowItem):\n+    type = FlowItemType.GRE\n+    valid_next_items = list(L3_FLOW_TYPES | ALWAYS_ALLOWED_ITEMS)\n+    valid_parent_items: List[FlowItemType] = [FlowItemType.IPV4, FlowItemType.IPV6]\n+    \"\"\"\n+    - ``c_rsvd0_ver``: checksum, reserved 0 and version.\n+    - ``protocol``: protocol type.\n+    - Default ``mask`` matches protocol only.\n+    \"\"\"\n+    possible_properties = {\n+        \"c_rsvd0_ver\": (\n+            \"gre c_rsvd0_ver is 0\",\n+            frozenset(\n+                {\"Ether() / GRE(chksum_present=0, version=0) / Raw('\\\\x00' * 64)\"}\n+            ),\n+            frozenset(\n+                {\n+                    \"Ether() / GRE(chksum_present=1, version=0)) / Raw('\\\\x00' * 64)\",\n+                    # this is the only other option\n+                }\n+            ),\n+        ),\n+        \"protocol\": (\n+            \"gre protocol is 0x0800\",\n+            frozenset({\"Ether() / GRE(proto=0x0800) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / GRE(proto=0x0842) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / GRE(proto=0x8100) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / GRE(proto=0x0806) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / GRE(proto=0x809B) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+    }\n+\n+\n+class FlowItemIcmp(PatternFlowItem):\n+    type = FlowItemType.ICMP\n+    valid_next_items = list({FlowItemType.RAW, FlowItemType.VOID})\n+    valid_parent_items: List[FlowItemType] = [FlowItemType.IPV4]\n+    \"\"\"\n+    - ``hdr``: ICMP header definition (``rte_icmp.h``).\n+    This definition includes:\n+    icmp_type (8 bits; for IPv4 echo request it's \"8\")\n+    icmp_code (8 bits)\n+    THE FOLLOWING ARE NOT SUPPORTED IN TESTPMD:\n+    icmp_cksum (16 bits)\n+    icmp_ident (16 bits)\n+    icmp_seq_nb (16 bits)\n+    - Default ``mask`` matches ICMP type and code only.\n+    \"\"\"\n+    possible_properties = {\n+        # THE FOLLOWING PROPERTIES ARE UNSUPPORTED BY TESTPMD AT THE TIME OF WRITING.\n+        # THEY CAN BE ENABLED ONCE TESTPMD SUPPORTS THEM\n+        # 'icmp_cksum':\n+        #     ('icmp cksum is 0x0800',\n+        #      frozenset({\"Ether() / ICMP() / UDP() / Raw('\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() / ICMP() / UDP() / Raw('\\x00' * 64)\",\n+        #                 \"Ether() / ICMP() / UDP() / Raw('\\x00' * 64)\",\n+        #                 \"Ether() / ICMP() / UDP() / Raw('\\x00' * 64)\",\n+        #                 \"Ether() / ICMP() / UDP() / Raw('\\x00' * 64)\"\n+        #                 })),\n+        # END UNSUPPORTED PROPERTIES\n+        \"icmp_type\": (\n+            \"icmp type is 3\",\n+            frozenset({\"Ether() / ICMP(type=3) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / ICMP(type=3) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ICMP(type=11) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ICMP(type=13) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ICMP(type=0) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"icmp_code\": (\n+            \"icmp type is 3 code is 3\",  # Assume type 3 code 3; code meanings/options are dependent on type.\n+            frozenset({\"Ether() / ICMP(type=3, code=3) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / ICMP(type=3, code=0) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ICMP(type=3, code=2) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ICMP(type=11, code=1) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ICMP(type=12, code=2) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"icmp_ident\": (\n+            \"icmp ident is 0x0800\",\n+            frozenset({\"Ether() / ICMP() / UDP() / Raw('\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / ICMP() / UDP() / Raw('\\x00' * 64)\",\n+                    \"Ether() / ICMP() / UDP() / Raw('\\x00' * 64)\",\n+                    \"Ether() / ICMP() / UDP() / Raw('\\x00' * 64)\",\n+                    \"Ether() / ICMP() / UDP() / Raw('\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"icmp_seq\": (\n+            \"icmp seq is 0x0800\",\n+            frozenset({\"Ether() / ICMP(proto=0x0800) / UDP() / Raw('\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / ICMP() / UDP() / Raw('\\x00' * 64)\",\n+                    \"Ether() / ICMP() / UDP() / Raw('\\x00' * 64)\",\n+                    \"Ether() / ICMP() / UDP() / Raw('\\x00' * 64)\",\n+                    \"Ether() / ICMP() / UDP() / Raw('\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+    }\n+\n+\n+class FlowItemIcmp6(PatternFlowItem):\n+    type = FlowItemType.ICMP6\n+    valid_next_items = list({FlowItemType.RAW, FlowItemType.VOID})\n+    valid_parent_items: List[FlowItemType] = [FlowItemType.IPV6]\n+    \"\"\"\n+    - ``type``: ICMPv6 type.\n+    - ``code``: ICMPv6 code.\n+    - ``checksum``: ICMPv6 checksum.\n+    - Default ``mask`` matches ``type`` and ``code``.\n+    \"\"\"\n+    possible_properties = {\n+        # THE FOLLOWING PROPERTIES ARE UNSUPPORTED BY TESTPMD AT THE TIME OF WRITING.\n+        # THEY CAN BE ENABLED ONCE TESTPMD SUPPORTS THEM\n+        # 'checksum':\n+        #     ('icmp6 cksum is 0x1234',\n+        #      frozenset({\"Ether() / ICMPv6DestUnreach(cksum=0x1234) / Raw('\\\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() / ICMPv6DestUnreach(cksum=0x4321) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ICMPv6DestUnreach(cksum=0xffff) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ICMPv6DestUnreach(cksum=0x1233) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / ICMPv6DestUnreach(cksum=0x1010) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # END UNSUPPORTED PROPERTIES\n+        \"type\": (\n+            \"icmp6 type is 1\",  # Destination Unreachable\n+            frozenset({\"Ether() / ICMPv6DestUnreach(type=1) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / ICMPv6DestUnreach(type=128) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ICMPv6DestUnreach(type=129) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ICMPv6DestUnreach(type=3) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ICMPv6DestUnreach(type=135) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"code\": (  # ICMP code is dependent on type; these are possible Destination Unreachable codes\n+            \"icmp6 code is 0\",\n+            frozenset({\"Ether() / ICMPv6DestUnreach(code=0) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / ICMPv6DestUnreach(code=1) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ICMPv6DestUnreach(code=2) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ICMPv6DestUnreach(code=3) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / ICMPv6DestUnreach(code=4) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+    }\n+\n+\n+class FlowItemIpv4(PatternFlowItem):\n+    type = FlowItemType.IPV4\n+    valid_next_items = list(L4_FLOW_ITEMS | {FlowItemType.ICMP} | ALWAYS_ALLOWED_ITEMS)\n+    valid_parent_items: List[FlowItemType] = [FlowItemType.ETH, FlowItemType.GRE]\n+    \"\"\"\n+    Note: IPv4 options are handled by dedicated pattern items.\n+    \n+    - ``hdr``: IPv4 header definition (``rte_ip.h``).\n+    - Default ``mask`` matches source and destination addresses only.\n+    \"\"\"\n+\n+    possible_properties = {\n+        \"tos\": (\n+            \"ipv4 tos is 0\",\n+            frozenset({\"Ether() / IP(tos=0) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IP(tos=2) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP(tos=4) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP(tos=8) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP(tos=16) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"ttl\": (\n+            \"ipv4 ttl is 64\",\n+            frozenset({\"Ether() / IP(ttl=64) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IP(ttl=128) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP(ttl=255) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP(ttl=32)  / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP(ttl=100) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"proto\": (\n+            \"ipv4 proto is 0x06\",  # TCP\n+            frozenset({\"Ether() / IP(proto=0x06) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IP(proto=0x01) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP(proto=0x11) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP(proto=0x12) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP(proto=0x58) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"src\": (\n+            \"ipv4 src is 192.168.0.5\",\n+            frozenset({\"Ether() / IP(src=\\\"192.168.0.5\\\") / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IP(src=\\\"10.10.10.10\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP(src=\\\"132.177.127.6\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP(src=\\\"192.168.0.4\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP(src=\\\"192.168.0.250\\\") / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"dst\": (\n+            \"ipv4 dst is 192.168.0.5\",\n+            frozenset({\"Ether() / IP(dst=\\\"192.168.0.5\\\") / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IP(dst=\\\"10.10.10.10\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP(dst=\\\"132.177.127.6\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP(dst=\\\"192.168.0.4\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP(dst=\\\"192.168.0.250\\\") / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        # CHECKSUM PROPERTY NOT SUPPORTED BY TESTPMD; DO NOT UNCOMMENT UNTIL SUPPORTED\n+        # 'checksum':\n+        #     ('ipv4 chksum is 0x1234',\n+        #     frozenset({\"Ether() / ICMPv6DestUnreach(cksum=0x1234) / Raw('\\\\x00' * 64)\"}),\n+        #     frozenset({\"Ether() / ICMPv6DestUnreach(cksum=0x4321) / Raw('\\\\x00' * 64)\",\n+        #                \"Ether() / ICMPv6DestUnreach(cksum=0xffff) / Raw('\\\\x00' * 64)\",\n+        #                \"Ether() / ICMPv6DestUnreach(cksum=0x1233) / Raw('\\\\x00' * 64)\",\n+        #                \"Ether() / ICMPv6DestUnreach(cksum=0x1010) / Raw('\\\\x00' * 64)\"\n+        #                })),\n+        ##########################################################################\n+    }\n+\n+\n+class FlowItemIpv6(PatternFlowItem):\n+    type = FlowItemType.IPV6\n+    valid_next_items = list(L4_FLOW_ITEMS | {FlowItemType.ICMP6} | ALWAYS_ALLOWED_ITEMS)\n+    valid_parent_items: List[FlowItemType] = [FlowItemType.ETH, FlowItemType.GRE]\n+    \"\"\"\n+    Note: IPv6 options are handled by dedicated pattern items, see `Item:\n+    IPV6_EXT`_.\n+    \n+    - ``hdr``: IPv6 header definition (``rte_ip.h``).\n+    - Default ``mask`` matches source and destination addresses only.\n+    \"\"\"\n+\n+    possible_properties = {\n+        # THE FOLLOWING PROPERTIES ARE UNSUPPORTED BY TESTPMD AT THE TIME OF WRITING.\n+        # THEY CAN BE ENABLED ONCE TESTPMD SUPPORTS THEM\n+        # 'vtc_flow':\n+        #     ('ipv6 vtc_flow is 0x0',\n+        #      frozenset({\"Ether() / IPv6(tc=0, fl=0, version=0) / Raw('\\\\x00' * 64)\"}),\n+        #      frozenset({\"Ether() / IPv6(tc=1, fl=0, version=0) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / IPv6(tc=0, fl=0xABCD, version=0) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / IPv6(tc=0, fl=0, version=1) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / IPv6(tc=6, fl=0x9999, version=1) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # 'payload_len':\n+        #     ('ipv6 payload_len is 64',\n+        #      frozenset({\"Ether() / IPv6(plen=64) / Raw('\\\\x00' * 64)\"}),\n+        #      frozenset({\"Ether() / IPv6(plen=32) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / IPv6(plen=128) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / IPv6(plen=5000) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / IPv6(plen=4) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # END UNSUPPORTED PROPERTIES\n+        \"tc\": (\n+            \"ipv6 tc is 0\",\n+            frozenset({\"Ether() / IPv6(tc=0) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IPv6(tc=1) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(tc=2) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(tc=4) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(tc=6) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"flow\": (\n+            \"ipv6 flow is 0xABCD\",\n+            frozenset({\"Ether() / IPv6(fl=0xABCD) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IPv6(fl=0xABCE) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(fl=0x0001) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(fl=0xFFFF) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(fl=0x1234) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"proto\": (  # next header (nh)\n+            \"ipv6 proto is 6\",  # TCP\n+            frozenset({\"Ether() / IPv6(nh=6) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IPv6(nh=17) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(nh=41) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(nh=0) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(nh=60) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"hop\": (  # hop limit\n+            \"ipv6 hop is 64\",\n+            frozenset({\"Ether() / IPv6(hlim=64) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IPv6(hlim=128) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(hlim=32) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(hlim=255) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(hlim=100) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"dst\": (\n+            \"ipv6 dst is 2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c2\",\n+            frozenset(\n+                {\n+                    \"Ether() / IPv6(dst=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c2\\\") / Raw('\\\\x00' * 64)\"\n+                }\n+            ),\n+            frozenset(\n+                {\n+                    \"Ether() / IPv6(dst=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c3\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(dst=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c4\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(dst=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c5\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(dst=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c6\\\") / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"src\": (\n+            \"ipv6 src is 2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c2\",\n+            frozenset(\n+                {\n+                    \"Ether() / IPv6(src=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c2\\\") / Raw('\\\\x00' * 64)\"\n+                }\n+            ),\n+            frozenset(\n+                {\n+                    \"Ether() / IPv6(src=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c3\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(src=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c4\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(src=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c5\\\") / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IPv6(src=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c6\\\") / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+    }\n+\n+\n+class FlowItemSctp(PatternFlowItem):\n+    type = FlowItemType.SCTP\n+    valid_next_items = list(ALWAYS_ALLOWED_ITEMS)\n+    valid_parent_items: List[FlowItemType] = [FlowItemType.IPV4, FlowItemType.IPV6]\n+    \"\"\"\n+    \n+    **chunks?\n+    - ``hdr``: SCTP header definition (``rte_sctp.h``).\n+    - Default ``mask`` matches source and destination ports only.\n+    \"\"\"\n+    possible_properties = {\n+        \"src\": (\n+            \"sctp src is 3838\",\n+            frozenset({\"Ether() / IP() / SCTP(sport=3838) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IP() / SCTP(sport=3939) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / SCTP(sport=5000) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / SCTP(sport=1998) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / SCTP(sport=1028) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"dst\": (\n+            \"sctp dst is 3838\",\n+            frozenset({\"Ether() / IP() / SCTP(dport=3838) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IP() / SCTP(dport=3939) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / SCTP(dport=5000) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / SCTP(dport=1998) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / SCTP(dport=1028) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"tag\": (\n+            \"sctp tag is 12345\",\n+            frozenset({\"Ether() / IP() / SCTP(tag=12345) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IP() / SCTP(tag=12346) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / SCTP(tag=12) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / SCTP(tag=9999) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / SCTP(tag=42) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"cksum\": (\n+            \"sctp cksum is 0x01535b67\",\n+            frozenset({\"Ether() / IP() / SCTP(chksum=0x01535b67) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IP() / SCTP(chksum=0x01535b68) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / SCTP(chksum=0xdeadbeef) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / SCTP(chksum=0x12345678) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / SCTP(chksum=0x385030fe) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+    }\n+\n+\n+class FlowItemTcp(PatternFlowItem):\n+    type = FlowItemType.TCP\n+    valid_next_items = list(ALWAYS_ALLOWED_ITEMS)\n+    valid_parent_items: List[FlowItemType] = [FlowItemType.IPV4, FlowItemType.IPV6]\n+    \"\"\"\n+    - ``hdr``: TCP header definition (``rte_tcp.h``).\n+    - Default ``mask`` matches source and destination ports only.\n+    \n+    #define \tRTE_TCP_CWR_FLAG   0x80\n+\n+    #define \tRTE_TCP_ECE_FLAG   0x40\n+\n+    #define \tRTE_TCP_URG_FLAG   0x20\n+\n+    #define \tRTE_TCP_ACK_FLAG   0x10\n+\n+    #define \tRTE_TCP_PSH_FLAG   0x08\n+\n+    #define \tRTE_TCP_RST_FLAG   0x04\n+\n+    #define \tRTE_TCP_SYN_FLAG   0x02\n+\n+    #define \tRTE_TCP_FIN_FLAG   0x01\n+\n+    Can we set multiple flags at once in testing (ex. SYN, ACK)?\n+    Probably, and we can definitely test them if necessary.\n+    \"\"\"\n+    possible_properties = {\n+        # THE FOLLOWING PROPERTIES ARE UNSUPPORTED BY TESTPMD AT THE TIME OF WRITING.\n+        # THEY CAN BE ENABLED ONCE TESTPMD SUPPORTS THEM\n+        # 'data_off':\n+        #     ('tcp data_off is 0',\n+        #      frozenset({\"Ether() / IP() / TCP(dataofs=0) / Raw('\\\\x00' * 64)\"}),\n+        #      frozenset({\"Ether() /  IP() / TCP(dataofs=1) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / TCP(dataofs=2) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / TCP(dataofs=3) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / TCP(dataofs=4) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # 'rx_win':\n+        #     ('tcp rx_win is 64',\n+        #      frozenset({\"Ether() /  IP() / TCP(window=64)/ Raw('\\\\x00' * 64)\"}),\n+        #      frozenset({\"Ether() /  IP() / TCP(window=16)/ Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / TCP(window=128) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / TCP(window=32) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / TCP(window=255) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # 'cksum':\n+        #     ('tcp cksum is 0x1234',\n+        #      frozenset({\"Ether() /  IP() / TCP(chksum=0x1234) / Raw('\\\\x00' * 64)\"}),\n+        #      frozenset({\"Ether() / IP() / TCP(chksum=0x4321) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / TCP(chksum=0xffff) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / TCP(chksum=0x9999) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / TCP(chksum=0x1233)  / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # END UNSUPPORTED PROPERTIES\n+        \"src\": (\n+            \"tcp src is 3838\",\n+            frozenset({\"Ether() / IP() / TCP(sport=3838) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IP() / TCP(sport=3939) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / TCP(sport=5000) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / TCP(sport=1998) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / TCP(sport=1028) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"dst\": (\n+            \"tcp dst is 3838\",\n+            frozenset({\"Ether() / IP() / TCP(dport=3838) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IP() / TCP(dport=3939) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / TCP(dport=5000) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / TCP(dport=1998) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / TCP(dport=1028) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"flags\": (\n+            \"tcp flags is 0x02\",\n+            frozenset({\"Ether() / IP() / TCP(flags=0x02) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IP() / TCP(flags=0x01) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / TCP(flags=0x04) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / TCP(flags=0x08) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / TCP(flags=0x10) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+    }\n+\n+\n+class FlowItemUdp(PatternFlowItem):\n+    type = FlowItemType.UDP\n+    valid_next_items = list(\n+        {FlowItemType.VXLAN, FlowItemType.VXLAN_GPE} | ALWAYS_ALLOWED_ITEMS\n+    )\n+    valid_parent_items: List[FlowItemType] = [FlowItemType.IPV4, FlowItemType.IPV6]\n+    \"\"\"\n+    - ``hdr``: UDP header definition (``rte_udp.h``).\n+    - Default ``mask`` matches source and destination ports only.\n+    \"\"\"\n+\n+    possible_properties = {\n+        # THE FOLLOWING PROPERTIES ARE UNSUPPORTED BY TESTPMD AT THE TIME OF WRITING.\n+        # THEY MAY BE RE-ENABLED ONCE TESTPMD SUPPORTS THEIR USE\n+        # 'dgram_len':\n+        #     ('udp dgram_len is 64',\n+        #      frozenset({\"Ether() / IP() / UDP(len=64) / Raw('\\\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() /  IP() / UDP(len=128) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / UDP(len=32) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / UDP(len=16) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / UDP(len=255) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # 'dgram_cksum':\n+        #     ('udp dgram_cksum is 0x1234',\n+        #      frozenset({\"Ether() /  IP() / UDP(chksum=0x1234) / Raw('\\\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() / IP() / UDP(chksum=0x4321) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / UDP(chksum=0xffff) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / UDP(chksum=0x9999) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / UDP(chksum=0x1233)  / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # END UNSUPPORTED PROPERTIES\n+        \"src\": (\n+            \"udp src is 3838\",\n+            frozenset({\"Ether() / IP() / UDP(sport=3838) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IP() / UDP(sport=3939) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / UDP(sport=5000) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / UDP(sport=1998) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / UDP(sport=1028) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"dst\": (\n+            \"udp dst is 3838\",\n+            frozenset({\"Ether() / IP() / UDP(dport=3838) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IP() / UDP(dport=3939) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / UDP(dport=5000) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / UDP(dport=1998) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / UDP(dport=1028) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+    }\n+\n+\n+class FlowItemVlan(PatternFlowItem):\n+    type = FlowItemType.VLAN\n+    valid_next_items = list(ALWAYS_ALLOWED_ITEMS)\n+    valid_parent_items: List[FlowItemType] = [FlowItemType.ETH]\n+    \"\"\"\n+    The corresponding standard outer EtherType (TPID) values are\n+    ``RTE_ETHER_TYPE_VLAN`` or ``RTE_ETHER_TYPE_QINQ``. It can be overridden by the\n+    preceding pattern item.\n+    If a ``VLAN`` item is present in the pattern, then only tagged packets will\n+    match the pattern.\n+    \n+    - ``tci``: tag control information.\n+    - ``inner_type``: inner EtherType or TPID.\n+    - Default ``mask`` matches the VID part of TCI only (lower 12 bits).\n+    \n+    tci in testpmd = pcp, dei, and vid, altogether.\n+    \n+    pcp in testpmd = prio in scapy\n+    dei in testpmd = id in scapy? \n+    vid in testpmd = vlan in scapy\n+    \n+    tpid in testpmd = type in scapy\n+    \"\"\"\n+    possible_properties = {\n+        # THE FOLLOWING PROPERTIES ARE UNSUPPORTED BY TESTPMD AT THE TIME OF WRITING.\n+        # THEY MAY BE RE-ENABLED ONCE TESTPMD SUPPORTS THEIR USE\n+        # 'tpid':\n+        #     ('vlan tpid is 0x8100',  # standard value\n+        #      frozenset({\"Ether() / Dot1Q(type=0x8100) / Raw('\\\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() /  Dot1Q(type=0x0800) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  Dot1Q(type=0x0842) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  Dot1Q(type=0x809b) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  Dot1Q(type=0x86dd) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # END UNSUPPORTED PROPERTIES\n+        \"tci\": (\n+            \"vlan tci is 0xaaaa\",\n+            frozenset(\n+                {\n+                    \"Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / Raw('\\\\x00' * 64)\"\n+                }\n+            ),\n+            frozenset(\n+                {\n+                    \"Ether() /  Dot1Q(prio = 0x0, id = 0x1, vlan = 0xbbb) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() /  Dot1Q(prio = 0x5, id = 0x0, vlan = 0xccc) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() /  Dot1Q(prio = 0x5, id = 0x1, vlan = 0xaaa) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() /  Dot1Q(prio = 0x4, id = 0x0, vlan = 0xaaa) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"pcp\": (\n+            \"vlan pcp is 0x0\",\n+            frozenset({\"Ether() / Dot1Q(prio=0x0) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() /  Dot1Q(prio=0x1) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() /  Dot1Q(prio=0x2) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() /  Dot1Q(prio=0x3) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() /  Dot1Q(prio=0x7) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+        \"dei\": (\n+            \"vlan dei is 0\",\n+            frozenset({\"Ether() / Dot1Q(id=0) / Raw('\\\\x00' * 64)\"}),\n+            frozenset({\"Ether() /  Dot1Q(id=1) / Raw('\\\\x00' * 64)\"}),\n+        ),\n+        \"vid\": (\n+            \"vlan vid is 0xabc\",\n+            frozenset({\"Ether() / Dot1Q(vlan=0xabc) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() /  Dot1Q(vlan=0xaaa) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() /  Dot1Q(vlan=0x123) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() /  Dot1Q(vlan=0x1f5) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() /  Dot1Q(vlan=0x999) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+    }\n+\n+\n+class FlowItemVxlan(PatternFlowItem):\n+    type = FlowItemType.VXLAN\n+    valid_next_items = frozenset({FlowItemType.ETH} | ALWAYS_ALLOWED_ITEMS)\n+    valid_parent_items: FrozenSet[FlowItemType] = frozenset({FlowItemType.UDP})\n+    \"\"\"\n+    - ``flags``: normally 0x08 (I flag).\n+    - ``rsvd0``: reserved, normally 0x000000.\n+    - ``vni``: VXLAN network identifier.\n+    - ``rsvd1``: reserved, normally 0x00.\n+    - Default ``mask`` matches VNI only.\n+    \n+    TESTPMD ONLY SUPPORTS VNI.\n+    \"\"\"\n+\n+    possible_properties = {\n+        # THE FOLLOWING PROPERTIES ARE UNSUPPORTED BY TESTPMD AT THE TIME OF WRITING.\n+        # THEY CAN BE ENABLED ONCE TESTPMD SUPPORTS THEM\n+        # 'rsvd0':\n+        #     ('vxlan rsvd0 is 0x000000',\n+        #      frozenset({\"Ether() / IP() / VXLAN(reserved0=0) / Raw('\\\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() /  IP() / VXLAN(reserved0=1) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() /  VXLAN(reserved0=2) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() /  VXLAN(reserved0=3) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP()  / VXLAN(reserved0=4) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # 'rsvd1':\n+        #     ('vxlan rsvd1 is 0x00',\n+        #      frozenset({\"Ether() /  IP() /  VXLAN(reserved0=0) / Raw('\\\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() / IP() /  VXLAN(reserved0=1) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() /  VXLAN(reserved0=2) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / VXLAN(reserved0=3) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() /  VXLAN(reserved0=4) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # 'flags':\n+        #     ('vxlan flags is 0x08',\n+        #      frozenset({\"Ether() /  IP() /  VXLAN(flags=0x08) / Raw('\\\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() / IP() /  VXLAN(flags=0x80) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() /  VXLAN(flags=0x00) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / VXLAN(flags=0x99) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() /  VXLAN(flags=0x01) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # END UNSUPPORTED PROPERTIES\n+        \"vni\": (  # a 3-byte value\n+            \"vxlan vni is 0x112233\",\n+            frozenset({\"Ether() / IP() / VXLAN(vni=0x112233) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IP() / VXLAN(vni=0x112234) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / VXLAN(vni=0x123456) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / VXLAN(vni=0xaabbcc) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / VXLAN(vni=0x999999) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+    }\n+\n+\n+class FlowItemVxlan_gpe(PatternFlowItem):\n+    type = FlowItemType.VXLAN_GPE\n+    valid_next_items = list({FlowItemType.ETH} | ALWAYS_ALLOWED_ITEMS)\n+    valid_parent_items: List[FlowItemType] = [FlowItemType.UDP]\n+    \"\"\"\n+    - ``flags``: normally 0x0C (I and P flags).\n+    - ``rsvd0``: reserved, normally 0x0000.\n+    - ``protocol``: protocol type. => NextProtocol?\n+    - ``vni``: VXLAN network identifier.\n+    - ``rsvd1``: reserved, normally 0x00.\n+    - Default ``mask`` matches VNI only.\n+    \n+    NOT CURRENTLY SUPPORTED BY TESTPMD.\n+    \"\"\"\n+\n+    possible_properties = {\n+        # THE FOLLOWING PROPERTIES ARE UNSUPPORTED BY TESTPMD AT THE TIME OF WRITING.\n+        # THEY CAN BE ENABLED ONCE TESTPMD SUPPORTS THEM\n+        # 'rsvd0':\n+        #     ('vxlan rsvd0 is 0x000000',\n+        #      frozenset({\"Ether() / IP() / VXLAN(reserved0=0) / Raw('\\\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() /  IP() / VXLAN(reserved0=1) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() /  VXLAN(reserved0=2) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() /  VXLAN(reserved0=3) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP()  / VXLAN(reserved0=4) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # 'rsvd1':\n+        #     ('vxlan rsvd1 is 0x00',\n+        #      frozenset({\"Ether() /  IP() /  VXLAN(reserved0=0) / Raw('\\\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() / IP() /  VXLAN(reserved0=1) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() /  VXLAN(reserved0=2) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / VXLAN(reserved0=3) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() /  VXLAN(reserved0=4) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # 'flags':\n+        #     ('vxlan flags is 0x08',\n+        #      frozenset({\"Ether() /  IP() /  VXLAN(flags=0x08) / Raw('\\\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() / IP() /  VXLAN(flags=0x80) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() /  VXLAN(flags=0x00) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() / VXLAN(flags=0x99) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() /  IP() /  VXLAN(flags=0x01) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # 'protocol':\n+        #     ('vxlan protocol is 0x01',\n+        #      frozenset({\"Ether() / IP() / VXLAN(NextProtocol=0x01) / Raw('\\\\x00' * 64)\"}),\n+        #\n+        #      frozenset({\"Ether() / IP() / VXLAN(NextProtocol=0x01) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / IP() / VXLAN(NextProtocol=0x11) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / IP() / VXLAN(NextProtocol=0x22) / Raw('\\\\x00' * 64)\",\n+        #                 \"Ether() / IP() / VXLAN(NextProtocol=0x33) / Raw('\\\\x00' * 64)\"\n+        #                 })),\n+        # END UNSUPPORTED PROPERTIES\n+        \"vni\": (  # a 3-byte value\n+            \"vxlan vni is 0x112233\",\n+            frozenset({\"Ether() / IP() / VXLAN(vni=0x112233) / Raw('\\\\x00' * 64)\"}),\n+            frozenset(\n+                {\n+                    \"Ether() / IP() / VXLAN(vni=0x112234) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / VXLAN(vni=0x123456) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / VXLAN(vni=0xaabbcc) / Raw('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / VXLAN(vni=0x999999) / Raw('\\\\x00' * 64)\",\n+                }\n+            ),\n+        ),\n+    }\n+\n+\n+class FlowItemFuzzy(PatternFlowItem):\n+    type = FlowItemType.FUZZY\n+    layer = 1  # This field needs to go before ethernet, and we ignore layer 1 in these filters\n+    valid_next_items = list({FlowItemType.ETH, FlowItemType.RAW, FlowItemType.VOID})\n+    \"\"\"\n+   +----------+---------------+--------------------------------------------------+\n+   | Field    |   Subfield    | Value                                            |\n+   +==========+===============+==================================================+\n+   | ``spec`` | ``threshold`` | 0 as perfect match, 0xffffffff as fuzziest match |\n+   +----------+---------------+--------------------------------------------------+\n+   | ``last`` | ``threshold`` | upper range value                                |\n+   +----------+---------------+--------------------------------------------------+\n+   | ``mask`` | ``threshold`` | bit-mask apply to \"spec\" and \"last\"              |\n+   +----------+---------------+--------------------------------------------------+\n+    \"\"\"\n+\n+\n+class FlowItemMark(PatternFlowItem):\n+    type = FlowItemType.MARK\n+    \"\"\"\n+    +----------+----------+---------------------------+\n+    | Field    | Subfield | Value                     |\n+    +==========+==========+===========================+\n+    | ``spec`` | ``id``   | integer value             |\n+    +----------+--------------------------------------+\n+    | ``last`` | ``id``   | upper range value         |\n+    +----------+----------+---------------------------+\n+    | ``mask`` | ``id``   | zeroed to match any value |\n+    +----------+----------+---------------------------+\n+    \"\"\"\n+\n+\n+class FlowItemMeta(PatternFlowItem):\n+    type = FlowItemType.META\n+    \"\"\"\n+    Matches an application specific 32 bit metadata item.\n+  \n+    - Default ``mask`` matches the specified metadata value.\n+    \"\"\"\n+\n+\n+class FlowItemTag(PatternFlowItem):\n+    type = FlowItemType.TAG\n+    \"\"\"\n+    Matches tag item set by other flows. Multiple tags are supported by specifying\n+    ``index``.\n+    \n+    - Default ``mask`` matches the specified tag value and index.\n+   +----------+----------+----------------------------------------+\n+   | Field    | Subfield  | Value                                 |\n+   +==========+===========+=======================================+\n+   | ``spec`` | ``data``  | 32 bit flow tag value                 |\n+   |          +-----------+---------------------------------------+\n+   |          | ``index`` | index of flow tag                     |\n+   +----------+-----------+---------------------------------------+\n+   | ``last`` | ``data``  | upper range value                     |\n+   |          +-----------+---------------------------------------+\n+   |          | ``index`` | field is ignored                      |\n+   +----------+-----------+---------------------------------------+\n+   | ``mask`` | ``data``  | bit-mask applies to \"spec\" and \"last\" |\n+   |          +-----------+---------------------------------------+\n+   |          | ``index`` | field is ignored                      |\n+   +----------+-----------+---------------------------------------+\n+    \"\"\"\n+\n+\n+PATTERN_ITEMS_TYPE_CLASS_MAPPING: Dict[FlowItemType, PatternFlowItem] = {\n+    FlowItemType.UDP: FlowItemUdp,\n+    FlowItemType.TCP: FlowItemTcp,\n+    FlowItemType.SCTP: FlowItemSctp,\n+    FlowItemType.IPV4: FlowItemIpv4,\n+    FlowItemType.IPV6: FlowItemIpv6,\n+    FlowItemType.ETH: FlowItemEth,\n+    FlowItemType.VLAN: FlowItemVlan,\n+    FlowItemType.VXLAN: FlowItemVxlan,\n+    FlowItemType.GRE: FlowItemGre,\n+    FlowItemType.VXLAN_GPE: FlowItemVxlan_gpe,\n+    FlowItemType.ARP_ETH_IPV4: FlowItemArp_eth_ipv4,\n+    FlowItemType.ICMP: FlowItemIcmp,\n+    FlowItemType.ICMP6: FlowItemIcmp6,\n+    FlowItemType.MARK: FlowItemMark,\n+    FlowItemType.META: FlowItemMeta,\n+    FlowItemType.TAG: FlowItemTag,\n+    FlowItemType.FUZZY: FlowItemFuzzy,\n+    FlowItemType.END: FlowItemEnd,\n+    FlowItemType.VOID: FlowItemVoid,\n+    FlowItemType.INVERT: FlowItemInvert,\n+    FlowItemType.ANY: FlowItemAny,\n+    FlowItemType.RAW: FlowItemRaw,\n+}\n+\n+ITEM_TYPE_SCAPY_CLASS_MAPPING: Dict[FlowItemType, Packet] = {\n+    FlowItemType.UDP: UDP,\n+    FlowItemType.TCP: TCP,\n+    FlowItemType.SCTP: SCTP,\n+    FlowItemType.IPV4: IP,\n+    FlowItemType.IPV6: IPv6,\n+    FlowItemType.ETH: Ether,\n+    FlowItemType.VLAN: Dot1Q,\n+    FlowItemType.VXLAN: VXLAN,\n+    FlowItemType.GRE: GRE,\n+    FlowItemType.VXLAN_GPE: VXLAN,\n+    FlowItemType.ARP_ETH_IPV4: ARP,  # The type rules prevent this from being under anything except Ether / IPv4\n+    FlowItemType.ICMP: ICMP,\n+    FlowItemType.ICMP6: ICMP,\n+    FlowItemType.MARK: None,\n+    FlowItemType.META: None,\n+    FlowItemType.TAG: None,\n+    FlowItemType.FUZZY: None,\n+    FlowItemType.END: None,\n+    FlowItemType.VOID: None,\n+    FlowItemType.INVERT: None,\n+    FlowItemType.ANY: None,\n+    FlowItemType.RAW: None,\n+}\n+\n+TUNNELING_PROTOCOLS = {FlowItemVlan, FlowItemVxlan, FlowItemGre, FlowItemVxlan_gpe}\n+\n+PATTERN_OPERATIONS = {\n+    FlowItemMark,\n+    FlowItemMeta,\n+    FlowItemTag,\n+    FlowItemFuzzy,\n+    FlowItemInvert,\n+}\n",
    "prefixes": [
        "RFC",
        "v1",
        "21/23"
    ]
}