From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 08D4CA04EF; Tue, 2 Jun 2020 05:17:55 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id B25481BFBF; Tue, 2 Jun 2020 05:17:55 +0200 (CEST) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by dpdk.org (Postfix) with ESMTP id 586D71BFB5 for ; Tue, 2 Jun 2020 05:17:53 +0200 (CEST) IronPort-SDR: uXCx87XEqJRsbnvt2/mJeUuKm4+i08NAniDUi/2EavnSmVXIQej9F0aFLI/g2x/Jr7bdMslQLy WA6J2ba2OoNw== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Jun 2020 20:17:51 -0700 IronPort-SDR: cvdJKwXr6IQxKhHs9SL/L1OppKCLvxuxPD3prq2fNKAy401hongEUEUWcv1SK+8iwz3tIOp13s jZEVR2p+5RaA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,462,1583222400"; d="scan'208";a="272207769" Received: from npg_dpdk_nic_yuanpeng_tester62.sh.intel.com ([10.67.119.61]) by orsmga006.jf.intel.com with ESMTP; 01 Jun 2020 20:17:48 -0700 From: Peng Yuan To: dts@dpdk.org Cc: Peng Yuan Date: Tue, 2 Jun 2020 10:24:50 +0000 Message-Id: <1591093490-26717-1-git-send-email-yuan.peng@intel.com> X-Mailer: git-send-email 2.7.4 Subject: [dts] [PATCH] add TestSuite_iavf_fdir.py and related files X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dts-bounces@dpdk.org Sender: "dts" Add TestSuite_iavf_fdir.py and related files to DTS Signed-off-by: Peng Yuan --- conf/iavf_fdir.cfg | 9 + dep/pfcp.py | 24 + framework/packet.py | 1 + tests/TestSuite_iavf_fdir.py | 2996 ++++++++++++++++++++++++++++++++++ tests/rte_flow_common.py | 96 +- 5 files changed, 3125 insertions(+), 1 deletion(-) create mode 100644 conf/iavf_fdir.cfg create mode 100644 dep/pfcp.py create mode 100644 tests/TestSuite_iavf_fdir.py diff --git a/conf/iavf_fdir.cfg b/conf/iavf_fdir.cfg new file mode 100644 index 00000000..cfd84192 --- /dev/null +++ b/conf/iavf_fdir.cfg @@ -0,0 +1,9 @@ +[suite] +# cvl_iavf_fdir common options ice driver file location +ice_driver_file_location = "/home/pengyuan/nd/nd_linux-cpk/ice-0.16.0_rc35_1_g7fb2b219_dirty/src/ice.ko" +# os default package file location +os_default_package_file_location="/lib/firmware/updates/intel/ice/ddp/ice-1.3.11.0.pkg" +# comms package file location +comms_package_file_location="/lib/firmware/updates/intel/ice/ddp/ice_comms-1.3.16.0.pkg" +# package file location +package_file_location="/lib/firmware/updates/intel/ice/ddp/ice.pkg" diff --git a/dep/pfcp.py b/dep/pfcp.py new file mode 100644 index 00000000..33f25105 --- /dev/null +++ b/dep/pfcp.py @@ -0,0 +1,24 @@ +from scapy.packet import Packet, bind_layers, Padding +from scapy.fields import * +from scapy.layers.inet import UDP + +class PFCP(Packet): + name = "PFCP" + fields_desc = [ BitField("version", 1, 3), + BitField("MP", 0, 4), + BitField("Sfield", 0, 1), + ByteField("MsgType", 0), + ShortField("len", None), + LongField("SEID", 0), + ThreeBytesField("SeqNum", 0), + BitField("MsgPrio", 0, 4), + BitField("spare", 0, 4)] + + + def post_build(self, pkt, pay): + if self.len is None: + l = len(pkt)+len(pay) + pkt = pkt[:2]+struct.pack("!H", l)+pkt[4:] + return pkt+pay + +bind_layers(UDP, PFCP, dport=8805) diff --git a/framework/packet.py b/framework/packet.py index 42982cd5..603840b4 100644 --- a/framework/packet.py +++ b/framework/packet.py @@ -56,6 +56,7 @@ from Dot1BR import Dot1BR from nsh import NSH from mpls import MPLS from igmp import IGMP +from pfcp import PFCP from utils import convert_ip2int from utils import convert_int2ip diff --git a/tests/TestSuite_iavf_fdir.py b/tests/TestSuite_iavf_fdir.py new file mode 100644 index 00000000..8d114878 --- /dev/null +++ b/tests/TestSuite_iavf_fdir.py @@ -0,0 +1,2996 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2019 Intel Corporation. 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. + + +import re +import time + +from packet import Packet +from pmd_output import PmdOutput +from test_case import TestCase +import rte_flow_common as rfc +from multiprocessing import Process +from multiprocessing import Manager + +from utils import GREEN, RED +import utils + +MAC_IPV4_PAY = { + "match": [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", proto=255, ttl=2, tos=4) / Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", frag=1, proto=255, ttl=2, tos=4)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", proto=255, ttl=2, tos=4)/UDP(sport=22,dport=23)/Raw("x" * 80)'], + "mismatch": [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.22",dst="192.168.0.21", proto=255, ttl=2, tos=4) / Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.1.21", proto=255, ttl=2, tos=4) / Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", proto=1, ttl=2, tos=4) / Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", proto=255, ttl=3, tos=4) / Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", proto=255, ttl=2, tos=9) / Raw("x" * 80)' + ] +} + +MAC_IPV4_PAY_protocol = { + "match": [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", proto=1)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", frag=1, proto=1)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=2, tos=4)/UDP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", frag=1, ttl=2, tos=4)/UDP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", proto=17, ttl=2, tos=4)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", frag=1, proto=17, ttl=2, tos=4)/Raw("x" * 80)'], + "mismatch": [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.22", proto=1)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", proto=6)/UDP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", frag=1)/TCP(sport=22,dport=23)/Raw("x" * 80)'] +} + +MAC_IPV4_UDP = { + "match": [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=2, tos=4) /UDP(sport=22,dport=23)/Raw("x" * 80)'], + "mismatch": [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.1.19",dst="192.168.0.21", ttl=2, tos=4) /UDP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.22", ttl=2, tos=4) /UDP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=2, tos=4) /UDP(sport=21,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=2, tos=4) /UDP(sport=22,dport=24)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=64, tos=4) /UDP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=2, tos=1) /UDP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=2, tos=4) /TCP(sport=22,dport=23)/Raw("x" * 80)'] +} + +MAC_IPV4_TCP = { + "match": [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=2, tos=4) /TCP(sport=22,dport=23)/Raw("x" * 80)'], + "mismatch": [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.1.19",dst="192.168.0.21", ttl=2, tos=4) /TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.22", ttl=2, tos=4) /TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=2, tos=4) /TCP(sport=21,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=2, tos=4) /TCP(sport=22,dport=24)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=64, tos=4) /TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=2, tos=1) /TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=2, tos=4) /UDP(sport=22,dport=23)/Raw("x" * 80)'] +} + +MAC_IPV4_SCTP = { + "match": [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=2, tos=4) /SCTP(sport=22,dport=23)/Raw("x" * 80)'], + "mismatch": [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.1.19",dst="192.168.0.21", ttl=2, tos=4) /SCTP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.22", ttl=2, tos=4) /SCTP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=2, tos=4) /SCTP(sport=21,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=2, tos=4) /SCTP(sport=22,dport=24)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=64, tos=4) /SCTP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=2, tos=1) /SCTP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", ttl=2, tos=4)/Raw("x" * 80)'] +} + +MAC_IPV6_PAY = { + "match": [ + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2", nh=0, tc=1, hlim=2)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2", nh=0, tc=1, hlim=2)/UDP(sport=22,dport=23)/("X"*480)'], + "mismatch": [ + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2022", src="2001::2", nh=0, tc=1, hlim=2)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::1", nh=0, tc=1, hlim=2)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2", nh=2, tc=1, hlim=2)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2", nh=0, tc=2, hlim=2)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2", nh=0, tc=1, hlim=5)/("X"*480)'] +} + +MAC_IPV6_PAY_protocol = { + "match": [ + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2", nh=44, tc=1, hlim=2)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020")/IPv6ExtHdrFragment(100)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", nh=44)/TCP(sport=22,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020")/IPv6ExtHdrFragment(100)/TCP(sport=22,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", nh=6)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020")/TCP(sport=22,dport=23)/("X"*480)'], + "mismatch": [ + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2021", nh=44)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020")/UDP(sport=22,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", nh=17)/TCP(sport=22,dport=23)/("X"*480)'] +} + +MAC_IPV6_UDP = { + "match": [ + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=1, hlim=2)/UDP(sport=22,dport=23)/("X"*480)'], + "mismatch": [ + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2021", src="2001::2",tc=1, hlim=2)/UDP(sport=22,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2002::2",tc=1, hlim=2)/UDP(sport=22,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=3, hlim=2)/UDP(sport=22,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=1, hlim=1)/UDP(sport=22,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=1, hlim=2)/UDP(sport=21,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=1, hlim=2)/UDP(sport=22,dport=24)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=1, hlim=2)/TCP(sport=22,dport=23)/("X"*480)'] +} + +MAC_IPV6_TCP = { + "match": [ + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=1, hlim=2)/TCP(sport=22,dport=23)/("X"*480)'], + "mismatch": [ + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2021", src="2001::2",tc=1, hlim=2)/TCP(sport=22,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2002::2",tc=1, hlim=2)/TCP(sport=22,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=3, hlim=2)/TCP(sport=22,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=1, hlim=1)/TCP(sport=22,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=1, hlim=2)/TCP(sport=21,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=1, hlim=2)/TCP(sport=22,dport=24)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=1, hlim=2)/SCTP(sport=22,dport=23)/("X"*480)'] +} + +MAC_IPV6_SCTP = { + "match": [ + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=1, hlim=2)/SCTP(sport=22,dport=23)/("X"*480)'], + "mismatch": [ + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2021", src="2001::2",tc=1, hlim=2)/SCTP(sport=22,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2002::2",tc=1, hlim=2)/SCTP(sport=22,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=3, hlim=2)/SCTP(sport=22,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=1, hlim=1)/SCTP(sport=22,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=1, hlim=2)/SCTP(sport=21,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=1, hlim=2)/SCTP(sport=22,dport=24)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=1, hlim=2)/UDP(sport=22,dport=23)/("X"*480)', + 'Ether(dst="00:11:22:33:44:55")/IPv6(dst="CDCD:910A:2222:5498:8475:1111:3900:2020", src="2001::2",tc=1, hlim=2)/("X"*480)'] +} + +MAC_IPV4_GTPU_EH = { + "match": [ + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x34)/IP()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x34)/IP(frag=1)/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x34)/IP()/UDP()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x34)/IP()/TCP(sport=22,dport=23)/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x34)/IP()/ICMP()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x34)/IPv6()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x34)/IPv6(nh=44)/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x34)/IPv6()/UDP()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x34)/IPv6()/TCP(sport=22,dport=23)/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x34)/IPv6()/ICMP()/Raw("x"*20)'], + "mismatch": [ + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x34)/IP()/SCTP()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x34)/IPv6()/SCTP()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x1234567)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x34)/IP()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x35)/IP()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/IP()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x34)/Raw("x"*20)'] +} + +MAC_IPV4_GTPU = { + "match": [ + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/IP()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/IP(frag=1)/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/IP()/UDP()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/IP()/TCP(sport=22, dport=23)/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/IP()/ICMP()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/IPv6()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/IPv6(nh=44)/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/IPv6()/UDP()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/IPv6()/TCP(sport=22, dport=23)/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/IPv6()/ICMP()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x35)/IP()/Raw("x"*20)'], + "mismatch": [ + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/IP()/SCTP()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/IPv6()/SCTP()/Raw("x"*20)', + 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x1234567)/IP()/Raw("x"*20)'] +} + +L2_Ethertype = [ + 'Ether(dst="00:11:22:33:44:55")/PPPoED()/PPP()/IP()/Raw("x" *80)', + 'Ether(dst="00:11:22:33:44:55", type=0x8863)/IP()/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/PPPoE()/PPP(proto=0x0021)/IP()/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55", type=0x8864)/IP()/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/ARP(pdst="192.168.1.1")', + 'Ether(dst="00:11:22:33:44:55", type=0x0806)/Raw("x" *80)', + 'Ether(dst="00:11:22:33:44:55",type=0x8100)', + 'Ether(dst="00:11:22:33:44:55")/Dot1Q(vlan=1)', + 'Ether(dst="00:11:22:33:44:55",type=0x88f7)/"\\x00\\x02"', + 'Ether(dst="00:11:22:33:44:55",type=0x8847)'] + +PFCP = [ + 'Ether(dst="00:11:22:33:44:55")/IP()/UDP(sport=22, dport=8805)/PFCP(Sfield=0)', + 'Ether(dst="00:11:22:33:44:55")/IP()/UDP(sport=22, dport=8805)/PFCP(Sfield=1, SEID=123)', + 'Ether(dst="00:11:22:33:44:55")/IPv6()/UDP(sport=22, dport=8805)/PFCP(Sfield=0)', + 'Ether(dst="00:11:22:33:44:55")/IPv6()/UDP(sport=22, dport=8805)/PFCP(Sfield=1, SEID=256)', + 'Ether(dst="00:11:22:33:44:55")/IPv6()/UDP(sport=22, dport=23)/Raw("x"*20)'] + +CREATE_2048_RULES_4_VFS = [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.7.255", ttl=2, tos=4) /UDP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:66")/IP(src="192.168.0.20",dst="192.168.7.255", ttl=2, tos=4) /UDP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:77")/IP(src="192.168.0.20",dst="192.168.7.255", ttl=2, tos=4) /UDP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:88")/IP(src="192.168.0.20",dst="192.168.7.255", ttl=2, tos=4) /UDP(sport=22,dport=23)/Raw("x" * 80)'] + +tv_l2_ethertype_queue_index = { + "name": "test_l2_ethertype_queue_index", + "rule": [ + "flow create 0 ingress pattern eth type is 0x8863 / end actions queue index 1 / mark id 1 / end", + "flow create 0 ingress pattern eth type is 0x8864 / end actions queue index 2 / mark id 2 / end", + "flow create 0 ingress pattern eth type is 0x0806 / end actions queue index 3 / mark id 3 / end", + "flow create 0 ingress pattern eth type is 0x8100 / end actions queue index 4 / mark id 4 / end", + "flow create 0 ingress pattern eth type is 0x88f7 / end actions queue index 5 / mark id 5 / end"], + "scapy_str": L2_Ethertype, + "check_param": [ + {"port_id": 0, "queue": 1, "mark_id": 1}, + {"port_id": 0, "queue": 1, "mark_id": 1}, + {"port_id": 0, "queue": 2, "mark_id": 2}, + {"port_id": 0, "queue": 2, "mark_id": 2}, + {"port_id": 0, "queue": 3, "mark_id": 3}, + {"port_id": 0, "queue": 3, "mark_id": 3}, + {"port_id": 0, "queue": 4, "mark_id": 4}, + {"port_id": 0, "queue": 4, "mark_id": 4}, + {"port_id": 0, "queue": 5, "mark_id": 5}, + {"port_id": 0, "queue": 0}] +} + +tv_l2_ethertype_queue_group = { + "name": "test_l2_ethertype_queue_group", + "rule": [ + "flow create 0 ingress pattern eth type is 0x8863 / end actions rss queues 0 1 end / mark id 0 / end", + "flow create 0 ingress pattern eth type is 0x8864 / end actions rss queues 2 3 end / mark id 1 / end", + "flow create 0 ingress pattern eth type is 0x0806 / end actions rss queues 4 5 end / mark id 2 / end", + "flow create 0 ingress pattern eth type is 0x8100 / end actions rss queues 6 7 end / mark id 2 / end", + "flow create 0 ingress pattern eth type is 0x88f7 / end actions rss queues 9 10 end / mark id 3 / end"], + "scapy_str": L2_Ethertype, + "check_param": [ + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "queue": 0, "mark_id": 1}, + {"port_id": 0, "queue": 0, "mark_id": 1}, + {"port_id": 0, "queue": 0, "mark_id": 2}, + {"port_id": 0, "queue": 0, "mark_id": 2}, + {"port_id": 0, "queue": 0, "mark_id": 2}, + {"port_id": 0, "queue": 0, "mark_id": 2}, + {"port_id": 0, "queue": 0, "mark_id": 3}, + {"port_id": 0, "queue": 0}] +} + +tv_l2_ethertype_passthru = { + "name": "test_l2_ethertype_passthru", + "rule": [ + "flow create 0 ingress pattern eth type is 0x8863 / end actions passthru / mark / end", + "flow create 0 ingress pattern eth type is 0x8864 / end actions passthru / mark id 1 / end", + "flow create 0 ingress pattern eth type is 0x0806 / end actions passthru / mark id 2 / end", + "flow create 0 ingress pattern eth type is 0x8100 / end actions passthru / mark id 3 / end", + "flow create 0 ingress pattern eth type is 0x88f7 / end actions passthru / mark id 4 / end"], + "scapy_str": L2_Ethertype, + "check_param": [ + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "queue": 0, "mark_id": 1}, + {"port_id": 0, "queue": 0, "mark_id": 1}, + {"port_id": 0, "queue": 0, "mark_id": 2}, + {"port_id": 0, "queue": 0, "mark_id": 2}, + {"port_id": 0, "queue": 0, "mark_id": 3}, + {"port_id": 0, "queue": 0, "mark_id": 3}, + {"port_id": 0, "queue": 0, "mark_id": 4}, + {"port_id": 0, "queue": 0}] +} + +tv_l2_ethertype_mark_rss = { + "name": "test_l2_ethertype_mark_rss", + "rule": [ + "flow create 0 ingress pattern eth type is 0x8863 / end actions rss / mark id 0 / end", + "flow create 0 ingress pattern eth type is 0x8864 / end actions mark id 1 / rss / end", + "flow create 0 ingress pattern eth type is 0x0806 / end actions mark / rss / end", + "flow create 0 ingress pattern eth type is 0x8100 / end actions rss / mark / end", + "flow create 0 ingress pattern eth type is 0x88f7 / end actions mark id 3 / rss / end"], + "scapy_str": L2_Ethertype, + "check_param": [ + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "queue": 0, "mark_id": 1}, + {"port_id": 0, "queue": 0, "mark_id": 1}, + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "queue": 0, "mark_id": 3}, + {"port_id": 0, "queue": 0}] +} + +tv_l2_ethertype_mark = { + "name": "test_l2_ethertype_mark", + "rule": [ + "flow create 0 ingress pattern eth type is 0x8863 / end actions mark id 0 / end", + "flow create 0 ingress pattern eth type is 0x8864 / end actions mark id 1 / end", + "flow create 0 ingress pattern eth type is 0x0806 / end actions mark id 2 / end", + "flow create 0 ingress pattern eth type is 0x8100 / end actions mark id 2 / end", + "flow create 0 ingress pattern eth type is 0x88f7 / end actions mark / end"], + "scapy_str": L2_Ethertype, + "check_param": [ + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "queue": 0, "mark_id": 1}, + {"port_id": 0, "queue": 0, "mark_id": 1}, + {"port_id": 0, "queue": 0, "mark_id": 2}, + {"port_id": 0, "queue": 0, "mark_id": 2}, + {"port_id": 0, "queue": 0, "mark_id": 2}, + {"port_id": 0, "queue": 0, "mark_id": 2}, + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "queue": 0}] +} + +tv_l2_ethertype_drop = { + "name": "test_l2_ethertype_drop", + "rule": [ + "flow create 0 ingress pattern eth type is 0x8863 / end actions drop / end", + "flow create 0 ingress pattern eth type is 0x8864 / end actions drop / end", + "flow create 0 ingress pattern eth type is 0x0806 / end actions drop / end", + "flow create 0 ingress pattern eth type is 0x8100 / end actions drop / end", + "flow create 0 ingress pattern eth type is 0x88f7 / end actions drop / end"], + "scapy_str": L2_Ethertype, + "check_param": [ + {"port_id": 0, "drop": 1}, + {"port_id": 0, "drop": 1}, + {"port_id": 0, "drop": 1}, + {"port_id": 0, "drop": 1}, + {"port_id": 0, "drop": 1}, + {"port_id": 0, "drop": 1}, + {"port_id": 0, "drop": 1}, + {"port_id": 0, "drop": 1}, + {"port_id": 0, "drop": 1}, + {"port_id": 0, "queue": 0}] +} + +tv_pfcp_queue_index = { + "name": "test_pfcp_queue_index", + "rule": [ + "flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 0 / end actions queue index 1 / end", + "flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 1 / end actions queue index 2 / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 0 / end actions queue index 3 / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 1 / end actions queue index 4 / end"], + "scapy_str": PFCP, + "check_param": [ + {"port_id": 0, "queue": 1}, + {"port_id": 0, "queue": 2}, + {"port_id": 0, "queue": 3}, + {"port_id": 0, "queue": 4}, + {"port_id": 0, "passthru": 1}] +} + +tv_pfcp_queue_group = { + "name": "test_pfcp_queue_group", + "rule": [ + "flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 0 / end actions rss queues 2 3 end / mark id 0 / end", + "flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 1 / end actions rss queues 4 5 6 7 end / mark id 1 / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 0 / end actions rss queues 8 9 10 11 12 13 14 15 end / mark id 2 / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 1 / end actions rss queues 3 4 5 6 end / mark id 3 / end"], + "scapy_str": PFCP, + "check_param": [ + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "queue": [4, 5, 6, 7], "mark_id": 1}, + {"port_id": 0, "queue": 0, "mark_id": 2}, + {"port_id": 0, "queue": [3, 4, 5, 6], "mark_id": 3}, + {"port_id": 0, "passthru": 1}] +} + +tv_pfcp_passthru = { + "name": "test_pfcp_passthru", + "rule": [ + "flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 0 / end actions passthru / mark id 0 / end", + "flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 1 / end actions passthru / mark id 1 / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 0 / end actions passthru / mark id 2 / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 1 / end actions passthru / mark id 3 / end"], + "scapy_str": PFCP, + "check_param": [ + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "passthru": 1, "mark_id": 1}, + {"port_id": 0, "queue": 0, "mark_id": 2}, + {"port_id": 0, "passthru": 1, "mark_id": 3}, + {"port_id": 0, "passthru": 1}] +} + +tv_pfcp_mark_rss = { + "name": "test_pfcp_mark_rss", + "rule": [ + "flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 0 / end actions mark / rss / end", + "flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 1 / end actions mark id 1 / rss / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 0 / end actions mark id 2 / rss / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 1 / end actions mark id 3 / rss / end"], + "scapy_str": PFCP, + "check_param": [ + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "passthru": 1, "mark_id": 1}, + {"port_id": 0, "queue": 0, "mark_id": 2}, + {"port_id": 0, "passthru": 1, "mark_id": 3}, + {"port_id": 0, "passthru": 1}] +} + +tv_pfcp_mark = { + "name": "test_pfcp_mark", + "rule": [ + "flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 0 / end actions mark / end", + "flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 1 / end actions mark id 1 / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 0 / end actions mark id 2 / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 1 / end actions mark id 4294967294 / end"], + "scapy_str": PFCP, + "check_param": [ + {"port_id": 0, "queue": 0, "mark_id": 0}, + {"port_id": 0, "passthru": 1, "mark_id": 1}, + {"port_id": 0, "queue": 0, "mark_id": 2}, + {"port_id": 0, "passthru": 1, "mark_id": 4294967294}, + {"port_id": 0, "passthru": 1}] +} + +tv_pfcp_drop = { + "name": "test_pfcp_drop", + "rule": [ + "flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 0 / end actions drop / end", + "flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 1 / end actions drop / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 0 / end actions drop / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 1 / end actions drop / end"], + "scapy_str": PFCP, + "check_param": [ + {"port_id": 0, "drop": 1}, + {"port_id": 0, "drop": 1}, + {"port_id": 0, "drop": 1}, + {"port_id": 0, "drop": 1}, + {"port_id": 0, "passthru": 1}] +} + +tv_add_2048_rules_on_4_VFs_at_meantime = { + "name": "test_add_2048_rules_on_4_VFs_at_meantime", + "scapy_str": CREATE_2048_RULES_4_VFS, + "check_param": {"port_id": 0, "queue": 1} +} + +tv_mac_ipv4_pay_queue_index = { + "name": "test_mac_ipv4_pay_queue_index", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 proto is 255 ttl is 2 tos is 4 / end actions queue index 1 / end", + "scapy_str": MAC_IPV4_PAY, + "check_param": {"port_id": 0, "queue": 1} +} + +tv_mac_ipv4_pay_queue_group = { + "name": "test_mac_ipv4_pay_queue_group", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 proto is 255 ttl is 2 tos is 4 / end actions rss queues 0 1 end / end", + "scapy_str": MAC_IPV4_PAY, + "check_param": {"port_id": 0, "queue": [0, 1]} +} + +tv_mac_ipv4_pay_passthru = { + "name": "test_mac_ipv4_pay_passthru", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 proto is 255 ttl is 2 tos is 4 / end actions passthru / end", + "scapy_str": MAC_IPV4_PAY, + "check_param": {"port_id": 0, "passthru": 1} +} + +tv_mac_ipv4_pay_mark_rss = { + "name": "test_mac_ipv4_pay_mark_rss", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 proto is 255 ttl is 2 tos is 4 / end actions mark / rss / end", + "scapy_str": MAC_IPV4_PAY, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 0} +} + +tv_mac_ipv4_pay_mark = { + "name": "test_mac_ipv4_pay_mark", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 proto is 255 ttl is 2 tos is 4 / end actions mark / end", + "scapy_str": MAC_IPV4_PAY, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 0} +} + +tv_mac_ipv4_pay_drop = { + "name": "test_mac_ipv4_pay_drop", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 proto is 255 ttl is 2 tos is 4 / end actions drop / end", + "scapy_str": MAC_IPV4_PAY, + "check_param": {"port_id": 0, "drop":1} +} + +tv_mac_ipv4_udp_queue_index = { + "name": "test_mac_ipv4_udp_queue_index", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / udp src is 22 dst is 23 / end actions queue index 1 / mark id 0 / end", + "scapy_str": MAC_IPV4_UDP, + "check_param": {"port_id": 0, "queue": 1, "mark_id": 0} +} + +tv_mac_ipv4_udp_drop = { + "name": "test_mac_ipv4_udp_drop", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / udp src is 22 dst is 23 / end actions drop / end", + "scapy_str": MAC_IPV4_UDP, + "check_param": {"port_id": 0, "drop": 1} +} + +tv_mac_ipv4_udp_queue_group = { + "name": "test_mac_ipv4_udp_queue_group", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / udp src is 22 dst is 23 / end actions rss queues 1 2 3 4 end / mark id 4294967294 / end", + "scapy_str": MAC_IPV4_UDP, + "check_param": {"port_id": 0, "queue": [1, 2, 3, 4], "mark_id": 4294967294} +} + +tv_mac_ipv4_udp_passthru = { + "name": "test_mac_ipv4_udp_passthru", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / udp src is 22 dst is 23 / end actions passthru / mark id 1 / end", + "scapy_str": MAC_IPV4_UDP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 1} +} + +tv_mac_ipv4_udp_mark_rss = { + "name": "test_mac_ipv4_udp_mark_rss", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / udp src is 22 dst is 23 / end actions mark id 2 / rss / end", + "scapy_str": MAC_IPV4_UDP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 2} +} + +tv_mac_ipv4_udp_mark = { + "name": "test_mac_ipv4_udp_mark", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / udp src is 22 dst is 23 / end actions mark id 1 / end", + "scapy_str": MAC_IPV4_UDP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 1} +} + +tv_mac_ipv4_tcp_queue_index = { + "name": "test_mac_ipv4_tcp_queue_index", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / tcp src is 22 dst is 23 / end actions queue index 15 / end", + "scapy_str": MAC_IPV4_TCP, + "check_param": {"port_id": 0, "queue": 15} +} + +tv_mac_ipv4_tcp_drop = { + "name": "test_mac_ipv4_tcp_drop", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / tcp src is 22 dst is 23 / end actions drop / end", + "scapy_str": MAC_IPV4_TCP, + "check_param": {"port_id": 0, "drop": 1} +} + +tv_mac_ipv4_tcp_queue_group = { + "name": "test_mac_ipv4_tcp_queue_group", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / tcp src is 22 dst is 23 / end actions rss queues 0 1 2 3 end / mark id 1 / end", + "scapy_str": MAC_IPV4_TCP, + "check_param": {"port_id": 0, "queue": [1, 2, 3, 4], "mark_id": 1} +} + +tv_mac_ipv4_tcp_passthru = { + "name": "test_mac_ipv4_tcp_passthru", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / tcp src is 22 dst is 23 / end actions passthru / mark id 2 / end", + "scapy_str": MAC_IPV4_TCP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 2} +} + +tv_mac_ipv4_tcp_mark_rss = { + "name": "test_mac_ipv4_tcp_mark_rss", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / tcp src is 22 dst is 23 / end actions mark id 0 / rss / end", + "scapy_str": MAC_IPV4_TCP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 0} +} + +tv_mac_ipv4_tcp_mark = { + "name": "test_mac_ipv4_tcp_mark", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / tcp src is 22 dst is 23 / end actions mark id 0 / end", + "scapy_str": MAC_IPV4_TCP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 0} +} + +tv_mac_ipv4_sctp_queue_index = { + "name": "test_mac_ipv4_sctp_queue_index", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / sctp src is 22 dst is 23 tag is 1 / end actions queue index 0 / end", + "scapy_str": MAC_IPV4_SCTP, + "check_param": {"port_id": 0, "queue": 0} +} + +tv_mac_ipv4_sctp_drop = { + "name": "test_mac_ipv4_sctp_drop", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / sctp src is 22 dst is 23 / end actions drop / mark / end", + "scapy_str": MAC_IPV4_SCTP, + "check_param": {"port_id": 0, "drop": 1} +} + +tv_mac_ipv4_sctp_queue_group = { + "name": "test_mac_ipv4_sctp_queue_group", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / sctp src is 22 dst is 23 / end actions rss queues 14 15 end / mark id 15 / end", + "scapy_str": MAC_IPV4_SCTP, + "check_param": {"port_id": 0, "queue": [14, 15], "mark_id": 15} +} + +tv_mac_ipv4_sctp_passthru = { + "name": "test_mac_ipv4_sctp_passthru", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / sctp src is 22 dst is 23 / end actions passthru / mark id 0 / end", + "scapy_str": MAC_IPV4_SCTP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 0} +} + +tv_mac_ipv4_sctp_mark_rss = { + "name": "test_mac_ipv4_sctp_mark_rss", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / sctp src is 22 dst is 23 / end actions mark / rss / end", + "scapy_str": MAC_IPV4_SCTP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 0} +} + +tv_mac_ipv4_sctp_mark = { + "name": "test_mac_ipv4_sctp_mark", + "rule": "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / sctp src is 22 dst is 23 / end actions mark / end", + "scapy_str": MAC_IPV4_SCTP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 0} +} + +tv_mac_ipv6_pay_queue_index = { + "name": "test_mac_ipv6_pay_queue_index", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 proto is 0 hop is 2 tc is 1 / end actions queue index 15 / mark id 1 / end", + "scapy_str": MAC_IPV6_PAY, + "check_param": {"port_id": 0, "queue": 15, "mark_id": 1} +} + +tv_mac_ipv6_pay_drop = { + "name": "test_mac_ipv6_pay_drop", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 proto is 0 hop is 2 tc is 1 / end actions drop / end", + "scapy_str": MAC_IPV6_PAY, + "check_param": {"port_id": 0, "drop": 1} +} + +tv_mac_ipv6_pay_queue_group = { + "name": "test_mac_ipv6_pay_queue_group", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 proto is 0 hop is 2 tc is 1 / end actions rss queues 8 9 10 11 12 13 14 15 end / mark id 2 / end", + "scapy_str": MAC_IPV6_PAY, + "check_param": {"port_id": 0, "queue": [8, 9, 10, 11, 12, 13, 14, 15], "mark_id": 2} +} + +tv_mac_ipv6_pay_passthru = { + "name": "test_mac_ipv6_pay_passthru", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 proto is 0 hop is 2 tc is 1 / end actions passthru / mark id 3 / end", + "scapy_str": MAC_IPV6_PAY, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 3} +} + +tv_mac_ipv6_pay_mark_rss = { + "name": "test_mac_ipv6_pay_mark_rss", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 proto is 0 hop is 2 tc is 1 / end actions mark id 4 / rss / end", + "scapy_str": MAC_IPV6_PAY, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 4} +} + +tv_mac_ipv6_pay_mark = { + "name": "test_mac_ipv6_pay_mark", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 proto is 0 hop is 2 tc is 1 / end actions mark id 5 / rss / end", + "scapy_str": MAC_IPV6_PAY, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 5} +} + +tv_mac_ipv6_udp_queue_index = { + "name": "test_mac_ipv6_udp_queue_index", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / udp src is 22 dst is 23 / end actions queue index 1 / end", + "scapy_str": MAC_IPV6_UDP, + "check_param": {"port_id": 0, "queue": 1} +} + +tv_mac_ipv6_udp_queue_group = { + "name": "test_mac_ipv6_udp_queue_group", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / udp src is 22 dst is 23 / end actions rss queues 1 2 end / end", + "scapy_str": MAC_IPV6_UDP, + "check_param": {"port_id": 0, "queue": [1, 2]} +} + +tv_mac_ipv6_udp_drop = { + "name": "test_mac_ipv6_udp_drop", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / udp src is 22 dst is 23 / end actions drop / end", + "scapy_str": MAC_IPV6_UDP, + "check_param": {"port_id": 0, "drop": 1} +} + +tv_mac_ipv6_udp_passthru = { + "name": "test_mac_ipv6_udp_passthru", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / udp src is 22 dst is 23 / end actions passthru / end", + "scapy_str": MAC_IPV6_UDP, + "check_param": {"port_id": 0, "passthru": 1} +} + +tv_mac_ipv6_udp_mark_rss = { + "name": "test_mac_ipv6_udp_mark_rss", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / udp src is 22 dst is 23 / end actions mark / rss / end", + "scapy_str": MAC_IPV6_UDP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 0} +} + +tv_mac_ipv6_udp_mark = { + "name": "test_mac_ipv6_udp_mark", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / udp src is 22 dst is 23 / end actions mark / end", + "scapy_str": MAC_IPV6_UDP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 0} +} + +tv_mac_ipv6_tcp_queue_index = { + "name": "test_mac_ipv6_tcp_queue_index", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / tcp src is 22 dst is 23 / end actions queue index 1 / mark / end", + "scapy_str": MAC_IPV6_TCP, + "check_param": {"port_id": 0, "queue": 1, "mark_id": 0} +} + +tv_mac_ipv6_tcp_queue_group = { + "name": "test_mac_ipv6_tcp_queue_group", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / tcp src is 22 dst is 23 / end actions rss queues 2 3 end / mark / end", + "scapy_str": MAC_IPV6_TCP, + "check_param": {"port_id": 0, "queue": [2, 3], "mark_id": 0} +} + +tv_mac_ipv6_tcp_drop = { + "name": "test_mac_ipv6_tcp_drop", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / tcp src is 22 dst is 23 / end actions drop / end", + "scapy_str": MAC_IPV6_TCP, + "check_param": {"port_id": 0, "drop": 1} +} + +tv_mac_ipv6_tcp_passthru = { + "name": "test_mac_ipv6_tcp_passthru", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / tcp src is 22 dst is 23 / end actions passthru / mark / end", + "scapy_str": MAC_IPV6_TCP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 0} +} + +tv_mac_ipv6_tcp_mark_rss = { + "name": "test_mac_ipv6_tcp_mark_rss", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / tcp src is 22 dst is 23 / end actions mark / rss / end", + "scapy_str": MAC_IPV6_TCP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 0} +} + +tv_mac_ipv6_tcp_mark = { + "name": "test_mac_ipv6_tcp_mark", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / tcp src is 22 dst is 23 / end actions mark / end", + "scapy_str": MAC_IPV6_TCP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 0} +} + +tv_mac_ipv6_sctp_queue_index = { + "name": "test_mac_ipv6_sctp_queue_index", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / sctp src is 22 dst is 23 / end actions queue index 3 / mark id 0 / end", + "scapy_str": MAC_IPV6_SCTP, + "check_param": {"port_id": 0, "queue": 3, "mark_id": 0 } +} + +tv_mac_ipv6_sctp_drop = { + "name": "test_mac_ipv6_sctp_drop", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / sctp src is 22 dst is 23 / end actions drop / end", + "scapy_str": MAC_IPV6_SCTP, + "check_param": {"port_id": 0, "drop": 1} +} + +tv_mac_ipv6_sctp_queue_group = { + "name": "test_mac_ipv6_sctp_queue_group", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / sctp src is 22 dst is 23 / end actions rss queues 12 13 end / mark id 0 / end", + "scapy_str": MAC_IPV6_SCTP, + "check_param": {"port_id": 0, "queue": [12, 13], "mark_id": 0} +} + +tv_mac_ipv6_sctp_passthru = { + "name": "test_mac_ipv6_sctp_passthru", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / sctp src is 22 dst is 23 / end actions passthru / mark id 0 / end", + "scapy_str": MAC_IPV6_SCTP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 0 } +} + +tv_mac_ipv6_sctp_mark_rss = { + "name": "test_mac_ipv6_sctp_mark_rss", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / sctp src is 22 dst is 23 / end actions mark id 1 / rss / end", + "scapy_str": MAC_IPV6_SCTP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 1 } +} + +tv_mac_ipv6_sctp_mark = { + "name": "test_mac_ipv6_sctp_mark", + "rule": "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 hop is 2 tc is 1 / sctp src is 22 dst is 23 / end actions mark id 2 / end", + "scapy_str": MAC_IPV6_SCTP, + "check_param": {"port_id": 0, "passthru": 1, "mark_id": 2 } +} + +tv_mac_ipv4_gtpu_eh_queue_index = { + "name": "test_mac_ipv4_gtpu_eh_queue_index", + "rule": "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x12345678 / gtp_psc qfi is 0x34 / end actions queue index 1 / end", + "scapy_str": MAC_IPV4_GTPU_EH, + "check_param": {"port_id": 0, "queue": 1} +} + +tv_mac_ipv4_gtpu_eh_drop = { + "name": "test_mac_ipv4_gtpu_eh_drop", + "rule": "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x12345678 / gtp_psc qfi is 0x34 / end actions drop / end", + "scapy_str": MAC_IPV4_GTPU_EH, + "check_param": {"port_id": 0, "drop": 1} +} + +tv_mac_ipv4_gtpu_eh_queue_group = { + "name": "test_mac_ipv4_gtpu_eh_queue_group", + "rule": "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x12345678 / gtp_psc qfi is 0x34 / end actions rss queues 2 3 end / mark / end", + "scapy_str": MAC_IPV4_GTPU_EH, + "check_param": {"port_id": 0, "mark_id": 0} +} + +tv_mac_ipv4_gtpu_eh_passthru = { + "name": "test_mac_ipv4_gtpu_eh_passthru", + "rule": "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x12345678 / gtp_psc qfi is 0x34 / end actions passthru / mark id 1 / end", + "scapy_str": MAC_IPV4_GTPU_EH, + "check_param": {"port_id": 0, "mark_id": 1} +} + +tv_mac_ipv4_gtpu_eh_mark_rss = { + "name": "test_mac_ipv4_gtpu_eh_mark_rss", + "rule": "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x12345678 / gtp_psc qfi is 0x34 / end actions mark / rss / end", + "scapy_str": MAC_IPV4_GTPU_EH, + "check_param": {"port_id": 0, "mark_id": 0} +} + +tv_mac_ipv4_gtpu_eh_mark = { + "name": "test_mac_ipv4_gtpu_eh_mark", + "rule": "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x12345678 / gtp_psc qfi is 0x34 / end actions mark / end", + "scapy_str": MAC_IPV4_GTPU_EH, + "check_param": {"port_id": 0, "mark_id": 0} +} + +tv_mac_ipv4_gtpu_queue_index = { + "name": "test_mac_ipv4_gtpu_queue_index", + "rule": "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x12345678 / end actions queue index 1 / mark id 0 / end", + "scapy_str": MAC_IPV4_GTPU, + "check_param": {"port_id": 0, "queue": 1, "mark_id": 0} +} + +tv_mac_ipv4_gtpu_drop = { + "name": "test_mac_ipv4_gtpu_drop", + "rule": "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x12345678 / end actions drop / end", + "scapy_str": MAC_IPV4_GTPU, + "check_param": {"port_id": 0, "drop": 1} +} + +tv_mac_ipv4_gtpu_queue_group = { + "name": "test_mac_ipv4_gtpu_queue_group", + "rule": "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x12345678 / end actions rss queues 1 2 end / mark id 1 / end", + "scapy_str": MAC_IPV4_GTPU, + "check_param": {"port_id": 0, "mark_id": 1} +} + +tv_mac_ipv4_gtpu_passthru = { + "name": "test_mac_ipv4_gtpu_passthru", + "rule": "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x12345678 / end actions passthru / mark id 2 / end", + "scapy_str": MAC_IPV4_GTPU, + "check_param": {"port_id": 0, "mark_id": 2} +} + +tv_mac_ipv4_gtpu_mark_rss = { + "name": "test_mac_ipv4_gtpu_mark_rss", + "rule": "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x12345678 / end actions mark id 3 / rss / end", + "scapy_str": MAC_IPV4_GTPU, + "check_param": {"port_id": 0, "mark_id": 3} +} + +tv_mac_ipv4_gtpu_mark = { + "name": "test_mac_ipv4_gtpu_mark", + "rule": "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x12345678 / end actions mark id 4 / end", + "scapy_str": MAC_IPV4_GTPU, + "check_param": {"port_id": 0, "mark_id": 4} +} + + +vectors_ipv4_pay = [tv_mac_ipv4_pay_queue_index, tv_mac_ipv4_pay_mark_rss,tv_mac_ipv4_pay_passthru, + tv_mac_ipv4_pay_drop, tv_mac_ipv4_pay_queue_group, tv_mac_ipv4_pay_mark] + +vectors_ipv4_udp = [tv_mac_ipv4_udp_drop, tv_mac_ipv4_udp_queue_group, tv_mac_ipv4_udp_queue_index, + tv_mac_ipv4_udp_mark_rss, tv_mac_ipv4_udp_passthru, tv_mac_ipv4_udp_mark] + +vectors_ipv4_tcp = [tv_mac_ipv4_tcp_drop, tv_mac_ipv4_tcp_queue_group, tv_mac_ipv4_tcp_queue_index, + tv_mac_ipv4_tcp_mark_rss, tv_mac_ipv4_tcp_passthru, tv_mac_ipv4_tcp_mark] + +vectors_ipv4_sctp = [tv_mac_ipv4_sctp_drop, tv_mac_ipv4_sctp_queue_group, tv_mac_ipv4_sctp_queue_index, + tv_mac_ipv4_sctp_passthru, tv_mac_ipv4_sctp_mark_rss, tv_mac_ipv4_sctp_mark] + +vectors_ipv6_pay = [tv_mac_ipv6_pay_drop, tv_mac_ipv6_pay_queue_group, tv_mac_ipv6_pay_queue_index, + tv_mac_ipv6_pay_mark_rss, tv_mac_ipv6_pay_passthru, tv_mac_ipv6_pay_mark] + +vectors_ipv6_udp = [tv_mac_ipv6_udp_drop, tv_mac_ipv6_udp_queue_group, tv_mac_ipv6_udp_queue_index, + tv_mac_ipv6_udp_passthru, tv_mac_ipv6_udp_mark_rss, tv_mac_ipv6_udp_mark] + +vectors_ipv6_tcp = [tv_mac_ipv6_tcp_drop, tv_mac_ipv6_tcp_queue_group, tv_mac_ipv6_tcp_queue_index, + tv_mac_ipv6_tcp_mark_rss, tv_mac_ipv6_tcp_passthru, tv_mac_ipv6_tcp_mark] + +vectors_ipv6_sctp = [tv_mac_ipv6_sctp_queue_index, tv_mac_ipv6_sctp_drop, tv_mac_ipv6_sctp_queue_group, + tv_mac_ipv6_sctp_passthru, tv_mac_ipv6_sctp_mark_rss, tv_mac_ipv6_sctp_mark] + +vectors_gtpu_eh = [tv_mac_ipv4_gtpu_eh_drop, tv_mac_ipv4_gtpu_eh_mark_rss, tv_mac_ipv4_gtpu_eh_queue_index, + tv_mac_ipv4_gtpu_eh_queue_group, tv_mac_ipv4_gtpu_eh_passthru, tv_mac_ipv4_gtpu_eh_mark] + +vectors_gtpu = [tv_mac_ipv4_gtpu_drop, tv_mac_ipv4_gtpu_mark_rss, tv_mac_ipv4_gtpu_queue_index, + tv_mac_ipv4_gtpu_queue_group, tv_mac_ipv4_gtpu_passthru, tv_mac_ipv4_gtpu_mark] + +vectors_pfcp = [tv_pfcp_queue_index, tv_pfcp_queue_group, tv_pfcp_passthru, tv_pfcp_drop, + tv_pfcp_mark, tv_pfcp_mark_rss] + +vectors_l2_ethertype = [tv_l2_ethertype_drop, tv_l2_ethertype_queue_index, tv_l2_ethertype_queue_group, + tv_l2_ethertype_passthru, tv_l2_ethertype_mark, tv_l2_ethertype_mark_rss] + +class TestIAVFFdir(TestCase): + + def rte_flow_process(self, vectors): + test_results = {} + for tv in vectors: + try: + port_id = tv["check_param"]["port_id"] + self.dut.send_expect("flow flush %d" % port_id, "testpmd> ", 120) + + # validate rule + self.validate_fdir_rule(tv["rule"], check_stats=True) + self.check_fdir_rule(port_id=port_id, stats=False) + + # create rule + rule_li = self.create_fdir_rule(tv["rule"], check_stats=True) + if "gtpu_eh" in tv["name"]: + gtpu_rss = [ + "flow create 0 ingress pattern eth / ipv4 / udp / gtpu / gtp_psc pdu_t is 1 / ipv4 / end actions rss types l3-src-only end key_len 0 queues end / end"] + gtpu_rss_rule_li = self.create_fdir_rule(gtpu_rss, check_stats=True) + + # send and check match packets + out1 = self.send_pkts_getouput(pkts=tv["scapy_str"]["match"]) + rfc.check_iavf_fdir_mark(out1, pkt_num=len(tv["scapy_str"]["match"]), check_param=tv["check_param"]) + # send and check mismatch packets + out2 = self.send_pkts_getouput(pkts=tv["scapy_str"]["mismatch"]) + rfc.check_iavf_fdir_mark(out2, pkt_num=len(tv["scapy_str"]["mismatch"]), check_param=tv["check_param"], + stats=False) + # list and destroy rule + if "gtpu_eh" in tv["name"]: + self.check_fdir_rule(port_id=port_id, rule_list=rule_li+gtpu_rss_rule_li) + else: + self.check_fdir_rule(port_id=port_id, rule_list=rule_li) + self.destroy_fdir_rule(rule_id=rule_li, port_id=port_id) + # send matched packet + out3 = self.send_pkts_getouput(pkts=tv["scapy_str"]["match"]) + rfc.check_iavf_fdir_mark(out3, pkt_num=len(tv["scapy_str"]["match"]), check_param=tv["check_param"], + stats=False) + # check not rule exists + if "gtpu_eh" in tv["name"]: + self.check_fdir_rule(port_id=port_id, rule_list=gtpu_rss_rule_li) + else: + self.check_fdir_rule(port_id=port_id, stats=False) + test_results[tv["name"]] = True + print((GREEN("case passed: %s" % tv["name"]))) + except Exception as e: + print((RED(e))) + test_results[tv["name"]] = False + continue + failed_cases = [] + for k, v in list(test_results.items()): + if not v: + failed_cases.append(k) + self.verify(all(test_results.values()), "{} failed.".format(failed_cases)) + + def multirules_process(self, vectors, port_id=0): + # create rules on only one port + test_results = {} + rule_li = [] + for tv in vectors: + try: + port_id = port_id + pkts=tv["scapy_str"] + check_param=tv["check_param"] + self.destroy_fdir_rule(rule_id=rule_li, port_id=port_id) + # validate rules + self.validate_fdir_rule(tv["rule"], check_stats=True) + + # create rules + rule_li = self.create_fdir_rule(tv["rule"], check_stats=True) + + for i in range(len(pkts)): + port_id = check_param[i]["port_id"] + out = self.send_pkts_getouput(pkts=pkts[i]) + rfc.check_iavf_fdir_mark(out, pkt_num=1, check_param=check_param[i]) + test_results[tv["name"]] = True + print((GREEN("case passed: %s" % tv["name"]))) + except Exception as e: + print((RED(e))) + test_results[tv["name"]] = False + continue + failed_cases = [] + for k, v in list(test_results.items()): + if not v: + failed_cases.append(k) + self.verify(all(test_results.values()), "{} failed.".format(failed_cases)) + + def set_up_all(self): + """ + Run at the start of each test suite. + prerequisites. + """ + # Based on h/w type, choose how many ports to use + self.dut_ports = self.dut.get_ports(self.nic) + self.verify(len(self.dut_ports) >= 2, "Insufficient ports for testing") + # Verify that enough threads are available + cores = self.dut.get_core_list("1S/4C/1T") + self.verify(cores is not None, "Insufficient cores for testing") + self.ports_socket = self.dut.get_numa_id(self.dut_ports[0]) + localPort0 = self.tester.get_local_port(self.dut_ports[0]) + localPort1 = self.tester.get_local_port(self.dut_ports[1]) + self.tester_iface0 = self.tester.get_interface(localPort0) + self.tester_iface1 = self.tester.get_interface(localPort1) + self.pf0_intf = self.dut.ports_info[self.dut_ports[0]]['intf'] + self.pf1_intf = self.dut.ports_info[self.dut_ports[1]]['intf'] + self.pf0_mac = self.dut.get_mac_address(0) + self.pf1_mac = self.dut.get_mac_address(1) + + #bind pf to kernel + for port in self.dut_ports: + netdev = self.dut.ports_info[port]['port'] + netdev.bind_driver(driver='ice') + + #set vf driver + self.vf_driver = 'vfio-pci' + self.dut.send_expect('modprobe vfio-pci', '#') + self.suite_config = rfc.get_suite_config(self) + + self.pkt = Packet() + self.pmd_output = PmdOutput(self.dut) + + self.re_load_ice_driver() + self.setup_2pf_4vf_env() + + self.src_file_dir = 'dep/' + self.dut_file_dir = '/tmp/' + + def set_up(self): + """ + Run before each test case. + """ + self.launch_testpmd() + + def setup_2pf_4vf_env(self, driver='default'): + + #get PF interface name + self.used_dut_port_0 = self.dut_ports[0] + self.used_dut_port_1 = self.dut_ports[1] + + #generate 2 VFs on PF + self.dut.generate_sriov_vfs_by_port(self.used_dut_port_0, 2, driver=driver) + self.dut.generate_sriov_vfs_by_port(self.used_dut_port_1, 2, driver=driver) + self.sriov_vfs_pf0 = self.dut.ports_info[self.used_dut_port_0]['vfs_port'] + self.sriov_vfs_pf1 = self.dut.ports_info[self.used_dut_port_1]['vfs_port'] + + self.dut.send_expect('ip link set %s vf 0 mac 00:11:22:33:44:55' % self.pf0_intf, '#') + self.dut.send_expect('ip link set %s vf 1 mac 00:11:22:33:44:66' % self.pf0_intf, '#') + self.dut.send_expect('ip link set %s vf 0 mac 00:11:22:33:44:77' % self.pf1_intf, '#') + self.dut.send_expect('ip link set %s vf 1 mac 00:11:22:33:44:88' % self.pf1_intf, '#') + + #bind VF0 and VF1 to dpdk driver + try: + for vf_port in self.sriov_vfs_pf0: + vf_port.bind_driver(self.vf_driver) + for vf_port in self.sriov_vfs_pf1: + vf_port.bind_driver(self.vf_driver) + + except Exception as e: + self.destroy_env() + raise Exception(e) + out = self.dut.send_expect('./usertools/dpdk-devbind.py -s', '#') + print(out) + + def setup_npf_nvf_env(self, pf_num=2, vf_num=2, driver='default'): + + #get PF interface name + self.used_dut_port_0 = self.dut_ports[0] + self.used_dut_port_1 = self.dut_ports[1] + try: + # generate vf on pf + if pf_num == 1: + self.dut.generate_sriov_vfs_by_port(self.used_dut_port_0, vf_num, driver=driver) + self.sriov_vfs_pf0 = self.dut.ports_info[self.used_dut_port_0]['vfs_port'] + #bind VF0 and VF1 to dpdk driver + for vf_port in self.sriov_vfs_pf0: + vf_port.bind_driver(self.vf_driver) + else: + self.dut.generate_sriov_vfs_by_port(self.used_dut_port_0, vf_num, driver=driver) + self.dut.generate_sriov_vfs_by_port(self.used_dut_port_1, vf_num, driver=driver) + self.sriov_vfs_pf0 = self.dut.ports_info[self.used_dut_port_0]['vfs_port'] + self.sriov_vfs_pf1 = self.dut.ports_info[self.used_dut_port_1]['vfs_port'] + for vf_port in self.sriov_vfs_pf0: + vf_port.bind_driver(self.vf_driver) + for vf_port in self.sriov_vfs_pf1: + vf_port.bind_driver(self.vf_driver) + + except Exception as e: + self.destroy_env() + raise Exception(e) + out = self.dut.send_expect('./usertools/dpdk-devbind.py -s', '#') + print(out) + + def destroy_env(self): + """ + This is to stop testpmd and destroy 1pf and 2vfs environment. + """ + self.dut.send_expect("quit", "# ", 60) + time.sleep(2) + self.dut.destroy_sriov_vfs_by_port(self.dut_ports[0]) + self.dut.destroy_sriov_vfs_by_port(self.dut_ports[1]) + + def re_load_ice_driver(self): + """ + remove and reload the ice driver + """ + self.dut.send_expect("rmmod ice", "# ", 20) + ice_driver_file_location = self.suite_config["ice_driver_file_location"] + self.dut.send_expect("insmod %s" % ice_driver_file_location, "# ") + self.dut.send_expect("ifconfig %s up" % self.tester_iface0, "# ", 15) + self.dut.send_expect("ifconfig %s up" % self.tester_iface1, "# ", 15) + + def config_testpmd(self): + self.pmd_output.execute_cmd("set fwd rxonly") + self.pmd_output.execute_cmd("set verbose 1") + # specify a fixed rss-hash-key for cvl ether + self.pmd_output.execute_cmd( + "port config 0 rss-hash-key ipv4 1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd") + self.pmd_output.execute_cmd( + "port config 1 rss-hash-key ipv4 1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd") + res = self.pmd_output.wait_link_status_up('all', timeout=15) + self.verify(res is True, 'there have port link is down') + self.pmd_output.execute_cmd("start") + + def launch_testpmd(self): + self.pmd_output.start_testpmd(cores="1S/4C/1T", + param="--rxq=16 --txq=16", + eal_param="-w %s -w %s" % ( + self.sriov_vfs_pf0[0].pci,self.sriov_vfs_pf0[1].pci), + socket=self.ports_socket) + self.config_testpmd() + + def send_packets(self, packets, pf_id=0): + self.pkt.update_pkt(packets) + tx_port = self.tester_iface0 if pf_id == 0 else self.tester_iface1 + self.pkt.send_pkt(crb=self.tester, tx_port=tx_port) + + def send_pkts_getouput(self, pkts, pf_id=0): + """ + if pkt_info is True, we need to get packet infomation to check the RSS hash and FDIR. + if pkt_info is False, we just need to get the packet number and queue number. + """ + self.send_packets(pkts, pf_id) + time.sleep(1) + out_info = self.dut.get_session_output(timeout=1) + out_pkt = self.pmd_output.execute_cmd("stop") + out = out_info + out_pkt + self.pmd_output.execute_cmd("start") + return out + + def validate_fdir_rule(self, rule, check_stats=None): + # validate rule. + p = "Flow rule validated" + rule_list = [] + if isinstance(rule, list): + for i in rule: + length = len(i) + rule_rep = i[0:5] + "validate" + i[11:length] + out = self.pmd_output.execute_cmd(rule_rep) + if (p in out) and ("Failed" not in out): + rule_list.append(True) + else: + rule_list.append(False) + elif isinstance(rule, str): + length = len(rule) + rule_rep = rule[0:5] + "validate" + rule[11:length] + out = self.pmd_output.execute_cmd(rule_rep) + if (p in out) and ("Failed" not in out): + rule_list.append(True) + else: + rule_list.append(False) + else: + raise Exception("unsupported rule type, only accept list or str") + if check_stats: + self.verify(all(rule_list), "some rules validate failed, result %s" % rule_list) + elif check_stats == False: + self.verify(not any(rule_list), "all rules should validate failed, result %s" % rule_list) + + def create_fdir_rule(self, rule, check_stats=None): + p = re.compile(r"Flow rule #(\d+) created") + rule_list = [] + if isinstance(rule, list): + for i in rule: + out = self.pmd_output.execute_cmd(i) + m = p.search(out) + if m: + rule_list.append(m.group(1)) + else: + rule_list.append(False) + elif isinstance(rule, str): + out = self.pmd_output.execute_cmd(rule) + m = p.search(out) + if m: + rule_list.append(m.group(1)) + else: + rule_list.append(False) + else: + raise Exception("unsupported rule type, only accept list or str") + if check_stats: + self.verify(all(rule_list), "some rules create failed, result %s" % rule_list) + elif check_stats == False: + self.verify(not any(rule_list), "all rules should create failed, result %s" % rule_list) + return rule_list + + def destroy_fdir_rule(self, rule_id, port_id=0): + if isinstance(rule_id, list): + for i in rule_id: + out = self.pmd_output.execute_cmd("flow destroy %s rule %s" % (port_id, i)) + p = re.compile(r"Flow rule #(\d+) destroyed") + m = p.search(out) + self.verify(m, "flow rule %s delete failed" % rule_id) + else: + out = self.pmd_output.execute_cmd("flow destroy %s rule %s" % (port_id, rule_id)) + p = re.compile(r"Flow rule #(\d+) destroyed") + m = p.search(out) + self.verify(m, "flow rule %s delete failed" % rule_id) + + def check_fdir_rule(self, port_id=0, stats=True, rule_list=None): + out = self.pmd_output.execute_cmd("flow list %s" % port_id) + p = re.compile(r"ID\s+Group\s+Prio\s+Attr\s+Rule") + if stats: + self.verify(p.search(out), "flow rule on port %s is not existed" % port_id) + if rule_list: + p = re.compile("^(\d+)\s") + li = out.splitlines() + res = list(filter(bool, list(map(p.match, li)))) + result = [i.group(1) for i in res] + self.verify(sorted(result) == sorted(rule_list), + "check rule list failed. expect %s, result %s" % (rule_list, result)) + else: + self.verify(not p.search(out), "flow rule on port %s is existed" % port_id) + + def check_rule_number(self, port_id=0, num=0): + out = self.pmd_output.execute_cmd("flow list %s" % port_id) + result_scanner = r'\d*.*?\d*.*?\d*.*?=>*' + scanner = re.compile(result_scanner, re.DOTALL) + li = scanner.findall(out) + if num == 0: + self.verify(not li, "there should be no rule listed") + else: + print(len(li)) + self.verify(len(li) == num, "the amount of rules is wrong.") + return out + + def test_mac_ipv4_pay(self): + self.rte_flow_process(vectors_ipv4_pay) + + def test_mac_ipv4_udp(self): + self.rte_flow_process(vectors_ipv4_udp) + + def test_mac_ipv4_tcp(self): + self.rte_flow_process(vectors_ipv4_tcp) + + def test_mac_ipv4_sctp(self): + self.rte_flow_process(vectors_ipv4_sctp) + + def test_mac_ipv6_pay(self): + self.rte_flow_process(vectors_ipv6_pay) + + def test_mac_ipv6_udp(self): + self.rte_flow_process(vectors_ipv6_udp) + + def test_mac_ipv6_tcp(self): + self.rte_flow_process(vectors_ipv6_tcp) + + def test_mac_ipv6_sctp(self): + self.rte_flow_process(vectors_ipv6_sctp) + + def test_mac_ipv4_gtpu_eh(self): + self.rte_flow_process(vectors_gtpu_eh) + + def test_mac_ipv4_gtpu(self): + self.rte_flow_process(vectors_gtpu) + + def test_mac_ipv4_protocol(self): + rules = [ + "flow create 0 ingress pattern eth / ipv4 dst is 192.168.0.21 proto is 1 / end actions queue index 1 / mark id 1 / end", + "flow create 0 ingress pattern eth / ipv4 dst is 192.168.0.21 proto is 17 / end actions passthru / mark id 3 / end"] + + #validate rules + self.validate_fdir_rule(rules, check_stats=True) + self.check_fdir_rule(port_id=0, stats=False) + + #create rules + rule_li = self.create_fdir_rule(rules, check_stats=True) + self.check_fdir_rule(port_id=0, rule_list=rule_li) + + # pkt1 and pkt2 in "match" match rule 0, pkt3-6 match rule 1. + out1 = self.send_pkts_getouput(MAC_IPV4_PAY_protocol["match"][0:2]) + rfc.check_iavf_fdir_mark(out1, pkt_num=2, check_param={"port_id": 0, "mark_id": 1, "queue": 1}, stats=True) + + out2 = self.send_pkts_getouput(MAC_IPV4_PAY_protocol["match"][2:6]) + rfc.check_iavf_fdir_mark(out2, pkt_num=4, check_param={"port_id": 0, "mark_id": 3, "passthru": 1}, stats=True) + + # send mismatched packets: + out3 = self.send_pkts_getouput(MAC_IPV4_PAY_protocol["mismatch"]) + rfc.check_iavf_fdir_mark(out3, pkt_num=4, check_param={"port_id": 0, "passthru": 1}, stats=False) + + # destroy the rules and check there is no rule listed. + self.destroy_fdir_rule(rule_id=rule_li, port_id=0) + self.check_fdir_rule(port_id=0, stats=False) + + # send matched packet + out4 = self.send_pkts_getouput(MAC_IPV4_PAY_protocol["match"]) + rfc.check_iavf_fdir_mark(out4, pkt_num=6, check_param={"port_id": 0, "passthru": 1}, stats=False) + + def test_mac_ipv6_protocol(self): + rules = [ + "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 proto is 44 / end actions rss queues 5 6 end / mark id 0 / end", + "flow create 0 ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 proto is 6 / end actions mark id 2 / rss / end"] + + # validate rules + self.validate_fdir_rule(rules, check_stats=True) + self.check_fdir_rule(port_id=0, stats=False) + + # create rules + rule_li = self.create_fdir_rule(rules, check_stats=True) + self.check_fdir_rule(port_id=0, rule_list=rule_li) + + # pkt1-4 in "match" match rule 0, pkt5-6 match rule 1. + out1 = self.send_pkts_getouput(MAC_IPV6_PAY_protocol["match"][0:4]) + rfc.check_iavf_fdir_mark(out1, pkt_num=4, check_param={"port_id": 0, "mark_id": 0, "queue": [5, 6]}, stats=True) + + out2 = self.send_pkts_getouput(MAC_IPV6_PAY_protocol["match"][4:6]) + rfc.check_iavf_fdir_mark(out2, pkt_num=2, check_param={"port_id": 0, "mark_id": 2, "passthru": 1}, stats=True) + + # send mismatched packets: + out3 = self.send_pkts_getouput(MAC_IPV6_PAY_protocol["mismatch"]) + rfc.check_iavf_fdir_mark(out3, pkt_num=3, check_param={"port_id": 0, "passthru": 1}, stats=False) + + # destroy the rules and check there is no rule listed. + self.destroy_fdir_rule(rule_id=rule_li, port_id=0) + self.check_fdir_rule(port_id=0, stats=False) + + # send matched packet + out4 = self.send_pkts_getouput(MAC_IPV6_PAY_protocol["match"]) + rfc.check_iavf_fdir_mark(out4, pkt_num=6, check_param={"port_id": 0, "passthru": 1}, stats=False) + + def test_mac_ipv4_gtpu_eh_without_teid(self): + rules = "flow create 0 ingress pattern eth / ipv4 / udp / gtpu / gtp_psc qfi is 0x34 / end actions queue index 1 / mark id 3 / end" + MAC_IPV4_GTPU_EH_WITHOUT_TEID = { + "match": 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x34)/IP()/TCP()/Raw("x"*20)', + "mismatch": 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255)/GTP_PDUSession_ExtensionHeader(pdu_type=1, qos_flow=0x35)/IP()/TCP()/Raw("x"*20)' + } + # validate rules + self.validate_fdir_rule(rules, check_stats=True) + self.check_fdir_rule(port_id=0, stats=False) + + # create rules + rule_li = self.create_fdir_rule(rules, check_stats=True) + self.check_fdir_rule(port_id=0, rule_list=rule_li) + + # send matched packet + out1 = self.send_pkts_getouput(MAC_IPV4_GTPU_EH_WITHOUT_TEID["match"]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 0, "mark_id": 3, "queue": 1}, stats=True) + + # send mismatched packets: + out2 = self.send_pkts_getouput(MAC_IPV4_GTPU_EH_WITHOUT_TEID["mismatch"]) + rfc.check_iavf_fdir_mark(out2, pkt_num=1, check_param={"port_id": 0, "passthru": 1}, stats=False) + + # destroy the rules and check there is no rule listed. + self.destroy_fdir_rule(rule_id=rule_li, port_id=0) + self.check_fdir_rule(port_id=0, stats=False) + + # send matched packet + out3 = self.send_pkts_getouput(MAC_IPV4_GTPU_EH_WITHOUT_TEID["match"]) + rfc.check_iavf_fdir_mark(out3, pkt_num=1, check_param={"port_id": 0, "passthru": 1}, stats=False) + + def test_mac_ipv4_gtpu_eh_without_qfi(self): + rules = "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x12345678 / gtp_psc / end actions rss queues 2 3 end / mark id 1 / end" + MAC_IPV4_GTPU_EH_WITHOUT_QFI = { + "match": 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x12345678)/GTP_PDUSession_ExtensionHeader(pdu_type=1)/IP()/UDP()/Raw("x"*20)', + "mismatch": 'Ether(src="a4:bf:01:51:27:ca", dst="00:11:22:33:44:55")/IP(src="192.168.0.20", dst="192.168.0.21")/UDP(dport=2152)/GTP_U_Header(gtp_type=255, teid=0x1234567)/GTP_PDUSession_ExtensionHeader(pdu_type=1)/IP()/UDP()/Raw("x"*20)' + } + # validate rules + self.validate_fdir_rule(rules, check_stats=True) + self.check_fdir_rule(port_id=0, stats=False) + + # create rules + rule_li = self.create_fdir_rule(rules, check_stats=True) + self.check_fdir_rule(port_id=0, rule_list=rule_li) + + # send matched packet + out1 = self.send_pkts_getouput(MAC_IPV4_GTPU_EH_WITHOUT_QFI["match"]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 0, "mark_id": 1, "queue": [2, 3]}, stats=True) + + # send mismatched packets: + out2 = self.send_pkts_getouput(MAC_IPV4_GTPU_EH_WITHOUT_QFI["mismatch"]) + rfc.check_iavf_fdir_mark(out2, pkt_num=1, check_param={"port_id": 0, "passthru": 1}, stats=False) + + # destroy the rules and check there is no rule listed. + self.destroy_fdir_rule(rule_id=rule_li, port_id=0) + self.check_fdir_rule(port_id=0, stats=False) + + # send matched packet + out3 = self.send_pkts_getouput(MAC_IPV4_GTPU_EH_WITHOUT_QFI["match"]) + rfc.check_iavf_fdir_mark(out3, pkt_num=1, check_param={"port_id": 0, "passthru": 1}, stats=False) + + def test_pfcp(self): + # open the RSS function for PFCP session packet. + out = self.pmd_output.execute_cmd("flow create 0 ingress pattern eth / ipv4 / udp / pfcp / end actions rss types pfcp end key_len 0 queues end / end") + self.verify("Flow rule #0 created" in out, "failed to enable RSS function for MAC_IPV4_PFCP session packet") + out = self.pmd_output.execute_cmd("flow create 0 ingress pattern eth / ipv6 / udp / pfcp / end actions rss types pfcp end key_len 0 queues end / end") + self.verify("Flow rule #1 created" in out, "failed to enable RSS function for MAC_IPV6_PFCP session packet") + self.multirules_process(vectors_pfcp) + + def test_l2_ethertype(self): + self.multirules_process(vectors_l2_ethertype) + + def test_negative_case(self): + """ + negative cases + """ + rules = { + "invalid parameters of queue index" : "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 proto is 255 ttl is 2 tos is 4 / end actions queue index 16 / end", + "invalid parameters of rss queues" : [ + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 proto is 255 ttl is 2 tos is 4 / end actions rss queues 1 2 3 end / end", + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 proto is 255 ttl is 2 tos is 4 / end actions rss queues 0 end / end", + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 proto is 255 ttl is 2 tos is 4 / end actions rss queues end / end", + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 proto is 255 ttl is 2 tos is 4 / end actions rss queues 1 2 3 5 end / end", + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 proto is 255 ttl is 2 tos is 4 / end actions rss queues 15 16 end / end", + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / end actions rss queues 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 end / end"], + "invalid mark id" : "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 proto is 255 ttl is 2 tos is 4 / end actions passthru / mark id 4294967296 / end", + "invalid parameters of GTPU input set" : [ + "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x12345678 / gtp_psc qfi is 0x100 / end actions queue index 1 / end", + "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x100000000 / gtp_psc qfi is 0x5 / end actions queue index 2 / end", + "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x100000000 / end actions queue index 1 / end"], + "unsupported type of L2 ethertype" : [ + "flow create 0 ingress pattern eth type is 0x0800 / end actions queue index 1 / end", + "flow create 0 ingress pattern eth type is 0x86dd / end actions queue index 1 / end"], + "conflicted actions" : "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / end actions queue index 1 / rss queues 2 3 end / end", + "void action" : "flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x12345678 / gtp_psc qfi is 0x34 / end actions end", + "unsupported action" : "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 proto is 255 ttl is 2 tos is 4 / end actions count / end", + "unsupported input set field" : "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 tc is 2 / end actions queue index 1 / end", + "void input set value" : "flow create 0 ingress pattern eth / ipv4 / end actions queue index 1 / end", + "invalid port" : "flow create 2 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / end actions queue index 1 / end" + } + # all the rules failed to create and validate + self.validate_fdir_rule(rules["invalid parameters of queue index"], check_stats=False) + self.create_fdir_rule(rules["invalid parameters of queue index"], check_stats=False) + self.validate_fdir_rule(rules["invalid parameters of rss queues"], check_stats=False) + self.create_fdir_rule(rules["invalid parameters of rss queues"], check_stats=False) + self.validate_fdir_rule(rules["invalid parameters of GTPU input set"], check_stats=False) + self.create_fdir_rule(rules["invalid parameters of GTPU input set"], check_stats=False) + self.validate_fdir_rule(rules["unsupported type of L2 ethertype"], check_stats=False) + self.create_fdir_rule(rules["unsupported type of L2 ethertype"], check_stats=False) + self.validate_fdir_rule(rules["conflicted actions"], check_stats=False) + self.create_fdir_rule(rules["conflicted actions"], check_stats=False) + self.validate_fdir_rule(rules["void action"], check_stats=False) + self.create_fdir_rule(rules["void action"], check_stats=False) + self.validate_fdir_rule(rules["unsupported input set field"], check_stats=False) + self.create_fdir_rule(rules["unsupported input set field"], check_stats=False) + self.validate_fdir_rule(rules["void input set value"], check_stats=False) + self.create_fdir_rule(rules["void input set value"], check_stats=False) + self.validate_fdir_rule(rules["invalid port"], check_stats=False) + self.create_fdir_rule(rules["invalid port"], check_stats=False) + + # check there is no rule listed + self.check_fdir_rule(port_id=0, stats=False) + self.check_fdir_rule(port_id=1, stats=False) + + # duplicated rules + rule = "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / end actions queue index 1 / end" + self.create_fdir_rule(rule, check_stats=True) + self.create_fdir_rule(rule, check_stats=False) + self.pmd_output.execute_cmd("flow destroy 0 rule 0") + + # conflict rules + rule = "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / end actions queue index 1 / end" + self.create_fdir_rule(rule, check_stats=True) + rule1 = "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / end actions queue index 2 / end" + self.create_fdir_rule(rule1, check_stats=False) + rule2 = "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 ttl is 2 tos is 4 / end actions drop / end" + self.create_fdir_rule(rule2, check_stats=False) + self.pmd_output.execute_cmd("flow destroy 0 rule 0", timeout=1) + + # delete a non-existent rule + out1 = self.pmd_output.execute_cmd("flow destroy 0 rule 0") + self.verify("error" not in out1, "there shouldn't report error message") + out2 = self.pmd_output.execute_cmd("flow destroy 2 rule 0") + self.verify("Invalid port" in out2, "there should report error message") + out3 = self.pmd_output.execute_cmd("flow flush 2") + self.verify("No such device" in out3, "port 2 doesn't exist.") + out4 = self.pmd_output.execute_cmd("flow list 2") + self.verify("Invalid port" in out4, "port 2 doesn't exist.") + + self.check_fdir_rule(port_id=0, stats=False) + self.check_fdir_rule(port_id=1, stats=False) + + def test_unsupported_pattern_with_OS_package(self): + """ + Create GTPU rule, PFCP rule and L2 Ethertype rule with OS default package + """ + rule = ["flow create 0 ingress pattern eth / ipv4 / udp / gtpu teid is 0x12345678 / gtp_psc qfi is 0x34 / end actions drop / end", + "flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 0 / end actions queue index 1 / end", + "flow create 0 ingress pattern eth type is 0x8863 / end actions queue index 1 / mark id 1 / end"] + self.destroy_env() + os_package_location = self.suite_config["os_default_package_file_location"] + comms_package_location = self.suite_config["comms_package_file_location"] + package_location = self.suite_config["package_file_location"] + self.dut.send_expect("cp %s %s" % (os_package_location, package_location), "# ") + self.re_load_ice_driver() + self.setup_2pf_4vf_env() + self.launch_testpmd() + + self.validate_fdir_rule(rule, check_stats=False) + self.create_fdir_rule(rule, check_stats=False) + self.check_fdir_rule(port_id=0, stats=False) + + self.destroy_env() + self.dut.send_expect("cp %s %s" % (comms_package_location, package_location), "# ") + self.re_load_ice_driver() + self.setup_2pf_4vf_env() + + def test_create_same_rule_on_pf_vf(self): + """ + create same rules on pf and vf, no conflict + """ + self.dut.kill_all() + self.session_secondary = self.dut.new_session() + self.session_third = self.dut.new_session() + + rules = [ + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / tcp src is 22 dst is 23 / end actions queue index 1 / end", + "flow create 1 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / tcp src is 22 dst is 23 / end actions queue index 1 / end"] + pkts = { + "matched": [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:66")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:77")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:88")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)'], + "mismatched": [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=24)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:66")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=24)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:77")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=24)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:88")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=24)/Raw("x" * 80)'], + "pf": [ + 'Ether(dst="%s")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)' % self.pf0_mac, + 'Ether(dst="%s")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)' % self.pf1_mac] + } + out_pf0 = self.dut.send_expect("ethtool -N %s flow-type tcp4 src-ip 192.168.0.20 dst-ip 192.168.0.21 src-port 22 dst-port 23 action 1" % self.pf0_intf, "# ") + out_pf1 = self.dut.send_expect("ethtool -N %s flow-type tcp4 src-ip 192.168.0.20 dst-ip 192.168.0.21 src-port 22 dst-port 23 action 1" % self.pf1_intf, "# ") + p = re.compile(r"Added rule with ID (\d+)") + m0 = p.search(out_pf0) + m1 = p.search(out_pf1) + + eal_param = "-c 0xf -n 6 -w %s -w %s --file-prefix=pf0" % (self.sriov_vfs_pf0[0].pci,self.sriov_vfs_pf0[1].pci) + command = "./%s/app/testpmd %s -- -i %s" % (self.dut.target, eal_param, "--rxq=16 --txq=16") + self.dut.send_expect(command, "testpmd> ", 300) + self.config_testpmd() + + eal_param = "-c 0xf0 -n 6 -w %s -w %s --file-prefix=pf1" % (self.sriov_vfs_pf1[0].pci,self.sriov_vfs_pf1[1].pci) + command = "./%s/app/testpmd %s -- -i %s" % (self.dut.target, eal_param, "--rxq=16 --txq=16") + self.session_secondary.send_expect(command, "testpmd> ", 300) + #self.session_secondary.config_testpmd() + self.session_secondary.send_expect("set fwd rxonly", "testpmd> ") + self.session_secondary.send_expect("set verbose 1", "testpmd> ") + # specify a fixed rss-hash-key for cvl ether + self.session_secondary.send_expect( + "port config 0 rss-hash-key ipv4 1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd", "testpmd> ") + self.session_secondary.send_expect( + "port config 1 rss-hash-key ipv4 1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd", "testpmd> ") + self.session_secondary.send_expect("start", "testpmd> ") + + self.create_fdir_rule(rules, check_stats=True) + self.session_secondary.send_expect("flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / tcp src is 22 dst is 23 / end actions queue index 1 / end", "created") + self.session_secondary.send_expect("flow create 1 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / tcp src is 22 dst is 23 / end actions queue index 1 / end", "created") + + # confirm pf link is up + self.session_third.send_expect("ifconfig %s up" % self.pf0_intf, "# ", 15) + self.session_third.send_expect("ifconfig %s up" % self.pf1_intf, "# ", 15) + time.sleep(1) + + # send matched packets + self.tester.scapy_append('sendp([%s], iface="%s")' % (pkts["pf"][0], self.tester_iface0)) + self.tester.scapy_append('sendp([%s], iface="%s")' % (pkts["pf"][1], self.tester_iface1)) + self.tester.scapy_execute() + time.sleep(1) + out_pf0 = self.session_third.send_expect("ethtool -S %s" % self.pf0_intf, "# ") + self.verify("rx_queue_1_packets: 1" in out_pf0, "the packet is not redirected to expected queue of pf0") + out_pf1 = self.session_third.send_expect("ethtool -S %s" % self.pf1_intf, "# ") + self.verify("rx_queue_1_packets: 1" in out_pf1, "the packet is not redirected to expected queue of pf1") + + out_vf00 = self.send_pkts_getouput(pkts["matched"][0]) + rfc.check_iavf_fdir_mark(out_vf00, pkt_num=1, check_param={"port_id": 0, "queue": 1}, stats=True) + out_vf01 = self.send_pkts_getouput(pkts["matched"][1]) + rfc.check_iavf_fdir_mark(out_vf01, pkt_num=1, check_param={"port_id": 1, "queue": 1}, stats=True) + + self.send_packets(pkts["matched"][2], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf10 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf10, pkt_num=1, check_param={"port_id": 0, "queue": 1}, stats=True) + + self.send_packets(pkts["matched"][3], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf11 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf11, pkt_num=1, check_param={"port_id": 1, "queue": 1}, stats=True) + + #send mismatched packets + out_vf00 = self.send_pkts_getouput(pkts["mismatched"][0]) + rfc.check_iavf_fdir_mark(out_vf00, pkt_num=1, check_param={"port_id": 0, "queue": 1}, stats=False) + out_vf01 = self.send_pkts_getouput(pkts["mismatched"][1]) + rfc.check_iavf_fdir_mark(out_vf01, pkt_num=1, check_param={"port_id": 1, "queue": 1}, stats=False) + + self.send_packets(pkts["mismatched"][2], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf10 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf10, pkt_num=1, check_param={"port_id": 0, "queue": 1}, stats=False) + + self.send_packets(pkts["mismatched"][3], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf11 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf11, pkt_num=1, check_param={"port_id": 1, "queue": 1}, stats=False) + + # flush all the rules + self.dut.send_expect("flow flush 0", "testpmd> ") + self.dut.send_expect("flow flush 1", "testpmd> ") + self.session_secondary.send_expect("flow flush 0", "testpmd> ") + self.session_secondary.send_expect("flow flush 1", "testpmd> ") + + self.session_third.send_expect("ethtool -N %s delete %d" % (self.pf0_intf, int(m0.group(1))), "# ") + self.session_third.send_expect("ethtool -N %s delete %d" % (self.pf1_intf, int(m1.group(1))), "# ") + self.session_third.send_expect("ethtool -n %s" % (self.pf0_intf), "Total 0 rules") + self.session_third.send_expect("ethtool -n %s" % (self.pf1_intf), "Total 0 rules") + + # send matched packets + self.tester.scapy_append('sendp([%s], iface="%s")' % (pkts["pf"][0], self.tester_iface0)) + self.tester.scapy_append('sendp([%s], iface="%s")' % (pkts["pf"][1], self.tester_iface1)) + self.tester.scapy_execute() + + out_pf0 = self.session_third.send_expect("ethtool -S %s" % self.pf0_intf, "# ") + self.verify("rx_queue_1_packets: 1" in out_pf0, "the packet is redirected to expected queue of pf0") + out_pf1 = self.session_third.send_expect("ethtool -S %s" % self.pf1_intf, "# ") + self.verify("rx_queue_1_packets: 1" in out_pf1, "the packet is redirected to expected queue of pf1") + + out_vf00 = self.send_pkts_getouput(pkts["matched"][0]) + rfc.check_iavf_fdir_mark(out_vf00, pkt_num=1, check_param={"port_id": 0, "queue": 1}, stats=False) + out_vf01 = self.send_pkts_getouput(pkts["matched"][1]) + rfc.check_iavf_fdir_mark(out_vf01, pkt_num=1, check_param={"port_id": 1, "queue": 1}, stats=False) + + self.send_packets(pkts["matched"][2], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf10 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf10, pkt_num=1, check_param={"port_id": 0, "queue": 1}, stats=False) + + self.send_packets(pkts["matched"][3], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf11 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf11, pkt_num=1, check_param={"port_id": 1, "queue": 1}, stats=False) + + self.dut.close_session(self.session_secondary) + self.dut.close_session(self.session_third) + + def test_create_same_input_diff_action_on_pf_vf(self): + """ + create same input set but different action rules on pf and vf, no conflict. + """ + self.dut.kill_all() + self.session_secondary = self.dut.new_session() + self.session_third = self.dut.new_session() + + rules = [ + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / tcp src is 22 dst is 23 / end actions queue index 1 / mark id 1 / end", + "flow create 1 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / tcp src is 22 dst is 23 / end actions rss queues 3 4 end / mark / end", + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / tcp src is 22 dst is 23 / end actions drop / end", + "flow create 1 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / tcp src is 22 dst is 23 / end actions passthru / mark id 1 / end"] + pkts = { + "matched": [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:66")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:77")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:88")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)'], + "mismatched": [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=24)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:66")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=24)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:77")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=24)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:88")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=24)/Raw("x" * 80)'], + "pf": [ + 'Ether(dst="%s")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)' % self.pf0_mac, + 'Ether(dst="%s")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)' % self.pf1_mac] + } + out_pf0 = self.dut.send_expect("ethtool -N %s flow-type tcp4 src-ip 192.168.0.20 dst-ip 192.168.0.21 src-port 22 dst-port 23 action 1" % self.pf0_intf, "# ") + out_pf1 = self.dut.send_expect("ethtool -N %s flow-type tcp4 src-ip 192.168.0.20 dst-ip 192.168.0.21 src-port 22 dst-port 23 action 2" % self.pf1_intf, "# ") + p = re.compile(r"Added rule with ID (\d+)") + m0 = p.search(out_pf0) + m1 = p.search(out_pf1) + + eal_param = "-c 0xf -n 6 -w %s -w %s --file-prefix=pf0" % (self.sriov_vfs_pf0[0].pci,self.sriov_vfs_pf0[1].pci) + command = "./%s/app/testpmd %s -- -i %s" % (self.dut.target, eal_param, "--rxq=16 --txq=16") + self.dut.send_expect(command, "testpmd> ", 300) + self.config_testpmd() + + eal_param = "-c 0xf0 -n 6 -w %s -w %s --file-prefix=pf1" % (self.sriov_vfs_pf1[0].pci,self.sriov_vfs_pf1[1].pci) + command = "./%s/app/testpmd %s -- -i %s" % (self.dut.target, eal_param, "--rxq=16 --txq=16") + self.session_secondary.send_expect(command, "testpmd> ", 300) + #self.session_secondary.config_testpmd() + self.session_secondary.send_expect("set fwd rxonly", "testpmd> ") + self.session_secondary.send_expect("set verbose 1", "testpmd> ") + # specify a fixed rss-hash-key for cvl ether + self.session_secondary.send_expect( + "port config 0 rss-hash-key ipv4 1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd", "testpmd> ") + self.session_secondary.send_expect( + "port config 1 rss-hash-key ipv4 1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd", "testpmd> ") + self.session_secondary.send_expect("start", "testpmd> ") + + self.create_fdir_rule(rules[:2], check_stats=True) + self.session_secondary.send_expect(rules[2], "created") + self.session_secondary.send_expect(rules[3], "created") + + # confirm pf link is up + self.session_third.send_expect("ifconfig %s up" % self.pf0_intf, "# ", 15) + self.session_third.send_expect("ifconfig %s up" % self.pf1_intf, "# ", 15) + time.sleep(1) + + # send matched packets + self.tester.scapy_append('sendp([%s], iface="%s")' % (pkts["pf"][0], self.tester_iface0)) + self.tester.scapy_append('sendp([%s], iface="%s")' % (pkts["pf"][1], self.tester_iface1)) + self.tester.scapy_execute() + time.sleep(1) + out_pf0 = self.session_third.send_expect("ethtool -S %s" % self.pf0_intf, "# ") + self.verify("rx_queue_1_packets: 1" in out_pf0, "the packet is not redirected to expected queue of pf0") + out_pf1 = self.session_third.send_expect("ethtool -S %s" % self.pf1_intf, "# ") + self.verify("rx_queue_2_packets: 1" in out_pf1, "the packet is not redirected to expected queue of pf1") + + out_vf00 = self.send_pkts_getouput(pkts["matched"][0]) + rfc.check_iavf_fdir_mark(out_vf00, pkt_num=1, check_param={"port_id": 0, "queue": 1, "mark_id": 1}, stats=True) + out_vf01 = self.send_pkts_getouput(pkts["matched"][1]) + rfc.check_iavf_fdir_mark(out_vf01, pkt_num=1, check_param={"port_id": 1, "queue": [3, 4], "mark_id": 0}, stats=True) + + self.send_packets(pkts["matched"][2], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf10 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf10, pkt_num=1, check_param={"port_id": 0, "drop": 1}, stats=True) + + self.send_packets(pkts["matched"][3], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf11 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf11, pkt_num=1, check_param={"port_id": 1, "passthru": 1, "mark_id": 1}, stats=True) + + #send mismatched packets + out_vf00 = self.send_pkts_getouput(pkts["mismatched"][0]) + rfc.check_iavf_fdir_mark(out_vf00, pkt_num=1, check_param={"port_id": 0, "queue": 1, "mark_id": 1}, stats=False) + out_vf01 = self.send_pkts_getouput(pkts["mismatched"][1]) + rfc.check_iavf_fdir_mark(out_vf01, pkt_num=1, check_param={"port_id": 1, "queue": [3, 4], "mark_id": 0}, stats=False) + + self.send_packets(pkts["mismatched"][2], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf10 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf10, pkt_num=1, check_param={"port_id": 0, "drop": 1}, stats=False) + + self.send_packets(pkts["mismatched"][3], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf11 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf11, pkt_num=1, check_param={"port_id": 1, "passthru": 1, "mark_id": 1}, stats=False) + + # flush all the rules + self.dut.send_expect("flow flush 0", "testpmd> ") + self.dut.send_expect("flow flush 1", "testpmd> ") + self.session_secondary.send_expect("flow flush 0", "testpmd> ") + self.session_secondary.send_expect("flow flush 1", "testpmd> ") + + self.session_third.send_expect("ethtool -N %s delete %d" % (self.pf0_intf, int(m0.group(1))), "# ") + self.session_third.send_expect("ethtool -N %s delete %d" % (self.pf1_intf, int(m1.group(1))), "# ") + self.session_third.send_expect("ethtool -n %s" % (self.pf0_intf), "Total 0 rules") + self.session_third.send_expect("ethtool -n %s" % (self.pf1_intf), "Total 0 rules") + + # send matched packets + self.tester.scapy_append('sendp([%s], iface="%s")' % (pkts["pf"][0], self.tester_iface0)) + self.tester.scapy_append('sendp([%s], iface="%s")' % (pkts["pf"][1], self.tester_iface1)) + self.tester.scapy_execute() + + out_pf0 = self.session_third.send_expect("ethtool -S %s" % self.pf0_intf, "# ") + self.verify("rx_queue_1_packets: 1" in out_pf0, "the packet is redirected to expected queue of pf0") + out_pf1 = self.session_third.send_expect("ethtool -S %s" % self.pf1_intf, "# ") + self.verify("rx_queue_2_packets: 1" in out_pf1, "the packet is redirected to expected queue of pf1") + + out_vf00 = self.send_pkts_getouput(pkts["matched"][0]) + rfc.check_iavf_fdir_mark(out_vf00, pkt_num=1, check_param={"port_id": 0, "queue": 1, "mark_id": 1}, stats=False) + out_vf01 = self.send_pkts_getouput(pkts["matched"][1]) + rfc.check_iavf_fdir_mark(out_vf01, pkt_num=1, check_param={"port_id": 1, "queue": [3, 4], "mark_id": 0}, stats=False) + + self.send_packets(pkts["matched"][2], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf10 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf10, pkt_num=1, check_param={"port_id": 0, "drop": 1}, stats=False) + + self.send_packets(pkts["matched"][3], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf11 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf11, pkt_num=1, check_param={"port_id": 1, "passthru": 1, "mark_id": 1}, stats=False) + + self.dut.close_session(self.session_secondary) + self.dut.close_session(self.session_third) + + def test_create_diff_input_diff_action_on_pf_vf(self): + """ + create different rules on pf and vf + """ + self.dut.kill_all() + self.session_secondary = self.dut.new_session() + self.session_third = self.dut.new_session() + + rules = [ + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / tcp src is 22 dst is 23 / end actions rss queues 2 3 end / end", + "flow create 1 ingress pattern eth / ipv4 src is 192.168.0.22 dst is 192.168.0.23 / udp src is 22 dst is 23 / end actions queue index 5 / mark / end", + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.22 dst is 192.168.0.23 / udp src is 22 dst is 23 / end actions queue index 5 / mark id 1 / end", + "flow create 1 ingress pattern eth / ipv4 src is 192.168.0.22 dst is 192.168.0.23 tos is 4 / tcp src is 22 dst is 23 / end actions drop / end"] + pkts = { + "matched": [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:66")/IP(src="192.168.0.22",dst="192.168.0.23")/UDP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:77")/IP(src="192.168.0.22",dst="192.168.0.23")/UDP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:88")/IP(src="192.168.0.22",dst="192.168.0.23",tos=4)/TCP(sport=22,dport=23)/Raw("x" * 80)'], + "mismatched": [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=24)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:66")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=24)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:77")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=24)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:88")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=24)/Raw("x" * 80)'], + "pf": [ + 'Ether(dst="%s")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)' % self.pf0_mac, + 'Ether(dst="%s")/IP(src="192.168.0.22",dst="192.168.0.23")/UDP(sport=22,dport=23)/Raw("x" * 80)' % self.pf1_mac] + } + out_pf0 = self.dut.send_expect("ethtool -N %s flow-type tcp4 src-ip 192.168.0.20 dst-ip 192.168.0.21 src-port 22 dst-port 23 action 1" % self.pf0_intf, "# ") + out_pf1 = self.dut.send_expect("ethtool -N %s flow-type udp4 src-ip 192.168.0.22 dst-ip 192.168.0.23 src-port 22 dst-port 23 action -1" % self.pf1_intf, "# ") + p = re.compile(r"Added rule with ID (\d+)") + m0 = p.search(out_pf0) + m1 = p.search(out_pf1) + + eal_param = "-c 0xf -n 6 -w %s -w %s --file-prefix=pf0" % (self.sriov_vfs_pf0[0].pci,self.sriov_vfs_pf0[1].pci) + command = "./%s/app/testpmd %s -- -i %s" % (self.dut.target, eal_param, "--rxq=16 --txq=16") + self.dut.send_expect(command, "testpmd> ", 300) + self.config_testpmd() + + eal_param = "-c 0xf0 -n 6 -w %s -w %s --file-prefix=pf1" % (self.sriov_vfs_pf1[0].pci,self.sriov_vfs_pf1[1].pci) + command = "./%s/app/testpmd %s -- -i %s" % (self.dut.target, eal_param, "--rxq=16 --txq=16") + self.session_secondary.send_expect(command, "testpmd> ", 300) + #self.session_secondary.config_testpmd() + self.session_secondary.send_expect("set fwd rxonly", "testpmd> ") + self.session_secondary.send_expect("set verbose 1", "testpmd> ") + # specify a fixed rss-hash-key for cvl ether + self.session_secondary.send_expect( + "port config 0 rss-hash-key ipv4 1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd", "testpmd> ") + self.session_secondary.send_expect( + "port config 1 rss-hash-key ipv4 1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd", "testpmd> ") + self.session_secondary.send_expect("start", "testpmd> ") + + self.create_fdir_rule(rules[:2], check_stats=True) + self.session_secondary.send_expect(rules[2], "created") + self.session_secondary.send_expect(rules[3], "created") + + # confirm pf link is up + self.session_third.send_expect("ifconfig %s up" % self.pf0_intf, "# ", 15) + self.session_third.send_expect("ifconfig %s up" % self.pf1_intf, "# ", 15) + time.sleep(1) + + # send matched packets + self.tester.scapy_append('sendp([%s], iface="%s")' % (pkts["pf"][0], self.tester_iface0)) + self.tester.scapy_append('sendp([%s], iface="%s")' % (pkts["pf"][1], self.tester_iface1)) + self.tester.scapy_execute() + time.sleep(1) + + out_pf0 = self.session_third.send_expect("ethtool -S %s" % self.pf0_intf, "# ") + self.verify("rx_queue_1_packets: 1" in out_pf0, "the packet is not redirected to expected queue of pf0") + out_pf1 = self.session_third.send_expect("ethtool -S %s" % self.pf1_intf, "# ") + self.verify("rx_dropped: 1" in out_pf1, "the packet is not dropped pf1") + + out_vf00 = self.send_pkts_getouput(pkts["matched"][0]) + rfc.check_iavf_fdir_mark(out_vf00, pkt_num=1, check_param={"port_id": 0, "queue": [2, 3]}, stats=True) + out_vf01 = self.send_pkts_getouput(pkts["matched"][1]) + rfc.check_iavf_fdir_mark(out_vf01, pkt_num=1, check_param={"port_id": 1, "queue": 5, "mark_id": 0}, stats=True) + + self.send_packets(pkts["matched"][2], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf10 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf10, pkt_num=1, check_param={"port_id": 0, "queue": 5, "mark_id": 1}, stats=True) + + self.send_packets(pkts["matched"][3], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf11 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf11, pkt_num=1, check_param={"port_id": 1, "drop": 1}, stats=True) + + #send mismatched packets + out_vf00 = self.send_pkts_getouput(pkts["mismatched"][0]) + rfc.check_iavf_fdir_mark(out_vf00, pkt_num=1, check_param={"port_id": 0, "queue": [2, 3]}, stats=False) + out_vf01 = self.send_pkts_getouput(pkts["mismatched"][1]) + rfc.check_iavf_fdir_mark(out_vf01, pkt_num=1, check_param={"port_id": 1, "queue": 5, "mark_id": 0}, stats=False) + + self.send_packets(pkts["mismatched"][2], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf10 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf10, pkt_num=1, check_param={"port_id": 0, "queue": 5, "mark_id": 1}, stats=False) + + self.send_packets(pkts["mismatched"][3], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf11 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf11, pkt_num=1, check_param={"port_id": 1, "drop": 1}, stats=False) + + # flush all the rules + self.dut.send_expect("flow flush 0", "testpmd> ") + self.dut.send_expect("flow flush 1", "testpmd> ") + self.session_secondary.send_expect("flow flush 0", "testpmd> ") + self.session_secondary.send_expect("flow flush 1", "testpmd> ") + + self.session_third.send_expect("ethtool -N %s delete %d" % (self.pf0_intf, int(m0.group(1))), "# ") + self.session_third.send_expect("ethtool -N %s delete %d" % (self.pf1_intf, int(m1.group(1))), "# ") + self.session_third.send_expect("ethtool -n %s" % (self.pf0_intf), "Total 0 rules") + self.session_third.send_expect("ethtool -n %s" % (self.pf1_intf), "Total 0 rules") + + # send matched packets + self.tester.scapy_append('sendp([%s], iface="%s")' % (pkts["pf"][0], self.tester_iface0)) + self.tester.scapy_append('sendp([%s], iface="%s")' % (pkts["pf"][1], self.tester_iface1)) + self.tester.scapy_execute() + + out_pf0 = self.session_third.send_expect("ethtool -S %s" % self.pf0_intf, "# ") + self.verify("rx_queue_1_packets: 1" in out_pf0, "the rule is not destroyed") + out_pf1 = self.session_third.send_expect("ethtool -S %s" % self.pf1_intf, "# ") + self.verify("rx_dropped: 1" in out_pf1, "the packet is dropped by pf1") + + #send mismatched packets + out_vf00 = self.send_pkts_getouput(pkts["matched"][0]) + rfc.check_iavf_fdir_mark(out_vf00, pkt_num=1, check_param={"port_id": 0, "queue": [2, 3]}, stats=False) + out_vf01 = self.send_pkts_getouput(pkts["matched"][1]) + rfc.check_iavf_fdir_mark(out_vf01, pkt_num=1, check_param={"port_id": 1, "queue": 5, "mark_id": 0}, stats=False) + + self.send_packets(pkts["matched"][2], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf10 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf10, pkt_num=1, check_param={"port_id": 0, "queue": 5, "mark_id": 1}, stats=False) + + self.send_packets(pkts["matched"][3], pf_id=1) + out_info = self.session_secondary.get_session_before(timeout=2) + out_pkt = self.session_secondary.send_expect("stop", "testpmd> ") + out_vf11 = out_info + out_pkt + self.session_secondary.send_expect("start", "testpmd> ") + rfc.check_iavf_fdir_mark(out_vf11, pkt_num=1, check_param={"port_id": 1, "drop": 1}, stats=False) + + self.dut.close_session(self.session_secondary) + self.dut.close_session(self.session_third) + + def test_maxnum_14336rules_1vf(self): + """ + vfs share 14336 rules table + """ + self.dut.kill_all() + src_file = 'create_14336_rules' + flows=open(self.src_file_dir + src_file,mode='w') + count=0 + for i in range(56): + for j in range(256): + flows.write('flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.%d.%d / end actions queue index 5 / mark / end \n'%(i,j)) + count=count+1 + flows.close() + self.verify(count == 14336, "failed to create 14336 fdir rules on vf.") + self.dut.session.copy_file_to(self.src_file_dir + src_file, self.dut_file_dir) + + eal_param = "-c f -n 6 -w %s -w %s" % (self.sriov_vfs_pf0[0].pci,self.sriov_vfs_pf0[1].pci) + command = "./%s/app/testpmd %s -- -i %s" % (self.dut.target, eal_param, "--rxq=16 --txq=16 --cmdline-file=%s" % self.dut_file_dir + src_file) + self.dut.send_expect(command, "testpmd> ", 300) + self.config_testpmd() + + # can't create more than 14336 rules on vf0 + rule_14336_vf0 = "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.56.0 / end actions queue index 5 / mark / end" + self.create_fdir_rule(rule_14336_vf0, check_stats=False) + #check there are 14336 rules created. + out = self.check_rule_number(port_id=0, num=14336) + self.verify("14336" not in out, "more than 14336 rules can be created on 1vf") + + # can't create rule on vf1 + rule_0_vf1 = "flow create 1 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.56.0 / end actions queue index 5 / mark / end" + self.create_fdir_rule(rule_0_vf1, check_stats=False) + self.check_fdir_rule(port_id=1, stats=False) + + pkt_0 = 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.0")/Raw("x" * 80)' + pkt_14335 = 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.55.255")/Raw("x" * 80)' + pkt_14336 = 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.56.0")/Raw("x" * 80)' + + # check packet match rule 0 and rule 14335 can be redirected to expected queue + out_0 = self.send_pkts_getouput(pkts=pkt_0, pf_id=0) + rfc.check_iavf_fdir_mark(out_0, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 5}, stats=True) + out_14335 = self.send_pkts_getouput(pkts=pkt_14335, pf_id=0) + rfc.check_iavf_fdir_mark(out_14335, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 5}, stats=True) + # check packet match rule 14336 can't be redirected to expected queue. + out_14336 = self.send_pkts_getouput(pkts=pkt_14336, pf_id=0) + rfc.check_iavf_fdir_mark(out_14336, pkt_num=1, check_param={"port_id": 0, "queue": 5}, stats=False) + + # flush all the rules + self.dut.send_expect("flow flush 0", "testpmd> ", timeout=200) + self.check_fdir_rule(port_id=0, stats=False) + out_0 = self.send_pkts_getouput(pkts=pkt_0, pf_id=0) + out_14335 = self.send_pkts_getouput(pkts=pkt_14335, pf_id=0) + rfc.check_iavf_fdir_mark(out_0, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 5}, stats=False) + rfc.check_iavf_fdir_mark(out_14335, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 5}, stats=False) + + self.create_fdir_rule(rule_14336_vf0, check_stats=True) + self.create_fdir_rule(rule_0_vf1, check_stats=True) + out_14336 = self.send_pkts_getouput(pkts=pkt_14336, pf_id=0) + rfc.check_iavf_fdir_mark(out_14336, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 5}, stats=True) + + + def test_maxnum_14336rules_2vf(self): + """ + vfs share 14336 rules table + """ + self.dut.kill_all() + self.session_secondary = self.dut.new_session() + src_file = 'create_14336_rules_2vf' + flows=open(self.src_file_dir + src_file,mode='w') + flows.write('flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.0 / end actions queue index 5 / mark / end \n') + count=1 + for i in range(55): + for j in range(256): + flows.write('flow create 1 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.%d.%d / end actions queue index 5 / mark / end \n'%(i,j)) + count=count+1 + for j in range(255): + flows.write('flow create 1 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.55.%d / end actions queue index 5 / mark / end \n' % j) + count=count+1 + flows.close() + self.verify(count == 14336, "failed to create 14336 fdir rules on 2 vfs.") + self.dut.session.copy_file_to(self.src_file_dir + src_file, self.dut_file_dir) + + eal_param = "-c f -n 6 -w %s -w %s" % (self.sriov_vfs_pf0[0].pci,self.sriov_vfs_pf1[0].pci) + command = "./%s/app/testpmd %s -- -i %s" % (self.dut.target, eal_param, "--rxq=16 --txq=16 --cmdline-file=%s" % self.dut_file_dir + src_file) + self.dut.send_expect(command, "testpmd> ", 300) + + self.config_testpmd() + self.check_fdir_rule(port_id=0, rule_list=['0']) + + # can't create more than 14336 rules on 2vf + rule_14335_vf1 = "flow create 1 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.56.0 / end actions queue index 5 / mark / end" + self.create_fdir_rule(rule_14335_vf1, check_stats=False) + #check there are 14336 rules created. + out = self.check_rule_number(port_id=1, num=14335) + self.verify("14335" not in out, "more than 14336 rules are created on 2vf") + + # can't create new rule on vf0 + rule_1_vf0 = "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.56.0 / end actions queue index 5 / mark / end" + self.create_fdir_rule(rule_1_vf0, check_stats=False) + self.check_rule_number(port_id=0, num=1) + + pkt_0 = 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.0")/Raw("x" * 80)' + pkt_1 = 'Ether(dst="00:11:22:33:44:77")/IP(src="192.168.0.20",dst="192.168.0.0")/Raw("x" * 80)' + pkt_14335 = 'Ether(dst="00:11:22:33:44:77")/IP(src="192.168.0.20",dst="192.168.55.254")/Raw("x" * 80)' + pkt_14336 = 'Ether(dst="00:11:22:33:44:77")/IP(src="192.168.0.20",dst="192.168.56.0")/Raw("x" * 80)' + + self.session_secondary.send_expect("ifconfig %s up" % self.pf0_intf, "# ", 15) + self.session_secondary.send_expect("ifconfig %s up" % self.pf1_intf, "# ", 15) + time.sleep(1) + + # check packet match rule 0 and rule 14335 can be redirected to expected queue + out_0 = self.send_pkts_getouput(pkts=pkt_0, pf_id=0) + rfc.check_iavf_fdir_mark(out_0, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 5}, stats=True) + out_1 = self.send_pkts_getouput(pkts=pkt_1, pf_id=1) + rfc.check_iavf_fdir_mark(out_1, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 5}, stats=True) + + out_14335 = self.send_pkts_getouput(pkts=pkt_14335, pf_id=1) + rfc.check_iavf_fdir_mark(out_14335, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 5}, stats=True) + # check packet match rule 14336 can't be redirected to expected queue. + out_14336 = self.send_pkts_getouput(pkts=pkt_14336, pf_id=1) + rfc.check_iavf_fdir_mark(out_14336, pkt_num=1, check_param={"port_id": 1, "queue": 5}, stats=False) + + # destroy rule 0 on vf0, then create a new rule on vf1 successfully. + self.dut.send_expect("flow flush 0", "testpmd> ") + self.create_fdir_rule(rule_14335_vf1, check_stats=True) + out_14336 = self.send_pkts_getouput(pkts=pkt_14336, pf_id=1) + rfc.check_iavf_fdir_mark(out_14336, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 5}, stats=True) + + self.dut.send_expect("flow flush 1", "testpmd> ", timeout=300) + + self.check_fdir_rule(port_id=0, stats=False) + self.check_fdir_rule(port_id=1, stats=False) + + out_0 = self.send_pkts_getouput(pkts=pkt_0, pf_id=0) + out_1 = self.send_pkts_getouput(pkts=pkt_1, pf_id=1) + out_14335 = self.send_pkts_getouput(pkts=pkt_14335, pf_id=1) + rfc.check_iavf_fdir_mark(out_0, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 5}, stats=False) + rfc.check_iavf_fdir_mark(out_1, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 5}, stats=False) + rfc.check_iavf_fdir_mark(out_14335, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 5}, stats=False) + + self.dut.close_session(self.session_secondary) + + def test_maxnum_15360rules_1pf_2vf(self): + """ + 2*100G NIC, each pf can create 1024 rules at least, vfs share 14336 rules table + """ + self.dut.kill_all() + self.session_secondary = self.dut.new_session() + + #create 1025 rules on pf0 + src_file = 'iavf_fdir_15360_kernel_rules' + flows=open(self.src_file_dir + src_file,mode='w') + count=0 + for i in range(4): + for j in range(256): + flows.write('ethtool -N enp134s0f1 flow-type tcp4 src-ip 192.168.%d.%d dst-ip 192.168.100.2 src-port 32 dst-port 33 action 8 \n'%(i,j)) + count=count+1 + flows.write('ethtool -N enp134s0f1 flow-type tcp4 src-ip 192.168.100.0 dst-ip 192.168.100.2 src-port 32 dst-port 33 action 8 \n') + count=count+1 + flows.close() + self.verify(count == 1025, "failed to create 1025 fdir rules on pf.") + self.dut.session.copy_file_to(self.src_file_dir + src_file, self.dut_file_dir) + + # create 1025 rules on pf0 + fkr = open(self.dut_file_dir + "iavf_fdir_15360_kernel_rules", "r+") + kernel_rules = fkr.read() + fkr.close() + self.dut.send_expect(kernel_rules, "# ", 300) + # write the kernel rules result to file + fkw = open("1025_kernel_rules_result.txt", "w") + fkw.write(self.dut.send_expect("ethtool -n %s" % self.pf1_intf, "# ", 300)) + + #create 1 rule on vf00, and 14334 rules on vf01 + src_file_vf = 'iavf_fdir_15360_vf_rules' + flows = open(self.src_file_dir + src_file_vf, mode='w') + flows.write('flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.0 / end actions queue index 5 / mark / end \n') + count=1 + for i in range(55): + for j in range(256): + flows.write('flow create 1 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.%d.%d / end actions queue index 5 / mark / end \n'%(i,j)) + count=count+1 + for j in range(254): + flows.write('flow create 1 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.55.%d / end actions queue index 5 / mark / end \n' % j) + count=count+1 + flows.close() + self.verify(count == 14335, "failed to create 14335 fdir rules on vfs.") + self.dut.session.copy_file_to(self.src_file_dir + src_file_vf, self.dut_file_dir) + + # start testpmd with creating rules in commandline + eal_param = "-c f -n 6 -w %s -w %s" % (self.sriov_vfs_pf0[0].pci,self.sriov_vfs_pf0[1].pci) + command = "./%s/app/testpmd %s -- -i %s" % (self.dut.target, eal_param, "--rxq=16 --txq=16 --cmdline-file=%s" % self.dut_file_dir + src_file_vf) + fdw = open("15360_rules_vf_result.txt", "w") + fdw.write(self.dut.send_expect(command, "testpmd> ", 360)) + fdw.close() + + self.config_testpmd() + # check there is 1 rule created on vf00 + self.check_fdir_rule(port_id=0, rule_list=['0']) + + # can't create more than 14335 rules on 2vf, the rule index is from 0 + rule_14334_vf1 = "flow create 1 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.56.0 / end actions queue index 5 / mark / end" + pkt_14334 = 'Ether(dst="00:11:22:33:44:66")/IP(src="192.168.0.20",dst="192.168.56.0")/Raw("x" * 80)' + self.create_fdir_rule(rule_14334_vf1, check_stats=False) + + #check there are 14334 rules created on vf01 + out = self.check_rule_number(port_id=1, num=14334) + self.verify("14334" not in out, "more than 15360 rules are created on 2vf") + + # delete a rule on pf0 + self.session_secondary.send_expect("ethtool -N %s delete 14847" % self.pf1_intf, "# ") + time.sleep(3) + + # then can create one more rule on vf01 + self.create_fdir_rule(rule_14334_vf1, check_stats=True) + out_14334 = self.send_pkts_getouput(pkts=pkt_14334, pf_id=0) + rfc.check_iavf_fdir_mark(out_14334, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 5}, stats=True) + + self.dut.send_expect("flow flush 0", "testpmd> ", timeout=200) + self.dut.send_expect("flow flush 1", "testpmd> ", timeout=200) + self.check_fdir_rule(port_id=0, stats=False) + self.check_fdir_rule(port_id=1, stats=False) + out_14334 = self.send_pkts_getouput(pkts=pkt_14334, pf_id=0) + rfc.check_iavf_fdir_mark(out_14334, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 5}, stats=False) + + self.dut.send_expect("quit", "# ") + self.dut.close_session(self.session_secondary) + self.re_load_ice_driver() + + def test_maxnum_128_profiles(self): + """ + There are 128 profiles in total. + each pf apply for 8 profiles when kernel driver init, 4 for non-tunnel packet, 4 for tunnel packet. + profile 0 and profile 1 are default profile for specific packet. + design case with 2*100G card, so only 110 profiles can be used for vf. + """ + self.destroy_env() + self.setup_npf_nvf_env(pf_num=1,vf_num=16) + self.dut.send_expect('ip link set %s vf 10 mac 00:11:22:33:44:55' % self.pf0_intf, '#') + command = "./%s/app/testpmd -c f -n 6 -- -i %s" % (self.dut.target, "--rxq=16 --txq=16") + self.dut.send_expect(command, "testpmd> ", 360) + self.config_testpmd() + for port_id in range(11): + rules = [ + "flow create %d ingress pattern eth / ipv4 proto is 255 / end actions queue index 1 / mark / end" % port_id, + "flow create %d ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / udp src is 22 dst is 23 / end actions queue index 1 / mark / end" % port_id, + "flow create %d ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / tcp src is 22 dst is 23 / end actions queue index 1 / mark / end" % port_id, + "flow create %d ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / sctp src is 22 dst is 23 / end actions queue index 1 / mark / end" % port_id, + "flow create %d ingress pattern eth / ipv6 proto is 0 / end actions mark / rss / end" % port_id, + "flow create %d ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 / udp src is 22 dst is 23 / end actions queue index 1 / mark / end" % port_id, + "flow create %d ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 / tcp src is 22 dst is 23 / end actions queue index 1 / mark / end" % port_id, + "flow create %d ingress pattern eth / ipv6 dst is CDCD:910A:2222:5498:8475:1111:3900:2020 src is 2001::2 / sctp src is 22 dst is 23 / end actions queue index 1 / mark / end" % port_id, + "flow create %d ingress pattern eth type is 0x8863 / end actions queue index 1 / mark id 1 / end" % port_id, + "flow create %d ingress pattern eth / ipv4 / udp / pfcp s_field is 0 / end actions queue index 2 / end" % port_id] + self.create_fdir_rule(rules, check_stats=True) + + rule = "flow create 11 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / udp src is 22 dst is 23 / end actions queue index 1 / mark / end" + self.create_fdir_rule(rule, check_stats=False) + self.check_fdir_rule(port_id=11, stats=False) + pkt = 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21")/UDP(sport=22, dport=23)/ Raw("x" * 80)' + out = self.send_pkts_getouput(pkts=pkt) + rfc.check_iavf_fdir_mark(out, pkt_num=1, check_param={"port_id": 10, "mark_id": 0, "queue": 1}, stats=True) + + self.dut.send_expect("flow flush 10", "testpmd> ") + self.check_fdir_rule(port_id=10, stats=False) + out = self.send_pkts_getouput(pkts=pkt) + rfc.check_iavf_fdir_mark(out, pkt_num=1, check_param={"port_id": 10, "mark_id": 0, "queue": 1}, stats=False) + + self.create_fdir_rule(rule, check_stats=False) + + self.destroy_env() + self.setup_2pf_4vf_env() + + def test_stress_port_stop_start(self): + """ + Rules can take effect after port stop/start + """ + rule = "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / end actions queue index 1 / mark / end" + pkt = 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21") / Raw("x" * 80)' + self.create_fdir_rule(rule, check_stats=True) + out = self.send_pkts_getouput(pkts=pkt) + rfc.check_iavf_fdir_mark(out, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 1}, stats=True) + self.dut.send_expect("stop", "testpmd> ") + self.dut.send_expect("port stop 0", "testpmd> ") + self.dut.send_expect("port start 0", "testpmd> ") + self.dut.send_expect("start", "testpmd> ") + self.check_fdir_rule(port_id=0, rule_list=['0']) + out = self.send_pkts_getouput(pkts=pkt) + rfc.check_iavf_fdir_mark(out, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 1}, stats=True) + + def test_stress_add_delete_rules_1vf(self): + """ + add/delete rules 14336 times on 1 vf + """ + rules = [ + "flow create 0 ingress pattern eth / ipv4 proto is 255 / end actions queue index 1 / mark / end", + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / tcp src is 22 dst is 23 / end actions rss queues 2 3 end / mark id 1 / end"] + pkts = [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21", proto=255)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)'] + self.dut.kill_all() + src_file = 'add_delete_rules_1vf' + flows=open(self.src_file_dir + src_file,mode='w') + count=0 + for i in range(14336): + flows.write('%s \n' % rules[0]) + flows.write('%s \n' % rules[1]) + flows.write('flow flush 0\n') + count=count+1 + flows.close() + self.verify(count == 14336, "failed to add/delete 14336 times of fdir rules on vf.") + self.dut.session.copy_file_to(self.src_file_dir + src_file, self.dut_file_dir) + + eal_param = "-c f -n 6 -w %s -w %s" % (self.sriov_vfs_pf0[0].pci,self.sriov_vfs_pf0[1].pci) + command = "./%s/app/testpmd %s -- -i %s" % (self.dut.target, eal_param, "--rxq=16 --txq=16 --cmdline-file=%s" % self.dut_file_dir + src_file) + self.dut.send_expect(command, "testpmd> ", 900) + self.config_testpmd() + self.check_fdir_rule(port_id=0, stats=False) + self.create_fdir_rule(rules, check_stats=True) + out_0 = self.send_pkts_getouput(pkts=pkts[0]) + rfc.check_iavf_fdir_mark(out_0, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 1}, stats=True) + out_1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out_1, pkt_num=1, check_param={"port_id": 0, "mark_id": 1, "queue": [2, 3]}, stats=True) + + def test_stress_add_delete_rules_2vf(self): + """ + add/delete rules 14336 times on 2 vfs + """ + rules = [ + "flow create 0 ingress pattern eth / ipv4 src is 192.168.56.0 dst is 192.1.0.0 tos is 4 / tcp src is 22 dst is 23 / end actions queue index 5 / end", + "flow create 1 ingress pattern eth / ipv4 src is 192.168.56.0 dst is 192.1.0.0 tos is 4 / tcp src is 22 dst is 23 / end actions queue index 5 / end"] + pkts = [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.56.0",dst="192.1.0.0", tos=4)/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:66")/IP(src="192.168.56.0",dst="192.1.0.0", tos=4)/TCP(sport=22,dport=23)/Raw("x" * 80)'] + self.dut.kill_all() + src_file = 'add_delete_rules_2vfs' + flows=open(self.src_file_dir + src_file,mode='w') + count=0 + for i in range(14336): + flows.write('%s \n' % rules[0]) + flows.write('%s \n' % rules[1]) + flows.write('flow flush 0\n') + flows.write('flow flush 1\n') + count=count+1 + flows.close() + self.verify(count == 14336, "failed to add/delete 14336 times of fdir rules on 2 vfs.") + self.dut.session.copy_file_to(self.src_file_dir + src_file, self.dut_file_dir) + + eal_param = "-c f -n 6 -w %s -w %s" % (self.sriov_vfs_pf0[0].pci,self.sriov_vfs_pf0[1].pci) + command = "./%s/app/testpmd %s -- -i %s" % (self.dut.target, eal_param, "--rxq=16 --txq=16 --cmdline-file=%s" % self.dut_file_dir + src_file) + self.dut.send_expect(command, "testpmd> ", 900) + self.config_testpmd() + self.check_fdir_rule(port_id=0, stats=False) + self.check_fdir_rule(port_id=1, stats=False) + + self.create_fdir_rule(rules, check_stats=True) + out_0 = self.send_pkts_getouput(pkts=pkts[0], pf_id=0) + rfc.check_iavf_fdir_mark(out_0, pkt_num=1, check_param={"port_id": 0, "queue": 5}, stats=True) + out_1 = self.send_pkts_getouput(pkts=pkts[1], pf_id=0) + rfc.check_iavf_fdir_mark(out_1, pkt_num=1, check_param={"port_id": 1, "queue": 5}, stats=True) + + def test_stress_delete_rules(self): + """ + delete 1st/2nd/last rule won't affect other rules + """ + rules = [ + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / tcp src is 22 dst is 23 / end actions queue index 1 / mark id 1 / end", + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / tcp src is 22 dst is 24 / end actions queue index 2 / mark id 2 / end", + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.20 dst is 192.168.0.21 / tcp src is 22 dst is 25 / end actions queue index 3 / mark id 3 / end"] + pkts = [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=24)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.20",dst="192.168.0.21")/TCP(sport=22,dport=25)/Raw("x" * 80)'] + + rule_li = self.create_fdir_rule(rules, check_stats=True) + self.check_fdir_rule(port_id=0, rule_list=rule_li) + out_0 = self.send_pkts_getouput(pkts=pkts[0]) + rfc.check_iavf_fdir_mark(out_0, pkt_num=1, check_param={"port_id": 0, "mark_id": 1, "queue": 1}, stats=True) + out_1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out_1, pkt_num=1, check_param={"port_id": 0, "mark_id": 2, "queue": 2}, stats=True) + out_2 = self.send_pkts_getouput(pkts=pkts[2]) + rfc.check_iavf_fdir_mark(out_2, pkt_num=1, check_param={"port_id": 0, "mark_id": 3, "queue": 3}, stats=True) + + self.dut.send_expect("flow destroy 0 rule 0", "testpmd> ") + out_0 = self.send_pkts_getouput(pkts=pkts[0]) + rfc.check_iavf_fdir_mark(out_0, pkt_num=1, check_param={"port_id": 0, "mark_id": 1, "queue": 1}, stats=False) + out_1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out_1, pkt_num=1, check_param={"port_id": 0, "mark_id": 2, "queue": 2}, stats=True) + out_2 = self.send_pkts_getouput(pkts=pkts[2]) + rfc.check_iavf_fdir_mark(out_2, pkt_num=1, check_param={"port_id": 0, "mark_id": 3, "queue": 3}, stats=True) + self.dut.send_expect("flow flush 0", "testpmd> ") + + rule_li = self.create_fdir_rule(rules, check_stats=True) + self.check_fdir_rule(port_id=0, rule_list=rule_li) + self.dut.send_expect("flow destroy 0 rule 1", "testpmd> ") + out_0 = self.send_pkts_getouput(pkts=pkts[0]) + rfc.check_iavf_fdir_mark(out_0, pkt_num=1, check_param={"port_id": 0, "mark_id": 1, "queue": 1}, stats=True) + out_1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out_1, pkt_num=1, check_param={"port_id": 0, "mark_id": 2, "queue": 2}, stats=False) + out_2 = self.send_pkts_getouput(pkts=pkts[2]) + rfc.check_iavf_fdir_mark(out_2, pkt_num=1, check_param={"port_id": 0, "mark_id": 3, "queue": 3}, stats=True) + self.dut.send_expect("flow flush 0", "testpmd> ") + + rule_li = self.create_fdir_rule(rules, check_stats=True) + self.check_fdir_rule(port_id=0, rule_list=rule_li) + self.dut.send_expect("flow destroy 0 rule 2", "testpmd> ") + out_0 = self.send_pkts_getouput(pkts=pkts[0]) + rfc.check_iavf_fdir_mark(out_0, pkt_num=1, check_param={"port_id": 0, "mark_id": 1, "queue": 1}, stats=True) + out_1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out_1, pkt_num=1, check_param={"port_id": 0, "mark_id": 2, "queue": 2}, stats=True) + out_2 = self.send_pkts_getouput(pkts=pkts[2]) + rfc.check_iavf_fdir_mark(out_2, pkt_num=1, check_param={"port_id": 0, "mark_id": 3, "queue": 3}, stats=False) + self.dut.send_expect("flow flush 0", "testpmd> ") + + out_0 = self.send_pkts_getouput(pkts=pkts[0]) + rfc.check_iavf_fdir_mark(out_0, pkt_num=1, check_param={"port_id": 0, "mark_id": 1, "queue": 1}, stats=False) + out_1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out_1, pkt_num=1, check_param={"port_id": 0, "mark_id": 2, "queue": 2}, stats=False) + out_2 = self.send_pkts_getouput(pkts=pkts[2]) + rfc.check_iavf_fdir_mark(out_2, pkt_num=1, check_param={"port_id": 0, "mark_id": 3, "queue": 3}, stats=False) + + def test_stress_vf_port_reset_add_new_rule(self): + """ + vf reset, the origin rule can't take effect, + then add a new rule which can take effect. + relaunch testpmd, create same rules, can take effect. + """ + rules = [ + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.0 dst is 192.1.0.0 tos is 4 / tcp src is 22 dst is 23 / end actions queue index 1 / mark / end", + "flow create 1 ingress pattern eth / ipv4 src is 192.168.0.0 dst is 192.1.0.0 tos is 4 / tcp src is 22 dst is 23 / end actions queue index 1 / mark / end"] + pkts = [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.0",dst="192.1.0.0", tos=4)/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:66")/IP(src="192.168.0.0",dst="192.1.0.0", tos=4)/TCP(sport=22,dport=23)/Raw("x" * 80)'] + self.create_fdir_rule(rules, check_stats=True) + out0 = self.send_pkts_getouput(pkts=pkts[0]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 1}, stats=True) + out1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 1}, stats=True) + # reset vf + self.dut.send_expect("stop", "testpmd> ") + self.dut.send_expect("port stop 0", "testpmd> ") + self.dut.send_expect("port reset 0", "testpmd> ") + self.dut.send_expect("port start 0", "testpmd> ") + self.dut.send_expect("start", "testpmd> ") + # check the rule of port0 is still listed, but doesn't take effect. + self.check_fdir_rule(port_id=0, rule_list=['0']) + self.check_fdir_rule(port_id=1, rule_list=['0']) + out0 = self.send_pkts_getouput(pkts=pkts[0]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "passthru": 1}, stats=True) + out1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 1}, stats=True) + # create the rule again + self.create_fdir_rule(rules[0], check_stats=True) + out0 = self.send_pkts_getouput(pkts=pkts[0]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 1}, stats=True) + # relaunch testpmd, and create the rules, check matched packets. + self.dut.send_expect("quit", "# ") + self.launch_testpmd() + self.create_fdir_rule(rules, check_stats=True) + out0 = self.send_pkts_getouput(pkts=pkts[0]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 1}, stats=True) + out1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 1}, stats=True) + + def test_stress_vf_port_reset_delete_rule(self): + """ + vf reset, the origin rule can't take effect, + then delete the rule which can't take effect without core dump, + relaunch testpmd, create same rules, can take effect. + """ + rules = [ + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.0 dst is 192.1.0.0 tos is 4 / tcp src is 22 dst is 23 / end actions queue index 1 / mark / end", + "flow create 1 ingress pattern eth / ipv4 src is 192.168.0.0 dst is 192.1.0.0 tos is 4 / tcp src is 22 dst is 23 / end actions queue index 1 / mark / end"] + pkts = [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.0",dst="192.1.0.0", tos=4)/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:66")/IP(src="192.168.0.0",dst="192.1.0.0", tos=4)/TCP(sport=22,dport=23)/Raw("x" * 80)'] + rule_li = self.create_fdir_rule(rules, check_stats=True) + out0 = self.send_pkts_getouput(pkts=pkts[0]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 1}, stats=True) + out1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 1}, stats=True) + # reset vf + self.dut.send_expect("stop", "testpmd> ") + self.dut.send_expect("port stop 0", "testpmd> ") + self.dut.send_expect("port reset 0", "testpmd> ") + self.dut.send_expect("port start 0", "testpmd> ") + self.dut.send_expect("start", "testpmd> ") + # check the rule of port0 is still listed, but doesn't take effect. + self.check_fdir_rule(port_id=0, rule_list=['0']) + self.check_fdir_rule(port_id=1, rule_list=['0']) + out0 = self.send_pkts_getouput(pkts=pkts[0]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "passthru": 1}, stats=True) + out1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 1}, stats=True) + # delete the rules + self.dut.send_expect("flow destroy 0 rule 0", "Invalid flow destroy") + self.destroy_fdir_rule(rule_id='0', port_id=1) + out0 = self.send_pkts_getouput(pkts=pkts[0]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 1}, stats=False) + out1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 1}, stats=False) + # relaunch testpmd, and create the rules, check matched packets. + self.dut.send_expect("quit", "# ") + self.launch_testpmd() + self.create_fdir_rule(rules, check_stats=True) + out0 = self.send_pkts_getouput(pkts=pkts[0]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 1}, stats=True) + out1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 1}, stats=True) + + def test_stress_pf_reset_vf_add_new_rule(self): + """ + pf trigger vf reset, the origin rule can't take effect, + then add a new rule which can take effect. + relaunch testpmd, create same rules, can take effect. + """ + self.session_secondary = self.dut.new_session() + rules = [ + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.0 dst is 192.1.0.0 tos is 4 / tcp src is 22 dst is 23 / end actions queue index 1 / mark / end", + "flow create 1 ingress pattern eth / ipv4 src is 192.168.0.0 dst is 192.1.0.0 tos is 4 / tcp src is 22 dst is 23 / end actions queue index 1 / mark / end"] + new_rule = "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.0 dst is 192.1.0.1 tos is 4 / tcp src is 22 dst is 23 / end actions queue index 6 / mark id 1 / end" + pkts = [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.0",dst="192.1.0.0", tos=4)/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:66")/IP(src="192.168.0.0",dst="192.1.0.0", tos=4)/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:56")/IP(src="192.168.0.0",dst="192.1.0.0", tos=4)/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:56")/IP(src="192.168.0.0",dst="192.1.0.1", tos=4)/TCP(sport=22,dport=23)/Raw("x" * 80)'] + self.create_fdir_rule(rules, check_stats=True) + out0 = self.send_pkts_getouput(pkts=pkts[0]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 1}, stats=True) + out1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 1}, stats=True) + + self.session_secondary.send_expect("ip link set %s vf 0 mac 00:11:22:33:44:56" % self.pf0_intf, "# ") + out = self.dut.session.get_session_before(timeout=2) + self.verify("Port 0: reset event" in out, "failed to reset vf0") + self.dut.send_expect("stop", "testpmd> ") + self.dut.send_expect("port stop 0", "testpmd> ") + self.dut.send_expect("port reset 0", "testpmd> ") + self.dut.send_expect("port start 0", "testpmd> ") + self.dut.send_expect("start", "testpmd> ") + out0 = self.send_pkts_getouput(pkts=pkts[2]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "passthru": 1}, stats=True) + out1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 1}, stats=True) + + # create a new rule, the packet patch the rule can be redirected to queue 6 with mark ID 1. + self.create_fdir_rule(new_rule, check_stats=True) + out0 = self.send_pkts_getouput(pkts=pkts[3]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 1, "queue": 6}, stats=True) + # relaunch testpmd, and create the rules, check matched packets. + self.dut.send_expect("quit", "# ") + self.launch_testpmd() + self.create_fdir_rule(rules, check_stats=True) + out0 = self.send_pkts_getouput(pkts=pkts[2]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 1}, stats=True) + out1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 1}, stats=True) + self.dut.send_expect("quit", "# ") + self.session_secondary.send_expect("ip link set %s vf 0 mac 00:11:22:33:44:55" % self.pf0_intf, "# ") + self.dut.close_session(self.session_secondary) + + def test_stress_pf_reset_vf_delete_rule(self): + """ + pf trigger vf reset, the origin rule can't take effect, + then delete the rule which can't take effect without core dump, + relaunch testpmd, create same rules, can take effect. + """ + self.session_secondary = self.dut.new_session() + rules = [ + "flow create 0 ingress pattern eth / ipv4 src is 192.168.0.0 dst is 192.1.0.0 tos is 4 / tcp src is 22 dst is 23 / end actions queue index 1 / mark / end", + "flow create 1 ingress pattern eth / ipv4 src is 192.168.0.0 dst is 192.1.0.0 tos is 4 / tcp src is 22 dst is 23 / end actions queue index 1 / mark / end"] + pkts = [ + 'Ether(dst="00:11:22:33:44:55")/IP(src="192.168.0.0",dst="192.1.0.0", tos=4)/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:66")/IP(src="192.168.0.0",dst="192.1.0.0", tos=4)/TCP(sport=22,dport=23)/Raw("x" * 80)', + 'Ether(dst="00:11:22:33:44:56")/IP(src="192.168.0.0",dst="192.1.0.0", tos=4)/TCP(sport=22,dport=23)/Raw("x" * 80)'] + self.create_fdir_rule(rules, check_stats=True) + out0 = self.send_pkts_getouput(pkts=pkts[0]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 1}, stats=True) + out1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 1}, stats=True) + + self.session_secondary.send_expect("ip link set %s vf 0 mac 00:11:22:33:44:56" % self.pf0_intf, "# ") + out = self.dut.session.get_session_before(timeout=2) + self.verify("Port 0: reset event" in out, "failed to reset vf0") + self.dut.send_expect("stop", "testpmd> ") + self.dut.send_expect("port stop 0", "testpmd> ") + self.dut.send_expect("port reset 0", "testpmd> ") + self.dut.send_expect("port start 0", "testpmd> ") + self.dut.send_expect("start", "testpmd> ") + out0 = self.send_pkts_getouput(pkts=pkts[2]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "passthru": 1}, stats=True) + out1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 1}, stats=True) + # delete the rules + self.dut.send_expect("flow destroy 0 rule 0", "Invalid flow destroy") + self.destroy_fdir_rule(rule_id='0', port_id=1) + out0 = self.send_pkts_getouput(pkts=pkts[2]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 1}, stats=False) + out1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 1}, stats=False) + + # relaunch testpmd, and create the rules, check matched packets. + self.dut.send_expect("quit", "# ") + self.launch_testpmd() + self.create_fdir_rule(rules, check_stats=True) + out0 = self.send_pkts_getouput(pkts=pkts[2]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 0, "queue": 1}, stats=True) + out1 = self.send_pkts_getouput(pkts=pkts[1]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 1, "mark_id": 0, "queue": 1}, stats=True) + self.dut.send_expect("quit", "# ") + self.session_secondary.send_expect("ip link set %s vf 0 mac 00:11:22:33:44:55" % self.pf0_intf, "# ") + self.dut.close_session(self.session_secondary) + + def checksum_enablehw(self, port, hw): + """ + set checksum parameters + """ + self.dut.send_expect("set fwd csum", "testpmd>") + self.dut.send_expect("port stop all", "testpmd>") + self.dut.send_expect("csum set ip %s %d" % (hw, port), "testpmd>") + self.dut.send_expect("csum set udp %s %d" %(hw, port), "testpmd>") + self.dut.send_expect("port start all", "testpmd>") + self.dut.send_expect("start", "testpmd>") + + def get_chksum_values(self, packets_expected): + """ + Validate the checksum flags. + """ + checksum_pattern = re.compile("chksum.*=.*(0x[0-9a-z]+)") + + chksum = dict() + + self.tester.send_expect("scapy", ">>> ") + self.tester.send_expect("import sys", ">>> ") + self.tester.send_expect("sys.path.append('./dep')", ">>> ") + self.tester.send_expect("from pfcp import PFCP", ">>> ") + + for packet_type in list(packets_expected.keys()): + self.tester.send_expect("p = %s" % packets_expected[packet_type], ">>>") + out = self.tester.send_command("p.show2()", timeout=1) + chksums = checksum_pattern.findall(out) + chksum[packet_type] = chksums + + self.tester.send_expect("exit()", "#") + return chksum + + def checksum_validate(self, packets_sent, packets_expected): + """ + Validate the checksum. + """ + tx_interface = self.tester_iface0 + rx_interface = self.tester_iface0 + + sniff_src = "00:11:22:33:44:55" + result = dict() + pkt = Packet() + chksum = self.get_chksum_values(packets_expected) + self.inst = self.tester.tcpdump_sniff_packets(intf=rx_interface, count=len(packets_sent), + filters=[{'layer': 'ether', 'config': {'src': sniff_src}}]) + for packet_type in list(packets_sent.keys()): + pkt.append_pkt(packets_sent[packet_type]) + pkt.send_pkt(crb=self.tester, tx_port=tx_interface, count=1) + + p = self.tester.load_tcpdump_sniff_packets(self.inst) + nr_packets = len(p) + print(p) + packets_received = [p[i].sprintf("%IP.chksum%;%TCP.chksum%;%UDP.chksum%;%SCTP.chksum%") for i in range(nr_packets)] + print(len(packets_sent), len(packets_received)) + self.verify(len(packets_sent)*1 == len(packets_received), "Unexpected Packets Drop") + i = 0 + for packet_received in packets_received: + ip_checksum, tcp_checksum, udp_checksum, sctp_checksum = packet_received.split(';') + if udp_checksum != '??': + packet_type = 'UDP' + l4_checksum = udp_checksum + if i == 0 or i == 2: + packet_type = packet_type + '/PFCP_NODE' + else: + packet_type = packet_type + '/PFCP_SESSION' + + if ip_checksum != '??': + packet_type = 'IP/' + packet_type + if chksum[packet_type] != [ip_checksum, l4_checksum]: + result[packet_type] = packet_type + " checksum error" + else: + packet_type = 'IPv6/' + packet_type + if chksum[packet_type] != [l4_checksum]: + result[packet_type] = packet_type + " checksum error" + i = i + 1 + return (result, p) + + def set_vlan(self, vlan, port, strip, rx_tx="rx"): + """ + set rx_vlan and tx_vlan + """ + self.dut.send_expect("vlan set filter on %d" % port, "testpmd> ", 20) + self.dut.send_expect("vlan set strip %s %d" % (strip, port), "testpmd> ", 20) + self.dut.send_expect("rx_vlan add %d %d" % (vlan, port), "testpmd> ", 20) + self.dut.send_expect("set verbose 1", "testpmd> ", 20) + + if rx_tx == "tx": + self.dut.send_expect("port stop %d" % port, "testpmd> ", 20) + self.dut.send_expect("tx_vlan set %d %d" % (port, vlan), "testpmd> ", 20) + self.dut.send_expect("port start %d" % port, "testpmd> ", 20) + self.dut.send_expect("set fwd mac", "testpmd> ", 20) + + def get_tcpdump_package(self, pkts): + """ + return vlan id of tcpdump packets + """ + vlans = [] + for i in range(len(pkts)): + vlan = pkts.strip_element_vlan("vlan", p_index=i) + print("vlan is:", vlan) + vlans.append(vlan) + return vlans + + def test_pfcp_vlan_strip_on_hw_checksum(self): + """ + Set PFCP FDIR rules + Enable HW checksum offload. + Enable vlan filter and receipt of VLAN packets with VLAN Tag Identifier 1 on port 0. + Disable vlan strip. + Send packet with incorrect checksum, + can rx it and report the checksum error, + verify forwarded packets have correct checksum. + """ + rules = ["flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 0 / end actions queue index 1 / mark id 1 / end", + "flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 1 / end actions queue index 2 / mark id 2 / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 0 / end actions queue index 3 / mark id 3 / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 1 / end actions queue index 4 / mark id 4 / end"] + + self.dut.send_expect("quit", "# ") + self.pmd_output.start_testpmd(cores="1S/4C/1T", + param="--rxq=16 --txq=16 --enable-rx-cksum --port-topology=loop", + eal_param="-w %s" % self.sriov_vfs_pf0[0].pci, + socket=self.ports_socket) + vlan = 51 + mac = "00:11:22:33:44:55" + sndIP = '10.0.0.1' + sndIPv6 = '::1' + pkts_sent = {'IP/UDP/PFCP_NODE': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=51)/IP(src="%s", chksum=0xf)/UDP(sport=22, dport=8805, chksum=0xf)/PFCP(Sfield=0)/("X"*46)' % (mac, sndIP), + 'IP/UDP/PFCP_SESSION': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=51)/IP(src="%s", chksum=0xf)/UDP(sport=22, dport=8805, chksum=0xf)/PFCP(Sfield=1)/("X"*46)' % (mac, sndIP), + 'IPv6/UDP/PFCP_NODE': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=51)/IPv6(src="%s")/UDP(sport=22, dport=8805, chksum=0xf)/PFCP(Sfield=0)/("X"*46)' % (mac, sndIPv6), + 'IPv6/UDP/PFCP_SESSION': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=51)/IPv6(src="%s")/UDP(sport=22, dport=8805, chksum=0xf)/PFCP(Sfield=1)/("X"*46)' % (mac, sndIPv6)} + + expIP = sndIP + expIPv6 = sndIPv6 + pkts_ref = {'IP/UDP/PFCP_NODE': 'Ether(src="%s", dst="52:00:00:00:00:00")/Dot1Q(vlan=51)/IP(src="%s")/UDP(sport=22, dport=8805)/PFCP(Sfield=0)/("X"*46)' % (mac, expIP), + 'IP/UDP/PFCP_SESSION': 'Ether(src="%s", dst="52:00:00:00:00:00")/Dot1Q(vlan=51)/IP(src="%s")/UDP(sport=22, dport=8805)/PFCP(Sfield=1)/("X"*46)' % (mac, expIP), + 'IPv6/UDP/PFCP_NODE': 'Ether(src="%s", dst="52:00:00:00:00:00")/Dot1Q(vlan=51)/IPv6(src="%s")/UDP(sport=22, dport=8805)/PFCP(Sfield=0)/("X"*46)' % (mac, expIPv6), + 'IPv6/UDP/PFCP_SESSION': 'Ether(src="%s", dst="52:00:00:00:00:00")/Dot1Q(vlan=51)/IPv6(src="%s")/UDP(sport=22, dport=8805)/PFCP(Sfield=1)/("X"*46)' % (mac, expIPv6)} + + self.checksum_enablehw(port=0, hw="hw") + + self.set_vlan(vlan=vlan, port=0, strip="on") + out_info = self.dut.send_expect("show port info 0", "testpmd> ", 20) + self.verify("strip on" in out_info, "Wrong strip:" + out_info) + + # send packets and check the checksum value + result = self.checksum_validate(pkts_sent, pkts_ref) + # validate vlan in the tcpdumped packets + out_dump = self.get_tcpdump_package(result[1]) + self.verify(len(out_dump), "Forwarded vlan packet not received!!!") + self.verify(vlan not in out_dump, "Wrong vlan:" + str(out_dump)) + + # Validate checksum on the receive packet + out_testpmd = self.dut.send_expect("stop", "testpmd> ") + bad_ipcsum = self.pmd_output.get_pmd_value("Bad-ipcsum:", out_testpmd) + bad_l4csum = self.pmd_output.get_pmd_value("Bad-l4csum:", out_testpmd) + self.verify(bad_ipcsum == 2, "Bad-ipcsum check error") + self.verify(bad_l4csum == 4, "Bad-l4csum check error") + self.dut.send_expect("start", "testpmd> ") + + # check fdir rule take effect + self.create_fdir_rule(rules, check_stats=True) + out0 = self.send_pkts_getouput(pkts=pkts_sent["IP/UDP/PFCP_NODE"]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 1, "queue": 1}, stats=True) + out1 = self.send_pkts_getouput(pkts=pkts_sent["IP/UDP/PFCP_SESSION"]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 0, "mark_id": 2, "queue": 2}, stats=True) + out2 = self.send_pkts_getouput(pkts=pkts_sent["IPv6/UDP/PFCP_NODE"]) + rfc.check_iavf_fdir_mark(out2, pkt_num=1, check_param={"port_id": 0, "mark_id": 3, "queue": 3}, stats=True) + out3 = self.send_pkts_getouput(pkts=pkts_sent["IPv6/UDP/PFCP_SESSION"]) + rfc.check_iavf_fdir_mark(out3, pkt_num=1, check_param={"port_id": 0, "mark_id": 4, "queue": 4}, stats=True) + + # destroy the rules and check there is no rule listed. + self.dut.send_expect("flow flush 0", "testpmd> ", 20) + self.check_fdir_rule(port_id=0, stats=False) + + # check no rules existing + out0 = self.send_pkts_getouput(pkts=pkts_sent["IP/UDP/PFCP_NODE"]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 1, "queue": 1}, stats=False) + out1 = self.send_pkts_getouput(pkts=pkts_sent["IP/UDP/PFCP_SESSION"]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 0, "mark_id": 2, "queue": 2}, stats=False) + out2 = self.send_pkts_getouput(pkts=pkts_sent["IPv6/UDP/PFCP_NODE"]) + rfc.check_iavf_fdir_mark(out2, pkt_num=1, check_param={"port_id": 0, "mark_id": 3, "queue": 3}, stats=False) + out3 = self.send_pkts_getouput(pkts=pkts_sent["IPv6/UDP/PFCP_SESSION"]) + rfc.check_iavf_fdir_mark(out3, pkt_num=1, check_param={"port_id": 0, "mark_id": 4, "queue": 4}, stats=False) + + # send packets and check the checksum value + result = self.checksum_validate(pkts_sent, pkts_ref) + # validate vlan in the tcpdumped packets + out_dump = self.get_tcpdump_package(result[1]) + self.verify(len(out_dump), "Forwarded vlan packet not received!!!") + self.verify(vlan not in out_dump, "Wrong vlan:" + str(out_dump)) + + # Validate checksum on the receive packet + out_testpmd = self.dut.send_expect("stop", "testpmd> ") + bad_ipcsum = self.pmd_output.get_pmd_value("Bad-ipcsum:", out_testpmd) + bad_l4csum = self.pmd_output.get_pmd_value("Bad-l4csum:", out_testpmd) + self.verify(bad_ipcsum == 2, "Bad-ipcsum check error") + self.verify(bad_l4csum == 4, "Bad-l4csum check error") + + def test_pfcp_vlan_strip_off_sw_checksum(self): + """ + Set PFCP FDIR rules + Enable SW checksum offload. + Enable vlan filter and receipt of VLAN packets with VLAN Tag Identifier 1 on port 0. + Disable vlan strip. + Send packet with incorrect checksum, + can rx it and report the checksum error, + verify forwarded packets have correct checksum. + """ + rules = ["flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 0 / end actions queue index 1 / mark id 1 / end", + "flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 1 / end actions queue index 2 / mark id 2 / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 0 / end actions queue index 3 / mark id 3 / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 1 / end actions queue index 4 / mark id 4 / end"] + + self.dut.send_expect("quit", "# ") + self.pmd_output.start_testpmd(cores="1S/4C/1T", + param="--rxq=16 --txq=16 --enable-rx-cksum --port-topology=loop", + eal_param="-w %s" % self.sriov_vfs_pf0[0].pci, + socket=self.ports_socket) + vlan = 51 + mac = "00:11:22:33:44:55" + sndIP = '10.0.0.1' + sndIPv6 = '::1' + pkts_sent = {'IP/UDP/PFCP_NODE': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=51)/IP(src="%s", chksum=0xf)/UDP(sport=22, dport=8805, chksum=0xf)/PFCP(Sfield=0)/("X"*46)' % (mac, sndIP), + 'IP/UDP/PFCP_SESSION': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=51)/IP(src="%s", chksum=0xf)/UDP(sport=22, dport=8805, chksum=0xf)/PFCP(Sfield=1)/("X"*46)' % (mac, sndIP), + 'IPv6/UDP/PFCP_NODE': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=51)/IPv6(src="%s")/UDP(sport=22, dport=8805, chksum=0xf)/PFCP(Sfield=0)/("X"*46)' % (mac, sndIPv6), + 'IPv6/UDP/PFCP_SESSION': 'Ether(dst="%s", src="52:00:00:00:00:00")/Dot1Q(vlan=51)/IPv6(src="%s")/UDP(sport=22, dport=8805, chksum=0xf)/PFCP(Sfield=1)/("X"*46)' % (mac, sndIPv6)} + + expIP = sndIP + expIPv6 = sndIPv6 + pkts_ref = {'IP/UDP/PFCP_NODE': 'Ether(src="%s", dst="52:00:00:00:00:00")/Dot1Q(vlan=51)/IP(src="%s")/UDP(sport=22, dport=8805)/PFCP(Sfield=0)/("X"*46)' % (mac, expIP), + 'IP/UDP/PFCP_SESSION': 'Ether(src="%s", dst="52:00:00:00:00:00")/Dot1Q(vlan=51)/IP(src="%s")/UDP(sport=22, dport=8805)/PFCP(Sfield=1)/("X"*46)' % (mac, expIP), + 'IPv6/UDP/PFCP_NODE': 'Ether(src="%s", dst="52:00:00:00:00:00")/Dot1Q(vlan=51)/IPv6(src="%s")/UDP(sport=22, dport=8805)/PFCP(Sfield=0)/("X"*46)' % (mac, expIPv6), + 'IPv6/UDP/PFCP_SESSION': 'Ether(src="%s", dst="52:00:00:00:00:00")/Dot1Q(vlan=51)/IPv6(src="%s")/UDP(sport=22, dport=8805)/PFCP(Sfield=1)/("X"*46)' % (mac, expIPv6)} + + self.checksum_enablehw(port=0, hw="sw") + + self.set_vlan(vlan=vlan, port=0, strip="off") + out_info = self.dut.send_expect("show port info 0", "testpmd> ", 20) + self.verify("strip off" in out_info, "Wrong strip:" + out_info) + + result = self.checksum_validate(pkts_sent, pkts_ref) + + out_dump = self.get_tcpdump_package(result[1]) + self.verify(len(out_dump), "Forwarded vlan packet not received!!!") + self.verify(vlan in out_dump, "Wrong vlan:" + str(out_dump)) + + # Validate checksum on the receive packet + out_testpmd = self.dut.send_expect("stop", "testpmd> ") + bad_ipcsum = self.pmd_output.get_pmd_value("Bad-ipcsum:", out_testpmd) + bad_l4csum = self.pmd_output.get_pmd_value("Bad-l4csum:", out_testpmd) + self.verify(bad_ipcsum == 2, "Bad-ipcsum check error") + self.verify(bad_l4csum == 4, "Bad-l4csum check error") + self.dut.send_expect("start", "testpmd> ") + + # check fdir rule take effect + self.create_fdir_rule(rules, check_stats=True) + out0 = self.send_pkts_getouput(pkts=pkts_sent["IP/UDP/PFCP_NODE"]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 1, "queue": 1}, stats=True) + out1 = self.send_pkts_getouput(pkts=pkts_sent["IP/UDP/PFCP_SESSION"]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 0, "mark_id": 2, "queue": 2}, stats=True) + out2 = self.send_pkts_getouput(pkts=pkts_sent["IPv6/UDP/PFCP_NODE"]) + rfc.check_iavf_fdir_mark(out2, pkt_num=1, check_param={"port_id": 0, "mark_id": 3, "queue": 3}, stats=True) + out3 = self.send_pkts_getouput(pkts=pkts_sent["IPv6/UDP/PFCP_SESSION"]) + rfc.check_iavf_fdir_mark(out3, pkt_num=1, check_param={"port_id": 0, "mark_id": 4, "queue": 4}, stats=True) + + # destroy the rules and check there is no rule listed. + self.dut.send_expect("flow flush 0", "testpmd> ", 20) + self.check_fdir_rule(port_id=0, stats=False) + + # check no rules existing + out0 = self.send_pkts_getouput(pkts=pkts_sent["IP/UDP/PFCP_NODE"]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 1, "queue": 1}, stats=False) + out1 = self.send_pkts_getouput(pkts=pkts_sent["IP/UDP/PFCP_SESSION"]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 0, "mark_id": 2, "queue": 2}, stats=False) + out2 = self.send_pkts_getouput(pkts=pkts_sent["IPv6/UDP/PFCP_NODE"]) + rfc.check_iavf_fdir_mark(out2, pkt_num=1, check_param={"port_id": 0, "mark_id": 3, "queue": 3}, stats=False) + out3 = self.send_pkts_getouput(pkts=pkts_sent["IPv6/UDP/PFCP_SESSION"]) + rfc.check_iavf_fdir_mark(out3, pkt_num=1, check_param={"port_id": 0, "mark_id": 4, "queue": 4}, stats=False) + + result = self.checksum_validate(pkts_sent, pkts_ref) + + out_dump = self.get_tcpdump_package(result[1]) + self.verify(len(out_dump), "Forwarded vlan packet not received!!!") + self.verify(vlan in out_dump, "Wrong vlan:" + str(out_dump)) + + # Validate checksum on the receive packet + out_testpmd = self.dut.send_expect("stop", "testpmd> ") + bad_ipcsum = self.pmd_output.get_pmd_value("Bad-ipcsum:", out_testpmd) + bad_l4csum = self.pmd_output.get_pmd_value("Bad-l4csum:", out_testpmd) + self.verify(bad_ipcsum == 2, "Bad-ipcsum check error") + self.verify(bad_l4csum == 4, "Bad-l4csum check error") + + def test_pfcp_vlan_insert_on(self): + """ + Set PFCP FDIR rules + Enable vlan filter and insert VLAN Tag Identifier 1 to vlan packet sent from port 0 + """ + rules = ["flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 0 / end actions queue index 1 / mark id 1 / end", + "flow create 0 ingress pattern eth / ipv4 / udp / pfcp s_field is 1 / end actions queue index 2 / mark id 2 / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 0 / end actions queue index 3 / mark id 3 / end", + "flow create 0 ingress pattern eth / ipv6 / udp / pfcp s_field is 1 / end actions queue index 4 / mark id 4 / end"] + + self.dut.send_expect("quit", "# ") + self.pmd_output.start_testpmd(cores="1S/4C/1T", + param="--rxq=16 --txq=16 --enable-rx-cksum --port-topology=loop", + eal_param="-w %s" % self.sriov_vfs_pf0[0].pci, + socket=self.ports_socket) + vlan = 51 + mac = "00:11:22:33:44:55" + sndIP = '10.0.0.1' + sndIPv6 = '::1' + pkt = Packet() + pkts_sent = {'IP/UDP/PFCP_NODE': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="%s")/UDP(sport=22, dport=8805)/PFCP(Sfield=0)/("X"*46)' % (mac, sndIP), + 'IP/UDP/PFCP_SESSION': 'Ether(dst="%s", src="52:00:00:00:00:00")/IP(src="%s")/UDP(sport=22, dport=8805)/PFCP(Sfield=1)/("X"*46)' % (mac, sndIP), + 'IPv6/UDP/PFCP_NODE': 'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="%s")/UDP(sport=22, dport=8805)/PFCP(Sfield=0)/("X"*46)' % (mac, sndIPv6), + 'IPv6/UDP/PFCP_SESSION': 'Ether(dst="%s", src="52:00:00:00:00:00")/IPv6(src="%s")/UDP(sport=22, dport=8805)/PFCP(Sfield=1)/("X"*46)' % (mac, sndIPv6)} + + self.set_vlan(vlan=vlan, port=0, strip="off", rx_tx="tx") + self.dut.send_expect("start", "testpmd> ") + + tx_interface = self.tester_iface0 + rx_interface = self.tester_iface0 + + dmac = "00:11:22:33:44:55" + smac = self.pf1_mac + inst = self.tester.tcpdump_sniff_packets(rx_interface) + + for packet_type in list(pkts_sent.keys()): + pkt.append_pkt(pkts_sent[packet_type]) + pkt.send_pkt(crb=self.tester, tx_port=tx_interface, count=1) + + p = self.tester.load_tcpdump_sniff_packets(inst) + + out = self.get_tcpdump_package(p) + self.verify(vlan in out, "Vlan not found:" + str(out)) + self.dut.send_expect("stop", "testpmd> ") + self.dut.send_expect("start", "testpmd> ") + + # check fdir rule take effect + self.create_fdir_rule(rules, check_stats=True) + out0 = self.send_pkts_getouput(pkts=pkts_sent["IP/UDP/PFCP_NODE"]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 1, "queue": 1}, stats=True) + out1 = self.send_pkts_getouput(pkts=pkts_sent["IP/UDP/PFCP_SESSION"]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 0, "mark_id": 2, "queue": 2}, stats=True) + out2 = self.send_pkts_getouput(pkts=pkts_sent["IPv6/UDP/PFCP_NODE"]) + rfc.check_iavf_fdir_mark(out2, pkt_num=1, check_param={"port_id": 0, "mark_id": 3, "queue": 3}, stats=True) + out3 = self.send_pkts_getouput(pkts=pkts_sent["IPv6/UDP/PFCP_SESSION"]) + rfc.check_iavf_fdir_mark(out3, pkt_num=1, check_param={"port_id": 0, "mark_id": 4, "queue": 4}, stats=True) + + # destroy the rules and check there is no rule listed. + self.dut.send_expect("flow flush 0", "testpmd> ", 20) + self.check_fdir_rule(port_id=0, stats=False) + + # check no rules existing + out0 = self.send_pkts_getouput(pkts=pkts_sent["IP/UDP/PFCP_NODE"]) + rfc.check_iavf_fdir_mark(out0, pkt_num=1, check_param={"port_id": 0, "mark_id": 1, "queue": 1}, stats=False) + out1 = self.send_pkts_getouput(pkts=pkts_sent["IP/UDP/PFCP_SESSION"]) + rfc.check_iavf_fdir_mark(out1, pkt_num=1, check_param={"port_id": 0, "mark_id": 2, "queue": 2}, stats=False) + out2 = self.send_pkts_getouput(pkts=pkts_sent["IPv6/UDP/PFCP_NODE"]) + rfc.check_iavf_fdir_mark(out2, pkt_num=1, check_param={"port_id": 0, "mark_id": 3, "queue": 3}, stats=False) + out3 = self.send_pkts_getouput(pkts=pkts_sent["IPv6/UDP/PFCP_SESSION"]) + rfc.check_iavf_fdir_mark(out3, pkt_num=1, check_param={"port_id": 0, "mark_id": 4, "queue": 4}, stats=False) + + self.dut.send_expect("stop", "testpmd> ") + self.dut.send_expect("port stop all", "testpmd> ") + self.dut.send_expect("tx_vlan reset 0", "testpmd> ") + self.dut.send_expect("port start all", "testpmd> ") + self.dut.send_expect("stop", "testpmd> ", 30) + + def tear_down(self): + # destroy all flow rule on port 0 + self.dut.kill_all() + + def tear_down_all(self): + self.destroy_env() + self.dut.kill_all() diff --git a/tests/rte_flow_common.py b/tests/rte_flow_common.py index be0e434a..dee47c6a 100644 --- a/tests/rte_flow_common.py +++ b/tests/rte_flow_common.py @@ -37,7 +37,7 @@ from utils import GREEN, RED # switch filter common functions def get_suite_config(test_case): """ - get the suite config from conf/cvl_dcf_switch_filter.cfg. + get the suite config from conf/suite.cfg. """ suite_config = {} if "ice_driver_file_location" in test_case.get_suite_cfg(): @@ -46,6 +46,12 @@ def get_suite_config(test_case): if "os_default_package_file_location" in test_case.get_suite_cfg(): os_default_package_file_location = test_case.get_suite_cfg()["os_default_package_file_location"] suite_config["os_default_package_file_location"] = os_default_package_file_location + if "comms_package_file_location" in test_case.get_suite_cfg(): + comms_package_file_location = test_case.get_suite_cfg()["comms_package_file_location"] + suite_config["comms_package_file_location"] = comms_package_file_location + if "package_file_location" in test_case.get_suite_cfg(): + package_file_location = test_case.get_suite_cfg()["package_file_location"] + suite_config["package_file_location"] = package_file_location return suite_config def get_rx_packet_number(out,match_string): @@ -388,6 +394,94 @@ def check_mark(out, pkt_num, check_param, stats=True): check_drop(out[1], pkt_num, check_param, stats) verify(not res, "should has no mark_id in %s" % res) +# IAVF fdir common functions +def check_iavf_fdir_queue(out, pkt_num, check_param, stats=True): + port_id = check_param["port_id"] if check_param.get("port_id") is not None else 0 + queue = check_param["queue"] + p = re.compile( + r"Forward Stats for RX Port=\s?%s/Queue=(\s?\d+)\s.*\n.*RX-packets:(\s?\d+)\s+TX-packets" % port_id) + res = p.findall(out) + if res: + res_queue = [int(i[0]) for i in res] + pkt_li = [int(i[1]) for i in res] + res_num = sum(pkt_li) + verify(res_num == pkt_num, "fail: got wrong number of packets, expect pakcet number %s, got %s." % (pkt_num, res_num)) + if stats: + if isinstance(queue, int): + verify(all(q == queue for q in res_queue), "fail: queue id not matched, expect queue %s, got %s" % (queue, res_queue)) + print((GREEN("pass: queue id %s matched" % res_queue))) + elif isinstance(queue, list): + verify(all(q in queue for q in res_queue), "fail: queue id not matched, expect queue %s, got %s" % (queue, res_queue)) + print((GREEN("pass: queue id %s matched" % res_queue))) + else: + raise Exception("wrong queue value, expect int or list") + else: + if isinstance(queue, int): + verify(not any(q == queue for q in res_queue), "fail: queue id should not matched, expect queue %s, got %s" % (queue, res_queue)) + print((GREEN("pass: queue id %s not matched" % res_queue))) + elif isinstance(queue, list): + verify_iavf_fdir_directed_by_rss(out, rxq=16, stats=True) + print((GREEN("pass: queue id %s not matched" % res_queue))) + else: + raise Exception("wrong action value, expect queue_index or queue_group") + else: + raise Exception("got wrong output, not match pattern %s" % p.pattern) + +def verify_iavf_fdir_directed_by_rss(out, rxq=16, stats=True): + p = re.compile("RSS hash=(0x\w+) - RSS queue=(0x\w+)") + pkt_info = p.findall(out) + if stats: + for i in pkt_info: + verify((int(i[0],16) % rxq == int(i[1],16)), "some packets are not directed by RSS") + print(GREEN("pass: queue id %s is redirected by RSS hash value %s" % (i[1], i[0]))) + else: + for i in pkt_info: + verify((int(i[0],16) % rxq != int(i[1],16)), "some packets are not directed by RSS") + +def check_iavf_fdir_passthru(out, pkt_num, check_param, stats=True): + # check the actual queue is distributed by RSS + port_id = check_param["port_id"] if check_param.get("port_id") is not None else 0 + p = re.compile('port\s*%s/queue\s?[0-9]+' % port_id) + pkt_li = p.findall(out) + verify(pkt_num == len(pkt_li), "fail: got wrong number of packets, expect pakcet number %s, got %s." % (pkt_num, len(pkt_li))) + p = re.compile('RSS\shash=(\w+)\s-\sRSS\squeue=(\w+)') + pkt_hash = p.findall(out) + verify(pkt_num == len(pkt_hash), "fail: got wrong number of passthru packets, expect passthru packet number %s, got %s." % (pkt_num, len(pkt_hash))) + verify_iavf_fdir_directed_by_rss(out, rxq=16, stats=True) + +def check_iavf_fdir_mark(out, pkt_num, check_param, stats=True): + mark_scanner = "FDIR matched ID=(0x\w+)" + res = re.findall(mark_scanner, out) + print(out) + if stats: + if check_param.get("drop") is not None: + check_drop(out, pkt_num, check_param, stats) + verify(not res, "should has no mark_id in %s" % res) + elif check_param.get("mark_id") is not None: + mark_list = [i for i in res] + print("mark list is: ", mark_list) + verify(len(res) == pkt_num, "get wrong number of packet with mark_id") + verify(all([int(i, 16) == check_param["mark_id"] for i in res]), + "failed: some packet mark id of %s not match" % mark_list) + if check_param.get("queue") is not None: + check_iavf_fdir_queue(out, pkt_num, check_param, stats) + elif check_param.get("passthru") is not None: + check_iavf_fdir_passthru(out, pkt_num, check_param, stats) + else: + if check_param.get("queue") is not None: + check_iavf_fdir_queue(out, pkt_num, check_param, stats) + elif check_param.get("passthru") is not None: + check_iavf_fdir_passthru(out, pkt_num, check_param, stats) + verify(not res, "should has no mark_id in %s" % res) + else: + if check_param.get("queue") is not None: + check_iavf_fdir_queue(out, pkt_num, check_param, stats) + elif check_param.get("drop") is not None: + check_drop(out, pkt_num, check_param, stats) + elif check_param.get("passthru") is not None: + check_iavf_fdir_passthru(out, pkt_num, check_param, stats) + verify(not res, "should has no mark_id in %s" % res) + # rss common functions def check_packets_of_each_queue(out): """ -- 2.17.1