Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/109321/?format=api
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" ] }{ "id": 109321, "url": "