From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR03-AM5-obe.outbound.protection.outlook.com (mail-eopbgr30077.outbound.protection.outlook.com [40.107.3.77]) by dpdk.org (Postfix) with ESMTP id 022A21B7A1 for ; Tue, 15 May 2018 13:07:39 +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=DfSOGgJm12Nuz/QrpG/3riVl+MZDhmBxau+7bi3LVoY=; b=RYNN4Jp4wOKRXWiD1+cDiA9H981DHh5haEH3h2Y/UofpWcbnV8/adYh6p8+5NAKx6YApBpXodvkmAEG50pztz/jZgRriJTgPnYEauiQ4mXaJ9jqeN25Yu/ZJ4bjQqLXHb66+sL5QI38ePPwqYi5GyZcNN14ySGz1XnyveEXYh04= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=matan@mellanox.com; Received: from mellanox.com (37.142.13.130) by HE1PR0501MB2604.eurprd05.prod.outlook.com (2603:10a6:3:6e::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.755.16; Tue, 15 May 2018 11:07:36 +0000 From: Matan Azrad To: Nelio Laranjeiro Cc: Shahaf Shuler , dev@dpdk.org Date: Tue, 15 May 2018 11:07:14 +0000 Message-Id: <1526382434-12092-1-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.9.5 In-Reply-To: <1526305280-23078-1-git-send-email-matan@mellanox.com> References: <1526305280-23078-1-git-send-email-matan@mellanox.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [37.142.13.130] X-ClientProxiedBy: VI1PR0502CA0007.eurprd05.prod.outlook.com (2603:10a6:803:1::20) To HE1PR0501MB2604.eurprd05.prod.outlook.com (2603:10a6:3:6e::19) 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:HE1PR0501MB2604; X-Microsoft-Exchange-Diagnostics: 1; HE1PR0501MB2604; 3:o2gryyjgM0/vp1NGbzk2gLVwIjuSspKHYufONFIv1IK+uslT+wbLJJQB0DPpr5yeAJvx9hxiyGmZSM9LZTE+DCeFxF7WltVJArYACcxpr5hcuPBqt2ADv4TFV+ZZi02b8wBRO5/1ogR1Y9FO49tu4dfi+oeF9UEAScCckvK45NJX2bT5fgWMQIW+9C0idO+ip6fg1rlyxufPtn1yNgln8tZQGuLMytQ1AO5u1PxqWXGGJePxgqht+ZVSSoiwR0Pl; 25:9VYCetEpNabYsanOEpSi2BYPHmCgJfMmDIWx28oQP+35aRugW2by5iwg8TzI0h+CIqZASzUkpGZMfiHDTTtuRKMvRHX4JC5/EjfK7AU5VswYRzTQe0PdvHNl6X2o5ANMn1k/HDRnWYSsKp3wOvQ5/4IrjDdoCahC11/j2l3IwfRmX5f8CAXheUaUbyW2AiG1IrGvsB/9Zn8iZZrOhEf07KlXJwgYDGHKxia4qCKVa3ffR1jT+v5ibLvYJutT8NqFRf1MqmokwKl7DC4qh3P79jvxQbFWBC7ABp1xUPK9zz4CkDPNNlRde+cpy8EwSFPlFe+W0FFls7sXC+Yb8pnHXQ==; 31:uHEqpt9XRPq98Y0SoFBsp9wFpSSsj6JqkE/0KkoW7rjYUTEFjT55c7/EONSREpueBc5HhV/muPz9zutv5rPdmL+Gi2XHXNXFU7H1yBSRtRS/5sfyTlu8hY7XIcJvumolDQK8nf7gQonb9TbLFm9hChwxFG0oq9DzmM7lYDyvEzfWh8t/2vqUurK5C6b8gJ5zyK6wyHXBEkkXNpsYsaW4DR9tJslQxjWs7fz4RuVsCH4= X-MS-TrafficTypeDiagnostic: HE1PR0501MB2604: X-LD-Processed: a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr X-Microsoft-Exchange-Diagnostics: 1; HE1PR0501MB2604; 20:Nm8QX2OcgBXElAfuxftHi9UAOmQYEpJy1X6hG6ynNcXy/kqpn8yAjFBgpyaqBZEAA82doYszq2kVibqJz0foroaew8nYz3GgvTV5RWeREEWPQjFeC+T7jd42iuDUKlAdsqp6psDVABinaS7OxFBUa1pQ9XypjsXOtP3/6XTw0t+3O/EKbARMEOySJXz/V6H4SXc+ZrIWrTqJrodXBvm9JaeGa6OEAYDaHmZtL1UWdfBLTovD8TTTPyUWQ2uFTDuXoocHtcmBC8f4TPORplDXWsMAHrEhYe2/TElmqr5T5R+EoPgwCMHLVk8uojRPJ6yvs111k1ASxhxeVC4ZUqb+N2lyfW9WczZ8sC4naFRxnuI1OFTBrnnGRAUXp3a9mBnuR6R47Peh09wbT3MqG3NEbu6FO6EvsDebJZE6fKG/s8y1ztiXqQt2RhRgV0lEui4ma+Nh9lZcL+POS2Sp1X2KVvg+Um0DLr8d7A1TyE6Fy8QuBcBmazfbDF0lRXeRN9Hr; 4:FMHgSYfZNOChC87npzgJCcVtcuqxWSccsJz/AdqUS5NSytZkGrPHazf1F41XPd81muAEAl919QuVnnfACL/S4bbiIp6iGjWH0Ss/xsTh6lXw8uuOwIyv4oOTTrQ9waq4pHkfdpUDHbkbexyALnUVjaBnutUM47aL+caQw4vcpOEM5bOgPn5BDWYOw31h8tYJJwMEwpCJ5VkyU2wSGXtUNrSju50c9/zZEXZAImGasBd4N/7yfdEABub9PryqvemwsyYEwbu1Dybnf+o+uQPrQg== 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)(5005006)(8121501046)(3231254)(944501410)(52105095)(93006095)(93001095)(3002001)(10201501046)(6055026)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(20161123562045)(20161123558120)(20161123560045)(6072148)(201708071742011); SRVR:HE1PR0501MB2604; BCL:0; PCL:0; RULEID:; SRVR:HE1PR0501MB2604; X-Forefront-PRVS: 0673F5BE31 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(376002)(346002)(366004)(39380400002)(396003)(39860400002)(189003)(199004)(51416003)(7696005)(86362001)(4326008)(59450400001)(52116002)(69596002)(966005)(16526019)(6666003)(6916009)(186003)(26005)(47776003)(68736007)(386003)(97736004)(21086003)(11346002)(446003)(76176011)(6306002)(53936002)(476003)(55016002)(6116002)(3846002)(36756003)(305945005)(2906002)(486006)(66066001)(50466002)(956004)(316002)(2616005)(81156014)(81166006)(8936002)(5660300001)(7736002)(50226002)(478600001)(16586007)(25786009)(8676002)(48376002)(33026002)(106356001)(105586002); DIR:OUT; SFP:1101; SCL:1; SRVR:HE1PR0501MB2604; 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; HE1PR0501MB2604; 23:fUDAoSHdFyzm0vsAWGQn7hvTn40jW2L2VvqekY5?= =?us-ascii?Q?8Rd8qIpVgUBkt4KAvJZ/r2gvtvOXuWjFL36f5KWGVAGX1pGoJv8haikITbtb?= =?us-ascii?Q?Mj/UnnOXKCTyOgZiAyWrEx5bbuuU9lwodDYA/c7MQKTXE2HhhW+VYineZUsk?= =?us-ascii?Q?gCVi7hXXPVGb/E8w0zxlwgUJGIO2HLD5JQ/U0sIVij/Jm/7jW1TwVStb61+V?= =?us-ascii?Q?l+d5L6nqIFpKxgvPqtmhViARKW2ALf1vGvYrZd6AQOG8LtpqNXS6tMhyTRFQ?= =?us-ascii?Q?0j0hwDtbiyWiEm8/i1l8ckJBVpZCs6/0vZO8eZsm4VpWZ+9aUo9nDpsQ4jAQ?= =?us-ascii?Q?6igyg78dlop8xDXW8qjh04RlWi4ljLNwlmfa407NXr0tiER074OwHWLi0Khu?= =?us-ascii?Q?i58DE9L3ZShLfGwkcoTrt17QJlXW+4UR2SedCITz9Wk9+Fgj5EBZ+2y39Qru?= =?us-ascii?Q?Hg/5WTKV4gh3BjNp4ZkriTMYKPQvPwGYqeMGIL/NirtAyZ3Zkd0n3Z009Vz8?= =?us-ascii?Q?1kRpns7Cn7ZtY37LJ6Dz5aLQ7hdjaQaXJGvadBmkTKVez66N4/a4YG/SXiMX?= =?us-ascii?Q?I0p5Byn87K6vNzRe8dpzRgRdlLdP24BVA8+OV1fUft7leID62sCOy5C8mgM7?= =?us-ascii?Q?tuZJYZ/zxhavmFAt5xO/lgXKRRreOEk2kCclRB8LOSxWowaqXfpeVHwe8mfr?= =?us-ascii?Q?f2mj0DWrK54UA/6kEiYwgKHi6P2VOJHZTJ3wUgLtt6EhoNlyNbq0UU+ngUOK?= =?us-ascii?Q?nEbYM2fFLJC4XfCqA5jYmWq84SYd5E32+SzAHpxjCFQclMeJwsPZE0DjbQx/?= =?us-ascii?Q?AxEjjKjf6C6/lKO1BgYBziECXXU4OirarZ22mZmtBGGrTP16XfJwWhjNJKfi?= =?us-ascii?Q?jFu4g4mhrlCHInkl6b8H1JmXJoDn0jzvMvCrqFIKkJx19QDihAs0tns2s2mx?= =?us-ascii?Q?matpsg6msBK1wjy1at3Ps+ModcoFq/y7iSzh8cDlk+6D0EqPOBF8fVdlOd21?= =?us-ascii?Q?E2obsATyazGP70Edd8Xzpn3SL9cqez3dNLoCkM5hJdDtEGR9WzGmopoXD3lF?= =?us-ascii?Q?cUtmEZElsPkjpyCIMLszC5mkS77laCV8KMCwSd3EXcZTseD3VgSIrIMLeE4q?= =?us-ascii?Q?MLm7a+TqgkyXcjyL988BklAa1Wj3YD2f234hf+wQHB+2MsNVuBZYbOWY22lx?= =?us-ascii?Q?M709iaadPTII7DQD/dHYjLtzRHdZPwTK+440j8G/MdWOff6DC/+HS3X6puJF?= =?us-ascii?Q?Tf/aL9elh1+r2rF6mBERlNa8iZo/7C/eN5OJ5S3LN84O9Ksh8MChxK/c25dY?= =?us-ascii?Q?FLg=3D=3D?= X-Microsoft-Antispam-Message-Info: JNvtk/pX258L2F2acDOOdz9l8q76ExtxNtBioXFTfsY5K7dQTR6fuZXfoaaSPzICFmrqwihi/wH8UUbxoA6lj51utQjNrgMb/irCylf3oKcXBh2aKU60eE30AmyWTzvG26IYh5reYDD1yPI027Z0+tTkEWjb1ZqiZPPY7sDbvX9sXf/MC/rwY5/KPPzDQ7sK X-Microsoft-Exchange-Diagnostics: 1; HE1PR0501MB2604; 6:fEh3/Ts0CPzBJYWZnJTWfVZSLRUCqq0s4pV6EiBX86PlZ7KMJJZjM7WYi+HxATd3W8TwQyysWET05gsV8XTsfUsXcHIAOBYnYbAhdQpWzwkdn5nETCns7ZTD0gh+4UemwVsNwWD2lIwl2TSDVqPGDDyQJRxfaCFH8uX4LLqz8Mt6r9jdr1ORTlAf9GbYlIt87pVHzIS50TvNR4pzi2pntbnW2T/g1NjKqMLwGGJ9n2/dV/Kpzld1PaPgftf5CZ90RrnJllQir27K80RdmZwVlwxmrglSnEhGrJX7HtCTvNO5f/Qjy0j4b2htkKwOwZ96Xwkjnq/2+U+EkL+waoZUR/s0LwRzssRB5iGYlq0hwe+t0uF3N8Hgu3bF06tIuxUOX2HsSLN4P1TnhNdJwbtdiu58mLTRP3EiYEm4KaokGFnYu2NKBrE3FXCUeC1N91WS3oIHKgJBx4JIJc8t1aboBQ==; 5:7+S1OGcHsDkWk99m3/cLAVIP32o/FEgNAa+3MxKcvkfB/3a1EjEeC+bL7Fo/zIzMJjqxx0TXkwZZfA7JE5u5ib9zAlDjAlakxSZtJFhjfBeN2VYAM25XBP9N2ZfaNwBPHwsYDZjBKntO/J+4j4QvVM69vyAHlkNmBbRotp8GOGk=; 24:Uz9B7Bv0LpC2HYiUGD50n+jilusn9qkr5ImmMGIk7EE5HH8OYex09z37ITGzL4Zoi4zwQIr7XzKT2dN3MUY0dlx4CA95T4PA4eHCgRPGPFk= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; HE1PR0501MB2604; 7:tdY5neBxiKSABTFFvmPoTO81qA5ZwcWau7td1ebkycyrUGEbzjkM20SFQGFmaeJLHtyVY+GuF1Qfq6FPAvbC3NzY7bPnJS1dXkzi6r7QVfni4JoQHUjjkJvurB+dVsN0kgt/7vtwcffMJyNNLdTv2dDWVBe59Npg68t8HCdgpqGKzGFbcjiw+Teq2arIRFoNHFNqdAprb5b7LLmd9wbtlNr61MKO7eeABhUjpX+LeD38gAN0nHmQvIlWpd9PNwMN X-MS-Office365-Filtering-Correlation-Id: ce4e66e8-1cc8-4ebd-0ec4-08d5ba541176 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 May 2018 11:07:36.8418 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ce4e66e8-1cc8-4ebd-0ec4-08d5ba541176 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: HE1PR0501MB2604 Subject: [dpdk-dev] [PATCH v2] 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: , X-List-Received-Date: Tue, 15 May 2018 11:07:39 -0000 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 | 161 +++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 176 insertions(+), 8 deletions(-) V2: Ignore void items between GRE and MPLS tunnels (Nelio suggestion). 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 7af1dfa..3af9524 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, @@ -865,6 +897,7 @@ struct ibv_spec_header { struct priv *priv = dev->data->dev_private; const struct mlx5_flow_items *cur_item = mlx5_flow_items; unsigned int i; + unsigned int last_voids = 0; int ret = 0; /* Initialise the offsets to start after verbs attribute. */ @@ -874,8 +907,10 @@ struct ibv_spec_header { const struct mlx5_flow_items *token = NULL; unsigned int n; - if (items->type == RTE_FLOW_ITEM_TYPE_VOID) + if (items->type == RTE_FLOW_ITEM_TYPE_VOID) { + last_voids++; continue; + } for (i = 0; cur_item->items && cur_item->items[i] != RTE_FLOW_ITEM_TYPE_END; @@ -896,7 +931,10 @@ struct ibv_spec_header { if (ret) goto exit_item_not_supported; if (IS_TUNNEL(items->type)) { - if (parser->tunnel) { + if (parser->tunnel && + !((items - last_voids - 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 +942,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, @@ -921,6 +969,7 @@ struct ibv_spec_header { for (n = 0; n != hash_rxq_init_n; ++n) parser->queue[n].offset += cur_item->dst_sz; } + last_voids = 0; } if (parser->drop) { parser->queue[HASH_RXQ_ETH].offset += @@ -1878,16 +1927,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 +1959,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 +2006,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 -- 1.9.5