From patchwork Mon May 14 13:41:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 40003 X-Patchwork-Delegate: shahafs@mellanox.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id C4E931C874; Mon, 14 May 2018 15:41:37 +0200 (CEST) Received: from EUR03-DB5-obe.outbound.protection.outlook.com (mail-eopbgr40074.outbound.protection.outlook.com [40.107.4.74]) by dpdk.org (Postfix) with ESMTP id EACF51C873 for ; Mon, 14 May 2018 15:41:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=chpcTeLL5vRn5rapzrA4jK41UyTBB1Z/EIwSmjNyRGw=; b=FZtW1yEPy6J2ih7g0PIk0Dv9Tvs7LyTIkZwkUr6CjFssTpRJ6Pjqtox0GuAKHJQBxKjuFyJUAeh8WiS1HAZlcP7Kqa9XWrpkQ4SHxOX/7knLfDPzrafPwSwa03xQTiFHGxTUUNYxcRAgo/z9fR74R4sYfTHmu3HO5Zchy6glL14= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=matan@mellanox.com; Received: from mellanox.com (37.142.13.130) by VI1PR0501MB2608.eurprd05.prod.outlook.com (2603:10a6:800:6a::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.755.16; Mon, 14 May 2018 13:41:33 +0000 From: Matan Azrad To: Nelio Laranjeiro Cc: Shahaf Shuler , dev@dpdk.org Date: Mon, 14 May 2018 13:41:20 +0000 Message-Id: <1526305280-23078-1-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.9.5 MIME-Version: 1.0 X-Originating-IP: [37.142.13.130] X-ClientProxiedBy: VI1PR07CA0211.eurprd07.prod.outlook.com (2603:10a6:802:58::14) To VI1PR0501MB2608.eurprd05.prod.outlook.com (2603:10a6:800:6a::20) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(48565401081)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:VI1PR0501MB2608; X-Microsoft-Exchange-Diagnostics: 1; VI1PR0501MB2608; 3:KoSpE4gBO63IDH54zF//OK3AFSazIb6a3NYYumMlYlqH88LR2xEzo1686EUBdyISBjQbIqGFWnGBy3kpYz0em/d4N/sB65OcdWQe1XXpdWwhdrOkWbmF0bG9Ugh5LpjOOOKrOmzL8b9DQSaI9CwoMBqQll6hps/buXYE1l5cFB5gNKyJkl2lbqE3BwBSV0tXhZam4t3clt9zdnJ0/eKs+uYJAGQlMH3a78c5NsTPBqPYajgrPz5MQXboNU/JgTtN; 25:YnPn7Fznxnc9I0Xe/kZmCOtkNXcqFOXLDGdkdjud4UFgk7erkUV0YHKdUDLbDc3P9o9uXif7TCMiRpsNS/tNx1/cdh4WYLruJ/ZDI/2xS72uK5QkkLQpRRd9L2GPZa6eRVOyBjfGLiYH4V5PkdFDRm47/i5jALO2WR2dIQPMMpAfVSapdOVxV65dy1rkX0VLVDa7NHFE4xkS3W43/qtfSKz47ApjiM3HqXXC8/k0f5riZk34pdRFAGZ7rZRlYG7jAHeyhDDGkJl4/AteeOUDBwGpqizu5W7++1VtRMtKIc+a6De2S/sbcDtZdET30U9jDGcl++/NhxUfUAb8mBh+Ug==; 31:ynVeOxOvnsvCfwJWM7fkcF4JfJ6dV0mdPp/r3rUNBjIojaCSAQz78wbFvnzVFnFX3mZyKVJ3UjQ2Fuhe/CcedGjK0xVoXNzuS43NCczEtZtxb/SYCa4G19kMprLtFdjkKAdP2zFMhm3PIcIRQKK4TSgRFTRinxbbH1i4apypkM+ug6eQ1oly91OVvYggKCD2RW4CSMjDEBU9rznxvbbIrvsCvSc7E9virI2eLJr7wts= X-MS-TrafficTypeDiagnostic: VI1PR0501MB2608: X-LD-Processed: a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr X-Microsoft-Exchange-Diagnostics: 1; VI1PR0501MB2608; 20:ogR5B4b5TBtWDR3Db7XuE7JiPwAoZdihpXumcXHcRSsBH8k3V/DXJxxI4paoh/1npgw7b1X26zTGs/LzhKOgKGgvleZNAL++4Ww+1MW0u/yA+irT1Diz8zOzQFV8Hc+J2GFRJhtglv6yZdP8459G5KITomqtddthPDvV6u6n5lSXQ5C5/8IaAzL8W/CQ6Od/hPVJxb7kMU7wQ7f/hPmKYGLOnAOGjv+MHW6/AwkgKvpR9KUzPd+tJoSOJwPN4pkd5nJ6wytPj91OTNw0Ehs7jecCPiJOvMnM/O468Bty0pictD/AvnTmS70zilyO3mhLtpGz5jauP5M9cWywR1e0SifJIAdwjOOz+naxpvwP0o9YspTPL29K/3VTgpavQV9T73+1+CnRVFN/geGx1jOICVF/hjS3CoJNwKDppyUWcP91vgKOybfrwcTag542bOh9nQ1Y9pwszyoss7L/sUjvXAiPCXzyUv4eNAOV9wx7X0iVXmI7UhUaommgUsIBlwcK; 4:vmxnGjSk7+/EQsGwIgmVVDSr7GaZi5Zl555uT2e/SjBj0IwAjkbrxl78edfXvA3Rq5ZeSLOpu2lzPfAjlBCv7MIHkdAHXLiBrXdO3As8u5PS5avCg+/HHtV5zcFp6DwaaAHQnBUvLZB46B4DT3xsXLwjIuY+wlyARs5qUgCkpqXz45tbrcfX1CixFIqBrl4VuULVBsoMEz3T8jg0sJolIKNSmJRo1ItjUOqqgths6gW2jrzevYjvVsdL9mpnSrr9QTEw7Vy8JVix67VpdhX2xQ== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(3002001)(10201501046)(93006095)(93001095)(3231254)(944501410)(52105095)(6055026)(149027)(150027)(6041310)(20161123560045)(20161123558120)(20161123564045)(20161123562045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(6072148)(201708071742011); SRVR:VI1PR0501MB2608; BCL:0; PCL:0; RULEID:; SRVR:VI1PR0501MB2608; X-Forefront-PRVS: 067270ECAF X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(39380400002)(366004)(396003)(376002)(346002)(39860400002)(189003)(199004)(5660300001)(105586002)(4326008)(16586007)(106356001)(2906002)(6116002)(316002)(305945005)(59450400001)(52116002)(51416003)(7696005)(48376002)(33026002)(86362001)(69596002)(50226002)(3846002)(68736007)(50466002)(53936002)(55016002)(66066001)(26005)(8936002)(478600001)(81166006)(6306002)(36756003)(386003)(8676002)(25786009)(81156014)(47776003)(16526019)(956004)(2616005)(6916009)(476003)(6666003)(1857600001)(21086003)(97736004)(966005)(486006)(7736002)(186003); DIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR0501MB2608; H:mellanox.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; Received-SPF: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; VI1PR0501MB2608; 23:0p4PcXPgw9nkUe3bAVs7JCrjhsQSW2Xbbbsy+Mf?= ue00y/9S9sEbV2IiWb/5xP/4SEcjkAJFSapAwhvMYOt2v78/jvvkdH77sVIvBaybX/56UZ5ilwfyjcQAB4b4KIEpbpGArgokMVCGPuQhCGoqNnIMOUHFUdCwchvCqx2E+rtF+tfsd/V1yb9wu3tF1e/Dr/IDKmZlFsRLGdOeZbOFAk65mpokE+8g9r+41Sg3TZG89vhZNpUlxFAp0iUMOHqe+zeUcJ2rhOUa8cpDqX5LCQrV2QFMeAhU8/+maPas0raKG6zWHt2bymiC4U640NAB8jWkh7Fv/j0mKuElSbosWjwl9hYEXx1AYLAgIa5iXZFogmRcp/9LuHnDB72piPg/IuU9ryX7Wtj+3h1rP8CQgZhwehop9ilf+thpYJS274TJ0+slhjtYI2KTS6gri2jmr4tjOYG1aCLjr+mCDzJfhQgwQwcuEf+q2ngD/Vs4Cipdi9dJSJp17yry7qeIL3YEes7ZVdMvGmrQRvj4by5sILg+So0MJpHpbeyxzxjxE1kMBTwdozT1vboFXx9tbBpmx6p7SHD9KKQ1OStkLFhWCX10YA0qNPosbpr57BxOr955m0WmFFxr6qkPOstMCflJsm3Onexc4MHjVMjmPrmSZwti9hkQ1uyggZkw/uGesjD/VQFoToEclXwRTi/vpmdGii+0MrcZwSIPc2V23H6g3qUUpyScOffcWIRT3waoHljrp0BB6UQwO8+1B2VznAnmI0dJMq3ilTDRilAGE/4LXAkq0HJLq6WNhjo6jODxNRgs4IURZiM3gSuHU51es+dMzEqArc+4eTCO1YWpo57AhsQxNUWBdOAp+qHWXakiAXC3MYWZDurByDp/Se60qvhlZQRVh5jeGHXJGCRJHfSsW5Enmm6OdCQQZ5Ke70+FMIrsK7JJBROdFrRi/imJ1dBN0u5cznSdtbgd9omsFVpaaWLNmgs4IkSJ4IzRcgJEr2ZnpyFzAAksVxN8Qu1K76SIVkIAmLusOah25AZ2eri3hWFyf6Plnj1beMVenqIz58KPH+ORwIky6RBkA4OXJDhbs2ql3Xvqiv8bNf08qZIi194a/hyGhb4oqwWluBJZFFdemh8p5j77bGyV3lYk7cQnl+wGwU2zO6FlI+PBR8Go9GTDZkyC7+uZXoC4fTZnzqvFd6dx42bwJrMmk8gy/JcWAMuM4pdX9EvDmsflULnD3rwLrnlXKf/sl/yFJEo4Fwy8= X-Microsoft-Antispam-Message-Info: 7mPUGca6lqGsMVk6WKlM658acjXbgPj+Yp+0LSQ12I+EyEdxobnlNS0lXyuM2AHAphFgOLCUV2d6zzR9Tbaiuo4lSxtx2i8h4aCKWUY/Sjp7qEYtz+TEKx2NNS4C6iNxf9yHERiTc2lvZet6b42yaoN0hRF8tfxrHBR9HcFxnPtaD8CGSgJuNHOHvBHw6bRF X-Microsoft-Exchange-Diagnostics: 1; VI1PR0501MB2608; 6:BhRZ/L6zV3Xi7VmJDsgD21r93e8poosgYYX75/Z2ea0ppRWKYVEtzMmNOHOPxzSlkMObZFBqH3PlkDxqlO1duX9JZFpo65ZW2mD7gzmhE9R8+MX2jMRgsaZ2tsZf+r3DEwL7eFaMrbqLmZI4q1UAugS12VG4+Ncj5KWBO/wg0uzlHFhgZ1JX1mQX6AnO1yxi/Bea4AWj/BIsC/80urQfhqRfq8gGsrWZ/glob8IIvUlbQ8IGiXK8qtktdEZqiuAHxrxpuAmK7r/bSvH9SilrHnfJEa4J+f+LYWPgX9jOHcmD6tRjghr1GVCQCK5o4K5xcmLrgEPmCKRWb6jZUuox+CU3zSomnERRQeZQ47HZz334mC1gaXhuzd8O8OiFcbJrf/fPBtpj+JOBHLRGnrigcskrQp/6MLRErvDZlSedl/DyWe48UeftejhmOrIwDHAPEGx+NHHR3GleWB6cGiu6Qg==; 5:SlMZQK1YZ7fRBlDqQe0vgPiMWHTSRpzQiYvCRTUPAINBHqQmTR0yL9eWYJOqoEIFONC1n9YcDzM4xNgVfI7YZc20O/4URVQ4NFWEyUyPSR56sRhTLZv3TdjznO0FeO+ppPibav4wANpRSK64mI8ekQh450K6YmIBnMKhAK4PLR0=; 24:yz+jFz6Gh20vXGb4iVuzZoPmAZvGwUxMhumQZdxw8cwi9fe03b9pGAmThl7v9OKhyznbuor68ZGjwnNRh+5NZ/JPVYYi7PRaCmBLb74yIdA= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; VI1PR0501MB2608; 7:nJYIel8jK6bNCrJVeKl/TniDuoyue6M+ibfdt7hJt++G0cRS+2ezGNL2GgMbKDX29ZQ2dx25DcKRt9hpZFbe1rU8uvn9TjZEOiArZpilMeBNUdU+CFhgDOz/tlotskTe1qORlmTs3NZNhkcDd7p7t7vpS7YhzZBuvCqmfkuMoXiIoiiSmlQHy1fkHZfMJR/CEVkhUJ6Hw7IK1AeWMivg6FcDOgBn7o8URnU8Yej+nrzLYruMT5u/mLfBMLENgYsG X-MS-Office365-Filtering-Correlation-Id: 3c2d5ce2-9d1b-4d86-e72f-08d5b9a0682f X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 14 May 2018 13:41:33.1200 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 3c2d5ce2-9d1b-4d86-e72f-08d5b9a0682f X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0501MB2608 Subject: [dpdk-dev] [PATCH] net/mlx5: support MPLS-in-GRE and MPLS-in-UDP X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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 MPLS over GRE and MPLS over UDP tunnel types as described in the next RFCs: 1. https://tools.ietf.org/html/rfc4023 2. https://tools.ietf.org/html/rfc7510 3. https://tools.ietf.org/html/rfc4385 Signed-off-by: Matan Azrad --- doc/guides/nics/mlx5.rst | 4 +- drivers/net/mlx5/Makefile | 5 ++ drivers/net/mlx5/mlx5.c | 13 ++++ drivers/net/mlx5/mlx5.h | 1 + drivers/net/mlx5/mlx5_flow.c | 154 +++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 170 insertions(+), 7 deletions(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index a7d5c90..2b110f4 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -74,7 +74,7 @@ Features - RX interrupts. - Statistics query including Basic, Extended and per queue. - Rx HW timestamp. -- Tunnel types: VXLAN, L3 VXLAN, VXLAN-GPE, GRE. +- Tunnel types: VXLAN, L3 VXLAN, VXLAN-GPE, GRE, MPLSoGRE, MPLSoUDP. - Tunnel HW offloads: packet type, inner/outer RSS, IP and UDP checksum verification. Limitations @@ -113,6 +113,8 @@ Limitations - VXLAN TSO and checksum offloads are not supported on VM. +- L3 VXLAN and VXLAN-GPE tunnels cannot be supported together with MPLSoGRE and MPLSoUDP. + - VF: flow rules created on VF devices can only match traffic targeted at the configured MAC addresses (see ``rte_eth_dev_mac_addr_add()``). diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile index 8d64d4c..293144e 100644 --- a/drivers/net/mlx5/Makefile +++ b/drivers/net/mlx5/Makefile @@ -108,6 +108,11 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh enum MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS \ $(AUTOCONF_OUTPUT) $Q sh -- '$<' '$@' \ + HAVE_IBV_DEVICE_MPLS_SUPPORT \ + infiniband/verbs.h \ + enum IBV_FLOW_SPEC_MPLS \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ HAVE_IBV_WQ_FLAG_RX_END_PADDING \ infiniband/verbs.h \ enum IBV_WQ_FLAG_RX_END_PADDING \ diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 8aa91cc..225ebd4 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -690,6 +690,7 @@ unsigned int mps; unsigned int cqe_comp; unsigned int tunnel_en = 0; + unsigned int mpls_en = 0; unsigned int swp = 0; unsigned int verb_priorities = 0; unsigned int mprq = 0; @@ -850,6 +851,17 @@ DRV_LOG(WARNING, "tunnel offloading disabled due to old OFED/rdma-core version"); #endif +#ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT + mpls_en = ((attrs_out.tunnel_offloads_caps & + MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_GRE) && + (attrs_out.tunnel_offloads_caps & + MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_UDP)); + DRV_LOG(DEBUG, "MPLS over GRE/UDP tunnel offloading is %ssupported", + mpls_en ? "" : "not "); +#else + DRV_LOG(WARNING, "MPLS over GRE/UDP tunnel offloading disabled due to" + " old OFED/rdma-core version or firmware configuration"); +#endif err = mlx5_glue->query_device_ex(attr_ctx, NULL, &device_attr); if (err) { DEBUG("ibv_query_device_ex() failed"); @@ -873,6 +885,7 @@ .cqe_comp = cqe_comp, .mps = mps, .tunnel_en = tunnel_en, + .mpls_en = mpls_en, .tx_vec_en = 1, .rx_vec_en = 1, .mpw_hdr_dseg = 0, diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index c4c962b..7750832 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -93,6 +93,7 @@ struct mlx5_dev_config { unsigned int mps:2; /* Multi-packet send supported mode. */ unsigned int tunnel_en:1; /* Whether tunnel stateless offloads are supported. */ + unsigned int mpls_en:1; /* MPLS over GRE/UDP is enabled. */ unsigned int flow_counter_en:1; /* Whether flow counter is supported. */ unsigned int cqe_comp:1; /* CQE compression is enabled. */ unsigned int tso:1; /* Whether TSO is supported. */ diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index ec6d00f..432fde0 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -101,6 +101,11 @@ struct mlx5_flow_data { const void *default_mask, struct mlx5_flow_data *data); +static int +mlx5_flow_create_mpls(const struct rte_flow_item *item, + const void *default_mask, + struct mlx5_flow_data *data); + struct mlx5_flow_parse; static void @@ -248,12 +253,14 @@ struct rte_flow { #define IS_TUNNEL(type) ( \ (type) == RTE_FLOW_ITEM_TYPE_VXLAN || \ (type) == RTE_FLOW_ITEM_TYPE_VXLAN_GPE || \ - (type) == RTE_FLOW_ITEM_TYPE_GRE) + (type) == RTE_FLOW_ITEM_TYPE_GRE || \ + (type) == RTE_FLOW_ITEM_TYPE_MPLS) const uint32_t flow_ptype[] = { [RTE_FLOW_ITEM_TYPE_VXLAN] = RTE_PTYPE_TUNNEL_VXLAN, [RTE_FLOW_ITEM_TYPE_VXLAN_GPE] = RTE_PTYPE_TUNNEL_VXLAN_GPE, [RTE_FLOW_ITEM_TYPE_GRE] = RTE_PTYPE_TUNNEL_GRE, + [RTE_FLOW_ITEM_TYPE_MPLS] = RTE_PTYPE_TUNNEL_MPLS_IN_GRE, }; #define PTYPE_IDX(t) ((RTE_PTYPE_TUNNEL_MASK & (t)) >> 12) @@ -264,6 +271,10 @@ struct rte_flow { [PTYPE_IDX(RTE_PTYPE_TUNNEL_VXLAN_GPE)] = RTE_PTYPE_TUNNEL_VXLAN_GPE | RTE_PTYPE_L4_UDP, [PTYPE_IDX(RTE_PTYPE_TUNNEL_GRE)] = RTE_PTYPE_TUNNEL_GRE, + [PTYPE_IDX(RTE_PTYPE_TUNNEL_MPLS_IN_GRE)] = + RTE_PTYPE_TUNNEL_MPLS_IN_GRE, + [PTYPE_IDX(RTE_PTYPE_TUNNEL_MPLS_IN_UDP)] = + RTE_PTYPE_TUNNEL_MPLS_IN_GRE | RTE_PTYPE_L4_UDP, }; /** Structure to generate a simple graph of layers supported by the NIC. */ @@ -400,7 +411,8 @@ struct mlx5_flow_items { }, [RTE_FLOW_ITEM_TYPE_UDP] = { .items = ITEMS(RTE_FLOW_ITEM_TYPE_VXLAN, - RTE_FLOW_ITEM_TYPE_VXLAN_GPE), + RTE_FLOW_ITEM_TYPE_VXLAN_GPE, + RTE_FLOW_ITEM_TYPE_MPLS), .actions = valid_actions, .mask = &(const struct rte_flow_item_udp){ .hdr = { @@ -429,7 +441,8 @@ struct mlx5_flow_items { [RTE_FLOW_ITEM_TYPE_GRE] = { .items = ITEMS(RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_IPV6), + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_MPLS), .actions = valid_actions, .mask = &(const struct rte_flow_item_gre){ .protocol = -1, @@ -437,7 +450,26 @@ struct mlx5_flow_items { .default_mask = &rte_flow_item_gre_mask, .mask_sz = sizeof(struct rte_flow_item_gre), .convert = mlx5_flow_create_gre, +#ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT + .dst_sz = sizeof(struct ibv_flow_spec_gre), +#else .dst_sz = sizeof(struct ibv_flow_spec_tunnel), +#endif + }, + [RTE_FLOW_ITEM_TYPE_MPLS] = { + .items = ITEMS(RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_IPV6), + .actions = valid_actions, + .mask = &(const struct rte_flow_item_mpls){ + .label_tc_s = "\xff\xff\xf0", + }, + .default_mask = &rte_flow_item_mpls_mask, + .mask_sz = sizeof(struct rte_flow_item_mpls), + .convert = mlx5_flow_create_mpls, +#ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT + .dst_sz = sizeof(struct ibv_flow_spec_mpls), +#endif }, [RTE_FLOW_ITEM_TYPE_VXLAN] = { .items = ITEMS(RTE_FLOW_ITEM_TYPE_ETH, @@ -896,7 +928,9 @@ struct ibv_spec_header { if (ret) goto exit_item_not_supported; if (IS_TUNNEL(items->type)) { - if (parser->tunnel) { + if (parser->tunnel && + !((items - 1)->type == RTE_FLOW_ITEM_TYPE_GRE && + items->type == RTE_FLOW_ITEM_TYPE_MPLS)) { rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, items, @@ -904,6 +938,16 @@ struct ibv_spec_header { " tunnel encapsulations."); return -rte_errno; } + if (items->type == RTE_FLOW_ITEM_TYPE_MPLS && + !priv->config.mpls_en) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, + items, + "MPLS not supported or" + " disabled in firmware" + " configuration."); + return -rte_errno; + } if (!priv->config.tunnel_en && parser->rss_conf.level > 1) { rte_flow_error_set(error, ENOTSUP, @@ -1878,16 +1922,27 @@ struct ibv_spec_header { * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -mlx5_flow_create_gre(const struct rte_flow_item *item __rte_unused, - const void *default_mask __rte_unused, +mlx5_flow_create_gre(const struct rte_flow_item *item, + const void *default_mask, struct mlx5_flow_data *data) { struct mlx5_flow_parse *parser = data->parser; +#ifndef HAVE_IBV_DEVICE_MPLS_SUPPORT + (void)default_mask; unsigned int size = sizeof(struct ibv_flow_spec_tunnel); struct ibv_flow_spec_tunnel tunnel = { .type = parser->inner | IBV_FLOW_SPEC_VXLAN_TUNNEL, .size = size, }; +#else + const struct rte_flow_item_gre *spec = item->spec; + const struct rte_flow_item_gre *mask = item->mask; + unsigned int size = sizeof(struct ibv_flow_spec_gre); + struct ibv_flow_spec_gre tunnel = { + .type = parser->inner | IBV_FLOW_SPEC_GRE, + .size = size, + }; +#endif struct ibv_flow_spec_ipv4_ext *ipv4; struct ibv_flow_spec_ipv6 *ipv6; unsigned int i; @@ -1899,6 +1954,20 @@ struct ibv_spec_header { /* Default GRE to inner RSS. */ if (!parser->rss_conf.level) parser->rss_conf.level = 2; +#ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT + if (spec) { + if (!mask) + mask = default_mask; + tunnel.val.c_ks_res0_ver = spec->c_rsvd0_ver; + tunnel.val.protocol = spec->protocol; + tunnel.mask.c_ks_res0_ver = mask->c_rsvd0_ver; + tunnel.mask.protocol = mask->protocol; + /* Remove unwanted bits from values. */ + tunnel.val.c_ks_res0_ver &= tunnel.mask.c_ks_res0_ver; + tunnel.val.protocol &= tunnel.mask.protocol; + tunnel.val.key &= tunnel.mask.key; + } +#endif /* Update encapsulation IP layer protocol. */ for (i = 0; i != hash_rxq_init_n; ++i) { if (!parser->queue[i].ibv_attr) @@ -1932,6 +2001,79 @@ struct ibv_spec_header { } /** + * Convert MPLS item to Verbs specification. + * MPLS tunnel types currently supported are MPLS-in-GRE and MPLS-in-UDP. + * + * @param item[in] + * Item specification. + * @param default_mask[in] + * Default bit-masks to use when item->mask is not provided. + * @param data[in, out] + * User structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_flow_create_mpls(const struct rte_flow_item *item, + const void *default_mask, + struct mlx5_flow_data *data) +{ +#ifndef HAVE_IBV_DEVICE_MPLS_SUPPORT + (void)default_mask; + return rte_flow_error_set(data->error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "MPLS is not supported by driver"); +#else + const struct rte_flow_item_mpls *spec = item->spec; + const struct rte_flow_item_mpls *mask = item->mask; + struct mlx5_flow_parse *parser = data->parser; + unsigned int size = sizeof(struct ibv_flow_spec_mpls); + struct ibv_flow_spec_mpls mpls = { + .type = IBV_FLOW_SPEC_MPLS, + .size = size, + }; + + parser->inner = IBV_FLOW_SPEC_INNER; + if (parser->layer == HASH_RXQ_UDPV4 || + parser->layer == HASH_RXQ_UDPV6) { + parser->tunnel = + ptype_ext[PTYPE_IDX(RTE_PTYPE_TUNNEL_MPLS_IN_UDP)]; + parser->out_layer = parser->layer; + } else { + parser->tunnel = + ptype_ext[PTYPE_IDX(RTE_PTYPE_TUNNEL_MPLS_IN_GRE)]; + /* parser->out_layer stays as in GRE out_layer. */ + } + parser->layer = HASH_RXQ_TUNNEL; + /* + * For MPLS-in-GRE, RSS level should have been set. + * For MPLS-in-UDP, use outer RSS. + */ + if (!parser->rss_conf.level) + parser->rss_conf.level = 1; + if (spec) { + if (!mask) + mask = default_mask; + /* + * The verbs label field includes the entire MPLS header: + * bits 0:19 - label value field. + * bits 20:22 - traffic class field. + * bits 23 - bottom of stack bit. + * bits 24:31 - ttl field. + */ + mpls.val.label = *(const uint32_t *)spec; + mpls.mask.label = *(const uint32_t *)mask; + /* Remove unwanted bits from values. */ + mpls.val.label &= mpls.mask.label; + } + mlx5_flow_create_copy(parser, &mpls, size); + return 0; +#endif +} + +/** * Convert mark/flag action to Verbs specification. * * @param parser