From patchwork Sun Apr 4 09:54:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1462063 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 4FCq0N2KZSz9sV5 for ; Sun, 4 Apr 2021 19:55:16 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 1DC5C402EF; Sun, 4 Apr 2021 09:55:12 +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 0bw28ggzfefc; Sun, 4 Apr 2021 09:55:11 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTP id D26F6402C3; Sun, 4 Apr 2021 09:55:09 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 54A44C0020; Sun, 4 Apr 2021 09:55:07 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5D5C0C000A for ; Sun, 4 Apr 2021 09:55:03 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 4938D41835 for ; Sun, 4 Apr 2021 09:55:03 +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 gm_3FGKOoHpC for ; Sun, 4 Apr 2021 09:55:02 +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 AF4AA414EC for ; Sun, 4 Apr 2021 09:55:01 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 4 Apr 2021 12:54:58 +0300 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 1349sw7x021189; Sun, 4 Apr 2021 12:54:58 +0300 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Sun, 4 Apr 2021 09:54:44 +0000 Message-Id: <20210404095456.27190-2-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210404095456.27190-1-elibr@nvidia.com> References: <20210404095456.27190-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny Subject: [ovs-dev] [PATCH V6 01/13] 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 Sun Apr 4 09:54:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1462064 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 4FCq0Q6FNzz9sV5 for ; Sun, 4 Apr 2021 19:55:18 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 57BA46082E; Sun, 4 Apr 2021 09:55:17 +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 KWdMDp9YEquX; Sun, 4 Apr 2021 09:55:14 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTP id 4901860813; Sun, 4 Apr 2021 09:55:13 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id A874DC0025; Sun, 4 Apr 2021 09:55:09 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) by lists.linuxfoundation.org (Postfix) with ESMTP id AE43CC000A for ; Sun, 4 Apr 2021 09:55:04 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 53DBB414EC for ; Sun, 4 Apr 2021 09:55:03 +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 SFVoAUXZ7UfL for ; Sun, 4 Apr 2021 09:55:02 +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 8155B4069A for ; Sun, 4 Apr 2021 09:55:01 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 4 Apr 2021 12:54:58 +0300 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 1349sw80021189; Sun, 4 Apr 2021 12:54:58 +0300 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Sun, 4 Apr 2021 09:54:45 +0000 Message-Id: <20210404095456.27190-3-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210404095456.27190-1-elibr@nvidia.com> References: <20210404095456.27190-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny Subject: [ovs-dev] [PATCH V6 02/13] 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 Sun Apr 4 09:54:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1462060 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 4FCq0D4l4mz9sV5 for ; Sun, 4 Apr 2021 19:55:08 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 855A34017E; Sun, 4 Apr 2021 09:55:06 +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 HJjIR_0l1FsD; Sun, 4 Apr 2021 09:55:05 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp2.osuosl.org (Postfix) with ESMTP id C3486400CC; Sun, 4 Apr 2021 09:55:04 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 8A0E7C000D; Sun, 4 Apr 2021 09:55:04 +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 2B8C0C000A for ; Sun, 4 Apr 2021 09:55:03 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 195F084D3A for ; Sun, 4 Apr 2021 09:55:03 +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 CcdSMtxCunvY for ; Sun, 4 Apr 2021 09:55:02 +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 75B9084A9F for ; Sun, 4 Apr 2021 09:55:01 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 4 Apr 2021 12:54:58 +0300 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 1349sw81021189; Sun, 4 Apr 2021 12:54:58 +0300 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Sun, 4 Apr 2021 09:54:46 +0000 Message-Id: <20210404095456.27190-4-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210404095456.27190-1-elibr@nvidia.com> References: <20210404095456.27190-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny Subject: [ovs-dev] [PATCH V6 03/13] 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 Sun Apr 4 09:54:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1462067 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 4FCq0X6p1Vz9sV5 for ; Sun, 4 Apr 2021 19:55:24 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 321406081E; Sun, 4 Apr 2021 09:55: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 5VyoDU1nKn6y; Sun, 4 Apr 2021 09:55:20 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTP id C0A5660E90; Sun, 4 Apr 2021 09:55:16 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 06901C002C; Sun, 4 Apr 2021 09:55:12 +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 2994EC000B for ; Sun, 4 Apr 2021 09:55:05 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id B8881607FF for ; Sun, 4 Apr 2021 09:55:03 +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 BPx4R5xfaVc4 for ; Sun, 4 Apr 2021 09:55:03 +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 B0AE160800 for ; Sun, 4 Apr 2021 09:55:01 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 4 Apr 2021 12:54:59 +0300 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 1349sw82021189; Sun, 4 Apr 2021 12:54:58 +0300 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Sun, 4 Apr 2021 09:54:47 +0000 Message-Id: <20210404095456.27190-5-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210404095456.27190-1-elibr@nvidia.com> References: <20210404095456.27190-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny Subject: [ovs-dev] [PATCH V6 04/13] 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 Sun Apr 4 09:54:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1462065 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 4FCq0R71l7z9sV5 for ; Sun, 4 Apr 2021 19:55:19 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id E098C402F7; Sun, 4 Apr 2021 09:55:13 +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 ZflntVj6j8TZ; Sun, 4 Apr 2021 09:55:12 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp2.osuosl.org (Postfix) with ESMTP id 291CE402E2; Sun, 4 Apr 2021 09:55:11 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7BE70C000B; Sun, 4 Apr 2021 09:55:08 +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 252E9C000A for ; Sun, 4 Apr 2021 09:55:04 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 43FFD607FC for ; Sun, 4 Apr 2021 09:55:03 +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 G5iEm41AmzcM for ; Sun, 4 Apr 2021 09:55:02 +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 89C0A607FF for ; Sun, 4 Apr 2021 09:55:01 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 4 Apr 2021 12:54:59 +0300 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 1349sw83021189; Sun, 4 Apr 2021 12:54:58 +0300 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Sun, 4 Apr 2021 09:54:48 +0000 Message-Id: <20210404095456.27190-6-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210404095456.27190-1-elibr@nvidia.com> References: <20210404095456.27190-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny Subject: [ovs-dev] [PATCH V6 05/13] 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 | 152 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index f2413f5be..d40b56207 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -1588,6 +1588,157 @@ 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; + } + /* Change the in_port to the vport's one, in order to continue packet + * processing in SW. + */ + 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 +1746,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 Sun Apr 4 09:54:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1462062 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 4FCq0L12R6z9sV5 for ; Sun, 4 Apr 2021 19:55:14 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id B1D5D84D61; Sun, 4 Apr 2021 09:55:10 +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 kzeXbIY8Wcxg; Sun, 4 Apr 2021 09:55:09 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTP id 8BA2884D58; Sun, 4 Apr 2021 09:55:08 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 73CC2C001A; Sun, 4 Apr 2021 09:55:06 +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 45DC0C000D for ; Sun, 4 Apr 2021 09:55:03 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 2DEC160801 for ; Sun, 4 Apr 2021 09:55:03 +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 sOOyA3UQ2Zf1 for ; Sun, 4 Apr 2021 09:55:02 +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 7BFBE607FC for ; Sun, 4 Apr 2021 09:55:01 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 4 Apr 2021 12:54:59 +0300 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 1349sw84021189; Sun, 4 Apr 2021 12:54:59 +0300 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Sun, 4 Apr 2021 09:54:49 +0000 Message-Id: <20210404095456.27190-7-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210404095456.27190-1-elibr@nvidia.com> References: <20210404095456.27190-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny Subject: [ovs-dev] [PATCH V6 06/13] 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 251788b04..2345df500 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -7064,6 +7064,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 @@ -7108,7 +7146,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); @@ -7127,24 +7164,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 Sun Apr 4 09:54:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1462061 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 4FCq0H1QjQz9sV5 for ; Sun, 4 Apr 2021 19:55:11 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 28FD384D6C; Sun, 4 Apr 2021 09:55:09 +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 MyIDejBJJmFs; Sun, 4 Apr 2021 09:55:08 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp1.osuosl.org (Postfix) with ESMTP id 6736384D3A; Sun, 4 Apr 2021 09:55:07 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 94377C0015; Sun, 4 Apr 2021 09:55:05 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 38DD3C000B for ; Sun, 4 Apr 2021 09:55:03 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 14391400D2 for ; Sun, 4 Apr 2021 09:55:03 +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 kehG1Q-GwPk3 for ; Sun, 4 Apr 2021 09:55:02 +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 ADF77400CC for ; Sun, 4 Apr 2021 09:55:01 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 4 Apr 2021 12:54:59 +0300 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 1349sw85021189; Sun, 4 Apr 2021 12:54:59 +0300 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Sun, 4 Apr 2021 09:54:50 +0000 Message-Id: <20210404095456.27190-8-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210404095456.27190-1-elibr@nvidia.com> References: <20210404095456.27190-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny Subject: [ovs-dev] [PATCH V6 07/13] 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 Sun Apr 4 09:54:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1462068 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 4FCq0c0wFLz9sV5 for ; Sun, 4 Apr 2021 19:55:28 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id D3BE94183A; Sun, 4 Apr 2021 09:55:25 +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 faWBDeql9erP; Sun, 4 Apr 2021 09:55:23 +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 99D35404D9; Sun, 4 Apr 2021 09:55:21 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 62AA0C0030; Sun, 4 Apr 2021 09:55:14 +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 0F7FAC000D for ; Sun, 4 Apr 2021 09:55:06 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 135CB60800 for ; Sun, 4 Apr 2021 09:55:04 +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 W-8KbimaJ_xN for ; Sun, 4 Apr 2021 09:55:02 +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 7AFD8607F6 for ; Sun, 4 Apr 2021 09:55:01 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 4 Apr 2021 12:54:59 +0300 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 1349sw86021189; Sun, 4 Apr 2021 12:54:59 +0300 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Sun, 4 Apr 2021 09:54:51 +0000 Message-Id: <20210404095456.27190-9-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210404095456.27190-1-elibr@nvidia.com> References: <20210404095456.27190-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny Subject: [ovs-dev] [PATCH V6 08/13] 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 2345df500..c93a95a9f 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -2698,8 +2698,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 d40b56207..04cc7d0fe 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 Sun Apr 4 09:54:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1462073 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 4FCq0x5bG3z9sV5 for ; Sun, 4 Apr 2021 19:55:45 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 31560402CD; Sun, 4 Apr 2021 09:55:44 +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 DBY4AQxW1yER; Sun, 4 Apr 2021 09:55:43 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTP id CE83341922; Sun, 4 Apr 2021 09:55:26 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id D146BC0026; Sun, 4 Apr 2021 09:55:16 +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 0F53EC000B for ; Sun, 4 Apr 2021 09:55:08 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 98D69607F9 for ; Sun, 4 Apr 2021 09:55:04 +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 xw87wVlLwrHd for ; Sun, 4 Apr 2021 09:55:02 +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 7AF97607BE for ; Sun, 4 Apr 2021 09:55:01 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 4 Apr 2021 12:54:59 +0300 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 1349sw87021189; Sun, 4 Apr 2021 12:54:59 +0300 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Sun, 4 Apr 2021 09:54:52 +0000 Message-Id: <20210404095456.27190-10-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210404095456.27190-1-elibr@nvidia.com> References: <20210404095456.27190-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny Subject: [ovs-dev] [PATCH V6 09/13] 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 04cc7d0fe..3b86bc5f9 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 Sun Apr 4 09:54:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1462069 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 4FCq0c6QBLz9sVw for ; Sun, 4 Apr 2021 19:55:28 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 0E12260EEF; Sun, 4 Apr 2021 09:55:27 +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 G6E0-s8TS1eO; Sun, 4 Apr 2021 09:55:23 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTP id 8F64E60E9E; Sun, 4 Apr 2021 09:55:18 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id B77EDC0011; Sun, 4 Apr 2021 09:55:12 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 62CEAC000B for ; Sun, 4 Apr 2021 09:55:05 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 8DF614069A for ; Sun, 4 Apr 2021 09:55:03 +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 9gKcqx7Me__9 for ; Sun, 4 Apr 2021 09:55:02 +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 AE17E40E9B for ; Sun, 4 Apr 2021 09:55:01 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 4 Apr 2021 12:54:59 +0300 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 1349sw88021189; Sun, 4 Apr 2021 12:54:59 +0300 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Sun, 4 Apr 2021 09:54:53 +0000 Message-Id: <20210404095456.27190-11-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210404095456.27190-1-elibr@nvidia.com> References: <20210404095456.27190-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny Subject: [ovs-dev] [PATCH V6 10/13] 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 95cf922aa..74eed0a6c 100644 --- a/NEWS +++ b/NEWS @@ -33,6 +33,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 3b86bc5f9..315575c38 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,34 @@ free_flow_actions(struct flow_actions *actions) free(actions->actions); actions->actions = NULL; actions->cnt = 0; + ds_destroy(&actions->s_tnl); +} + +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 @@ -960,7 +1056,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 +1403,59 @@ 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 +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 Sun Apr 4 09:54:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1462066 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.138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.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 4FCq0S28Vjz9sVw for ; Sun, 4 Apr 2021 19:55:20 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 5E91A84FB0; Sun, 4 Apr 2021 09:55:18 +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 816q_LmC-y1G; Sun, 4 Apr 2021 09:55:16 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTP id AC09184D4C; Sun, 4 Apr 2021 09:55:14 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 9A871C0027; Sun, 4 Apr 2021 09:55:10 +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 C894AC0013 for ; Sun, 4 Apr 2021 09:55:04 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 5300284A9F for ; Sun, 4 Apr 2021 09:55:03 +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 jVlMcd_RAdYS for ; Sun, 4 Apr 2021 09:55:02 +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 ADA4484D02 for ; Sun, 4 Apr 2021 09:55:01 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 4 Apr 2021 12:54:59 +0300 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 1349sw89021189; Sun, 4 Apr 2021 12:54:59 +0300 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Sun, 4 Apr 2021 09:54:54 +0000 Message-Id: <20210404095456.27190-12-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210404095456.27190-1-elibr@nvidia.com> References: <20210404095456.27190-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny Subject: [ovs-dev] [PATCH V6 11/13] 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 c93a95a9f..b6b4125ed 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -431,6 +431,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; }; @@ -2696,11 +2697,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); @@ -2798,7 +2801,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; @@ -2824,6 +2828,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); } @@ -3625,7 +3630,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; @@ -3691,7 +3697,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; @@ -3762,7 +3769,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; } @@ -3778,7 +3785,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); @@ -7256,6 +7263,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); @@ -7305,7 +7313,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 Sun Apr 4 09:54:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1462071 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 4FCq0q0dwGz9sV5 for ; Sun, 4 Apr 2021 19:55:39 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 01FC541974; Sun, 4 Apr 2021 09:55:37 +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 dllJySMFYxhu; Sun, 4 Apr 2021 09:55:34 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTP id 9C59C418FB; Sun, 4 Apr 2021 09:55:23 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 68EB1C0035; Sun, 4 Apr 2021 09:55:15 +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 D4E7EC001D for ; Sun, 4 Apr 2021 09:55:06 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 9864084C1D for ; Sun, 4 Apr 2021 09:55:03 +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 32QumF0EFO7N for ; Sun, 4 Apr 2021 09:55:02 +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 78C6184C19 for ; Sun, 4 Apr 2021 09:55:01 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 4 Apr 2021 12:54:59 +0300 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 1349sw8A021189; Sun, 4 Apr 2021 12:54:59 +0300 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Sun, 4 Apr 2021 09:54:55 +0000 Message-Id: <20210404095456.27190-13-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210404095456.27190-1-elibr@nvidia.com> References: <20210404095456.27190-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny Subject: [ovs-dev] [PATCH V6 12/13] 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 | 216 ++++++++++++++++++++++++++++++++------ 1 file changed, 183 insertions(+), 33 deletions(-) diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index 315575c38..197deb96b 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 *physdev, 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); @@ -106,6 +109,7 @@ ufid_to_rte_flow_associate(const ovs_u128 *ufid, struct netdev *netdev, data->ufid = *ufid; data->netdev = netdev_ref(netdev); + data->physdev = netdev != physdev ? netdev_ref(physdev) : physdev; 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,11 @@ struct flow_patterns { struct rte_flow_item *items; int cnt; int current_max; + struct netdev *physdev; + /* tnl_pmd_items is the opaque array of items returned by the PMD. */ + struct rte_flow_item *tnl_pmd_items; + uint32_t tnl_pmd_items_cnt; + struct ds s_tnl; }; struct flow_actions { @@ -154,16 +166,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 +193,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 +594,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 +616,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 +630,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 +645,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, @@ -693,12 +719,44 @@ add_flow_tnl_actions(struct flow_actions *actions, } } +static void +add_flow_tnl_items(struct flow_patterns *patterns, + struct netdev *physdev, + struct rte_flow_item *tnl_pmd_items, + uint32_t tnl_pmd_items_cnt) +{ + int i; + + patterns->physdev = physdev; + patterns->tnl_pmd_items = tnl_pmd_items; + patterns->tnl_pmd_items_cnt = tnl_pmd_items_cnt; + for (i = 0; i < tnl_pmd_items_cnt; i++) { + add_flow_pattern(patterns, tnl_pmd_items[i].type, + tnl_pmd_items[i].spec, tnl_pmd_items[i].mask); + } +} + static void free_flow_patterns(struct flow_patterns *patterns) { + struct rte_flow_error error; int i; - for (i = 0; i < patterns->cnt; i++) { + if (patterns->tnl_pmd_items) { + struct rte_flow_item *tnl_pmd_items = patterns->tnl_pmd_items; + uint32_t tnl_pmd_items_cnt = patterns->tnl_pmd_items_cnt; + struct netdev *physdev = patterns->physdev; + + 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); + } + } + + for (i = patterns->tnl_pmd_items_cnt; i < patterns->cnt; i++) { if (patterns->items[i].spec) { free(CONST_CAST(void *, patterns->items[i].spec)); } @@ -770,7 +828,58 @@ vport_to_rte_tunnel(struct netdev *vport, } static int -parse_flow_match(struct flow_patterns *patterns, +add_vport_match(struct flow_patterns *patterns, + odp_port_t orig_in_port, + struct netdev *tnldev) +{ + 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; + int ret; + + physdev = netdev_ports_get(orig_in_port, tnldev->dpif_type); + if (physdev == NULL) { + return -1; + } + + ret = vport_to_rte_tunnel(tnldev, &tunnel, physdev, &patterns->s_tnl); + if (ret) { + goto out; + } + ret = netdev_dpdk_rte_flow_tunnel_match(physdev, &tunnel, &tnl_pmd_items, + &tnl_pmd_items_cnt, &error); + if (ret) { + 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_items(patterns, physdev, tnl_pmd_items, tnl_pmd_items_cnt); + +out: + netdev_close(physdev); + return ret; +} + +static int +parse_flow_tnl_match(struct netdev *tnldev, + struct flow_patterns *patterns, + odp_port_t orig_in_port, + struct match *match OVS_UNUSED) +{ + int ret; + + ret = add_vport_match(patterns, orig_in_port, tnldev); + + return ret; +} + +static int +parse_flow_match(struct netdev *netdev, + odp_port_t orig_in_port, + struct flow_patterns *patterns, struct match *match) { struct flow *consumed_masks; @@ -782,6 +891,11 @@ parse_flow_match(struct flow_patterns *patterns, memset(&consumed_masks->tunnel, 0, sizeof consumed_masks->tunnel); } + patterns->physdev = netdev; + if (netdev_vport_is_vport_class(netdev->netdev_class) && + parse_flow_tnl_match(netdev, patterns, orig_in_port, match)) { + return -1; + } memset(&consumed_masks->in_port, 0, sizeof consumed_masks->in_port); /* recirc id must be zero. */ if (match->wc.masks.recirc_id & match->flow.recirc_id) { @@ -1055,7 +1169,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, + flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns, &actions, &error); free_flow_actions(&actions); @@ -1535,7 +1649,7 @@ netdev_offload_dpdk_actions(struct netdev *netdev, if (ret) { goto out; } - flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns->items, + flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns, &actions, &error); out: free_flow_actions(&actions); @@ -1555,15 +1669,15 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, bool actions_offloaded = true; struct rte_flow *flow; - if (parse_flow_match(&patterns, match)) { + if (parse_flow_match(netdev, info->orig_in_port, &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; } - flow = netdev_offload_dpdk_actions(netdev, &patterns, nl_actions, + flow = netdev_offload_dpdk_actions(patterns.physdev, &patterns, nl_actions, actions_len); - if (!flow) { + if (!flow && !netdev_vport_is_vport_class(netdev->netdev_class)) { /* If we failed to offload the rule actions fallback to MARK+RSS * actions. */ @@ -1575,10 +1689,11 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, 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)); + flows_data = ufid_to_rte_flow_associate(ufid, netdev, patterns.physdev, + flow, actions_offloaded); + VLOG_DBG("%s/%s: installed flow %p by ufid "UUID_FMT, + netdev_get_name(netdev), netdev_get_name(patterns.physdev), flow, + UUID_ARGS((struct uuid *) ufid)); out: free_flow_patterns(&patterns); @@ -1590,32 +1705,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, @@ -1634,6 +1772,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); @@ -1714,8 +1863,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), @@ -1739,7 +1889,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 Sun Apr 4 09:54:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1462072 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 4FCq0t0RNcz9sV5 for ; Sun, 4 Apr 2021 19:55:42 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 58D0B4191A; Sun, 4 Apr 2021 09:55:40 +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 dTklxQ1pL0U9; Sun, 4 Apr 2021 09:55:38 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp2.osuosl.org (Postfix) with ESMTP id 2EF154190C; Sun, 4 Apr 2021 09:55:25 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 159C5C003C; Sun, 4 Apr 2021 09:55:16 +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 34C5CC0011 for ; Sun, 4 Apr 2021 09:55:07 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 595F9607FC for ; Sun, 4 Apr 2021 09:55:04 +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 jjhD_zLpCuAA for ; Sun, 4 Apr 2021 09:55:02 +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 7B008607F9 for ; Sun, 4 Apr 2021 09:55:01 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 4 Apr 2021 12:54:59 +0300 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 1349sw8B021189; Sun, 4 Apr 2021 12:54:59 +0300 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Sun, 4 Apr 2021 09:54:56 +0000 Message-Id: <20210404095456.27190-14-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.2311.g225365fb51 In-Reply-To: <20210404095456.27190-1-elibr@nvidia.com> References: <20210404095456.27190-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ivan.Malov@oktetlabs.ru, Ameer Mahagneh , Majd Dibbiny Subject: [ovs-dev] [PATCH V6 13/13] 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 | 155 +++++++++++++++++++++++++++++++++++++- 2 files changed, 155 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 74eed0a6c..2fee43b9a 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,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 197deb96b..52a74a707 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -372,6 +372,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); } @@ -863,15 +877,154 @@ out: return ret; } +static int +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, odp_port_t orig_in_port, - struct match *match OVS_UNUSED) + struct match *match) { int ret; ret = add_vport_match(patterns, orig_in_port, tnldev); + if (ret) { + return ret; + } + + if (!strcmp(netdev_get_type(tnldev), "vxlan")) { + ret = parse_vxlan_match(patterns, match); + } return ret; }