From patchwork Wed Apr 6 15:18:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Juraj_Linke=C5=A1?= X-Patchwork-Id: 109319 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: 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]) by inbox.dpdk.org (Postfix) with ESMTP id 685F0A0509; Wed, 6 Apr 2022 17:21:34 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2D9D542978; Wed, 6 Apr 2022 17:19:31 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id 15B1C42966 for ; Wed, 6 Apr 2022 17:19:28 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id 6D5D1129C28; Wed, 6 Apr 2022 17:19:27 +0200 (CEST) X-Virus-Scanned: amavisd-new at siecit.sk Received: from lb.pantheon.sk ([127.0.0.1]) by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id azlPRA1ht7vk; Wed, 6 Apr 2022 17:19:24 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id 9500D19E0DE; Wed, 6 Apr 2022 17:19:15 +0200 (CEST) From: =?utf-8?q?Juraj_Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= Subject: [RFC PATCH v1 19/23] dts: merge DTS framework/flow/flow_action_items.py to DPDK Date: Wed, 6 Apr 2022 15:18:59 +0000 Message-Id: <20220406151903.2916254-20-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 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --- dts/framework/flow/flow_action_items.py | 1597 +++++++++++++++++++++++ 1 file changed, 1597 insertions(+) create mode 100644 dts/framework/flow/flow_action_items.py diff --git a/dts/framework/flow/flow_action_items.py b/dts/framework/flow/flow_action_items.py new file mode 100644 index 0000000000..1542bd9225 --- /dev/null +++ b/dts/framework/flow/flow_action_items.py @@ -0,0 +1,1597 @@ +# BSD LICENSE +# +# Copyright(c) 2020 Intel Corporation. All rights reserved. +# Copyright © 2018[, 2019] The University of New Hampshire. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from typing import Dict, FrozenSet, Tuple + +from .enums import FlowActionType +from .flow_items import FlowItem + +ALWAYS_ALLOWED_ACTIONS = {FlowActionType.VOID} + +ENTRY_POINTS = { + FlowActionType.VOID, + FlowActionType.PASSTHRU, + FlowActionType.FLAG, + FlowActionType.DROP, + FlowActionType.COUNT, + FlowActionType.MAC_SWAP, + FlowActionType.DEC_TTL, + FlowActionType.JUMP, + FlowActionType.MARK, + FlowActionType.QUEUE, + FlowActionType.RSS, + FlowActionType.PF, + FlowActionType.VF, + FlowActionType.PHY_PORT, + FlowActionType.PORT_ID, + FlowActionType.SECURITY, + FlowActionType.OF_SET_MPLS_TTL, + FlowActionType.OF_DEC_MPLS_TTL, + FlowActionType.OF_SET_NW_TTL, + FlowActionType.OF_DEC_NW_TTL, + FlowActionType.OF_COPY_TTL_OUT, + FlowActionType.OF_COPY_TTL_IN, + FlowActionType.OF_POP_VLAN, + FlowActionType.OF_PUSH_VLAN, + FlowActionType.OF_SET_VLAN_VID, + FlowActionType.OF_SET_VLAN_PCP, + FlowActionType.OF_POP_MPLS, + FlowActionType.OF_PUSH_MPLS, + FlowActionType.VXLAN_ENCAP, + FlowActionType.VXLAN_DECAP, + FlowActionType.NVGRE_ENCAP, + FlowActionType.NVGRE_DECAP, + FlowActionType.RAW_ENCAP, + FlowActionType.RAW_DECAP, + FlowActionType.SET_IPV4_SRC, + FlowActionType.SET_IPV4_DST, + FlowActionType.SET_IPV6_SRC, + FlowActionType.SET_IPV6_DST, + FlowActionType.SET_TP_SRC, + FlowActionType.SET_TP_DST, + FlowActionType.SET_TTL, + FlowActionType.SET_MAC_SRC, + FlowActionType.SET_MAC_DST, + FlowActionType.INC_TCP_SEQ, + FlowActionType.DEC_TCP_SEQ, + FlowActionType.INC_TCP_ACK, + FlowActionType.DEC_TCP_ACK, + FlowActionType.SET_TAG, + FlowActionType.SET_META, + FlowActionType.SET_IPV4_DSCP, + FlowActionType.SET_IPV6_DSCP, + FlowActionType.AGE, +} + + +class ActionFlowItem(FlowItem): + allowed_with: FrozenSet[FlowActionType] = frozenset( + {item for item in FlowActionType} + ) + + valid_next_items: FrozenSet[FlowActionType] = frozenset( + {item for item in FlowActionType} + ) + + test_case: Dict[str, Tuple[str, frozenset, frozenset]] = dict() + + +class FlowActionVoid(ActionFlowItem): + type = FlowActionType.VOID + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions void / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionPassthru(ActionFlowItem): + type = FlowActionType.PASSTHRU + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions passthru / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionFlag(ActionFlowItem): + type = FlowActionType.FLAG + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions flag / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionDrop(ActionFlowItem): + type = FlowActionType.DROP + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions drop / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionCount(ActionFlowItem): + type = FlowActionType.COUNT + test_case = { + "test_shared": ( + "ingress pattern eth / ipv4 src is 192.168.0.1" + " / udp / end actions count shared 0 id 1 / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + "test_id": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions count id 1 / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionMac_swap(ActionFlowItem): + type = FlowActionType.MAC_SWAP + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions mac_swap / end", + frozenset( + { + 'Ether(src="90:61:ae:fd:41:43", dst = "ab:cd:ef:12:34:56") ' + "/ IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + 'Ether(src="90:61:ae:fd:41:43", dst = "ab:cd:ef:12:34:56") ' + "/ IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + 'Ether(src="90:61:ae:fd:41:43", dst = "ab:cd:ef:12:34:56") ' + "/ IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + 'Ether(src="90:61:ae:fd:41:43", dst = "ab:cd:ef:12:34:56") ' + "/ IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + 'Ether(src="90:61:ae:fd:41:43", dst = "ab:cd:ef:12:34:56") ' + "/ IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionDec_ttl(ActionFlowItem): + type = FlowActionType.DEC_TTL + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions dec_ttl / end", + frozenset( + { + "Ether() / IP(src=\"192.168.0.1\", ttl = 128) / UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\", ttl = 128) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\", ttl = 128) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\", ttl = 128 ) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\", ttl = 128) / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionJump(ActionFlowItem): + type = FlowActionType.JUMP + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions jump group 1 / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionMark(ActionFlowItem): + type = FlowActionType.MARK + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions mark id 0xABCDEF / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionQueue(ActionFlowItem): + type = FlowActionType.QUEUE + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions queue index 1 / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionRss(ActionFlowItem): + type = FlowActionType.RSS + + # RSS already has a test suite. + """ + test_case = { + 'case1': ('ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions / end', + frozenset({"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"}), + frozenset({"Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)"})), + } + """ + + +class FlowActionPf(ActionFlowItem): + type = FlowActionType.PF + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions pf / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionVf(ActionFlowItem): + type = FlowActionType.VF + test_case = { + "test_original": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 /" + " udp / end actions vf original 1/ end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + "test_id": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions vf id 1 / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionPhy_port(ActionFlowItem): + type = FlowActionType.PHY_PORT + + test_case = { + # original port index + "test_original": ( + "ingress pattern eth / ipv4 src is 192.168.0.1" + " / udp / end actions phy_port original / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + # physical port index + "test_index": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions phy_port index 1 / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionPort_id(ActionFlowItem): + type = FlowActionType.PORT_ID + + test_case = { + # original DPDK port ID + "test_original": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions port_id original / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + # DPDK port ID + "test_id": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions port_id id 1 / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionMeter(ActionFlowItem): + type = FlowActionType.METER + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions meter mtr_id 1 / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionSecurity(ActionFlowItem): + type = FlowActionType.SECURITY + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1" + " / udp / end actions security security_session 1 / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionOf_set_mpls_ttl(ActionFlowItem): + type = FlowActionType.OF_SET_MPLS_TTL + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions of_set_mpls_ttl mpls_ttl 64 / end", + frozenset( + { + 'Ether() / IP(src="192.168.0.1") / MPLS(label = 0xab, ttl=128)' + " / UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\\x00' * 64)", + 'Ether() / IP(src="132.177.0.99") / MPLS(label = 0xab, ttl=128)' + " / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionOf_dec_mpls_ttl(ActionFlowItem): + type = FlowActionType.OF_DEC_MPLS_TTL + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions of_dec_mpls_ttl / end", + frozenset( + { + "Ether() / IP(src=\"192.168.0.1\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionOf_set_nw_ttl(ActionFlowItem): + type = FlowActionType.OF_SET_NW_TTL + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions of_set_nw_ttl nw_ttl 64 / end", + frozenset( + { + "Ether() / IP(src=\"192.168.0.1\", ttl=128) / UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\", ttl=128) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\", ttl=128) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\", ttl=128) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\", ttl=128) / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionOf_dec_nw_ttl(ActionFlowItem): + type = FlowActionType.OF_DEC_NW_TTL + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions of_dec_nw_ttl / end", + frozenset( + { + "Ether() / IP(src=\"192.168.0.1\", ttl=128) / UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\", ttl=128) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\", ttl=128) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\", ttl=128) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\", ttl=128) / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionOf_copy_ttl_out(ActionFlowItem): + type = FlowActionType.OF_COPY_TTL_OUT + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions of_copy_ttl_out / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionOf_copy_ttl_in(ActionFlowItem): + type = FlowActionType.OF_COPY_TTL_IN + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions of_copy_ttl_out / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionOf_pop_vlan(ActionFlowItem): + type = FlowActionType.OF_POP_VLAN + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions of_pop_vlan / end", + frozenset( + { + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="192.168.0.1") ' + "/ UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="192.168.0.2") ' + "/ UDP() / Raw('\\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="10.0.30.99") ' + "/ UDP() / Raw('\\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="8.8.8.8") ' + "/ UDP() / Raw('\\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="132.177.0.99")' + " / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionOf_push_vlan(ActionFlowItem): + type = FlowActionType.OF_PUSH_VLAN + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1" + " / udp / end actions of_push_vlan ethertype 0x8100 / end", + frozenset( + { + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="192.168.0.1") ' + "/ UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="192.168.0.2") ' + "/ UDP() / Raw('\\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="10.0.30.99") ' + "/ UDP() / Raw('\\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="8.8.8.8") ' + "/ UDP() / Raw('\\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="132.177.0.99")' + " / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionOf_set_vlan_vid(ActionFlowItem): + type = FlowActionType.OF_SET_VLAN_VID + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions of_set_vlan_vid vlan_vid 0xbbb / end", + frozenset( + { + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="192.168.0.1")' + " / UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="192.168.0.2") ' + "/ UDP() / Raw('\\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="10.0.30.99") ' + "/ UDP() / Raw('\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="8.8.8.8") ' + "/ UDP() / Raw('\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="132.177.0.99") ' + "/ UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionOf_set_vlan_pcp(ActionFlowItem): + type = FlowActionType.OF_SET_VLAN_PCP + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1" + " / udp / end actions of_set_vlan_vid vlan_pcp 0x7 / end", + frozenset( + { + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="192.168.0.1") ' + "/ UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="192.168.0.2") ' + "/ UDP() / Raw('\\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="10.0.30.99") ' + "/ UDP() / Raw('\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="8.8.8.8") ' + "/ UDP() / Raw('\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xaaa) / IP(src="132.177.0.99") ' + "/ UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionOf_pop_mpls(ActionFlowItem): + type = FlowActionType.OF_POP_MPLS + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions of_pop_mpls ethertype 0x0806 / end", + frozenset( + { + "Ether() / IP(src=\"192.168.0.1\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionOf_push_mpls(ActionFlowItem): + type = FlowActionType.OF_PUSH_MPLS + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1" + " / udp / end actions of_push_mpls ethertype 0x0806 / end", + frozenset( + { + "Ether() / IP(src=\"192.168.0.1\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / MPLS(label = 0xab, ttl=128) / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionVxlan_encap(ActionFlowItem): + type = FlowActionType.VXLAN_ENCAP + + test_case = { + # VXLAN encap definition is the VNI? + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1" + " / udp / end actions vxlan_encap definition 0x112233 / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionVxlan_decap(ActionFlowItem): + type = FlowActionType.VXLAN_DECAP + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions vxlan_decap / end", + frozenset( + { + "Ether() / IP(src=\"192.168.0.1\") / UDP() / VXLAN() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / VXLAN() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / VXLAN() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / VXLAN() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / VXLAN() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionNvgre_encap(ActionFlowItem): + type = FlowActionType.NVGRE_ENCAP + # NVGRE PACKETS NOT SUPPORTED BY SCAPY. + """ + test_case = { + 'test': ('ingress pattern eth / ipv4 src is 192.168.0.1 + / udp / end actions nvgre_encap definition 0x112233 / end', + frozenset({"Ether() / IP(src=\"192.168.0.1\") / UDP() / NVGRE() / Raw('\\x00' * 64)"}), + frozenset({"Ether() / IP(src=\"192.168.0.2\") / UDP() / NVGRE() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / NVGRE() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / NVGRE() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / NVGRE() / Raw('\\x00' * 64)"})), + } + """ + + +class FlowActionNvgre_decap(ActionFlowItem): + type = FlowActionType.NVGRE_DECAP + # NVGRE PACKETS NOT SUPPORTED BY SCAPY. + """ + test_case = { + 'test': ('ingress pattern eth / ipv4 src is 192.168.0.1 / udp / end actions nvgre_decap / end', + frozenset({"Ether() / IP(src=\"192.168.0.1\") / UDP() / NVGRE() / Raw('\\x00' * 64)"}), + frozenset({"Ether() / IP(src=\"192.168.0.2\") / UDP() / NVGRE() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / NVGRE() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / NVGRE() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / NVGRE() / Raw('\\x00' * 64)"})), + } + """ + + +class FlowActionRaw_encap(ActionFlowItem): + type = FlowActionType.RAW_ENCAP + # Assume we are encapsulating with a VLAN header with the following values: + # TPID: 0x8100 + # Prio: 0x5 + # PCP: 0 + # VID: 0xaaa + # This makes the full header: 0x8100aaaa + test_case = { + "test_data": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions raw_encap data 0x8100aaaa / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + "test_preserve": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions raw_encap data 0x8100aaaa preserve 0xffffffff / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + # Is "size" in bits or bytes? Unclear in documentation, defaulting to bits. + "test_size": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions raw_encap data 0x8100aaaa size 32 / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionRaw_decap(ActionFlowItem): + type = FlowActionType.RAW_DECAP + test_case = { + "test_data": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions raw_decap data 0x8100aaaa / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xbbb) / IP(src="192.168.0.2")' + " / UDP() / Raw('\\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xbbb) / IP(src="10.0.30.99") ' + "/ UDP() / Raw('\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xbbb) / IP(src="8.8.8.8")' + " / UDP() / Raw('\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xbbb) / IP(src="132.177.0.99") ' + "/ UDP() / Raw('\\x00' * 64)", + } + ), + ), + # Is "size" in bits or bytes? Unclear in documentation, defaulting to bits. + "test_size": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions raw_decap data 0x8100aaaa size 32 / end", + frozenset( + { + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xbbb) / IP(src="192.168.0.1") ' + "/ UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xbbb) / IP(src="192.168.0.2") ' + "/ UDP() / Raw('\\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xbbb) / IP(src="10.0.30.99")' + " / UDP() / Raw('\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xbbb) / IP(src="8.8.8.8") ' + "/ UDP() / Raw('\x00' * 64)", + 'Ether() / Dot1Q(prio = 0x5, id = 0x0, vlan = 0xbbb) / IP(src="132.177.0.99") ' + "/ UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionSet_ipv4_src(ActionFlowItem): + type = FlowActionType.SET_IPV4_SRC + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions set_ipv4_src ipv4_addr 172.16.0.10 / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionSet_ipv4_dst(ActionFlowItem): + type = FlowActionType.SET_IPV4_DST + + test_case = { + "test": ( + "ingress pattern eth / ipv4 dst is 192.168.0.1" + " / udp / end actions set_ipv4_dst ipv4_addr 172.16.0.10 / end", + frozenset( + {"Ether() / IP(dst=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(dst=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(dst=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(dst=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(dst=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionSet_ipv6_src(ActionFlowItem): + type = FlowActionType.SET_IPV6_SRC + + test_case = { + "test": ( + "ingress pattern eth / ipv6 src is 2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c2 " + "/ udp / end actions set_ipv6_src ipv6_addr 2001:0000:9d38:6ab8:1c48:9999:aaaa:bbbb", + frozenset( + { + 'Ether() / IPv6(src="2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c2") ' + "/ UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + "Ether() / IPv6(src=\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c3\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IPv6(src=\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c4\") / UDP() / Raw('\x00' * 64)", + "Ether() / IPv6(src=\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c5\") / UDP() / Raw('\x00' * 64)", + 'Ether() / IPv6(src="2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c6") ' + "/ UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionSet_ipv6_dst(ActionFlowItem): + type = FlowActionType.SET_IPV6_DST + + test_case = { + "test": ( + "ingress pattern eth / ipv6 dst is 2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c2 " + "/ udp / end actions set_ipv6_dst ipv6_addr 2001:0000:9d38:6ab8:1c48:9999:aaaa:bbbb", + frozenset( + { + 'Ether() / IPv6(dst="2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c2")' + " / UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + "Ether() / IPv6(dst=\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c3\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IPv6(dst=\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c4\") / UDP() / Raw('\x00' * 64)", + "Ether() / IPv6(dst=\"2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c5\") / UDP() / Raw('\x00' * 64)", + 'Ether() / IPv6(dst="2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c6") ' + "/ UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionSet_tp_src(ActionFlowItem): + type = FlowActionType.SET_TP_SRC + + test_case = { + # UDP + "test_udp": ( + "ingress pattern eth / ipv4 src is 192.168.0.1" + " / udp / end actions set_tp_src port 1998 / end", + frozenset( + { + "Ether() / IP(src=\"192.168.0.1\") UDP(sport=3838) / Raw('\\x00' * 64)" + } + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") UDP(sport=3838) / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") UDP(sport=3838) / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") UDP(sport=3838) / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") UDP(sport=3838) / Raw('\\x00' * 64)", + } + ), + ), + # TCP + "test_tcp": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / tcp / end actions set_tp_src port 1998 / end", + frozenset( + { + "Ether() / IP(src=\"192.168.0.1\") TCP(sport=3838) / Raw('\\x00' * 64)" + } + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") TCP(sport=3838) / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") TCP(sport=3838) / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") TCP(sport=3838) / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") TCP(sport=3838) / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionSet_tp_dst(ActionFlowItem): + type = FlowActionType.SET_TP_DST + + test_case = { + # UDP + "test_udp": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions set_tp_dst port 1998 / end", + frozenset( + { + "Ether() / IP(src=\"192.168.0.1\") UDP(dport=3838) / Raw('\\x00' * 64)" + } + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") UDP(dport=3838) / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") UDP(dport=3838) / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") UDP(dport=3838) / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") UDP(dport=3838) / Raw('\\x00' * 64)", + } + ), + ), + # TCP + "test_tcp": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / tcp / end actions set_tp_dst port 1998 / end", + frozenset( + { + "Ether() / IP(src=\"192.168.0.1\") TCP(dport=3838) / Raw('\\x00' * 64)" + } + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") TCP(dport=3838) / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") TCP(dport=3838) / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") TCP(dport=3838) / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") TCP(dport=3838) / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionSet_ttl(ActionFlowItem): + type = FlowActionType.SET_TTL + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1" + " / udp / end actions set_ttl ttl_value 64 / end", + frozenset( + { + "Ether() / IP(src=\"192.168.0.1\" , ttl=128 ) / UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\" , ttl=128 ) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\" , ttl=128 ) / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\", ttl=128 ) / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\", ttl=128 ) / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionSet_mac_src(ActionFlowItem): + type = FlowActionType.SET_MAC_SRC + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1" + " / udp / end actions set_mac_src mac_addr 10:20:30:40:50:60 / end", + frozenset( + { + 'Ether(src="90:61:ae:fd:41:43") / IP(src="192.168.0.1") / UDP() / Raw(\'\\x00\' * 64)' + } + ), + frozenset( + { + 'Ether(src="90:61:ae:fd:41:43") / IP(src="192.168.0.2") / UDP() / Raw(\'\\x00\' * 64)', + 'Ether(src="90:61:ae:fd:41:43") / IP(src="10.0.30.99") / UDP() / Raw(\'\\x00\' * 64)', + 'Ether(src="90:61:ae:fd:41:43") / IP(src="8.8.8.8") / UDP() / Raw(\'\\x00\' * 64)', + 'Ether(src="90:61:ae:fd:41:43") / IP(src="132.177.0.99") / UDP() / Raw(\'\\x00\' * 64)', + } + ), + ), + } + + +class FlowActionSet_mac_dst(ActionFlowItem): + type = FlowActionType.SET_MAC_DST + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1" + " / udp / end actions set_mac_dst mac_addr 10:20:30:40:50:60 / end", + frozenset( + { + 'Ether(dst="90:61:ae:fd:41:43") / IP(src="192.168.0.1") ' + "/ UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + 'Ether(dst="90:61:ae:fd:41:43") / IP(src="192.168.0.2") / UDP() / Raw(\'\\x00\' * 64)', + 'Ether(dst="90:61:ae:fd:41:43") / IP(src="10.0.30.99") / UDP() / Raw(\'\x00\' * 64)', + 'Ether(dst="90:61:ae:fd:41:43") / IP(src="8.8.8.8") / UDP() / Raw(\'\x00\' * 64)', + 'Ether(dst="90:61:ae:fd:41:43") / IP(src="132.177.0.99") ' + "/ UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionInc_tcp_seq(ActionFlowItem): + type = FlowActionType.INC_TCP_SEQ + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / tcp / end actions inc_tcp_seq / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / TCP(seq=2) / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / TCP(seq=2) / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / TCP(seq=2) / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / TCP(seq=2) / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / TCP(seq=2) / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionDec_tcp_seq(ActionFlowItem): + type = FlowActionType.DEC_TCP_SEQ + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / tcp / end actions dec_tcp_seq / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / TCP(seq=2) / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / TCP(seq=2) / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / TCP(seq=2) / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / TCP(seq=2) / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / TCP(seq=2) / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionInc_tcp_ack(ActionFlowItem): + type = FlowActionType.INC_TCP_ACK + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / tcp / end actions inc_tcp_ack / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / TCP(ack=2) / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / TCP(ack=2) / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / TCP(ack=2) / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / TCP(ack=2) / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / TCP(ack=2) / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionDec_tcp_ack(ActionFlowItem): + type = FlowActionType.DEC_TCP_ACK + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 / tcp / end actions dec_tcp_ack / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / TCP(ack=2) / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / TCP(ack=2) / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / TCP(ack=2) / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / TCP(ack=2) / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / TCP(ack=2) / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionSet_tag(ActionFlowItem): + type = FlowActionType.SET_TAG + + test_case = { + "test_data": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions set_tag data 0xabc / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + # bit-mask applies to "data" + "test_mask": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions set_tag data 0xabc mask 0xcba / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + "test_index": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions set_tag data 0xabc index 1 / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionSet_meta(ActionFlowItem): + type = FlowActionType.SET_META + + test_case = { + "test_data": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions set_meta data 0xabc / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + # bit-mask applies to "data" + "test_mask": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions set_meta data 0xabc mask 0xcb / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionSet_ipv4_dscp(ActionFlowItem): + type = FlowActionType.SET_IPV4_DSCP + + test_case = { + "test": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions set_ipv4_dscp dscp 2 / end", + frozenset( + { + "Ether() / IP(src=\"192.168.0.1\", tos = 0) / UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\", tos = 0) / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\", tos = 0) / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\", tos = 0) / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\", tos = 0) / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionSet_ipv6_dscp(ActionFlowItem): + type = FlowActionType.SET_IPV6_DSCP + + test_case = { + "test": ( + "ingress pattern eth / ipv6 src is 2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c2 " + "/ udp / end actions set_ipv6_dscp dscp 0x30", + frozenset( + { + 'Ether() / IPv6(src="2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c2", tc = 0) ' + "/ UDP() / Raw('\\x00' * 64)" + } + ), + frozenset( + { + 'Ether() / IPv6(src="2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c3", tc = 0) ' + "/ UDP() / Raw('\\x00' * 64)", + 'Ether() / IPv6(src="2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c4", tc = 0) ' + "/ UDP() / Raw('\x00' * 64)", + 'Ether() / IPv6(src="2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c5", tc = 0) ' + "/ UDP() / Raw('\x00' * 64)", + 'Ether() / IPv6(src="2001:0000:9d38:6ab8:1c48:3a1c:a95a:b1c6", tc = 0) ' + "/ UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +class FlowActionAge(ActionFlowItem): + type = FlowActionType.AGE + + test_case = { + "test_timeout": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions age timeout 128 / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + # 8 bits reserved, must be zero + "test_reserved": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions age timeout 128 reserved 0 / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + # The user flow context, NULL means the rte_flow pointer. + "test_context": ( + "ingress pattern eth / ipv4 src is 192.168.0.1 " + "/ udp / end actions age timeout 128 context NULL / end", + frozenset( + {"Ether() / IP(src=\"192.168.0.1\") / UDP() / Raw('\\x00' * 64)"} + ), + frozenset( + { + "Ether() / IP(src=\"192.168.0.2\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"10.0.30.99\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"8.8.8.8\") / UDP() / Raw('\\x00' * 64)", + "Ether() / IP(src=\"132.177.0.99\") / UDP() / Raw('\\x00' * 64)", + } + ), + ), + } + + +ACTION_ITEMS_TYPE_CLASS_MAPPING: Dict[FlowActionType, ActionFlowItem] = { + FlowActionType.PASSTHRU: FlowActionPassthru, + FlowActionType.FLAG: FlowActionFlag, + FlowActionType.DROP: FlowActionDrop, + FlowActionType.COUNT: FlowActionCount, + FlowActionType.MAC_SWAP: FlowActionMac_swap, + FlowActionType.DEC_TTL: FlowActionDec_ttl, + FlowActionType.JUMP: FlowActionJump, + FlowActionType.MARK: FlowActionMark, + FlowActionType.QUEUE: FlowActionQueue, + FlowActionType.RSS: FlowActionRss, + FlowActionType.PF: FlowActionPf, + FlowActionType.VF: FlowActionVf, + FlowActionType.PHY_PORT: FlowActionPhy_port, + FlowActionType.PORT_ID: FlowActionPort_id, + FlowActionType.METER: FlowActionMeter, + FlowActionType.SECURITY: FlowActionSecurity, + FlowActionType.OF_SET_MPLS_TTL: FlowActionOf_set_mpls_ttl, + FlowActionType.OF_DEC_MPLS_TTL: FlowActionOf_dec_mpls_ttl, + FlowActionType.OF_SET_NW_TTL: FlowActionOf_set_nw_ttl, + FlowActionType.OF_DEC_NW_TTL: FlowActionOf_dec_nw_ttl, + FlowActionType.OF_COPY_TTL_OUT: FlowActionOf_copy_ttl_out, + FlowActionType.OF_COPY_TTL_IN: FlowActionOf_copy_ttl_in, + FlowActionType.OF_POP_VLAN: FlowActionOf_pop_vlan, + FlowActionType.OF_PUSH_VLAN: FlowActionOf_push_vlan, + FlowActionType.OF_SET_VLAN_VID: FlowActionOf_set_vlan_vid, + FlowActionType.OF_SET_VLAN_PCP: FlowActionOf_set_vlan_pcp, + FlowActionType.OF_POP_MPLS: FlowActionOf_pop_mpls, + FlowActionType.OF_PUSH_MPLS: FlowActionOf_push_mpls, + FlowActionType.VXLAN_ENCAP: FlowActionVxlan_encap, + FlowActionType.VXLAN_DECAP: FlowActionVxlan_decap, + FlowActionType.NVGRE_ENCAP: FlowActionNvgre_encap, + FlowActionType.NVGRE_DECAP: FlowActionNvgre_decap, + FlowActionType.RAW_ENCAP: FlowActionRaw_encap, + FlowActionType.RAW_DECAP: FlowActionRaw_decap, + FlowActionType.SET_IPV4_SRC: FlowActionSet_ipv4_src, + FlowActionType.SET_IPV4_DST: FlowActionSet_ipv4_dst, + FlowActionType.SET_IPV6_SRC: FlowActionSet_ipv6_src, + FlowActionType.SET_IPV6_DST: FlowActionSet_ipv6_dst, + FlowActionType.SET_TP_SRC: FlowActionSet_tp_src, + FlowActionType.SET_TP_DST: FlowActionSet_tp_dst, + FlowActionType.SET_TTL: FlowActionSet_ttl, + FlowActionType.SET_MAC_SRC: FlowActionSet_mac_src, + FlowActionType.SET_MAC_DST: FlowActionSet_mac_dst, + FlowActionType.INC_TCP_SEQ: FlowActionInc_tcp_seq, + FlowActionType.DEC_TCP_SEQ: FlowActionDec_tcp_seq, + FlowActionType.INC_TCP_ACK: FlowActionInc_tcp_ack, + FlowActionType.DEC_TCP_ACK: FlowActionDec_tcp_ack, + FlowActionType.SET_TAG: FlowActionSet_tag, + FlowActionType.SET_META: FlowActionSet_meta, + FlowActionType.SET_IPV4_DSCP: FlowActionSet_ipv4_dscp, + FlowActionType.SET_IPV6_DSCP: FlowActionSet_ipv6_dscp, + FlowActionType.AGE: FlowActionAge, +}