From patchwork Thu Oct 21 10:49:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jie Wang X-Patchwork-Id: 102586 X-Patchwork-Delegate: ferruh.yigit@amd.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 8F53BA0547; Thu, 21 Oct 2021 12:50:27 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 758844117A; Thu, 21 Oct 2021 12:50:27 +0200 (CEST) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mails.dpdk.org (Postfix) with ESMTP id 4D297410E2 for ; Thu, 21 Oct 2021 12:50:26 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10143"; a="289845359" X-IronPort-AV: E=Sophos;i="5.87,169,1631602800"; d="scan'208";a="289845359" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2021 03:50:24 -0700 X-IronPort-AV: E=Sophos;i="5.87,169,1631602800"; d="scan'208";a="484152641" Received: from dpdk.cd.intel.com ([10.240.178.133]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2021 03:50:19 -0700 From: Jie Wang To: dev@dpdk.org Cc: orika@nvidia.com, ferruh.yigit@intel.com, thomas@monjalon.net, andrew.rybchenko@oktetlabs.ru, xiaoyun.li@intel.com, stevex.yang@intel.com, jingjing.wu@intel.com, beilei.xing@intel.com, wenjun1.wu@intel.com, qi.z.zhang@intel.com, Jie Wang Date: Thu, 21 Oct 2021 18:49:22 +0800 Message-Id: <20211021104924.1586172-2-jie1x.wang@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211021104924.1586172-1-jie1x.wang@intel.com> References: <20211021100527.1582052-1-jie1x.wang@intel.com> <20211021104924.1586172-1-jie1x.wang@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v9 1/3] ethdev: support L2TPv2 and PPP procotol 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 Sender: "dev" Added flow pattern items and header formats of L2TPv2 and PPP. Signed-off-by: Wenjun Wu Signed-off-by: Jie Wang Acked-by: Ori Kam Acked-by: Andrew Rybchenko --- doc/api/doxy-api-index.md | 2 + doc/guides/nics/features/default.ini | 2 + doc/guides/prog_guide/rte_flow.rst | 25 +++ doc/guides/rel_notes/release_21_11.rst | 4 + lib/ethdev/rte_flow.c | 2 + lib/ethdev/rte_flow.h | 67 +++++++ lib/net/meson.build | 2 + lib/net/rte_l2tpv2.h | 234 +++++++++++++++++++++++++ lib/net/rte_ppp.h | 34 ++++ 9 files changed, 372 insertions(+) create mode 100644 lib/net/rte_l2tpv2.h create mode 100644 lib/net/rte_ppp.h diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md index 1992107a03..42db196afe 100644 --- a/doc/api/doxy-api-index.md +++ b/doc/api/doxy-api-index.md @@ -121,6 +121,8 @@ The public API headers are grouped by topics: [VXLAN] (@ref rte_vxlan.h), [Geneve] (@ref rte_geneve.h), [eCPRI] (@ref rte_ecpri.h) + [L2TPv2] (@ref rte_l2tpv2.h) + [PPP] (@ref rte_ppp.h) - **QoS**: [metering] (@ref rte_meter.h), diff --git a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini index 09914b1ad3..8e6a28c419 100644 --- a/doc/guides/nics/features/default.ini +++ b/doc/guides/nics/features/default.ini @@ -110,6 +110,7 @@ ipv4 = ipv6 = ipv6_ext = ipv6_frag_ext = +l2tpv2 = l2tpv3oip = mark = meta = @@ -121,6 +122,7 @@ pfcp = phy_port = port_id = port_representor = +ppp = pppoed = pppoes = pppoe_proto_id = diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index aeba374182..a2169517c3 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -1573,6 +1573,31 @@ rte_flow_flex_item_create() routine. as padded with trailing zeroes up to full configured length, both for value and mask. +Item: ``L2TPV2`` +^^^^^^^^^^^^^^^^^^^ + +Matches a L2TPv2 header. + +- ``flags_version``: flags(12b), version(4b). +- ``length``: total length of the message. +- ``tunnel_id``: identifier for the control connection. +- ``session_id``: identifier for a session within a tunnel. +- ``ns``: sequence number for this date or control message. +- ``nr``: sequence number expected in the next control message to be received. +- ``offset_size``: offset of payload data. +- ``offset_padding``: offset padding, variable length. +- Default ``mask`` matches flags_version only. + +Item: ``PPP`` +^^^^^^^^^^^^^^^^^^^ + +Matches a PPP header. + +- ``addr``: PPP address. +- ``ctrl``: PPP control. +- ``proto_id``: PPP protocol identifier. +- Default ``mask`` matches addr, ctrl, proto_id. + Actions ~~~~~~~ diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst index 041383ee2a..283770131c 100644 --- a/doc/guides/rel_notes/release_21_11.rst +++ b/doc/guides/rel_notes/release_21_11.rst @@ -105,6 +105,10 @@ New Features Added an ethdev API which can help users get device configuration. +* **Added L2TPv2 and PPP protocol support in rte_flow.** + + Added flow pattern items and header formats of L2TPv2 and PPP protocol. + * **Updated AF_XDP PMD.** * Disabled secondary process support. diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index bcf0513b3c..d268784532 100644 --- a/lib/ethdev/rte_flow.c +++ b/lib/ethdev/rte_flow.c @@ -156,6 +156,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = { MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)), MK_FLOW_ITEM_FN(FLEX, sizeof(struct rte_flow_item_flex), rte_flow_item_flex_conv), + MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), + MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), }; /** Generate flow_action[] entry. */ diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index 64ed7f2618..db3392bf97 100644 --- a/lib/ethdev/rte_flow.h +++ b/lib/ethdev/rte_flow.h @@ -35,6 +35,8 @@ #include #include #include +#include +#include #ifdef __cplusplus extern "C" { @@ -644,6 +646,20 @@ enum rte_flow_item_type { * @see struct rte_flow_item_flex. */ RTE_FLOW_ITEM_TYPE_FLEX, + + /** + * Matches L2TPv2 Header. + * + * See struct rte_flow_item_l2tpv2. + */ + RTE_FLOW_ITEM_TYPE_L2TPV2, + + /** + * Matches PPP Header. + * + * See struct rte_flow_item_ppp. + */ + RTE_FLOW_ITEM_TYPE_PPP, }; /** @@ -1900,6 +1916,57 @@ static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = { }; #endif +/** + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + * + * RTE_FLOW_ITEM_TYPE_L2TPV2 + * + * Matches L2TPv2 Header + */ +struct rte_flow_item_l2tpv2 { + struct rte_l2tpv2_combined_msg_hdr hdr; +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */ +#ifndef __cplusplus +static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = { + /* + * flags and version bit mask + * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 + * T L x x S x O P x x x x V V V V + */ + .hdr = { + .common = { + .flags_version = RTE_BE16(0xcb0f), + }, + }, +}; +#endif + +/** + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + * + * RTE_FLOW_ITEM_TYPE_PPP + * + * Matches PPP Header + */ +struct rte_flow_item_ppp { + struct rte_ppp_hdr hdr; +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */ +#ifndef __cplusplus +static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = { + .hdr = { + .addr = 0xff, + .ctrl = 0xff, + .proto_id = RTE_BE16(0xffff), + } +}; +#endif + /** * Matching pattern item definition. * diff --git a/lib/net/meson.build b/lib/net/meson.build index a4e395e9c5..e899846578 100644 --- a/lib/net/meson.build +++ b/lib/net/meson.build @@ -19,6 +19,8 @@ headers = files( 'rte_higig.h', 'rte_ecpri.h', 'rte_geneve.h', + 'rte_l2tpv2.h', + 'rte_ppp.h', ) sources = files( diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h new file mode 100644 index 0000000000..4634964820 --- /dev/null +++ b/lib/net/rte_l2tpv2.h @@ -0,0 +1,234 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 Intel Corporation. + */ + +#ifndef _RTE_L2TPV2_H_ +#define _RTE_L2TPV2_H_ + +/** + * @file + * + * L2TP header: + * + * `-0--------------------1----------------2-------------------3` + * + * `-0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1` + * + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+` + * + * `|T|L|x|x|S|x|O|P|x|x|x|x|--Ver--|-----------Length (opt)--------|` + * + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+` + * + * `|-----------Tunnel ID-----------|-----------Session ID----------|` + * + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+` + * + * `|-----------Ns (opt)------------|-----------Nr (opt)------------|` + * + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+` + * + * `|---------Offset Size (opt)-----|---------Offset pad... (opt)` + * + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+` + * + * The Type (T) bit indicates the type of message. It is set to 0 for a data + * message and 1 for a control message. + * + * If the Length (L) bit is 1, the Length field is present. This bit MUST be + * set to 1 for control messages. + * + * The x bits are reserved for future extensions. All reserved bits MUST + * be set to 0 on outgoing messages and ignored on incoming messages. + * + * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present. + * The S bit MUST be set to 1 for control messages. + * + * If the Offset (O) bit is 1, the Offset Size field is present. The O + * bit MUST be set to 0 for control messages. + * + * If the Priority (P) bit is 1, this data message should receive + * preferential treatment in its local queuing and transmission. + * The P bit MUST be set to 0 for control messages. + * + * Ver MUST be 2, indicating the version of the L2TP data message header. + * + * The Length field indicates the total length of the message in octets. + * + * Tunnel ID indicates the identifier for the control connection. + * + * Session ID indicates the identifier for a session within a tunnel. + * + * Ns indicates the sequence number for this data or control message. + * + * Nr indicates the sequence number expected in the next control message + * to be received. + * + * The Offset Size field, if present, specifies the number of octets + * past the L2TP header at which the payload data is expected to start. + * Actual data within the offset padding is undefined. If the offset + * field is present, the L2TP header ends after the last octet of the + * offset padding. + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * L2TPv2 Common Header + */ +RTE_STD_C11 +struct rte_l2tpv2_common_hdr { + union { + /** header flags and protocol version */ + rte_be16_t flags_version; + struct { +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN + rte_be16_t t:1; /**< message Type */ + rte_be16_t l:1; /**< length option bit */ + rte_be16_t res1:2; /**< reserved */ + rte_be16_t s:1; /**< ns/nr option bit */ + rte_be16_t res2:1; /**< reserved */ + rte_be16_t o:1; /**< offset option bit */ + rte_be16_t p:1; /**< priority option bit */ + rte_be16_t res3:4; /**< reserved */ + rte_be16_t ver:4; /**< protocol version */ +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN + rte_be16_t ver:4; /**< protocol version */ + rte_be16_t res3:4; /**< reserved */ + rte_be16_t p:1; /**< priority option bit */ + rte_be16_t o:1; /**< offset option bit */ + rte_be16_t res2:1; /**< reserved */ + rte_be16_t s:1; /**< ns/nr option bit */ + rte_be16_t res1:2; /**< reserved */ + rte_be16_t l:1; /**< length option bit */ + rte_be16_t t:1; /**< message Type */ +#endif + }; + }; +}; + +/** + * L2TPv2 message Header contains all options(length, ns, nr, + * offset size, offset padding). + */ +struct rte_l2tpv2_msg_with_all_options { + rte_be16_t length; /**< length(16) */ + rte_be16_t tunnel_id; /**< tunnel ID(16) */ + rte_be16_t session_id; /**< session ID(16) */ + rte_be16_t ns; /**< Ns(16) */ + rte_be16_t nr; /**< Nr(16) */ + rte_be16_t offset_size; /**< offset size(16) */ + uint8_t *offset_padding; /**< offset padding(variable length) */ +} __rte_packed; + +/** + * L2TPv2 message Header contains all options except length(ns, nr, + * offset size, offset padding). + */ +struct rte_l2tpv2_msg_without_length { + rte_be16_t tunnel_id; /**< tunnel ID(16) */ + rte_be16_t session_id; /**< session ID(16) */ + rte_be16_t ns; /**< Ns(16) */ + rte_be16_t nr; /**< Nr(16) */ + rte_be16_t offset_size; /**< offset size(16) */ + uint8_t *offset_padding; /**< offset padding(variable length) */ +} __rte_packed; + +/** + * L2TPv2 message Header contains all options except ns_nr(length, + * offset size, offset padding). + * Ns and Nr MUST be toghter. + */ +struct rte_l2tpv2_msg_without_ns_nr { + rte_be16_t length; /**< length(16) */ + rte_be16_t tunnel_id; /**< tunnel ID(16) */ + rte_be16_t session_id; /**< session ID(16) */ + rte_be16_t offset_size; /**< offset size(16) */ + uint8_t *offset_padding; /**< offset padding(variable length) */ +}; + +/** + * L2TPv2 message Header contains all options except ns_nr(length, ns, nr). + * offset size and offset padding MUST be toghter. + */ +struct rte_l2tpv2_msg_without_offset { + rte_be16_t length; /**< length(16) */ + rte_be16_t tunnel_id; /**< tunnel ID(16) */ + rte_be16_t session_id; /**< session ID(16) */ + rte_be16_t ns; /**< Ns(16) */ + rte_be16_t nr; /**< Nr(16) */ +}; + +/** + * L2TPv2 message Header contains options offset size and offset padding. + */ +struct rte_l2tpv2_msg_with_offset { + rte_be16_t tunnel_id; /**< tunnel ID(16) */ + rte_be16_t session_id; /**< session ID(16) */ + rte_be16_t offset_size; /**< offset size(16) */ + uint8_t *offset_padding; /**< offset padding(variable length) */ +} __rte_packed; + +/** + * L2TPv2 message Header contains options ns and nr. + */ +struct rte_l2tpv2_msg_with_ns_nr { + rte_be16_t tunnel_id; /**< tunnel ID(16) */ + rte_be16_t session_id; /**< session ID(16) */ + rte_be16_t ns; /**< Ns(16) */ + rte_be16_t nr; /**< Nr(16) */ +}; + +/** + * L2TPv2 message Header contains option length. + */ +struct rte_l2tpv2_msg_with_length { + rte_be16_t length; /**< length(16) */ + rte_be16_t tunnel_id; /**< tunnel ID(16) */ + rte_be16_t session_id; /**< session ID(16) */ +}; + +/** + * L2TPv2 message Header without all options. + */ +struct rte_l2tpv2_msg_without_all_options { + rte_be16_t tunnel_id; /**< tunnel ID(16) */ + rte_be16_t session_id; /**< session ID(16) */ +}; + +/** + * L2TPv2 Combined Message Header Format: Common Header + Options + */ +RTE_STD_C11 +struct rte_l2tpv2_combined_msg_hdr { + struct rte_l2tpv2_common_hdr common; /**< common header */ + union { + /** header with all options */ + struct rte_l2tpv2_msg_with_all_options type0; + /** header with all options except length */ + struct rte_l2tpv2_msg_without_length type1; + /** header with all options except ns/nr */ + struct rte_l2tpv2_msg_without_ns_nr type2; + /** header with all options except offset */ + struct rte_l2tpv2_msg_without_offset type3; + /** header with offset options */ + struct rte_l2tpv2_msg_with_offset type4; + /** header with ns/nr options */ + struct rte_l2tpv2_msg_with_ns_nr type5; + /** header with length option */ + struct rte_l2tpv2_msg_with_length type6; + /** header without all options */ + struct rte_l2tpv2_msg_without_all_options type7; + }; +} __rte_packed; + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_L2TPV2_H_ */ diff --git a/lib/net/rte_ppp.h b/lib/net/rte_ppp.h new file mode 100644 index 0000000000..7b86ac4363 --- /dev/null +++ b/lib/net/rte_ppp.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 Intel Corporation. + */ + +#ifndef _RTE_PPP_H_ +#define _RTE_PPP_H_ + +/** + * @file + * + * PPP headers definition. + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * PPP Header + */ +struct rte_ppp_hdr { + uint8_t addr; /**< PPP address(8) */ + uint8_t ctrl; /**< PPP control(8) */ + rte_be16_t proto_id; /**< PPP protocol identifier(16) */ +} __rte_packed; + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_PPP_H_ */ From patchwork Thu Oct 21 10:49:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jie Wang X-Patchwork-Id: 102587 X-Patchwork-Delegate: ferruh.yigit@amd.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 0F798A0547; Thu, 21 Oct 2021 12:50:34 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7810C411D1; Thu, 21 Oct 2021 12:50:33 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mails.dpdk.org (Postfix) with ESMTP id 9BC97410E2 for ; Thu, 21 Oct 2021 12:50:31 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10143"; a="226461309" X-IronPort-AV: E=Sophos;i="5.87,169,1631602800"; d="scan'208";a="226461309" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2021 03:50:29 -0700 X-IronPort-AV: E=Sophos;i="5.87,169,1631602800"; d="scan'208";a="484152729" Received: from dpdk.cd.intel.com ([10.240.178.133]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2021 03:50:25 -0700 From: Jie Wang To: dev@dpdk.org Cc: orika@nvidia.com, ferruh.yigit@intel.com, thomas@monjalon.net, andrew.rybchenko@oktetlabs.ru, xiaoyun.li@intel.com, stevex.yang@intel.com, jingjing.wu@intel.com, beilei.xing@intel.com, wenjun1.wu@intel.com, qi.z.zhang@intel.com, Jie Wang Date: Thu, 21 Oct 2021 18:49:23 +0800 Message-Id: <20211021104924.1586172-3-jie1x.wang@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211021104924.1586172-1-jie1x.wang@intel.com> References: <20211021100527.1582052-1-jie1x.wang@intel.com> <20211021104924.1586172-1-jie1x.wang@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v9 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash 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 Sender: "dev" Add support for PPP over L2TPv2 over UDP protocol RSS Hash based on inner IP src/dst address and TCP/UDP src/dst port. Patterns are listed below: eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6) eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/udp eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/tcp Signed-off-by: Wenjun Wu Signed-off-by: Jie Wang Acked-by: Beilei Xing --- doc/guides/nics/features/iavf.ini | 2 + doc/guides/rel_notes/release_21_11.rst | 1 + drivers/net/iavf/iavf_generic_flow.c | 131 +++++++++++++++++++++++++ drivers/net/iavf/iavf_generic_flow.h | 15 +++ drivers/net/iavf/iavf_hash.c | 108 +++++++++++++++++++- 5 files changed, 255 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini index d00ca934c3..a916275b88 100644 --- a/doc/guides/nics/features/iavf.ini +++ b/doc/guides/nics/features/iavf.ini @@ -50,8 +50,10 @@ icmp6 = Y ipv4 = Y ipv6 = Y ipv6_frag_ext = Y +l2tpv2 = Y l2tpv3oip = Y pfcp = Y +ppp = Y sctp = Y tcp = Y udp = Y diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst index 283770131c..bd0eacc0c5 100644 --- a/doc/guides/rel_notes/release_21_11.rst +++ b/doc/guides/rel_notes/release_21_11.rst @@ -132,6 +132,7 @@ New Features * Added Intel iavf support on Windows. * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS flow. + * Added PPPoL2TPv2oUDP RSS hash based on inner IP address and TCP/UDP port. * **Updated Intel ice driver.** diff --git a/drivers/net/iavf/iavf_generic_flow.c b/drivers/net/iavf/iavf_generic_flow.c index b86d99e57d..364904fa02 100644 --- a/drivers/net/iavf/iavf_generic_flow.c +++ b/drivers/net/iavf/iavf_generic_flow.c @@ -1611,6 +1611,137 @@ enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[] = { RTE_FLOW_ITEM_TYPE_END, }; +/* PPPoL2TPv2oUDP */ +enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_END, +}; + +enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_END, +}; + +enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_END, +}; + +enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_TCP, + RTE_FLOW_ITEM_TYPE_END, +}; + +enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_END, +}; + +enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_TCP, + RTE_FLOW_ITEM_TYPE_END, +}; + +enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_END, +}; + +enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_END, +}; + +enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_END, +}; + +enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_TCP, + RTE_FLOW_ITEM_TYPE_END, +}; + +enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_END, +}; + +enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_TCP, + RTE_FLOW_ITEM_TYPE_END, +}; + + + typedef struct iavf_flow_engine * (*parse_engine_t)(struct iavf_adapter *ad, struct rte_flow *flow, struct iavf_parser_list *parser_list, diff --git a/drivers/net/iavf/iavf_generic_flow.h b/drivers/net/iavf/iavf_generic_flow.h index 4794d1fb80..f2b54e1944 100644 --- a/drivers/net/iavf/iavf_generic_flow.h +++ b/drivers/net/iavf/iavf_generic_flow.h @@ -410,6 +410,21 @@ extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_tcp[]; extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv4_udp[]; extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[]; +/* PPPoL2TPv2oUDP */ +extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[]; +extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[]; +extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[]; +extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[]; +extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[]; +extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[]; +extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[]; +extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[]; +extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[]; +extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[]; +extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[]; +extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[]; + + extern const struct rte_flow_ops iavf_flow_ops; /* pattern structure */ diff --git a/drivers/net/iavf/iavf_hash.c b/drivers/net/iavf/iavf_hash.c index 1f2d3772d1..01724cd569 100644 --- a/drivers/net/iavf/iavf_hash.c +++ b/drivers/net/iavf/iavf_hash.c @@ -34,6 +34,8 @@ /* the second IP header of GTPoGRE */ #define IAVF_PHINT_MID_IPV4 BIT_ULL(7) #define IAVF_PHINT_MID_IPV6 BIT_ULL(8) +/* L2TPv2 */ +#define IAVF_PHINT_L2TPV2 BIT_ULL(9) #define IAVF_PHINT_GTPU_MSK (IAVF_PHINT_GTPU | \ IAVF_PHINT_GTPU_EH | \ @@ -164,6 +166,12 @@ iavf_hash_parse_pattern_action(struct iavf_adapter *ad, VIRTCHNL_PROTO_HDR_ECPRI, \ FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ECPRI_PC_RTC_ID), {BUFF_NOUSED} } +#define proto_hdr_l2tpv2 { \ + VIRTCHNL_PROTO_HDR_L2TPV2, 0, {BUFF_NOUSED} } + +#define proto_hdr_ppp { \ + VIRTCHNL_PROTO_HDR_PPP, 0, {BUFF_NOUSED} } + #define TUNNEL_LEVEL_OUTER 0 #define TUNNEL_LEVEL_INNER 1 @@ -338,6 +346,52 @@ struct virtchnl_proto_hdrs ipv4_ecpri_tmplt = { TUNNEL_LEVEL_OUTER, 3, {proto_hdr_ipv4, proto_hdr_udp, proto_hdr_ecpri} }; +struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tmplt = { + TUNNEL_LEVEL_INNER, 3, + {proto_hdr_l2tpv2, + proto_hdr_ppp, + proto_hdr_ipv4} +}; + +struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tmplt = { + TUNNEL_LEVEL_INNER, 3, + {proto_hdr_l2tpv2, + proto_hdr_ppp, + proto_hdr_ipv6} +}; + +struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_udp_tmplt = { + TUNNEL_LEVEL_INNER, 4, + {proto_hdr_l2tpv2, + proto_hdr_ppp, + proto_hdr_ipv4_with_prot, + proto_hdr_udp} +}; + +struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tcp_tmplt = { + TUNNEL_LEVEL_INNER, 4, + {proto_hdr_l2tpv2, + proto_hdr_ppp, + proto_hdr_ipv4_with_prot, + proto_hdr_tcp} +}; + +struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_udp_tmplt = { + TUNNEL_LEVEL_INNER, 4, + {proto_hdr_l2tpv2, + proto_hdr_ppp, + proto_hdr_ipv6_with_prot, + proto_hdr_udp} +}; + +struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tcp_tmplt = { + TUNNEL_LEVEL_INNER, 4, + {proto_hdr_l2tpv2, + proto_hdr_ppp, + proto_hdr_ipv6_with_prot, + proto_hdr_tcp} +}; + /* rss type super set */ /* IPv4 outer */ @@ -493,6 +547,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = { {iavf_pattern_eth_ipv6_gre_ipv4_tcp, IAVF_RSS_TYPE_INNER_IPV4_TCP, &inner_ipv4_tcp_tmplt}, {iavf_pattern_eth_ipv4_gre_ipv4_udp, IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt}, {iavf_pattern_eth_ipv6_gre_ipv4_udp, IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt}, + {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4, IAVF_RSS_TYPE_INNER_IPV4, &udp_l2tpv2_ppp_ipv4_tmplt}, + {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp, IAVF_RSS_TYPE_INNER_IPV4_UDP, &udp_l2tpv2_ppp_ipv4_udp_tmplt}, + {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp, IAVF_RSS_TYPE_INNER_IPV4_TCP, &udp_l2tpv2_ppp_ipv4_tcp_tmplt}, + {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4, IAVF_RSS_TYPE_INNER_IPV4, &udp_l2tpv2_ppp_ipv4_tmplt}, + {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp, IAVF_RSS_TYPE_INNER_IPV4_UDP, &udp_l2tpv2_ppp_ipv4_udp_tmplt}, + {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp, IAVF_RSS_TYPE_INNER_IPV4_TCP, &udp_l2tpv2_ppp_ipv4_tcp_tmplt}, + /* IPv6 */ {iavf_pattern_eth_ipv6, IAVF_RSS_TYPE_OUTER_IPV6, &outer_ipv6_tmplt}, {iavf_pattern_eth_ipv6_frag_ext, IAVF_RSS_TYPE_OUTER_IPV6_FRAG, &outer_ipv6_frag_tmplt}, @@ -553,6 +614,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = { {iavf_pattern_eth_ipv6_gre_ipv6_tcp, IAVF_RSS_TYPE_INNER_IPV6_TCP, &inner_ipv6_tcp_tmplt}, {iavf_pattern_eth_ipv4_gre_ipv6_udp, IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt}, {iavf_pattern_eth_ipv6_gre_ipv6_udp, IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt}, + {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6, IAVF_RSS_TYPE_INNER_IPV6, &udp_l2tpv2_ppp_ipv6_tmplt}, + {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp, IAVF_RSS_TYPE_INNER_IPV6_UDP, &udp_l2tpv2_ppp_ipv6_udp_tmplt}, + {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp, IAVF_RSS_TYPE_INNER_IPV6_TCP, &udp_l2tpv2_ppp_ipv6_tcp_tmplt}, + {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6, IAVF_RSS_TYPE_INNER_IPV6, &udp_l2tpv2_ppp_ipv6_tmplt}, + {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp, IAVF_RSS_TYPE_INNER_IPV6_UDP, &udp_l2tpv2_ppp_ipv6_udp_tmplt}, + {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp, IAVF_RSS_TYPE_INNER_IPV6_TCP, &udp_l2tpv2_ppp_ipv6_tcp_tmplt}, + }; static struct iavf_flow_engine iavf_hash_engine = { @@ -687,13 +755,17 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint, switch (item->type) { case RTE_FLOW_ITEM_TYPE_IPV4: - if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE)) + if (!(*phint & IAVF_PHINT_GTPU_MSK) && + !(*phint & IAVF_PHINT_GRE) && + !(*phint & IAVF_PHINT_L2TPV2)) *phint |= IAVF_PHINT_OUTER_IPV4; if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK)) *phint |= IAVF_PHINT_MID_IPV4; break; case RTE_FLOW_ITEM_TYPE_IPV6: - if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE)) + if (!(*phint & IAVF_PHINT_GTPU_MSK) && + !(*phint & IAVF_PHINT_GRE) && + !(*phint & IAVF_PHINT_L2TPV2)) *phint |= IAVF_PHINT_OUTER_IPV6; if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK)) *phint |= IAVF_PHINT_MID_IPV6; @@ -728,6 +800,10 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint, break; case RTE_FLOW_ITEM_TYPE_GRE: *phint |= IAVF_PHINT_GRE; + break; + case RTE_FLOW_ITEM_TYPE_L2TPV2: + *phint |= IAVF_PHINT_L2TPV2; + break; default: break; } @@ -1050,12 +1126,40 @@ iavf_refine_proto_hdrs_by_pattern(struct virtchnl_proto_hdrs *proto_hdrs, proto_hdrs->tunnel_level = tun_lvl; } +static void +iavf_refine_proto_hdrs_l2tpv2(struct virtchnl_proto_hdrs *proto_hdrs, + uint64_t phint) +{ + struct virtchnl_proto_hdr *hdr1; + int i; + + if (!(phint & IAVF_PHINT_L2TPV2)) + return; + + if (proto_hdrs->tunnel_level == TUNNEL_LEVEL_INNER) { + /* shift headers layer */ + for (i = proto_hdrs->count - 1 + 1; i > 0; i--) + proto_hdrs->proto_hdr[i] = proto_hdrs->proto_hdr[i - 1]; + + /* adding outer ip header at layer 0 */ + hdr1 = &proto_hdrs->proto_hdr[0]; + hdr1->field_selector = 0; + proto_hdrs->count++; + proto_hdrs->tunnel_level = TUNNEL_LEVEL_OUTER; + if (phint & IAVF_PHINT_OUTER_IPV4) + VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV4); + else if (phint & IAVF_PHINT_OUTER_IPV6) + VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV6); + } +} + static void iavf_refine_proto_hdrs(struct virtchnl_proto_hdrs *proto_hdrs, uint64_t rss_type, uint64_t phint) { iavf_refine_proto_hdrs_l234(proto_hdrs, rss_type); iavf_refine_proto_hdrs_by_pattern(proto_hdrs, phint); iavf_refine_proto_hdrs_gtpu(proto_hdrs, rss_type); + iavf_refine_proto_hdrs_l2tpv2(proto_hdrs, phint); } static uint64_t invalid_rss_comb[] = { From patchwork Thu Oct 21 10:49:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jie Wang X-Patchwork-Id: 102588 X-Patchwork-Delegate: ferruh.yigit@amd.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 48F46A0547; Thu, 21 Oct 2021 12:50:44 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D2AA641205; Thu, 21 Oct 2021 12:50:37 +0200 (CEST) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mails.dpdk.org (Postfix) with ESMTP id AD9BF411FA for ; Thu, 21 Oct 2021 12:50:35 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10143"; a="289845419" X-IronPort-AV: E=Sophos;i="5.87,169,1631602800"; d="scan'208";a="289845419" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2021 03:50:34 -0700 X-IronPort-AV: E=Sophos;i="5.87,169,1631602800"; d="scan'208";a="484152767" Received: from dpdk.cd.intel.com ([10.240.178.133]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2021 03:50:30 -0700 From: Jie Wang To: dev@dpdk.org Cc: orika@nvidia.com, ferruh.yigit@intel.com, thomas@monjalon.net, andrew.rybchenko@oktetlabs.ru, xiaoyun.li@intel.com, stevex.yang@intel.com, jingjing.wu@intel.com, beilei.xing@intel.com, wenjun1.wu@intel.com, qi.z.zhang@intel.com, Jie Wang Date: Thu, 21 Oct 2021 18:49:24 +0800 Message-Id: <20211021104924.1586172-4-jie1x.wang@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211021104924.1586172-1-jie1x.wang@intel.com> References: <20211021100527.1582052-1-jie1x.wang@intel.com> <20211021104924.1586172-1-jie1x.wang@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v9 3/3] app/testpmd: support L2TPv2 and PPP protocol pattern 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 Sender: "dev" Add support for test-pmd to parse protocol pattern L2TPv2 and PPP. Signed-off-by: Wenjun Wu Signed-off-by: Jie Wang --- app/test-pmd/cmdline_flow.c | 251 ++++++++++++++++++++ doc/guides/testpmd_app_ug/testpmd_funcs.rst | 28 +++ 2 files changed, 279 insertions(+) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 5437975837..d8218771fb 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -321,6 +321,23 @@ enum index { ITEM_FLEX, ITEM_FLEX_ITEM_HANDLE, ITEM_FLEX_PATTERN_HANDLE, + ITEM_L2TPV2, + ITEM_L2TPV2_COMMON, + ITEM_L2TPV2_COMMON_TYPE, + ITEM_L2TPV2_COMMON_TYPE_DATA_L, + ITEM_L2TPV2_COMMON_TYPE_CTRL, + ITEM_L2TPV2_MSG_DATA_L_LENGTH, + ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, + ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, + ITEM_L2TPV2_MSG_CTRL_LENGTH, + ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, + ITEM_L2TPV2_MSG_CTRL_SESSION_ID, + ITEM_L2TPV2_MSG_CTRL_NS, + ITEM_L2TPV2_MSG_CTRL_NR, + ITEM_PPP, + ITEM_PPP_ADDR, + ITEM_PPP_CTRL, + ITEM_PPP_PROTO_ID, /* Validate/create actions. */ ACTIONS, @@ -1042,6 +1059,8 @@ static const enum index next_item[] = { ITEM_PORT_REPRESENTOR, ITEM_REPRESENTED_PORT, ITEM_FLEX, + ITEM_L2TPV2, + ITEM_PPP, END_SET, ZERO, }; @@ -1429,6 +1448,31 @@ static const enum index item_flex[] = { ZERO, }; +static const enum index item_l2tpv2[] = { + ITEM_L2TPV2_COMMON, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_l2tpv2_common[] = { + ITEM_L2TPV2_COMMON_TYPE, + ZERO, +}; + +static const enum index item_l2tpv2_common_type[] = { + ITEM_L2TPV2_COMMON_TYPE_DATA_L, + ITEM_L2TPV2_COMMON_TYPE_CTRL, + ZERO, +}; + +static const enum index item_ppp[] = { + ITEM_PPP_ADDR, + ITEM_PPP_CTRL, + ITEM_PPP_PROTO_ID, + ITEM_NEXT, + ZERO, +}; + static const enum index next_action[] = { ACTION_END, ACTION_VOID, @@ -1815,6 +1859,9 @@ static int parse_vc_conf(struct context *, const struct token *, static int parse_vc_item_ecpri_type(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int parse_vc_item_l2tpv2_type(struct context *, const struct token *, + const char *, unsigned int, + void *, unsigned int); static int parse_vc_action_meter_color_type(struct context *, const struct token *, const char *, unsigned int, void *, @@ -3789,6 +3836,153 @@ static const struct token token_list[] = { NEXT_ENTRY(ITEM_PARAM_IS)), .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)), }, + [ITEM_L2TPV2] = { + .name = "l2tpv2", + .help = "match L2TPv2 header", + .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), + .next = NEXT(item_l2tpv2), + .call = parse_vc, + }, + [ITEM_L2TPV2_COMMON] = { + .name = "common", + .help = "L2TPv2 common header", + .next = NEXT(item_l2tpv2_common), + }, + [ITEM_L2TPV2_COMMON_TYPE] = { + .name = "type", + .help = "type of common header", + .next = NEXT(item_l2tpv2_common_type), + .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), + }, + [ITEM_L2TPV2_COMMON_TYPE_DATA_L] = { + .name = "data_l", + .help = "Type #6: data message with length option", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH, + ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, + ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, + ITEM_NEXT)), + .call = parse_vc_item_l2tpv2_type, + }, + [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = { + .name = "length", + .help = "message length", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH, + ITEM_L2TPV2_COMMON, ITEM_NEXT), + NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, + hdr.type6.length)), + }, + [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = { + .name = "tunnel_id", + .help = "tunnel identifier", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, + ITEM_L2TPV2_COMMON, ITEM_NEXT), + NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, + hdr.type6.tunnel_id)), + }, + [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = { + .name = "session_id", + .help = "session identifier", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, + ITEM_L2TPV2_COMMON, ITEM_NEXT), + NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, + hdr.type6.session_id)), + }, + [ITEM_L2TPV2_COMMON_TYPE_CTRL] = { + .name = "control", + .help = "Type #3: conrtol message contains length, ns, nr options", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH, + ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, + ITEM_L2TPV2_MSG_CTRL_SESSION_ID, + ITEM_L2TPV2_MSG_CTRL_NS, + ITEM_L2TPV2_MSG_CTRL_NR, + ITEM_NEXT)), + .call = parse_vc_item_l2tpv2_type, + }, + [ITEM_L2TPV2_MSG_CTRL_LENGTH] = { + .name = "length", + .help = "message length", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH, + ITEM_L2TPV2_COMMON, ITEM_NEXT), + NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, + hdr.type3.length)), + }, + [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = { + .name = "tunnel_id", + .help = "tunnel identifier", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, + ITEM_L2TPV2_COMMON, ITEM_NEXT), + NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, + hdr.type3.tunnel_id)), + }, + [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = { + .name = "session_id", + .help = "session identifier", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_SESSION_ID, + ITEM_L2TPV2_COMMON, ITEM_NEXT), + NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, + hdr.type3.session_id)), + }, + [ITEM_L2TPV2_MSG_CTRL_NS] = { + .name = "ns", + .help = "sequence number for message", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS, + ITEM_L2TPV2_COMMON, ITEM_NEXT), + NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, + hdr.type3.ns)), + }, + [ITEM_L2TPV2_MSG_CTRL_NR] = { + .name = "nr", + .help = "sequence number for next receive message", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS, + ITEM_L2TPV2_COMMON, ITEM_NEXT), + NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, + hdr.type3.nr)), + }, + [ITEM_PPP] = { + .name = "ppp", + .help = "match PPP header", + .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), + .next = NEXT(item_ppp), + .call = parse_vc, + }, + [ITEM_PPP_ADDR] = { + .name = "addr", + .help = "PPP address", + .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)), + }, + [ITEM_PPP_CTRL] = { + .name = "ctrl", + .help = "PPP control", + .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)), + }, + [ITEM_PPP_PROTO_ID] = { + .name = "proto_id", + .help = "PPP protocol identifier", + .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, + hdr.proto_id)), + }, /* Validate/create actions. */ [ACTIONS] = { .name = "actions", @@ -5676,6 +5870,57 @@ parse_vc_item_ecpri_type(struct context *ctx, const struct token *token, return len; } +/** Parse L2TPv2 common header type field. */ +static int +parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + struct rte_flow_item_l2tpv2 *l2tpv2; + struct rte_flow_item_l2tpv2 *l2tpv2_mask; + struct rte_flow_item *item; + uint32_t data_size; + uint8_t msg_type = 0; + struct buffer *out = buf; + const struct arg *arg; + + (void)size; + /* Token name must match. */ + if (parse_default(ctx, token, str, len, NULL, 0) < 0) + return -1; + switch (ctx->curr) { + case ITEM_L2TPV2_COMMON_TYPE_DATA_L: + msg_type |= 0x4000; + break; + case ITEM_L2TPV2_COMMON_TYPE_CTRL: + msg_type |= 0xC800; + break; + default: + return -1; + } + if (!ctx->object) + return len; + arg = pop_args(ctx); + if (!arg) + return -1; + l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data; + l2tpv2->hdr.common.flags_version |= msg_type; + data_size = ctx->objdata / 3; /* spec, last, mask */ + l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data + + (data_size * 2)); + l2tpv2_mask->hdr.common.flags_version = 0xFFFF; + if (arg->hton) { + l2tpv2->hdr.common.flags_version = + rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version); + l2tpv2_mask->hdr.common.flags_version = + rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version); + } + item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; + item->spec = l2tpv2; + item->mask = l2tpv2_mask; + return len; +} + /** Parse meter color action type. */ static int parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, @@ -8701,6 +8946,12 @@ flow_item_default_mask(const struct rte_flow_item *item) case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: mask = &rte_flow_item_ethdev_mask; break; + case RTE_FLOW_ITEM_TYPE_L2TPV2: + mask = &rte_flow_item_l2tpv2_mask; + break; + case RTE_FLOW_ITEM_TYPE_PPP: + mask = &rte_flow_item_ppp_mask; + break; default: break; } diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index 6d127d9a7b..31d6e1b293 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -3810,6 +3810,20 @@ This section lists supported pattern items and their attributes, if any. - ``ethdev_port_id {unsigned}``: ethdev port ID +- ``l2tpv2``: match L2TPv2 header. + + - ``length {unsigned}``: L2TPv2 option length. + - ``tunnel_id {unsigned}``: L2TPv2 tunnel identifier. + - ``session_id {unsigned}``: L2TPv2 session identifier. + - ``ns {unsigned}``: L2TPv2 option ns. + - ``nr {unsigned}``: L2TPv2 option nr. + +- ``ppp``: match PPP header. + + - ``addr {unsigned}``: PPP address. + - ``ctrl {unsigned}``: PPP control. + - ``proto_id {unsigned}``: PPP protocol identifier. + Actions list ^^^^^^^^^^^^ @@ -5036,6 +5050,20 @@ The meter policy action list: ``green -> green, yellow -> yellow, red -> red``. testpmd> create port meter 0 1 13 1 yes 0xffff 0 0 testpmd> flow create 0 priority 0 ingress group 1 pattern eth / end actions meter mtr_id 1 / end +Sample PPPoL2TPv2oUDP RSS rules +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +PPPoL2TPv2oUDP RSS rules can be created by the following commands:: + + testpmd> flow create 0 ingress pattern eth / ipv4 / udp / l2tpv2 / ppp / ipv4 + / end actions rss types ipv4 end queues end / end + testpmd> flow create 0 ingress pattern eth / ipv4 / udp / l2tpv2 / ppp / ipv6 + / udp / end actions rss types ipv6-udp end queues end / end + testpmd> flow create 0 ingress pattern eth / ipv6 / udp / l2tpv2 / ppp / ipv4 + / tcp / end actions rss types ipv4-tcp end queues end / end + testpmd> flow create 0 ingress pattern eth / ipv6 / udp / l2tpv2 / ppp / ipv6 + / end actions rss types ipv6 end queues end / end + BPF Functions --------------