From patchwork Wed Jan 27 18:10:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1432295 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=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DQs9j1fqVz9sBy for ; Thu, 28 Jan 2021 05:11:21 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id C8A7F8727D; Wed, 27 Jan 2021 18:11:19 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id BVg5rS5iZ7ad; Wed, 27 Jan 2021 18:11:17 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id CA51487247; Wed, 27 Jan 2021 18:11:07 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id AD58DC1E84; Wed, 27 Jan 2021 18:11:07 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id B0330C013A for ; Wed, 27 Jan 2021 18:10:56 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 951138727D for ; Wed, 27 Jan 2021 18:10:56 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9WaSqTUTLnFp for ; Wed, 27 Jan 2021 18:10:55 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by hemlock.osuosl.org (Postfix) with ESMTP id 1409B87264 for ; Wed, 27 Jan 2021 18:10:54 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 27 Jan 2021 20:10:43 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10RIAhXi027513; Wed, 27 Jan 2021 20:10:43 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 27 Jan 2021 18:10:22 +0000 Message-Id: <20210127181036.32448-2-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.546.g385c171 In-Reply-To: <20210127181036.32448-1-elibr@nvidia.com> References: <20210127181036.32448-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH 01/15] 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. Add API for that. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/netdev-offload-provider.h | 5 +++++ lib/netdev-offload.c | 12 ++++++++++++ lib/netdev-offload.h | 1 + 3 files changed, 18 insertions(+) diff --git a/lib/netdev-offload-provider.h b/lib/netdev-offload-provider.h index cf859d1b4..f24c7dd19 100644 --- a/lib/netdev-offload-provider.h +++ b/lib/netdev-offload-provider.h @@ -87,6 +87,11 @@ struct netdev_flow_api { * Return 0 if successful, otherwise returns a positive errno value. */ int (*flow_get_n_flows)(struct netdev *, uint64_t *n_flows); + /* Recover the packet state (contents and data) for continued processing + * in software. + * Return 0 if successful, otherwise returns a positive errno value. */ + int (*hw_miss_packet_recover)(struct netdev *, struct dp_packet *); + /* Initializies the netdev flow api. * Return 0 if successful, otherwise returns a positive errno value. */ int (*init_flow_api)(struct netdev *); diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c index 6237667c3..e5d24651f 100644 --- a/lib/netdev-offload.c +++ b/lib/netdev-offload.c @@ -253,6 +253,18 @@ netdev_flow_put(struct netdev *netdev, struct match *match, : EOPNOTSUPP; } +int +netdev_hw_miss_packet_recover(struct netdev *netdev, + struct dp_packet *packet) +{ + const struct netdev_flow_api *flow_api = + ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api); + + return (flow_api && flow_api->hw_miss_packet_recover) + ? flow_api->hw_miss_packet_recover(netdev, packet) + : EOPNOTSUPP; +} + int netdev_flow_get(struct netdev *netdev, struct match *match, struct nlattr **actions, const ovs_u128 *ufid, diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h index 18b48790f..b063c43a3 100644 --- a/lib/netdev-offload.h +++ b/lib/netdev-offload.h @@ -89,6 +89,7 @@ bool netdev_flow_dump_next(struct netdev_flow_dump *, struct match *, int netdev_flow_put(struct netdev *, struct match *, struct nlattr *actions, size_t actions_len, const ovs_u128 *, struct offload_info *, struct dpif_flow_stats *); +int netdev_hw_miss_packet_recover(struct netdev *, struct dp_packet *); int netdev_flow_get(struct netdev *, struct match *, struct nlattr **actions, const ovs_u128 *, struct dpif_flow_stats *, struct dpif_flow_attrs *, struct ofpbuf *wbuffer); From patchwork Wed Jan 27 18:10:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1432301 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=whitealder.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DQsC20qCrz9sBy for ; Thu, 28 Jan 2021 05:12:30 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 5C06E86D4A; Wed, 27 Jan 2021 18:12:28 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id F76KBLw9p6uR; Wed, 27 Jan 2021 18:12:19 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by whitealder.osuosl.org (Postfix) with ESMTP id B271486D0B; Wed, 27 Jan 2021 18:11:16 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 81860C1E8A; Wed, 27 Jan 2021 18:11:16 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0711FC1E73 for ; Wed, 27 Jan 2021 18:11:06 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id F0D8886C61 for ; Wed, 27 Jan 2021 18:11:05 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id OrHKhXTdbbbS for ; Wed, 27 Jan 2021 18:11:00 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by whitealder.osuosl.org (Postfix) with ESMTP id 22FAB86B4A for ; Wed, 27 Jan 2021 18:10:54 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 27 Jan 2021 20:10:43 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10RIAhXj027513; Wed, 27 Jan 2021 20:10:43 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 27 Jan 2021 18:10:23 +0000 Message-Id: <20210127181036.32448-3-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.546.g385c171 In-Reply-To: <20210127181036.32448-1-elibr@nvidia.com> References: <20210127181036.32448-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH 02/15] 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 | 102 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 208 insertions(+), 6 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 2640a421a..18dee0d7c 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -5301,6 +5301,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..0bbbd6927 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,101 @@ 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 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_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 OVS_UNUSED, + struct rte_flow_error *error) +{ + 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 OVS_UNUSED, + uint32_t num_of_items OVS_UNUSED, + struct rte_flow_error *error) +{ + set_error(error, RTE_FLOW_ERROR_TYPE_NONE); + return 0; +} + +#endif /* ALLOW_EXPERIMENTAL_API */ + #else static inline void From patchwork Wed Jan 27 18:10:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1432286 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=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DQs9F4KJYz9sBy for ; Thu, 28 Jan 2021 05:10:57 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id CEF1F8725C; Wed, 27 Jan 2021 18:10:54 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id lLupvBrSWPBi; Wed, 27 Jan 2021 18:10:54 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 47AC387248; Wed, 27 Jan 2021 18:10:54 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 179A1C1E6F; Wed, 27 Jan 2021 18:10:54 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id B95C7C0FA7 for ; Wed, 27 Jan 2021 18:10:51 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id B24BC860F0 for ; Wed, 27 Jan 2021 18:10:51 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id TSdch1hUM0AI for ; Wed, 27 Jan 2021 18:10:50 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by fraxinus.osuosl.org (Postfix) with ESMTP id 0214A860EF for ; Wed, 27 Jan 2021 18:10:49 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 27 Jan 2021 20:10:44 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10RIAhXk027513; Wed, 27 Jan 2021 20:10:43 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 27 Jan 2021 18:10:24 +0000 Message-Id: <20210127181036.32448-4-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.546.g385c171 In-Reply-To: <20210127181036.32448-1-elibr@nvidia.com> References: <20210127181036.32448-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH 03/15] netdev-offload-dpdk: Implement flow dump create/destroy 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" When offloading vports, we don't configure rte_flow on the vport itself, as it is not a physical dpdk port, but rather on uplinks. Implement those APIs as a pre-step to enable iterate over the ports. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/netdev-offload-dpdk.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index f2413f5be..8cc90d0f1 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -1588,6 +1588,28 @@ netdev_offload_dpdk_flow_flush(struct netdev *netdev) return 0; } +static int +netdev_offload_dpdk_flow_dump_create(struct netdev *netdev, + struct netdev_flow_dump **dump_out, + bool terse OVS_UNUSED) +{ + struct netdev_flow_dump *dump; + + dump = xzalloc(sizeof *dump); + dump->netdev = netdev_ref(netdev); + + *dump_out = dump; + return 0; +} + +static int +netdev_offload_dpdk_flow_dump_destroy(struct netdev_flow_dump *dump) +{ + netdev_close(dump->netdev); + free(dump); + return 0; +} + const struct netdev_flow_api netdev_offload_dpdk = { .type = "dpdk_flow_api", .flow_put = netdev_offload_dpdk_flow_put, @@ -1595,4 +1617,6 @@ 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, + .flow_dump_create = netdev_offload_dpdk_flow_dump_create, + .flow_dump_destroy = netdev_offload_dpdk_flow_dump_destroy, }; From patchwork Wed Jan 27 18:10:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1432288 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DQs9H6CzVz9sBy for ; Thu, 28 Jan 2021 05:10:59 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 90FB486119; Wed, 27 Jan 2021 18:10:57 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ojS0FjFl_KJG; Wed, 27 Jan 2021 18:10:56 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id 7A1618614E; Wed, 27 Jan 2021 18:10:56 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 25601C1E6F; Wed, 27 Jan 2021 18:10:56 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 03D88C0FA7 for ; Wed, 27 Jan 2021 18:10:52 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id DC25522D22 for ; Wed, 27 Jan 2021 18:10:51 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 1Lu6CkJ2Dn2d for ; Wed, 27 Jan 2021 18:10:50 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by silver.osuosl.org (Postfix) with ESMTP id F32C322CCE for ; Wed, 27 Jan 2021 18:10:49 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 27 Jan 2021 20:10:44 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10RIAhXl027513; Wed, 27 Jan 2021 20:10:44 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 27 Jan 2021 18:10:25 +0000 Message-Id: <20210127181036.32448-5-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.546.g385c171 In-Reply-To: <20210127181036.32448-1-elibr@nvidia.com> References: <20210127181036.32448-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH 04/15] 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 18dee0d7c..ca1667f21 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -5226,6 +5226,12 @@ netdev_dpdk_flow_api_supported(struct netdev *netdev) struct netdev_dpdk *dev; bool ret = false; + if (!strcmp(netdev_get_type(netdev), "vxlan") && + !strcmp(netdev_get_dpif_type(netdev), "netdev")) { + ret = true; + goto out; + } + if (!is_dpdk_class(netdev->netdev_class)) { goto out; } From patchwork Wed Jan 27 18:10:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1432297 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DQs9n679Zz9sBy for ; Thu, 28 Jan 2021 05:11:25 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 7162986308; Wed, 27 Jan 2021 18:11:24 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NQsZzp8C8Fyt; Wed, 27 Jan 2021 18:11:21 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id 209F786239; Wed, 27 Jan 2021 18:11:15 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id F04AEC1E6F; Wed, 27 Jan 2021 18:11:14 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7323AC1E76 for ; Wed, 27 Jan 2021 18:11:03 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 6E5DC86C3A for ; Wed, 27 Jan 2021 18:11:03 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zLZ46oOqprG5 for ; Wed, 27 Jan 2021 18:10:58 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by whitealder.osuosl.org (Postfix) with ESMTP id F2D1986B3A for ; Wed, 27 Jan 2021 18:10:54 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 27 Jan 2021 20:10:44 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10RIAhXm027513; Wed, 27 Jan 2021 20:10:44 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 27 Jan 2021 18:10:26 +0000 Message-Id: <20210127181036.32448-6-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.546.g385c171 In-Reply-To: <20210127181036.32448-1-elibr@nvidia.com> References: <20210127181036.32448-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH 05/15] 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 | 95 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index 8cc90d0f1..21aa26b42 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -1610,6 +1610,100 @@ netdev_offload_dpdk_flow_dump_destroy(struct netdev_flow_dump *dump) return 0; } +static struct netdev * +get_vport_netdev(const char *dpif_type, + struct rte_flow_tunnel *tunnel, + odp_port_t *odp_port) +{ + const struct netdev_tunnel_config *tnl_cfg; + struct netdev_flow_dump **netdev_dumps; + struct netdev *vport = NULL; + bool found = false; + int num_ports = 0; + int err; + int i; + + netdev_dumps = netdev_ports_flow_dump_create(dpif_type, &num_ports, false); + for (i = 0; i < num_ports; i++) { + if (!found && tunnel->type == RTE_FLOW_ITEM_TYPE_VXLAN && + !strcmp(netdev_get_type(netdev_dumps[i]->netdev), "vxlan")) { + tnl_cfg = netdev_get_tunnel_config(netdev_dumps[i]->netdev); + if (tnl_cfg && tnl_cfg->dst_port == tunnel->tp_dst) { + found = true; + vport = netdev_dumps[i]->netdev; + netdev_ref(vport); + *odp_port = netdev_dumps[i]->port; + } + } + err = netdev_flow_dump_destroy(netdev_dumps[i]); + if (err != 0 && err != EOPNOTSUPP) { + VLOG_ERR("failed dumping netdev: %s", ovs_strerror(err)); + } + } + return vport; +} + +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 rte_flow_error error; + struct netdev *vport_netdev; + struct pkt_metadata *md; + struct flow_tnl *md_tnl; + odp_port_t vport_odp; + + 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 -1; + } + + rte_tnl = &rte_restore_info.tunnel; + if (rte_restore_info.flags & RTE_FLOW_RESTORE_INFO_TUNNEL) { + vport_netdev = get_vport_netdev(netdev->dpif_type, rte_tnl, + &vport_odp); + md = &packet->md; + if (rte_restore_info.flags & RTE_FLOW_RESTORE_INFO_ENCAPSULATED) { + if (!vport_netdev || !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)); + return -1; + } + vport_netdev->netdev_class->pop_header(packet); + netdev_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; + } + if (vport_netdev) { + md->in_port.odp_port = vport_odp; + } + } + dp_packet_reset_offload(packet); + + return 0; +} + const struct netdev_flow_api netdev_offload_dpdk = { .type = "dpdk_flow_api", .flow_put = netdev_offload_dpdk_flow_put, @@ -1619,4 +1713,5 @@ const struct netdev_flow_api netdev_offload_dpdk = { .flow_flush = netdev_offload_dpdk_flow_flush, .flow_dump_create = netdev_offload_dpdk_flow_dump_create, .flow_dump_destroy = netdev_offload_dpdk_flow_dump_destroy, + .hw_miss_packet_recover = netdev_offload_dpdk_hw_miss_packet_recover, }; From patchwork Wed Jan 27 18:10:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1432290 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=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DQs9J1fQ0z9sVw for ; Thu, 28 Jan 2021 05:11:00 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 96D178728A; Wed, 27 Jan 2021 18:10:58 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Ev9-+tgJfVgj; Wed, 27 Jan 2021 18:10:57 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id A68598725E; Wed, 27 Jan 2021 18:10:57 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5252CC1E70; Wed, 27 Jan 2021 18:10:57 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 1AB62C013A for ; Wed, 27 Jan 2021 18:10:52 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 030FC22CCE for ; Wed, 27 Jan 2021 18:10:52 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id T0V48zbAjQl6 for ; Wed, 27 Jan 2021 18:10:50 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by silver.osuosl.org (Postfix) with ESMTP id F1FE2228E3 for ; Wed, 27 Jan 2021 18:10:49 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 27 Jan 2021 20:10:44 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10RIAhXn027513; Wed, 27 Jan 2021 20:10:44 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 27 Jan 2021 18:10:27 +0000 Message-Id: <20210127181036.32448-7-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.546.g385c171 In-Reply-To: <20210127181036.32448-1-elibr@nvidia.com> References: <20210127181036.32448-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH 06/15] 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 | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index e3fd0a07f..09e86631e 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -7036,6 +7036,10 @@ 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); + /* 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 @@ -7099,23 +7103,33 @@ 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++); + if (*recirc_depth_get() == 0) { + /* Restore the packet if HW processing was terminated before + * completion. + */ + struct tx_port *p; + + tcp_flags = parse_tcp_flags(packet); + p = pmd_send_port_cache_lookup(pmd, port_no); + if (!p || netdev_hw_miss_packet_recover(p->port->netdev, packet)) { + if (dp_packet_has_flow_mark(packet, &mark)) { + flow = mark_to_flow_find(pmd, mark); + if (OVS_LIKELY(flow)) { + 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; + } } - continue; } } From patchwork Wed Jan 27 18:10:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1432299 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=whitealder.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DQsBP4Fytz9sBy for ; Thu, 28 Jan 2021 05:11:57 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 291DB86BA5; Wed, 27 Jan 2021 18:11:56 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id K-znbk+ZjNgc; Wed, 27 Jan 2021 18:11:52 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by whitealder.osuosl.org (Postfix) with ESMTP id 8040B86C80; Wed, 27 Jan 2021 18:11:09 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 24AD2C1E92; Wed, 27 Jan 2021 18:11:09 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 80747C1E70 for ; Wed, 27 Jan 2021 18:10:59 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 73F0D86BDE for ; Wed, 27 Jan 2021 18:10:59 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cXC+HAZ1Nzvt for ; Wed, 27 Jan 2021 18:10:55 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by whitealder.osuosl.org (Postfix) with ESMTP id 867B986B21 for ; Wed, 27 Jan 2021 18:10:54 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 27 Jan 2021 20:10:44 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10RIAhXo027513; Wed, 27 Jan 2021 20:10:44 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 27 Jan 2021 18:10:28 +0000 Message-Id: <20210127181036.32448-8-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.546.g385c171 In-Reply-To: <20210127181036.32448-1-elibr@nvidia.com> References: <20210127181036.32448-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH 07/15] 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 e5d24651f..9234423e3 100644 --- a/lib/netdev-offload.c +++ b/lib/netdev-offload.c @@ -561,10 +561,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); @@ -574,13 +570,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); @@ -616,7 +617,9 @@ netdev_ports_remove(odp_port_t port_no, const char *dpif_type) dpif_port_destroy(&data->dpif_port); netdev_close(data->netdev); /* unref and possibly close */ hmap_remove(&port_to_netdev, &data->portno_node); - hmap_remove(&ifindex_to_port, &data->ifindex_node); + if (data->ifindex >= 0) { + hmap_remove(&ifindex_to_port, &data->ifindex_node); + } free(data); ret = 0; } From patchwork Wed Jan 27 18:10:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1432287 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=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DQs9F6FPmz9sVb for ; Thu, 28 Jan 2021 05:10:57 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id A755F22F26; Wed, 27 Jan 2021 18:10:55 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zUBtL+2VdplY; Wed, 27 Jan 2021 18:10:53 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id E504222CCE; Wed, 27 Jan 2021 18:10:52 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id BDFCCC1825; Wed, 27 Jan 2021 18:10:52 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 99289C013A for ; Wed, 27 Jan 2021 18:10:51 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 807308684A for ; Wed, 27 Jan 2021 18:10:51 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id wvy0uGHKD4j6 for ; Wed, 27 Jan 2021 18:10:50 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by whitealder.osuosl.org (Postfix) with ESMTP id 05AC68060A for ; Wed, 27 Jan 2021 18:10:49 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 27 Jan 2021 20:10:44 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10RIAhXp027513; Wed, 27 Jan 2021 20:10:44 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 27 Jan 2021 18:10:29 +0000 Message-Id: <20210127181036.32448-9-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.546.g385c171 In-Reply-To: <20210127181036.32448-1-elibr@nvidia.com> References: <20210127181036.32448-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH 08/15] 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 09e86631e..7c82a7a27 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -2697,8 +2697,7 @@ dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload) info.flow_mark = mark; port = netdev_ports_get(in_port, dpif_type_str); - if (!port || netdev_vport_is_vport_class(port->netdev_class)) { - netdev_close(port); + if (!port) { goto err_free; } /* Taking a global 'port_mutex' to fulfill thread safety restrictions for diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index 21aa26b42..041429be8 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 717a987d1..5d6fbcfbf 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" @@ -2013,6 +2014,13 @@ netdev_tc_init_flow_api(struct netdev *netdev) int ifindex; int error; + if (netdev_vport_is_vport_class(netdev->netdev_class) + && strcmp(netdev_get_dpif_type(netdev), "system")) { + VLOG_DBG("%s: vport doesn't belong to the system datapath. Skipping.", + netdev_get_name(netdev)); + return EOPNOTSUPP; + } + ifindex = netdev_get_ifindex(netdev); if (ifindex < 0) { VLOG_INFO("init: failed to get ifindex for %s: %s", From patchwork Wed Jan 27 18:10:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1432293 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=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DQs9c0ky0z9sBy for ; Thu, 28 Jan 2021 05:11:16 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 8614D8732F; Wed, 27 Jan 2021 18:11:14 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id p6pGBZ4etVDK; Wed, 27 Jan 2021 18:11:12 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 6D5C98729E; Wed, 27 Jan 2021 18:11:04 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 3D423C1E76; Wed, 27 Jan 2021 18:11:04 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 2CCB4C1E70 for ; Wed, 27 Jan 2021 18:10:56 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 1C5BF860FD for ; Wed, 27 Jan 2021 18:10:56 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id pEYHnFFuaqb4 for ; Wed, 27 Jan 2021 18:10:55 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by fraxinus.osuosl.org (Postfix) with ESMTP id DBE6C860F6 for ; Wed, 27 Jan 2021 18:10:54 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 27 Jan 2021 20:10:44 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10RIAhXq027513; Wed, 27 Jan 2021 20:10:44 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 27 Jan 2021 18:10:30 +0000 Message-Id: <20210127181036.32448-10-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.546.g385c171 In-Reply-To: <20210127181036.32448-1-elibr@nvidia.com> References: <20210127181036.32448-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH 09/15] 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 041429be8..78f866080 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -31,7 +31,7 @@ #include "uuid.h" VLOG_DEFINE_THIS_MODULE(netdev_offload_dpdk); -static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(100, 5); +static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(600, 600); /* Thread-safety * ============= From patchwork Wed Jan 27 18:10:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1432292 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=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DQs9X1Bxwz9sBy for ; Thu, 28 Jan 2021 05:11:12 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 8CE3B87315; Wed, 27 Jan 2021 18:11:10 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id J6iTRdm+gLAX; Wed, 27 Jan 2021 18:11:06 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id E082C87292; Wed, 27 Jan 2021 18:11:02 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id AA394C1E7C; Wed, 27 Jan 2021 18:11:02 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 3A907C0FA7 for ; Wed, 27 Jan 2021 18:10:53 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id BDAEB228E3 for ; Wed, 27 Jan 2021 18:10:52 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id O4L1cObAW00z for ; Wed, 27 Jan 2021 18:10:50 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by silver.osuosl.org (Postfix) with ESMTP id F2FA622902 for ; Wed, 27 Jan 2021 18:10:49 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 27 Jan 2021 20:10:44 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10RIAhXr027513; Wed, 27 Jan 2021 20:10:44 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 27 Jan 2021 18:10:31 +0000 Message-Id: <20210127181036.32448-11-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.546.g385c171 In-Reply-To: <20210127181036.32448-1-elibr@nvidia.com> References: <20210127181036.32448-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH 10/15] 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 | 173 ++++++++++++++++++++++++++++++++--- 3 files changed, 160 insertions(+), 15 deletions(-) diff --git a/Documentation/howto/dpdk.rst b/Documentation/howto/dpdk.rst index f0d45e47b..54a5188b4 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 PF port to a vport. Further Reading --------------- diff --git a/NEWS b/NEWS index 066317e88..916b9882a 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,7 @@ v2.15.0 - xx xxx xxxx - 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 78f866080..493cc9159 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_actions is the opaque array of actions returned by the PMD. */ + struct rte_flow_action *tnl_actions; + uint32_t num_of_tnl_actions; + /* tnl_actions_pos is where the tunnel actions starts within the 'actions' + * field. + */ + int tnl_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->num_of_tnl_actions) { + 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->num_of_tnl_actions ? "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->num_of_tnl_actions && + act_index >= flow_actions->tnl_actions_pos && + act_index < flow_actions->tnl_actions_pos + + flow_actions->num_of_tnl_actions) { + /* 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,23 @@ 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_actions, + uint32_t num_of_tnl_actions) +{ + int i; + + actions->tnl_netdev = tnl_netdev; + actions->tnl_actions_pos = actions->cnt; + actions->tnl_actions = tnl_actions; + actions->num_of_tnl_actions = num_of_tnl_actions; + for (i = 0; i < num_of_tnl_actions; i++) { + add_flow_action(actions, tnl_actions[i].type, tnl_actions[i].conf); + } +} + static void free_flow_patterns(struct flow_patterns *patterns) { @@ -661,9 +713,23 @@ 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->num_of_tnl_actions && i == actions->tnl_actions_pos) { + if (netdev_dpdk_rte_flow_tunnel_action_decap_release + (actions->tnl_netdev, actions->tnl_actions, + actions->num_of_tnl_actions, &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->num_of_tnl_actions - 1; + continue; + } if (actions->actions[i].conf) { free(CONST_CAST(void *, actions->actions[i].conf)); } @@ -671,6 +737,7 @@ free_flow_actions(struct flow_actions *actions) free(actions->actions); actions->actions = NULL; actions->cnt = 0; + ds_destroy(&actions->s_tnl); } static int @@ -960,7 +1027,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 +1374,78 @@ parse_clone_actions(struct netdev *netdev, return 0; } +static void +add_jump_action(struct flow_actions *actions, uint32_t group) +{ + struct rte_flow_action_jump *jump = xzalloc (sizeof *jump); + + jump->group = group; + add_flow_action(actions, RTE_FLOW_ACTION_TYPE_JUMP, jump); +} + +static int +vport_to_rte_tunnel(struct netdev *vport, + struct rte_flow_tunnel *tunnel, + struct netdev *netdev, + struct ds *s_tnl) +{ + const struct netdev_tunnel_config *tnl_cfg; + + memset(tunnel, 0, sizeof *tunnel); + if (!strcmp(netdev_get_type(vport), "vxlan")) { + tunnel->type = RTE_FLOW_ITEM_TYPE_VXLAN; + tnl_cfg = netdev_get_tunnel_config(vport); + if (!tnl_cfg) { + return -1; + } + tunnel->tp_dst = tnl_cfg->dst_port; + if (!VLOG_DROP_DBG(&rl)) { + ds_put_format(s_tnl, "flow tunnel create %d type vxlan; ", + netdev_dpdk_get_port_id(netdev)); + } + } else { + OVS_NOT_REACHED(); + } + + return 0; +} + +static int +add_tnl_pop_action(struct netdev *netdev, + struct flow_actions *actions, + const struct nlattr *nla) +{ + struct rte_flow_action *tnl_actions = NULL; + uint32_t num_of_tnl_actions = 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_actions, + &num_of_tnl_actions, &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_actions, num_of_tnl_actions); + add_jump_action(actions, 0); + return 0; +} + static int parse_flow_actions(struct netdev *netdev, struct flow_actions *actions, @@ -1351,6 +1490,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 +1526,7 @@ netdev_offload_dpdk_actions(struct netdev *netdev, goto out; } flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns->items, - actions.actions, &error); + &actions, &error); out: free_flow_actions(&actions); return flow; From patchwork Wed Jan 27 18:10:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1432289 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=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DQs9H6Py4z9sVb for ; Thu, 28 Jan 2021 05:10:59 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 546D187278; Wed, 27 Jan 2021 18:10:57 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cBBMjeOQNX9m; Wed, 27 Jan 2021 18:10:55 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 4076B8726D; Wed, 27 Jan 2021 18:10:55 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 1131BC1E71; Wed, 27 Jan 2021 18:10:55 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id EA1E1C013A for ; Wed, 27 Jan 2021 18:10:51 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id D7B34860EF for ; Wed, 27 Jan 2021 18:10:51 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qIXTxAUVnN4P for ; Wed, 27 Jan 2021 18:10:50 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by fraxinus.osuosl.org (Postfix) with ESMTP id 012A486081 for ; Wed, 27 Jan 2021 18:10:49 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 27 Jan 2021 20:10:44 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10RIAhXs027513; Wed, 27 Jan 2021 20:10:44 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 27 Jan 2021 18:10:32 +0000 Message-Id: <20210127181036.32448-12-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.546.g385c171 In-Reply-To: <20210127181036.32448-1-elibr@nvidia.com> References: <20210127181036.32448-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH 11/15] netdev-offload-dpdk: Refactor offload rule creation X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Refactor offload rule creation as a pre-step towards tunnel matching that depend on the netdev. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/netdev-offload-dpdk.c | 103 ++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 59 deletions(-) diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index 493cc9159..8c6d8dd21 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -1009,30 +1009,6 @@ add_flow_mark_rss_actions(struct flow_actions *actions, add_flow_action(actions, RTE_FLOW_ACTION_TYPE_END, NULL); } -static struct rte_flow * -netdev_offload_dpdk_mark_rss(struct flow_patterns *patterns, - struct netdev *netdev, - uint32_t flow_mark) -{ - struct flow_actions actions = { .actions = NULL, .cnt = 0 }; - const struct rte_flow_attr flow_attr = { - .group = 0, - .priority = 0, - .ingress = 1, - .egress = 0 - }; - struct rte_flow_error error; - struct rte_flow *flow; - - add_flow_mark_rss_actions(&actions, flow_mark, netdev); - - flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns->items, - &actions, &error); - - free_flow_actions(&actions); - return flow; -} - static void add_count_action(struct flow_actions *actions) { @@ -1509,27 +1485,49 @@ parse_flow_actions(struct netdev *netdev, return 0; } -static struct rte_flow * -netdev_offload_dpdk_actions(struct netdev *netdev, - struct flow_patterns *patterns, - struct nlattr *nl_actions, - size_t actions_len) +static struct ufid_to_rte_flow_data * +create_netdev_offload(struct netdev *netdev, + const ovs_u128 *ufid, + struct flow_patterns *flow_patterns, + struct flow_actions *flow_actions, + bool enable_full, + bool enable_partial, + uint32_t flow_mark) { - const struct rte_flow_attr flow_attr = { .ingress = 1, .transfer = 1 }; - struct flow_actions actions = { .actions = NULL, .cnt = 0 }; + struct flow_actions rss_actions = { .s_tnl = DS_EMPTY_INITIALIZER, }; + struct rte_flow_item *items = flow_patterns->items; + struct rte_flow_attr flow_attr = { .ingress = 1, .transfer = 1, }; + struct ufid_to_rte_flow_data *flow_data = NULL; + bool actions_offloaded = true; struct rte_flow *flow = NULL; struct rte_flow_error error; - int ret; - ret = parse_flow_actions(netdev, &actions, nl_actions, actions_len); - if (ret) { - goto out; + if (enable_full) { + flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, items, + flow_actions, &error); } - flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns->items, - &actions, &error); -out: - free_flow_actions(&actions); - return flow; + + if (enable_partial && !flow) { + /* If we failed to offload the rule actions fallback to MARK+RSS + * actions. + */ + actions_offloaded = false; + flow_attr.transfer = 0; + add_flow_mark_rss_actions(&rss_actions, flow_mark, netdev); + flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, items, + &rss_actions, &error); + } + + if (flow) { + flow_data = ufid_to_rte_flow_associate(ufid, netdev, flow, + actions_offloaded); + VLOG_DBG("%s: installed flow %p by ufid "UUID_FMT, + netdev_get_name(netdev), flow, + UUID_ARGS((struct uuid *) ufid)); + } + + free_flow_actions(&rss_actions); + return flow_data; } static struct ufid_to_rte_flow_data * @@ -1541,9 +1539,9 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, struct offload_info *info) { struct flow_patterns patterns = { .items = NULL, .cnt = 0 }; + struct flow_actions actions = { .actions = NULL, .cnt = 0 }; struct ufid_to_rte_flow_data *flows_data = NULL; - bool actions_offloaded = true; - struct rte_flow *flow; + int err; if (parse_flow_match(&patterns, match)) { VLOG_DBG_RL(&rl, "%s: matches of ufid "UUID_FMT" are not supported", @@ -1551,27 +1549,14 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, goto out; } - flow = netdev_offload_dpdk_actions(netdev, &patterns, nl_actions, - actions_len); - if (!flow) { - /* If we failed to offload the rule actions fallback to MARK+RSS - * actions. - */ - flow = netdev_offload_dpdk_mark_rss(&patterns, netdev, - info->flow_mark); - actions_offloaded = false; - } + err = parse_flow_actions(netdev, &actions, nl_actions, actions_len); - if (!flow) { - goto out; - } - flows_data = ufid_to_rte_flow_associate(ufid, netdev, flow, - actions_offloaded); - VLOG_DBG("%s: installed flow %p by ufid "UUID_FMT, - netdev_get_name(netdev), flow, UUID_ARGS((struct uuid *)ufid)); + flows_data = create_netdev_offload(netdev, ufid, &patterns, &actions, + !err, true, info->flow_mark); out: free_flow_patterns(&patterns); + free_flow_actions(&actions); return flows_data; } From patchwork Wed Jan 27 18:10:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1432294 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=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DQs9f2VS6z9sBy for ; Thu, 28 Jan 2021 05:11:18 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 5281B87342; Wed, 27 Jan 2021 18:11:16 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9iIVXXepgRnd; Wed, 27 Jan 2021 18:11:14 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id F18A3872AD; Wed, 27 Jan 2021 18:11:05 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id C3AE9C1E77; Wed, 27 Jan 2021 18:11:05 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id C3915C1E6F for ; Wed, 27 Jan 2021 18:10:56 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 910538727C for ; Wed, 27 Jan 2021 18:10:56 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id hNKLHKO2yIpT for ; Wed, 27 Jan 2021 18:10:55 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by hemlock.osuosl.org (Postfix) with ESMTP id 0FCB987262 for ; Wed, 27 Jan 2021 18:10:54 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 27 Jan 2021 20:10:45 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10RIAhXt027513; Wed, 27 Jan 2021 20:10:44 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 27 Jan 2021 18:10:33 +0000 Message-Id: <20210127181036.32448-13-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.546.g385c171 In-Reply-To: <20210127181036.32448-1-elibr@nvidia.com> References: <20210127181036.32448-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH 12/15] netdev-dpdk: Introduce an API to query if a dpdk port is an uplink port 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 a vport is offloaded it has no explicit matching physical port so rte_flows are created on each of the uplink ports. Add an API to query if a DPDK port is an uplink port, as a pre-step towards applying vport flows on the uplink ports. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/netdev-dpdk.c | 17 +++++++++++++++++ lib/netdev-dpdk.h | 2 ++ 2 files changed, 19 insertions(+) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index ca1667f21..2caca25eb 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -443,6 +443,7 @@ struct netdev_dpdk { }; struct dpdk_tx_queue *tx_q; struct rte_eth_link link; + bool is_uplink_port; /* True=uplink port, false=representor port. */ ); PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline1, @@ -1143,6 +1144,9 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev) } } + dev->is_uplink_port = !(*info.dev_flags & RTE_ETH_DEV_REPRESENTOR) && + info.switch_info.domain_id != RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID; + n_rxq = MIN(info.max_rx_queues, dev->up.n_rxq); n_txq = MIN(info.max_tx_queues, dev->up.n_txq); @@ -5220,6 +5224,19 @@ out: return ret; } +bool +netdev_dpdk_port_is_uplink(struct netdev *netdev) +{ + struct netdev_dpdk *dev; + + if (!is_dpdk_class(netdev->netdev_class)) { + return false; + } + + dev = netdev_dpdk_cast(netdev); + return dev->is_uplink_port; +} + bool netdev_dpdk_flow_api_supported(struct netdev *netdev) { diff --git a/lib/netdev-dpdk.h b/lib/netdev-dpdk.h index 0bbbd6927..a03fd3053 100644 --- a/lib/netdev-dpdk.h +++ b/lib/netdev-dpdk.h @@ -50,6 +50,8 @@ netdev_dpdk_rte_flow_query_count(struct netdev *netdev, struct rte_flow_error *error); int netdev_dpdk_get_port_id(struct netdev *netdev); +bool +netdev_dpdk_port_is_uplink(struct netdev *netdev); #ifdef ALLOW_EXPERIMENTAL_API From patchwork Wed Jan 27 18:10:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1432296 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=whitealder.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DQs9l4qMFz9sBy for ; Thu, 28 Jan 2021 05:11:23 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 329BB86D7A; Wed, 27 Jan 2021 18:11:22 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id m5bgUVKxNYNe; Wed, 27 Jan 2021 18:11:11 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by whitealder.osuosl.org (Postfix) with ESMTP id 04D9D86BDF; Wed, 27 Jan 2021 18:10:59 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id A3B56C1E71; Wed, 27 Jan 2021 18:10:58 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 240DAC0FA7 for ; Wed, 27 Jan 2021 18:10:52 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 0F41F86081 for ; Wed, 27 Jan 2021 18:10:52 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id GwiSNZnXSyY0 for ; Wed, 27 Jan 2021 18:10:50 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by fraxinus.osuosl.org (Postfix) with ESMTP id 01321860D5 for ; Wed, 27 Jan 2021 18:10:49 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 27 Jan 2021 20:10:45 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10RIAhXu027513; Wed, 27 Jan 2021 20:10:45 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 27 Jan 2021 18:10:34 +0000 Message-Id: <20210127181036.32448-14-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.546.g385c171 In-Reply-To: <20210127181036.32448-1-elibr@nvidia.com> References: <20210127181036.32448-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH 13/15] netdev-offload-dpdk: Map netdev and ufid to offload objects 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 vport offloads, several offload objects are mapped by multiple netdevs with a single ufid. As a pre-step to enable such mapping, use the netdev with the ufid as key in the mapping. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- lib/netdev-offload-dpdk.c | 89 +++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 37 deletions(-) diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index 8c6d8dd21..042996da7 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -53,9 +53,9 @@ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(600, 600); /* * A mapping from ufid to dpdk rte_flow. */ -static struct cmap ufid_to_rte_flow = CMAP_INITIALIZER; +static struct cmap rte_flow_data_map = CMAP_INITIALIZER; -struct ufid_to_rte_flow_data { +struct rte_flow_data { struct cmap_node node; ovs_u128 ufid; struct netdev *netdev; @@ -64,34 +64,49 @@ struct ufid_to_rte_flow_data { struct dpif_flow_stats stats; }; +static uint32_t +rte_flow_data_hash(const struct netdev *netdev, const ovs_u128 *ufid) +{ + uint32_t hash; + + hash = hash_bytes(ufid, sizeof *ufid, 0); + /* Hashing the pointer value is the intent. */ + hash = hash_bytes(netdev, sizeof netdev, hash); + + return hash; +} + /* Find rte_flow with @ufid. */ -static struct ufid_to_rte_flow_data * -ufid_to_rte_flow_data_find(const ovs_u128 *ufid, bool warn) +static struct rte_flow_data * +rte_flow_data_find(const struct netdev *netdev, + const ovs_u128 *ufid, + bool warn) { - size_t hash = hash_bytes(ufid, sizeof *ufid, 0); - struct ufid_to_rte_flow_data *data; + uint32_t hash = rte_flow_data_hash(netdev, ufid); + struct rte_flow_data *data; - CMAP_FOR_EACH_WITH_HASH (data, node, hash, &ufid_to_rte_flow) { - if (ovs_u128_equals(*ufid, data->ufid)) { + CMAP_FOR_EACH_WITH_HASH (data, node, hash, &rte_flow_data_map) { + if (netdev == data->netdev && ovs_u128_equals(*ufid, data->ufid)) { return data; } } if (warn) { - VLOG_WARN("ufid "UUID_FMT" is not associated with an rte flow", - UUID_ARGS((struct uuid *) ufid)); + VLOG_WARN("ufid "UUID_FMT" is not associated with an rte flow for " + "netdev %s", + UUID_ARGS((struct uuid *) ufid), netdev_get_name(netdev)); } return NULL; } -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) +static inline struct rte_flow_data * +rte_flow_data_associate(struct netdev *netdev, const ovs_u128 *ufid, + 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); - struct ufid_to_rte_flow_data *data_prev; + uint32_t hash = rte_flow_data_hash(netdev, ufid); + struct rte_flow_data *data = xzalloc(sizeof *data); + struct rte_flow_data *data_prev; /* * We should not simply overwrite an existing rte flow. @@ -99,7 +114,7 @@ ufid_to_rte_flow_associate(const ovs_u128 *ufid, struct netdev *netdev, * Thus, if following assert triggers, something is wrong: * the rte_flow is not destroyed. */ - data_prev = ufid_to_rte_flow_data_find(ufid, false); + data_prev = rte_flow_data_find(netdev, ufid, false); if (data_prev) { ovs_assert(data_prev->rte_flow == NULL); } @@ -109,17 +124,17 @@ ufid_to_rte_flow_associate(const ovs_u128 *ufid, struct netdev *netdev, data->rte_flow = rte_flow; data->actions_offloaded = actions_offloaded; - cmap_insert(&ufid_to_rte_flow, + cmap_insert(&rte_flow_data_map, CONST_CAST(struct cmap_node *, &data->node), hash); return data; } static inline void -ufid_to_rte_flow_disassociate(struct ufid_to_rte_flow_data *data) +rte_flow_data_disassociate(struct rte_flow_data *data) { - size_t hash = hash_bytes(&data->ufid, sizeof data->ufid, 0); + uint32_t hash = rte_flow_data_hash(data->netdev, &data->ufid); - cmap_remove(&ufid_to_rte_flow, + cmap_remove(&rte_flow_data_map, CONST_CAST(struct cmap_node *, &data->node), hash); netdev_close(data->netdev); ovsrcu_postpone(free, data); @@ -1485,7 +1500,7 @@ parse_flow_actions(struct netdev *netdev, return 0; } -static struct ufid_to_rte_flow_data * +static struct rte_flow_data * create_netdev_offload(struct netdev *netdev, const ovs_u128 *ufid, struct flow_patterns *flow_patterns, @@ -1497,7 +1512,7 @@ create_netdev_offload(struct netdev *netdev, struct flow_actions rss_actions = { .s_tnl = DS_EMPTY_INITIALIZER, }; struct rte_flow_item *items = flow_patterns->items; struct rte_flow_attr flow_attr = { .ingress = 1, .transfer = 1, }; - struct ufid_to_rte_flow_data *flow_data = NULL; + struct rte_flow_data *flow_data = NULL; bool actions_offloaded = true; struct rte_flow *flow = NULL; struct rte_flow_error error; @@ -1519,8 +1534,8 @@ create_netdev_offload(struct netdev *netdev, } if (flow) { - flow_data = ufid_to_rte_flow_associate(ufid, netdev, flow, - actions_offloaded); + flow_data = rte_flow_data_associate(netdev, ufid, flow, + actions_offloaded); VLOG_DBG("%s: installed flow %p by ufid "UUID_FMT, netdev_get_name(netdev), flow, UUID_ARGS((struct uuid *) ufid)); @@ -1530,7 +1545,7 @@ create_netdev_offload(struct netdev *netdev, return flow_data; } -static struct ufid_to_rte_flow_data * +static struct rte_flow_data * netdev_offload_dpdk_add_flow(struct netdev *netdev, struct match *match, struct nlattr *nl_actions, @@ -1540,7 +1555,7 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, { struct flow_patterns patterns = { .items = NULL, .cnt = 0 }; struct flow_actions actions = { .actions = NULL, .cnt = 0 }; - struct ufid_to_rte_flow_data *flows_data = NULL; + struct rte_flow_data *flows_data = NULL; int err; if (parse_flow_match(&patterns, match)) { @@ -1561,7 +1576,7 @@ out: } static int -netdev_offload_dpdk_flow_destroy(struct ufid_to_rte_flow_data *rte_flow_data) +netdev_offload_dpdk_flow_destroy(struct rte_flow_data *rte_flow_data) { struct rte_flow_error error; struct rte_flow *rte_flow; @@ -1576,7 +1591,7 @@ netdev_offload_dpdk_flow_destroy(struct ufid_to_rte_flow_data *rte_flow_data) ret = netdev_dpdk_rte_flow_destroy(netdev, rte_flow, &error); if (ret == 0) { - ufid_to_rte_flow_disassociate(rte_flow_data); + rte_flow_data_disassociate(rte_flow_data); VLOG_DBG_RL(&rl, "%s: rte_flow 0x%"PRIxPTR " flow destroy %d ufid " UUID_FMT, netdev_get_name(netdev), (intptr_t) rte_flow, @@ -1597,7 +1612,7 @@ netdev_offload_dpdk_flow_put(struct netdev *netdev, struct match *match, const ovs_u128 *ufid, struct offload_info *info, struct dpif_flow_stats *stats) { - struct ufid_to_rte_flow_data *rte_flow_data; + struct rte_flow_data *rte_flow_data; struct dpif_flow_stats old_stats; bool modification = false; int ret; @@ -1607,7 +1622,7 @@ netdev_offload_dpdk_flow_put(struct netdev *netdev, struct match *match, * Here destroy the old rte flow first before adding a new one. * Keep the stats for the newly created rule. */ - rte_flow_data = ufid_to_rte_flow_data_find(ufid, false); + rte_flow_data = rte_flow_data_find(netdev, ufid, false); if (rte_flow_data && rte_flow_data->rte_flow) { old_stats = rte_flow_data->stats; modification = true; @@ -1636,9 +1651,9 @@ netdev_offload_dpdk_flow_del(struct netdev *netdev OVS_UNUSED, const ovs_u128 *ufid, struct dpif_flow_stats *stats) { - struct ufid_to_rte_flow_data *rte_flow_data; + struct rte_flow_data *rte_flow_data; - rte_flow_data = ufid_to_rte_flow_data_find(ufid, true); + rte_flow_data = rte_flow_data_find(netdev, ufid, true); if (!rte_flow_data || !rte_flow_data->rte_flow) { return -1; } @@ -1672,11 +1687,11 @@ netdev_offload_dpdk_flow_get(struct netdev *netdev, struct ofpbuf *buf OVS_UNUSED) { struct rte_flow_query_count query = { .reset = 1 }; - struct ufid_to_rte_flow_data *rte_flow_data; + struct rte_flow_data *rte_flow_data; struct rte_flow_error error; int ret = 0; - rte_flow_data = ufid_to_rte_flow_data_find(ufid, false); + rte_flow_data = rte_flow_data_find(netdev, ufid, false); if (!rte_flow_data || !rte_flow_data->rte_flow) { ret = -1; goto out; @@ -1711,9 +1726,9 @@ out: static int netdev_offload_dpdk_flow_flush(struct netdev *netdev) { - struct ufid_to_rte_flow_data *data; + struct rte_flow_data *data; - CMAP_FOR_EACH (data, node, &ufid_to_rte_flow) { + CMAP_FOR_EACH (data, node, &rte_flow_data_map) { if (data->netdev != netdev) { continue; } From patchwork Wed Jan 27 18:10:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1432291 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=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DQs9Q32Zbz9sBy for ; Thu, 28 Jan 2021 05:11:06 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id EAAD48729A; Wed, 27 Jan 2021 18:11:04 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ffQsAGZOrgDZ; Wed, 27 Jan 2021 18:11:00 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 5A77A872A0; Wed, 27 Jan 2021 18:11:00 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 106B1C0FA7; Wed, 27 Jan 2021 18:11:00 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id A473CC013A for ; Wed, 27 Jan 2021 18:10:52 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 9FBB087246 for ; Wed, 27 Jan 2021 18:10:52 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id wTVgQ4o7PI3z for ; Wed, 27 Jan 2021 18:10:50 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by hemlock.osuosl.org (Postfix) with ESMTP id F15F487224 for ; Wed, 27 Jan 2021 18:10:49 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 27 Jan 2021 20:10:45 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10RIAhXv027513; Wed, 27 Jan 2021 20:10:45 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 27 Jan 2021 18:10:35 +0000 Message-Id: <20210127181036.32448-15-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.546.g385c171 In-Reply-To: <20210127181036.32448-1-elibr@nvidia.com> References: <20210127181036.32448-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH 14/15] 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 on uplink ports. This create a one-to-many relation between an OVS flow to HW rules. Link them with an indirect list, and support such rules with such indirection. Signed-off-by: Eli Britstein Reviewed-by: Gaetan Rivet --- NEWS | 1 + lib/netdev-offload-dpdk.c | 226 +++++++++++++++++++++++++++++++++----- 2 files changed, 201 insertions(+), 26 deletions(-) diff --git a/NEWS b/NEWS index 916b9882a..1db53afbd 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,7 @@ v2.15.0 - xx xxx xxxx * 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 042996da7..3907849c3 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -62,6 +62,7 @@ struct rte_flow_data { struct rte_flow *rte_flow; bool actions_offloaded; struct dpif_flow_stats stats; + struct ovs_list indirect; }; static uint32_t @@ -123,6 +124,7 @@ rte_flow_data_associate(struct netdev *netdev, const ovs_u128 *ufid, data->netdev = netdev_ref(netdev); data->rte_flow = rte_flow; data->actions_offloaded = actions_offloaded; + ovs_list_init(&data->indirect); cmap_insert(&rte_flow_data_map, CONST_CAST(struct cmap_node *, &data->node), hash); @@ -137,6 +139,9 @@ rte_flow_data_disassociate(struct rte_flow_data *data) cmap_remove(&rte_flow_data_map, CONST_CAST(struct cmap_node *, &data->node), hash); netdev_close(data->netdev); + if (!ovs_list_is_empty(&data->indirect)) { + ovs_list_remove(&data->indirect); + } ovsrcu_postpone(free, data); } @@ -149,6 +154,8 @@ struct flow_patterns { struct rte_flow_item *items; int cnt; int current_max; + uint32_t num_of_tnl_items; + struct ds s_tnl; }; struct flow_actions { @@ -169,16 +176,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->num_of_tnl_actions) { ds_clone(s_extra, &flow_actions->s_tnl); + } else if (flow_patterns->num_of_tnl_items) { + 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->num_of_tnl_actions ? "tunnel_set 1 " : ""); + flow_actions->num_of_tnl_actions ? "tunnel_set 1 " : "", + flow_patterns->num_of_tnl_items ? "tunnel_match 1 " : ""); } /* Adds one pattern item 'field' with the 'mask' to dynamic string 's' using @@ -192,9 +203,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->num_of_tnl_items && + pattern_index < flow_patterns->num_of_tnl_items) { + 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; @@ -584,19 +604,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); } @@ -606,11 +626,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; @@ -619,7 +640,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, @@ -634,7 +655,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, @@ -669,6 +690,28 @@ add_flow_pattern(struct flow_patterns *patterns, enum rte_flow_item_type type, patterns->cnt++; } +static void +add_flow_tnl_patterns(struct flow_patterns *all_patterns, + struct rte_flow_item *tnl_items, + uint32_t num_of_tnl_items, + struct flow_patterns *flow_patterns) +{ + int i; + + all_patterns->num_of_tnl_items = num_of_tnl_items; + + for (i = 0; i < num_of_tnl_items; i++) { + add_flow_pattern(all_patterns, tnl_items[i].type, tnl_items[i].spec, + tnl_items[i].mask); + } + + for (i = 0; i < flow_patterns->cnt; i++) { + add_flow_pattern(all_patterns, flow_patterns->items[i].type, + flow_patterns->items[i].spec, + flow_patterns->items[i].mask); + } +} + static void add_flow_action(struct flow_actions *actions, enum rte_flow_action_type type, const void *conf) @@ -1510,7 +1553,6 @@ create_netdev_offload(struct netdev *netdev, uint32_t flow_mark) { struct flow_actions rss_actions = { .s_tnl = DS_EMPTY_INITIALIZER, }; - struct rte_flow_item *items = flow_patterns->items; struct rte_flow_attr flow_attr = { .ingress = 1, .transfer = 1, }; struct rte_flow_data *flow_data = NULL; bool actions_offloaded = true; @@ -1518,8 +1560,9 @@ create_netdev_offload(struct netdev *netdev, struct rte_flow_error error; if (enable_full) { - flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, items, - flow_actions, &error); + flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, + flow_patterns, flow_actions, + &error); } if (enable_partial && !flow) { @@ -1529,8 +1572,9 @@ create_netdev_offload(struct netdev *netdev, actions_offloaded = false; flow_attr.transfer = 0; add_flow_mark_rss_actions(&rss_actions, flow_mark, netdev); - flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, items, - &rss_actions, &error); + flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, + flow_patterns, &rss_actions, + &error); } if (flow) { @@ -1545,6 +1589,88 @@ create_netdev_offload(struct netdev *netdev, return flow_data; } +static struct rte_flow_data * +create_vport_offload(struct netdev *vport, + const ovs_u128 *ufid, + struct flow_patterns *flow_patterns, + struct flow_actions *flow_actions) +{ + struct flow_patterns all_patterns = { .items = NULL, .cnt = 0 }; + struct rte_flow_data *flows_data = NULL; + struct netdev_flow_dump **netdev_dumps; + struct rte_flow_item *tnl_items; + struct rte_flow_tunnel tunnel; + struct rte_flow_error error; + uint32_t num_of_tnl_items; + struct ovs_list indirect; + struct netdev *physdev; + bool actions_offloaded; + int num_ports = 0; + int err; + int i; + + ovs_list_init(&indirect); + netdev_dumps = netdev_ports_flow_dump_create(vport->dpif_type, &num_ports, + false); + actions_offloaded = false; + for (i = 0; i < num_ports; i++) { + physdev = netdev_dumps[i]->netdev; + if (!netdev_dpdk_port_is_uplink(physdev)) { + continue; + } + + ds_init(&all_patterns.s_tnl); + if (vport_to_rte_tunnel(vport, &tunnel, physdev, + &all_patterns.s_tnl)) { + ds_destroy(&all_patterns.s_tnl); + break; + } + if (netdev_dpdk_rte_flow_tunnel_match(physdev, &tunnel, &tnl_items, + &num_of_tnl_items, &error)) { + VLOG_DBG_RL(&rl, "%s: netdev_dpdk_rte_flow_tunnel_match failed: " + "%d (%s).", netdev_get_name(physdev), error.type, + error.message); + ds_destroy(&all_patterns.s_tnl); + continue; + } + add_flow_tnl_patterns(&all_patterns, tnl_items, num_of_tnl_items, + flow_patterns); + flows_data = create_netdev_offload(physdev, ufid, &all_patterns, + flow_actions, true, false, 0); + if (netdev_dpdk_rte_flow_tunnel_item_release(physdev, tnl_items, + num_of_tnl_items, + &error)) { + VLOG_DBG_RL(&rl, "%s: netdev_dpdk_rte_flow_tunnel_item_release " + "failed: %d (%s).", netdev_get_name(physdev), + error.type, error.message); + } + ds_destroy(&all_patterns.s_tnl); + all_patterns.cnt = 0; + if (flows_data) { + ovs_list_push_back(&indirect, &flows_data->indirect); + actions_offloaded |= flows_data->actions_offloaded; + } + } + free_flow_patterns(&all_patterns); + + for (i = 0; i < num_ports; i++) { + err = netdev_flow_dump_destroy(netdev_dumps[i]); + if (err != 0 && err != EOPNOTSUPP) { + VLOG_ERR("failed dumping netdev: %s", ovs_strerror(err)); + } + } + + if (!ovs_list_is_empty(&indirect)) { + flows_data = rte_flow_data_associate(vport, ufid, NULL, + actions_offloaded); + ovs_list_move(&flows_data->indirect, &indirect); + VLOG_DBG("%s: installed flow for ufid "UUID_FMT, + netdev_get_name(vport), UUID_ARGS((struct uuid *) ufid)); + } + + return flows_data; +} + static struct rte_flow_data * netdev_offload_dpdk_add_flow(struct netdev *netdev, struct match *match, @@ -1566,8 +1692,12 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, err = parse_flow_actions(netdev, &actions, nl_actions, actions_len); - flows_data = create_netdev_offload(netdev, ufid, &patterns, &actions, - !err, true, info->flow_mark); + if (!err && netdev_vport_is_vport_class(netdev->netdev_class)) { + flows_data = create_vport_offload(netdev, ufid, &patterns, &actions); + } else { + flows_data = create_netdev_offload(netdev, ufid, &patterns, &actions, + !err, true, info->flow_mark); + } out: free_flow_patterns(&patterns); @@ -1582,13 +1712,27 @@ netdev_offload_dpdk_flow_destroy(struct rte_flow_data *rte_flow_data) struct rte_flow *rte_flow; struct netdev *netdev; ovs_u128 *ufid; - int ret; + int ret = 0; - rte_flow = rte_flow_data->rte_flow; netdev = rte_flow_data->netdev; + + /* For vport, follow indirect rules (recursive call). */ + if (netdev_vport_is_vport_class(netdev->netdev_class)) { + struct rte_flow_data *phys, *next; + + LIST_FOR_EACH_SAFE (phys, next, indirect, &rte_flow_data->indirect) { + if (netdev_offload_dpdk_flow_destroy(phys)) { + ret = -1; + } + } + } + + rte_flow = rte_flow_data->rte_flow; ufid = &rte_flow_data->ufid; - ret = netdev_dpdk_rte_flow_destroy(netdev, rte_flow, &error); + if (rte_flow) { + ret = netdev_dpdk_rte_flow_destroy(netdev, rte_flow, &error); + } if (ret == 0) { rte_flow_data_disassociate(rte_flow_data); @@ -1654,7 +1798,7 @@ netdev_offload_dpdk_flow_del(struct netdev *netdev OVS_UNUSED, struct rte_flow_data *rte_flow_data; rte_flow_data = rte_flow_data_find(netdev, ufid, true); - if (!rte_flow_data || !rte_flow_data->rte_flow) { + if (!rte_flow_data) { return -1; } @@ -1692,7 +1836,7 @@ netdev_offload_dpdk_flow_get(struct netdev *netdev, int ret = 0; rte_flow_data = rte_flow_data_find(netdev, ufid, false); - if (!rte_flow_data || !rte_flow_data->rte_flow) { + if (!rte_flow_data) { ret = -1; goto out; } @@ -1704,6 +1848,34 @@ netdev_offload_dpdk_flow_get(struct netdev *netdev, goto out; } attrs->dp_layer = "dpdk"; + /* For vport, follow indirect rules (recursive call). */ + if (netdev_vport_is_vport_class(netdev->netdev_class)) { + struct dpif_flow_stats phys_stats; + struct dpif_flow_attrs phys_attrs; + struct rte_flow_data *phys_data; + + memset(&rte_flow_data->stats, 0, sizeof rte_flow_data->stats); + LIST_FOR_EACH (phys_data, indirect, &rte_flow_data->indirect) { + if (netdev_offload_dpdk_flow_get(phys_data->netdev, match, actions, + ufid, &phys_stats, &phys_attrs, + buf)) { + ret = -1; + goto out; + } else { + rte_flow_data->stats.n_packets += phys_stats.n_packets; + rte_flow_data->stats.n_bytes += phys_stats.n_bytes; + if (phys_stats.used > rte_flow_data->stats.used) { + rte_flow_data->stats.used = phys_stats.used; + } + } + } + goto out; + } + + if (!rte_flow_data->rte_flow) { + ret = -1; + goto out; + } ret = netdev_dpdk_rte_flow_query_count(netdev, rte_flow_data->rte_flow, &query, &error); if (ret) { @@ -1717,9 +1889,11 @@ netdev_offload_dpdk_flow_get(struct netdev *netdev, if (query.hits_set && query.hits) { rte_flow_data->stats.used = time_msec(); } - memcpy(stats, &rte_flow_data->stats, sizeof *stats); out: - attrs->dp_extra_info = NULL; + if (!ret) { + memcpy(stats, &rte_flow_data->stats, sizeof *stats); + attrs->dp_extra_info = NULL; + } return ret; } From patchwork Wed Jan 27 18:10:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1432300 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=whitealder.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DQsBb2j7Yz9sBy for ; Thu, 28 Jan 2021 05:12:07 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id B33FA86C48; Wed, 27 Jan 2021 18:12:05 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id pQ-8vboxSaHQ; Wed, 27 Jan 2021 18:11:59 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by whitealder.osuosl.org (Postfix) with ESMTP id F396986C74; Wed, 27 Jan 2021 18:11:11 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id D2F74C1E70; Wed, 27 Jan 2021 18:11:11 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id D9504C1E73 for ; Wed, 27 Jan 2021 18:11:01 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id C59CD228E3 for ; Wed, 27 Jan 2021 18:11:01 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 2kz78PvZvstF for ; Wed, 27 Jan 2021 18:10:56 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by silver.osuosl.org (Postfix) with ESMTP id DE7AF22F05 for ; Wed, 27 Jan 2021 18:10:54 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 27 Jan 2021 20:10:45 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10RIAhXw027513; Wed, 27 Jan 2021 20:10:45 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Wed, 27 Jan 2021 18:10:36 +0000 Message-Id: <20210127181036.32448-16-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.546.g385c171 In-Reply-To: <20210127181036.32448-1-elibr@nvidia.com> References: <20210127181036.32448-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein , Ameer Mahagneh , Majd Dibbiny , Gaetan Rivet Subject: [ovs-dev] [PATCH 15/15] 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 --- lib/netdev-offload-dpdk.c | 169 +++++++++++++++++++++++++++++++++++++- 1 file changed, 167 insertions(+), 2 deletions(-) diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index 3907849c3..6cfdea8fc 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -382,6 +382,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); } @@ -799,7 +813,154 @@ free_flow_actions(struct flow_actions *actions) } static int -parse_flow_match(struct flow_patterns *patterns, +parse_tnl_ip_match(struct flow_patterns *patterns, + struct match *match, + uint8_t proto) +{ + struct flow *consumed_masks; + + consumed_masks = &match->wc.masks; + /* IP v4 */ + if (match->wc.masks.tunnel.ip_src || match->wc.masks.tunnel.ip_dst) { + struct rte_flow_item_ipv4 *spec, *mask; + + spec = xzalloc(sizeof *spec); + mask = xzalloc(sizeof *mask); + + spec->hdr.type_of_service = match->flow.tunnel.ip_tos; + spec->hdr.time_to_live = match->flow.tunnel.ip_ttl; + spec->hdr.next_proto_id = proto; + spec->hdr.src_addr = match->flow.tunnel.ip_src; + spec->hdr.dst_addr = match->flow.tunnel.ip_dst; + + mask->hdr.type_of_service = match->wc.masks.tunnel.ip_tos; + mask->hdr.time_to_live = match->wc.masks.tunnel.ip_ttl; + mask->hdr.next_proto_id = UINT8_MAX; + mask->hdr.src_addr = match->wc.masks.tunnel.ip_src; + mask->hdr.dst_addr = match->wc.masks.tunnel.ip_dst; + + consumed_masks->tunnel.ip_tos = 0; + consumed_masks->tunnel.ip_ttl = 0; + consumed_masks->tunnel.ip_src = 0; + consumed_masks->tunnel.ip_dst = 0; + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV4, spec, mask); + } else if (!is_all_zeros(&match->wc.masks.tunnel.ipv6_src, + sizeof(struct in6_addr)) || + !is_all_zeros(&match->wc.masks.tunnel.ipv6_dst, + sizeof(struct in6_addr))) { + /* IP v6 */ + struct rte_flow_item_ipv6 *spec, *mask; + + spec = xzalloc(sizeof *spec); + mask = xzalloc(sizeof *mask); + + spec->hdr.proto = proto; + spec->hdr.hop_limits = match->flow.tunnel.ip_ttl; + spec->hdr.vtc_flow = htonl((uint32_t) match->flow.tunnel.ip_tos << + RTE_IPV6_HDR_TC_SHIFT); + memcpy(spec->hdr.src_addr, &match->flow.tunnel.ipv6_src, + sizeof spec->hdr.src_addr); + memcpy(spec->hdr.dst_addr, &match->flow.tunnel.ipv6_dst, + sizeof spec->hdr.dst_addr); + + mask->hdr.proto = UINT8_MAX; + mask->hdr.hop_limits = match->wc.masks.tunnel.ip_ttl; + mask->hdr.vtc_flow = htonl((uint32_t) match->wc.masks.tunnel.ip_tos << + RTE_IPV6_HDR_TC_SHIFT); + memcpy(mask->hdr.src_addr, &match->wc.masks.tunnel.ipv6_src, + sizeof mask->hdr.src_addr); + memcpy(mask->hdr.dst_addr, &match->wc.masks.tunnel.ipv6_dst, + sizeof mask->hdr.dst_addr); + + consumed_masks->tunnel.ip_tos = 0; + consumed_masks->tunnel.ip_ttl = 0; + memset(&consumed_masks->tunnel.ipv6_src, 0, + sizeof consumed_masks->tunnel.ipv6_src); + memset(&consumed_masks->tunnel.ipv6_dst, 0, + sizeof consumed_masks->tunnel.ipv6_dst); + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV6, spec, mask); + } else { + VLOG_ERR_RL(&rl, "Tunnel L3 protocol is neither IPv4 nor IPv6"); + return -1; + } + + return 0; +} + +static void +parse_tnl_udp_match(struct flow_patterns *patterns, + struct match *match) +{ + struct flow *consumed_masks; + struct rte_flow_item_udp *spec, *mask; + + consumed_masks = &match->wc.masks; + + spec = xzalloc(sizeof *spec); + mask = xzalloc(sizeof *mask); + + spec->hdr.src_port = match->flow.tunnel.tp_src; + spec->hdr.dst_port = match->flow.tunnel.tp_dst; + + mask->hdr.src_port = match->wc.masks.tunnel.tp_src; + mask->hdr.dst_port = match->wc.masks.tunnel.tp_dst; + + consumed_masks->tunnel.tp_src = 0; + consumed_masks->tunnel.tp_dst = 0; + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_UDP, spec, mask); +} + +static int +parse_vxlan_match(struct flow_patterns *patterns, + struct match *match) +{ + struct rte_flow_item_vxlan *vx_spec, *vx_mask; + struct flow *consumed_masks; + int ret; + + ret = parse_tnl_ip_match(patterns, match, IPPROTO_UDP); + if (ret) { + return -1; + } + parse_tnl_udp_match(patterns, match); + + consumed_masks = &match->wc.masks; + /* VXLAN */ + vx_spec = xzalloc(sizeof *vx_spec); + vx_mask = xzalloc(sizeof *vx_mask); + + put_unaligned_be32((ovs_be32 *) vx_spec->vni, + htonl(ntohll(match->flow.tunnel.tun_id) << 8)); + put_unaligned_be32((ovs_be32 *) vx_mask->vni, + htonl(ntohll(match->wc.masks.tunnel.tun_id) << 8)); + + consumed_masks->tunnel.tun_id = 0; + consumed_masks->tunnel.flags = 0; + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_VXLAN, vx_spec, vx_mask); + return 0; +} + +static int +parse_flow_tnl_match(struct netdev *tnldev, + struct flow_patterns *patterns, + struct match *match) +{ + if (!netdev_vport_is_vport_class(tnldev->netdev_class)) { + return -1; + } + if (!strcmp(netdev_get_type(tnldev), "vxlan")) { + return parse_vxlan_match(patterns, match); + } + return -1; +} + +static int +parse_flow_match(struct netdev *netdev, + struct flow_patterns *patterns, struct match *match) { struct flow *consumed_masks; @@ -809,6 +970,10 @@ parse_flow_match(struct flow_patterns *patterns, if (!flow_tnl_dst_is_set(&match->flow.tunnel)) { memset(&consumed_masks->tunnel, 0, sizeof consumed_masks->tunnel); + } else { + if (parse_flow_tnl_match(netdev, patterns, match)) { + return -1; + } } memset(&consumed_masks->in_port, 0, sizeof consumed_masks->in_port); @@ -1684,7 +1849,7 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, struct rte_flow_data *flows_data = NULL; int err; - if (parse_flow_match(&patterns, match)) { + if (parse_flow_match(netdev, &patterns, match)) { VLOG_DBG_RL(&rl, "%s: matches of ufid "UUID_FMT" are not supported", netdev_get_name(netdev), UUID_ARGS((struct uuid *) ufid)); goto out;