From patchwork Fri Sep 30 06:36:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Yang X-Patchwork-Id: 117174 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id E00AEA034C; Fri, 30 Sep 2022 08:47:48 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7C1DB40FAE; Fri, 30 Sep 2022 08:47:48 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mails.dpdk.org (Postfix) with ESMTP id 6703B40E5A for ; Fri, 30 Sep 2022 08:47:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1664520466; x=1696056466; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=u1U8V8kb6Uj96EhNgDMP4HNmjs7YF/b1srekPTIV+fk=; b=K/gQPh8jWCJ/jCXQO6/SiCMPh3KehsBwnxlBSDn3Jpa9sY0pZr4UQ8oZ S3H+b/+TeL/fEEUX+1LTJnTAROspzuviOkbz6PN+XS84F30HlcjTXe1cb E3s9G6IySYYFiLOcTXVNLmrHOqXqdhSlsPIc5CXLEeb1A5CLLa20oLOeV HJ4MN4kvxJIGtNfkPWVy/e8ZenH5N0eFY8NOBtgB5HEYxTl7pFTpn0Jde 88XwKlLhtEFLv0fro4ZzgqUPI9zql1HqKHvSaFiYDaF+F928Lg+NLO7m4 1cYSeAi9YjJmAHJaJ9NfMMkQlObcb9iYvT3KvmkZrHWyqbCfp12k2KxNw g==; X-IronPort-AV: E=McAfee;i="6500,9779,10485"; a="303606868" X-IronPort-AV: E=Sophos;i="5.93,357,1654585200"; d="scan'208";a="303606868" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Sep 2022 23:47:45 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10485"; a="748132705" X-IronPort-AV: E=Sophos;i="5.93,357,1654585200"; d="scan'208";a="748132705" Received: from intel-cd-odc-steve.cd.intel.com ([10.240.178.133]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Sep 2022 23:47:43 -0700 From: Steve Yang To: dev@dpdk.org Cc: qiming.yang@intel.com, Steve Yang Subject: [RFC v1] net/i40e: support customerized VXLAN FDIR and inner RSS Date: Fri, 30 Sep 2022 06:36:57 +0000 Message-Id: <20220930063657.1118777-1-stevex.yang@intel.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Usage: flow create ingress pattern / end actions / end Added following pattern_str: eth / ipv4 / udp / vxlan / ipv4 / udp eth / ipv4 / udp / vxlan / ipv4 / tcp eth / ipv4 / udp / vxlan / ipv4 / icmp eth / ipv4 / udp / vxlan / ipv6 / udp eth / ipv4 / udp / vxlan / ipv6 / tcp eth / ipv4 / udp / vxlan / ipv6 / icmp eth / ipv4 / icmp eth / ipv6 / udp / vxlan / ipv4 / udp eth / ipv6 / udp / vxlan / ipv4 / tcp eth / ipv6 / udp / vxlan / ipv4 / icmp eth / ipv6 / udp / vxlan / ipv6 / udp eth / ipv6 / udp / vxlan / ipv6 / tcp eth / ipv6 / udp / vxlan / ipv6 / icmp eth / ipv6 / icmp action_str: queue index input set: ipv4: src, dst, tos, ttl udp: src, dst For example: flow create 0 ingress pattern eth / ipv4 src is 1.0.0.4 dst is 19.9.0.4 tos is 2 ttl is 40 / udp src is 250 dst is 250 / vxlan / ipv4 / udp / end actions queue index 4 / end Baseline: dpdk-stable 20.11 / 73655c6414 (tag: v20.11.6, origin/20.11, 20.11) version: 20.11.6 Dependency: - need load vxlan-ip.pkgo before configuring flow filter rule; - need add vxlan-gpe port via command: 'port config udp_tunnel_port add vxlan-gpe ' e.g.: port config 0 udp_tunnel_port add vxlan-gpe 250 - enable rss via command 'port config all rss all' Signed-off-by: Steve Yang --- drivers/net/i40e/base/i40e_type.h | 15 ++ drivers/net/i40e/i40e_ethdev.c | 168 +++++++++++- drivers/net/i40e/i40e_fdir.c | 431 ++++++++++++++++++++---------- drivers/net/i40e/i40e_flow.c | 281 ++++++++++++++++++- drivers/net/i40e/i40e_rxtx.c | 28 ++ lib/librte_ethdev/rte_ethdev.h | 18 +- 6 files changed, 799 insertions(+), 142 deletions(-) diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h index 4674715ed7..66acb3cd7f 100644 --- a/drivers/net/i40e/base/i40e_type.h +++ b/drivers/net/i40e/base/i40e_type.h @@ -1290,6 +1290,21 @@ struct i40e_filter_program_desc { /* Packet Classifier Types for filters */ enum i40e_filter_pctype { + I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_UDP = 1, + I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_TCP = 2, + I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_ICMP = 3, + I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_UDP = 4, + I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_TCP = 5, + I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_ICMP = 6, + I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_UDP = 7, + I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_TCP = 8, + I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_ICMP = 9, + I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_UDP = 10, + I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_TCP = 11, + I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_ICMP = 12, + I40E_FILTER_PCTYPE_NONF_IPV4_ICMP = 13, + I40E_FILTER_PCTYPE_NONF_IPV6_ICMP = 14, + /* Note: Values 0-28 are reserved for future use. * Value 29, 30, 32 are not supported on XL710 and X710. */ diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index c2d52e4acc..0793750dac 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -7621,6 +7621,10 @@ i40e_config_hena(const struct i40e_adapter *adapter, uint64_t flags) hena |= adapter->pctypes_tbl[i]; } + /* Force enable vxlan relative hash flags */ + for (i = RTE_ETH_FLOW_IPV4_VXLAN_IPV4_UDP; i < RTE_ETH_FLOW_MAX; i++) + hena |= adapter->pctypes_tbl[i]; + return hena; } @@ -7861,7 +7865,7 @@ i40e_tunnel_filter_convert( tunnel_filter->input.inner_vlan = cld_filter->element.inner_vlan; if ((rte_le_to_cpu_16(cld_filter->element.flags) & I40E_AQC_ADD_CLOUD_FLAGS_IPV6) == - I40E_AQC_ADD_CLOUD_FLAGS_IPV6) + I40E_AQC_ADD_CLOUD_FLAGS_IPV6) tunnel_filter->input.ip_type = I40E_TUNNEL_IPTYPE_IPV6; else tunnel_filter->input.ip_type = I40E_TUNNEL_IPTYPE_IPV4; @@ -9017,6 +9021,60 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype, uint64_t valid; static const uint64_t valid_hash_inset_table[] = { + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_UDP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_TCP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_ICMP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_UDP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_TCP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_ICMP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_UDP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_TCP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_ICMP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_UDP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_TCP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_ICMP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV4_ICMP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV6_ICMP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST, [I40E_FILTER_PCTYPE_FRAG_IPV4] = I40E_INSET_DMAC | I40E_INSET_SMAC | I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | @@ -9168,6 +9226,60 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype, * union rte_eth_fdir_flow. */ static const uint64_t valid_fdir_inset_table[] = { + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_UDP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_TCP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_ICMP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_UDP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_TCP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_ICMP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_UDP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_TCP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_ICMP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_UDP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_TCP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_ICMP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV4_ICMP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV6_ICMP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST, [I40E_FILTER_PCTYPE_FRAG_IPV4] = I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | @@ -9289,6 +9401,60 @@ uint64_t i40e_get_default_input_set(uint16_t pctype) { static const uint64_t default_inset_table[] = { + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_UDP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_TCP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_ICMP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_UDP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_TCP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_ICMP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_UDP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_TCP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_ICMP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_UDP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_TCP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_ICMP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | + I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, + [I40E_FILTER_PCTYPE_NONF_IPV4_ICMP] = + I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | + I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | + I40E_INSET_IPV4_TTL, + [I40E_FILTER_PCTYPE_NONF_IPV6_ICMP] = + I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST, [I40E_FILTER_PCTYPE_FRAG_IPV4] = I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST, [I40E_FILTER_PCTYPE_NONF_IPV4_UDP] = diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c index 5e2bb64c14..a929ca84b6 100644 --- a/drivers/net/i40e/i40e_fdir.c +++ b/drivers/net/i40e/i40e_fdir.c @@ -824,6 +824,8 @@ i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf, [I40E_FILTER_PCTYPE_NONF_IPV6_UDP] = IPPROTO_UDP, [I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] = IPPROTO_SCTP, [I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] = IPPROTO_NONE, + [I40E_FILTER_PCTYPE_NONF_IPV4_ICMP] = IPPROTO_ICMP, + [I40E_FILTER_PCTYPE_NONF_IPV6_ICMP] = IPPROTO_ICMP }; rte_memcpy(raw_pkt, &fdir_input->flow.l2_flow.dst, @@ -854,64 +856,81 @@ i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf, } } - if (pctype == I40E_FILTER_PCTYPE_L2_PAYLOAD) + switch (pctype) { + case I40E_FILTER_PCTYPE_L2_PAYLOAD: *ether_type = fdir_input->flow.l2_flow.ether_type; - else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_TCP || - pctype == I40E_FILTER_PCTYPE_NONF_IPV4_UDP || - pctype == I40E_FILTER_PCTYPE_NONF_IPV4_SCTP || - pctype == I40E_FILTER_PCTYPE_NONF_IPV4_OTHER || - pctype == I40E_FILTER_PCTYPE_FRAG_IPV4 || - pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP || - pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP || - pctype == I40E_FILTER_PCTYPE_NONF_IPV6_SCTP || - pctype == I40E_FILTER_PCTYPE_NONF_IPV6_OTHER || - pctype == I40E_FILTER_PCTYPE_FRAG_IPV6 || - is_customized_pctype) { - if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_TCP || - pctype == I40E_FILTER_PCTYPE_NONF_IPV4_UDP || - pctype == I40E_FILTER_PCTYPE_NONF_IPV4_SCTP || - pctype == I40E_FILTER_PCTYPE_NONF_IPV4_OTHER || - pctype == I40E_FILTER_PCTYPE_FRAG_IPV4) { - len = fill_ip4_head(fdir_input, raw_pkt, - next_proto[pctype], len, ether_type); - } else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP || - pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP || - pctype == I40E_FILTER_PCTYPE_NONF_IPV6_SCTP || - pctype == I40E_FILTER_PCTYPE_NONF_IPV6_OTHER || - pctype == I40E_FILTER_PCTYPE_FRAG_IPV6) { - len = fill_ip6_head(fdir_input, raw_pkt, - next_proto[pctype], len, - ether_type); - } else if (cus_pctype->index == I40E_CUSTOMIZED_GTPC || - cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV4 || - cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV6 || - cus_pctype->index == I40E_CUSTOMIZED_GTPU) { + break; + case I40E_FILTER_PCTYPE_NONF_IPV4_TCP: + case I40E_FILTER_PCTYPE_NONF_IPV4_UDP: + case I40E_FILTER_PCTYPE_NONF_IPV4_ICMP: + case I40E_FILTER_PCTYPE_NONF_IPV4_SCTP: + case I40E_FILTER_PCTYPE_NONF_IPV4_OTHER: + case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_UDP: + case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_TCP: + case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_ICMP: + case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_UDP: + case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_TCP: + case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_ICMP: + case I40E_FILTER_PCTYPE_FRAG_IPV4: + len = fill_ip4_head(fdir_input, raw_pkt, + next_proto[pctype], len, ether_type); + break; + + case I40E_FILTER_PCTYPE_NONF_IPV6_TCP: + case I40E_FILTER_PCTYPE_NONF_IPV6_UDP: + case I40E_FILTER_PCTYPE_NONF_IPV6_ICMP: + case I40E_FILTER_PCTYPE_NONF_IPV6_SCTP: + case I40E_FILTER_PCTYPE_NONF_IPV6_OTHER: + case I40E_FILTER_PCTYPE_FRAG_IPV6: + case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_UDP: + case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_TCP: + case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_ICMP: + case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_UDP: + case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_TCP: + case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_ICMP: + len = fill_ip6_head(fdir_input, raw_pkt, + next_proto[pctype], len, + ether_type); + break; + default: + if (!is_customized_pctype) { + PMD_DRV_LOG(ERR, "unknown pctype %u.", fdir_input->pctype); + return -1; + } + + switch (cus_pctype->index) { + case I40E_CUSTOMIZED_GTPC: + case I40E_CUSTOMIZED_GTPU_IPV4: + case I40E_CUSTOMIZED_GTPU_IPV6: + case I40E_CUSTOMIZED_GTPU: + case I40E_CUSTOMIZED_ESP_IPV4_UDP: len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_UDP, - len, ether_type); - } else if (cus_pctype->index == I40E_CUSTOMIZED_IPV4_L2TPV3) { - len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_L2TP, - len, ether_type); - } else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4) { + len, ether_type); + break; + case I40E_CUSTOMIZED_ESP_IPV4: len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_ESP, - len, ether_type); - } else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4_UDP) { - len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_UDP, - len, ether_type); - } else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4_UDP) { - len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_UDP, - len, ether_type); - } else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV6) + len, ether_type); + break; + case I40E_CUSTOMIZED_IPV4_L2TPV3: + len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_L2TP, + len, ether_type); + break; + case I40E_CUSTOMIZED_ESP_IPV6: len = fill_ip6_head(fdir_input, raw_pkt, IPPROTO_ESP, - len, ether_type); - else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV6_UDP) + len, ether_type); + break; + case I40E_CUSTOMIZED_ESP_IPV6_UDP: len = fill_ip6_head(fdir_input, raw_pkt, IPPROTO_UDP, - len, ether_type); - else if (cus_pctype->index == I40E_CUSTOMIZED_IPV6_L2TPV3) + len, ether_type); + break; + case I40E_CUSTOMIZED_IPV6_L2TPV3: len = fill_ip6_head(fdir_input, raw_pkt, IPPROTO_L2TP, - len, ether_type); - } else { - PMD_DRV_LOG(ERR, "unknown pctype %u.", fdir_input->pctype); - return -1; + len, ether_type); + break; + default: + PMD_DRV_LOG(ERR, "unknown customized pctype: %u.", fdir_input->pctype); + return -1; + } } return len; @@ -940,13 +959,54 @@ i40e_flow_fdir_construct_pkt(struct i40e_pf *pf, struct rte_flow_item_esp *esp; struct rte_ipv4_hdr *esp_ipv4; struct rte_ipv6_hdr *esp_ipv6; + struct rte_icmp_hdr *icmp; + struct rte_ipv4_hdr *ip; + struct rte_ipv6_hdr *ip6; + static char packet_4_4[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0, 0x45, 0, + 0, 0x62, 0, 0x01, 0, 0, 0x40, 0x11, 0x11, 0xb9, 0xac, 0x10, 0xd4, 0x16, 0xc0, 0xa8, + 0x28, 0x02, 0, 0x35, 0x12, 0xb5, 0, 0x4e, 0x55, 0x4a, 0x08, 0, 0, 0, 0, 0, + 0x22, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0, + 0x45, 0, 0, 0x30, 0, 0x01, 0, 0, 0x40, 0x11, 0x11, 0xeb, 0xac, 0x10, 0xd4, 0x16, + 0xc0, 0xa8, 0x28, 0x02, 0, 0x23, 0, 0x05, 0, 0x1c, 0xe2, 0x07, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78}; + static char packet_4_6[] = {0x68, 0x05, 0xCA, 0x34, 0x8B, 0x98, 0xA4, 0xBF, 0x01, 0x16, 0xB2, 0xA6, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x76, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11, 0x38, 0x03, 0xC0, 0xA8, 0x00, 0x04, 0xC0, 0xA8, + 0x00, 0x04, 0x12, 0xB5, 0x12, 0xB5, 0, 0x62, 0x05, 0xC5, 0x04, 0, 0, 0x03, 0, 0, + 0, 0, 0x1D, 0x44, 0x9D, 0x54, 0xDA, 0xDE, 0, 0, 0, 0, 0, 0, 0x86, 0xDD, + 0x60, 0, 0, 0, 0, 0x1C, 0x11, 0x40, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x01, 0x04, 0, 0x04, 0, 0, 0x1C, 0x43, 0, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78}; + static char packet_6_4[] = {0x68, 0x05, 0xCA, 0x34, 0x8B, 0x98, 0xA4, 0xBF, 0x01, 0x16, 0xB2, 0xA6, 0x86, 0xDD, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x3A, 0x11, 0x40, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x56, + 0xB9, 0x14, 0x4F, 0xFC, 0x11, 0x98, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, + 0x54, 0xFF, 0xFE, 0xF5, 0x00, 0x00, 0x12, 0xB5, 0x12, 0xB5, 0, 0x4e, 0x55, 0x4a, 0x08, 0, 0, 0, 0, 0, + 0x22, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0, + 0x45, 0, 0, 0x30, 0, 0x01, 0, 0, 0x40, 0x11, 0x11, 0xeb, 0xac, 0x10, 0xd4, 0x16, + 0xc0, 0xa8, 0x28, 0x02, 0, 0x23, 0, 0x05, 0, 0x1c, 0xe2, 0x07, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78}; + static char packet_6_6[] = {0x68, 0x05, 0xCA, 0x34, 0x8B, 0x98, 0xA4, 0xBF, 0x01, 0x16, 0xB2, 0xA6, 0x86, 0xDD, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x3A, 0x11, 0x40, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x56, + 0xB9, 0x14, 0x4F, 0xFC, 0x11, 0x98, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, + 0x54, 0xFF, 0xFE, 0xF5, 0x00, 0x00, 0x12, 0xB5, 0x12, 0xB5, 0, 0x62, 0x05, 0xC5, 0x04, 0, 0, 0x03, 0, 0, + 0, 0, 0x1D, 0x44, 0x9D, 0x54, 0xDA, 0xDE, 0, 0, 0, 0, 0, 0, 0x86, 0xDD, + 0x60, 0, 0, 0, 0, 0x1C, 0x11, 0x40, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x01, 0x04, 0, 0x04, 0, 0, 0x1C, 0x43, 0, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78}; + /* fill the ethernet and IP head */ uint8_t size, dst = 0; uint8_t i, pit_idx, set_idx = I40E_FLXPLD_L4_IDX; /* use l4 by default*/ int len; uint8_t pctype = fdir_input->pctype; struct i40e_customized_pctype *cus_pctype; + if (!raw_pkt) + return -ENOMEM; + /* raw packet template - just copy contents of the raw packet */ if (fdir_input->flow_ext.pkt_template) { memcpy(raw_pkt, fdir_input->flow.raw_flow.packet, @@ -961,7 +1021,52 @@ i40e_flow_fdir_construct_pkt(struct i40e_pf *pf, return -EINVAL; /* fill the L4 head */ - if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_UDP) { + switch (pctype) { + case I40E_FILTER_PCTYPE_NONF_IPV4_ICMP: + icmp = (struct rte_icmp_hdr *)(raw_pkt + len); + payload = (unsigned char *)icmp + sizeof(struct rte_icmp_hdr); + icmp->icmp_type = 8; + icmp->icmp_cksum = 63487; + break; + + case I40E_FILTER_PCTYPE_NONF_IPV6_ICMP: + icmp = (struct rte_icmp_hdr *)(raw_pkt + len); + payload = (unsigned char *)icmp + sizeof(struct rte_icmp_hdr); + icmp->icmp_type = 8; + icmp->icmp_cksum = 63487; + break; + + case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_UDP: + case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_TCP: + case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_ICMP: + if (!raw_pkt) + return -ENOMEM; + memcpy(raw_pkt, packet_4_4, sizeof(packet_4_4)); + ip = (struct rte_ipv4_hdr *)(raw_pkt + 14); + udp = (struct rte_udp_hdr *)(raw_pkt + 14 + sizeof(struct rte_ipv4_hdr)); + payload = (unsigned char *)udp + sizeof(struct rte_udp_hdr); + ip->dst_addr = fdir_input->flow.udp4_flow.ip.dst_ip; + ip->src_addr = fdir_input->flow.udp4_flow.ip.src_ip; + udp->src_port = fdir_input->flow.udp4_flow.src_port; + udp->dst_port = fdir_input->flow.udp4_flow.dst_port; + break; + + case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_UDP: + case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_TCP: + case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_ICMP: + if (!raw_pkt) + return -ENOMEM; + memcpy(raw_pkt, packet_4_6, sizeof(packet_4_6)); + ip = (struct rte_ipv4_hdr *)(raw_pkt + 14); + udp = (struct rte_udp_hdr *)(raw_pkt + 14 + sizeof(struct rte_ipv4_hdr)); + payload = (unsigned char *)udp + sizeof(struct rte_udp_hdr); + ip->dst_addr = fdir_input->flow.udp4_flow.ip.dst_ip; + ip->src_addr = fdir_input->flow.udp4_flow.ip.src_ip; + udp->src_port = fdir_input->flow.udp4_flow.src_port; + udp->dst_port = fdir_input->flow.udp4_flow.dst_port; + break; + + case I40E_FILTER_PCTYPE_NONF_IPV4_UDP: udp = (struct rte_udp_hdr *)(raw_pkt + len); payload = (unsigned char *)udp + sizeof(struct rte_udp_hdr); /** @@ -972,7 +1077,9 @@ i40e_flow_fdir_construct_pkt(struct i40e_pf *pf, udp->src_port = fdir_input->flow.udp4_flow.dst_port; udp->dst_port = fdir_input->flow.udp4_flow.src_port; udp->dgram_len = rte_cpu_to_be_16(I40E_FDIR_UDP_DEFAULT_LEN); - } else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_TCP) { + break; + + case I40E_FILTER_PCTYPE_NONF_IPV4_TCP: tcp = (struct rte_tcp_hdr *)(raw_pkt + len); payload = (unsigned char *)tcp + sizeof(struct rte_tcp_hdr); /** @@ -983,7 +1090,9 @@ i40e_flow_fdir_construct_pkt(struct i40e_pf *pf, tcp->src_port = fdir_input->flow.tcp4_flow.dst_port; tcp->dst_port = fdir_input->flow.tcp4_flow.src_port; tcp->data_off = I40E_FDIR_TCP_DEFAULT_DATAOFF; - } else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_SCTP) { + break; + + case I40E_FILTER_PCTYPE_NONF_IPV4_SCTP: sctp = (struct rte_sctp_hdr *)(raw_pkt + len); payload = (unsigned char *)sctp + sizeof(struct rte_sctp_hdr); /** @@ -994,11 +1103,52 @@ i40e_flow_fdir_construct_pkt(struct i40e_pf *pf, sctp->src_port = fdir_input->flow.sctp4_flow.dst_port; sctp->dst_port = fdir_input->flow.sctp4_flow.src_port; sctp->tag = fdir_input->flow.sctp4_flow.verify_tag; - } else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_OTHER || - pctype == I40E_FILTER_PCTYPE_FRAG_IPV4) { + break; + + case I40E_FILTER_PCTYPE_NONF_IPV4_OTHER: + case I40E_FILTER_PCTYPE_FRAG_IPV4: payload = raw_pkt + len; set_idx = I40E_FLXPLD_L3_IDX; - } else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP) { + break; + + case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_UDP: + case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_TCP: + case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_ICMP: + if (!raw_pkt) + return -ENOMEM; + memcpy(raw_pkt, packet_6_4, sizeof(packet_6_4)); + ip6 = (struct rte_ipv6_hdr *)(raw_pkt + 14); + udp = (struct rte_udp_hdr *)(raw_pkt + 14 + sizeof(struct rte_ipv6_hdr)); + payload = (unsigned char *)udp + sizeof(struct rte_udp_hdr); + rte_memcpy(&ip6->src_addr, + &fdir_input->flow.ipv6_flow.src_ip, + IPV6_ADDR_LEN); + rte_memcpy(&ip6->dst_addr, + &fdir_input->flow.ipv6_flow.dst_ip, + IPV6_ADDR_LEN); + udp->src_port = fdir_input->flow.udp6_flow.src_port; + udp->dst_port = fdir_input->flow.udp6_flow.dst_port; + break; + case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_UDP: + case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_TCP: + case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_ICMP: + if (!raw_pkt) + return -ENOMEM; + memcpy(raw_pkt, packet_6_6, sizeof(packet_6_6)); + ip6 = (struct rte_ipv6_hdr *)(raw_pkt + 14); + udp = (struct rte_udp_hdr *)(raw_pkt + 14 + sizeof(struct rte_ipv6_hdr)); + payload = (unsigned char *)udp + sizeof(struct rte_udp_hdr); + rte_memcpy(&ip6->src_addr, + &fdir_input->flow.ipv6_flow.src_ip, + IPV6_ADDR_LEN); + rte_memcpy(&ip6->dst_addr, + &fdir_input->flow.ipv6_flow.dst_ip, + IPV6_ADDR_LEN); + udp->src_port = fdir_input->flow.udp6_flow.src_port; + udp->dst_port = fdir_input->flow.udp6_flow.dst_port; + break; + + case I40E_FILTER_PCTYPE_NONF_IPV6_UDP: udp = (struct rte_udp_hdr *)(raw_pkt + len); payload = (unsigned char *)udp + sizeof(struct rte_udp_hdr); /** @@ -1009,7 +1159,9 @@ i40e_flow_fdir_construct_pkt(struct i40e_pf *pf, udp->src_port = fdir_input->flow.udp6_flow.dst_port; udp->dst_port = fdir_input->flow.udp6_flow.src_port; udp->dgram_len = rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN); - } else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP) { + break; + + case I40E_FILTER_PCTYPE_NONF_IPV6_TCP: tcp = (struct rte_tcp_hdr *)(raw_pkt + len); payload = (unsigned char *)tcp + sizeof(struct rte_tcp_hdr); /** @@ -1020,7 +1172,9 @@ i40e_flow_fdir_construct_pkt(struct i40e_pf *pf, tcp->data_off = I40E_FDIR_TCP_DEFAULT_DATAOFF; tcp->src_port = fdir_input->flow.udp6_flow.dst_port; tcp->dst_port = fdir_input->flow.udp6_flow.src_port; - } else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_SCTP) { + break; + + case I40E_FILTER_PCTYPE_NONF_IPV6_SCTP: sctp = (struct rte_sctp_hdr *)(raw_pkt + len); payload = (unsigned char *)sctp + sizeof(struct rte_sctp_hdr); /** @@ -1031,11 +1185,15 @@ i40e_flow_fdir_construct_pkt(struct i40e_pf *pf, sctp->src_port = fdir_input->flow.sctp6_flow.dst_port; sctp->dst_port = fdir_input->flow.sctp6_flow.src_port; sctp->tag = fdir_input->flow.sctp6_flow.verify_tag; - } else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_OTHER || - pctype == I40E_FILTER_PCTYPE_FRAG_IPV6) { + break; + + case I40E_FILTER_PCTYPE_NONF_IPV6_OTHER: + case I40E_FILTER_PCTYPE_FRAG_IPV6: payload = raw_pkt + len; set_idx = I40E_FLXPLD_L3_IDX; - } else if (pctype == I40E_FILTER_PCTYPE_L2_PAYLOAD) { + break; + + case I40E_FILTER_PCTYPE_L2_PAYLOAD: payload = raw_pkt + len; /** * ARP packet is a special case on which the payload @@ -1045,13 +1203,21 @@ i40e_flow_fdir_construct_pkt(struct i40e_pf *pf, rte_cpu_to_be_16(RTE_ETHER_TYPE_ARP)) payload += sizeof(struct rte_arp_hdr); set_idx = I40E_FLXPLD_L2_IDX; - } else if (fdir_input->flow_ext.customized_pctype) { + break; + + default: + if (!fdir_input->flow_ext.customized_pctype) { + PMD_DRV_LOG(ERR, "unknown pctype %u.", fdir_input->pctype); + return -1; + } + /* If customized pctype is used */ cus_pctype = i40e_flow_fdir_find_customized_pctype(pf, pctype); - if (cus_pctype->index == I40E_CUSTOMIZED_GTPC || - cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV4 || - cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV6 || - cus_pctype->index == I40E_CUSTOMIZED_GTPU) { + switch (cus_pctype->index) { + case I40E_CUSTOMIZED_GTPC: + case I40E_CUSTOMIZED_GTPU_IPV4: + case I40E_CUSTOMIZED_GTPU_IPV6: + case I40E_CUSTOMIZED_GTPU: udp = (struct rte_udp_hdr *)(raw_pkt + len); udp->dgram_len = rte_cpu_to_be_16(I40E_FDIR_UDP_DEFAULT_LEN); @@ -1111,8 +1277,10 @@ i40e_flow_fdir_construct_pkt(struct i40e_pf *pf, } else payload = (unsigned char *)gtp + sizeof(struct rte_flow_item_gtp); - } else if (cus_pctype->index == I40E_CUSTOMIZED_IPV4_L2TPV3 || - cus_pctype->index == I40E_CUSTOMIZED_IPV6_L2TPV3) { + break; + + case I40E_CUSTOMIZED_IPV4_L2TPV3: + case I40E_CUSTOMIZED_IPV6_L2TPV3: l2tpv3oip = (struct rte_flow_item_l2tpv3oip *)(raw_pkt + len); @@ -1124,72 +1292,62 @@ i40e_flow_fdir_construct_pkt(struct i40e_pf *pf, fdir_input->flow.ip6_l2tpv3oip_flow.session_id; payload = (unsigned char *)l2tpv3oip + sizeof(struct rte_flow_item_l2tpv3oip); - } else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4 || - cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV6 || - cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4_UDP || - cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV6_UDP) { - if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4) { - esp_ipv4 = (struct rte_ipv4_hdr *) - (raw_pkt + len); - esp = (struct rte_flow_item_esp *)esp_ipv4; - esp->hdr.spi = - fdir_input->flow.esp_ipv4_flow.spi; - payload = (unsigned char *)esp + - sizeof(struct rte_esp_hdr); - len += sizeof(struct rte_esp_hdr); - } else if (cus_pctype->index == - I40E_CUSTOMIZED_ESP_IPV4_UDP) { - esp_ipv4 = (struct rte_ipv4_hdr *) - (raw_pkt + len); - udp = (struct rte_udp_hdr *)esp_ipv4; - udp->dst_port = rte_cpu_to_be_16 - (I40E_FDIR_ESP_DST_PORT); - - udp->dgram_len = rte_cpu_to_be_16 - (I40E_FDIR_UDP_DEFAULT_LEN); - esp = (struct rte_flow_item_esp *) - ((unsigned char *)esp_ipv4 + - sizeof(struct rte_udp_hdr)); - esp->hdr.spi = - fdir_input->flow.esp_ipv4_udp_flow.spi; - payload = (unsigned char *)esp + - sizeof(struct rte_esp_hdr); - len += sizeof(struct rte_udp_hdr) + - sizeof(struct rte_esp_hdr); - } else if (cus_pctype->index == - I40E_CUSTOMIZED_ESP_IPV6) { - esp_ipv6 = (struct rte_ipv6_hdr *) - (raw_pkt + len); - esp = (struct rte_flow_item_esp *)esp_ipv6; - esp->hdr.spi = - fdir_input->flow.esp_ipv6_flow.spi; - payload = (unsigned char *)esp + - sizeof(struct rte_esp_hdr); - len += sizeof(struct rte_esp_hdr); - } else if (cus_pctype->index == - I40E_CUSTOMIZED_ESP_IPV6_UDP) { - esp_ipv6 = (struct rte_ipv6_hdr *) - (raw_pkt + len); - udp = (struct rte_udp_hdr *)esp_ipv6; - udp->dst_port = rte_cpu_to_be_16 - (I40E_FDIR_ESP_DST_PORT); - - udp->dgram_len = rte_cpu_to_be_16 - (I40E_FDIR_UDP_DEFAULT_LEN); - esp = (struct rte_flow_item_esp *) - ((unsigned char *)esp_ipv6 + - sizeof(struct rte_udp_hdr)); - esp->hdr.spi = - fdir_input->flow.esp_ipv6_udp_flow.spi; - payload = (unsigned char *)esp + - sizeof(struct rte_esp_hdr); - len += sizeof(struct rte_udp_hdr) + - sizeof(struct rte_esp_hdr); - } + break; + + case I40E_CUSTOMIZED_ESP_IPV4: + esp_ipv4 = (struct rte_ipv4_hdr *)(raw_pkt + len); + esp = (struct rte_flow_item_esp *)esp_ipv4; + esp->hdr.spi = + fdir_input->flow.esp_ipv4_flow.spi; + payload = (unsigned char *)esp + + sizeof(struct rte_esp_hdr); + len += sizeof(struct rte_esp_hdr); + break; + case I40E_CUSTOMIZED_ESP_IPV6: + esp_ipv6 = (struct rte_ipv6_hdr *)(raw_pkt + len); + esp = (struct rte_flow_item_esp *)esp_ipv6; + esp->hdr.spi = + fdir_input->flow.esp_ipv6_flow.spi; + payload = (unsigned char *)esp + + sizeof(struct rte_esp_hdr); + len += sizeof(struct rte_esp_hdr); + break; + case I40E_CUSTOMIZED_ESP_IPV4_UDP: + esp_ipv4 = (struct rte_ipv4_hdr *)(raw_pkt + len); + udp = (struct rte_udp_hdr *)esp_ipv4; + udp->dst_port = rte_cpu_to_be_16(I40E_FDIR_ESP_DST_PORT); + + udp->dgram_len = rte_cpu_to_be_16(I40E_FDIR_UDP_DEFAULT_LEN); + esp = (struct rte_flow_item_esp *)((unsigned char *)esp_ipv4 + + sizeof(struct rte_udp_hdr)); + esp->hdr.spi = + fdir_input->flow.esp_ipv4_udp_flow.spi; + payload = (unsigned char *)esp + + sizeof(struct rte_esp_hdr); + len += sizeof(struct rte_udp_hdr) + + sizeof(struct rte_esp_hdr); + break; + + case I40E_CUSTOMIZED_ESP_IPV6_UDP: + esp_ipv6 = (struct rte_ipv6_hdr *)(raw_pkt + len); + udp = (struct rte_udp_hdr *)esp_ipv6; + udp->dst_port = rte_cpu_to_be_16(I40E_FDIR_ESP_DST_PORT); + + udp->dgram_len = rte_cpu_to_be_16(I40E_FDIR_UDP_DEFAULT_LEN); + esp = (struct rte_flow_item_esp *)((unsigned char *)esp_ipv6 + + sizeof(struct rte_udp_hdr)); + esp->hdr.spi = + fdir_input->flow.esp_ipv6_udp_flow.spi; + payload = (unsigned char *)esp + + sizeof(struct rte_esp_hdr); + len += sizeof(struct rte_udp_hdr) + + sizeof(struct rte_esp_hdr); + break; + + default: + PMD_DRV_LOG(ERR, "unknown customized pctype %u.", fdir_input->pctype); + return -1; } - } else { - PMD_DRV_LOG(ERR, "unknown pctype %u.", fdir_input->pctype); - return -1; } /* fill the flexbytes to payload */ @@ -1764,7 +1922,8 @@ i40e_flow_add_del_fdir_filter(struct rte_eth_dev *dev, if (add) { /* configure the input set for common PCTYPEs*/ if (!filter->input.flow_ext.customized_pctype && - !filter->input.flow_ext.pkt_template) { + !filter->input.flow_ext.pkt_template && + filter->input.pctype > I40E_FILTER_PCTYPE_NONF_IPV6_ICMP) { ret = i40e_flow_set_fdir_inset(pf, pctype, filter->input.flow_ext.input_set); if (ret < 0) diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c index b41a1fd3ca..35ab2ebd3f 100644 --- a/drivers/net/i40e/i40e_flow.c +++ b/drivers/net/i40e/i40e_flow.c @@ -1558,6 +1558,142 @@ static enum rte_flow_item_type pattern_vxlan_4[] = { RTE_FLOW_ITEM_TYPE_END, }; +/* VXLAN outer IPv4 */ +static enum rte_flow_item_type pattern_fdir_ipv4_vxlan_ipv4_udp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_END, +}; + +static enum rte_flow_item_type pattern_fdir_ipv4_vxlan_ipv4_tcp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_TCP, + RTE_FLOW_ITEM_TYPE_END, +}; + +static enum rte_flow_item_type pattern_fdir_ipv4_vxlan_ipv4_icmp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_ICMP, + RTE_FLOW_ITEM_TYPE_END, +}; + +static enum rte_flow_item_type pattern_fdir_ipv4_vxlan_ipv6_udp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_END, +}; + +static enum rte_flow_item_type pattern_fdir_ipv4_vxlan_ipv6_tcp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_TCP, + RTE_FLOW_ITEM_TYPE_END, +}; + +static enum rte_flow_item_type pattern_fdir_ipv4_vxlan_ipv6_icmp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_ICMP, + RTE_FLOW_ITEM_TYPE_END, +}; + +static enum rte_flow_item_type pattern_fdir_ipv4_icmp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_ICMP, + RTE_FLOW_ITEM_TYPE_END, +}; + +/* VXLAN outer IPv6 */ +static enum rte_flow_item_type pattern_fdir_ipv6_vxlan_ipv4_udp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_END, +}; + +static enum rte_flow_item_type pattern_fdir_ipv6_vxlan_ipv4_tcp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_TCP, + RTE_FLOW_ITEM_TYPE_END, +}; + +static enum rte_flow_item_type pattern_fdir_ipv6_vxlan_ipv4_icmp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_ICMP, + RTE_FLOW_ITEM_TYPE_END, +}; + +static enum rte_flow_item_type pattern_fdir_ipv6_vxlan_ipv6_udp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_END, +}; + +static enum rte_flow_item_type pattern_fdir_ipv6_vxlan_ipv6_tcp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_TCP, + RTE_FLOW_ITEM_TYPE_END, +}; + +static enum rte_flow_item_type pattern_fdir_ipv6_vxlan_ipv6_icmp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_ICMP, + RTE_FLOW_ITEM_TYPE_END, +}; + +static enum rte_flow_item_type pattern_fdir_ipv6_icmp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_ICMP, + RTE_FLOW_ITEM_TYPE_END, +}; + static enum rte_flow_item_type pattern_nvgre_1[] = { RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, @@ -1837,6 +1973,25 @@ static struct i40e_valid_pattern i40e_supported_patterns[] = { { pattern_fdir_vlan_ipv6_sctp_raw_1_vf, i40e_flow_parse_fdir_filter }, { pattern_fdir_vlan_ipv6_sctp_raw_2_vf, i40e_flow_parse_fdir_filter }, { pattern_fdir_vlan_ipv6_sctp_raw_3_vf, i40e_flow_parse_fdir_filter }, + + /* VXLAN outer IPv4 */ + { pattern_fdir_ipv4_vxlan_ipv4_udp, i40e_flow_parse_fdir_filter }, + { pattern_fdir_ipv4_vxlan_ipv4_tcp, i40e_flow_parse_fdir_filter }, + { pattern_fdir_ipv4_vxlan_ipv4_icmp, i40e_flow_parse_fdir_filter }, + { pattern_fdir_ipv4_vxlan_ipv6_udp, i40e_flow_parse_fdir_filter }, + { pattern_fdir_ipv4_vxlan_ipv6_tcp, i40e_flow_parse_fdir_filter }, + { pattern_fdir_ipv4_vxlan_ipv6_icmp, i40e_flow_parse_fdir_filter }, + { pattern_fdir_ipv4_icmp, i40e_flow_parse_fdir_filter }, + + /* VXLAN outer IPv6 */ + { pattern_fdir_ipv6_vxlan_ipv4_udp, i40e_flow_parse_fdir_filter }, + { pattern_fdir_ipv6_vxlan_ipv4_tcp, i40e_flow_parse_fdir_filter }, + { pattern_fdir_ipv6_vxlan_ipv4_icmp, i40e_flow_parse_fdir_filter }, + { pattern_fdir_ipv6_vxlan_ipv6_udp, i40e_flow_parse_fdir_filter }, + { pattern_fdir_ipv6_vxlan_ipv6_tcp, i40e_flow_parse_fdir_filter }, + { pattern_fdir_ipv6_vxlan_ipv6_icmp, i40e_flow_parse_fdir_filter }, + { pattern_fdir_ipv6_icmp, i40e_flow_parse_fdir_filter }, + /* VXLAN */ { pattern_vxlan_1, i40e_flow_parse_vxlan_filter }, { pattern_vxlan_2, i40e_flow_parse_vxlan_filter }, @@ -2361,6 +2516,7 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask; const struct rte_flow_item_tcp *tcp_spec, *tcp_mask; const struct rte_flow_item_udp *udp_spec, *udp_mask; + const struct rte_flow_item_icmp *icmp_spec, *icmp_mask; const struct rte_flow_item_sctp *sctp_spec, *sctp_mask; const struct rte_flow_item_gtp *gtp_spec, *gtp_mask; const struct rte_flow_item_esp *esp_spec, *esp_mask; @@ -2388,8 +2544,15 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, uint16_t ether_type; uint32_t vtc_flow_cpu; bool outer_ip = true; + bool is_vxlan = false; uint8_t field_idx; int ret; + enum out_inner_ip_type { + I40E_OIIP_IP4_IP4 = 0, + I40E_OIIP_IP4_IP6 = 1, + I40E_OIIP_IP6_IP4 = 2, + I40E_OIIP_IP6_IP6 = 3, + } oiip_type = I40E_OIIP_IP4_IP4; memset(off_arr, 0, sizeof(off_arr)); memset(len_arr, 0, sizeof(len_arr)); @@ -2531,7 +2694,6 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, break; case RTE_FLOW_ITEM_TYPE_IPV4: - l3 = RTE_FLOW_ITEM_TYPE_IPV4; ipv4_spec = item->spec; ipv4_mask = item->mask; ipv4_last = item->last; @@ -2682,12 +2844,16 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, return -rte_errno; } - if (outer_ip) + if (outer_ip) { + l3 = RTE_FLOW_ITEM_TYPE_IPV4; outer_ip = false; + } else { + oiip_type = (l3 == RTE_FLOW_ITEM_TYPE_IPV4) ? + I40E_OIIP_IP4_IP4 : I40E_OIIP_IP6_IP4; + } break; case RTE_FLOW_ITEM_TYPE_IPV6: - l3 = RTE_FLOW_ITEM_TYPE_IPV6; ipv6_spec = item->spec; ipv6_mask = item->mask; pctype = I40E_FILTER_PCTYPE_NONF_IPV6_OTHER; @@ -2761,19 +2927,55 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, return -rte_errno; } - if (outer_ip) + if (outer_ip) { + l3 = RTE_FLOW_ITEM_TYPE_IPV6; outer_ip = false; + } else { + oiip_type = (l3 == RTE_FLOW_ITEM_TYPE_IPV4) ? + I40E_OIIP_IP4_IP6 : I40E_OIIP_IP6_IP6; + } + break; case RTE_FLOW_ITEM_TYPE_TCP: tcp_spec = item->spec; tcp_mask = item->mask; + if (is_vxlan) { + switch (oiip_type) { + case I40E_OIIP_IP4_IP4: + pctype = I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_TCP; + break; + case I40E_OIIP_IP4_IP6: + pctype = I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_TCP; + break; + case I40E_OIIP_IP6_IP4: + pctype = I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_TCP; + break; + case I40E_OIIP_IP6_IP6: + pctype = I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_TCP; + break; + } + + /* Check TCP mask and update input set */ + if (tcp_spec || tcp_mask) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "Invalid TCP mask"); + return -rte_errno; + } + + layer_idx = I40E_FLXPLD_L4_IDX; + break; + } + if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) pctype = I40E_FILTER_PCTYPE_NONF_IPV4_TCP; else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) pctype = I40E_FILTER_PCTYPE_NONF_IPV6_TCP; + if (tcp_spec && tcp_mask) { /* Check TCP mask and update input set */ if (tcp_mask->hdr.sent_seq || @@ -2827,6 +3029,36 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, udp_spec = item->spec; udp_mask = item->mask; + if (is_vxlan) { + switch (oiip_type) { + case I40E_OIIP_IP4_IP4: + pctype = I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_UDP; + break; + case I40E_OIIP_IP4_IP6: + pctype = I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_UDP; + break; + case I40E_OIIP_IP6_IP4: + pctype = I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_UDP; + break; + case I40E_OIIP_IP6_IP6: + pctype = I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_UDP; + break; + } + + /* Check UDP mask and update input set */ + if (udp_spec || udp_mask) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "Invalid UDP mask"); + return -rte_errno; + } + + filter->input.flow_ext.is_udp = true; + layer_idx = I40E_FLXPLD_L4_IDX; + break; + } + if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP; @@ -2878,6 +3110,47 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, layer_idx = I40E_FLXPLD_L4_IDX; break; + + case RTE_FLOW_ITEM_TYPE_ICMP: + icmp_spec = item->spec; + icmp_mask = item->mask; + + pctype = (l3 == RTE_FLOW_ITEM_TYPE_IPV4) ? + I40E_FILTER_PCTYPE_NONF_IPV4_ICMP : + I40E_FILTER_PCTYPE_NONF_IPV6_ICMP; + + if (is_vxlan) { + switch (oiip_type) { + case I40E_OIIP_IP4_IP4: + pctype = I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_ICMP; + break; + case I40E_OIIP_IP4_IP6: + pctype = I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_ICMP; + break; + case I40E_OIIP_IP6_IP4: + pctype = I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_ICMP; + break; + case I40E_OIIP_IP6_IP6: + pctype = I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_ICMP; + break; + } + + /* Check ICMP mask and update input set */ + if (icmp_spec || icmp_mask) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "Invalid ICMP mask"); + return -rte_errno; + } + } + + layer_idx = I40E_FLXPLD_L4_IDX; + break; + case RTE_FLOW_ITEM_TYPE_VXLAN: + case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: + is_vxlan = true; + break; case RTE_FLOW_ITEM_TYPE_GTPC: case RTE_FLOW_ITEM_TYPE_GTPU: if (!pf->gtp_support) { diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c index 8a687803b9..f73d0335c6 100644 --- a/drivers/net/i40e/i40e_rxtx.c +++ b/drivers/net/i40e/i40e_rxtx.c @@ -3449,6 +3449,34 @@ i40e_set_default_pctype_table(struct rte_eth_dev *dev) (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER); ad->pctypes_tbl[RTE_ETH_FLOW_L2_PAYLOAD] = (1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD); + ad->pctypes_tbl[RTE_ETH_FLOW_IPV4_VXLAN_IPV4_UDP] = + (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_UDP); + ad->pctypes_tbl[RTE_ETH_FLOW_IPV4_VXLAN_IPV4_TCP] = + (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_TCP); + ad->pctypes_tbl[RTE_ETH_FLOW_IPV4_VXLAN_IPV4_ICMP] = + (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_ICMP); + ad->pctypes_tbl[RTE_ETH_FLOW_IPV4_VXLAN_IPV6_UDP] = + (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_UDP); + ad->pctypes_tbl[RTE_ETH_FLOW_IPV4_VXLAN_IPV6_TCP] = + (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_TCP); + ad->pctypes_tbl[RTE_ETH_FLOW_IPV4_VXLAN_IPV6_ICMP] = + (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_ICMP); + ad->pctypes_tbl[RTE_ETH_FLOW_IPV6_VXLAN_IPV4_UDP] = + (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_UDP); + ad->pctypes_tbl[RTE_ETH_FLOW_IPV6_VXLAN_IPV4_TCP] = + (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_TCP); + ad->pctypes_tbl[RTE_ETH_FLOW_IPV6_VXLAN_IPV4_ICMP] = + (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_ICMP); + ad->pctypes_tbl[RTE_ETH_FLOW_IPV6_VXLAN_IPV6_UDP] = + (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_UDP); + ad->pctypes_tbl[RTE_ETH_FLOW_IPV6_VXLAN_IPV6_TCP] = + (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_TCP); + ad->pctypes_tbl[RTE_ETH_FLOW_IPV6_VXLAN_IPV6_ICMP] = + (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_ICMP); + ad->pctypes_tbl[RTE_ETH_FLOW_IPV4_ICMP] = + (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_ICMP); + ad->pctypes_tbl[RTE_ETH_FLOW_IPV6_ICMP] = + (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_ICMP); if (hw->mac.type == I40E_MAC_X722 || hw->mac.type == I40E_MAC_X722_VF) { diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h index 5e8331da1c..e9dbfc43d5 100644 --- a/lib/librte_ethdev/rte_ethdev.h +++ b/lib/librte_ethdev/rte_ethdev.h @@ -490,7 +490,23 @@ struct rte_eth_rss_conf { #define RTE_ETH_FLOW_NVGRE 21 /**< NVGRE protocol based flow */ #define RTE_ETH_FLOW_VXLAN_GPE 22 /**< VXLAN-GPE protocol based flow */ #define RTE_ETH_FLOW_GTPU 23 /**< GTPU protocol based flow */ -#define RTE_ETH_FLOW_MAX 24 + +#define RTE_ETH_FLOW_IPV4_VXLAN_IPV4_UDP 24 +#define RTE_ETH_FLOW_IPV4_VXLAN_IPV4_TCP 25 +#define RTE_ETH_FLOW_IPV4_VXLAN_IPV4_ICMP 26 +#define RTE_ETH_FLOW_IPV4_VXLAN_IPV6_UDP 27 +#define RTE_ETH_FLOW_IPV4_VXLAN_IPV6_TCP 28 +#define RTE_ETH_FLOW_IPV4_VXLAN_IPV6_ICMP 29 +#define RTE_ETH_FLOW_IPV6_VXLAN_IPV4_UDP 30 +#define RTE_ETH_FLOW_IPV6_VXLAN_IPV4_TCP 31 +#define RTE_ETH_FLOW_IPV6_VXLAN_IPV4_ICMP 32 +#define RTE_ETH_FLOW_IPV6_VXLAN_IPV6_UDP 33 +#define RTE_ETH_FLOW_IPV6_VXLAN_IPV6_TCP 34 +#define RTE_ETH_FLOW_IPV6_VXLAN_IPV6_ICMP 35 +#define RTE_ETH_FLOW_IPV4_ICMP 36 +#define RTE_ETH_FLOW_IPV6_ICMP 37 + +#define RTE_ETH_FLOW_MAX 38 /* * Below macros are defined for RSS offload types, they can be used to