get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 82029,
    "url": "http://patches.dpdk.org/api/patches/82029/?format=api",
    "web_url": "http://patches.dpdk.org/project/dts/patch/20201023232903.37387-6-ohilyard@iol.unh.edu/",
    "project": {
        "id": 3,
        "url": "http://patches.dpdk.org/api/projects/3/?format=api",
        "name": "DTS",
        "link_name": "dts",
        "list_id": "dts.dpdk.org",
        "list_email": "dts@dpdk.org",
        "web_url": "",
        "scm_url": "git://dpdk.org/tools/dts",
        "webscm_url": "http://git.dpdk.org/tools/dts/",
        "list_archive_url": "https://inbox.dpdk.org/dts",
        "list_archive_url_format": "https://inbox.dpdk.org/dts/{}",
        "commit_url_format": ""
    },
    "msgid": "<20201023232903.37387-6-ohilyard@iol.unh.edu>",
    "list_archive_url": "https://inbox.dpdk.org/dts/20201023232903.37387-6-ohilyard@iol.unh.edu",
    "date": "2020-10-23T23:29:01",
    "name": "[v2,6/7] rte flow: add pattern items",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "7cb22b74d382172985b1c555837aa3c895a52926",
    "submitter": {
        "id": 1829,
        "url": "http://patches.dpdk.org/api/people/1829/?format=api",
        "name": "Owen Hilyard",
        "email": "ohilyard@iol.unh.edu"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dts/patch/20201023232903.37387-6-ohilyard@iol.unh.edu/mbox/",
    "series": [
        {
            "id": 13289,
            "url": "http://patches.dpdk.org/api/series/13289/?format=api",
            "web_url": "http://patches.dpdk.org/project/dts/list/?series=13289",
            "date": "2020-10-23T23:28:57",
            "name": "[v2,1/7] rte flow: add test plan and test suite",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/13289/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/82029/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/82029/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dts-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 37DFDA04B0;\n\tSat, 24 Oct 2020 01:29:27 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 2958F68F0;\n\tSat, 24 Oct 2020 01:29:26 +0200 (CEST)",
            "from mail-qt1-f174.google.com (mail-qt1-f174.google.com\n [209.85.160.174]) by dpdk.org (Postfix) with ESMTP id 759A768C3\n for <dts@dpdk.org>; Sat, 24 Oct 2020 01:29:24 +0200 (CEST)",
            "by mail-qt1-f174.google.com with SMTP id c15so2577120qtc.2\n for <dts@dpdk.org>; Fri, 23 Oct 2020 16:29:24 -0700 (PDT)",
            "from ohilyard-Alienware-m17.iol.unh.edu (nt-238-66.w4.unh.edu.\n [132.177.238.66])\n by smtp.googlemail.com with ESMTPSA id j16sm1851673qkg.26.2020.10.23.16.29.21\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Fri, 23 Oct 2020 16:29:22 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=iol.unh.edu;\n s=unh-iol;\n h=from:to:cc:subject:date:message-id:in-reply-to:references\n :mime-version:content-transfer-encoding;\n bh=+Zcz5JQ1sblTVTdk0BnOPDxicxSDjxw5YzKWfhjBAhE=;\n b=JMvs5MUPlrSApCUgUoJiFp6SCiDVJAeSqDD+MrzCJ+3fQqno0hRLYT18b6VRqzr7K/\n yVW1XWFnQ7Mi29ayy767Secol7uvPh+xKHc1Fhs4TrpDUoSwiQ4NrNmNvAxvjQlxhbyS\n U3/3s7ezEd938bYsGWL7WguD1XAGIwv8WVBNE=",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20161025;\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=+Zcz5JQ1sblTVTdk0BnOPDxicxSDjxw5YzKWfhjBAhE=;\n b=MFjabzX3flWE6vFwtF5G5D8whhd/aekpntozZ25mxZDLu4m8uznEhW4M0lDrk9RBak\n 4tjZq2LGiSntO7IHxXQp6XYcOxkONUUh6oK/7IeoDm1j6qQyZBI/haRGb3v09jsPn05s\n 7dzF+10912/QJvigLuREhIacD9qZg1p5a/NZ8HCuj7hidRYkimkO8eU/cA41c/l2rxzg\n MdGnU5LUXi8iX1BXG/8CaGf2/onyOzZ1xCifOQZLwJVQDycpRrBMOVBLofDG2bzBdsRV\n Wt8p8b94AqZkfF8cFvVy+YhFyWWSN5T/QySCXO86vJbK8hg1qbclmI2JkDf6tB4xMC2i\n 4aCQ==",
        "X-Gm-Message-State": "AOAM531casa42DDafH+fCo4UQQsR849ltosBbNK+BE8ci/DZRN4sRnu6\n iN3RyE/QzIP0K5ffhXDLv6HAug==",
        "X-Google-Smtp-Source": "\n ABdhPJyQjMQsEUYw1mwK5MuIKOSlZUcIL2iQ8Va2NaF97QyIsqlfyRI3Xpbpoxlxu2AAx25/aV+DaQ==",
        "X-Received": "by 2002:ac8:24c3:: with SMTP id t3mr4567081qtt.46.1603495762548;\n Fri, 23 Oct 2020 16:29:22 -0700 (PDT)",
        "From": "Owen Hilyard <ohilyard@iol.unh.edu>",
        "To": "ohilyard@iol.unh.edu,\n\tdts@dpdk.org,\n\tlijuan.tu@intel.com",
        "Cc": "shall@iol.unh.edu, lihongx.ma@intel.com, lylavoie@iol.unh.edu,\n zhaoyan.chen@intel.com, yuan.peng@intel.com",
        "Date": "Fri, 23 Oct 2020 19:29:01 -0400",
        "Message-Id": "<20201023232903.37387-6-ohilyard@iol.unh.edu>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20201023232903.37387-5-ohilyard@iol.unh.edu>",
        "References": "\n <CAHx6DYCAyA9iXe18+1xd-JqH0N7DKu0fF=ts=bJ3WU_eV1H1Rw@mail.gmail.com>\n <20201023232903.37387-1-ohilyard@iol.unh.edu>\n <20201023232903.37387-2-ohilyard@iol.unh.edu>\n <20201023232903.37387-3-ohilyard@iol.unh.edu>\n <20201023232903.37387-4-ohilyard@iol.unh.edu>\n <20201023232903.37387-5-ohilyard@iol.unh.edu>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dts] [PATCH v2 6/7] rte flow: add pattern items",
        "X-BeenThere": "dts@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "test suite reviews and discussions <dts.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dts>,\n <mailto:dts-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dts/>",
        "List-Post": "<mailto:dts@dpdk.org>",
        "List-Help": "<mailto:dts-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dts>,\n <mailto:dts-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dts-bounces@dpdk.org",
        "Sender": "\"dts\" <dts-bounces@dpdk.org>"
    },
    "content": "This file contains the pattern flow item definitions and supporting information.\n\nSigned-off-by: Owen Hilyard <ohilyard@iol.unh.edu>\n---\n framework/flow/flow_pattern_items.py | 1102 ++++++++++++++++++++++++++\n 1 file changed, 1102 insertions(+)\n create mode 100644 framework/flow/flow_pattern_items.py",
    "diff": "diff --git a/framework/flow/flow_pattern_items.py b/framework/flow/flow_pattern_items.py\nnew file mode 100644\nindex 0000000..bb14306\n--- /dev/null\n+++ b/framework/flow/flow_pattern_items.py\n@@ -0,0 +1,1102 @@\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 FrozenSet, Dict, List, Tuple, Iterable\n+\n+from scapy.layers.inet import UDP, TCP, IP, ICMP\n+from scapy.layers.inet6 import IPv6\n+from scapy.layers.l2 import Ether, Dot1Q, GRE, ARP\n+from scapy.layers.sctp import SCTP\n+from scapy.layers.vxlan import VXLAN\n+from scapy.packet import Packet\n+\n+from flow.enums import FlowItemType\n+from flow.exceptions import InvalidFlowItemException\n+from flow.flow_items import FlowItem\n+\n+ALWAYS_ALLOWED_ITEMS = {\n+    FlowItemType.RAW,\n+    FlowItemType.VOID\n+}\n+L3_FLOW_TYPES = {FlowItemType.IPV4, FlowItemType.IPV6}\n+L4_FLOW_ITEMS = {FlowItemType.UDP, FlowItemType.TCP, FlowItemType.SCTP, FlowItemType.GRE, }\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] = \\\n+        frozenset({item for item in FlowItemType})\n+\n+    valid_next_items: List[FlowItemType] = \\\n+        [item for item in FlowItemType]\n+\n+    # Only used for building a tree upward\n+    valid_parent_items: List[FlowItemType] = \\\n+        [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 \\\n+                other.type == FlowItemType.END:\n+            # This import is in here so there is no circular import\n+            from flow.flow import Flow\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+        'hdr':\n+            ('arp_eth_ipv4 hdr is 1',\n+             frozenset({\"Ether() / ARP(hwtype=1) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / ARP(hwtype=2) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(hwtype=3) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(hwtype=6) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(hwtype-15) / ('\\\\x00' * 64)\"\n+                        })),\n+        'pro':\n+            ('arp_eth_ipv4 pro is 0x0800',\n+             frozenset({\"Ether() / ARP(ptype=0x0800) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / ARP(ptype=0x0800) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(ptype=0x0842) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(ptype=0x6004) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(ptype=0x809b) / ('\\\\x00' * 64)\"\n+                        })),\n+\n+        'hln':\n+            ('arp_eth_ipv4 hln is 6',\n+             frozenset({\"Ether() / ARP(hwlen=6) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / ARP(hwlen=12) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(hwlen=2) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(hwlen=8) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(hwlen=4) / ('\\\\x00' * 64)\"\n+                        })),\n+\n+        'pln':\n+            ('arp_eth_ipv4 pln is 4',\n+             frozenset({\"Ether() / ARP(plen=4) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / ARP(plen=6) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(plen=2) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(plen=8) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(plen=12) / ('\\\\x00' * 64)\"\n+                        })),\n+\n+        'op':\n+            ('arp_eth_ipv4 op is 1',\n+             frozenset({\"Ether() / ARP(op=1) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / ARP(op=2) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(op=3) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(op=4) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(op=5) / ('\\\\x00' * 64)\"\n+                        })),\n+\n+        'sha':\n+            ('arp_eth_ipv4 sha is 90:61:ae:fd:41:43',\n+             frozenset({\"Ether() / ARP(hwsrc=\\\"90:61:ae:fd:41:43\\\") / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / ARP(hwsrc=\\\"90:61:ae:fd:41:44\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(hwsrc=\\\"90:61:ae:fd:41:45\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(hwsrc=\\\"90:61:ae:fd:41:46\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(hwsrc=\\\"90:61:ae:fd:41:47\\\") / ('\\\\x00' * 64)\"\n+                        })),\n+\n+        'spa':\n+            ('arp_eth_ipv4 spa is 192.168.0.80',\n+             frozenset({\"Ether() / ARP(psrc=\\\"192.168.0.80\\\") / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / ARP(psrc=\\\"10.0.30.10\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(psrc=\\\"8.8.8.8\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(psrc=\\\"132.177.0.5\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(psrc=\\\"123.4.5.6\\\") / ('\\\\x00' * 64)\"\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) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / ARP(hwdst=90:61:ae:fd:41:45) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(hwdst=90:61:ae:fd:41:46) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(hwdst=90:61:ae:fd:41:47) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(hwdst=90:61:ae:fd:41:48) / ('\\\\x00' * 64)\"\n+                        })),\n+\n+        'tpa':\n+            ('arp_eth_ipv4 tpa is 192.168.0.1',\n+             frozenset({\"Ether() / ARP(pdst=192.168.0.1) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / ARP(pdst=10.0.30.10) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(pdst=8.8.8.8) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(pdst=132.177.0.5) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ARP(pdst=123.4.5.6) / ('\\\\x00' * 64)\"\n+                        })),\n+\n+    }\n+\n+\n+class FlowItemEth(PatternFlowItem):\n+    type = FlowItemType.ETH\n+    valid_next_items = list(ALWAYS_ALLOWED_ITEMS | L3_FLOW_TYPES | {FlowItemType.VLAN, FlowItemType.ARP_ETH_IPV4})\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\\\") / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether(dst=\\\"90:61:ae:fd:41:44\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether(dst=\\\"90:61:ae:fd:41:45\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether(dst=\\\"90:61:ae:fd:41:46\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether(dst=\\\"91:61:ae:fd:41:43\\\") / ('\\\\x00' * 64)\"\n+                        })),\n+        'src':\n+            ('eth src is 90:61:ae:fd:41:43',\n+             frozenset({\"Ether(src=\\\"90:61:ae:fd:41:43\\\") / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether(src=\\\"90:61:ae:fd:41:44\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether(src=\\\"90:61:ae:fd:41:45\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether(src=\\\"90:61:ae:fd:41:46\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether(src=\\\"91:61:ae:fd:41:43\\\") / ('\\\\x00' * 64)\"\n+                        })),\n+        'type':\n+            ('eth type is 0x0800',  # IPv4 EtherType\n+             frozenset({\"Ether(type=0x0800) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether(type=0x0842) / ('\\\\x00' * 64)\",\n+                        \"Ether(type=0x8100) / ('\\\\x00' * 64)\",  # Possibly a special case? TPID/VLAN\n+                        \"Ether(type=0x9100) / ('\\\\x00' * 64)\",  # Possibly special, VLAN double tagging\n+                        \"Ether(type=0x8863) / ('\\\\x00' * 64)\",\n+                        \"Ether(type=0x9000) / ('\\\\x00' * 64)\"\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({\"Ether() / GRE(chksum_present=0, version=0) / ('\\\\x00' * 64)\"}),\n+\n+           frozenset({\"Ether() / GRE(chksum_present=1, version=0)) / ('\\\\x00' * 64)\", #this is the only other option\n+                      })),\n+        'protocol':\n+            ('gre protocol is 0x0800',\n+             frozenset({\"Ether() / GRE(proto=0x0800) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / GRE(proto=0x0842) / ('\\\\x00' * 64)\",\n+                        \"Ether() / GRE(proto=0x8100) / ('\\\\x00' * 64)\",\n+                        \"Ether() / GRE(proto=0x0806) / ('\\\\x00' * 64)\",\n+                        \"Ether() / GRE(proto=0x809B) / ('\\\\x00' * 64)\"\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+\n+        'icmp_type':\n+            ('icmp type is 3',\n+             frozenset({\"Ether() / ICMP(type=3) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / ICMP(type=3) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ICMP(type=11) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ICMP(type=13) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ICMP(type=0) / ('\\\\x00' * 64)\"\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+\n+             frozenset({\"Ether() / ICMP(type=3, code=3) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / ICMP(type=3, code=0) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ICMP(type=3, code=2) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ICMP(type=11, code=1) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ICMP(type=12, code=2) / ('\\\\x00' * 64)\"\n+                        })),\n+        'icmp_cksum':\n+           ('icmp cksum is 0x0800',\n+            frozenset({\"Ether() / ICMP() / UDP() / ('\\x00' * 64)\"}),\n+\n+            frozenset({\"Ether() / ICMP() / UDP() / ('\\x00' * 64)\",\n+                       \"Ether() / ICMP() / UDP() / ('\\x00' * 64)\",\n+                       \"Ether() / ICMP() / UDP() / ('\\x00' * 64)\",\n+                       \"Ether() / ICMP() / UDP() / ('\\x00' * 64)\"\n+                       })),\n+        'icmp_ident':\n+           ('icmp ident is 0x0800',\n+            frozenset({\"Ether() / ICMP() / UDP() / ('\\x00' * 64)\"}),\n+\n+            frozenset({\"Ether() / ICMP() / UDP() / ('\\x00' * 64)\",\n+                       \"Ether() / ICMP() / UDP() / ('\\x00' * 64)\",\n+                       \"Ether() / ICMP() / UDP() / ('\\x00' * 64)\",\n+                       \"Ether() / ICMP() / UDP() / ('\\x00' * 64)\"\n+                       })),\n+        'icmp_seq_nb':\n+           ('icmp seq_nb is 0x0800',\n+            frozenset({\"Ether() / ICMP(proto=0x0800) / UDP() / ('\\x00' * 64)\"}),\n+\n+            frozenset({\"Ether() / ICMP() / UDP() / ('\\x00' * 64)\",\n+                       \"Ether() / ICMP() / UDP() / ('\\x00' * 64)\",\n+                       \"Ether() / ICMP() / UDP() / ('\\x00' * 64)\",\n+                       \"Ether() / ICMP() / UDP() / ('\\x00' * 64)\"\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+    # ICMP6 NOT SUPPORTED BY TESTPMD.\n+    # DO NOT UNCOMMENT THE FOLLOWING TEST CASES UNTIL IT IS SUPPORTED.\n+    possible_properties = {\n+        'type':\n+            ('icmp6 type is 1',  # Destination Unreachable\n+             frozenset({\"Ether() / ICMPv6DestUnreach(type=1) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / ICMPv6DestUnreach(type=128) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ICMPv6DestUnreach(type=129) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ICMPv6DestUnreach(type=3) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ICMPv6DestUnreach(type=135) / ('\\\\x00' * 64)\"\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) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / ICMPv6DestUnreach(code=1) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ICMPv6DestUnreach(code=2) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ICMPv6DestUnreach(code=3) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ICMPv6DestUnreach(code=4) / ('\\\\x00' * 64)\"\n+                        })),\n+\n+        'checksum':\n+            ('icmp6 cksum is 0x1234',\n+             frozenset({\"Ether() / ICMPv6DestUnreach(cksum=0x1234) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / ICMPv6DestUnreach(cksum=0x4321) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ICMPv6DestUnreach(cksum=0xffff) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ICMPv6DestUnreach(cksum=0x1233) / ('\\\\x00' * 64)\",\n+                        \"Ether() / ICMPv6DestUnreach(cksum=0x1010) / ('\\\\x00' * 64)\"\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+\n+        'tos':\n+            ('ipv4 tos is 0',\n+             frozenset({\"Ether() / IP(tos=0) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP(tos=2) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP(tos=4) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP(tos=8) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP(tos=16) / ('\\\\x00' * 64)\"\n+                        })),\n+        'ttl':\n+            ('ipv4 ttl is 64',\n+             frozenset({\"Ether() / IP(ttl=64) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP(ttl=128) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP(ttl=255) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP(ttl=32)  / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP(ttl=100) / ('\\\\x00' * 64)\"\n+                        })),\n+        'proto':\n+            ('ipv4 proto is 0x06',  # TCP\n+             frozenset({\"Ether() / IP(proto=0x06) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP(proto=0x01) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP(proto=0x11) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP(proto=0x12) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP(proto=0x58) / ('\\\\x00' * 64)\"\n+                        })),\n+        'src':\n+            ('ipv4 src is 192.168.0.5',\n+             frozenset({\"Ether() / IP(src=\\\"192.168.0.5\\\") / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP(src=\\\"10.10.10.10\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP(src=\\\"132.177.127.6\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP(src=\\\"192.168.0.4\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP(src=\\\"192.168.0.250\\\") / ('\\\\x00' * 64)\"\n+                        })),\n+        'dst':\n+            ('ipv4 dst is 192.168.0.5',\n+             frozenset({\"Ether() / IP(dst=\\\"192.168.0.5\\\") / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP(dst=\\\"10.10.10.10\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP(dst=\\\"132.177.127.6\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP(dst=\\\"192.168.0.4\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP(dst=\\\"192.168.0.250\\\") / ('\\\\x00' * 64)\"\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) / ('\\\\x00' * 64)\"}),\n+\n+        #     frozenset({\"Ether() / ICMPv6DestUnreach(cksum=0x4321) / ('\\\\x00' * 64)\",\n+        #                \"Ether() / ICMPv6DestUnreach(cksum=0xffff) / ('\\\\x00' * 64)\",\n+        #                \"Ether() / ICMPv6DestUnreach(cksum=0x1233) / ('\\\\x00' * 64)\",\n+        #                \"Ether() / ICMPv6DestUnreach(cksum=0x1010) / ('\\\\x00' * 64)\"\n+        #                })),\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 are still tested to future proof this test suite.\n+        'vtc_flow':\n+            ('ipv6 vtc_flow is 0x0',\n+             frozenset({\"Ether() / IPv6(tc=0, fl=0, version=0) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IPv6(tc=1, fl=0, version=0) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(tc=0, fl=0xABCD, version=0) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(tc=0, fl=0, version=1) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(tc=6, fl=0x9999, version=1) / ('\\\\x00' * 64)\"\n+                        })),\n+        'payload_len':\n+            ('ipv6 payload_len is 64',\n+             frozenset({\"Ether() / IPv6(plen=64) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IPv6(plen=32) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(plen=128) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(plen=5000) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(plen=4) / ('\\\\x00' * 64)\"\n+                        })),\n+        # END UNSUPPORTED PROPERTIES\n+        'tc':\n+            ('ipv6 tc is 0',\n+             frozenset({\"Ether() / IPv6(tc=0) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IPv6(tc=1) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(tc=2) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(tc=4) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(tc=6) / ('\\\\x00' * 64)\"\n+                        })),\n+        'flow':\n+            ('ipv6 flow is 0xABCD',\n+             frozenset({\"Ether() / IPv6(fl=0xABCD) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IPv6(fl=0xABCE) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(fl=0x0001) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(fl=0xFFFF) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(fl=0x1234) / ('\\\\x00' * 64)\"\n+                        })),\n+        'proto':  # next header (nh)\n+            ('ipv6 proto is 6',  # TCP\n+             frozenset({\"Ether() / IPv6(nh=6) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IPv6(nh=17) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(nh=41) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(nh=0) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(nh=60) / ('\\\\x00' * 64)\"\n+                        })),\n+        'hop':  # hop limit\n+            ('ipv6 hop is 64',\n+             frozenset({\"Ether() / IPv6(hlim=64) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IPv6(hlim=128) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(hlim=32) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(hlim=255) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(hlim=100) / ('\\\\x00' * 64)\"\n+                        })),\n+        'dst':\n+            ('ipv6 dst is 2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c2',\n+             frozenset({\"Ether() / IPv6(dst=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c2\\\") / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IPv6(dst=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c3\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(dst=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c4\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(dst=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c5\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(dst=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c6\\\") / ('\\\\x00' * 64)\"\n+                        })),\n+        'src':\n+            ('ipv6 src is 2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c2',\n+             frozenset({\"Ether() / IPv6(src=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c2\\\") / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IPv6(src=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c3\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(src=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c4\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(src=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c5\\\") / ('\\\\x00' * 64)\",\n+                        \"Ether() / IPv6(src=\\\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c6\\\") / ('\\\\x00' * 64)\"\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+\n+        'src':\n+            ('sctp src is 3838',\n+             frozenset({\"Ether() / IP() / SCTP(sport=3838) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP() / SCTP(sport=3939) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / SCTP(sport=5000) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / SCTP(sport=1998) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / SCTP(sport=1028) / ('\\\\x00' * 64)\"\n+                        })),\n+\n+        'dst':\n+            ('sctp dst is 3838',\n+             frozenset({\"Ether() / IP() / SCTP(dport=3838) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP() / SCTP(dport=3939) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / SCTP(dport=5000) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / SCTP(dport=1998) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / SCTP(dport=1028) / ('\\\\x00' * 64)\"\n+                        })),\n+        'tag':\n+            ('sctp tag is 12345',\n+             frozenset({\"Ether() / IP() / SCTP(tag=12345) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP() / SCTP(tag=12346) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / SCTP(tag=12) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / SCTP(tag=9999) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / SCTP(tag=42) / ('\\\\x00' * 64)\"\n+                        })),\n+\n+        'cksum':\n+            ('sctp cksum is 0x01535b67',\n+             frozenset({\"Ether() / IP() / SCTP(chksum=0x01535b67) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP() / SCTP(chksum=0x01535b68) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / SCTP(chksum=0xdeadbeef) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / SCTP(chksum=0x12345678) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / SCTP(chksum=0x385030fe) / ('\\\\x00' * 64)\"\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 are still tested to future proof this test suite.\n+        'data_off':\n+            ('tcp data_off is 0',\n+             frozenset({\"Ether() / IP() / TCP(dataofs=0) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() /  IP() / TCP(dataofs=1) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / TCP(dataofs=2) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / TCP(dataofs=3) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / TCP(dataofs=4) / ('\\\\x00' * 64)\"\n+                        })),\n+        'rx_win':\n+            ('tcp rx_win is 64',\n+             frozenset({\"Ether() /  IP() / TCP(window=64)/ ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() /  IP() / TCP(window=16)/ ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / TCP(window=128) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / TCP(window=32) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / TCP(window=255) / ('\\\\x00' * 64)\"\n+                        })),\n+        'cksum':\n+            ('tcp cksum is 0x1234',\n+             frozenset({\"Ether() /  IP() / TCP(chksum=0x1234) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP() / TCP(chksum=0x4321) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / TCP(chksum=0xffff) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / TCP(chksum=0x9999) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / TCP(chksum=0x1233)  / ('\\\\x00' * 64)\"\n+                        })),\n+        # END UNSUPPORTED PROPERTIES\n+        'src':\n+            ('tcp src is 3838',\n+             frozenset({\"Ether() / IP() / TCP(sport=3838) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP() / TCP(sport=3939) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / TCP(sport=5000) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / TCP(sport=1998) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / TCP(sport=1028) / ('\\\\x00' * 64)\"\n+                        })),\n+\n+        'dst':\n+            ('tcp dst is 3838',\n+             frozenset({\"Ether() / IP() / TCP(dport=3838) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP() / TCP(dport=3939) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / TCP(dport=5000) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / TCP(dport=1998) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / TCP(dport=1028) / ('\\\\x00' * 64)\"\n+                        })),\n+        'flags':\n+            ('tcp flags is 0x02',\n+             frozenset({\"Ether() / IP() / TCP(flags=0x02) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP() / TCP(flags=0x01) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / TCP(flags=0x04) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / TCP(flags=0x08) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / TCP(flags=0x10) / ('\\\\x00' * 64)\"\n+                        }))\n+\n+    }\n+\n+\n+class FlowItemUdp(PatternFlowItem):\n+    type = FlowItemType.UDP\n+    valid_next_items = list({FlowItemType.VXLAN, FlowItemType.VXLAN_GPE} | ALWAYS_ALLOWED_ITEMS)\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 are still tested to future proof this test suite.\n+        'dgram_len':\n+            ('udp dgram_len is 64',\n+             frozenset({\"Ether() / IP() / UDP(len=64) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() /  IP() / UDP(len=128) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / UDP(len=32) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / UDP(len=16) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / UDP(len=255) / ('\\\\x00' * 64)\"\n+                        })),\n+        'dgram_cksum':\n+            ('udp dgram_cksum is 0x1234',\n+             frozenset({\"Ether() /  IP() / UDP(chksum=0x1234) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP() / UDP(chksum=0x4321) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / UDP(chksum=0xffff) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / UDP(chksum=0x9999) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / UDP(chksum=0x1233)  / ('\\\\x00' * 64)\"\n+                        })),\n+        # END UNSUPPORTED PROPERTIES\n+\n+        'src':\n+            ('udp src is 3838',\n+             frozenset({\"Ether() / IP() / UDP(sport=3838) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP() / UDP(sport=3939) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / UDP(sport=5000) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / UDP(sport=1998) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / UDP(sport=1028) / ('\\\\x00' * 64)\"\n+                        })),\n+\n+        'dst':\n+            ('udp dst is 3838',\n+             frozenset({\"Ether() / IP() / UDP(dport=3838) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP() / UDP(dport=3939) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / UDP(dport=5000) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / UDP(dport=1998) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / UDP(dport=1028) / ('\\\\x00' * 64)\"\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+\n+        'tci':\n+            ('vlan tci is 0xaaaa',\n+             frozenset({\"Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() /  Dot1Q(prio = 0x0, id = 0x1, vlan = 0xbbb) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  Dot1Q(prio = 0x5, id = 0x0, vlan = 0xccc) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  Dot1Q(prio = 0x5, id = 0x1, vlan = 0xaaa) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  Dot1Q(prio = 0x4, id = 0x0, vlan = 0xaaa) / ('\\\\x00' * 64)\"\n+                        })),\n+\n+        'pcp':\n+            ('vlan pcp is 0x0',\n+             frozenset({\"Ether() / Dot1Q(prio=0x0) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() /  Dot1Q(prio=0x1) /  ('\\\\x00' * 64)\",\n+                        \"Ether() /  Dot1Q(prio=0x2) /  ('\\\\x00' * 64)\",\n+                        \"Ether() /  Dot1Q(prio=0x3) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  Dot1Q(prio=0x7) / ('\\\\x00' * 64)\"\n+                        })),\n+        'dei':\n+            ('vlan dei is 0',\n+             frozenset({\"Ether() / Dot1Q(id=0) /  ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() /  Dot1Q(id=1) / ('\\\\x00' * 64)\"\n+                        })),\n+\n+        'vid':\n+            ('vlan vid is 0xabc',\n+             frozenset({\"Ether() / Dot1Q(vlan=0xabc) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() /  Dot1Q(vlan=0xaaa) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  Dot1Q(vlan=0x123) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  Dot1Q(vlan=0x1f5) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  Dot1Q(vlan=0x999) / ('\\\\x00' * 64)\"\n+                        })),\n+\n+        'tpid':\n+            ('vlan tpid is 0x8100',  # standard value\n+             frozenset({\"Ether() / Dot1Q(type=0x8100) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() /  Dot1Q(type=0x0800) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  Dot1Q(type=0x0842) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  Dot1Q(type=0x809b) / ('\\\\x00' * 64)\",\n+                        \"Ether() /  Dot1Q(type=0x86dd) / ('\\\\x00' * 64)\"\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+\n+possible_properties = {\n+    # THE FOLLOWING PROPERTIES ARE UNSUPPORTED BY TESTPMD AT THE TIME OF WRITING.\n+    # They are still tested to future proof this test suite.\n+    'rsvd0':\n+        ('vxlan rsvd0 is 0x000000',\n+         frozenset({\"Ether() / IP() / VXLAN(reserved0=0) / ('\\\\x00' * 64)\"}),\n+\n+         frozenset({\"Ether() /  IP() / VXLAN(reserved0=1) /  ('\\\\x00' * 64)\",\n+                    \"Ether() /  IP() /  VXLAN(reserved0=2) /  ('\\\\x00' * 64)\",\n+                    \"Ether() /  IP() /  VXLAN(reserved0=3) /  ('\\\\x00' * 64)\",\n+                    \"Ether() /  IP()  / VXLAN(reserved0=4) /  ('\\\\x00' * 64)\"\n+                    })),\n+    'rsvd1':\n+        ('vxlan rsvd1 is 0x00',\n+         frozenset({\"Ether() /  IP() /  VXLAN(reserved0=0) /  ('\\\\x00' * 64)\"}),\n+\n+         frozenset({\"Ether() / IP() /  VXLAN(reserved0=1) /  ('\\\\x00' * 64)\",\n+                    \"Ether() /  IP() /  VXLAN(reserved0=2) /  ('\\\\x00' * 64)\",\n+                    \"Ether() /  IP() / VXLAN(reserved0=3) /  ('\\\\x00' * 64)\",\n+                    \"Ether() /  IP() /  VXLAN(reserved0=4) /  ('\\\\x00' * 64)\"\n+                    })),\n+    'flags':\n+        ('vxlan flags is 0x08',\n+         frozenset({\"Ether() /  IP() /  VXLAN(flags=0x08) /  ('\\\\x00' * 64)\"}),\n+\n+         frozenset({\"Ether() / IP() /  VXLAN(flags=0x80) /  ('\\\\x00' * 64)\",\n+                    \"Ether() /  IP() /  VXLAN(flags=0x00) /  ('\\\\x00' * 64)\",\n+                    \"Ether() /  IP() / VXLAN(flags=0x99) /  ('\\\\x00' * 64)\",\n+                    \"Ether() /  IP() /  VXLAN(flags=0x01) /  ('\\\\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) / ('\\\\x00' * 64)\"}),\n+\n+         frozenset({\"Ether() / IP() / VXLAN(vni=0x112234) / ('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / VXLAN(vni=0x123456) / ('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / VXLAN(vni=0xaabbcc) / ('\\\\x00' * 64)\",\n+                    \"Ether() / IP() / VXLAN(vni=0x999999) / ('\\\\x00' * 64)\"\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+    # THE FOLLOWING PROPERTIES ARE UNSUPPORTED BY TESTPMD AT THE TIME OF WRITING.\n+    # They are still tested to future proof this test suite.\n+    possible_properties = {\n+\n+        'rsvd0':\n+            ('vxlan rsvd0 is 0x000000',\n+             frozenset({\"Ether() / IP() / VXLAN(reserved0=0) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() /  IP() / VXLAN(reserved0=1) /  ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() /  VXLAN(reserved0=2) /  ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() /  VXLAN(reserved0=3) /  ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP()  / VXLAN(reserved0=4) /  ('\\\\x00' * 64)\"\n+                        })),\n+        'rsvd1':\n+            ('vxlan rsvd1 is 0x00',\n+             frozenset({\"Ether() /  IP() /  VXLAN(reserved0=0) /  ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP() /  VXLAN(reserved0=1) /  ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() /  VXLAN(reserved0=2) /  ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / VXLAN(reserved0=3) /  ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() /  VXLAN(reserved0=4) /  ('\\\\x00' * 64)\"\n+                        })),\n+        'flags':\n+            ('vxlan flags is 0x08',\n+             frozenset({\"Ether() /  IP() /  VXLAN(flags=0x08) /  ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP() /  VXLAN(flags=0x80) /  ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() /  VXLAN(flags=0x00) /  ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() / VXLAN(flags=0x99) /  ('\\\\x00' * 64)\",\n+                        \"Ether() /  IP() /  VXLAN(flags=0x01) /  ('\\\\x00' * 64)\"\n+                        })),\n+\n+        'vni':  # a 3-byte value\n+            ('vxlan vni is 0x112233',\n+             frozenset({\"Ether() / IP() / VXLAN(vni=0x112233) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP() / VXLAN(vni=0x112234) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / VXLAN(vni=0x123456) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / VXLAN(vni=0xaabbcc) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / VXLAN(vni=0x999999) / ('\\\\x00' * 64)\"\n+                        })),\n+        'protocol':\n+            ('vxlan protocol is 0x01',\n+             frozenset({\"Ether() / IP() / VXLAN(NextProtocol=0x01) / ('\\\\x00' * 64)\"}),\n+\n+             frozenset({\"Ether() / IP() / VXLAN(NextProtocol=0x01) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / VXLAN(NextProtocol=0x11) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / VXLAN(NextProtocol=0x22) / ('\\\\x00' * 64)\",\n+                        \"Ether() / IP() / VXLAN(NextProtocol=0x33) / ('\\\\x00' * 64)\"\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 = {\n+    FlowItemVlan,\n+    FlowItemVxlan,\n+    FlowItemGre,\n+    FlowItemVxlan_gpe\n+}\n+\n+PATTERN_OPERATIONS = {\n+    FlowItemMark,\n+    FlowItemMeta,\n+    FlowItemTag,\n+    FlowItemFuzzy,\n+    FlowItemInvert,\n+}\n",
    "prefixes": [
        "v2",
        "6/7"
    ]
}