From patchwork Wed Mar 17 06:35:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1454464 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F0gQz3WBhz9sVm for ; Wed, 17 Mar 2021 17:36:11 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 297FE432C2; Wed, 17 Mar 2021 06:36:08 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 11lNWy3Bvhms; Wed, 17 Mar 2021 06:36:06 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTP id B990F4329F; Wed, 17 Mar 2021 06:36:03 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6FBD2C002F; Wed, 17 Mar 2021 06:35:58 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 594FDC0019 for ; Wed, 17 Mar 2021 06:35:50 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id DADBD431EF for ; Wed, 17 Mar 2021 06:35:48 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zLSyNfL_70lP for ; Wed, 17 Mar 2021 06:35:45 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp2.osuosl.org (Postfix) with ESMTP id A27264304F for ; Wed, 17 Mar 2021 06:35:44 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 17 Mar 2021 08:35:41 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 12H6ZfYi031345; Wed, 17 Mar 2021 08:35:41 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 17 Mar 2021 06:35:25 +0000 Message-Id: <20210317063538.12451-2-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210317063538.12451-1-elibr@nvidia.com> References: <20210317063538.12451-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH V4 01/14] netdev-offload: Add HW miss packet state recover API X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" When the HW offload involves multiple flows, like in tunnel decap path, it is possible that not all flows in the path are offloaded, resulting in partial processing in HW. In order to proceed with rest of the processing in SW, the packet state has to be recovered as if it was processed in SW from the beginning. In the case of tunnel decap, potential state to recover could be the outer tunneling layer to metadata. Add an API for that. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/netdev-offload-provider.h | 5 +++++ lib/netdev-offload.c | 12 ++++++++++++ lib/netdev-offload.h | 1 + 3 files changed, 18 insertions(+) diff --git a/lib/netdev-offload-provider.h b/lib/netdev-offload-provider.h index cf859d1b4..f24c7dd19 100644 --- a/lib/netdev-offload-provider.h +++ b/lib/netdev-offload-provider.h @@ -87,6 +87,11 @@ struct netdev_flow_api { * Return 0 if successful, otherwise returns a positive errno value. */ int (*flow_get_n_flows)(struct netdev *, uint64_t *n_flows); + /* Recover the packet state (contents and data) for continued processing + * in software. + * Return 0 if successful, otherwise returns a positive errno value. */ + int (*hw_miss_packet_recover)(struct netdev *, struct dp_packet *); + /* Initializies the netdev flow api. * Return 0 if successful, otherwise returns a positive errno value. */ int (*init_flow_api)(struct netdev *); diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c index 6237667c3..e5d24651f 100644 --- a/lib/netdev-offload.c +++ b/lib/netdev-offload.c @@ -253,6 +253,18 @@ netdev_flow_put(struct netdev *netdev, struct match *match, : EOPNOTSUPP; } +int +netdev_hw_miss_packet_recover(struct netdev *netdev, + struct dp_packet *packet) +{ + const struct netdev_flow_api *flow_api = + ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api); + + return (flow_api && flow_api->hw_miss_packet_recover) + ? flow_api->hw_miss_packet_recover(netdev, packet) + : EOPNOTSUPP; +} + int netdev_flow_get(struct netdev *netdev, struct match *match, struct nlattr **actions, const ovs_u128 *ufid, diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h index 18b48790f..b063c43a3 100644 --- a/lib/netdev-offload.h +++ b/lib/netdev-offload.h @@ -89,6 +89,7 @@ bool netdev_flow_dump_next(struct netdev_flow_dump *, struct match *, int netdev_flow_put(struct netdev *, struct match *, struct nlattr *actions, size_t actions_len, const ovs_u128 *, struct offload_info *, struct dpif_flow_stats *); +int netdev_hw_miss_packet_recover(struct netdev *, struct dp_packet *); int netdev_flow_get(struct netdev *, struct match *, struct nlattr **actions, const ovs_u128 *, struct dpif_flow_stats *, struct dpif_flow_attrs *, struct ofpbuf *wbuffer); From patchwork Wed Mar 17 06:35:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1454467 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F0gR96Jhcz9sVm for ; Wed, 17 Mar 2021 17:36:21 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id D8ABC4EDDC; Wed, 17 Mar 2021 06:36:19 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ofFeIg5-bXlB; Wed, 17 Mar 2021 06:36:16 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp4.osuosl.org (Postfix) with ESMTP id 04A0D4EDB0; Wed, 17 Mar 2021 06:36:07 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id DE05DC0010; Wed, 17 Mar 2021 06:36:00 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 529DBC001B for ; Wed, 17 Mar 2021 06:35:51 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 01FB14304F for ; Wed, 17 Mar 2021 06:35:49 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id vH4PT-cxHNiQ for ; Wed, 17 Mar 2021 06:35:45 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp2.osuosl.org (Postfix) with ESMTP id A5A91431EA for ; Wed, 17 Mar 2021 06:35:44 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 17 Mar 2021 08:35:41 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 12H6ZfYj031345; Wed, 17 Mar 2021 08:35:41 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 17 Mar 2021 06:35:26 +0000 Message-Id: <20210317063538.12451-3-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210317063538.12451-1-elibr@nvidia.com> References: <20210317063538.12451-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH V4 02/14] netdev-dpdk: Introduce DPDK tunnel APIs X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" As a pre-step towards tunnel offloads, introduce DPDK APIs. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/netdev-dpdk.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++ lib/netdev-dpdk.h | 106 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 212 insertions(+), 6 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 9d8096668..aa8716fb3 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -5291,6 +5291,118 @@ netdev_dpdk_rte_flow_query_count(struct netdev *netdev, return ret; } +#ifdef ALLOW_EXPERIMENTAL_API + +int +netdev_dpdk_rte_flow_tunnel_decap_set(struct netdev *netdev, + struct rte_flow_tunnel *tunnel, + struct rte_flow_action **actions, + uint32_t *num_of_actions, + struct rte_flow_error *error) +{ + struct netdev_dpdk *dev; + int ret; + + if (!is_dpdk_class(netdev->netdev_class)) { + return -1; + } + + dev = netdev_dpdk_cast(netdev); + ovs_mutex_lock(&dev->mutex); + ret = rte_flow_tunnel_decap_set(dev->port_id, tunnel, actions, + num_of_actions, error); + ovs_mutex_unlock(&dev->mutex); + return ret; +} + +int +netdev_dpdk_rte_flow_tunnel_match(struct netdev *netdev, + struct rte_flow_tunnel *tunnel, + struct rte_flow_item **items, + uint32_t *num_of_items, + struct rte_flow_error *error) +{ + struct netdev_dpdk *dev; + int ret; + + if (!is_dpdk_class(netdev->netdev_class)) { + return -1; + } + + dev = netdev_dpdk_cast(netdev); + ovs_mutex_lock(&dev->mutex); + ret = rte_flow_tunnel_match(dev->port_id, tunnel, items, num_of_items, + error); + ovs_mutex_unlock(&dev->mutex); + return ret; +} + +int +netdev_dpdk_rte_flow_get_restore_info(struct netdev *netdev, + struct dp_packet *p, + struct rte_flow_restore_info *info, + struct rte_flow_error *error) +{ + struct rte_mbuf *m = (struct rte_mbuf *) p; + struct netdev_dpdk *dev; + int ret; + + if (!is_dpdk_class(netdev->netdev_class)) { + return -1; + } + + dev = netdev_dpdk_cast(netdev); + ovs_mutex_lock(&dev->mutex); + ret = rte_flow_get_restore_info(dev->port_id, m, info, error); + ovs_mutex_unlock(&dev->mutex); + return ret; +} + +int +netdev_dpdk_rte_flow_tunnel_action_decap_release + (struct netdev *netdev, + struct rte_flow_action *actions, + uint32_t num_of_actions, + struct rte_flow_error *error) +{ + struct netdev_dpdk *dev; + int ret; + + if (!is_dpdk_class(netdev->netdev_class)) { + return -1; + } + + dev = netdev_dpdk_cast(netdev); + ovs_mutex_lock(&dev->mutex); + ret = rte_flow_tunnel_action_decap_release(dev->port_id, actions, + num_of_actions, error); + ovs_mutex_unlock(&dev->mutex); + return ret; +} + +int +netdev_dpdk_rte_flow_tunnel_item_release(struct netdev *netdev, + struct rte_flow_item *items, + uint32_t num_of_items, + struct rte_flow_error *error) +{ + struct netdev_dpdk *dev; + int ret; + + if (!is_dpdk_class(netdev->netdev_class)) { + return -1; + } + + dev = netdev_dpdk_cast(netdev); + ovs_mutex_lock(&dev->mutex); + ret = rte_flow_tunnel_item_release(dev->port_id, items, num_of_items, + error); + ovs_mutex_unlock(&dev->mutex); + return ret; +} + +#endif /* ALLOW_EXPERIMENTAL_API */ + #define NETDEV_DPDK_CLASS_COMMON \ .is_pmd = true, \ .alloc = netdev_dpdk_alloc, \ diff --git a/lib/netdev-dpdk.h b/lib/netdev-dpdk.h index 848346cb4..3b9bf8681 100644 --- a/lib/netdev-dpdk.h +++ b/lib/netdev-dpdk.h @@ -26,12 +26,7 @@ struct netdev; #ifdef DPDK_NETDEV -struct rte_flow; -struct rte_flow_error; -struct rte_flow_attr; -struct rte_flow_item; -struct rte_flow_action; -struct rte_flow_query_count; +#include void netdev_dpdk_register(void); void free_dpdk_buf(struct dp_packet *); @@ -56,6 +51,105 @@ netdev_dpdk_rte_flow_query_count(struct netdev *netdev, int netdev_dpdk_get_port_id(struct netdev *netdev); +#ifdef ALLOW_EXPERIMENTAL_API + +int +netdev_dpdk_rte_flow_tunnel_decap_set(struct netdev *, + struct rte_flow_tunnel *, + struct rte_flow_action **, + uint32_t *, + struct rte_flow_error *); +int +netdev_dpdk_rte_flow_tunnel_match(struct netdev *, + struct rte_flow_tunnel *, + struct rte_flow_item **, + uint32_t *, + struct rte_flow_error *); +int +netdev_dpdk_rte_flow_get_restore_info(struct netdev *, + struct dp_packet *, + struct rte_flow_restore_info *, + struct rte_flow_error *); +int +netdev_dpdk_rte_flow_tunnel_action_decap_release(struct netdev *, + struct rte_flow_action *, + uint32_t, + struct rte_flow_error *); +int +netdev_dpdk_rte_flow_tunnel_item_release(struct netdev *, + struct rte_flow_item *, + uint32_t, + struct rte_flow_error *); + +#else + +static inline void +set_error(struct rte_flow_error *error, enum rte_flow_error_type type) +{ + error->type = type; + error->cause = NULL; + error->message = NULL; +} + +static inline int +netdev_dpdk_rte_flow_tunnel_decap_set(struct netdev *netdev OVS_UNUSED, + struct rte_flow_tunnel *tunnel, + struct rte_flow_action **actions, + uint32_t *num_of_actions OVS_UNUSED, + struct rte_flow_error *error) +{ + (void) tunnel; + (void) actions; + set_error(error, RTE_FLOW_ERROR_TYPE_ACTION); + return -1; +} + +static inline int +netdev_dpdk_rte_flow_tunnel_match(struct netdev *netdev OVS_UNUSED, + struct rte_flow_tunnel *tunnel OVS_UNUSED, + struct rte_flow_item **items OVS_UNUSED, + uint32_t *num_of_items OVS_UNUSED, + struct rte_flow_error *error) +{ + set_error(error, RTE_FLOW_ERROR_TYPE_ITEM); + return -1; +} + +static inline int +netdev_dpdk_rte_flow_get_restore_info(struct netdev *netdev OVS_UNUSED, + struct dp_packet *p OVS_UNUSED, + struct rte_flow_restore_info *info, + struct rte_flow_error *error) +{ + (void) info; + set_error(error, RTE_FLOW_ERROR_TYPE_ATTR); + return -1; +} + +static inline int +netdev_dpdk_rte_flow_tunnel_action_decap_release + (struct netdev *netdev OVS_UNUSED, + struct rte_flow_action *actions OVS_UNUSED, + uint32_t num_of_actions OVS_UNUSED, + struct rte_flow_error *error) +{ + set_error(error, RTE_FLOW_ERROR_TYPE_NONE); + return 0; +} + +static inline int +netdev_dpdk_rte_flow_tunnel_item_release(struct netdev *netdev OVS_UNUSED, + struct rte_flow_item *items, + uint32_t num_of_items OVS_UNUSED, + struct rte_flow_error *error) +{ + (void) items; + set_error(error, RTE_FLOW_ERROR_TYPE_NONE); + return 0; +} + +#endif /* ALLOW_EXPERIMENTAL_API */ + #else static inline void From patchwork Wed Mar 17 06:35:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1454456 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F0gQj3Z0Rz9sVm for ; Wed, 17 Mar 2021 17:35:57 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 1187543208; Wed, 17 Mar 2021 06:35:54 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6Cn2cMf8hh5M; Wed, 17 Mar 2021 06:35:52 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTP id 86FF9431F0; Wed, 17 Mar 2021 06:35:51 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 37DBCC0014; Wed, 17 Mar 2021 06:35:50 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 1D4D9C000C for ; Wed, 17 Mar 2021 06:35:48 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id EC72883F11 for ; Wed, 17 Mar 2021 06:35:47 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id WkFgbMjT_E_V for ; Wed, 17 Mar 2021 06:35:45 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp1.osuosl.org (Postfix) with ESMTP id A4B45827A9 for ; Wed, 17 Mar 2021 06:35:44 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 17 Mar 2021 08:35:42 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 12H6ZfYk031345; Wed, 17 Mar 2021 08:35:41 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 17 Mar 2021 06:35:27 +0000 Message-Id: <20210317063538.12451-4-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210317063538.12451-1-elibr@nvidia.com> References: <20210317063538.12451-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH V4 03/14] netdev-offload: Introduce an API to traverse ports X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Introduce an API to traverse the ports added to the offload ports map, with a generic callback for each one. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/netdev-offload.c | 18 ++++++++++++++++++ lib/netdev-offload.h | 8 ++++++++ 2 files changed, 26 insertions(+) diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c index e5d24651f..10f543018 100644 --- a/lib/netdev-offload.c +++ b/lib/netdev-offload.c @@ -458,6 +458,24 @@ netdev_ports_flow_flush(const char *dpif_type) ovs_rwlock_unlock(&netdev_hmap_rwlock); } +void +netdev_ports_traverse(const char *dpif_type, + bool (*cb)(struct netdev *, odp_port_t, void *), + void *aux) +{ + struct port_to_netdev_data *data; + + ovs_rwlock_rdlock(&netdev_hmap_rwlock); + HMAP_FOR_EACH (data, portno_node, &port_to_netdev) { + if (netdev_get_dpif_type(data->netdev) == dpif_type) { + if (cb(data->netdev, data->dpif_port.port_no, aux)) { + break; + } + } + } + ovs_rwlock_unlock(&netdev_hmap_rwlock); +} + struct netdev_flow_dump ** netdev_ports_flow_dump_create(const char *dpif_type, int *ports, bool terse) { diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h index b063c43a3..5bf89f891 100644 --- a/lib/netdev-offload.h +++ b/lib/netdev-offload.h @@ -113,6 +113,14 @@ struct netdev *netdev_ports_get(odp_port_t port, const char *dpif_type); int netdev_ports_remove(odp_port_t port, const char *dpif_type); odp_port_t netdev_ifindex_to_odp_port(int ifindex); +/* For each of the ports with dpif_type, call cb with the netdev and port + * number of the port, and an opaque user argument. + * The returned value is used to continue traversing upon false or stop if + * true. + */ +void netdev_ports_traverse(const char *dpif_type, + bool (*cb)(struct netdev *, odp_port_t, void *), + void *aux); struct netdev_flow_dump **netdev_ports_flow_dump_create( const char *dpif_type, int *ports, From patchwork Wed Mar 17 06:35:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1454468 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F0gRF3BC5z9sVm for ; Wed, 17 Mar 2021 17:36:25 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 1D40B6FB03; Wed, 17 Mar 2021 06:36:22 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id dS4N4oechhKX; Wed, 17 Mar 2021 06:36:21 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp3.osuosl.org (Postfix) with ESMTP id CDC196F98D; Wed, 17 Mar 2021 06:36:08 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id C2FFAC0024; Wed, 17 Mar 2021 06:36:01 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 43DC1C0019 for ; Wed, 17 Mar 2021 06:35:51 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 5E13E83F11 for ; Wed, 17 Mar 2021 06:35:49 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id EICcYa5nAGQu for ; Wed, 17 Mar 2021 06:35:46 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp1.osuosl.org (Postfix) with ESMTP id A4BA18379C for ; Wed, 17 Mar 2021 06:35:44 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 17 Mar 2021 08:35:42 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 12H6ZfYl031345; Wed, 17 Mar 2021 08:35:42 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 17 Mar 2021 06:35:28 +0000 Message-Id: <20210317063538.12451-5-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210317063538.12451-1-elibr@nvidia.com> References: <20210317063538.12451-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH V4 04/14] netdev-dpdk: Add flow_api support for netdev vxlan vports X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Add the acceptance of vxlan devices to netdev_dpdk_flow_api_supported() API, to allow offloading of DPDK vxlan devices. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/netdev-dpdk.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index aa8716fb3..6e35d0574 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -5216,6 +5216,12 @@ netdev_dpdk_flow_api_supported(struct netdev *netdev) struct netdev_dpdk *dev; bool ret = false; + if (!strcmp(netdev_get_type(netdev), "vxlan") && + !strcmp(netdev_get_dpif_type(netdev), "netdev")) { + ret = true; + goto out; + } + if (!is_dpdk_class(netdev->netdev_class)) { goto out; } From patchwork Wed Mar 17 06:35:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1454460 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F0gQs3NPjz9sVm for ; Wed, 17 Mar 2021 17:36:05 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id CDE0B6F980; Wed, 17 Mar 2021 06:36:02 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id x49JlTH6fp_Y; Wed, 17 Mar 2021 06:35:58 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp3.osuosl.org (Postfix) with ESMTP id 0F5CD6F83A; Wed, 17 Mar 2021 06:35:57 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 31FE6C001F; Wed, 17 Mar 2021 06:35:54 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 4C557C0013 for ; Wed, 17 Mar 2021 06:35:49 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 0E3B86F6C6 for ; Wed, 17 Mar 2021 06:35:48 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id QC50YvOTaBGD for ; Wed, 17 Mar 2021 06:35:47 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp3.osuosl.org (Postfix) with ESMTP id B32036F6CD for ; Wed, 17 Mar 2021 06:35:44 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 17 Mar 2021 08:35:42 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 12H6ZfYm031345; Wed, 17 Mar 2021 08:35:42 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 17 Mar 2021 06:35:29 +0000 Message-Id: <20210317063538.12451-6-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210317063538.12451-1-elibr@nvidia.com> References: <20210317063538.12451-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH V4 05/14] netdev-offload-dpdk: Implement HW miss packet recover for vport X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" A miss in virtual port offloads means the flow with tnl_pop was offloaded, but not the following one. Recover the state and continue with SW processing. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/netdev-offload-dpdk.c | 150 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index f2413f5be..c78089605 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -1588,6 +1588,155 @@ netdev_offload_dpdk_flow_flush(struct netdev *netdev) return 0; } +struct get_vport_netdev_aux { + struct rte_flow_tunnel *tunnel; + odp_port_t *odp_port; + struct netdev *vport; +}; + +static bool +get_vxlan_netdev_cb(struct netdev *netdev, + odp_port_t odp_port, + void *aux_) +{ + const struct netdev_tunnel_config *tnl_cfg; + struct get_vport_netdev_aux *aux = aux_; + + if (strcmp(netdev_get_type(netdev), "vxlan")) { + return false; + } + + tnl_cfg = netdev_get_tunnel_config(netdev); + if (!tnl_cfg) { + VLOG_ERR_RL(&rl, "Cannot get a tunnel config for netdev %s", + netdev_get_name(netdev)); + return false; + } + + if (tnl_cfg->dst_port == aux->tunnel->tp_dst) { + /* Found the netdev. Store the results and stop the traversing. */ + aux->vport = netdev_ref(netdev); + *aux->odp_port = odp_port; + return true; + } + + return false; +} + +static struct netdev * +get_vxlan_netdev(const char *dpif_type, + struct rte_flow_tunnel *tunnel, + odp_port_t *odp_port) +{ + struct get_vport_netdev_aux aux = { + .tunnel = tunnel, + .odp_port = odp_port, + .vport = NULL, + }; + + netdev_ports_traverse(dpif_type, get_vxlan_netdev_cb, &aux); + return aux.vport; +} + +static struct netdev * +get_vport_netdev(const char *dpif_type, + struct rte_flow_tunnel *tunnel, + odp_port_t *odp_port) +{ + if (tunnel->type == RTE_FLOW_ITEM_TYPE_VXLAN) { + return get_vxlan_netdev(dpif_type, tunnel, odp_port); + } + + OVS_NOT_REACHED(); +} + +static int +netdev_offload_dpdk_hw_miss_packet_recover(struct netdev *netdev, + struct dp_packet *packet) +{ + struct rte_flow_restore_info rte_restore_info; + struct rte_flow_tunnel *rte_tnl; + struct netdev *vport_netdev; + struct rte_flow_error error; + struct pkt_metadata *md; + struct flow_tnl *md_tnl; + odp_port_t vport_odp; + int ret = 0; + + if (netdev_dpdk_rte_flow_get_restore_info(netdev, packet, + &rte_restore_info, &error)) { + /* This function is called for every packet, and in most cases there + * will be no restore info from the HW, thus error is expected. + */ + (void) error; + return 0; + } + + if (!(rte_restore_info.flags & RTE_FLOW_RESTORE_INFO_TUNNEL)) { + return EOPNOTSUPP; + } + + rte_tnl = &rte_restore_info.tunnel; + vport_netdev = get_vport_netdev(netdev->dpif_type, rte_tnl, + &vport_odp); + if (!vport_netdev) { + VLOG_WARN("Could not find vport netdev"); + return EOPNOTSUPP; + } + + md = &packet->md; + /* For tunnel recovery (RTE_FLOW_RESTORE_INFO_TUNNEL), it is possible + * to have the packet to still be encapsulated, or not + * (RTE_FLOW_RESTORE_INFO_ENCAPSULATED). + * In the case it is on, the packet is still encapsulated, and we do + * the pop in SW. + * In the case it is off, the packet is already decapsulated by HW, and + * the tunnel info is provided in the tunnel struct. For this case we + * take it to OVS metadata. + */ + if (rte_restore_info.flags & RTE_FLOW_RESTORE_INFO_ENCAPSULATED) { + if (!vport_netdev->netdev_class || + !vport_netdev->netdev_class->pop_header) { + VLOG_ERR("vport nedtdev=%s with no pop_header method", + netdev_get_name(vport_netdev)); + ret = EOPNOTSUPP; + goto close_vport_netdev; + } + parse_tcp_flags(packet); + if (vport_netdev->netdev_class->pop_header(packet) == NULL) { + /* If there is an error with popping the header, the packet is + * freed. In this case it should not continue SW processing. + */ + ret = -1; + goto close_vport_netdev; + } + } else { + md_tnl = &md->tunnel; + if (rte_tnl->is_ipv6) { + memcpy(&md_tnl->ipv6_src, &rte_tnl->ipv6.src_addr, + sizeof md_tnl->ipv6_src); + memcpy(&md_tnl->ipv6_dst, &rte_tnl->ipv6.dst_addr, + sizeof md_tnl->ipv6_dst); + } else { + md_tnl->ip_src = rte_tnl->ipv4.src_addr; + md_tnl->ip_dst = rte_tnl->ipv4.dst_addr; + } + md_tnl->tun_id = htonll(rte_tnl->tun_id); + md_tnl->flags = rte_tnl->tun_flags; + md_tnl->ip_tos = rte_tnl->tos; + md_tnl->ip_ttl = rte_tnl->ttl; + md_tnl->tp_src = rte_tnl->tp_src; + } + + md->in_port.odp_port = vport_odp; + dp_packet_reset_offload(packet); + +close_vport_netdev: + netdev_close(vport_netdev); + + return ret; +} + const struct netdev_flow_api netdev_offload_dpdk = { .type = "dpdk_flow_api", .flow_put = netdev_offload_dpdk_flow_put, @@ -1595,4 +1744,5 @@ const struct netdev_flow_api netdev_offload_dpdk = { .init_flow_api = netdev_offload_dpdk_init_flow_api, .flow_get = netdev_offload_dpdk_flow_get, .flow_flush = netdev_offload_dpdk_flow_flush, + .hw_miss_packet_recover = netdev_offload_dpdk_hw_miss_packet_recover, }; From patchwork Wed Mar 17 06:35:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1454463 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F0gQw3N0mz9sWH for ; Wed, 17 Mar 2021 17:36:08 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 906F64320D; Wed, 17 Mar 2021 06:36:05 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 4UN3UizbMZfJ; Wed, 17 Mar 2021 06:36:04 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTP id 2AF684328D; Wed, 17 Mar 2021 06:36:02 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 58C3AC002A; Wed, 17 Mar 2021 06:35:57 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 4A589C0017 for ; Wed, 17 Mar 2021 06:35:50 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 3592B6F703 for ; Wed, 17 Mar 2021 06:35:49 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Tk8V0EyUWtyX for ; Wed, 17 Mar 2021 06:35:46 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp3.osuosl.org (Postfix) with ESMTP id B04E06F6CA for ; Wed, 17 Mar 2021 06:35:44 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 17 Mar 2021 08:35:42 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 12H6ZfYn031345; Wed, 17 Mar 2021 08:35:42 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 17 Mar 2021 06:35:30 +0000 Message-Id: <20210317063538.12451-7-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210317063538.12451-1-elibr@nvidia.com> References: <20210317063538.12451-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH V4 06/14] dpif-netdev: Add HW miss packet state recover logic X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Recover the packet if it was partially processed by the HW. Fallback to lookup flow by mark association. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/dpif-netdev.c | 74 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 816945375..c37a25279 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -7049,6 +7049,44 @@ smc_lookup_batch(struct dp_netdev_pmd_thread *pmd, pmd_perf_update_counter(&pmd->perf_stats, PMD_STAT_SMC_HIT, n_smc_hit); } +static struct tx_port * +pmd_send_port_cache_lookup(const struct dp_netdev_pmd_thread *pmd, + odp_port_t port_no); + +static inline int +dp_netdev_hw_flow(const struct dp_netdev_pmd_thread *pmd, + odp_port_t port_no, + struct dp_packet *packet, + struct dp_netdev_flow **flow) +{ + struct tx_port *p; + uint32_t mark; + + if (!netdev_is_flow_api_enabled() || *recirc_depth_get() != 0) { + *flow = NULL; + return 0; + } + + /* Restore the packet if HW processing was terminated before completion. */ + p = pmd_send_port_cache_lookup(pmd, port_no); + if (OVS_LIKELY(p)) { + int err = netdev_hw_miss_packet_recover(p->port->netdev, packet); + + if (err != 0 && err != EOPNOTSUPP) { + return -1; + } + } + + /* If no mark, no flow to find. */ + if (!dp_packet_has_flow_mark(packet, &mark)) { + *flow = NULL; + return 0; + } + + *flow = mark_to_flow_find(pmd, mark); + return 0; +} + /* Try to process all ('cnt') the 'packets' using only the datapath flow cache * 'pmd->flow_cache'. If a flow is not found for a packet 'packets[i]', the * miniflow is copied into 'keys' and the packet pointer is moved at the @@ -7093,7 +7131,6 @@ dfc_processing(struct dp_netdev_pmd_thread *pmd, DP_PACKET_BATCH_REFILL_FOR_EACH (i, cnt, packet, packets_) { struct dp_netdev_flow *flow; - uint32_t mark; if (OVS_UNLIKELY(dp_packet_size(packet) < ETH_HEADER_LEN)) { dp_packet_delete(packet); @@ -7112,24 +7149,25 @@ dfc_processing(struct dp_netdev_pmd_thread *pmd, pkt_metadata_init(&packet->md, port_no); } - if ((*recirc_depth_get() == 0) && - dp_packet_has_flow_mark(packet, &mark)) { - flow = mark_to_flow_find(pmd, mark); - if (OVS_LIKELY(flow)) { - tcp_flags = parse_tcp_flags(packet); - if (OVS_LIKELY(batch_enable)) { - dp_netdev_queue_batches(packet, flow, tcp_flags, batches, - n_batches); - } else { - /* Flow batching should be performed only after fast-path - * processing is also completed for packets with emc miss - * or else it will result in reordering of packets with - * same datapath flows. */ - packet_enqueue_to_flow_map(packet, flow, tcp_flags, - flow_map, map_cnt++); - } - continue; + if (OVS_UNLIKELY(dp_netdev_hw_flow(pmd, port_no, packet, &flow))) { + /* Packet restoration failed. Its mbuf was freed, do not continue + * processing. + */ + continue; + } else if (OVS_LIKELY(flow)) { + tcp_flags = parse_tcp_flags(packet); + if (OVS_LIKELY(batch_enable)) { + dp_netdev_queue_batches(packet, flow, tcp_flags, batches, + n_batches); + } else { + /* Flow batching should be performed only after fast-path + * processing is also completed for packets with emc miss + * or else it will result in reordering of packets with + * same datapath flows. */ + packet_enqueue_to_flow_map(packet, flow, tcp_flags, flow_map, + map_cnt++); } + continue; } miniflow_extract(packet, &key->mf); From patchwork Wed Mar 17 06:35:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1454459 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F0gQr0mnbz9sVm for ; Wed, 17 Mar 2021 17:36:03 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id A77B683F8D; Wed, 17 Mar 2021 06:35:58 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7UcS08Sfmbpm; Wed, 17 Mar 2021 06:35:56 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTP id A257983F17; Wed, 17 Mar 2021 06:35:55 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5DA45C0018; Wed, 17 Mar 2021 06:35:53 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 26478C0012 for ; Wed, 17 Mar 2021 06:35:49 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 0949783EFF for ; Wed, 17 Mar 2021 06:35:49 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DGgMQmFYVP1u for ; Wed, 17 Mar 2021 06:35:45 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp1.osuosl.org (Postfix) with ESMTP id AA47083934 for ; Wed, 17 Mar 2021 06:35:44 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 17 Mar 2021 08:35:42 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 12H6ZfYo031345; Wed, 17 Mar 2021 08:35:42 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 17 Mar 2021 06:35:31 +0000 Message-Id: <20210317063538.12451-8-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210317063538.12451-1-elibr@nvidia.com> References: <20210317063538.12451-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH V4 07/14] netdev-offload: Allow offloading to netdev without ifindex. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Ilya Maximets Virtual interfaces like vports or dpdk vhost-user ports have no proper ifindex, while still supporting some offloads. This is a prerequisite for tunneling vport offloading with DPDK flow API. Signed-off-by: Ilya Maximets Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/netdev-offload.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c index 10f543018..8075cfbd8 100644 --- a/lib/netdev-offload.c +++ b/lib/netdev-offload.c @@ -579,10 +579,6 @@ netdev_ports_insert(struct netdev *netdev, const char *dpif_type, struct port_to_netdev_data *data; int ifindex = netdev_get_ifindex(netdev); - if (ifindex < 0) { - return ENODEV; - } - ovs_rwlock_wrlock(&netdev_hmap_rwlock); if (netdev_ports_lookup(dpif_port->port_no, dpif_type)) { ovs_rwlock_unlock(&netdev_hmap_rwlock); @@ -592,13 +588,18 @@ netdev_ports_insert(struct netdev *netdev, const char *dpif_type, data = xzalloc(sizeof *data); data->netdev = netdev_ref(netdev); dpif_port_clone(&data->dpif_port, dpif_port); - data->ifindex = ifindex; + + if (ifindex >= 0) { + data->ifindex = ifindex; + hmap_insert(&ifindex_to_port, &data->ifindex_node, ifindex); + } else { + data->ifindex = -1; + } netdev_set_dpif_type(netdev, dpif_type); hmap_insert(&port_to_netdev, &data->portno_node, netdev_ports_hash(dpif_port->port_no, dpif_type)); - hmap_insert(&ifindex_to_port, &data->ifindex_node, ifindex); ovs_rwlock_unlock(&netdev_hmap_rwlock); netdev_init_flow_api(netdev); @@ -634,7 +635,9 @@ netdev_ports_remove(odp_port_t port_no, const char *dpif_type) dpif_port_destroy(&data->dpif_port); netdev_close(data->netdev); /* unref and possibly close */ hmap_remove(&port_to_netdev, &data->portno_node); - hmap_remove(&ifindex_to_port, &data->ifindex_node); + if (data->ifindex >= 0) { + hmap_remove(&ifindex_to_port, &data->ifindex_node); + } free(data); ret = 0; } From patchwork Wed Mar 17 06:35:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1454457 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F0gQk6Q42z9sVm for ; Wed, 17 Mar 2021 17:35:58 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 542056F914; Wed, 17 Mar 2021 06:35:56 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6-EVN9uMUpam; Wed, 17 Mar 2021 06:35:54 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp3.osuosl.org (Postfix) with ESMTP id DE6DA6F81D; Wed, 17 Mar 2021 06:35:52 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5D0B3C0013; Wed, 17 Mar 2021 06:35:51 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 1EB4CC000F for ; Wed, 17 Mar 2021 06:35:48 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id EDD896F703 for ; Wed, 17 Mar 2021 06:35:47 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id FWISCrTnIuJe for ; Wed, 17 Mar 2021 06:35:46 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp3.osuosl.org (Postfix) with ESMTP id AD3EA6F6C6 for ; Wed, 17 Mar 2021 06:35:44 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 17 Mar 2021 08:35:42 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 12H6ZfYp031345; Wed, 17 Mar 2021 08:35:42 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 17 Mar 2021 06:35:32 +0000 Message-Id: <20210317063538.12451-9-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210317063538.12451-1-elibr@nvidia.com> References: <20210317063538.12451-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH V4 08/14] netdev-offload: Disallow offloading to unrelated tunneling vports. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Ilya Maximets 'linux_tc' flow API suitable only for tunneling vports with backing linux interfaces. DPDK flow API is not suitable for such ports. With this change we could drop vport restriction from dpif-netdev. This is a prerequisite for enabling vport offloading in DPDK. Signed-off-by: Ilya Maximets Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/dpif-netdev.c | 3 +-- lib/netdev-offload-dpdk.c | 8 ++++++++ lib/netdev-offload-tc.c | 8 ++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index c37a25279..8c548b897 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -2697,8 +2697,7 @@ dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload) info.flow_mark = mark; port = netdev_ports_get(in_port, dpif_type_str); - if (!port || netdev_vport_is_vport_class(port->netdev_class)) { - netdev_close(port); + if (!port) { goto err_free; } /* Taking a global 'port_mutex' to fulfill thread safety restrictions for diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index c78089605..077d10470 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -24,6 +24,7 @@ #include "dpif-netdev.h" #include "netdev-offload-provider.h" #include "netdev-provider.h" +#include "netdev-vport.h" #include "openvswitch/match.h" #include "openvswitch/vlog.h" #include "packets.h" @@ -1523,6 +1524,13 @@ netdev_offload_dpdk_flow_del(struct netdev *netdev OVS_UNUSED, static int netdev_offload_dpdk_init_flow_api(struct netdev *netdev) { + if (netdev_vport_is_vport_class(netdev->netdev_class) + && !strcmp(netdev_get_dpif_type(netdev), "system")) { + VLOG_DBG("%s: vport belongs to the system datapath. Skipping.", + netdev_get_name(netdev)); + return EOPNOTSUPP; + } + return netdev_dpdk_flow_api_supported(netdev) ? 0 : EOPNOTSUPP; } diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index 448747eae..00b02411c 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -31,6 +31,7 @@ #include "netdev-linux.h" #include "netdev-offload-provider.h" #include "netdev-provider.h" +#include "netdev-vport.h" #include "netlink.h" #include "netlink-socket.h" #include "odp-netlink.h" @@ -2211,6 +2212,13 @@ netdev_tc_init_flow_api(struct netdev *netdev) int ifindex; int error; + if (netdev_vport_is_vport_class(netdev->netdev_class) + && strcmp(netdev_get_dpif_type(netdev), "system")) { + VLOG_DBG("%s: vport doesn't belong to the system datapath. Skipping.", + netdev_get_name(netdev)); + return EOPNOTSUPP; + } + ifindex = netdev_get_ifindex(netdev); if (ifindex < 0) { VLOG_INFO("init: failed to get ifindex for %s: %s", From patchwork Wed Mar 17 06:35:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1454455 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F0gQd4ySKz9sVm for ; Wed, 17 Mar 2021 17:35:53 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 338724ED85; Wed, 17 Mar 2021 06:35:51 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id g7KSnRHjC3x8; Wed, 17 Mar 2021 06:35:50 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp4.osuosl.org (Postfix) with ESMTP id 28F034ED45; Wed, 17 Mar 2021 06:35:49 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id EF81AC000C; Wed, 17 Mar 2021 06:35:48 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0DC3EC000A for ; Wed, 17 Mar 2021 06:35:48 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id E8E41431F5 for ; Wed, 17 Mar 2021 06:35:47 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id T8NQuZQgt8bm for ; Wed, 17 Mar 2021 06:35:46 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp2.osuosl.org (Postfix) with ESMTP id ACED7431F0 for ; Wed, 17 Mar 2021 06:35:44 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 17 Mar 2021 08:35:42 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 12H6ZfYq031345; Wed, 17 Mar 2021 08:35:42 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 17 Mar 2021 06:35:33 +0000 Message-Id: <20210317063538.12451-10-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210317063538.12451-1-elibr@nvidia.com> References: <20210317063538.12451-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH V4 09/14] netdev-offload-dpdk: Change log rate limits X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" In order to allow showing more debug messages, increase the rate limits. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/netdev-offload-dpdk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index 077d10470..cbeb334a9 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -31,7 +31,7 @@ #include "uuid.h" VLOG_DEFINE_THIS_MODULE(netdev_offload_dpdk); -static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(100, 5); +static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(600, 600); /* Thread-safety * ============= From patchwork Wed Mar 17 06:35:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1454466 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F0gR62BS5z9sWH for ; Wed, 17 Mar 2021 17:36:18 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 10E8E4EE8B; Wed, 17 Mar 2021 06:36:16 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ZTPgzKTjVeFO; Wed, 17 Mar 2021 06:36:14 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp4.osuosl.org (Postfix) with ESMTP id 61BAD4EE30; Wed, 17 Mar 2021 06:36:05 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id BDD6FC0020; Wed, 17 Mar 2021 06:35:59 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 13857C0013 for ; Wed, 17 Mar 2021 06:35:51 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 73BEB6F6C6 for ; Wed, 17 Mar 2021 06:35:49 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id uPd47LzP212S for ; Wed, 17 Mar 2021 06:35:45 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp3.osuosl.org (Postfix) with ESMTP id AD3B76F6B5 for ; Wed, 17 Mar 2021 06:35:44 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 17 Mar 2021 08:35:42 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 12H6ZfYr031345; Wed, 17 Mar 2021 08:35:42 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 17 Mar 2021 06:35:34 +0000 Message-Id: <20210317063538.12451-11-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210317063538.12451-1-elibr@nvidia.com> References: <20210317063538.12451-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH V4 10/14] netdev-offload-dpdk: Support tunnel pop action X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Support tunnel pop action. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- Documentation/howto/dpdk.rst | 1 + NEWS | 1 + lib/netdev-offload-dpdk.c | 183 ++++++++++++++++++++++++++++++++--- 3 files changed, 170 insertions(+), 15 deletions(-) diff --git a/Documentation/howto/dpdk.rst b/Documentation/howto/dpdk.rst index f0d45e47b..4918d80f3 100644 --- a/Documentation/howto/dpdk.rst +++ b/Documentation/howto/dpdk.rst @@ -398,6 +398,7 @@ Supported actions for hardware offload are: - VLAN Push/Pop (push_vlan/pop_vlan). - Modification of IPv6 (set_field:->ipv6_src/ipv6_dst/mod_nw_ttl). - Clone/output (tnl_push and output) for encapsulating over a tunnel. +- Tunnel pop, for changing from a physical port to a vport. Further Reading --------------- diff --git a/NEWS b/NEWS index a1af992e9..a5d103b1d 100644 --- a/NEWS +++ b/NEWS @@ -30,6 +30,7 @@ v2.15.0 - 15 Feb 2021 - DPDK: * Removed support for vhost-user dequeue zero-copy. * Add support for DPDK 20.11. + * Add hardware offload support for tunnel pop action (experimental). - Userspace datapath: * Add the 'pmd' option to "ovs-appctl dpctl/dump-flows", which restricts a flow dump to a single PMD thread if set. diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index cbeb334a9..4d2a13005 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -140,15 +140,30 @@ struct flow_actions { struct rte_flow_action *actions; int cnt; int current_max; + struct netdev *tnl_netdev; + /* tnl_pmd_actions is the opaque array of actions returned by the PMD. */ + struct rte_flow_action *tnl_pmd_actions; + uint32_t tnl_pmd_actions_cnt; + /* tnl_pmd_actions_pos is where the tunnel actions starts within the + * 'actions' field. + */ + int tnl_pmd_actions_pos; + struct ds s_tnl; }; static void -dump_flow_attr(struct ds *s, const struct rte_flow_attr *attr) +dump_flow_attr(struct ds *s, struct ds *s_extra, + const struct rte_flow_attr *attr, + struct flow_actions *flow_actions) { - ds_put_format(s, "%s%spriority %"PRIu32" group %"PRIu32" %s", + if (flow_actions->tnl_pmd_actions_cnt) { + ds_clone(s_extra, &flow_actions->s_tnl); + } + ds_put_format(s, "%s%spriority %"PRIu32" group %"PRIu32" %s%s", attr->ingress ? "ingress " : "", attr->egress ? "egress " : "", attr->priority, attr->group, - attr->transfer ? "transfer " : ""); + attr->transfer ? "transfer " : "", + flow_actions->tnl_pmd_actions_cnt ? "tunnel_set 1 " : ""); } /* Adds one pattern item 'field' with the 'mask' to dynamic string 's' using @@ -395,9 +410,19 @@ dump_vxlan_encap(struct ds *s, const struct rte_flow_item *items) static void dump_flow_action(struct ds *s, struct ds *s_extra, - const struct rte_flow_action *actions) + struct flow_actions *flow_actions, int act_index) { - if (actions->type == RTE_FLOW_ACTION_TYPE_MARK) { + const struct rte_flow_action *actions = &flow_actions->actions[act_index]; + + if (actions->type == RTE_FLOW_ACTION_TYPE_END) { + ds_put_cstr(s, "end"); + } else if (flow_actions->tnl_pmd_actions_cnt && + act_index >= flow_actions->tnl_pmd_actions_pos && + act_index < flow_actions->tnl_pmd_actions_pos + + flow_actions->tnl_pmd_actions_cnt) { + /* Opaque PMD tunnel actions is skipped. */ + return; + } else if (actions->type == RTE_FLOW_ACTION_TYPE_MARK) { const struct rte_flow_action_mark *mark = actions->conf; ds_put_cstr(s, "mark "); @@ -528,6 +553,14 @@ dump_flow_action(struct ds *s, struct ds *s_extra, ds_put_cstr(s, "vxlan_encap / "); dump_vxlan_encap(s_extra, items); ds_put_cstr(s_extra, ";"); + } else if (actions->type == RTE_FLOW_ACTION_TYPE_JUMP) { + const struct rte_flow_action_jump *jump = actions->conf; + + ds_put_cstr(s, "jump "); + if (jump) { + ds_put_format(s, "group %"PRIu32" ", jump->group); + } + ds_put_cstr(s, "/ "); } else { ds_put_format(s, "unknown rte flow action (%d)\n", actions->type); } @@ -537,20 +570,21 @@ static struct ds * dump_flow(struct ds *s, struct ds *s_extra, const struct rte_flow_attr *attr, const struct rte_flow_item *items, - const struct rte_flow_action *actions) + struct flow_actions *flow_actions) { + int i; + if (attr) { - dump_flow_attr(s, attr); + dump_flow_attr(s, s_extra, attr, flow_actions); } ds_put_cstr(s, "pattern "); while (items && items->type != RTE_FLOW_ITEM_TYPE_END) { dump_flow_pattern(s, items++); } ds_put_cstr(s, "end actions "); - while (actions && actions->type != RTE_FLOW_ACTION_TYPE_END) { - dump_flow_action(s, s_extra, actions++); + for (i = 0; i < flow_actions->cnt; i++) { + dump_flow_action(s, s_extra, flow_actions, i); } - ds_put_cstr(s, "end"); return s; } @@ -558,9 +592,10 @@ static struct rte_flow * netdev_offload_dpdk_flow_create(struct netdev *netdev, const struct rte_flow_attr *attr, const struct rte_flow_item *items, - const struct rte_flow_action *actions, + struct flow_actions *flow_actions, struct rte_flow_error *error) { + const struct rte_flow_action *actions = flow_actions->actions; struct ds s_extra = DS_EMPTY_INITIALIZER; struct ds s = DS_EMPTY_INITIALIZER; struct rte_flow *flow; @@ -569,7 +604,7 @@ netdev_offload_dpdk_flow_create(struct netdev *netdev, flow = netdev_dpdk_rte_flow_create(netdev, attr, items, actions, error); if (flow) { if (!VLOG_DROP_DBG(&rl)) { - dump_flow(&s, &s_extra, attr, items, actions); + dump_flow(&s, &s_extra, attr, items, flow_actions); extra_str = ds_cstr(&s_extra); VLOG_DBG_RL(&rl, "%s: rte_flow 0x%"PRIxPTR" %s flow create %d %s", netdev_get_name(netdev), (intptr_t) flow, extra_str, @@ -584,7 +619,7 @@ netdev_offload_dpdk_flow_create(struct netdev *netdev, VLOG_RL(&rl, level, "%s: rte_flow creation failed: %d (%s).", netdev_get_name(netdev), error->type, error->message); if (!vlog_should_drop(&this_module, level, &rl)) { - dump_flow(&s, &s_extra, attr, items, actions); + dump_flow(&s, &s_extra, attr, items, flow_actions); extra_str = ds_cstr(&s_extra); VLOG_RL(&rl, level, "%s: Failed flow: %s flow create %d %s", netdev_get_name(netdev), extra_str, @@ -640,6 +675,24 @@ add_flow_action(struct flow_actions *actions, enum rte_flow_action_type type, actions->cnt++; } +static void +add_flow_tnl_actions(struct flow_actions *actions, + struct netdev *tnl_netdev, + struct rte_flow_action *tnl_pmd_actions, + uint32_t tnl_pmd_actions_cnt) +{ + int i; + + actions->tnl_netdev = tnl_netdev; + actions->tnl_pmd_actions_pos = actions->cnt; + actions->tnl_pmd_actions = tnl_pmd_actions; + actions->tnl_pmd_actions_cnt = tnl_pmd_actions_cnt; + for (i = 0; i < tnl_pmd_actions_cnt; i++) { + add_flow_action(actions, tnl_pmd_actions[i].type, + tnl_pmd_actions[i].conf); + } +} + static void free_flow_patterns(struct flow_patterns *patterns) { @@ -661,9 +714,24 @@ free_flow_patterns(struct flow_patterns *patterns) static void free_flow_actions(struct flow_actions *actions) { + struct rte_flow_error error; int i; for (i = 0; i < actions->cnt; i++) { + if (actions->tnl_pmd_actions_cnt && + i == actions->tnl_pmd_actions_pos) { + if (netdev_dpdk_rte_flow_tunnel_action_decap_release + (actions->tnl_netdev, actions->tnl_pmd_actions, + actions->tnl_pmd_actions_cnt, &error)) { + VLOG_DBG_RL(&rl, "%s: " + "netdev_dpdk_rte_flow_tunnel_action_decap_release " + "failed: %d (%s).", + netdev_get_name(actions->tnl_netdev), + error.type, error.message); + } + i += actions->tnl_pmd_actions_cnt - 1; + continue; + } if (actions->actions[i].conf) { free(CONST_CAST(void *, actions->actions[i].conf)); } @@ -671,6 +739,7 @@ free_flow_actions(struct flow_actions *actions) free(actions->actions); actions->actions = NULL; actions->cnt = 0; + ds_destroy(&actions->s_tnl); } static int @@ -960,7 +1029,7 @@ netdev_offload_dpdk_mark_rss(struct flow_patterns *patterns, add_flow_mark_rss_actions(&actions, flow_mark, netdev); flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns->items, - actions.actions, &error); + &actions, &error); free_flow_actions(&actions); return flow; @@ -1307,6 +1376,86 @@ parse_clone_actions(struct netdev *netdev, return 0; } +static void +add_jump_action(struct flow_actions *actions, uint32_t group) +{ + struct rte_flow_action_jump *jump = xzalloc (sizeof *jump); + + jump->group = group; + add_flow_action(actions, RTE_FLOW_ACTION_TYPE_JUMP, jump); +} + +static int +vport_to_rte_tunnel(struct netdev *vport, + struct rte_flow_tunnel *tunnel, + struct netdev *netdev, + struct ds *s_tnl) +{ + const struct netdev_tunnel_config *tnl_cfg; + + memset(tunnel, 0, sizeof *tunnel); + if (!strcmp(netdev_get_type(vport), "vxlan")) { + tunnel->type = RTE_FLOW_ITEM_TYPE_VXLAN; + tnl_cfg = netdev_get_tunnel_config(vport); + if (!tnl_cfg) { + return -1; + } + tunnel->tp_dst = tnl_cfg->dst_port; + if (!VLOG_DROP_DBG(&rl)) { + ds_put_format(s_tnl, "flow tunnel create %d type vxlan; ", + netdev_dpdk_get_port_id(netdev)); + } + } else { + OVS_NOT_REACHED(); + } + + return 0; +} + +static int +add_tnl_pop_action(struct netdev *netdev, + struct flow_actions *actions, + const struct nlattr *nla) +{ + struct rte_flow_action *tnl_pmd_actions = NULL; + uint32_t tnl_pmd_actions_cnt = 0; + struct rte_flow_tunnel tunnel; + struct rte_flow_error error; + struct netdev *vport; + odp_port_t port; + int ret; + + port = nl_attr_get_odp_port(nla); + vport = netdev_ports_get(port, netdev->dpif_type); + if (vport == NULL) { + return -1; + } + ret = vport_to_rte_tunnel(vport, &tunnel, netdev, &actions->s_tnl); + netdev_close(vport); + if (ret) { + return ret; + } + ret = netdev_dpdk_rte_flow_tunnel_decap_set(netdev, &tunnel, + &tnl_pmd_actions, + &tnl_pmd_actions_cnt, + &error); + if (ret) { + VLOG_DBG_RL(&rl, "%s: netdev_dpdk_rte_flow_tunnel_decap_set failed: " + "%d (%s).", netdev_get_name(netdev), error.type, + error.message); + return ret; + } + add_flow_tnl_actions(actions, netdev, tnl_pmd_actions, + tnl_pmd_actions_cnt); + /* After decap_set, the packet processing should continue. In SW, it is + * done by recirculation (recirc_id = 0). In rte_flow, the group is + * equivalent to recirc_id, thus jump to group 0 is added to instruct the + * the HW to proceed processing. + */ + add_jump_action(actions, 0); + return 0; +} + static int parse_flow_actions(struct netdev *netdev, struct flow_actions *actions, @@ -1351,6 +1500,10 @@ parse_flow_actions(struct netdev *netdev, clone_actions_len)) { return -1; } + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_TUNNEL_POP) { + if (add_tnl_pop_action(netdev, actions, nla)) { + return -1; + } } else { VLOG_DBG_RL(&rl, "Unsupported action type %d", nl_attr_type(nla)); return -1; @@ -1383,7 +1536,7 @@ netdev_offload_dpdk_actions(struct netdev *netdev, goto out; } flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns->items, - actions.actions, &error); + &actions, &error); out: free_flow_actions(&actions); return flow; From patchwork Wed Mar 17 06:35:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1454469 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F0gRM0Q4Dz9sWH for ; Wed, 17 Mar 2021 17:36:31 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 721616FB7D; Wed, 17 Mar 2021 06:36:29 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id kbOTllf4aZu8; Wed, 17 Mar 2021 06:36:27 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTP id 4595C6F913; Wed, 17 Mar 2021 06:36:12 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7A143C0018; Wed, 17 Mar 2021 06:36:03 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 19F6EC000A for ; Wed, 17 Mar 2021 06:35:53 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 33F2883934 for ; Wed, 17 Mar 2021 06:35:51 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id AKZEo07xodxR for ; Wed, 17 Mar 2021 06:35:45 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp1.osuosl.org (Postfix) with ESMTP id AC78B83A65 for ; Wed, 17 Mar 2021 06:35:44 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 17 Mar 2021 08:35:42 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 12H6ZfYs031345; Wed, 17 Mar 2021 08:35:42 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 17 Mar 2021 06:35:35 +0000 Message-Id: <20210317063538.12451-12-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210317063538.12451-1-elibr@nvidia.com> References: <20210317063538.12451-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH V4 11/14] netdev-offload-dpdk: Refactor offload rule creation X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Refactor offload rule creation as a pre-step towards tunnel matching that depend on the netdev. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/netdev-offload-dpdk.c | 106 ++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 61 deletions(-) diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index 4d2a13005..ade7fae09 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -1011,30 +1011,6 @@ add_flow_mark_rss_actions(struct flow_actions *actions, add_flow_action(actions, RTE_FLOW_ACTION_TYPE_END, NULL); } -static struct rte_flow * -netdev_offload_dpdk_mark_rss(struct flow_patterns *patterns, - struct netdev *netdev, - uint32_t flow_mark) -{ - struct flow_actions actions = { .actions = NULL, .cnt = 0 }; - const struct rte_flow_attr flow_attr = { - .group = 0, - .priority = 0, - .ingress = 1, - .egress = 0 - }; - struct rte_flow_error error; - struct rte_flow *flow; - - add_flow_mark_rss_actions(&actions, flow_mark, netdev); - - flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns->items, - &actions, &error); - - free_flow_actions(&actions); - return flow; -} - static void add_count_action(struct flow_actions *actions) { @@ -1519,27 +1495,48 @@ parse_flow_actions(struct netdev *netdev, return 0; } -static struct rte_flow * -netdev_offload_dpdk_actions(struct netdev *netdev, - struct flow_patterns *patterns, - struct nlattr *nl_actions, - size_t actions_len) +static struct ufid_to_rte_flow_data * +create_netdev_offload(struct netdev *netdev, + const ovs_u128 *ufid, + struct flow_patterns *flow_patterns, + struct flow_actions *flow_actions, + bool enable_full, + uint32_t flow_mark) { - const struct rte_flow_attr flow_attr = { .ingress = 1, .transfer = 1 }; - struct flow_actions actions = { .actions = NULL, .cnt = 0 }; + struct rte_flow_attr flow_attr = { .ingress = 1, .transfer = 1, }; + struct flow_actions rss_actions = { .actions = NULL, .cnt = 0 }; + struct rte_flow_item *items = flow_patterns->items; + struct ufid_to_rte_flow_data *flow_data = NULL; + bool actions_offloaded = true; struct rte_flow *flow = NULL; struct rte_flow_error error; - int ret; - ret = parse_flow_actions(netdev, &actions, nl_actions, actions_len); - if (ret) { - goto out; + if (enable_full) { + flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, items, + flow_actions, &error); } - flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns->items, - &actions, &error); -out: - free_flow_actions(&actions); - return flow; + + if (!flow) { + /* If we failed to offload the rule actions fallback to MARK+RSS + * actions. + */ + actions_offloaded = false; + flow_attr.transfer = 0; + add_flow_mark_rss_actions(&rss_actions, flow_mark, netdev); + flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, items, + &rss_actions, &error); + free_flow_actions(&rss_actions); + } + + if (flow) { + flow_data = ufid_to_rte_flow_associate(ufid, netdev, flow, + actions_offloaded); + VLOG_DBG("%s: installed flow %p by ufid "UUID_FMT, + netdev_get_name(netdev), flow, + UUID_ARGS((struct uuid *) ufid)); + } + + return flow_data; } static struct ufid_to_rte_flow_data * @@ -1551,9 +1548,9 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, struct offload_info *info) { struct flow_patterns patterns = { .items = NULL, .cnt = 0 }; - struct ufid_to_rte_flow_data *flows_data = NULL; - bool actions_offloaded = true; - struct rte_flow *flow; + struct flow_actions actions = { .actions = NULL, .cnt = 0 }; + struct ufid_to_rte_flow_data *flow_data = NULL; + int err; if (parse_flow_match(&patterns, match)) { VLOG_DBG_RL(&rl, "%s: matches of ufid "UUID_FMT" are not supported", @@ -1561,28 +1558,15 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, goto out; } - flow = netdev_offload_dpdk_actions(netdev, &patterns, nl_actions, - actions_len); - if (!flow) { - /* If we failed to offload the rule actions fallback to MARK+RSS - * actions. - */ - flow = netdev_offload_dpdk_mark_rss(&patterns, netdev, - info->flow_mark); - actions_offloaded = false; - } + err = parse_flow_actions(netdev, &actions, nl_actions, actions_len); - if (!flow) { - goto out; - } - flows_data = ufid_to_rte_flow_associate(ufid, netdev, flow, - actions_offloaded); - VLOG_DBG("%s: installed flow %p by ufid "UUID_FMT, - netdev_get_name(netdev), flow, UUID_ARGS((struct uuid *)ufid)); + flow_data = create_netdev_offload(netdev, ufid, &patterns, &actions, !err, + info->flow_mark); out: free_flow_patterns(&patterns); - return flows_data; + free_flow_actions(&actions); + return flow_data; } static int From patchwork Wed Mar 17 06:35:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1454461 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F0gQt25G3z9sWH for ; Wed, 17 Mar 2021 17:36:06 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 59756432A6; Wed, 17 Mar 2021 06:36:04 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id s-H-h63A-MSg; Wed, 17 Mar 2021 06:36:01 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTP id B9DFC43226; Wed, 17 Mar 2021 06:36:00 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 74E91C001C; Wed, 17 Mar 2021 06:35:56 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 19EEAC0013 for ; Wed, 17 Mar 2021 06:35:50 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 2EEA483EFF for ; Wed, 17 Mar 2021 06:35:49 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Rz7lJL_CtbfK for ; Wed, 17 Mar 2021 06:35:45 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp1.osuosl.org (Postfix) with ESMTP id A4B68836C3 for ; Wed, 17 Mar 2021 06:35:44 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 17 Mar 2021 08:35:42 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 12H6ZfYt031345; Wed, 17 Mar 2021 08:35:42 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 17 Mar 2021 06:35:36 +0000 Message-Id: <20210317063538.12451-13-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210317063538.12451-1-elibr@nvidia.com> References: <20210317063538.12451-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH V4 12/14] dpif-netdev: Provide orig_in_port in metadata for tunneled packets X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Sriharsha Basavapatna When an encapsulated packet is recirculated through a TUNNEL_POP action, the metadata gets reinitialized and the originating physical port information is lost. When this flow gets processed by the vport and it needs to be offloaded, we can't figure out the physical port through which the tunneled packet was received. Add a new member to the metadata: 'orig_in_port'. This is passed to the next stage during recirculation and the offload layer can use it to offload the flow to this physical port. Signed-off-by: Sriharsha Basavapatna Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/dpif-netdev.c | 20 ++++++++++++++------ lib/netdev-offload.h | 1 + lib/packets.h | 8 +++++++- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 8c548b897..acc5c184a 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -430,6 +430,7 @@ struct dp_flow_offload_item { struct match match; struct nlattr *actions; size_t actions_len; + odp_port_t orig_in_port; /* Originating in_port for tnl flows. */ struct ovs_list node; }; @@ -2695,11 +2696,13 @@ dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload) } } info.flow_mark = mark; + info.orig_in_port = offload->orig_in_port; port = netdev_ports_get(in_port, dpif_type_str); if (!port) { goto err_free; } + /* Taking a global 'port_mutex' to fulfill thread safety restrictions for * the netdev-offload-dpdk module. */ ovs_mutex_lock(&pmd->dp->port_mutex); @@ -2797,7 +2800,8 @@ queue_netdev_flow_del(struct dp_netdev_pmd_thread *pmd, static void queue_netdev_flow_put(struct dp_netdev_pmd_thread *pmd, struct dp_netdev_flow *flow, struct match *match, - const struct nlattr *actions, size_t actions_len) + const struct nlattr *actions, size_t actions_len, + odp_port_t orig_in_port) { struct dp_flow_offload_item *offload; int op; @@ -2823,6 +2827,7 @@ queue_netdev_flow_put(struct dp_netdev_pmd_thread *pmd, offload->actions = xmalloc(actions_len); memcpy(offload->actions, actions, actions_len); offload->actions_len = actions_len; + offload->orig_in_port = orig_in_port; dp_netdev_append_flow_offload(offload); } @@ -3624,7 +3629,8 @@ dp_netdev_get_mega_ufid(const struct match *match, ovs_u128 *mega_ufid) static struct dp_netdev_flow * dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd, struct match *match, const ovs_u128 *ufid, - const struct nlattr *actions, size_t actions_len) + const struct nlattr *actions, size_t actions_len, + odp_port_t orig_in_port) OVS_REQUIRES(pmd->flow_mutex) { struct ds extra_info = DS_EMPTY_INITIALIZER; @@ -3690,7 +3696,8 @@ dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd, cmap_insert(&pmd->flow_table, CONST_CAST(struct cmap_node *, &flow->node), dp_netdev_flow_hash(&flow->ufid)); - queue_netdev_flow_put(pmd, flow, match, actions, actions_len); + queue_netdev_flow_put(pmd, flow, match, actions, actions_len, + orig_in_port); if (OVS_UNLIKELY(!VLOG_DROP_DBG((&upcall_rl)))) { struct ds ds = DS_EMPTY_INITIALIZER; @@ -3761,7 +3768,7 @@ flow_put_on_pmd(struct dp_netdev_pmd_thread *pmd, if (!netdev_flow) { if (put->flags & DPIF_FP_CREATE) { dp_netdev_flow_add(pmd, match, ufid, put->actions, - put->actions_len); + put->actions_len, ODPP_NONE); } else { error = ENOENT; } @@ -3777,7 +3784,7 @@ flow_put_on_pmd(struct dp_netdev_pmd_thread *pmd, ovsrcu_set(&netdev_flow->actions, new_actions); queue_netdev_flow_put(pmd, netdev_flow, match, - put->actions, put->actions_len); + put->actions, put->actions_len, ODPP_NONE); if (stats) { get_dpif_flow_status(pmd->dp, netdev_flow, stats, NULL); @@ -7241,6 +7248,7 @@ handle_packet_upcall(struct dp_netdev_pmd_thread *pmd, ovs_u128 ufid; int error; uint64_t cycles = cycles_counter_update(&pmd->perf_stats); + odp_port_t orig_in_port = packet->md.orig_in_port; match.tun_md.valid = false; miniflow_expand(&key->mf, &match.flow); @@ -7290,7 +7298,7 @@ handle_packet_upcall(struct dp_netdev_pmd_thread *pmd, if (OVS_LIKELY(!netdev_flow)) { netdev_flow = dp_netdev_flow_add(pmd, &match, &ufid, add_actions->data, - add_actions->size); + add_actions->size, orig_in_port); } ovs_mutex_unlock(&pmd->flow_mutex); uint32_t hash = dp_netdev_flow_hash(&netdev_flow->ufid); diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h index 5bf89f891..e7fcedae9 100644 --- a/lib/netdev-offload.h +++ b/lib/netdev-offload.h @@ -76,6 +76,7 @@ struct offload_info { bool tc_modify_flow_deleted; /* Indicate the tc modify flow put success * to delete the original flow. */ + odp_port_t orig_in_port; /* Originating in_port for tnl flows. */ }; int netdev_flow_flush(struct netdev *); diff --git a/lib/packets.h b/lib/packets.h index 481bc22fa..515bb59b1 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -115,6 +115,7 @@ PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline0, uint32_t ct_mark; /* Connection mark. */ ovs_u128 ct_label; /* Connection label. */ union flow_in_port in_port; /* Input port. */ + odp_port_t orig_in_port; /* Originating in_port for tunneled packets */ struct conn *conn; /* Cached conntrack connection. */ bool reply; /* True if reply direction. */ bool icmp_related; /* True if ICMP related. */ @@ -143,10 +144,14 @@ BUILD_ASSERT_DECL(offsetof(struct pkt_metadata, cacheline2) == static inline void pkt_metadata_init_tnl(struct pkt_metadata *md) { + odp_port_t orig_in_port; + /* Zero up through the tunnel metadata options. The length and table * are before this and as long as they are empty, the options won't - * be looked at. */ + * be looked at. Keep the orig_in_port field. */ + orig_in_port = md->in_port.odp_port; memset(md, 0, offsetof(struct pkt_metadata, tunnel.metadata.opts)); + md->orig_in_port = orig_in_port; } static inline void @@ -173,6 +178,7 @@ pkt_metadata_init(struct pkt_metadata *md, odp_port_t port) md->tunnel.ip_dst = 0; md->tunnel.ipv6_dst = in6addr_any; md->in_port.odp_port = port; + md->orig_in_port = port; md->conn = NULL; } From patchwork Wed Mar 17 06:35:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1454465 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F0gR571wdz9sVm for ; Wed, 17 Mar 2021 17:36:17 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id C05EA83FB4; Wed, 17 Mar 2021 06:36:15 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Tmjx5aoHpjtd; Wed, 17 Mar 2021 06:36:11 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTP id 6DB8583FBA; Wed, 17 Mar 2021 06:36:10 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id AE074C001C; Wed, 17 Mar 2021 06:36:02 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 169CFC0012 for ; Wed, 17 Mar 2021 06:35:52 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 77051827A9 for ; Wed, 17 Mar 2021 06:35:50 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id pNBrHmef44yY for ; Wed, 17 Mar 2021 06:35:46 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp1.osuosl.org (Postfix) with ESMTP id AC6A0839DC for ; Wed, 17 Mar 2021 06:35:44 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 17 Mar 2021 08:35:42 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 12H6ZfYu031345; Wed, 17 Mar 2021 08:35:42 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 17 Mar 2021 06:35:37 +0000 Message-Id: <20210317063538.12451-14-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210317063538.12451-1-elibr@nvidia.com> References: <20210317063538.12451-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH V4 13/14] netdev-offload-dpdk: Support vports flows offload X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Vports are virtual, OVS only logical devices, so rte_flows cannot be applied as is on them. Instead, apply the rules the physical port from which the packet has arrived, provided by orig_in_port field. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/netdev-offload-dpdk.c | 204 ++++++++++++++++++++++++++++++++------ 1 file changed, 171 insertions(+), 33 deletions(-) diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index ade7fae09..69aaefa0f 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -25,6 +25,7 @@ #include "netdev-offload-provider.h" #include "netdev-provider.h" #include "netdev-vport.h" +#include "odp-util.h" #include "openvswitch/match.h" #include "openvswitch/vlog.h" #include "packets.h" @@ -62,6 +63,7 @@ struct ufid_to_rte_flow_data { struct rte_flow *rte_flow; bool actions_offloaded; struct dpif_flow_stats stats; + struct netdev *physdev; }; /* Find rte_flow with @ufid. */ @@ -87,7 +89,8 @@ ufid_to_rte_flow_data_find(const ovs_u128 *ufid, bool warn) static inline struct ufid_to_rte_flow_data * ufid_to_rte_flow_associate(const ovs_u128 *ufid, struct netdev *netdev, - struct rte_flow *rte_flow, bool actions_offloaded) + struct netdev *vport, struct rte_flow *rte_flow, + bool actions_offloaded) { size_t hash = hash_bytes(ufid, sizeof *ufid, 0); struct ufid_to_rte_flow_data *data = xzalloc(sizeof *data); @@ -105,7 +108,8 @@ ufid_to_rte_flow_associate(const ovs_u128 *ufid, struct netdev *netdev, } data->ufid = *ufid; - data->netdev = netdev_ref(netdev); + data->physdev = netdev_ref(netdev); + data->netdev = vport ? netdev_ref(vport) : netdev; data->rte_flow = rte_flow; data->actions_offloaded = actions_offloaded; @@ -121,7 +125,10 @@ ufid_to_rte_flow_disassociate(struct ufid_to_rte_flow_data *data) cmap_remove(&ufid_to_rte_flow, CONST_CAST(struct cmap_node *, &data->node), hash); - netdev_close(data->netdev); + if (data->netdev != data->physdev) { + netdev_close(data->netdev); + } + netdev_close(data->physdev); ovsrcu_postpone(free, data); } @@ -134,6 +141,8 @@ struct flow_patterns { struct rte_flow_item *items; int cnt; int current_max; + uint32_t tnl_pmd_items_cnt; + struct ds s_tnl; }; struct flow_actions { @@ -154,16 +163,20 @@ struct flow_actions { static void dump_flow_attr(struct ds *s, struct ds *s_extra, const struct rte_flow_attr *attr, + struct flow_patterns *flow_patterns, struct flow_actions *flow_actions) { if (flow_actions->tnl_pmd_actions_cnt) { ds_clone(s_extra, &flow_actions->s_tnl); + } else if (flow_patterns->tnl_pmd_items_cnt) { + ds_clone(s_extra, &flow_patterns->s_tnl); } - ds_put_format(s, "%s%spriority %"PRIu32" group %"PRIu32" %s%s", + ds_put_format(s, "%s%spriority %"PRIu32" group %"PRIu32" %s%s%s", attr->ingress ? "ingress " : "", attr->egress ? "egress " : "", attr->priority, attr->group, attr->transfer ? "transfer " : "", - flow_actions->tnl_pmd_actions_cnt ? "tunnel_set 1 " : ""); + flow_actions->tnl_pmd_actions_cnt ? "tunnel_set 1 " : "", + flow_patterns->tnl_pmd_items_cnt ? "tunnel_match 1 " : ""); } /* Adds one pattern item 'field' with the 'mask' to dynamic string 's' using @@ -177,9 +190,18 @@ dump_flow_attr(struct ds *s, struct ds *s_extra, } static void -dump_flow_pattern(struct ds *s, const struct rte_flow_item *item) +dump_flow_pattern(struct ds *s, + struct flow_patterns *flow_patterns, + int pattern_index) { - if (item->type == RTE_FLOW_ITEM_TYPE_ETH) { + const struct rte_flow_item *item = &flow_patterns->items[pattern_index]; + + if (item->type == RTE_FLOW_ITEM_TYPE_END) { + ds_put_cstr(s, "end "); + } else if (flow_patterns->tnl_pmd_items_cnt && + pattern_index < flow_patterns->tnl_pmd_items_cnt) { + return; + } else if (item->type == RTE_FLOW_ITEM_TYPE_ETH) { const struct rte_flow_item_eth *eth_spec = item->spec; const struct rte_flow_item_eth *eth_mask = item->mask; @@ -569,19 +591,19 @@ dump_flow_action(struct ds *s, struct ds *s_extra, static struct ds * dump_flow(struct ds *s, struct ds *s_extra, const struct rte_flow_attr *attr, - const struct rte_flow_item *items, + struct flow_patterns *flow_patterns, struct flow_actions *flow_actions) { int i; if (attr) { - dump_flow_attr(s, s_extra, attr, flow_actions); + dump_flow_attr(s, s_extra, attr, flow_patterns, flow_actions); } ds_put_cstr(s, "pattern "); - while (items && items->type != RTE_FLOW_ITEM_TYPE_END) { - dump_flow_pattern(s, items++); + for (i = 0; i < flow_patterns->cnt; i++) { + dump_flow_pattern(s, flow_patterns, i); } - ds_put_cstr(s, "end actions "); + ds_put_cstr(s, "actions "); for (i = 0; i < flow_actions->cnt; i++) { dump_flow_action(s, s_extra, flow_actions, i); } @@ -591,11 +613,12 @@ dump_flow(struct ds *s, struct ds *s_extra, static struct rte_flow * netdev_offload_dpdk_flow_create(struct netdev *netdev, const struct rte_flow_attr *attr, - const struct rte_flow_item *items, + struct flow_patterns *flow_patterns, struct flow_actions *flow_actions, struct rte_flow_error *error) { const struct rte_flow_action *actions = flow_actions->actions; + const struct rte_flow_item *items = flow_patterns->items; struct ds s_extra = DS_EMPTY_INITIALIZER; struct ds s = DS_EMPTY_INITIALIZER; struct rte_flow *flow; @@ -604,7 +627,7 @@ netdev_offload_dpdk_flow_create(struct netdev *netdev, flow = netdev_dpdk_rte_flow_create(netdev, attr, items, actions, error); if (flow) { if (!VLOG_DROP_DBG(&rl)) { - dump_flow(&s, &s_extra, attr, items, flow_actions); + dump_flow(&s, &s_extra, attr, flow_patterns, flow_actions); extra_str = ds_cstr(&s_extra); VLOG_DBG_RL(&rl, "%s: rte_flow 0x%"PRIxPTR" %s flow create %d %s", netdev_get_name(netdev), (intptr_t) flow, extra_str, @@ -619,7 +642,7 @@ netdev_offload_dpdk_flow_create(struct netdev *netdev, VLOG_RL(&rl, level, "%s: rte_flow creation failed: %d (%s).", netdev_get_name(netdev), error->type, error->message); if (!vlog_should_drop(&this_module, level, &rl)) { - dump_flow(&s, &s_extra, attr, items, flow_actions); + dump_flow(&s, &s_extra, attr, flow_patterns, flow_actions); extra_str = ds_cstr(&s_extra); VLOG_RL(&rl, level, "%s: Failed flow: %s flow create %d %s", netdev_get_name(netdev), extra_str, @@ -654,6 +677,28 @@ add_flow_pattern(struct flow_patterns *patterns, enum rte_flow_item_type type, patterns->cnt++; } +static void +add_flow_tnl_patterns(struct flow_patterns *all_patterns, + struct rte_flow_item *tnl_pmd_items, + uint32_t tnl_pmd_items_cnt, + struct flow_patterns *flow_patterns) +{ + int i; + + all_patterns->tnl_pmd_items_cnt = tnl_pmd_items_cnt; + + for (i = 0; i < tnl_pmd_items_cnt; i++) { + add_flow_pattern(all_patterns, tnl_pmd_items[i].type, + tnl_pmd_items[i].spec, tnl_pmd_items[i].mask); + } + + for (i = 0; i < flow_patterns->cnt; i++) { + add_flow_pattern(all_patterns, flow_patterns->items[i].type, + flow_patterns->items[i].spec, + flow_patterns->items[i].mask); + } +} + static void add_flow_action(struct flow_actions *actions, enum rte_flow_action_type type, const void *conf) @@ -1497,6 +1542,7 @@ parse_flow_actions(struct netdev *netdev, static struct ufid_to_rte_flow_data * create_netdev_offload(struct netdev *netdev, + struct netdev *vport, const ovs_u128 *ufid, struct flow_patterns *flow_patterns, struct flow_actions *flow_actions, @@ -1505,33 +1551,35 @@ create_netdev_offload(struct netdev *netdev, { struct rte_flow_attr flow_attr = { .ingress = 1, .transfer = 1, }; struct flow_actions rss_actions = { .actions = NULL, .cnt = 0 }; - struct rte_flow_item *items = flow_patterns->items; struct ufid_to_rte_flow_data *flow_data = NULL; bool actions_offloaded = true; struct rte_flow *flow = NULL; struct rte_flow_error error; if (enable_full) { - flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, items, - flow_actions, &error); + flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, + flow_patterns, flow_actions, + &error); } - if (!flow) { + if (!vport && !flow) { /* If we failed to offload the rule actions fallback to MARK+RSS * actions. */ actions_offloaded = false; flow_attr.transfer = 0; add_flow_mark_rss_actions(&rss_actions, flow_mark, netdev); - flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, items, - &rss_actions, &error); + flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, + flow_patterns, &rss_actions, + &error); free_flow_actions(&rss_actions); } if (flow) { - flow_data = ufid_to_rte_flow_associate(ufid, netdev, flow, + flow_data = ufid_to_rte_flow_associate(ufid, netdev, vport, flow, actions_offloaded); - VLOG_DBG("%s: installed flow %p by ufid "UUID_FMT, + VLOG_DBG("%s/%s: installed flow %p by ufid "UUID_FMT, + vport ? netdev_get_name(vport) : netdev_get_name(netdev), netdev_get_name(netdev), flow, UUID_ARGS((struct uuid *) ufid)); } @@ -1539,6 +1587,55 @@ create_netdev_offload(struct netdev *netdev, return flow_data; } +static struct ufid_to_rte_flow_data * +create_vport_offload(struct netdev *vport, + odp_port_t orig_in_port, + const ovs_u128 *ufid, + struct flow_patterns *flow_patterns, + struct flow_actions *flow_actions) +{ + struct flow_patterns all_patterns = { .items = NULL, .cnt = 0 }; + struct ufid_to_rte_flow_data *flows_data = NULL; + struct rte_flow_item *tnl_pmd_items; + struct rte_flow_tunnel tunnel; + struct rte_flow_error error; + uint32_t tnl_pmd_items_cnt; + struct netdev *physdev; + + physdev = netdev_ports_get(orig_in_port, vport->dpif_type); + if (physdev == NULL) { + return NULL; + } + + if (vport_to_rte_tunnel(vport, &tunnel, physdev, + &all_patterns.s_tnl)) { + goto out; + } + if (netdev_dpdk_rte_flow_tunnel_match(physdev, &tunnel, &tnl_pmd_items, + &tnl_pmd_items_cnt, &error)) { + VLOG_DBG_RL(&rl, "%s: netdev_dpdk_rte_flow_tunnel_match failed: " + "%d (%s).", netdev_get_name(physdev), error.type, + error.message); + goto out; + } + add_flow_tnl_patterns(&all_patterns, tnl_pmd_items, tnl_pmd_items_cnt, + flow_patterns); + flows_data = create_netdev_offload(physdev, vport, ufid, &all_patterns, + flow_actions, true, 0); + if (netdev_dpdk_rte_flow_tunnel_item_release(physdev, tnl_pmd_items, + tnl_pmd_items_cnt, + &error)) { + VLOG_DBG_RL(&rl, "%s: netdev_dpdk_rte_flow_tunnel_item_release " + "failed: %d (%s).", netdev_get_name(physdev), + error.type, error.message); + } +out: + all_patterns.cnt = 0; + free_flow_patterns(&all_patterns); + netdev_close(physdev); + return flows_data; +} + static struct ufid_to_rte_flow_data * netdev_offload_dpdk_add_flow(struct netdev *netdev, struct match *match, @@ -1560,8 +1657,14 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, err = parse_flow_actions(netdev, &actions, nl_actions, actions_len); - flow_data = create_netdev_offload(netdev, ufid, &patterns, &actions, !err, - info->flow_mark); + if (netdev_vport_is_vport_class(netdev->netdev_class)) { + flow_data = err ? NULL : + create_vport_offload(netdev, info->orig_in_port, ufid, &patterns, + &actions); + } else { + flow_data = create_netdev_offload(netdev, NULL, ufid, &patterns, + &actions, !err, info->flow_mark); + } out: free_flow_patterns(&patterns); @@ -1574,32 +1677,55 @@ netdev_offload_dpdk_flow_destroy(struct ufid_to_rte_flow_data *rte_flow_data) { struct rte_flow_error error; struct rte_flow *rte_flow; + struct netdev *physdev; struct netdev *netdev; ovs_u128 *ufid; int ret; rte_flow = rte_flow_data->rte_flow; + physdev = rte_flow_data->physdev; netdev = rte_flow_data->netdev; ufid = &rte_flow_data->ufid; - ret = netdev_dpdk_rte_flow_destroy(netdev, rte_flow, &error); + ret = netdev_dpdk_rte_flow_destroy(physdev, rte_flow, &error); if (ret == 0) { ufid_to_rte_flow_disassociate(rte_flow_data); - VLOG_DBG_RL(&rl, "%s: rte_flow 0x%"PRIxPTR + VLOG_DBG_RL(&rl, "%s/%s: rte_flow 0x%"PRIxPTR " flow destroy %d ufid " UUID_FMT, - netdev_get_name(netdev), (intptr_t) rte_flow, + netdev_get_name(netdev), netdev_get_name(physdev), + (intptr_t) rte_flow, netdev_dpdk_get_port_id(netdev), UUID_ARGS((struct uuid *) ufid)); } else { - VLOG_ERR("Failed flow: %s: flow destroy %d ufid " UUID_FMT, - netdev_get_name(netdev), netdev_dpdk_get_port_id(netdev), + VLOG_ERR("Failed flow: %s/%s: flow destroy %d ufid " UUID_FMT, + netdev_get_name(netdev), netdev_get_name(physdev), + netdev_dpdk_get_port_id(netdev), UUID_ARGS((struct uuid *) ufid)); } return ret; } +struct get_netdev_odp_aux { + struct netdev *netdev; + odp_port_t odp_port; +}; + +static bool +get_netdev_odp_cb(struct netdev *netdev, + odp_port_t odp_port, + void *aux_) +{ + struct get_netdev_odp_aux *aux = aux_; + + if (netdev == aux->netdev) { + aux->odp_port = odp_port; + return true; + } + return false; +} + static int netdev_offload_dpdk_flow_put(struct netdev *netdev, struct match *match, struct nlattr *actions, size_t actions_len, @@ -1618,6 +1744,17 @@ netdev_offload_dpdk_flow_put(struct netdev *netdev, struct match *match, */ rte_flow_data = ufid_to_rte_flow_data_find(ufid, false); if (rte_flow_data && rte_flow_data->rte_flow) { + struct get_netdev_odp_aux aux = { + .netdev = rte_flow_data->physdev, + .odp_port = ODPP_NONE, + }; + + /* Extract the orig_in_port from physdev as in case of modify the one + * provided by upper layer cannot be used. + */ + netdev_ports_traverse(rte_flow_data->physdev->dpif_type, + get_netdev_odp_cb, &aux); + info->orig_in_port = aux.odp_port; old_stats = rte_flow_data->stats; modification = true; ret = netdev_offload_dpdk_flow_destroy(rte_flow_data); @@ -1698,8 +1835,9 @@ netdev_offload_dpdk_flow_get(struct netdev *netdev, goto out; } attrs->dp_layer = "dpdk"; - ret = netdev_dpdk_rte_flow_query_count(netdev, rte_flow_data->rte_flow, - &query, &error); + ret = netdev_dpdk_rte_flow_query_count(rte_flow_data->physdev, + rte_flow_data->rte_flow, &query, + &error); if (ret) { VLOG_DBG_RL(&rl, "%s: Failed to query ufid "UUID_FMT" flow: %p", netdev_get_name(netdev), UUID_ARGS((struct uuid *) ufid), @@ -1723,7 +1861,7 @@ netdev_offload_dpdk_flow_flush(struct netdev *netdev) struct ufid_to_rte_flow_data *data; CMAP_FOR_EACH (data, node, &ufid_to_rte_flow) { - if (data->netdev != netdev) { + if (data->netdev != netdev && data->physdev != netdev) { continue; } From patchwork Wed Mar 17 06:35:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1454462 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F0gQv2rrLz9sVm for ; Wed, 17 Mar 2021 17:36:07 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 67CD74EE26; Wed, 17 Mar 2021 06:36:04 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id r22FKoH0y0mX; Wed, 17 Mar 2021 06:36:01 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp4.osuosl.org (Postfix) with ESMTP id 0CFD74EDED; Wed, 17 Mar 2021 06:35:59 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 47E50C0026; Wed, 17 Mar 2021 06:35:55 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 33245C000C for ; Wed, 17 Mar 2021 06:35:50 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 0E1724ED34 for ; Wed, 17 Mar 2021 06:35:50 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ck9iedi4y1CV for ; Wed, 17 Mar 2021 06:35:49 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp4.osuosl.org (Postfix) with ESMTP id 6A3274ECAE for ; Wed, 17 Mar 2021 06:35:48 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 17 Mar 2021 08:35:43 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 12H6ZfYv031345; Wed, 17 Mar 2021 08:35:42 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 17 Mar 2021 06:35:38 +0000 Message-Id: <20210317063538.12451-15-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210317063538.12451-1-elibr@nvidia.com> References: <20210317063538.12451-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH V4 14/14] netdev-dpdk-offload: Add vxlan pattern matching function X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" For VXLAN offload, matches should be done on outer header for tunnel properties as well as inner packet matches. Add a function for parsing VXLAN tunnel matches. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- NEWS | 1 + lib/netdev-offload-dpdk.c | 169 +++++++++++++++++++++++++++++++++++++- 2 files changed, 168 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index a5d103b1d..f706e4783 100644 --- a/NEWS +++ b/NEWS @@ -31,6 +31,7 @@ v2.15.0 - 15 Feb 2021 * Removed support for vhost-user dequeue zero-copy. * Add support for DPDK 20.11. * Add hardware offload support for tunnel pop action (experimental). + * Add hardware offload support for VXLAN flows (experimental). - Userspace datapath: * Add the 'pmd' option to "ovs-appctl dpctl/dump-flows", which restricts a flow dump to a single PMD thread if set. diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index 69aaefa0f..63e9bd474 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -369,6 +369,20 @@ dump_flow_pattern(struct ds *s, ipv6_mask->hdr.hop_limits); } ds_put_cstr(s, "/ "); + } else if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN) { + const struct rte_flow_item_vxlan *vxlan_spec = item->spec; + const struct rte_flow_item_vxlan *vxlan_mask = item->mask; + + ds_put_cstr(s, "vxlan "); + if (vxlan_spec) { + if (!vxlan_mask) { + vxlan_mask = &rte_flow_item_vxlan_mask; + } + DUMP_PATTERN_ITEM(vxlan_mask->vni, "vni", "%"PRIu32, + ntohl(*(ovs_be32 *) vxlan_spec->vni) >> 8, + ntohl(*(ovs_be32 *) vxlan_mask->vni) >> 8); + } + ds_put_cstr(s, "/ "); } else { ds_put_format(s, "unknown rte flow pattern (%d)\n", item->type); } @@ -788,7 +802,154 @@ free_flow_actions(struct flow_actions *actions) } static int -parse_flow_match(struct flow_patterns *patterns, +parse_tnl_ip_match(struct flow_patterns *patterns, + struct match *match, + uint8_t proto) +{ + struct flow *consumed_masks; + + consumed_masks = &match->wc.masks; + /* IP v4 */ + if (match->wc.masks.tunnel.ip_src || match->wc.masks.tunnel.ip_dst) { + struct rte_flow_item_ipv4 *spec, *mask; + + spec = xzalloc(sizeof *spec); + mask = xzalloc(sizeof *mask); + + spec->hdr.type_of_service = match->flow.tunnel.ip_tos; + spec->hdr.time_to_live = match->flow.tunnel.ip_ttl; + spec->hdr.next_proto_id = proto; + spec->hdr.src_addr = match->flow.tunnel.ip_src; + spec->hdr.dst_addr = match->flow.tunnel.ip_dst; + + mask->hdr.type_of_service = match->wc.masks.tunnel.ip_tos; + mask->hdr.time_to_live = match->wc.masks.tunnel.ip_ttl; + mask->hdr.next_proto_id = UINT8_MAX; + mask->hdr.src_addr = match->wc.masks.tunnel.ip_src; + mask->hdr.dst_addr = match->wc.masks.tunnel.ip_dst; + + consumed_masks->tunnel.ip_tos = 0; + consumed_masks->tunnel.ip_ttl = 0; + consumed_masks->tunnel.ip_src = 0; + consumed_masks->tunnel.ip_dst = 0; + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV4, spec, mask); + } else if (!is_all_zeros(&match->wc.masks.tunnel.ipv6_src, + sizeof(struct in6_addr)) || + !is_all_zeros(&match->wc.masks.tunnel.ipv6_dst, + sizeof(struct in6_addr))) { + /* IP v6 */ + struct rte_flow_item_ipv6 *spec, *mask; + + spec = xzalloc(sizeof *spec); + mask = xzalloc(sizeof *mask); + + spec->hdr.proto = proto; + spec->hdr.hop_limits = match->flow.tunnel.ip_ttl; + spec->hdr.vtc_flow = htonl((uint32_t) match->flow.tunnel.ip_tos << + RTE_IPV6_HDR_TC_SHIFT); + memcpy(spec->hdr.src_addr, &match->flow.tunnel.ipv6_src, + sizeof spec->hdr.src_addr); + memcpy(spec->hdr.dst_addr, &match->flow.tunnel.ipv6_dst, + sizeof spec->hdr.dst_addr); + + mask->hdr.proto = UINT8_MAX; + mask->hdr.hop_limits = match->wc.masks.tunnel.ip_ttl; + mask->hdr.vtc_flow = htonl((uint32_t) match->wc.masks.tunnel.ip_tos << + RTE_IPV6_HDR_TC_SHIFT); + memcpy(mask->hdr.src_addr, &match->wc.masks.tunnel.ipv6_src, + sizeof mask->hdr.src_addr); + memcpy(mask->hdr.dst_addr, &match->wc.masks.tunnel.ipv6_dst, + sizeof mask->hdr.dst_addr); + + consumed_masks->tunnel.ip_tos = 0; + consumed_masks->tunnel.ip_ttl = 0; + memset(&consumed_masks->tunnel.ipv6_src, 0, + sizeof consumed_masks->tunnel.ipv6_src); + memset(&consumed_masks->tunnel.ipv6_dst, 0, + sizeof consumed_masks->tunnel.ipv6_dst); + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV6, spec, mask); + } else { + VLOG_ERR_RL(&rl, "Tunnel L3 protocol is neither IPv4 nor IPv6"); + return -1; + } + + return 0; +} + +static void +parse_tnl_udp_match(struct flow_patterns *patterns, + struct match *match) +{ + struct flow *consumed_masks; + struct rte_flow_item_udp *spec, *mask; + + consumed_masks = &match->wc.masks; + + spec = xzalloc(sizeof *spec); + mask = xzalloc(sizeof *mask); + + spec->hdr.src_port = match->flow.tunnel.tp_src; + spec->hdr.dst_port = match->flow.tunnel.tp_dst; + + mask->hdr.src_port = match->wc.masks.tunnel.tp_src; + mask->hdr.dst_port = match->wc.masks.tunnel.tp_dst; + + consumed_masks->tunnel.tp_src = 0; + consumed_masks->tunnel.tp_dst = 0; + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_UDP, spec, mask); +} + +static int +parse_vxlan_match(struct flow_patterns *patterns, + struct match *match) +{ + struct rte_flow_item_vxlan *vx_spec, *vx_mask; + struct flow *consumed_masks; + int ret; + + ret = parse_tnl_ip_match(patterns, match, IPPROTO_UDP); + if (ret) { + return -1; + } + parse_tnl_udp_match(patterns, match); + + consumed_masks = &match->wc.masks; + /* VXLAN */ + vx_spec = xzalloc(sizeof *vx_spec); + vx_mask = xzalloc(sizeof *vx_mask); + + put_unaligned_be32((ovs_be32 *) vx_spec->vni, + htonl(ntohll(match->flow.tunnel.tun_id) << 8)); + put_unaligned_be32((ovs_be32 *) vx_mask->vni, + htonl(ntohll(match->wc.masks.tunnel.tun_id) << 8)); + + consumed_masks->tunnel.tun_id = 0; + consumed_masks->tunnel.flags = 0; + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_VXLAN, vx_spec, vx_mask); + return 0; +} + +static int +parse_flow_tnl_match(struct netdev *tnldev, + struct flow_patterns *patterns, + struct match *match) +{ + if (!netdev_vport_is_vport_class(tnldev->netdev_class)) { + return -1; + } + if (!strcmp(netdev_get_type(tnldev), "vxlan")) { + return parse_vxlan_match(patterns, match); + } + return -1; +} + +static int +parse_flow_match(struct netdev *netdev, + struct flow_patterns *patterns, struct match *match) { struct flow *consumed_masks; @@ -798,6 +959,10 @@ parse_flow_match(struct flow_patterns *patterns, if (!flow_tnl_dst_is_set(&match->flow.tunnel)) { memset(&consumed_masks->tunnel, 0, sizeof consumed_masks->tunnel); + } else { + if (parse_flow_tnl_match(netdev, patterns, match)) { + return -1; + } } memset(&consumed_masks->in_port, 0, sizeof consumed_masks->in_port); @@ -1649,7 +1814,7 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, struct ufid_to_rte_flow_data *flow_data = NULL; int err; - if (parse_flow_match(&patterns, match)) { + if (parse_flow_match(netdev, &patterns, match)) { VLOG_DBG_RL(&rl, "%s: matches of ufid "UUID_FMT" are not supported", netdev_get_name(netdev), UUID_ARGS((struct uuid *) ufid)); goto out;