From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3FA69A0547; Sun, 17 Oct 2021 10:51:42 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id B4AC240041; Sun, 17 Oct 2021 10:51:41 +0200 (CEST) Received: from NAM12-DM6-obe.outbound.protection.outlook.com (mail-dm6nam12on2062.outbound.protection.outlook.com [40.107.243.62]) by mails.dpdk.org (Postfix) with ESMTP id DD9B54003C for ; Sun, 17 Oct 2021 10:51:40 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=U0kiSg0Eegs2Gfq5Y9MrwcS3m8l1zrEanamcnUoDZp6Ju54NjcHofbaWAIlP7lnIe/v8On4riY7U8QpvEmZ0U1URipAiyzHTB1ffOw7T32IR8ZjF36J2nJE/suR7/ekokPrtlO3/1pR4OifsOIHzIGxr+fxldhRULeo7YYeVeFZ54QlHFIR2CdtZBtPHI44VsqUegx1aMLIk2Cv0UPy5eTslntpIKscPc7MeD5lMjd0WBx2SrpVKaQe1WHVpAo8FyYbqvXXq5vz5zN9SPMVTnd+tbW6LYxH1waEU5tY0yydJZClav3PS/mUvVg4z61kiI1G8qYiPatFz77s4OwhjkQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=gFYZRCXOKUi8iB10zW6Xhh728omhttdh568c5E2/fZw=; b=KqP1KZQVGqEDETLl3liT2IX0nlzG54LLFCuvCzHZe5k6LsiW/hmSzBMAHrflrtREC4Wj48welqyJpGvOoDhs2iG9ZgToBmSZL/u6BNI41brWLyiLMWdg9I57N/PRcx7qoMs9ZMW9t7trpA4B/ii0KNTLPb/x6jOTxgH+mW0ueTnv7gERkW+2w7WeO8oLdKXsXs8O5cNFLTUkGwc3oTC8LxKW6CHlHvOP/Byfq3SlAFdHrMXElN/7ENU9W7LAK9CyP9U34J0qzws/8OGzwch4MnzKJy64LlOgQ0ppj8vUQYzeVVRjbb/a46PWaYHlKASc8h1NFiwC6/YLsNdXmvvcvQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=gFYZRCXOKUi8iB10zW6Xhh728omhttdh568c5E2/fZw=; b=E0n7I2v/gIo31tyjc3k7T+w8nDDtw9jz88GzYI12enKK07I6eyF3MdSCfImEQOpAu+/jBOpYhleG5JDlm3Mmx1ZODTKlnzyjUmJTPs3c5HTtntgGF3otIzt82VaE7sXvC24NwURMbqq3JR1XbbDuzmY1PJF80EzGle0p/FRNqIYBTAw39Ty6woiJ1IRkR95nTyikqvlg8kYgSr6BDrEmUmtzTpNZablwlixeatH9hdIy5Ec48zsugd+Oj22rrR3kGeAj84SC0xgbjYVbyG5YPFXb20oP2Drhim4JvzElU0h+4TH8PdxR4s83tI9WLBYmsDoAJX3mk+KMazwZ21fcCQ== Received: from DM8PR12MB5400.namprd12.prod.outlook.com (2603:10b6:8:3b::12) by DM4PR12MB5037.namprd12.prod.outlook.com (2603:10b6:5:388::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4608.16; Sun, 17 Oct 2021 08:51:38 +0000 Received: from DM8PR12MB5400.namprd12.prod.outlook.com ([fe80::d03d:1f75:ca20:6a32]) by DM8PR12MB5400.namprd12.prod.outlook.com ([fe80::d03d:1f75:ca20:6a32%7]) with mapi id 15.20.4608.018; Sun, 17 Oct 2021 08:51:38 +0000 From: Ori Kam To: Jie Wang , "dev@dpdk.org" CC: "ferruh.yigit@intel.com" , NBU-Contact-Thomas Monjalon , "andrew.rybchenko@oktetlabs.ru" , "xiaoyun.li@intel.com" , "stevex.yang@intel.com" , "jingjing.wu@intel.com" , "beilei.xing@intel.com" , "wenjun1.wu@intel.com" Thread-Topic: [PATCH v3 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern Thread-Index: AQHXwatH5/2rFw15gEGNf0FD7oKUxKvW3Q0Q Date: Sun, 17 Oct 2021 08:51:38 +0000 Message-ID: References: <20211012102508.275790-1-jie1x.wang@intel.com> <20211015095823.701188-1-jie1x.wang@intel.com> <20211015095823.701188-4-jie1x.wang@intel.com> In-Reply-To: <20211015095823.701188-4-jie1x.wang@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: intel.com; dkim=none (message not signed) header.d=none;intel.com; dmarc=none action=none header.from=nvidia.com; x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 2d491093-f170-4e1f-108f-08d9914b5510 x-ms-traffictypediagnostic: DM4PR12MB5037: x-ld-processed: 43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:9508; x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: YE7V9Ytrqml/SSzrUvNKXkEGGmEvZuL9+jyzayWR9/0dqtwJuvXm8h2DvGvDYffMECLWZlMizhOr5rfIw9jP4L5jhC78pcFtogZJYqzwASzZ82W+xiJtAuVOyv4B6/niGJHoGwa5Kn90ZRb1syLhiFCBJ7et0StK1z27C5ZNiCLAkb0EeLO5UA+B+RK+UsJBE1lvTjO7GynYLQeJZDwtlfYfhrEzGqE2xSWxQ9j7oOsI/VzhWHBFSWq5DxbmQeBDRLM3zqjzmFS59YYEhMqK9M3BgVoNDuHrYcoR9zMhaK8YKlzekotTSyCMV3K51yV3CZu9Bs2t39mxyiUeSqkLAVvFmXmSZyx/ZU6WBIXskoc9gPfAg8eaQv8PNHGT/+f21+0bbhV5Iox5W7Ei0VYr1puAXYqIEk83hOWSEm1KcsJPQX6yB4zXG/7Ho9htK0PdQ3peXqnkU1d8E+QXGD1jKEz+QRfivXdJX1jlRorb7GxvFIQZU2/7m6DvshWVU76RPxGaDoCZnfqrD/2m9TF4ZzyLno3cVuuXq7Dfr2hvZVfGsrL4sIvjgI491IivtgihCnlw4b7EF94nocZ3OxZBIYYx8UDk1Fc1nk0mask4UA9purGOgC8PJlOBy246e6uKwnm2MMBPBd9a2ucK7oSBdm+3QTAgHEHmoJ9JW+XY8Fna4SMZc6CRkLgPadHKuYbIPiaHbjn9t2MhzPQtHxEjUg== x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DM8PR12MB5400.namprd12.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(366004)(54906003)(55016002)(64756008)(76116006)(52536014)(4326008)(66946007)(110136005)(71200400001)(5660300002)(7416002)(122000001)(2906002)(9686003)(53546011)(6506007)(66556008)(38070700005)(30864003)(26005)(86362001)(33656002)(316002)(8676002)(83380400001)(8936002)(66476007)(7696005)(38100700002)(66446008)(186003)(508600001)(559001)(579004); DIR:OUT; SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?hUVwdn6nkdD2XZJ5GI65fzvSMaRiDcvuuBZWAzs8sAKHiBYhKIGbxEKaNSvq?= =?us-ascii?Q?xJl0EvoJuACaivxPfwlvPrRPVLpYhsqWk7KGIWBajqybYu8hMwin5G7nlIDC?= =?us-ascii?Q?7b2uinvGgVHhPzjLNVTX4kiOvWJgZzmok6iDmb48zatBzKwPR32QfFek3W2E?= =?us-ascii?Q?im3ZWMAO+syOdGe8mW2PPKbqPG3D/m6yy/z/jAq29O5L1j6ebU05KLEBiX24?= =?us-ascii?Q?yDHsaBuAm4eDxGT+ilAb8mScAMIForW/bq1dUz7H64MBGGbKjoPbB2qsNNqK?= =?us-ascii?Q?ky3Xoq7pZHcbSC4vMRuvsciJWwjliDH+NpwbPvsXz5I+XK9lIfCY1Lg4n2Xu?= =?us-ascii?Q?4dmD4JT+7QdQJNVkyuP9IdcA7JXGQTwmamjyLukj+lZEQet5DawTNOw6KJB2?= =?us-ascii?Q?PHox6vs1KRlwnYIlF0VohUk13gZ4KJgr2+ZG1+ZXdcF23eYoUEQplIve2amR?= =?us-ascii?Q?ZpmDc6zTd5oUULdlVQsmhNJCz+MH1Kr0HfdCpuVclJl5ZdW9Pt5VIvgCjcb1?= =?us-ascii?Q?uP59F6OWWW1fRZb7gh6fwXAR5aV6JkniSQo+nITJhlkwchgJeOdbr1FCqF4Y?= =?us-ascii?Q?Pq07CsqmKOveRBSBhmQuW8JtavBEuUqKGNoVlQmG2k9iMY48hTWybBWM4RN5?= =?us-ascii?Q?vnDGg66Dj/yhaWidoGPaHSx2EfzmmFGoIuB4u5JrC1EJqlZnHtO0a+5kmpBX?= =?us-ascii?Q?RGOgRHeJ2/3+bUyGkNk5JhI2WVofEsx6GR8Bk5i4IW1/6AHz/2+9pR/55U+y?= =?us-ascii?Q?T3mdQ40AqEz0yxMYLqn07KznCJJQv3/d+zOtFcn58Vx68RSl8JWHybkqSMNM?= =?us-ascii?Q?GCw5m1mAlmMfXGgHaGYxWpJjUm8yNp2AYCSMtwHGwmnI+Zr1YBZnI+bWyG04?= =?us-ascii?Q?QA3etms68G5E/NBFjs4sJO0Ka3ZNp1o/yavL9R8tSWmCLImJs2GVjJAiabHh?= =?us-ascii?Q?+02el3pb59kq2vJBrtRC4DcFzZub/sl67o0lo/IasWNQ2UrK2J70CDD+OQbH?= =?us-ascii?Q?+KTOifvjS7L++pdofXdUVy21y+IJe/RR+TQVKLxmvqg31zpQqzhq4USTiHxM?= =?us-ascii?Q?TYGgdkGM6uFv+ljXcz8ZDx4Og4OUgk0Rarlpd3QN7Cs47x2ExHaVXikfkpEC?= =?us-ascii?Q?wBtub1FExMLx60Gj3EmZIUW/pLqJg0H4GuigQnvCxC7Pga0mKbwEI2loBhsd?= =?us-ascii?Q?+fwt631CAt5p5GV201T9S5rBhTowjY855g3ZtOLkeFNF8h9S2xVNtxMGlZK1?= =?us-ascii?Q?y5HpDR0vOvJlrrwuifmBITd1soMV3UlNre9wz8cSgPb3sQ39wii9bCI71jYY?= =?us-ascii?Q?zjlkx4Nd3lJvF1aMyErEVu4J?= x-ms-exchange-transport-forked: True Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: DM8PR12MB5400.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2d491093-f170-4e1f-108f-08d9914b5510 X-MS-Exchange-CrossTenant-originalarrivaltime: 17 Oct 2021 08:51:38.4201 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: Jnx7e7OX56JThMVC0UnWuMFUotLaRoD6fBwTa6R/c9tm/SMuzBjw7Y1eINOZQVKk36PiBXW9dQOaUh0xBExNkA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB5037 Subject: Re: [dpdk-dev] [PATCH v3 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" Hi Jie, Sorry if I wan't clear on my last review. You don't need to implement encap/decap for those protocols just make sure = they are working with the set encap and set decap along with the raw action. You can look at cmd_set_raw_parsed and use other tunnels as reference (for = example gtp). > -----Original Message----- > From: Jie Wang > Sent: Friday, October 15, 2021 12:58 PM > To: dev@dpdk.org > Subject: [PATCH v3 3/3] app/testpmd: support L2TPV2 and PPP protocol patt= ern >=20 > Add support for test-pmd to parse protocol pattern L2TPv2 and PPP. >=20 > Signed-off-by: Wenjun Wu > Signed-off-by: Jie Wang > --- > app/test-pmd/cmdline.c | 244 ++++++++++++++++++++++ > app/test-pmd/cmdline_flow.c | 396 ++++++++++++++++++++++++++++++++++++ > app/test-pmd/testpmd.h | 22 ++ > 3 files changed, 662 insertions(+) >=20 > diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 36d50f= d3c7..bba761ad4b 100644 > --- a/app/test-pmd/cmdline.c > +++ b/app/test-pmd/cmdline.c > @@ -13300,6 +13300,247 @@ cmdline_parse_inst_t cmd_set_nvgre_with_vlan = =3D { > }, > }; >=20 > +/** Set L2TPV2 encapsulation details */ struct cmd_set_l2tpv2_result { > + cmdline_fixed_string_t set; > + cmdline_fixed_string_t l2tpv2; > + cmdline_fixed_string_t pos_token; > + cmdline_fixed_string_t ip_version; > + uint32_t vlan_present:1; > + uint16_t flags_version; > + uint16_t session_id; > + uint16_t udp_src; > + uint16_t udp_dst; > + cmdline_ipaddr_t ip_src; > + cmdline_ipaddr_t ip_dst; > + uint16_t tci; > + uint8_t tos; > + uint8_t ttl; > + struct rte_ether_addr eth_src; > + struct rte_ether_addr eth_dst; > +}; > + > +cmdline_parse_token_string_t cmd_set_l2tpv2_set =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, set, "set"); > +cmdline_parse_token_string_t cmd_set_l2tpv2_l2tpv2 =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, l2tpv2, > +"l2tpv2"); cmdline_parse_token_string_t cmd_set_l2tpv2_l2tpv2_tos_ttl = =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, l2tpv2, > + "l2tpv2-tos-ttl"); > +cmdline_parse_token_string_t cmd_set_l2tpv2_l2tpv2_with_vlan =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, l2tpv2, > + "l2tpv2-with-vlan"); > +cmdline_parse_token_string_t cmd_set_l2tpv2_ip_version =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token, > + "ip-version"); > +cmdline_parse_token_string_t cmd_set_l2tpv2_ip_version_value =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, ip_version, > + "ipv4#ipv6"); > +cmdline_parse_token_string_t cmd_set_l2tpv2_flags_version =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token, > + "flags_version"); > +cmdline_parse_token_num_t cmd_set_l2tpv2_flags_version_value =3D > + TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, flags_version, > + RTE_UINT16); > +cmdline_parse_token_string_t cmd_set_l2tpv2_session_id =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token, > + "session_id"); > +cmdline_parse_token_num_t cmd_set_l2tpv2_session_id_value =3D > + TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, session_id, > + RTE_UINT16); > +cmdline_parse_token_string_t cmd_set_l2tpv2_udp_src =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token, > + "udp-src"); > +cmdline_parse_token_num_t cmd_set_l2tpv2_udp_src_value =3D > + TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, udp_src, > + RTE_UINT16); > +cmdline_parse_token_string_t cmd_set_l2tpv2_udp_dst =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token, > + "udp-dst"); > +cmdline_parse_token_num_t cmd_set_l2tpv2_udp_dst_value =3D > + TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, udp_dst, > + RTE_UINT16); > +cmdline_parse_token_string_t cmd_set_l2tpv2_ip_tos =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token, > + "ip-tos"); > +cmdline_parse_token_num_t cmd_set_l2tpv2_ip_tos_value =3D > + TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, tos, RTE_UINT8); > +cmdline_parse_token_string_t cmd_set_l2tpv2_ip_ttl =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token, > + "ip-ttl"); > +cmdline_parse_token_num_t cmd_set_l2tpv2_ip_ttl_value =3D > + TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, ttl, RTE_UINT8); > +cmdline_parse_token_string_t cmd_set_l2tpv2_ip_src =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token, > + "ip-src"); > +cmdline_parse_token_ipaddr_t cmd_set_l2tpv2_ip_src_value =3D > + TOKEN_IPADDR_INITIALIZER(struct cmd_set_l2tpv2_result, ip_src); > +cmdline_parse_token_string_t cmd_set_l2tpv2_ip_dst =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token, > + "ip-dst"); > +cmdline_parse_token_ipaddr_t cmd_set_l2tpv2_ip_dst_value =3D > + TOKEN_IPADDR_INITIALIZER(struct cmd_set_l2tpv2_result, ip_dst); > +cmdline_parse_token_string_t cmd_set_l2tpv2_vlan =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token, > + "vlan-tci"); > +cmdline_parse_token_num_t cmd_set_l2tpv2_vlan_value =3D > + TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, tci, RTE_UINT16); > +cmdline_parse_token_string_t cmd_set_l2tpv2_eth_src =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token, > + "eth-src"); > +cmdline_parse_token_etheraddr_t cmd_set_l2tpv2_eth_src_value =3D > + TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_l2tpv2_result, eth_src); > +cmdline_parse_token_string_t cmd_set_l2tpv2_eth_dst =3D > + TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token, > + "eth-dst"); > +cmdline_parse_token_etheraddr_t cmd_set_l2tpv2_eth_dst_value =3D > + TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_l2tpv2_result, eth_dst); > + > +static void cmd_set_l2tpv2_parsed(void *parsed_result, > + __rte_unused struct cmdline *cl, > + __rte_unused void *data) > +{ > + struct cmd_set_l2tpv2_result *res =3D parsed_result; > + > + l2tpv2_encap_conf.select_tos_ttl =3D 0; > + if (strcmp(res->l2tpv2, "l2tpv2") =3D=3D 0) > + l2tpv2_encap_conf.select_vlan =3D 0; > + else if (strcmp(res->l2tpv2, "l2tpv2-with-vlan") =3D=3D 0) > + l2tpv2_encap_conf.select_vlan =3D 1; > + else if (strcmp(res->l2tpv2, "l2tpv2-tos-ttl") =3D=3D 0) { > + l2tpv2_encap_conf.select_vlan =3D 0; > + l2tpv2_encap_conf.select_tos_ttl =3D 1; > + } > + if (strcmp(res->ip_version, "ipv4") =3D=3D 0) > + l2tpv2_encap_conf.select_ipv4 =3D 1; > + else if (strcmp(res->ip_version, "ipv6") =3D=3D 0) > + l2tpv2_encap_conf.select_ipv4 =3D 0; > + else > + return; > + > + l2tpv2_encap_conf.flags_version =3D res->flags_version; > + l2tpv2_encap_conf.session_id =3D res->session_id; > + l2tpv2_encap_conf.udp_src =3D res->udp_src; > + l2tpv2_encap_conf.udp_dst =3D res->udp_dst; > + l2tpv2_encap_conf.ip_tos =3D res->tos; > + l2tpv2_encap_conf.ip_ttl =3D res->ttl; > + if (l2tpv2_encap_conf.select_ipv4) { > + IPV4_ADDR_TO_UINT(res->ip_src, l2tpv2_encap_conf.ipv4_src); > + IPV4_ADDR_TO_UINT(res->ip_dst, l2tpv2_encap_conf.ipv4_dst); > + } else { > + IPV6_ADDR_TO_ARRAY(res->ip_src, l2tpv2_encap_conf.ipv6_src); > + IPV6_ADDR_TO_ARRAY(res->ip_dst, l2tpv2_encap_conf.ipv6_dst); > + } > + if (l2tpv2_encap_conf.select_vlan) > + l2tpv2_encap_conf.vlan_tci =3D rte_cpu_to_be_16(res->tci); > + rte_memcpy(l2tpv2_encap_conf.eth_src, res->eth_src.addr_bytes, > + RTE_ETHER_ADDR_LEN); > + rte_memcpy(l2tpv2_encap_conf.eth_dst, res->eth_dst.addr_bytes, > + RTE_ETHER_ADDR_LEN); > +} > + > +cmdline_parse_inst_t cmd_set_l2tpv2 =3D { > + .f =3D cmd_set_l2tpv2_parsed, > + .data =3D NULL, > + .help_str =3D "set l2tpv2 ip-version ipv4|ipv6 flags_version" > + " session_id udp-src " > + " udp-dst ip-src ip-dst eth-src" > + " eth-dst ", > + .tokens =3D { > + (void *)&cmd_set_l2tpv2_set, > + (void *)&cmd_set_l2tpv2_l2tpv2, > + (void *)&cmd_set_l2tpv2_ip_version, > + (void *)&cmd_set_l2tpv2_ip_version_value, > + (void *)&cmd_set_l2tpv2_flags_version, > + (void *)&cmd_set_l2tpv2_flags_version_value, > + (void *)&cmd_set_l2tpv2_session_id, > + (void *)&cmd_set_l2tpv2_session_id_value, > + (void *)&cmd_set_l2tpv2_udp_src, > + (void *)&cmd_set_l2tpv2_udp_src_value, > + (void *)&cmd_set_l2tpv2_udp_dst, > + (void *)&cmd_set_l2tpv2_udp_dst_value, > + (void *)&cmd_set_l2tpv2_ip_src, > + (void *)&cmd_set_l2tpv2_ip_src_value, > + (void *)&cmd_set_l2tpv2_ip_dst, > + (void *)&cmd_set_l2tpv2_ip_dst_value, > + (void *)&cmd_set_l2tpv2_eth_src, > + (void *)&cmd_set_l2tpv2_eth_src_value, > + (void *)&cmd_set_l2tpv2_eth_dst, > + (void *)&cmd_set_l2tpv2_eth_dst_value, > + NULL, > + }, > +}; > + > +cmdline_parse_inst_t cmd_set_l2tpv2_tos_ttl =3D { > + .f =3D cmd_set_l2tpv2_parsed, > + .data =3D NULL, > + .help_str =3D "set l2tpv2-tos-ttl ip-version ipv4|ipv6 flags_version" > + " session_id udp-src " > + " udp-dst ip-tos ip-ttl ip-src" > + " ip-dst eth-src eth-dst ", > + .tokens =3D { > + (void *)&cmd_set_l2tpv2_set, > + (void *)&cmd_set_l2tpv2_l2tpv2_tos_ttl, > + (void *)&cmd_set_l2tpv2_ip_version, > + (void *)&cmd_set_l2tpv2_ip_version_value, > + (void *)&cmd_set_l2tpv2_flags_version, > + (void *)&cmd_set_l2tpv2_flags_version_value, > + (void *)&cmd_set_l2tpv2_session_id, > + (void *)&cmd_set_l2tpv2_session_id_value, > + (void *)&cmd_set_l2tpv2_udp_src, > + (void *)&cmd_set_l2tpv2_udp_src_value, > + (void *)&cmd_set_l2tpv2_udp_dst, > + (void *)&cmd_set_l2tpv2_udp_dst_value, > + (void *)&cmd_set_l2tpv2_ip_tos, > + (void *)&cmd_set_l2tpv2_ip_tos_value, > + (void *)&cmd_set_l2tpv2_ip_ttl, > + (void *)&cmd_set_l2tpv2_ip_ttl_value, > + (void *)&cmd_set_l2tpv2_ip_src, > + (void *)&cmd_set_l2tpv2_ip_src_value, > + (void *)&cmd_set_l2tpv2_ip_dst, > + (void *)&cmd_set_l2tpv2_ip_dst_value, > + (void *)&cmd_set_l2tpv2_eth_src, > + (void *)&cmd_set_l2tpv2_eth_src_value, > + (void *)&cmd_set_l2tpv2_eth_dst, > + (void *)&cmd_set_l2tpv2_eth_dst_value, > + NULL, > + }, > +}; > + > +cmdline_parse_inst_t cmd_set_l2tpv2_with_vlan =3D { > + .f =3D cmd_set_l2tpv2_parsed, > + .data =3D NULL, > + .help_str =3D "set l2tpv2-with-vlan ip-version ipv4|ipv6 flags_version" > + " session_id udp-src " > + " udp-dst ip-src ip-dst vlan-tci" > + " eth-src eth-dst ", > + .tokens =3D { > + (void *)&cmd_set_l2tpv2_set, > + (void *)&cmd_set_l2tpv2_l2tpv2_with_vlan, > + (void *)&cmd_set_l2tpv2_ip_version, > + (void *)&cmd_set_l2tpv2_ip_version_value, > + (void *)&cmd_set_l2tpv2_flags_version, > + (void *)&cmd_set_l2tpv2_flags_version_value, > + (void *)&cmd_set_l2tpv2_session_id, > + (void *)&cmd_set_l2tpv2_session_id_value, > + (void *)&cmd_set_l2tpv2_udp_src, > + (void *)&cmd_set_l2tpv2_udp_src_value, > + (void *)&cmd_set_l2tpv2_udp_dst, > + (void *)&cmd_set_l2tpv2_udp_dst_value, > + (void *)&cmd_set_l2tpv2_ip_src, > + (void *)&cmd_set_l2tpv2_ip_src_value, > + (void *)&cmd_set_l2tpv2_ip_dst, > + (void *)&cmd_set_l2tpv2_ip_dst_value, > + (void *)&cmd_set_l2tpv2_vlan, > + (void *)&cmd_set_l2tpv2_vlan_value, > + (void *)&cmd_set_l2tpv2_eth_src, > + (void *)&cmd_set_l2tpv2_eth_src_value, > + (void *)&cmd_set_l2tpv2_eth_dst, > + (void *)&cmd_set_l2tpv2_eth_dst_value, > + NULL, > + }, > +}; > + > /** Set L2 encapsulation details */ > struct cmd_set_l2_encap_result { > cmdline_fixed_string_t set; > @@ -17774,6 +18015,9 @@ cmdline_parse_ctx_t main_ctx[] =3D { > (cmdline_parse_inst_t *)&cmd_set_vxlan_with_vlan, > (cmdline_parse_inst_t *)&cmd_set_nvgre, > (cmdline_parse_inst_t *)&cmd_set_nvgre_with_vlan, > + (cmdline_parse_inst_t *)&cmd_set_l2tpv2, > + (cmdline_parse_inst_t *)&cmd_set_l2tpv2_tos_ttl, > + (cmdline_parse_inst_t *)&cmd_set_l2tpv2_with_vlan, > (cmdline_parse_inst_t *)&cmd_set_l2_encap, > (cmdline_parse_inst_t *)&cmd_set_l2_encap_with_vlan, > (cmdline_parse_inst_t *)&cmd_set_l2_decap, diff --git a/app/test-pmd/cm= dline_flow.c > b/app/test-pmd/cmdline_flow.c index 0b5856c7d5..4f73d4f39d 100644 > --- a/app/test-pmd/cmdline_flow.c > +++ b/app/test-pmd/cmdline_flow.c > @@ -306,6 +306,23 @@ enum index { > ITEM_POL_PORT, > ITEM_POL_METER, > ITEM_POL_POLICY, > + 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, >=20 > /* Validate/create actions. */ > ACTIONS, > @@ -376,6 +393,8 @@ enum index { > ACTION_VXLAN_DECAP, > ACTION_NVGRE_ENCAP, > ACTION_NVGRE_DECAP, > + ACTION_L2TPV2_ENCAP, > + ACTION_L2TPV2_DECAP, > ACTION_L2_ENCAP, > ACTION_L2_DECAP, > ACTION_MPLSOGRE_ENCAP, > @@ -581,6 +600,44 @@ struct action_nvgre_encap_data { > struct rte_flow_item_nvgre item_nvgre; }; >=20 > +struct l2tpv2_encap_conf l2tpv2_encap_conf =3D { > + .select_ipv4 =3D 1, > + .select_vlan =3D 0, > + .select_tos_ttl =3D 0, > + .flags_version =3D 0, > + .session_id =3D 0, > + .udp_src =3D 0, > + .udp_dst =3D 1701, > + .ipv4_src =3D RTE_IPV4(127, 0, 0, 1), > + .ipv4_dst =3D RTE_IPV4(255, 255, 255, 255), > + .ipv6_src =3D "\x00\x00\x00\x00\x00\x00\x00\x00" > + "\x00\x00\x00\x00\x00\x00\x00\x01", > + .ipv6_dst =3D "\x00\x00\x00\x00\x00\x00\x00\x00" > + "\x00\x00\x00\x00\x00\x00\x11\x11", > + .vlan_tci =3D 0, > + .ip_tos =3D 0, > + .ip_ttl =3D 255, > + .eth_src =3D "\x00\x00\x00\x00\x00\x00", > + .eth_dst =3D "\xff\xff\xff\xff\xff\xff", }; > + > +/** Maximum number of items in struct rte_flow_action_l2tpv2_encap. */ > +#define ACTION_L2TPV2_ENCAP_ITEMS_NUM 6 > + > +/** Storage for struct rte_flow_action_l2tpv2_encap including external > +data. */ struct action_l2tpv2_encap_data { > + struct rte_flow_action_l2tpv2_encap conf; > + struct rte_flow_item items[ACTION_L2TPV2_ENCAP_ITEMS_NUM]; > + struct rte_flow_item_eth item_eth; > + struct rte_flow_item_vlan item_vlan; > + union { > + struct rte_flow_item_ipv4 item_ipv4; > + struct rte_flow_item_ipv6 item_ipv6; > + }; > + struct rte_flow_item_udp item_udp; > + struct rte_flow_item_l2tpv2 item_l2tpv2; }; > + > struct l2_encap_conf l2_encap_conf; >=20 See my comment at the top. > struct l2_decap_conf l2_decap_conf; > @@ -614,6 +671,7 @@ struct rte_flow_action_port_id > sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM]; > struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM]; > struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_N= UM]; > struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_N= UM]; > +struct action_l2tpv2_encap_data > +sample_l2tpv2_encap[RAW_SAMPLE_CONFS_MAX_NUM]; > struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM]; > struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM]; >=20 > @@ -999,6 +1057,8 @@ static const enum index next_item[] =3D { > ITEM_GENEVE_OPT, > ITEM_INTEGRITY, > ITEM_CONNTRACK, > + ITEM_L2TPV2, > + ITEM_PPP, > END_SET, > ZERO, > }; > @@ -1367,6 +1427,31 @@ static const enum index item_integrity_lv[] =3D { > ZERO, > }; >=20 > +static const enum index item_l2tpv2[] =3D { > + ITEM_L2TPV2_COMMON, > + ITEM_NEXT, > + ZERO, > +}; > + > +static const enum index item_l2tpv2_common[] =3D { > + ITEM_L2TPV2_COMMON_TYPE, > + ZERO, > +}; > + > +static const enum index item_l2tpv2_common_type[] =3D { > + ITEM_L2TPV2_COMMON_TYPE_DATA_L, > + ITEM_L2TPV2_COMMON_TYPE_CTRL, > + ZERO, > +}; > + > +static const enum index item_ppp[] =3D { > + ITEM_PPP_ADDR, > + ITEM_PPP_CTRL, > + ITEM_PPP_PROTO_ID, > + ITEM_NEXT, > + ZERO, > +}; > + > static const enum index next_action[] =3D { > ACTION_END, > ACTION_VOID, > @@ -1400,6 +1485,8 @@ static const enum index next_action[] =3D { > ACTION_VXLAN_DECAP, > ACTION_NVGRE_ENCAP, > ACTION_NVGRE_DECAP, > + ACTION_L2TPV2_ENCAP, > + ACTION_L2TPV2_DECAP, > ACTION_L2_ENCAP, > ACTION_L2_DECAP, > ACTION_MPLSOGRE_ENCAP, > @@ -1687,6 +1774,7 @@ static const enum index next_action_sample[] =3D { > ACTION_RAW_ENCAP, > ACTION_VXLAN_ENCAP, > ACTION_NVGRE_ENCAP, > + ACTION_L2TPV2_ENCAP, > ACTION_NEXT, > ZERO, > }; > @@ -1757,6 +1845,9 @@ static int parse_vc_action_vxlan_encap(struct conte= xt *, const struct token > *, static int parse_vc_action_nvgre_encap(struct context *, const struct= token *, > const char *, unsigned int, void *, > unsigned int); > +static int parse_vc_action_l2tpv2_encap(struct context *, const struct t= oken *, > + const char *, unsigned int, void *, > + unsigned int); > static int parse_vc_action_l2_encap(struct context *, const struct token= *, > const char *, unsigned int, void *, > unsigned int); > @@ -3606,6 +3697,136 @@ static const struct token token_list[] =3D { > item_param), > .args =3D ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)), > }, > + [ITEM_L2TPV2] =3D { > + .name =3D "l2tpv2", > + .help =3D "match l2tpv2 header", > + .priv =3D PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), > + .next =3D NEXT(item_l2tpv2), > + .call =3D parse_vc, > + }, > + [ITEM_L2TPV2_COMMON] =3D { > + .name =3D "common", > + .help =3D "l2tpv2 common header", > + .next =3D NEXT(item_l2tpv2_common), > + }, > + [ITEM_L2TPV2_COMMON_TYPE] =3D { > + .name =3D "type", > + .help =3D "type of common header", > + .next =3D NEXT(item_l2tpv2_common_type), > + .args =3D ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), > + }, > + [ITEM_L2TPV2_COMMON_TYPE_DATA_L] =3D { > + .name =3D "data_l", > + .help =3D "Type #6: data message with length option", > + .next =3D 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 =3D parse_vc, > + }, > + [ITEM_L2TPV2_MSG_DATA_L_LENGTH] =3D { > + .name =3D "length", > + .help =3D "message length", > + .next =3D NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED), > + item_param), > + .args =3D ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, > + hdr.type7.tunnel_id)), > + }, > + [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] =3D { > + .name =3D "tunnel_id", > + .help =3D "tunnel identifier", > + .next =3D NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED), > + item_param), > + .args =3D ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, > + hdr.type7.tunnel_id)), > + }, > + [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] =3D { > + .name =3D "session_id", > + .help =3D "session identifier", > + .next =3D NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED), > + item_param), > + .args =3D ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, > + hdr.type7.session_id)), > + }, > + [ITEM_L2TPV2_COMMON_TYPE_CTRL] =3D { > + .name =3D "control", > + .help =3D "Type #3: conrtol message contains length, ns, nr options", > + .next =3D 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 =3D parse_vc, > + }, > + [ITEM_L2TPV2_MSG_CTRL_LENGTH] =3D { > + .name =3D "length", > + .help =3D "message length", > + .next =3D NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED), > + item_param), > + .args =3D ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, > + hdr.type3.length)), > + }, > + [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] =3D { > + .name =3D "tunnel_id", > + .help =3D "tunnel identifier", > + .next =3D NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED), > + item_param), > + .args =3D ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, > + hdr.type3.tunnel_id)), > + }, > + [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] =3D { > + .name =3D "session_id", > + .help =3D "session identifier", > + .next =3D NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED), > + item_param), > + .args =3D ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, > + hdr.type3.session_id)), > + }, > + [ITEM_L2TPV2_MSG_CTRL_NS] =3D { > + .name =3D "ns", > + .help =3D "sequence number for message", > + .next =3D NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED), > + item_param), > + .args =3D ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, > + hdr.type3.ns)), > + }, > + [ITEM_L2TPV2_MSG_CTRL_NR] =3D { > + .name =3D "nr", > + .help =3D "sequence number for next receive message", > + .next =3D NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED), > + item_param), > + .args =3D ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, > + hdr.type3.nr)), > + }, > + [ITEM_PPP] =3D { > + .name =3D "ppp", > + .help =3D "match ppp header", > + .priv =3D PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), > + .next =3D NEXT(item_ppp), > + .call =3D parse_vc, > + }, > + [ITEM_PPP_ADDR] =3D { > + .name =3D "addr", > + .help =3D "ppp address", > + .next =3D NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), > + item_param), > + .args =3D ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, addr)), > + }, > + [ITEM_PPP_CTRL] =3D { > + .name =3D "ctrl", > + .help =3D "ppp control", > + .next =3D NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), > + item_param), > + .args =3D ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, ctrl)), > + }, > + [ITEM_PPP_PROTO_ID] =3D { > + .name =3D "proto_id", > + .help =3D "ppp protocol id", > + .next =3D NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), > + item_param), > + .args =3D ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, proto_id)), > + }, > /* Validate/create actions. */ > [ACTIONS] =3D { > .name =3D "actions", > @@ -4125,6 +4346,24 @@ static const struct token token_list[] =3D { > .next =3D NEXT(NEXT_ENTRY(ACTION_NEXT)), > .call =3D parse_vc, > }, > + [ACTION_L2TPV2_ENCAP] =3D { > + .name =3D "l2tpv2_encap", > + .help =3D "L2TPV2 encapsulation, uses configuration set by \"set" > + " l2tpv2\"", > + .priv =3D PRIV_ACTION(L2TPV2_ENCAP, > + sizeof(struct action_l2tpv2_encap_data)), > + .next =3D NEXT(NEXT_ENTRY(ACTION_NEXT)), > + .call =3D parse_vc_action_l2tpv2_encap, > + }, > + [ACTION_L2TPV2_DECAP] =3D { > + .name =3D "l2tpv2_decap", > + .help =3D "Performs a decapsulation action by stripping all" > + " headers of the L2TPV2 tunnel network overlay from the" > + " matched flow.", > + .priv =3D PRIV_ACTION(L2TPV2_DECAP, 0), > + .next =3D NEXT(NEXT_ENTRY(ACTION_NEXT)), > + .call =3D parse_vc, > + }, > [ACTION_L2_ENCAP] =3D { > .name =3D "l2_encap", > .help =3D "l2 encap, uses configuration set by" > @@ -5907,6 +6146,152 @@ parse_vc_action_nvgre_encap(struct context *ctx, = const struct token > *token, > return ret; > } >=20 > +/** Setup L2TPV2 encap configuration. */ static int > +parse_setup_l2tpv2_encap_data(struct action_l2tpv2_encap_data > +*action_l2tpv2_encap_data) { > + /* Set up default configuration. */ > + *action_l2tpv2_encap_data =3D (struct action_l2tpv2_encap_data){ > + .conf =3D (struct rte_flow_action_l2tpv2_encap){ > + .definition =3D action_l2tpv2_encap_data->items, > + }, > + .items =3D { > + { > + .type =3D RTE_FLOW_ITEM_TYPE_ETH, > + .spec =3D &action_l2tpv2_encap_data->item_eth, > + .mask =3D &rte_flow_item_eth_mask, > + }, > + { > + .type =3D RTE_FLOW_ITEM_TYPE_VLAN, > + .spec =3D &action_l2tpv2_encap_data->item_vlan, > + .mask =3D &rte_flow_item_vlan_mask, > + }, > + { > + .type =3D RTE_FLOW_ITEM_TYPE_IPV4, > + .spec =3D &action_l2tpv2_encap_data->item_ipv4, > + .mask =3D &rte_flow_item_ipv4_mask, > + }, > + { > + .type =3D RTE_FLOW_ITEM_TYPE_UDP, > + .spec =3D &action_l2tpv2_encap_data->item_udp, > + .mask =3D &rte_flow_item_udp_mask, > + }, > + { > + .type =3D RTE_FLOW_ITEM_TYPE_L2TPV2, > + .spec =3D &action_l2tpv2_encap_data->item_l2tpv2, > + .mask =3D &rte_flow_item_l2tpv2_mask, > + }, > + { > + .type =3D RTE_FLOW_ITEM_TYPE_END, > + }, > + }, > + .item_eth.type =3D 0, > + .item_vlan =3D { > + .tci =3D l2tpv2_encap_conf.vlan_tci, > + .inner_type =3D 0, > + }, > + .item_ipv4.hdr =3D { > + .src_addr =3D l2tpv2_encap_conf.ipv4_src, > + .dst_addr =3D l2tpv2_encap_conf.ipv4_dst, > + }, > + .item_udp.hdr =3D { > + .src_port =3D l2tpv2_encap_conf.udp_src, > + .dst_port =3D l2tpv2_encap_conf.udp_dst, > + }, > + }; > + memcpy(action_l2tpv2_encap_data->item_eth.dst.addr_bytes, > + l2tpv2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); > + memcpy(action_l2tpv2_encap_data->item_eth.src.addr_bytes, > + l2tpv2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); > + if (!l2tpv2_encap_conf.select_ipv4) { > + memcpy(&action_l2tpv2_encap_data->item_ipv6.hdr.src_addr, > + &l2tpv2_encap_conf.ipv6_src, > + sizeof(l2tpv2_encap_conf.ipv6_src)); > + memcpy(&action_l2tpv2_encap_data->item_ipv6.hdr.dst_addr, > + &l2tpv2_encap_conf.ipv6_dst, > + sizeof(l2tpv2_encap_conf.ipv6_dst)); > + action_l2tpv2_encap_data->items[2] =3D (struct rte_flow_item){ > + .type =3D RTE_FLOW_ITEM_TYPE_IPV6, > + .spec =3D &action_l2tpv2_encap_data->item_ipv6, > + .mask =3D &rte_flow_item_ipv6_mask, > + }; > + } > + if (!l2tpv2_encap_conf.select_vlan) > + action_l2tpv2_encap_data->items[1].type =3D > + RTE_FLOW_ITEM_TYPE_VOID; > + if (l2tpv2_encap_conf.select_tos_ttl) { > + if (l2tpv2_encap_conf.select_ipv4) { > + static struct rte_flow_item_ipv4 ipv4_mask_tos; > + > + memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask, > + sizeof(ipv4_mask_tos)); > + ipv4_mask_tos.hdr.type_of_service =3D 0xff; > + ipv4_mask_tos.hdr.time_to_live =3D 0xff; > + action_l2tpv2_encap_data->item_ipv4.hdr.type_of_service =3D > + l2tpv2_encap_conf.ip_tos; > + action_l2tpv2_encap_data->item_ipv4.hdr.time_to_live =3D > + l2tpv2_encap_conf.ip_ttl; > + action_l2tpv2_encap_data->items[2].mask =3D > + &ipv4_mask_tos; > + } else { > + static struct rte_flow_item_ipv6 ipv6_mask_tos; > + > + memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask, > + sizeof(ipv6_mask_tos)); > + ipv6_mask_tos.hdr.vtc_flow |=3D > + RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT); > + ipv6_mask_tos.hdr.hop_limits =3D 0xff; > + action_l2tpv2_encap_data->item_ipv6.hdr.vtc_flow |=3D > + rte_cpu_to_be_32 > + ((uint32_t)l2tpv2_encap_conf.ip_tos << > + RTE_IPV6_HDR_TC_SHIFT); > + action_l2tpv2_encap_data->item_ipv6.hdr.hop_limits =3D > + l2tpv2_encap_conf.ip_ttl; > + action_l2tpv2_encap_data->items[2].mask =3D > + &ipv6_mask_tos; > + } > + } > + > + if (0xc800 =3D=3D (l2tpv2_encap_conf.flags_version & 0xcb00)) { > + action_l2tpv2_encap_data->item_l2tpv2.hdr.type3.session_id =3D > + l2tpv2_encap_conf.session_id; > + } else if (0x4000 =3D=3D (l2tpv2_encap_conf.flags_version & 0xcb00)) { > + action_l2tpv2_encap_data->item_l2tpv2.hdr.type6.session_id =3D > + l2tpv2_encap_conf.session_id; > + } > + > + return 0; > +} > + > +/** Parse l2tpv2 encap action. */ > +static int > +parse_vc_action_l2tpv2_encap(struct context *ctx, const struct token *to= ken, > + const char *str, unsigned int len, > + void *buf, unsigned int size) > +{ > + struct buffer *out =3D buf; > + struct rte_flow_action *action; > + struct action_l2tpv2_encap_data *action_l2tpv2_encap_data; > + int ret; > + > + ret =3D parse_vc(ctx, token, str, len, buf, size); > + if (ret < 0) > + return ret; > + /* Nothing else to do if there is no buffer. */ > + if (!out) > + return ret; > + if (!out->args.vc.actions_n) > + return -1; > + action =3D &out->args.vc.actions[out->args.vc.actions_n - 1]; > + /* Point to selected object. */ > + ctx->object =3D out->args.vc.data; > + ctx->objmask =3D NULL; > + action_l2tpv2_encap_data =3D ctx->object; > + parse_setup_l2tpv2_encap_data(action_l2tpv2_encap_data); > + action->conf =3D &action_l2tpv2_encap_data->conf; > + return ret; > +} > + > /** Parse l2 encap action. */ > static int > parse_vc_action_l2_encap(struct context *ctx, const struct token *token,= @@ -8333,6 +8718,12 @@ > flow_item_default_mask(const struct rte_flow_item *item) > case RTE_FLOW_ITEM_TYPE_PFCP: > mask =3D &rte_flow_item_pfcp_mask; > break; > + case RTE_FLOW_ITEM_TYPE_L2TPV2: > + mask =3D &rte_flow_item_l2tpv2_mask; > + break; > + case RTE_FLOW_ITEM_TYPE_PPP: > + mask =3D &rte_flow_item_ppp_mask; > + break; > default: > break; > } > @@ -8432,6 +8823,11 @@ cmd_set_raw_parsed_sample(const struct buffer *in) > parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]); > action->conf =3D &sample_nvgre_encap[idx]; > break; > + case RTE_FLOW_ACTION_TYPE_L2TPV2_ENCAP: > + size =3D sizeof(struct rte_flow_action_l2tpv2_encap); > + parse_setup_l2tpv2_encap_data(&sample_l2tpv2_encap[idx]); > + action->conf =3D &sample_l2tpv2_encap[idx]; > + break; > default: > fprintf(stderr, "Error - Not supported action\n"); > return; > diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index e9d9db= 06ce..c744799b46 > 100644 > --- a/app/test-pmd/testpmd.h > +++ b/app/test-pmd/testpmd.h > @@ -567,6 +567,28 @@ struct nvgre_encap_conf { >=20 > extern struct nvgre_encap_conf nvgre_encap_conf; >=20 > +/* L2TPV2 encap/decap parameters. */ > +struct l2tpv2_encap_conf { > + uint32_t select_ipv4:1; > + uint32_t select_vlan:1; > + uint32_t select_tos_ttl:1; > + rte_be16_t flags_version; > + rte_be16_t session_id; > + rte_be16_t udp_src; > + rte_be16_t udp_dst; > + rte_be32_t ipv4_src; > + rte_be32_t ipv4_dst; > + uint8_t ipv6_src[16]; > + uint8_t ipv6_dst[16]; > + rte_be16_t vlan_tci; > + uint8_t ip_tos; > + uint8_t ip_ttl; > + uint8_t eth_src[RTE_ETHER_ADDR_LEN]; > + uint8_t eth_dst[RTE_ETHER_ADDR_LEN]; > +}; > + > +extern struct l2tpv2_encap_conf l2tpv2_encap_conf; > + > /* L2 encap parameters. */ > struct l2_encap_conf { > uint32_t select_ipv4:1; > -- > 2.25.1 Best, Ori