Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/82027/?format=api
https://patches.dpdk.org/api/patches/82027/?format=api", "web_url": "https://patches.dpdk.org/project/dts/patch/20201023232903.37387-3-ohilyard@iol.unh.edu/", "project": { "id": 3, "url": "https://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-3-ohilyard@iol.unh.edu>", "list_archive_url": "https://inbox.dpdk.org/dts/20201023232903.37387-3-ohilyard@iol.unh.edu", "date": "2020-10-23T23:28:58", "name": "[v2,3/7] rte flow: Add base flow type", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "343d01c9624f48e6cf56c79874f6d0c123b12c42", "submitter": { "id": 1829, "url": "https://patches.dpdk.org/api/people/1829/?format=api", "name": "Owen Hilyard", "email": "ohilyard@iol.unh.edu" }, "delegate": null, "mbox": "https://patches.dpdk.org/project/dts/patch/20201023232903.37387-3-ohilyard@iol.unh.edu/mbox/", "series": [ { "id": 13289, "url": "https://patches.dpdk.org/api/series/13289/?format=api", "web_url": "https://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": "https://patches.dpdk.org/series/13289/mbox/" } ], "comments": "https://patches.dpdk.org/api/patches/82027/comments/", "check": "pending", "checks": "https://patches.dpdk.org/api/patches/82027/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 386DDA04DD;\n\tSat, 24 Oct 2020 01:29:23 +0200 (CEST)", "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id B330A685C;\n\tSat, 24 Oct 2020 01:29:21 +0200 (CEST)", "from mail-qk1-f194.google.com (mail-qk1-f194.google.com\n [209.85.222.194]) by dpdk.org (Postfix) with ESMTP id 1C841B62\n for <dts@dpdk.org>; Sat, 24 Oct 2020 01:29:21 +0200 (CEST)", "by mail-qk1-f194.google.com with SMTP id s14so3087797qkg.11\n for <dts@dpdk.org>; Fri, 23 Oct 2020 16:29:21 -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.18\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Fri, 23 Oct 2020 16:29:19 -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=jGOyub4+liwUc1MR0l+4Y/FREf3/hGgyDpj6auij8qk=;\n b=U9Jyz8Y41C1jk7F0gTXQEA638rR3CE9YYzDEE9Y97c9lNie7vEwPlpo3Ncv5RXWvnG\n 3TRqZLg1XtVoQzhnsuODwEZP1+1FzTZzuu0p4/QF/Ki7GegudpwUnuIEROqVoQBqzDDy\n o1ipTXSAmgLA/s4wLICD41sqgWKdqP2lThUdw=", "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=jGOyub4+liwUc1MR0l+4Y/FREf3/hGgyDpj6auij8qk=;\n b=c08AXZGJjAgXNbwtFa7F7j/yOVWZVp4EngPTNSFnchMzfKivwWR9o0DF0pPNCHUZeF\n PFW/ePc0edtRNRRlI/mtY3t1ft7c4p+6Q8x11xtCh00MZBtgu9vifwFW+UVup/5fZjYJ\n q2C+DY1vi3lyW4Y3gLnGbzOUu+d/5SxzbcH51pTdaThgMfkVFXjwChCqbqplBhawZnrS\n doZa2lnLpQqVHL8o3dp3HtPh+c54CEgXphQPOcBA9ZwWd/uLr7YMe6a0JiWqtgCUzgy4\n mVdH26LsXez+ucbohiQxIp1dyG46G1YgbotAzwtrPE9SeLgQXC3gafkaKDqeQpeTer5h\n xRjQ==", "X-Gm-Message-State": "AOAM532hZNMIaQ2yzSFC7RFeT5cXUrFyenFuGRJi0JSJRtYOAL95907U\n JBWgQQ92ylSvjRXIdoHbRCigcA==", "X-Google-Smtp-Source": "\n ABdhPJxnYao5y9swhG/EE+rU/YvbsdTst+Dptfj9oHcyn8C7mA9EegpJpTaIitlOafDLwXXpSAI+vQ==", "X-Received": "by 2002:a37:6285:: with SMTP id\n w127mr4767241qkb.454.1603495759452;\n Fri, 23 Oct 2020 16:29:19 -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:28:58 -0400", "Message-Id": "<20201023232903.37387-3-ohilyard@iol.unh.edu>", "X-Mailer": "git-send-email 2.25.1", "In-Reply-To": "<20201023232903.37387-2-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>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "Subject": "[dts] [PATCH v2 3/7] rte flow: Add base flow type", "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 type acts as a generic base for all flows.\n\nSigned-off-by: Owen Hilyard <ohilyard@iol.unh.edu>\n---\n framework/flow/flow.py | 186 +++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 186 insertions(+)\n create mode 100644 framework/flow/flow.py", "diff": "diff --git a/framework/flow/flow.py b/framework/flow/flow.py\nnew file mode 100644\nindex 0000000..2cce079\n--- /dev/null\n+++ b/framework/flow/flow.py\n@@ -0,0 +1,186 @@\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+from __future__ import annotations\n+\n+import copy\n+import itertools\n+import operator\n+from functools import reduce\n+from typing import List, FrozenSet, Union, Iterable, Tuple\n+\n+from scapy.layers.l2 import Ether\n+\n+from flow.enums import FlowItemType, FlowActionType\n+from flow.exceptions import InvalidFlowItemException\n+from flow.flow_action_items import ActionFlowItem\n+from flow.flow_items import FlowItem\n+from flow.flow_pattern_items import PatternFlowItem, TUNNELING_PROTOCOLS\n+\n+# Get reserved mac addresses\n+NEVER_MATCH_PACKET = Ether(src=\"\", dst=\"\") / ('\\x00' * 64)\n+\n+\n+def _iterable_deep_compare(i1, i2):\n+ return reduce(\n+ lambda x, y: x and y,\n+ map(lambda x, y: x == y, i1, i2),\n+ True\n+ )\n+\n+\n+def expand_pattern_list_with_iterable_replacing_item(patterns: List[Iterable[FlowItem]],\n+ it: Iterable[Tuple[FlowItem, FrozenSet[str], FrozenSet[str], str]],\n+ item):\n+ \"\"\"\n+ This function takes a list of patterns and splits each of them into 2\n+ parts, excluding the item at index. It then uses the provided\n+ iterator to fill in that value for all patterns.\n+\n+ Ex:\n+ if patterns is [['a', 'b', 'c'], ['c','b','a']], it is [1,2], and item is 'b',\n+ then this function will produce\n+\n+ [['a', 1], ['a', 2], ['a', 1], ['a', 2], ['a', 1], ['a', 2]]\n+\n+ if everything is converted into a list. It is not converted\n+ because that requires using the memory to store all of this at\n+ the same time, which could be fairly large.\n+ \"\"\"\n+\n+ split_patterns = list(map(lambda pattern: (pattern[:pattern.index(item)], pattern[pattern.index(item) + 1:],),\n+ filter(lambda pattern: item in pattern, patterns)))\n+ # Tee the iterators so I can consume all of them\n+\n+ iterators = itertools.tee(it, len(patterns))\n+ for pattern_before, pattern_after in split_patterns:\n+ for iterator in iterators:\n+ for dataset in iterator:\n+ backup_dataset = copy.deepcopy(dataset)\n+ yield (\n+ [*pattern_before, backup_dataset[0], *pattern_after],\n+ *backup_dataset[1:],\n+ )\n+ # yield from map(\n+ # lambda flow_item_test_properties: (\n+ # [*pattern_before, flow_item_test_properties[0], *pattern_after],\n+ # *flow_item_test_properties[1:],\n+ # ), iterator\n+ # )\n+\n+ yield from filter(lambda pattern: item not in pattern, patterns)\n+\n+\n+class Flow(object):\n+ action_items: List[ActionFlowItem]\n+ pattern_items: List[PatternFlowItem]\n+ entry_points: FrozenSet[FlowItemType]\n+\n+ def __init__(self, action_items=None, pattern_items=None, ):\n+ if action_items is None:\n+ action_items = []\n+\n+ if pattern_items is None:\n+ pattern_items = []\n+\n+ self.action_items = action_items\n+ self.pattern_items = pattern_items\n+\n+ def __truediv__(self, item: Union[FlowItem, Flow]):\n+ \"\"\"\n+ Used in a similar way to scapy's packet composition. Returns a new flow with the mutated state.\n+ @param item: The other flow item.\n+ @return: A Flow containing both items\n+ \"\"\"\n+ if isinstance(item, Flow):\n+ return Flow(pattern_items=[*self.pattern_items, *item.pattern_items],\n+ action_items=[*self.action_items, *item.action_items])\n+ elif isinstance(item, PatternFlowItem):\n+ if len(self.pattern_items) == 0:\n+ return Flow(pattern_items=[*self.pattern_items, item], action_items=[*self.action_items])\n+ elif item.type in self.pattern_items[-1].valid_next_items:\n+ return Flow(pattern_items=[*self.pattern_items, item], action_items=[*self.action_items])\n+ else:\n+ raise InvalidFlowItemException(self.pattern_items[-1], item, flow=self)\n+ elif isinstance(item, ActionFlowItem):\n+ if len(self.action_items) == 0:\n+ return Flow(pattern_items=[*self.pattern_items], action_items=[*self.action_items, item])\n+\n+ for action in self.action_items:\n+ if item.type not in action.allowed_with:\n+ raise InvalidFlowItemException(action, item, flow=self)\n+ return Flow(pattern_items=[*self.pattern_items], action_items=[*self.action_items, item])\n+\n+ def __str__(self):\n+ return f\"ingress pattern %s actions queue index 1 / end\" % (\n+ \" / \".join(str(item) for item in self.pattern_items) + \" / end\")\n+\n+ def __repr__(self):\n+ return str(self)\n+\n+ def __eq__(self, other):\n+ return isinstance(other, Flow) and \\\n+ len(self.action_items) == len(other.action_items) and \\\n+ len(self.pattern_items) == len(other.pattern_items) and \\\n+ _iterable_deep_compare(self.pattern_items, other.pattern_items) and \\\n+ _iterable_deep_compare(self.action_items, other.action_items)\n+\n+ def to_scapy_packet(self):\n+ return reduce(operator.truediv, map(lambda x: x.to_scapy_packet(), self.pattern_items))\n+\n+ def get_test_property_flows(self, pattern_item_types_to_update=None, action_item_types_to_update=None) -> \\\n+ Iterable[Flow]:\n+ if pattern_item_types_to_update is None and action_item_types_to_update is None:\n+ pattern_item_types_to_update = [self.pattern_items[-1]]\n+ elif pattern_item_types_to_update is None:\n+ pattern_item_types_to_update = []\n+ elif action_item_types_to_update is None:\n+ action_item_types_to_update = []\n+\n+ # So that if this object is mutated before the generator is finished, it won't change anything\n+ base_pattern_items = copy.deepcopy(self.pattern_items)\n+ base_action_items = copy.deepcopy(self.action_items)\n+\n+ test_flows: Iterable[Iterable[FlowItem]] = [base_pattern_items]\n+\n+ tunnelling_protocols = list(filter(lambda i: type(i) in TUNNELING_PROTOCOLS, base_pattern_items))\n+ if len(tunnelling_protocols) > 0:\n+ test_flows = expand_pattern_list_with_iterable_replacing_item([*test_flows],\n+ tunnelling_protocols[0].get_property_stream(),\n+ tunnelling_protocols[0])\n+ else:\n+ test_flows = expand_pattern_list_with_iterable_replacing_item([*test_flows],\n+ self.pattern_items[\n+ -1].get_property_stream(),\n+ self.pattern_items[-1])\n+ for pattern in test_flows:\n+ yield Flow(pattern_items=pattern[0], action_items=base_action_items), *pattern[1:]\n", "prefixes": [ "v2", "3/7" ] }{ "id": 82027, "url": "