From patchwork Sat Sep 30 10:00:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chaoyong He X-Patchwork-Id: 132250 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 5E30242682; Sat, 30 Sep 2023 12:01:51 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2CD0B40287; Sat, 30 Sep 2023 12:01:46 +0200 (CEST) Received: from NAM12-DM6-obe.outbound.protection.outlook.com (mail-dm6nam12on2128.outbound.protection.outlook.com [40.107.243.128]) by mails.dpdk.org (Postfix) with ESMTP id 2766C40268 for ; Sat, 30 Sep 2023 12:01:43 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=XcnL4DMHn5LH5/FR0v6LqxvQbIZCY5UkaqMJBw9jyxwsi5WZ/KDIGJ0Zkn04RKaRlv6Kq38rddVB+FI5k1EU/LakYOX80YwR7IayJT9kxWxOibZUrG6Yt+byIzDJhWd/daKZx9vqEWpMD+fHnKUA7lB+XcVT240S8XXsh8UIAXkF0aahh7UVvVnbcKdONha1urtZB/5Q3n9EfamJnaLhtbGc/nf2Gwu3JC88G4VhppeCbuaNkzpwBJiFPlEUJqwS5LDxSTrEbfpvozLWxKJKPWHQ3sDltQkyGxn2drsRQByPjpGKca39cPG1M5lcY1k/Tl/ygQkb1CKBA6tffJiFwg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=LTSL5EhAxJkOQ2c0702HEgJe0y0TEYktLlnmF+jxK8c=; b=mm480CjcIwFaXC1rLS1Kg58bfGp4G7SKCg3miWOaXRQbydAma2oJ+WpCvJLxJUZEsn8flSWxB8xNlVoZ4oPf9yiu8RdpBH2N89JyqI/wghPiXDhWh1rXy6JAF4u+gDbtHPNt9aUWDSBSqz+ZnICBuR7R7cAPnWuoGWmyf14iZAA04Juo+aoQYASurgCyOeubnkCzsCDwzdZLAZhxE+TneRK31A33h7sXdCFZxe+wVkdU2znmzJsGveoBzxMN1bZFzeLH/d1xyg5nsLz+Q5puCis1usciXTLEKFwUYECYtMU1HDfHGKHiOYFkS+OHWrq+luzpHD+JREyfC+I8qbwHug== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=corigine.com; dmarc=pass action=none header.from=corigine.com; dkim=pass header.d=corigine.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=corigine.onmicrosoft.com; s=selector2-corigine-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=LTSL5EhAxJkOQ2c0702HEgJe0y0TEYktLlnmF+jxK8c=; b=XK7gkS+HqC/ZRYHQi3V6pUjeb1tfV/+kzKd0wREE9u72NA79LLfQIPmWE82/pBfPX8t4zrDAbMsM2dtbM2QDgs6b9SER2Scix4o7Ephx1QTDKXr7wbV8UR7nwzzaZiGqEtkITaDDsNvICYkjPFDWtV9KiC3y3rIlpBM4GqOxhQw= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=corigine.com; Received: from SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5) by PH7PR13MB5429.namprd13.prod.outlook.com (2603:10b6:510:138::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6813.21; Sat, 30 Sep 2023 10:01:40 +0000 Received: from SJ0PR13MB5545.namprd13.prod.outlook.com ([fe80::28c0:63e2:ecd1:9314]) by SJ0PR13MB5545.namprd13.prod.outlook.com ([fe80::28c0:63e2:ecd1:9314%4]) with mapi id 15.20.6813.027; Sat, 30 Sep 2023 10:01:40 +0000 From: Chaoyong He To: dev@dpdk.org Cc: oss-drivers@corigine.com, Chaoyong He Subject: [PATCH 1/4] net/nfp: prepare for the flow merge Date: Sat, 30 Sep 2023 18:00:50 +0800 Message-Id: <20230930100053.1227215-2-chaoyong.he@corigine.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230930100053.1227215-1-chaoyong.he@corigine.com> References: <20230930100053.1227215-1-chaoyong.he@corigine.com> X-ClientProxiedBy: PH8PR22CA0022.namprd22.prod.outlook.com (2603:10b6:510:2d1::17) To SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ0PR13MB5545:EE_|PH7PR13MB5429:EE_ X-MS-Office365-Filtering-Correlation-Id: b016b9d6-89f2-4b9b-f5ef-08dbc19c3db6 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: GHT01QIrTPgIMK+7hV4axU4VQLiz4BNKuZa3eWbuEZLs4lEDossyJ7+2SMCM9G5YdS1MT+8m45p1Pij7auFp8HUAPqKsrhIhu/tvIdgeCJnpCEdtZgYekRyzoERNPOMEGRTH+zY4gy/IMMa+wUQK5Esi8OkKE4mB2q58rvPetUgjDs9LxLVDdhf5ZHAtGmdAkqjo2grFtPR9YVwxFqeTfYj/Js/0ddfWVLRJ6EMgBgRUEHpb9t0Yx/oGiwrjO4GDiKYzsKR75N3rUiaw4qRhhKNXKd4YRCfRHmSIQXfFdDKKTBRz75hFgO0NbmmyRi0gCVtwMMqNin2O+t5y6u81Uh1B1tTBW7/Zhf1V17ApAeSXkWWKVvv8yZQxe6h0orC3zb4ynHuboxt5H6hEUNw3du6Ti6lqgRALg0frtlvRxftd4HjBN+qB3oy/+aUwcp8u3SGGwD3se98z+dg9UeSzM0zMH4jNaSQYlUkROQPcu4deY9k6DrKey3qAz/uJ6gf9IVQ+zLnNZQvWqUQlZjFlCAhXg9FO5Lr4a+VMYYH53vK5YvvWeuR9ENgMgQMSJMDNlyjBjvrdbGNrCuSyq4Q0tugEvyQuprFUd6SE9pvzHVlKr+pb+wzuIuhIy2t9r5K0B6VysZXf9Ly6VKOOujUnT1pTY2XJmi5tsjdLKySpvik= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:SJ0PR13MB5545.namprd13.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(366004)(346002)(136003)(39830400003)(396003)(376002)(230922051799003)(1800799009)(451199024)(64100799003)(186009)(66946007)(6916009)(8676002)(44832011)(316002)(4326008)(66476007)(66556008)(38100700002)(38350700002)(86362001)(6486002)(478600001)(41300700001)(2906002)(5660300002)(8936002)(6512007)(2616005)(52116002)(107886003)(1076003)(26005)(36756003)(6666004)(83380400001)(6506007); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: GoW+SItEgiEYAu5eZGkcLKR++wuQ414JQegtJOwOuRP7ZOYEfLfLZNPL1c8nq8pWAt/35kGJMsB1Z9BVa93KeAVv8Te/Yx9gPXCtBzfAjY4idIzxw1Grpf+3dFuE+6afYTe1TU7Ki8SI8+K+xw6bud71JFRb0u/fUN2xNhHGZOv6NJ11fVH+fmQ8OfUo0YLTpra5sAc4ShDVW7cnFU/zt2Ly2eKm5Gjem/dFBTUP9/F4wz++G/NkIpFumFpwdU9/M9LSOfmK3Xm8oJcFaDnq/VHLL07RODE+iaZhgjWKR96s6TNXWisTZesQxVpPOFfPX4IsP1vZfAaYlkW4Yk6qr1GbwIr0B0k/Bd0yPU8LaimnZcUGaH5UhKpUCaWl6BDYk12rBu//ZSvkkvtkMrolJZSqCvEXvaMjWitTaob4jr1sq350KBggsryCjcQx1eQIJcQ81PaoGLh1Wg6LSvsX7gOOGArmaeHHCDXiRCmdxHQtS8nIlNyFJrSBb0/K/Nvde76rPrxsafGkHrcWkLgd+W/TL46dHmxJczZEyzawE9QVz7cDG/yYXmQUbk4b4h5uymP9Bsf2sOBagd051xNq5A0R5BzXg/j+VcSvztwvDys/VwhF+wekcgV5L+HuzQ67/qCfSkWTAeGhkt81Qb/aUQs/DbkCulZEsuX7vE383ilRDYaCNQTyWt8mleehUw93sdWE1PIcD5++D5tmbAMemG7oGjhUnl0KWkpTixzvGlFOp94Z1FqtCtUPtdAxNEgoxImYm52+4//CoOmpfFi68w2OPIa6igFE2GvOTXNF8iQhf3XWyjM84L3+IGcAf47JumnlEk0br87f2Doij+jEamY+WQCzrzdPwJxPQeTDiJ1LzJUZg0fMoV/YE7drj4LZlDEYbIAHOiEZtXumJD+3FTh7V+cCbuFTVsx5/lWDh4wfsOryZvsRwVUgKqshTLKR5GbY5xujdygBrp3/PYbbRim4+tzb8FTJm2P0TD4St+RR5qULJ5zMCQIKG7zrnI5ePB4EnfExXiKjiocaj7Tpvz3cfRx7ixBwPkoZ2kppraPVFVeULnrhKVwsFVcb4hL6xVu9WK1HfuiB3ESoJwBz4o28ssIXCcn6NX0PYO5kxPSzPRmE/C+U9NyWfw+pmulFdEwADflczyrmBJpVHqLHgpAdwp31KUpuSk5PNOaZ7pZiv1ADbqtQpoBHIMC0HK8AIMc0YW4wdOXjZTCIN4TnX1LpvcvpVXW81kLFkxNY3E5rVodW1f66pmnoTJsF9T8EcOjlo7DQlN/CSx6dbPhOsmikjlmDnfUFm0FZ9QOxqeP6/hmFyWjdC5iUEb1CuaZlLRJRiBBSohCydCQZpjM9uVefrNQXwmXu4Mtg+DRT3qrFw3mODRP0uu3rjN59qc/C3c/cTif7lkbUbDVcr6V0h/kS1i08NTEoCOI8dhwOFhHe1zwS2i/A0p7LW5nafrL5pRetes7zt3EiLt+4x7X3fELoiRzJnipwgcWeanMfT0latsjyFOmiToMwU2MtVM6j4zHn4lqgrpsUe750cO76BXwA6449nmz8ciddtNehv+A11sCJg4VMahG3c+CrQrDCjoChcNze2K2OzmZde+xs1Q== X-OriginatorOrg: corigine.com X-MS-Exchange-CrossTenant-Network-Message-Id: b016b9d6-89f2-4b9b-f5ef-08dbc19c3db6 X-MS-Exchange-CrossTenant-AuthSource: SJ0PR13MB5545.namprd13.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Sep 2023 10:01:40.1993 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: fe128f2c-073b-4c20-818e-7246a585940c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: hzbVFHJrAKSeqkjV3qEEpbGp/mIjTBo4shZayCDE1vSSwDBdMOBPnO0By3ssO5uZAuvdVp9OI7CgH6ggypHYaDxFURXUp1aSUr1xk4+/ka0= X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR13MB5429 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Move data structure and macro from source file to header file. Export the needed function to header file. We add two more parameter for 'nfp_flow_process()' to prepare for the flow merge. The 'cookie' moved as parameter is because the flow merge logic need this cookie. The 'install' parameter is needed because in flow merge, some flow are not need install to the hardware. Signed-off-by: Chaoyong He --- drivers/net/nfp/nfp_flow.c | 42 +++++++++++++++++--------------------- drivers/net/nfp/nfp_flow.h | 31 ++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c index aa286535f7..1bb93bcfb5 100644 --- a/drivers/net/nfp/nfp_flow.c +++ b/drivers/net/nfp/nfp_flow.c @@ -89,17 +89,6 @@ /* Tunnel ports */ #define NFP_FL_PORT_TYPE_TUN 0x50000000 -/* - * Maximum number of items in struct rte_flow_action_vxlan_encap. - * ETH / IPv4(6) / UDP / VXLAN / END - */ -#define ACTION_VXLAN_ENCAP_ITEMS_NUM 5 - -struct vxlan_data { - struct rte_flow_action_vxlan_encap conf; - struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM]; -}; - /* Static initializer for a list of subsequent item types */ #define NEXT_ITEM(...) \ ((const enum rte_flow_item_type []){ \ @@ -359,7 +348,7 @@ nfp_check_mask_remove(struct nfp_flow_priv *priv, return true; } -static int +int nfp_flow_table_add(struct nfp_flow_priv *priv, struct rte_flow *nfp_flow) { @@ -440,7 +429,7 @@ nfp_flow_alloc(struct nfp_fl_key_ls *key_layer, uint32_t port_id) return NULL; } -static void +void nfp_flow_free(struct rte_flow *nfp_flow) { rte_free(nfp_flow->payload.meta); @@ -721,7 +710,8 @@ static void nfp_flow_compile_metadata(struct nfp_flow_priv *priv, struct rte_flow *nfp_flow, struct nfp_fl_key_ls *key_layer, - uint32_t stats_ctx) + uint32_t stats_ctx, + uint64_t cookie) { struct nfp_fl_rule_metadata *nfp_flow_meta; char *mbuf_off_exact; @@ -737,7 +727,7 @@ nfp_flow_compile_metadata(struct nfp_flow_priv *priv, nfp_flow_meta->act_len = key_layer->act_size >> NFP_FL_LW_SIZ; nfp_flow_meta->flags = 0; nfp_flow_meta->host_ctx_id = rte_cpu_to_be_32(stats_ctx); - nfp_flow_meta->host_cookie = rte_rand(); + nfp_flow_meta->host_cookie = rte_cpu_to_be_64(cookie); nfp_flow_meta->flow_version = rte_cpu_to_be_64(priv->flower_version); mbuf_off_exact = nfp_flow->payload.unmasked_data; @@ -1958,7 +1948,7 @@ nfp_flow_is_tun_item(const struct rte_flow_item *item) return false; } -static bool +bool nfp_flow_inner_item_get(const struct rte_flow_item items[], const struct rte_flow_item **inner_item) { @@ -3650,11 +3640,13 @@ nfp_flow_compile_action(struct nfp_flower_representor *representor, return 0; } -static struct rte_flow * +struct rte_flow * nfp_flow_process(struct nfp_flower_representor *representor, const struct rte_flow_item items[], const struct rte_flow_action actions[], - bool validate_flag) + bool validate_flag, + uint64_t cookie, + bool install_flag) { int ret; char *hash_data; @@ -3690,9 +3682,9 @@ nfp_flow_process(struct nfp_flower_representor *representor, goto free_stats; } - nfp_flow->install_flag = true; + nfp_flow->install_flag = install_flag; - nfp_flow_compile_metadata(priv, nfp_flow, &key_layer, stats_ctx); + nfp_flow_compile_metadata(priv, nfp_flow, &key_layer, stats_ctx, cookie); ret = nfp_flow_compile_items(representor, items, nfp_flow); if (ret != 0) { @@ -3755,6 +3747,8 @@ nfp_flow_setup(struct nfp_flower_representor *representor, __rte_unused struct rte_flow_error *error, bool validate_flag) { + uint64_t cookie; + if (attr->group != 0) PMD_DRV_LOG(INFO, "Pretend we support group attribute."); @@ -3764,10 +3758,12 @@ nfp_flow_setup(struct nfp_flower_representor *representor, if (attr->transfer != 0) PMD_DRV_LOG(INFO, "Pretend we support transfer attribute."); - return nfp_flow_process(representor, items, actions, validate_flag); + cookie = rte_rand(); + + return nfp_flow_process(representor, items, actions, validate_flag, cookie, true); } -static int +int nfp_flow_teardown(struct nfp_flow_priv *priv, struct rte_flow *nfp_flow, bool validate_flag) @@ -3895,7 +3891,7 @@ nfp_flow_create(struct rte_eth_dev *dev, return NULL; } -static int +int nfp_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *nfp_flow, struct rte_flow_error *error) diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h index 7ce7f62453..817eaecba2 100644 --- a/drivers/net/nfp/nfp_flow.h +++ b/drivers/net/nfp/nfp_flow.h @@ -11,6 +11,17 @@ /* The firmware expects lengths in units of long words */ #define NFP_FL_LW_SIZ 2 +/* + * Maximum number of items in struct rte_flow_action_vxlan_encap. + * ETH / IPv4(6) / UDP / VXLAN / END + */ +#define ACTION_VXLAN_ENCAP_ITEMS_NUM 5 + +struct vxlan_data { + struct rte_flow_action_vxlan_encap conf; + struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM]; +}; + enum nfp_flower_tun_type { NFP_FL_TUN_NONE = 0, NFP_FL_TUN_GRE = 1, @@ -153,8 +164,28 @@ struct rte_flow { enum nfp_flow_type type; }; +/* Forward declaration */ +struct nfp_flower_representor; + int nfp_flow_priv_init(struct nfp_pf_dev *pf_dev); void nfp_flow_priv_uninit(struct nfp_pf_dev *pf_dev); int nfp_net_flow_ops_get(struct rte_eth_dev *dev, const struct rte_flow_ops **ops); +bool nfp_flow_inner_item_get(const struct rte_flow_item items[], + const struct rte_flow_item **inner_item); +struct rte_flow *nfp_flow_process(struct nfp_flower_representor *representor, + const struct rte_flow_item items[], + const struct rte_flow_action actions[], + bool validate_flag, + uint64_t cookie, + bool install_flag); +int nfp_flow_table_add(struct nfp_flow_priv *priv, + struct rte_flow *nfp_flow); +int nfp_flow_teardown(struct nfp_flow_priv *priv, + struct rte_flow *nfp_flow, + bool validate_flag); +void nfp_flow_free(struct rte_flow *nfp_flow); +int nfp_flow_destroy(struct rte_eth_dev *dev, + struct rte_flow *nfp_flow, + struct rte_flow_error *error); #endif /* _NFP_FLOW_H_ */ From patchwork Sat Sep 30 10:00:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chaoyong He X-Patchwork-Id: 132251 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1C14042682; Sat, 30 Sep 2023 12:01:59 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5D515402CA; Sat, 30 Sep 2023 12:01:47 +0200 (CEST) Received: from NAM02-DM3-obe.outbound.protection.outlook.com (mail-dm3nam02on2105.outbound.protection.outlook.com [40.107.95.105]) by mails.dpdk.org (Postfix) with ESMTP id 728BE40287 for ; Sat, 30 Sep 2023 12:01:45 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=NMFZ0FKOqGRM0/x6hx/5wS/gOGVo1acLKaK9jjxCwmLxN8T5WcWoU1vFubjRXnoOfY11L0smYdBasjHAaI1S4Ns7qJyWxhnHt2ObulnbOAHKNlgB+rog8v83Smp8GzkUnO6HWFsKv9srG9xW0S9w1Fp4zL3Vlkqj9/V5I4m6gnjC6hhatNJSsUAy3UViHw50z22Paci0+NdcZFadwAp6eJdPO/OvGkzjYIEpRYKph4o0XZt83BsaUclh/UqKl4PBGqoe6riAJm4Uu6ZoO3oBq6lRLvlb1sIDpK/qg0CgcL53hA6XHuqn/AEfc9KNLqRt80CZOBd2akn3jreH6LXaAg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=uS7pVZ1ThvG3v0Ni+rCXB9KUw2Dt0eVhVOQLMNPfHes=; b=MKqr2Rv0I+Lmst+RBNvoTxSOZsWHkF+YMuVjXxifTbZefrbLhuqSDdbRiveYxWHLl1lJJksc/1ilHZ+t8bP8ntMlvRmpJrs0iFWz4phQode4PQVZAHvozI9hwhTWySDOABbS5sY2YW/6sIbJXP1SoJeCFgXiH1AmILJTgpzg4m6zDwjoPCEojY46NY7+JOeCB5TJmmP3lRKzikZcBhweObtIZsx3j4Yy5CxMzXNYqOE48U+5qEd48ameqTX3HlpwS4Wyv1NuiFg8M55HgTMk3yJkDvhJRChT6uohHrnpiRvgIWbcQPQgu8swfZbG347XtBI/JJ1fAPAMwkQ+R6QvqA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=corigine.com; dmarc=pass action=none header.from=corigine.com; dkim=pass header.d=corigine.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=corigine.onmicrosoft.com; s=selector2-corigine-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=uS7pVZ1ThvG3v0Ni+rCXB9KUw2Dt0eVhVOQLMNPfHes=; b=MZR9O0rJgrE5lyygPXsFHNJrYc6IM++14HNOYIRzs4kXtPAdsrzx63tDDIZheLd/Qli1g+E2MAhU53eDz4SZ8uGca8t41WqCUw4nWcAtH0KXWPp7cHjP8wcAhoDMUD5hNeyIBbGGWMj27/tIvxymXVbGuDJoZ7JWqHf+P+EJ0V0= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=corigine.com; Received: from SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5) by PH7PR13MB5429.namprd13.prod.outlook.com (2603:10b6:510:138::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6813.21; Sat, 30 Sep 2023 10:01:42 +0000 Received: from SJ0PR13MB5545.namprd13.prod.outlook.com ([fe80::28c0:63e2:ecd1:9314]) by SJ0PR13MB5545.namprd13.prod.outlook.com ([fe80::28c0:63e2:ecd1:9314%4]) with mapi id 15.20.6813.027; Sat, 30 Sep 2023 10:01:42 +0000 From: Chaoyong He To: dev@dpdk.org Cc: oss-drivers@corigine.com, Chaoyong He Subject: [PATCH 2/4] net/nfp: add infrastructure for ct flow merge Date: Sat, 30 Sep 2023 18:00:51 +0800 Message-Id: <20230930100053.1227215-3-chaoyong.he@corigine.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230930100053.1227215-1-chaoyong.he@corigine.com> References: <20230930100053.1227215-1-chaoyong.he@corigine.com> X-ClientProxiedBy: PH8PR22CA0022.namprd22.prod.outlook.com (2603:10b6:510:2d1::17) To SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ0PR13MB5545:EE_|PH7PR13MB5429:EE_ X-MS-Office365-Filtering-Correlation-Id: 9948fa67-07e4-4d73-3d4f-08dbc19c3ed0 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: wqW68OB4PnYBu9K5gHM2YqlEzD1S2khhiKYSGrrcRs0c+bajeP4Hi3V4zprFnH4y9N4asgwgU0XouVIxa3HlxDHr2/h6lzjx/8zgosEtdjQjf3xWvTKdylF83xgKjZC1pKxOtMWa98A83KSmZdlvbunNoXaoQLbC7TgB20+vbN0WJsoT0E16bHcyNI9UEE2Whu2ualOSvN+gM5Lk+AX6f5nnQFlLsR2d+hlIKBQS66nkdQpuWcXwLOsCNedwqzU5P0/rBbZXdDC3MG5ZWd7Xp+HruFUekRL3x08gP2B17bMN5AMz5ARQelz80iuaBNBCRQJe1MoIEe6Thsu4mOMHrZQViEhNclB9EhQyMaefTQIdTZAx0kByv9dYwoksbzHp3O2EAP9L8C3K0NoonpTwx/yBCIcw9EqS+4c3pIpSAsCXxwIrYdKzbg6lpfiukPY1MFAifc1q4RfR1d89nTAg8ENOvqh2eJY9cZzGg7KOpObhcW4od2ieuv8Oxp+A1w+aATqBZp7BMFzspZOknkHVEAxtAKd62+K0H5WGXR0OhTw6Y3wZd5/8PVGos03uiMcT0fvLa50P5e96LUpl8345n4shUi/760uigpoo8z+OPJRrFLwXsQH3EA2RbTTe6S2XJ5ehgYb1fQ2wgx+T1P09RKhnla+WXitgBjgoMYtFBCQ= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:SJ0PR13MB5545.namprd13.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(366004)(346002)(136003)(39830400003)(396003)(376002)(230922051799003)(1800799009)(451199024)(64100799003)(186009)(66946007)(6916009)(8676002)(44832011)(316002)(4326008)(66476007)(66556008)(38100700002)(38350700002)(86362001)(6486002)(478600001)(30864003)(41300700001)(2906002)(5660300002)(8936002)(6512007)(2616005)(52116002)(107886003)(1076003)(26005)(36756003)(6666004)(83380400001)(6506007)(579004)(559001); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: rnkskTbK/HRFY5QCIHUbqxXhzbsDgiZzkpkjbTpZds+RCoK++JmBWw/d6blQD6mP8am3pqNo7N8S84D+zlzjl2i64493ZgDnMxfo9AMWk2c+jjkHWvFK8sNCJqOmcHszoLhalKV0RtFQsFvgKzS3lcE1SiraP2rLHS8AWCgVe+hW59ccA7+Bkf8mZXXp0aI+d/ej8S+J+rHhUsa2WEmG4VW/rVl599p4QihJ70P5S5FvTQC7Llvbi9SjZUlYekXNUf4CnmKoba9VdU3bZBjBHHr4kE0c2Huw+BsqY1qdFnlJ6D0NI3cOa2mEr+rAvnqeV/6nzhus37hhwUsiAsKLur5Oxfs6dkHhYLQQ78YK3xk3fh1HnEMh2aW+rI6mJQRbq/hVd3AYSTeS/lgmxs+TqI67Fme+Z/H/CFoAuamrOVLi3YGqkucCgCyhGBtLBZJyQ4Y108jt483zVM495My0r0zqe6H0O5E7dyfq7uxsRhLCZtchUfo/Rzcr59+hqkh7G+W7D1uptqqQ4mqhiGQuDunGnHC3fahWrREsYbPZJ+yxFO33MCcmMiDryh0px4vZMDJwgU4++dcQs19NNx4XtLJY+Pk55KCRsonpyDrQf+Xus/LIV2B5ZOeIak1FTxyik3lI8GAZLa+aM+Q7i+KTzxp8BbkhKVmBgCeO0JH34KOx1H9coJ54GCxz0357eH/Hyl4nBia5OOIr3U1rbs+AZ6K/EZvEf0/gfgdOU64AT19YAVCWSBfIOm5J5LU5zH/8wQP0jZkNykMQP+KYLUA7L+wCVhMiXDsuAWNNWGtO0jNYyBHkfwGBqAjRn1rRIbWAeMf36k2TGxDeD1PYbMpT/Hyd20llO80075B3sHOxeTA/PBlBX4LbE1ei6eEGia6PK23dRvyBIFznsjFL1/Q5lZ7mNy87NjaJslyBPNorWQcyqckPdxEVpuW9gUqK6ipF2tmxWeWQplmrYOlgq/EroSmnrcgHVy7LSCV0QTZRUN+d5EpgDCpVEQgLNjhIuO+k9gZHdWJX5rG1rTJHZSIubn/ysrwfqiWoJor2k4yuCZy9g8oPdTnhgwNVQE60r4MhNNkqX4m13d0CaIhXM9lY4D7heUwqixNQiELLQ4yYOzcGFJRszdBYjXkVVmmV9/eYslyxX0KDgC35pslFQOfiFQFlkxPaM8rvoBzw+clpoNDPs9zVsJpt6c8VVXwjObV+F0LklcpPyKYHpnWE2Dfm2CPc8XtPhkvx8WYMs2IGbgpqyUeP3U/HN84hT2kIfg8BHR+xKbyveBpg3epbV+Cp647zTdANQ5v8vwXQo2WCWfEtd00tMwq44nurHHN5DRldE2V03yW/JlvMZNF1xgyZW8EsZPM6vtRbaG5VpJy//q53r/0Jr/u742rcRfwTn+bFBoOrg1jmNsO517AYapVbA12dC1JrnfoqmSBXbHS2vuPhzZXG3mUgh41yyFBFPGjwdiWoCfOxz8SqibKE1Ez4qeEBCMaqahjcBngiO4rxLRXhlVZFtckrOkdQumlsvMVb0qp+eI6C0tM07l5wYDKY1aIIk+2qM16pRyUiL9HtM2r1mVH01qUlnMNF37yv6uDHE4vRaU3DdnzgW/hvgpsnGg== X-OriginatorOrg: corigine.com X-MS-Exchange-CrossTenant-Network-Message-Id: 9948fa67-07e4-4d73-3d4f-08dbc19c3ed0 X-MS-Exchange-CrossTenant-AuthSource: SJ0PR13MB5545.namprd13.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Sep 2023 10:01:42.5287 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: fe128f2c-073b-4c20-818e-7246a585940c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: mk5y7a7jQ0HB8RXezW6SxgL13kVq9zAHC0bXvEnPuXA8yrN/5W0aFZBAmsa9Admun5iokk2iGL+XR7laThYBdIUnGsKWWiQf6f3wO+WKFN8= X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR13MB5429 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add the logic to process the merge of items and actions of pre_ct and post_ct flow. The result will be stored in a field of merged flow. Signed-off-by: Chaoyong He --- drivers/net/nfp/flower/nfp_conntrack.c | 1626 ++++++++++++++++++++++++ drivers/net/nfp/flower/nfp_conntrack.h | 32 + drivers/net/nfp/meson.build | 1 + drivers/net/nfp/nfp_flow.c | 56 + drivers/net/nfp/nfp_flow.h | 4 + 5 files changed, 1719 insertions(+) create mode 100644 drivers/net/nfp/flower/nfp_conntrack.c create mode 100644 drivers/net/nfp/flower/nfp_conntrack.h diff --git a/drivers/net/nfp/flower/nfp_conntrack.c b/drivers/net/nfp/flower/nfp_conntrack.c new file mode 100644 index 0000000000..24762de133 --- /dev/null +++ b/drivers/net/nfp/flower/nfp_conntrack.c @@ -0,0 +1,1626 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Corigine, Inc. + * All rights reserved. + */ + +#include "nfp_conntrack.h" + +#include +#include +#include + +#include "../nfp_flow.h" +#include "../nfp_logs.h" +#include "nfp_flower_representor.h" + +struct ct_data { + uint8_t ct_state; /* Connection state. */ + uint16_t ct_zone; /* Connection zone. */ +}; + +enum ct_entry_type { + CT_TYPE_PRE_CT, + CT_TYPE_POST_CT, +}; + +struct nfp_initial_flow { + struct rte_flow_item *items; + struct rte_flow_action *actions; + uint8_t items_cnt; + uint8_t actions_cnt; +}; + +struct nfp_ct_flow_entry { + uint64_t cookie; + LIST_ENTRY(nfp_ct_flow_entry) pre_ct_list; + LIST_ENTRY(nfp_ct_flow_entry) post_ct_list; + LIST_HEAD(, nfp_ct_merge_entry) children; + enum ct_entry_type type; + struct nfp_flower_representor *repr; + struct nfp_ct_zone_entry *ze; + struct nfp_initial_flow rule; +}; + +struct nfp_ct_map_entry { + uint64_t cookie; + struct nfp_ct_flow_entry *fe; +}; + +struct nfp_ct_zone_entry { + uint32_t zone; + struct nfp_flow_priv *priv; + LIST_HEAD(, nfp_ct_flow_entry) pre_ct_list; + LIST_HEAD(, nfp_ct_flow_entry) post_ct_list; + struct rte_hash *ct_merge_table; +}; + +struct nfp_ct_merge_entry { + uint64_t cookie[2]; + LIST_ENTRY(nfp_ct_merge_entry) pre_ct_list; + LIST_ENTRY(nfp_ct_merge_entry) post_ct_list; + struct nfp_initial_flow rule; + struct nfp_ct_zone_entry *ze; + struct nfp_ct_flow_entry *pre_ct_parent; + struct nfp_ct_flow_entry *post_ct_parent; +}; + +/* OVS_KEY_ATTR_CT_STATE flags */ +#define OVS_CS_F_NEW 0x01 /* Beginning of a new connection. */ +#define OVS_CS_F_ESTABLISHED 0x02 /* Part of an existing connection. */ +#define OVS_CS_F_RELATED 0x04 /* Related to an established connection. */ +#define OVS_CS_F_REPLY_DIR 0x08 /* Flow is in the reply direction. */ +#define OVS_CS_F_INVALID 0x10 /* Could not track connection. */ +#define OVS_CS_F_TRACKED 0x20 /* Conntrack has occurred. */ +#define OVS_CS_F_SRC_NAT 0x40 /* Packet's source address/port was mangled by NAT. */ +#define OVS_CS_F_DST_NAT 0x80 /* Packet's destination address/port was mangled by NAT. */ + +typedef void (*nfp_action_free_fn)(void *field); +typedef bool (*nfp_action_copy_fn)(const void *src, void *dst); + +static bool +is_pre_ct_flow(const struct ct_data *ct, + const struct rte_flow_action *actions) +{ + const struct rte_flow_action *action; + + if (ct == NULL) + return false; + + for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) { + if (action->type == RTE_FLOW_ACTION_TYPE_CONNTRACK) + return true; + } + + return false; +} + +static bool +is_post_ct_flow(const struct ct_data *ct) +{ + if (ct == NULL) + return false; + + if ((ct->ct_state & OVS_CS_F_ESTABLISHED) != 0) + return true; + + return false; +} + +static bool +is_ct_commit_flow(const struct ct_data *ct) +{ + if (ct == NULL) + return false; + + if ((ct->ct_state & OVS_CS_F_NEW) != 0) + return true; + + return false; +} + +static struct nfp_ct_merge_entry * +nfp_ct_merge_table_search(struct nfp_ct_zone_entry *ze, + char *hash_data, + uint32_t hash_len) +{ + int index; + uint32_t hash_key; + struct nfp_ct_merge_entry *m_ent; + + hash_key = rte_jhash(hash_data, hash_len, ze->priv->hash_seed); + index = rte_hash_lookup_data(ze->ct_merge_table, &hash_key, (void **)&m_ent); + if (index < 0) { + PMD_DRV_LOG(DEBUG, "Data NOT found in the ct_merge table"); + return NULL; + } + + return m_ent; +} + +static bool +nfp_ct_merge_table_add(struct nfp_ct_zone_entry *ze, + struct nfp_ct_merge_entry *merge_entry) +{ + int ret; + uint32_t hash_key; + + hash_key = rte_jhash(merge_entry, sizeof(uint64_t) * 2, ze->priv->hash_seed); + ret = rte_hash_add_key_data(ze->ct_merge_table, &hash_key, merge_entry); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Add to ct_merge table failed"); + return false; + } + + return true; +} + +static void +nfp_ct_merge_table_delete(struct nfp_ct_zone_entry *ze, + struct nfp_ct_merge_entry *m_ent) +{ + int ret; + uint32_t hash_key; + + hash_key = rte_jhash(m_ent, sizeof(uint64_t) * 2, ze->priv->hash_seed); + ret = rte_hash_del_key(ze->ct_merge_table, &hash_key); + if (ret < 0) + PMD_DRV_LOG(ERR, "Delete from ct_merge table failed, ret=%d", ret); +} + +static void +nfp_ct_merge_entry_destroy(struct nfp_ct_merge_entry *m_ent) +{ + struct nfp_ct_zone_entry *ze; + + ze = m_ent->ze; + nfp_ct_merge_table_delete(ze, m_ent); + + rte_free(m_ent->rule.actions); + rte_free(m_ent->rule.items); + LIST_REMOVE(m_ent, pre_ct_list); + LIST_REMOVE(m_ent, post_ct_list); + rte_free(m_ent); +} + +struct nfp_ct_map_entry * +nfp_ct_map_table_search(struct nfp_flow_priv *priv, + char *hash_data, + uint32_t hash_len) +{ + int index; + uint32_t hash_key; + struct nfp_ct_map_entry *me; + + hash_key = rte_jhash(hash_data, hash_len, priv->hash_seed); + index = rte_hash_lookup_data(priv->ct_map_table, &hash_key, (void **)&me); + if (index < 0) { + PMD_DRV_LOG(DEBUG, "Data NOT found in the ct_map table"); + return NULL; + } + + return me; +} + +static bool +nfp_ct_map_table_add(struct nfp_flow_priv *priv, + struct nfp_ct_map_entry *me) +{ + int ret; + uint32_t hash_key; + + hash_key = rte_jhash(me, sizeof(uint64_t), priv->hash_seed); + ret = rte_hash_add_key_data(priv->ct_map_table, &hash_key, me); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Add to ct_map table failed"); + return false; + } + + return true; +} + +static void +nfp_ct_map_table_delete(struct nfp_flow_priv *priv, + struct nfp_ct_map_entry *me) +{ + int ret; + uint32_t hash_key; + + hash_key = rte_jhash(me, sizeof(uint64_t), priv->hash_seed); + ret = rte_hash_del_key(priv->ct_map_table, &hash_key); + if (ret < 0) + PMD_DRV_LOG(ERR, "Delete form ct_map table failed"); +} + +static void +nfp_ct_map_entry_destroy(struct nfp_ct_map_entry *me) +{ + rte_free(me); +} + +static void +nfp_ct_flow_item_free_real(void *field, + enum rte_flow_item_type type) +{ + switch (type) { + case RTE_FLOW_ITEM_TYPE_VOID: + break; + case RTE_FLOW_ITEM_TYPE_ETH: /* FALLTHROUGH */ + case RTE_FLOW_ITEM_TYPE_VLAN: /* FALLTHROUGH */ + case RTE_FLOW_ITEM_TYPE_MPLS: /* FALLTHROUGH */ + case RTE_FLOW_ITEM_TYPE_IPV4: /* FALLTHROUGH */ + case RTE_FLOW_ITEM_TYPE_IPV6: /* FALLTHROUGH */ + case RTE_FLOW_ITEM_TYPE_TCP: /* FALLTHROUGH */ + case RTE_FLOW_ITEM_TYPE_UDP: /* FALLTHROUGH */ + case RTE_FLOW_ITEM_TYPE_SCTP: /* FALLTHROUGH */ + case RTE_FLOW_ITEM_TYPE_ICMP: /* FALLTHROUGH */ + case RTE_FLOW_ITEM_TYPE_ICMP6: /* FALLTHROUGH */ + case RTE_FLOW_ITEM_TYPE_VXLAN: /* FALLTHROUGH */ + case RTE_FLOW_ITEM_TYPE_GRE: /* FALLTHROUGH */ + case RTE_FLOW_ITEM_TYPE_GRE_KEY: /* FALLTHROUGH */ + case RTE_FLOW_ITEM_TYPE_GENEVE: + rte_free(field); + break; + default: + break; + } +} + +static void +nfp_ct_flow_item_free(struct rte_flow_item *item) +{ + if (item->spec != NULL) + nfp_ct_flow_item_free_real((void *)(ptrdiff_t)item->spec, item->type); + + if (item->mask != NULL) + nfp_ct_flow_item_free_real((void *)(ptrdiff_t)item->mask, item->type); + + if (item->last != NULL) + nfp_ct_flow_item_free_real((void *)(ptrdiff_t)item->last, item->type); +} + +static void +nfp_ct_flow_items_free(struct rte_flow_item *items, + uint8_t item_cnt) +{ + uint8_t loop; + + for (loop = 0; loop < item_cnt; ++loop) + nfp_ct_flow_item_free(items + loop); +} + +static bool +nfp_flow_item_conf_size_get(enum rte_flow_item_type type, + size_t *size) +{ + size_t len = 0; + + switch (type) { + case RTE_FLOW_ITEM_TYPE_VOID: + break; + case RTE_FLOW_ITEM_TYPE_ETH: + len = sizeof(struct rte_flow_item_eth); + break; + case RTE_FLOW_ITEM_TYPE_VLAN: + len = sizeof(struct rte_flow_item_vlan); + break; + case RTE_FLOW_ITEM_TYPE_MPLS: + len = sizeof(struct rte_flow_item_mpls); + break; + case RTE_FLOW_ITEM_TYPE_IPV4: + len = sizeof(struct rte_flow_item_ipv4); + break; + case RTE_FLOW_ITEM_TYPE_IPV6: + len = sizeof(struct rte_flow_item_ipv6); + break; + case RTE_FLOW_ITEM_TYPE_TCP: + len = sizeof(struct rte_flow_item_tcp); + break; + case RTE_FLOW_ITEM_TYPE_UDP: + len = sizeof(struct rte_flow_item_udp); + break; + case RTE_FLOW_ITEM_TYPE_SCTP: + len = sizeof(struct rte_flow_item_sctp); + break; + case RTE_FLOW_ITEM_TYPE_VXLAN: + len = sizeof(struct rte_flow_item_vxlan); + break; + case RTE_FLOW_ITEM_TYPE_GRE: + len = sizeof(struct rte_flow_item_gre); + break; + case RTE_FLOW_ITEM_TYPE_GRE_KEY: + len = sizeof(rte_be32_t); + break; + case RTE_FLOW_ITEM_TYPE_GENEVE: + len = sizeof(struct rte_flow_item_geneve); + break; + default: + PMD_DRV_LOG(ERR, "Unsupported item type: %d", type); + return false; + } + + *size = len; + + return true; +} + +static void * +nfp_ct_flow_item_copy_real(const void *src, + enum rte_flow_item_type type) +{ + bool ret; + void *dst; + size_t len; + + ret = nfp_flow_item_conf_size_get(type, &len); + if (!ret) { + PMD_DRV_LOG(ERR, "Get flow item conf size failed"); + return NULL; + } + + dst = rte_zmalloc("flow_item", len, 0); + if (dst == NULL) { + PMD_DRV_LOG(ERR, "Malloc memory for ct item failed"); + return NULL; + } + + rte_memcpy(dst, src, len); + + return dst; +} + +static bool +nfp_ct_flow_item_copy(const struct rte_flow_item *src, + struct rte_flow_item *dst) +{ + dst->type = src->type; + + if (src->spec != NULL) { + dst->spec = nfp_ct_flow_item_copy_real(src->spec, src->type); + if (dst->spec == NULL) { + PMD_DRV_LOG(ERR, "Copy spec of ct item failed"); + goto end; + } + } + + if (src->mask != NULL) { + dst->mask = nfp_ct_flow_item_copy_real(src->mask, src->type); + if (dst->mask == NULL) { + PMD_DRV_LOG(ERR, "Copy mask of ct item failed"); + goto free_spec; + } + } + + if (src->last != NULL) { + dst->last = nfp_ct_flow_item_copy_real(src->last, src->type); + if (dst->last == NULL) { + PMD_DRV_LOG(ERR, "Copy last of ct item failed"); + goto free_mask; + } + } + + return true; + +free_mask: + nfp_ct_flow_item_free_real((void *)(ptrdiff_t)dst->mask, dst->type); +free_spec: + nfp_ct_flow_item_free_real((void *)(ptrdiff_t)dst->spec, dst->type); +end: + return false; +} + +static bool +nfp_ct_flow_items_copy(const struct rte_flow_item *src, + struct rte_flow_item *dst, + uint8_t item_cnt) +{ + bool ret; + uint8_t loop; + + for (loop = 0; loop < item_cnt; ++loop) { + ret = nfp_ct_flow_item_copy(src + loop, dst + loop); + if (!ret) { + PMD_DRV_LOG(ERR, "Copy ct item failed"); + nfp_ct_flow_items_free(dst, loop); + return false; + } + } + + return true; +} + +static void +nfp_ct_flow_action_free_real(void *field, + nfp_action_free_fn func) +{ + if (func != NULL) + func(field); + + rte_free(field); +} + +static void +nfp_ct_flow_action_free_vxlan(void *field) +{ + struct vxlan_data *vxlan = field; + + nfp_ct_flow_items_free(vxlan->items, ACTION_VXLAN_ENCAP_ITEMS_NUM); +} + +static void +nfp_ct_flow_action_free_raw(void *field) +{ + struct rte_flow_action_raw_encap *raw_encap = field; + + rte_free(raw_encap->data); +} + +static void +nfp_ct_flow_action_free(struct rte_flow_action *action) +{ + nfp_action_free_fn func = NULL; + + if (action->conf == NULL) + return; + + switch (action->type) { + case RTE_FLOW_ACTION_TYPE_VOID: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_MARK: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_DROP: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_COUNT: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_RSS: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_JUMP: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_RAW_DECAP: + return; + case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_MAC_DST: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_PORT_ID: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_TTL: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_TP_SRC: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_TP_DST: + break; + case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: + func = nfp_ct_flow_action_free_vxlan; + break; + case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: + func = nfp_ct_flow_action_free_raw; + break; + default: + PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type); + break; + } + + nfp_ct_flow_action_free_real((void *)(ptrdiff_t)action->conf, func); +} + +static void +nfp_ct_flow_actions_free(struct rte_flow_action *actions, + uint8_t action_cnt) +{ + uint8_t loop; + + for (loop = 0; loop < action_cnt; ++loop) + nfp_ct_flow_action_free(actions + loop); +} + +static void * +nfp_ct_flow_action_copy_real(const void *src, + size_t len, + nfp_action_copy_fn func) +{ + bool ret; + void *dst; + + dst = rte_zmalloc("flow_action", len, 0); + if (dst == NULL) { + PMD_DRV_LOG(ERR, "Malloc memory for ct action failed"); + return NULL; + } + + if (func != NULL) { + ret = func(src, dst); + if (!ret) { + PMD_DRV_LOG(ERR, "Copy ct action failed"); + return NULL; + } + + return dst; + } + + rte_memcpy(dst, src, len); + + return dst; +} + +static bool +nfp_ct_flow_action_copy_vxlan(const void *src, + void *dst) +{ + struct vxlan_data *vxlan_dst = dst; + const struct vxlan_data *vxlan_src = src; + + vxlan_dst->conf.definition = vxlan_dst->items; + return nfp_ct_flow_items_copy(vxlan_src->items, vxlan_dst->items, + ACTION_VXLAN_ENCAP_ITEMS_NUM); +} + +static bool +nfp_ct_flow_action_copy_raw(const void *src, + void *dst) +{ + struct rte_flow_action_raw_encap *raw_dst = dst; + const struct rte_flow_action_raw_encap *raw_src = src; + + raw_dst->size = raw_src->size; + raw_dst->data = nfp_ct_flow_action_copy_real(raw_src->data, + raw_src->size, NULL); + if (raw_dst->data == NULL) { + PMD_DRV_LOG(ERR, "Copy ct action process failed"); + return false; + } + + return true; +} + +static bool +nfp_ct_flow_action_copy(const struct rte_flow_action *src, + struct rte_flow_action *dst) +{ + size_t len; + nfp_action_copy_fn func = NULL; + + dst->type = src->type; + + if (src->conf == NULL) + return true; + + switch (src->type) { + case RTE_FLOW_ACTION_TYPE_VOID: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_MARK: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_DROP: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_COUNT: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_RSS: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_JUMP: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_RAW_DECAP: + return true; + case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_MAC_DST: + len = sizeof(struct rte_flow_action_set_mac); + break; + case RTE_FLOW_ACTION_TYPE_PORT_ID: + len = sizeof(struct rte_flow_action_port_id); + break; + case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN: + len = sizeof(struct rte_flow_action_of_push_vlan); + break; + case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST: + len = sizeof(struct rte_flow_action_set_ipv4); + break; + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP: + len = sizeof(struct rte_flow_action_set_dscp); + break; + case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST: + len = sizeof(struct rte_flow_action_set_ipv6); + break; + case RTE_FLOW_ACTION_TYPE_SET_TTL: + len = sizeof(struct rte_flow_action_set_ttl); + break; + case RTE_FLOW_ACTION_TYPE_SET_TP_SRC: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_TP_DST: + len = sizeof(struct rte_flow_action_set_tp); + break; + case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: + len = sizeof(struct vxlan_data); + func = nfp_ct_flow_action_copy_vxlan; + break; + case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: + len = sizeof(struct rte_flow_action_raw_encap); + func = nfp_ct_flow_action_copy_raw; + break; + default: + PMD_DRV_LOG(DEBUG, "Unsupported action type: %d", src->type); + return false; + } + + dst->conf = nfp_ct_flow_action_copy_real(src->conf, len, func); + if (dst->conf == NULL) { + PMD_DRV_LOG(DEBUG, "Copy ct action process failed"); + return false; + } + + return true; +} + +static bool +nfp_ct_flow_actions_copy(const struct rte_flow_action *src, + struct rte_flow_action *dst, + uint8_t action_cnt) +{ + bool ret; + uint8_t loop; + + for (loop = 0; loop < action_cnt; ++loop) { + ret = nfp_ct_flow_action_copy(src + loop, dst + loop); + if (!ret) { + PMD_DRV_LOG(DEBUG, "Copy ct action failed"); + nfp_ct_flow_actions_free(dst, loop); + return false; + } + } + + return true; +} + +static struct nfp_ct_flow_entry * +nfp_ct_flow_entry_get(struct nfp_ct_zone_entry *ze, + struct nfp_flower_representor *repr, + const struct rte_flow_item items[], + const struct rte_flow_action actions[], + uint64_t cookie) +{ + bool ret; + uint8_t loop; + uint8_t item_cnt = 1; /* the RTE_FLOW_ITEM_TYPE_END */ + uint8_t action_cnt = 1; /* the RTE_FLOW_ACTION_TYPE_END */ + struct nfp_flow_priv *priv; + struct nfp_ct_map_entry *me; + struct nfp_ct_flow_entry *fe; + + fe = rte_zmalloc("ct_flow_entry", sizeof(*fe), 0); + if (fe == NULL) { + PMD_DRV_LOG(ERR, "Could not alloc ct_flow entry"); + return NULL; + } + + fe->ze = ze; + fe->repr = repr; + fe->cookie = cookie; + LIST_INIT(&fe->children); + + for (loop = 0; (items + loop)->type != RTE_FLOW_ITEM_TYPE_END; loop++) + item_cnt++; + for (loop = 0; (actions + loop)->type != RTE_FLOW_ACTION_TYPE_END; loop++) + action_cnt++; + + fe->rule.items = rte_zmalloc("ct_flow_item", + sizeof(struct rte_flow_item) * item_cnt, 0); + if (fe->rule.items == NULL) { + PMD_DRV_LOG(ERR, "Could not alloc ct flow items"); + goto free_flow_entry; + } + + fe->rule.actions = rte_zmalloc("ct_flow_action", + sizeof(struct rte_flow_action) * action_cnt, 0); + if (fe->rule.actions == NULL) { + PMD_DRV_LOG(ERR, "Could not alloc ct flow actions"); + goto free_flow_item; + } + + /* Deep copy of items */ + ret = nfp_ct_flow_items_copy(items, fe->rule.items, item_cnt); + if (!ret) { + PMD_DRV_LOG(ERR, "Could not deep copy ct flow items"); + goto free_flow_action; + } + + /* Deep copy of actions */ + ret = nfp_ct_flow_actions_copy(actions, fe->rule.actions, action_cnt); + if (!ret) { + PMD_DRV_LOG(ERR, "Could not deep copy ct flow actions"); + goto free_copied_items; + } + + fe->rule.items_cnt = item_cnt; + fe->rule.actions_cnt = action_cnt; + + /* Now add a ct map entry */ + me = rte_zmalloc("ct_map_entry", sizeof(*me), 0); + if (me == NULL) { + PMD_DRV_LOG(ERR, "Malloc memory for ct map entry failed"); + goto free_copied_actions; + } + + me->cookie = fe->cookie; + me->fe = fe; + + priv = repr->app_fw_flower->flow_priv; + ret = nfp_ct_map_table_add(priv, me); + if (!ret) { + PMD_DRV_LOG(ERR, "Add into ct map table failed"); + goto free_map_entry; + } + + return fe; + +free_map_entry: + nfp_ct_map_entry_destroy(me); +free_copied_actions: + nfp_ct_flow_actions_free(fe->rule.actions, action_cnt); +free_copied_items: + nfp_ct_flow_items_free(fe->rule.items, item_cnt); +free_flow_action: + rte_free(fe->rule.actions); +free_flow_item: + rte_free(fe->rule.items); +free_flow_entry: + rte_free(fe); + + return NULL; +} + +static void +nfp_flow_children_merge_free(struct nfp_ct_flow_entry *fe) +{ + struct nfp_ct_merge_entry *m_ent; + + switch (fe->type) { + case CT_TYPE_PRE_CT: + LIST_FOREACH(m_ent, &fe->children, pre_ct_list) + nfp_ct_merge_entry_destroy(m_ent); + break; + case CT_TYPE_POST_CT: + LIST_FOREACH(m_ent, &fe->children, post_ct_list) + nfp_ct_merge_entry_destroy(m_ent); + break; + default: + break; + } +} + +static void +nfp_ct_flow_entry_destroy_partly(struct nfp_ct_flow_entry *fe) +{ + struct nfp_ct_map_entry *me; + + if (!LIST_EMPTY(&fe->children)) + nfp_flow_children_merge_free(fe); + + me = nfp_ct_map_table_search(fe->ze->priv, (char *)&fe->cookie, sizeof(uint64_t)); + if (me != NULL) { + nfp_ct_map_table_delete(fe->ze->priv, me); + nfp_ct_map_entry_destroy(me); + } + + nfp_ct_flow_actions_free(fe->rule.actions, fe->rule.actions_cnt); + nfp_ct_flow_items_free(fe->rule.items, fe->rule.items_cnt); + rte_free(fe->rule.actions); + rte_free(fe->rule.items); + rte_free(fe); +} + +static void +nfp_ct_flow_entry_destroy(struct nfp_ct_flow_entry *fe) +{ + LIST_REMOVE(fe, pre_ct_list); + LIST_REMOVE(fe, post_ct_list); + + nfp_ct_flow_entry_destroy_partly(fe); +} + +static struct nfp_ct_zone_entry * +nfp_ct_zone_table_search(struct nfp_flow_priv *priv, + char *hash_data, + uint32_t hash_len) +{ + int index; + uint32_t hash_key; + struct nfp_ct_zone_entry *ze; + + hash_key = rte_jhash(hash_data, hash_len, priv->hash_seed); + index = rte_hash_lookup_data(priv->ct_zone_table, &hash_key, (void **)&ze); + if (index < 0) { + PMD_DRV_LOG(DEBUG, "Data NOT found in the ct_zone table"); + return NULL; + } + + return ze; +} + +static bool +nfp_ct_zone_table_add(struct nfp_flow_priv *priv, + struct nfp_ct_zone_entry *ze) +{ + int ret; + uint32_t hash_key; + + hash_key = rte_jhash(ze, sizeof(uint32_t), priv->hash_seed); + ret = rte_hash_add_key_data(priv->ct_zone_table, &hash_key, ze); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Add to the ct_zone table failed"); + return false; + } + + return true; +} + +static void +nfp_ct_zone_table_delete(struct nfp_flow_priv *priv, + struct nfp_ct_zone_entry *ze) +{ + int ret; + uint32_t hash_key; + + hash_key = rte_jhash(ze, sizeof(uint32_t), priv->hash_seed); + ret = rte_hash_del_key(priv->ct_zone_table, &hash_key); + if (ret < 0) + PMD_DRV_LOG(ERR, "Delete from the ct_zone table failed"); +} + +static bool +nfp_ct_zone_entry_init(struct nfp_ct_zone_entry *ze, + struct nfp_flow_priv *priv, + uint32_t zone, + bool wildcard) +{ + char hash_name[RTE_HASH_NAMESIZE]; + struct rte_hash_parameters ct_merge_hash_params = { + .entries = 1000, + .hash_func = rte_jhash, + .socket_id = rte_socket_id(), + .key_len = sizeof(uint32_t), + .extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY, + }; + + if (wildcard) { + ct_merge_hash_params.name = "ct_wc_merge_table"; + } else { + snprintf(hash_name, sizeof(hash_name), "ct_%d_merge_table", ze->zone); + ct_merge_hash_params.name = hash_name; + } + + ct_merge_hash_params.hash_func_init_val = priv->hash_seed; + ze->ct_merge_table = rte_hash_create(&ct_merge_hash_params); + if (ze->ct_merge_table == NULL) { + PMD_DRV_LOG(ERR, "ct merge table creation failed"); + return false; + } + + ze->zone = zone; + ze->priv = priv; + LIST_INIT(&ze->pre_ct_list); + LIST_INIT(&ze->post_ct_list); + + return true; +} + +static void +nfp_ct_zone_entry_destroy(struct nfp_ct_zone_entry *ze) +{ + struct nfp_ct_flow_entry *fe; + + if (ze == NULL) + return; + + rte_hash_free(ze->ct_merge_table); + + LIST_FOREACH(fe, &ze->pre_ct_list, pre_ct_list) + nfp_ct_flow_entry_destroy(fe); + + LIST_FOREACH(fe, &ze->post_ct_list, post_ct_list) + nfp_ct_flow_entry_destroy(fe); + + rte_free(ze); +} + +static struct nfp_ct_zone_entry * +nfp_ct_zone_entry_get(struct nfp_flow_priv *priv, + uint32_t zone, + bool wildcard) +{ + bool is_ok; + struct nfp_ct_zone_entry *ze; + + if (wildcard) { + if (priv->ct_zone_wc != NULL) + return priv->ct_zone_wc; + + ze = rte_zmalloc("ct_zone_wc", sizeof(*ze), 0); + if (ze == NULL) { + PMD_DRV_LOG(ERR, "Could not alloc ct_zone_wc entry"); + return NULL; + } + + is_ok = nfp_ct_zone_entry_init(ze, priv, zone, true); + if (!is_ok) { + PMD_DRV_LOG(ERR, "Init ct zone wc entry failed"); + goto free_ct_zone_entry; + } + + priv->ct_zone_wc = ze; + } else { + ze = nfp_ct_zone_table_search(priv, (char *)&zone, sizeof(uint32_t)); + if (ze != NULL) + return ze; + + ze = rte_zmalloc("ct_zone_entry", sizeof(*ze), 0); + if (ze == NULL) { + PMD_DRV_LOG(ERR, "Could not alloc ct_zone entry"); + return NULL; + } + + is_ok = nfp_ct_zone_entry_init(ze, priv, zone, false); + if (!is_ok) { + PMD_DRV_LOG(ERR, "Init ct zone entry failed"); + goto free_ct_zone_entry; + } + + is_ok = nfp_ct_zone_table_add(priv, ze); + if (!is_ok) { + PMD_DRV_LOG(ERR, "Add into ct zone table failed"); + goto free_ct_zone_entry; + } + } + + return ze; + +free_ct_zone_entry: + nfp_ct_zone_entry_destroy(ze); + + return NULL; +} + +static void +nfp_ct_zone_entry_free(struct nfp_ct_zone_entry *ze, + bool wildcard) +{ + if (LIST_EMPTY(&ze->pre_ct_list) && LIST_EMPTY(&ze->post_ct_list)) { + if (!wildcard) + nfp_ct_zone_table_delete(ze->priv, ze); + + nfp_ct_zone_entry_destroy(ze); + } +} + +static inline bool +is_item_check_pass(const struct rte_flow_item *item1, + const struct rte_flow_item *item2, + uint8_t *cnt_same) +{ + bool pass; + uint32_t i; + size_t size; + const char *key1 = item1->spec; + const char *key2 = item2->spec; + const char *mask1 = item1->mask; + const char *mask2 = item2->mask; + + if (item1->type != item2->type) + return true; + + pass = nfp_flow_item_conf_size_get(item1->type, &size); + if (!pass) + return false; + + for (i = 0; i < size; i++) { + if ((key1[i] & mask1[i] & mask2[i]) ^ (key2[i] & mask1[i] & mask2[i])) + return false; + } + + *cnt_same = *cnt_same + 1; + + return true; +} + +static bool +nfp_ct_merge_items_check(struct rte_flow_item *items1, + struct rte_flow_item *items2, + uint8_t *cnt_same) +{ + bool pass; + bool is_tun_flow_1; + bool is_tun_flow_2; + const struct rte_flow_item *item1; + const struct rte_flow_item *item2; + const struct rte_flow_item *inner_item1 = NULL; + const struct rte_flow_item *inner_item2 = NULL; + + is_tun_flow_1 = nfp_flow_inner_item_get(items1, &inner_item1); + is_tun_flow_2 = nfp_flow_inner_item_get(items2, &inner_item2); + + if (is_tun_flow_1) { + if (is_tun_flow_2) { + /* Outer layer */ + for (item1 = items1; item1 != inner_item1; item1++) { + for (item2 = items2; item2 != inner_item2; item2++) { + pass = is_item_check_pass(item1, item2, cnt_same); + if (!pass) + return false; + } + } + /* Inner layer */ + for (item1 = inner_item1; item1->type != RTE_FLOW_ITEM_TYPE_END; item1++) { + for (item2 = inner_item2; item2->type != RTE_FLOW_ITEM_TYPE_END; + item2++) { + pass = is_item_check_pass(item1, item2, cnt_same); + if (!pass) + return false; + } + } + } else { + for (item1 = items1; item1 != inner_item1; item1++) { + for (item2 = items2; item2->type != RTE_FLOW_ITEM_TYPE_END; + item2++) { + pass = is_item_check_pass(item1, item2, cnt_same); + if (!pass) + return false; + } + } + } + } else { + if (is_tun_flow_2) { + for (item1 = items1; item1->type != RTE_FLOW_ITEM_TYPE_END; item1++) { + for (item2 = items2; item2 != inner_item2; item2++) { + pass = is_item_check_pass(item1, item2, cnt_same); + if (!pass) + return false; + } + } + } else { + for (item1 = items1; item1->type != RTE_FLOW_ITEM_TYPE_END; item1++) { + for (item2 = items2; item2->type != RTE_FLOW_ITEM_TYPE_END; + item2++) { + pass = is_item_check_pass(item1, item2, cnt_same); + if (!pass) + return false; + } + } + } + } + + return true; +} + +static inline bool +is_action_pattern_check_pass(struct rte_flow_item *items, + enum rte_flow_item_type type) +{ + struct rte_flow_item *item; + + for (item = items; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { + if (item->type == type) + return false; + } + + return true; +} + +static bool +nfp_ct_merge_action_check(struct rte_flow_action *action, + struct rte_flow_item *items) +{ + bool pass = true; + + switch (action->type) { + case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_MAC_DST: + pass = is_action_pattern_check_pass(items, RTE_FLOW_ITEM_TYPE_ETH); + break; + case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP: + pass = is_action_pattern_check_pass(items, RTE_FLOW_ITEM_TYPE_IPV4); + break; + case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP: + pass = is_action_pattern_check_pass(items, RTE_FLOW_ITEM_TYPE_IPV6); + break; + case RTE_FLOW_ACTION_TYPE_SET_TP_SRC: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_TP_DST: + pass = is_action_pattern_check_pass(items, RTE_FLOW_ITEM_TYPE_UDP); + pass |= is_action_pattern_check_pass(items, RTE_FLOW_ITEM_TYPE_TCP); + pass |= is_action_pattern_check_pass(items, RTE_FLOW_ITEM_TYPE_SCTP); + break; + default: + break; + } + + return pass; +} + +static bool +nfp_ct_merge_actions_check(struct rte_flow_action *actions, + struct rte_flow_item *items, + uint8_t *cnt_same) +{ + bool pass = true; + struct rte_flow_action *action; + + for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; action++) { + switch (action->type) { + case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_MAC_DST: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_TP_SRC: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_SET_TP_DST: + pass = nfp_ct_merge_action_check(action, items); + break; + case RTE_FLOW_ACTION_TYPE_CONNTRACK: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_JUMP: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_COUNT: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_DROP: /* FALLTHROUGH */ + case RTE_FLOW_ACTION_TYPE_VOID: + *cnt_same = *cnt_same + 1; + break; + default: + pass = false; + break; + } + } + + return pass; +} + +static void +nfp_ct_merge_item_real(const struct rte_flow_item *item_src, + struct rte_flow_item *item_dst) +{ + uint32_t i; + size_t size; + char *key_dst; + char *mask_dst; + const char *key_src; + const char *mask_src; + + key_src = item_src->spec; + mask_src = item_src->mask; + key_dst = (char *)(ptrdiff_t)item_dst->spec; + mask_dst = (char *)(ptrdiff_t)item_dst->mask; + nfp_flow_item_conf_size_get(item_src->type, &size); + + for (i = 0; i < size; i++) { + key_dst[i] |= key_src[i]; + mask_dst[i] |= mask_src[i]; + } +} + +static bool +nfp_ct_merge_item(uint32_t index, + const struct rte_flow_item *item1, + const struct rte_flow_item *item2_start, + const struct rte_flow_item *item2_end, + struct nfp_ct_merge_entry *merge_entry) +{ + struct rte_flow_item *item; + const struct rte_flow_item *item2; + + /* Copy to the merged items */ + item = &merge_entry->rule.items[index]; + *item = *item1; + + item2 = item2_start; + if (item2_end != NULL) { + for (; item2 != item2_end; item2++) { + if (item1->type == item2->type) { + nfp_ct_merge_item_real(item2, item); + return true; + } + } + } else { + for (; item2->type != RTE_FLOW_ITEM_TYPE_END; item2++) { + if (item1->type == item2->type) { + nfp_ct_merge_item_real(item2, item); + return true; + } + } + } + + return false; +} + +static void +nfp_ct_merge_items(struct nfp_ct_merge_entry *merge_entry) +{ + uint32_t index = 0; + bool is_tun_flow_1; + bool is_tun_flow_2; + struct rte_flow_item *items1; + struct rte_flow_item *items2; + struct rte_flow_item *merge_item; + const struct rte_flow_item *item; + const struct rte_flow_item *inner1 = NULL; + const struct rte_flow_item *inner2 = NULL; + + items1 = merge_entry->pre_ct_parent->rule.items; + items2 = merge_entry->post_ct_parent->rule.items; + is_tun_flow_1 = nfp_flow_inner_item_get(items1, &inner1); + is_tun_flow_2 = nfp_flow_inner_item_get(items2, &inner2); + + if (is_tun_flow_1) { + if (is_tun_flow_2) { + /* Outer layer */ + for (item = items1; item != inner1; item++, index++) { + if (nfp_ct_merge_item(index, item, items2, inner2, merge_entry)) + items2++; + } + + /* Copy the remainning outer layer items */ + for (item = items2; item != inner2; item++, index++) { + merge_item = &merge_entry->rule.items[index]; + *merge_item = *item; + } + + /* Inner layer */ + for (item = inner1; item->type != RTE_FLOW_ITEM_TYPE_END; item++, index++) { + if (nfp_ct_merge_item(index, item, inner2, NULL, merge_entry)) + items2++; + } + + /* Copy the remainning inner layer items */ + for (item = items2; item->type != RTE_FLOW_ITEM_TYPE_END; item++, index++) { + merge_item = &merge_entry->rule.items[index]; + *merge_item = *item; + } + } else { + for (item = items1; item != inner1; item++, index++) { + if (nfp_ct_merge_item(index, item, items2, NULL, merge_entry)) + items2++; + } + + /* Copy the remainning items */ + for (item = items2; item->type != RTE_FLOW_ITEM_TYPE_END; item++, index++) { + merge_item = &merge_entry->rule.items[index]; + *merge_item = *item; + } + + /* Copy the inner layer items */ + for (item = inner1; item->type != RTE_FLOW_ITEM_TYPE_END; item++, index++) { + merge_item = &merge_entry->rule.items[index]; + *merge_item = *item; + } + } + } else { + if (is_tun_flow_2) { + for (item = items1; item->type != RTE_FLOW_ITEM_TYPE_END; item++, index++) { + if (nfp_ct_merge_item(index, item, items2, inner2, merge_entry)) + items2++; + } + + /* Copy the remainning items */ + for (item = items2; item->type != RTE_FLOW_ITEM_TYPE_END; item++, index++) { + merge_item = &merge_entry->rule.items[index]; + *merge_item = *item; + } + } else { + for (item = items1; item->type != RTE_FLOW_ITEM_TYPE_END; item++, index++) { + if (nfp_ct_merge_item(index, item, items2, NULL, merge_entry)) + items2++; + } + + /* Copy the remainning items */ + for (item = items2; item->type != RTE_FLOW_ITEM_TYPE_END; item++, index++) { + merge_item = &merge_entry->rule.items[index]; + *merge_item = *item; + } + } + } +} + +static void +nfp_ct_merge_actions(struct nfp_ct_merge_entry *merge_entry) +{ + struct rte_flow_action *action; + struct rte_flow_action *merge_actions; + + merge_actions = merge_entry->rule.actions; + + action = merge_entry->pre_ct_parent->rule.actions; + for (; action->type != RTE_FLOW_ACTION_TYPE_END; action++) { + if (action->type == RTE_FLOW_ACTION_TYPE_CONNTRACK || + action->type == RTE_FLOW_ACTION_TYPE_JUMP) + continue; + + *merge_actions = *action; + merge_actions++; + } + + action = merge_entry->post_ct_parent->rule.actions; + for (; action->type != RTE_FLOW_ACTION_TYPE_END; action++) { + *merge_actions = *action; + merge_actions++; + } +} + +static bool +nfp_ct_do_flow_merge(struct nfp_ct_zone_entry *ze, + struct nfp_ct_flow_entry *pre_ct_entry, + struct nfp_ct_flow_entry *post_ct_entry) +{ + bool ret; + uint64_t new_cookie[2]; + uint8_t cnt_same_item = 0; + uint8_t cnt_same_action = 0; + struct nfp_ct_merge_entry *merge_entry; + + if (pre_ct_entry->repr != post_ct_entry->repr) + return true; + + ret = nfp_ct_merge_items_check(pre_ct_entry->rule.items, + post_ct_entry->rule.items, &cnt_same_item); + if (!ret) + return true; + + ret = nfp_ct_merge_actions_check(pre_ct_entry->rule.actions, + post_ct_entry->rule.items, &cnt_same_action); + if (!ret) + return true; + + new_cookie[0] = pre_ct_entry->cookie; + new_cookie[1] = post_ct_entry->cookie; + merge_entry = nfp_ct_merge_table_search(ze, (char *)&new_cookie, sizeof(uint64_t) * 2); + if (merge_entry != NULL) + return true; + + merge_entry = rte_zmalloc("ct_merge_entry", sizeof(*merge_entry), 0); + if (merge_entry == NULL) { + PMD_DRV_LOG(ERR, "Malloc memory for ct merge entry failed"); + return false; + } + + merge_entry->ze = ze; + merge_entry->pre_ct_parent = pre_ct_entry; + merge_entry->post_ct_parent = post_ct_entry; + rte_memcpy(merge_entry->cookie, new_cookie, sizeof(new_cookie)); + merge_entry->rule.items_cnt = pre_ct_entry->rule.items_cnt + + post_ct_entry->rule.items_cnt - cnt_same_item - 1; + merge_entry->rule.actions_cnt = pre_ct_entry->rule.actions_cnt + + post_ct_entry->rule.actions_cnt - cnt_same_action - 1; + + merge_entry->rule.items = rte_zmalloc("ct_flow_item", + sizeof(struct rte_flow_item) * merge_entry->rule.items_cnt, 0); + if (merge_entry->rule.items == NULL) { + PMD_DRV_LOG(ERR, "Could not alloc items for merged flow"); + goto merge_exit; + } + + merge_entry->rule.actions = rte_zmalloc("ct_flow_action", + sizeof(struct rte_flow_action) * merge_entry->rule.actions_cnt, 0); + if (merge_entry->rule.actions == NULL) { + PMD_DRV_LOG(ERR, "Could not alloc actions for merged flow"); + goto free_items; + } + + nfp_ct_merge_items(merge_entry); + nfp_ct_merge_actions(merge_entry); + + /* Add this entry to the pre_ct and post_ct lists */ + LIST_INSERT_HEAD(&pre_ct_entry->children, merge_entry, pre_ct_list); + LIST_INSERT_HEAD(&post_ct_entry->children, merge_entry, post_ct_list); + + ret = nfp_ct_merge_table_add(ze, merge_entry); + if (!ret) { + PMD_DRV_LOG(ERR, "Add into ct merge table failed"); + goto free_actions; + } + + return true; + +free_actions: + rte_free(merge_entry->rule.actions); +free_items: + rte_free(merge_entry->rule.items); +merge_exit: + LIST_REMOVE(merge_entry, post_ct_list); + LIST_REMOVE(merge_entry, pre_ct_list); + rte_free(merge_entry); + + return ret; +} + +static bool +nfp_ct_merge_flow_entries(struct nfp_ct_flow_entry *fe, + struct nfp_ct_zone_entry *ze_src, + struct nfp_ct_zone_entry *ze_dst) +{ + bool ret; + struct nfp_ct_flow_entry *fe_tmp; + + if (fe->type == CT_TYPE_PRE_CT) { + LIST_FOREACH(fe_tmp, &ze_src->post_ct_list, post_ct_list) { + ret = nfp_ct_do_flow_merge(ze_dst, fe, fe_tmp); + if (!ret) { + PMD_DRV_LOG(ERR, "Merge for ct pre flow failed"); + return false; + } + } + } else { + LIST_FOREACH(fe_tmp, &ze_src->pre_ct_list, pre_ct_list) { + ret = nfp_ct_do_flow_merge(ze_dst, fe_tmp, fe); + if (!ret) { + PMD_DRV_LOG(ERR, "Merge for ct post flow failed"); + return false; + } + } + } + + return true; +} + +static bool +nfp_flow_handle_pre_ct(const struct rte_flow_item *ct_item, + struct nfp_flower_representor *representor, + const struct rte_flow_item items[], + const struct rte_flow_action actions[], + uint64_t cookie) +{ + bool ret; + struct nfp_flow_priv *priv; + struct nfp_ct_zone_entry *ze; + struct nfp_ct_flow_entry *fe; + const struct ct_data *ct = ct_item->spec; + + priv = representor->app_fw_flower->flow_priv; + ze = nfp_ct_zone_entry_get(priv, ct->ct_zone, false); + if (ze == NULL) { + PMD_DRV_LOG(ERR, "Could not get ct zone entry"); + return false; + } + + /* Add entry to pre_ct_lsit */ + fe = nfp_ct_flow_entry_get(ze, representor, items, actions, cookie); + if (fe == NULL) { + PMD_DRV_LOG(ERR, "Could not get ct flow entry"); + goto ct_zone_entry_free; + } + + fe->type = CT_TYPE_PRE_CT; + LIST_INSERT_HEAD(&ze->pre_ct_list, fe, pre_ct_list); + + ret = nfp_ct_merge_flow_entries(fe, ze, ze); + if (!ret) { + PMD_DRV_LOG(ERR, "Merge ct flow entries failed"); + goto ct_flow_entry_free; + } + + /* Need to check and merge with tables in the wc_zone as well */ + if (priv->ct_zone_wc != NULL) { + ret = nfp_ct_merge_flow_entries(fe, priv->ct_zone_wc, ze); + if (!ret) { + PMD_DRV_LOG(ERR, "Merge ct flow entries wildcast failed"); + goto ct_flow_entry_free; + } + } + + /* The real offload logic comes in next commit, so here just return false for now */ + +ct_flow_entry_free: + nfp_ct_flow_entry_destroy(fe); + +ct_zone_entry_free: + nfp_ct_zone_entry_free(ze, false); + + return false; +} + +static bool +nfp_flow_handle_post_ct(const struct rte_flow_item *ct_item, + struct nfp_flower_representor *representor, + const struct rte_flow_item items[], + const struct rte_flow_action actions[], + uint64_t cookie) +{ + bool ret; + void *next_data; + uint32_t iter = 0; + const void *next_key; + bool wildcard = false; + struct nfp_flow_priv *priv; + struct nfp_ct_zone_entry *ze; + struct nfp_ct_flow_entry *fe; + const struct ct_data *ct = ct_item->spec; + const struct ct_data *ct_mask = ct_item->mask; + + if (ct_mask->ct_zone == 0) { + wildcard = true; + } else if (ct_mask->ct_zone != UINT16_MAX) { + PMD_DRV_LOG(ERR, "Partially wildcard ct_zone is not supported"); + return false; + } + + priv = representor->app_fw_flower->flow_priv; + ze = nfp_ct_zone_entry_get(priv, ct->ct_zone, wildcard); + if (ze == NULL) { + PMD_DRV_LOG(ERR, "Could not get ct zone entry"); + return false; + } + + /* Add entry to post_ct_list */ + fe = nfp_ct_flow_entry_get(ze, representor, items, actions, cookie); + if (fe == NULL) { + PMD_DRV_LOG(ERR, "Could not get ct flow entry"); + goto ct_zone_entry_free; + } + + fe->type = CT_TYPE_POST_CT; + LIST_INSERT_HEAD(&ze->post_ct_list, fe, post_ct_list); + + if (wildcard) { + while (rte_hash_iterate(priv->ct_zone_table, &next_key, &next_data, &iter) >= 0) { + ze = (struct nfp_ct_zone_entry *)next_data; + ret = nfp_ct_merge_flow_entries(fe, ze, ze); + if (!ret) { + PMD_DRV_LOG(ERR, "Merge ct flow entries wildcast failed"); + break; + } + } + } else { + ret = nfp_ct_merge_flow_entries(fe, ze, ze); + } + + if (!ret) + goto ct_flow_entry_free; + + /* The real offload logic comes in next commit, so here just return false for now */ + +ct_flow_entry_free: + nfp_ct_flow_entry_destroy(fe); + +ct_zone_entry_free: + nfp_ct_zone_entry_free(ze, wildcard); + + return false; +} + +struct rte_flow * +nfp_ct_flow_setup(struct nfp_flower_representor *representor, + const struct rte_flow_item items[], + const struct rte_flow_action actions[], + const struct rte_flow_item *ct_item, + bool validate_flag, + uint64_t cookie) +{ + const struct ct_data *ct; + + if (ct_item == NULL) + return NULL; + + ct = ct_item->spec; + + if (is_ct_commit_flow(ct)) { + return nfp_flow_process(representor, &items[1], actions, + validate_flag, cookie, false); + } + + if (is_post_ct_flow(ct)) { + if (nfp_flow_handle_post_ct(ct_item, representor, &items[1], + actions, cookie)) { + return nfp_flow_process(representor, &items[1], actions, + validate_flag, cookie, false); + } + + PMD_DRV_LOG(ERR, "Handle nfp post ct flow failed."); + return NULL; + } + + if (is_pre_ct_flow(ct, actions)) { + if (nfp_flow_handle_pre_ct(ct_item, representor, &items[1], + actions, cookie)) { + return nfp_flow_process(representor, &items[1], actions, + validate_flag, cookie, false); + } + + PMD_DRV_LOG(ERR, "Handle nfp pre ct flow failed."); + return NULL; + } + + PMD_DRV_LOG(ERR, "Unsupported ct flow type."); + return NULL; +} diff --git a/drivers/net/nfp/flower/nfp_conntrack.h b/drivers/net/nfp/flower/nfp_conntrack.h new file mode 100644 index 0000000000..149a3eb040 --- /dev/null +++ b/drivers/net/nfp/flower/nfp_conntrack.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Corigine, Inc. + * All rights reserved. + */ + +#ifndef __NFP_CONNTRACK_H__ +#define __NFP_CONNTRACK_H__ + +#include + +#include + +#include "../nfp_flow.h" + +struct nfp_ct_map_entry; + +struct nfp_ct_zone_entry; + +struct nfp_ct_merge_entry; + +struct nfp_ct_map_entry *nfp_ct_map_table_search(struct nfp_flow_priv *priv, + char *hash_data, + uint32_t hash_len); + +struct rte_flow *nfp_ct_flow_setup(struct nfp_flower_representor *representor, + const struct rte_flow_item items[], + const struct rte_flow_action actions[], + const struct rte_flow_item *ct_item, + bool validate_flag, + uint64_t cookie); + +#endif /* __NFP_CONNTRACK_H__ */ diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build index d422269c4b..e6a642da49 100644 --- a/drivers/net/nfp/meson.build +++ b/drivers/net/nfp/meson.build @@ -6,6 +6,7 @@ if not is_linux or not dpdk_conf.get('RTE_ARCH_64') reason = 'only supported on 64-bit Linux' endif sources = files( + 'flower/nfp_conntrack.c', 'flower/nfp_flower.c', 'flower/nfp_flower_cmsg.c', 'flower/nfp_flower_ctrl.c', diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c index 1bb93bcfb5..16a5c7e055 100644 --- a/drivers/net/nfp/nfp_flow.c +++ b/drivers/net/nfp/nfp_flow.c @@ -10,6 +10,7 @@ #include #include +#include "flower/nfp_conntrack.h" #include "flower/nfp_flower_representor.h" #include "nfpcore/nfp_rtsym.h" #include "nfp_logs.h" @@ -3748,6 +3749,8 @@ nfp_flow_setup(struct nfp_flower_representor *representor, bool validate_flag) { uint64_t cookie; + const struct rte_flow_item *item; + const struct rte_flow_item *ct_item = NULL; if (attr->group != 0) PMD_DRV_LOG(INFO, "Pretend we support group attribute."); @@ -3758,8 +3761,19 @@ nfp_flow_setup(struct nfp_flower_representor *representor, if (attr->transfer != 0) PMD_DRV_LOG(INFO, "Pretend we support transfer attribute."); + for (item = items; item->type != RTE_FLOW_ITEM_TYPE_END; ++item) { + if (item->type == RTE_FLOW_ITEM_TYPE_CONNTRACK) { + ct_item = item; + break; + } + } + cookie = rte_rand(); + if (ct_item != NULL) + return nfp_ct_flow_setup(representor, items, actions, + ct_item, validate_flag, cookie); + return nfp_flow_process(representor, items, actions, validate_flag, cookie, true); } @@ -4235,6 +4249,23 @@ nfp_flow_priv_init(struct nfp_pf_dev *pf_dev) .extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY, }; + struct rte_hash_parameters ct_zone_hash_params = { + .name = "ct_zone_table", + .entries = 65536, + .hash_func = rte_jhash, + .socket_id = rte_socket_id(), + .key_len = sizeof(uint32_t), + .extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY, + }; + + struct rte_hash_parameters ct_map_hash_params = { + .name = "ct_map_table", + .hash_func = rte_jhash, + .socket_id = rte_socket_id(), + .key_len = sizeof(uint32_t), + .extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY, + }; + ctx_count = nfp_rtsym_read_le(pf_dev->sym_tbl, "CONFIG_FC_HOST_CTX_COUNT", &ret); if (ret < 0) { @@ -4325,6 +4356,25 @@ nfp_flow_priv_init(struct nfp_pf_dev *pf_dev) goto free_flow_table; } + /* ct zone table */ + ct_zone_hash_params.hash_func_init_val = priv->hash_seed; + priv->ct_zone_table = rte_hash_create(&ct_zone_hash_params); + if (priv->ct_zone_table == NULL) { + PMD_INIT_LOG(ERR, "ct zone table creation failed"); + ret = -ENOMEM; + goto free_pre_tnl_table; + } + + /* ct map table */ + ct_map_hash_params.hash_func_init_val = priv->hash_seed; + ct_map_hash_params.entries = ctx_count; + priv->ct_map_table = rte_hash_create(&ct_map_hash_params); + if (priv->ct_map_table == NULL) { + PMD_INIT_LOG(ERR, "ct map table creation failed"); + ret = -ENOMEM; + goto free_ct_zone_table; + } + /* ipv4 off list */ rte_spinlock_init(&priv->ipv4_off_lock); LIST_INIT(&priv->ipv4_off_list); @@ -4338,6 +4388,10 @@ nfp_flow_priv_init(struct nfp_pf_dev *pf_dev) return 0; +free_ct_zone_table: + rte_hash_free(priv->ct_zone_table); +free_pre_tnl_table: + rte_hash_free(priv->pre_tun_table); free_flow_table: rte_hash_free(priv->flow_table); free_mask_table: @@ -4363,6 +4417,8 @@ nfp_flow_priv_uninit(struct nfp_pf_dev *pf_dev) app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv); priv = app_fw_flower->flow_priv; + rte_hash_free(priv->ct_map_table); + rte_hash_free(priv->ct_zone_table); rte_hash_free(priv->pre_tun_table); rte_hash_free(priv->flow_table); rte_hash_free(priv->mask_table); diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h index 817eaecba2..df16cab8b5 100644 --- a/drivers/net/nfp/nfp_flow.h +++ b/drivers/net/nfp/nfp_flow.h @@ -150,6 +150,10 @@ struct nfp_flow_priv { rte_spinlock_t ipv6_off_lock; /**< Lock the ipv6 off list */ /* neighbor next */ LIST_HEAD(, nfp_fl_tun)nn_list; /**< Store nn entry */ + /* Conntrack */ + struct rte_hash *ct_zone_table; /**< Hash table to store ct zone entry */ + struct nfp_ct_zone_entry *ct_zone_wc; /**< The wildcard ct zone entry */ + struct rte_hash *ct_map_table; /**< Hash table to store ct map entry */ }; struct rte_flow { From patchwork Sat Sep 30 10:00:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chaoyong He X-Patchwork-Id: 132252 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 64E8E42682; Sat, 30 Sep 2023 12:02:10 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0482E402E0; Sat, 30 Sep 2023 12:01:50 +0200 (CEST) Received: from NAM02-DM3-obe.outbound.protection.outlook.com (mail-dm3nam02on2105.outbound.protection.outlook.com [40.107.95.105]) by mails.dpdk.org (Postfix) with ESMTP id 06B9B402A5 for ; Sat, 30 Sep 2023 12:01:46 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Yeik+Eg6AQNpB1cdzDbo7CVNoF9Uxna+NCQmEJ0F4GZBVKZ1ZR3KGq2kMKHsGonQ3uRR0odqjQaTKMg1wb1UJvqpXuYBX43zu0Cfeaw4FPwyGrlw8u5YOgOjAOHCEh/0vB06STaNFQUStkgCTzWxsOmaSEASorZAeKRPVolEGM8ADRG2a9CKl/bOexg0+g/RvwrAtTnpOfc8kqDopdcApSaRqHmA+eUCTADGfVyB/eAsQldonksvOKPIK9oqgA8HTDG0oAW9cF04HHWopEgwwjIRC5nzRC45HCuuY3Rr3IyDOwzGiNnVxjw7DTnK68yLo0FYKXUzLYiqyjbh/lkAEg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=nu5vyg3p7qlR+z6XxZg0v5fC/+HDR7qNkWZGvwSYqdM=; b=XYpkE83ehrSa2VBezvv8KHZQ8e8syA0TUzSPhTNO4askRRsInVweCrnpfvf9vz3hCnVMx2wk4cRxj+YLUndIMFSRGx1CpxblYPRkmLi/u+WX4SDuJofM6qYCKc8BML7IK0OkG5PEJdFrcR0fKIcEykH5BIpowc2zrzj5I/ZY1GtcK7W9scVz7KaZfVCG8+9nHLBNn451KdwREcBQ5PPgULZWhfbY3WiqkqHUU2qXQAlJttIqrk6KEnjK08/q6rFOBRqU2+/pG5s+rPGljKGbgL7w6ytBMOdnSrCGmAr56wF+Y8AIi3Ip9CUbZpZXP6g/U52CBsLnn8JMcn9iRNa7RA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=corigine.com; dmarc=pass action=none header.from=corigine.com; dkim=pass header.d=corigine.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=corigine.onmicrosoft.com; s=selector2-corigine-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=nu5vyg3p7qlR+z6XxZg0v5fC/+HDR7qNkWZGvwSYqdM=; b=uwWypEQTyiVuaJlN3+eVsp1jMlH6roB42cZzhv54r3Vry56vzODIO2UkXFh6FPFesLyOmM4bSsOnDgFW44qdrhBaqTP5FZIcpkbbO3+P++INKtd/0kckr3FOmsU+Q+jWj172idcarppZL/a4lqikRnSHlFL7DaYDH565BaaVwaI= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=corigine.com; Received: from SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5) by PH7PR13MB5429.namprd13.prod.outlook.com (2603:10b6:510:138::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6813.21; Sat, 30 Sep 2023 10:01:44 +0000 Received: from SJ0PR13MB5545.namprd13.prod.outlook.com ([fe80::28c0:63e2:ecd1:9314]) by SJ0PR13MB5545.namprd13.prod.outlook.com ([fe80::28c0:63e2:ecd1:9314%4]) with mapi id 15.20.6813.027; Sat, 30 Sep 2023 10:01:44 +0000 From: Chaoyong He To: dev@dpdk.org Cc: oss-drivers@corigine.com, Chaoyong He Subject: [PATCH 3/4] net/nfp: add call to add and delete the flows to firmware Date: Sat, 30 Sep 2023 18:00:52 +0800 Message-Id: <20230930100053.1227215-4-chaoyong.he@corigine.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230930100053.1227215-1-chaoyong.he@corigine.com> References: <20230930100053.1227215-1-chaoyong.he@corigine.com> X-ClientProxiedBy: PH8PR22CA0022.namprd22.prod.outlook.com (2603:10b6:510:2d1::17) To SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ0PR13MB5545:EE_|PH7PR13MB5429:EE_ X-MS-Office365-Filtering-Correlation-Id: b734fbdf-6087-4e7c-433d-08dbc19c402c X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: rJrZ5tF8qTChfiSr2NshN6V6nPx2Cbmtv2yqJiaUN70XVB6uJhciNvqcHUnqZLtDOHTHChE2Gu+HX+/2qmNJ7T8nCaTMbJV6d2q8t3ZtEODB4HkhYhDV1T/LaRuFMAf6yWhPny22mfzgFaikG3QbEjoTpGFW0szUzsZ/s4U+BSrwnhUUU4tA84cVimkjXccKsflFGUXDRs+plUSc1Kada9BRmwL6C5myZOXfxLPjUBhin0i53W9aTcwAMAXfUuZme8bToiNVwRz3iHf7TmVDaW0w0o12iI5A+hnnPc5mDbro/1OSUBtLXVYgbdFaWUcgThPJNcEK8A282gjZ8TKUVtd4GdvmXV36gR01+vF3+5mTa0pMwOa/a5AfQBtVdv3UhlEhtcNEX9P9qivuja/ti+XXbT/617cNpsrdXXbjobL+4+q2OzdIULd0i+uvaPH4EieAuOXhxI6O43PX1JmHw0RMzzfnhMKL4oosYS3TLw+x3ofzYAZqkn9cdUdq3rBcfJnHF5zmF/UONYxPHs/DSfnLcOq+pl8cCpoUsEfH+H/8NY3cuTuAVYXJXflJRitPfUFc80LI2N9/f0LspV5j9AY/yjofUI3oGk2mcmhdUrpUXv2i/fNii6BejdkqtVOIqnLggGVG1RwIGw5+vqrEnuo/3HprhJv5eMNdcCSOIYc= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:SJ0PR13MB5545.namprd13.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(366004)(346002)(136003)(39830400003)(396003)(376002)(230922051799003)(1800799009)(451199024)(64100799003)(186009)(66946007)(6916009)(8676002)(44832011)(316002)(4326008)(66476007)(66556008)(38100700002)(38350700002)(86362001)(6486002)(478600001)(41300700001)(2906002)(5660300002)(8936002)(6512007)(2616005)(52116002)(107886003)(1076003)(26005)(36756003)(6666004)(83380400001)(6506007); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: rb2RK1wFKCHM+Mrj1xQlwN78cPHfh+lRnkySXh1zAPByAJDsq+yDyzMpZjBqbdj2e1oV958VeKWeGw+v7H17H50VAx36uMRu0EiQzTkCJWWklfLhwPEmUCGRy//QNjJRjU+4nZbJg/NVQSDy5Rp5YH4aGXUwSIme71Yhnf9f5iE6pj2F+fmgu4td2912bsWImWEINPZVl+CSIu6xbfdIkKbaBYPUzzL8+lixTRFVZWgjS3yHzZHU8w/EfnYLiez/SckxiDARxFz4/09ZoGAu3IRWWSCnDOcN0ZCa7Lp5tSUHadhSxT2724M2Yo8B7YJqPCtJZ2mYOM2OBhCKH6vi2GzreJplEks/gL/u2NzEiOeRIQc3cnz6g2WUDcviZemYfuCcrbGZi2qmB4yYwnoXzSrMZQsEzzR1U82qauGPW0+sEGxwjQhOiIvjM8GrHm2AsS/Wb47qsfjaHa6dOXeH7V/qdx5F4e2dsC6U4LCPfNQ5nWvocfqEt16qIR6EvpBJGJeGrGYv+Jf8rGh3hrY/BKa7Flt+rb/NyHKuzbrc54+l5K6FouaVATh1RL1WeDIKrbN49vYS7OAYoLsZ6zQlVXbIjDyPqeQAgS0GmZwXrninN9RRlXNUIPOMRKZsXnZSEplUbwPl6b7DsFih2DAszJiKHmqtwQpNbYJTZ3s6oyQAqLJOUKCK4dzkCt7jYTpEU5+II7usVn6SixDbsi8p4X9zgkOKIorfrMbX9Rq4Bjz117yfIyA3S0O5ASJLxHpoJuTXXvUVTuq+aXT0dNv9qCPB05b4XAZ6jxPWZA+HEwDnwIrgmppnN64iiT3gAyVzYUY/cqtYXTGOfadDTPtJl3Hbi0pNM9utN5dg8OqsHP5FDzo1GI/N2ImiY6/q/bCImUYlDjHmF5vm718KmEtpqCPJ2SI9QCu5LxUD9fo5rZSDs8fc2iyriIGXavpdbBbipBdyG7zY4mAGjuzIwi0kon0megBMC0Qaors2iCt9R5ktGKwU8WrTxtjymu60vGwrU0+f1EBfVNERwzLATD8kpoVy67hL6BS6e84UUWWh5HE6pvvznNE1OyhCBNQNswGS9RClVTi+lZtNztaD/Za0TG0BVKif6kId3PVh5kOX6CVxTC8s79xQZcVF4UI/51T7bZFmKI6PdSUebIDzwEmCPIkQX4i5a3YdWQgTk9EvdwHpiV2PO4I8zITk1mHhjzMUwSCWN8OAgeB0tTKyktwLLAmETMQIm9L+PGgBr4F2S1t3NgYjEFMBcTgOe+/r7f90exajMyLKKz4LcFzUTXPA4fyDRJOvPAWfzc8eg3pOvBPUk6o6/yCZwY9c/x7m7z1zDcmeVoL8st7dKAiwFdpmSc8Kic7pZF64OaO/n1fFCq5bwb0OTQlunM8gdjpiIVtV1JBGItA+ddo5bzJvWArP2CKxx4GSAgRIPldh6JpPr7cseVrKgCz1fYhvJ8H1znNRCtR+9ubdMAwf0Rb32Ftz756gMiVY3PTqFpgug1sN7XJBkZ93GqizdRU94iOt6vph/tNKweop2x9N52o5X6SAWXCtgYYvbp4fRUPffBaCoBLfYOEbTLMoJo0XRIzQzgiUvLal4MpxI/UssPi3dm3o/Q== X-OriginatorOrg: corigine.com X-MS-Exchange-CrossTenant-Network-Message-Id: b734fbdf-6087-4e7c-433d-08dbc19c402c X-MS-Exchange-CrossTenant-AuthSource: SJ0PR13MB5545.namprd13.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Sep 2023 10:01:44.1785 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: fe128f2c-073b-4c20-818e-7246a585940c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: L7Da4YBK+ixpqDQyvFEtzvXPsb42kLpQL+oj1JDjeSwQPi4PUkhngIrKBYQa7lKFxRqYUXJ4y9T5bKstVxYAGFhu2O1kx96H9o1X5S64+uM= X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR13MB5429 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add the offload call to add and delete the flows to the firmware. Signed-off-by: Chaoyong He --- drivers/net/nfp/flower/nfp_conntrack.c | 112 ++++++++++++++++++++++++- drivers/net/nfp/flower/nfp_conntrack.h | 5 ++ drivers/net/nfp/nfp_flow.c | 8 ++ 3 files changed, 122 insertions(+), 3 deletions(-) diff --git a/drivers/net/nfp/flower/nfp_conntrack.c b/drivers/net/nfp/flower/nfp_conntrack.c index 24762de133..d81e2970fb 100644 --- a/drivers/net/nfp/flower/nfp_conntrack.c +++ b/drivers/net/nfp/flower/nfp_conntrack.c @@ -9,8 +9,8 @@ #include #include -#include "../nfp_flow.h" #include "../nfp_logs.h" +#include "nfp_flower_cmsg.h" #include "nfp_flower_representor.h" struct ct_data { @@ -59,6 +59,7 @@ struct nfp_ct_merge_entry { LIST_ENTRY(nfp_ct_merge_entry) pre_ct_list; LIST_ENTRY(nfp_ct_merge_entry) post_ct_list; struct nfp_initial_flow rule; + struct rte_flow *compiled_rule; struct nfp_ct_zone_entry *ze; struct nfp_ct_flow_entry *pre_ct_parent; struct nfp_ct_flow_entry *post_ct_parent; @@ -984,6 +985,102 @@ nfp_ct_zone_entry_free(struct nfp_ct_zone_entry *ze, } } +static int +nfp_ct_offload_add(struct nfp_flower_representor *repr, + struct nfp_ct_merge_entry *merge_entry) +{ + int ret; + uint64_t cookie; + struct rte_flow *nfp_flow; + struct nfp_flow_priv *priv; + const struct rte_flow_item *items; + const struct rte_flow_action *actions; + + cookie = rte_rand(); + items = merge_entry->rule.items; + actions = merge_entry->rule.actions; + nfp_flow = nfp_flow_process(repr, items, actions, false, cookie, true); + if (nfp_flow == NULL) { + PMD_DRV_LOG(ERR, "Process the merged flow rule failed."); + return -EINVAL; + } + + /* Add the flow to hardware */ + priv = repr->app_fw_flower->flow_priv; + ret = nfp_flower_cmsg_flow_add(repr->app_fw_flower, nfp_flow); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Add the merged flow to firmware failed."); + goto flow_teardown; + } + + /* Add the flow to flow hash table */ + ret = nfp_flow_table_add(priv, nfp_flow); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Add the merged flow to flow table failed."); + goto flow_teardown; + } + + merge_entry->compiled_rule = nfp_flow; + + return 0; + +flow_teardown: + nfp_flow_teardown(priv, nfp_flow, false); + nfp_flow_free(nfp_flow); + + return ret; +} + +int +nfp_ct_offload_del(struct rte_eth_dev *dev, + struct nfp_ct_map_entry *me, + struct rte_flow_error *error) +{ + int ret; + struct nfp_ct_flow_entry *fe; + struct nfp_ct_merge_entry *m_ent; + + fe = me->fe; + + if (fe->type == CT_TYPE_PRE_CT) { + LIST_FOREACH(m_ent, &fe->children, pre_ct_list) { + if (m_ent->compiled_rule != NULL) { + ret = nfp_flow_destroy(dev, m_ent->compiled_rule, error); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Could not alloc ct_flow_item"); + return -EINVAL; + } + m_ent->compiled_rule = NULL; + } + + m_ent->pre_ct_parent = NULL; + LIST_REMOVE(m_ent, pre_ct_list); + if (m_ent->post_ct_parent == NULL) + nfp_ct_merge_entry_destroy(m_ent); + } + } else { + LIST_FOREACH(m_ent, &fe->children, post_ct_list) { + if (m_ent->compiled_rule != NULL) { + ret = nfp_flow_destroy(dev, m_ent->compiled_rule, error); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Could not alloc ct_flow_item"); + return -EINVAL; + } + m_ent->compiled_rule = NULL; + } + + m_ent->post_ct_parent = NULL; + LIST_REMOVE(m_ent, post_ct_list); + if (m_ent->pre_ct_parent == NULL) + nfp_ct_merge_entry_destroy(m_ent); + } + } + + nfp_ct_flow_entry_destroy_partly(fe); + + return 0; +} + static inline bool is_item_check_pass(const struct rte_flow_item *item1, const struct rte_flow_item *item2, @@ -1411,8 +1508,17 @@ nfp_ct_do_flow_merge(struct nfp_ct_zone_entry *ze, goto free_actions; } + /* Send to firmware */ + ret = nfp_ct_offload_add(pre_ct_entry->repr, merge_entry); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Send the merged flow to firmware failed"); + goto merge_table_del; + } + return true; +merge_table_del: + nfp_ct_merge_table_delete(ze, merge_entry); free_actions: rte_free(merge_entry->rule.actions); free_items: @@ -1499,7 +1605,7 @@ nfp_flow_handle_pre_ct(const struct rte_flow_item *ct_item, } } - /* The real offload logic comes in next commit, so here just return false for now */ + return true; ct_flow_entry_free: nfp_ct_flow_entry_destroy(fe); @@ -1568,7 +1674,7 @@ nfp_flow_handle_post_ct(const struct rte_flow_item *ct_item, if (!ret) goto ct_flow_entry_free; - /* The real offload logic comes in next commit, so here just return false for now */ + return true; ct_flow_entry_free: nfp_ct_flow_entry_destroy(fe); diff --git a/drivers/net/nfp/flower/nfp_conntrack.h b/drivers/net/nfp/flower/nfp_conntrack.h index 149a3eb040..2f47280716 100644 --- a/drivers/net/nfp/flower/nfp_conntrack.h +++ b/drivers/net/nfp/flower/nfp_conntrack.h @@ -8,6 +8,7 @@ #include +#include #include #include "../nfp_flow.h" @@ -22,6 +23,10 @@ struct nfp_ct_map_entry *nfp_ct_map_table_search(struct nfp_flow_priv *priv, char *hash_data, uint32_t hash_len); +int nfp_ct_offload_del(struct rte_eth_dev *dev, + struct nfp_ct_map_entry *me, + struct rte_flow_error *error); + struct rte_flow *nfp_ct_flow_setup(struct nfp_flower_representor *representor, const struct rte_flow_item items[], const struct rte_flow_action actions[], diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c index 16a5c7e055..a6439679d3 100644 --- a/drivers/net/nfp/nfp_flow.c +++ b/drivers/net/nfp/nfp_flow.c @@ -3911,8 +3911,10 @@ nfp_flow_destroy(struct rte_eth_dev *dev, struct rte_flow_error *error) { int ret; + uint64_t cookie; struct rte_flow *flow_find; struct nfp_flow_priv *priv; + struct nfp_ct_map_entry *me; struct nfp_app_fw_flower *app_fw_flower; struct nfp_flower_representor *representor; @@ -3920,6 +3922,12 @@ nfp_flow_destroy(struct rte_eth_dev *dev, app_fw_flower = representor->app_fw_flower; priv = app_fw_flower->flow_priv; + /* Find the flow in ct_map_table */ + cookie = rte_be_to_cpu_64(nfp_flow->payload.meta->host_cookie); + me = nfp_ct_map_table_search(priv, (char *)&cookie, sizeof(uint64_t)); + if (me != NULL) + return nfp_ct_offload_del(dev, me, error); + /* Find the flow in flow hash table */ flow_find = nfp_flow_table_search(priv, nfp_flow); if (flow_find == NULL) { From patchwork Sat Sep 30 10:00:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chaoyong He X-Patchwork-Id: 132253 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 16CE042682; Sat, 30 Sep 2023 12:02:18 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 28CD9402E6; Sat, 30 Sep 2023 12:01:51 +0200 (CEST) Received: from NAM02-DM3-obe.outbound.protection.outlook.com (mail-dm3nam02on2098.outbound.protection.outlook.com [40.107.95.98]) by mails.dpdk.org (Postfix) with ESMTP id 7E960402D4 for ; Sat, 30 Sep 2023 12:01:47 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=R6ZrjQt07vJoti/YRFz/zU6vz30VHqd44n+uwmeVdd/cpBaigjpcne3dESwVtDj9/TKWfxOhFrBfZrDUiW2OY6DA4Br1t8SFT0DFFLfLtql+pXWt7cuyClwLfVuJ2Oz5OrdHj967g/s5aOTrQ57qWoJEfRjyMajMJU/97hLaWPV3Bo/HaHuEhAhwULnYpgKCRR7e5zky01gL2lk0IHSTtP0l2NqTtLD6ieNzrJF6E2neBHQjg1MlbI5eQmIIfzSXYaGWTkqulJKK4C4N2G4tDEQ1RooD/E8vOT6AioirWmjdc7wioXM2sfLSAOpk5KoA5G5jZmmFzOCdnxCoD5Ahzg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=frXfWlVZkhGDsd4v6Wl0/94gs1hhmI8UqdmQEuGMtlk=; b=cgu8utM/3L1uU2O3garWLnWYOwsib0DNWHowgEbf3VsvQ4kAdzWEsb5duJnaZxDC/EtdvZkFJ9gDhN/BsoTyDYy9lM7v+LFlSEWHZkPSNrke83pquWJI3ozjhilGCH2p6euKsH4ymgnZh35PI/2xsIgkYNaLJc/nBnQUNlHeb0o+FtzT0Dg/dQ5B+qfPF0m9cZEx95EgVJ2YG8Oax84paKmRqJvHZDzTxmUIAyjAq/t534lJwvEjU7RH0D+/eV3JNcdsoU1VIOXzqbqjS9k2bIngBkCnN0Vv6ocg7TzMFUVxsjRYsy7JrYCxovoMW8RDdyFt8qOtyrfCIv1kkopMKw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=corigine.com; dmarc=pass action=none header.from=corigine.com; dkim=pass header.d=corigine.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=corigine.onmicrosoft.com; s=selector2-corigine-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=frXfWlVZkhGDsd4v6Wl0/94gs1hhmI8UqdmQEuGMtlk=; b=GdCy2TARIauCgbQhHnnhlBgiyFV69XoJPPBDmB1d7rSb0nj7pEeyp9EmrvcwynFH5RMzYzPHuBjVlNQ0iUnQqGWpnm3r2KRjXV6KtiB8fa5a4JsorlMX8TQFuiJfsc4T2u1CaPIdRymv24UJYzLNwjk0gK6B65jB137KWtuuOvE= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=corigine.com; Received: from SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5) by PH7PR13MB5429.namprd13.prod.outlook.com (2603:10b6:510:138::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6813.21; Sat, 30 Sep 2023 10:01:45 +0000 Received: from SJ0PR13MB5545.namprd13.prod.outlook.com ([fe80::28c0:63e2:ecd1:9314]) by SJ0PR13MB5545.namprd13.prod.outlook.com ([fe80::28c0:63e2:ecd1:9314%4]) with mapi id 15.20.6813.027; Sat, 30 Sep 2023 10:01:45 +0000 From: Chaoyong He To: dev@dpdk.org Cc: oss-drivers@corigine.com, Chaoyong He Subject: [PATCH 4/4] net/nfp: add support for merged flows and conntrack stats Date: Sat, 30 Sep 2023 18:00:53 +0800 Message-Id: <20230930100053.1227215-5-chaoyong.he@corigine.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230930100053.1227215-1-chaoyong.he@corigine.com> References: <20230930100053.1227215-1-chaoyong.he@corigine.com> X-ClientProxiedBy: PH8PR22CA0022.namprd22.prod.outlook.com (2603:10b6:510:2d1::17) To SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ0PR13MB5545:EE_|PH7PR13MB5429:EE_ X-MS-Office365-Filtering-Correlation-Id: 7891d467-8a02-4484-2b6d-08dbc19c4124 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Tcuoh107SlV7G4Tl7SaK10qPWlTF8l+EJDGpelrX21vVNpsCvuzydytaJqnnGDFqepLcHM7RyCmhTpGe33ROn410MbtONSRg1iyM+XeyTziHb25cSrISIiBkgaCuDkSyhFfmXgFRsOBAgp/KSmFxY9CF3stGaRcF/OHK7qkoKnlHBUWS5zI9Ar+VyGGXnpstOwLf54OvURuAZ3SoO1p/92HA18j5paSIom5JUiGnu5lRSGgaXwEZ+gg8sgWZOs/cvrlbank+8amAhlAJabbPjPiTCersOC2ol1Z9oIxdmXXYJB1NFnTUaqODxdxNlwfewsnC9PAgJNlVx6kVNZRXlAqv953wxurIJFEQ8RVcZ408pgjer9my1CdLyy+Xz3Og1OmUwQsD4/wfOgum5N/+4GxTfoH+eHXrO3ej01kVJU1YJar8kWR8O8Sjram4PKAJU72Aci7DD7HoolHJtpFDkacbtdolYymAHPp7ozIrXuAgFUbR8sVtQUkQECI3sEl2E0HjwYI4zjbYUkQRCGrppkS1uneSRl6CNyO8+4vuumb9Ax2sYw3i9YsWxYUGCmLI0JH/s5cF4t6vJnBQ+PM9OSqH1zuHy7eZ6jB6rBQiqZIruYL5+rPNIZqgBUzCypaRAkqItaNSbkO+kAI4jezPQddV2tyfjkscchR8A+IQwh4= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:SJ0PR13MB5545.namprd13.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(366004)(346002)(136003)(39830400003)(396003)(376002)(230922051799003)(1800799009)(451199024)(64100799003)(186009)(66946007)(6916009)(8676002)(44832011)(316002)(4326008)(66476007)(66556008)(38100700002)(38350700002)(86362001)(6486002)(478600001)(30864003)(41300700001)(2906002)(5660300002)(8936002)(6512007)(2616005)(52116002)(107886003)(1076003)(26005)(36756003)(6666004)(83380400001)(6506007); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: ywZR8ejwKbwZ8zb7gs77uVrX+8O/yhyXuLeA2D6nHS6OjBSjBoN0wf7Y4YrGijt/S2gX9XR+4oUGLErtI13ahJ6q13GsX8dM7m8Hfs9aMSXVvTjP8d488/tJRpyWmzNNiRQ6Hq1DtsxdV9YdguNhQjSyHhtG2BptIzFTgJQU7joGyexh2F9y66RhgtO4g8QVpQLA8TBroqmWRElJ1SwAyyGN23ndeRsn8OzYfndnjN7tgonVPdPDMTWVGnM1G3krBgzJWpXUc3GhvFhu9v2jibLYZ98QGMw5YCL7CrId1hWmfUJ1lujR2RzhgF7KCfoKVZgc5D9xmNEmkLUrV7F9xUCzvcV87RyADvTOWK9emOOCSbrR+dIu2YWlAu7PFKjsi1lelj5qp7p5bUhmaJzmW2QKUeoIyp+p0pOPuY7gWpC9P6781e14n9WUb1w4SNw80gXhWA56Gu3xxi9Ld8vZanG0EUtMVV8hjI2yM7ocah2I1QDAFiyGdT02JW0+TRqu83MFczj2FY3/ErpwbGkYxvIc5Raq4LvAgHTlSG7LcgV/qmm1F6OXKUAV5aaw1kJJQK3gJ6PXZ+vF1BRnaNSbNXPMNSLM2avGOSXMYR7HtziBamzNH9QGtTtkSp05sIFdQ2QEYVuya890HsFUromAjXw5o99HSHUmsV3vonq5EAL+QhwF0PVdKLT0V9bF9pNfIemg8LMAoTS6PNe433oZ+IhqTc1ExSxRE+FLdhinLjm0WXBLIIcipKjB85WnmnVnZAIkf/u1zuq7K9D0surBombnCfOOGiCgYO30GKvhvEqvwn2HG8ZZQcfKD3URl/qbEfPj/HzaOSvDSyuZzSh13HBENVgvKVDnYE8NwZZ//eN8fXzXppAnKQvn7ddJWjXbOA3nINhFDcgzW2uXFHMSZt/W4ski8noALQ7FInNiSDsdlqq9HartzdXiEFamwLEeOy6A9HEPZkQ62nKo0PJYvgbASEStw5X1ZR/Puvs8O2kq/GC6J29cpbmNTRAw6vWLWzN8Hpo9MzHA9JfHXy2x7YLNS9Wzm31MJexiDL8OXunkVV38/9yMsEa4zyhyqOhAkO4/Ama7MPhS8gJ0+vu55/wKSObfkeAxSnhAcQuwEoyerYdhFV+TQ2GoVh3PW0t0ET23GLR2sNBIxhiPCxetO5FaOAFikk8kfUmqVrKZyhKrpRl963Mg0sSW+cx3oU40gZxu7U9/mmcaHkeJUjhGOkaCCwqEFebKYe/Ry8rXY4PrDRhkypHJVjoSwIGVgwPbB2svqxhEsVsQXFH1Yp1gtqP5tv2vPQ6p1MimUMwd9mPId6rKJvDAF1ZCJ1FofhNG3USPhZXMVnbuVCHBIFbuAENBFtAGMBHFNBKtzYn5GkruZrkcwwT0DVPP3El6mZf+WcTrxVnxZPxVp/AGqsVAtPA3IvnH+UlRYFNhARWTv65TCVnkBvM41YJosECsoSy5Zriwhic7t1YkQ9oLrcMjYxRFBEVG2QbLcQQuYFX8gUnTbhJtE4gEd9UNQs1Leuwtkr3WHrsKmQWSDWlKqW/aFbyfcZ174MwCCFAi08CT8mqPdfYdYeuxsi7kxfvihQyVUGPLlJFlN3iQk+LaxOQ+cQ== X-OriginatorOrg: corigine.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7891d467-8a02-4484-2b6d-08dbc19c4124 X-MS-Exchange-CrossTenant-AuthSource: SJ0PR13MB5545.namprd13.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Sep 2023 10:01:45.8055 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: fe128f2c-073b-4c20-818e-7246a585940c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: csz0/xqHWDsTuche9xuReT61FFKuzU+gVAqFuG5of12SWiaQvHiHHKrWzdNdQiRvuhyvZXhPR4jdyIglGDbHK4mfV3u0trA/ftHyVhLOtH0= X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR13MB5429 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Adjust the original logic to make it valid for both normal flow and merged flow. Add the logic to update ct flow stats. Add the support of conntrack action. Signed-off-by: Chaoyong He --- drivers/net/nfp/flower/nfp_conntrack.c | 54 ++++++++++++++++-- drivers/net/nfp/flower/nfp_conntrack.h | 3 + drivers/net/nfp/nfp_flow.c | 79 ++++++++++++++++++++++---- drivers/net/nfp/nfp_flow.h | 7 ++- 4 files changed, 126 insertions(+), 17 deletions(-) diff --git a/drivers/net/nfp/flower/nfp_conntrack.c b/drivers/net/nfp/flower/nfp_conntrack.c index d81e2970fb..3df2411ce4 100644 --- a/drivers/net/nfp/flower/nfp_conntrack.c +++ b/drivers/net/nfp/flower/nfp_conntrack.c @@ -39,6 +39,7 @@ struct nfp_ct_flow_entry { struct nfp_flower_representor *repr; struct nfp_ct_zone_entry *ze; struct nfp_initial_flow rule; + struct nfp_fl_stats stats; }; struct nfp_ct_map_entry { @@ -56,6 +57,7 @@ struct nfp_ct_zone_entry { struct nfp_ct_merge_entry { uint64_t cookie[2]; + uint32_t ctx_id; LIST_ENTRY(nfp_ct_merge_entry) pre_ct_list; LIST_ENTRY(nfp_ct_merge_entry) post_ct_list; struct nfp_initial_flow rule; @@ -999,12 +1001,14 @@ nfp_ct_offload_add(struct nfp_flower_representor *repr, cookie = rte_rand(); items = merge_entry->rule.items; actions = merge_entry->rule.actions; - nfp_flow = nfp_flow_process(repr, items, actions, false, cookie, true); + nfp_flow = nfp_flow_process(repr, items, actions, false, cookie, true, true); if (nfp_flow == NULL) { PMD_DRV_LOG(ERR, "Process the merged flow rule failed."); return -EINVAL; } + merge_entry->ctx_id = rte_be_to_cpu_32(nfp_flow->payload.meta->host_ctx_id); + /* Add the flow to hardware */ priv = repr->app_fw_flower->flow_priv; ret = nfp_flower_cmsg_flow_add(repr->app_fw_flower, nfp_flow); @@ -1014,7 +1018,7 @@ nfp_ct_offload_add(struct nfp_flower_representor *repr, } /* Add the flow to flow hash table */ - ret = nfp_flow_table_add(priv, nfp_flow); + ret = nfp_flow_table_add_merge(priv, nfp_flow); if (ret != 0) { PMD_DRV_LOG(ERR, "Add the merged flow to flow table failed."); goto flow_teardown; @@ -1702,14 +1706,14 @@ nfp_ct_flow_setup(struct nfp_flower_representor *representor, if (is_ct_commit_flow(ct)) { return nfp_flow_process(representor, &items[1], actions, - validate_flag, cookie, false); + validate_flag, cookie, false, false); } if (is_post_ct_flow(ct)) { if (nfp_flow_handle_post_ct(ct_item, representor, &items[1], actions, cookie)) { return nfp_flow_process(representor, &items[1], actions, - validate_flag, cookie, false); + validate_flag, cookie, false, false); } PMD_DRV_LOG(ERR, "Handle nfp post ct flow failed."); @@ -1720,7 +1724,7 @@ nfp_ct_flow_setup(struct nfp_flower_representor *representor, if (nfp_flow_handle_pre_ct(ct_item, representor, &items[1], actions, cookie)) { return nfp_flow_process(representor, &items[1], actions, - validate_flag, cookie, false); + validate_flag, cookie, false, false); } PMD_DRV_LOG(ERR, "Handle nfp pre ct flow failed."); @@ -1730,3 +1734,43 @@ nfp_ct_flow_setup(struct nfp_flower_representor *representor, PMD_DRV_LOG(ERR, "Unsupported ct flow type."); return NULL; } + +static inline void +nfp_ct_flow_stats_update(struct nfp_flow_priv *priv, + struct nfp_ct_merge_entry *m_ent) +{ + uint32_t ctx_id; + struct nfp_fl_stats *merge_stats; + + ctx_id = m_ent->ctx_id; + merge_stats = &priv->stats[ctx_id]; + + m_ent->pre_ct_parent->stats.bytes += merge_stats->bytes; + m_ent->pre_ct_parent->stats.pkts += merge_stats->pkts; + m_ent->post_ct_parent->stats.bytes += merge_stats->bytes; + m_ent->post_ct_parent->stats.pkts += merge_stats->pkts; + + merge_stats->bytes = 0; + merge_stats->pkts = 0; +} + +struct nfp_fl_stats * +nfp_ct_flow_stats_get(struct nfp_flow_priv *priv, + struct nfp_ct_map_entry *me) +{ + struct nfp_ct_merge_entry *m_ent; + + rte_spinlock_lock(&priv->stats_lock); + + if (me->fe->type == CT_TYPE_PRE_CT) { + LIST_FOREACH(m_ent, &me->fe->children, pre_ct_list) + nfp_ct_flow_stats_update(priv, m_ent); + } else { + LIST_FOREACH(m_ent, &me->fe->children, post_ct_list) + nfp_ct_flow_stats_update(priv, m_ent); + } + + rte_spinlock_unlock(&priv->stats_lock); + + return &me->fe->stats; +} diff --git a/drivers/net/nfp/flower/nfp_conntrack.h b/drivers/net/nfp/flower/nfp_conntrack.h index 2f47280716..5abab4e984 100644 --- a/drivers/net/nfp/flower/nfp_conntrack.h +++ b/drivers/net/nfp/flower/nfp_conntrack.h @@ -34,4 +34,7 @@ struct rte_flow *nfp_ct_flow_setup(struct nfp_flower_representor *representor, bool validate_flag, uint64_t cookie); +struct nfp_fl_stats *nfp_ct_flow_stats_get(struct nfp_flow_priv *priv, + struct nfp_ct_map_entry *me); + #endif /* __NFP_CONNTRACK_H__ */ diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c index a6439679d3..020e31e9de 100644 --- a/drivers/net/nfp/nfp_flow.c +++ b/drivers/net/nfp/nfp_flow.c @@ -310,14 +310,14 @@ nfp_check_mask_add(struct nfp_flow_priv *priv, ret = nfp_mask_table_add(priv, mask_data, mask_len, mask_id); if (ret != 0) return false; - - *meta_flags |= NFP_FL_META_FLAG_MANAGE_MASK; } else { /* mask entry already exist */ mask_entry->ref_cnt++; *mask_id = mask_entry->mask_id; } + *meta_flags |= NFP_FL_META_FLAG_MANAGE_MASK; + return true; } @@ -349,7 +349,7 @@ nfp_check_mask_remove(struct nfp_flow_priv *priv, return true; } -int +static int nfp_flow_table_add(struct nfp_flow_priv *priv, struct rte_flow *nfp_flow) { @@ -396,6 +396,48 @@ nfp_flow_table_search(struct nfp_flow_priv *priv, return flow_find; } +int +nfp_flow_table_add_merge(struct nfp_flow_priv *priv, + struct rte_flow *nfp_flow) +{ + struct rte_flow *flow_find; + + flow_find = nfp_flow_table_search(priv, nfp_flow); + if (flow_find != NULL) { + if (nfp_flow->merge_flag || flow_find->merge_flag) { + flow_find->merge_flag = true; + flow_find->ref_cnt++; + return 0; + } + + PMD_DRV_LOG(ERR, "Add to flow table failed."); + return -EINVAL; + } + + return nfp_flow_table_add(priv, nfp_flow); +} + +static int +nfp_flow_table_delete_merge(struct nfp_flow_priv *priv, + struct rte_flow *nfp_flow) +{ + struct rte_flow *flow_find; + + flow_find = nfp_flow_table_search(priv, nfp_flow); + if (flow_find == NULL) { + PMD_DRV_LOG(ERR, "Can't delete a non-existing flow."); + return -EINVAL; + } + + if (nfp_flow->merge_flag || flow_find->merge_flag) { + flow_find->ref_cnt--; + if (flow_find->ref_cnt > 0) + return 0; + } + + return nfp_flow_table_delete(priv, nfp_flow); +} + static struct rte_flow * nfp_flow_alloc(struct nfp_fl_key_ls *key_layer, uint32_t port_id) { @@ -1082,6 +1124,9 @@ nfp_flow_key_layers_calculate_actions(const struct rte_flow_action actions[], return -ENOTSUP; } break; + case RTE_FLOW_ACTION_TYPE_CONNTRACK: + PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_CONNTRACK detected"); + break; default: PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type); return -ENOTSUP; @@ -3626,6 +3671,9 @@ nfp_flow_compile_action(struct nfp_flower_representor *representor, return -EINVAL; position += sizeof(struct nfp_fl_act_meter); break; + case RTE_FLOW_ACTION_TYPE_CONNTRACK: + PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_CONNTRACK"); + break; default: PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type); return -ENOTSUP; @@ -3647,7 +3695,8 @@ nfp_flow_process(struct nfp_flower_representor *representor, const struct rte_flow_action actions[], bool validate_flag, uint64_t cookie, - bool install_flag) + bool install_flag, + bool merge_flag) { int ret; char *hash_data; @@ -3684,6 +3733,7 @@ nfp_flow_process(struct nfp_flower_representor *representor, } nfp_flow->install_flag = install_flag; + nfp_flow->merge_flag = merge_flag; nfp_flow_compile_metadata(priv, nfp_flow, &key_layer, stats_ctx, cookie); @@ -3717,7 +3767,7 @@ nfp_flow_process(struct nfp_flower_representor *representor, /* Find the flow in hash table */ flow_find = nfp_flow_table_search(priv, nfp_flow); - if (flow_find != NULL) { + if (flow_find != NULL && !nfp_flow->merge_flag && !flow_find->merge_flag) { PMD_DRV_LOG(ERR, "This flow is already exist."); if (!nfp_check_mask_remove(priv, mask_data, mask_len, &nfp_flow_meta->flags)) { @@ -3774,7 +3824,7 @@ nfp_flow_setup(struct nfp_flower_representor *representor, return nfp_ct_flow_setup(representor, items, actions, ct_item, validate_flag, cookie); - return nfp_flow_process(representor, items, actions, validate_flag, cookie, true); + return nfp_flow_process(representor, items, actions, validate_flag, cookie, true, false); } int @@ -3877,7 +3927,7 @@ nfp_flow_create(struct rte_eth_dev *dev, } /* Add the flow to flow hash table */ - ret = nfp_flow_table_add(priv, nfp_flow); + ret = nfp_flow_table_add_merge(priv, nfp_flow); if (ret != 0) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "Add flow to the flow table failed."); @@ -3988,7 +4038,7 @@ nfp_flow_destroy(struct rte_eth_dev *dev, } /* Delete the flow from flow hash table */ - ret = nfp_flow_table_delete(priv, nfp_flow); + ret = nfp_flow_table_delete_merge(priv, nfp_flow); if (ret != 0) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "Delete flow from the flow table failed."); @@ -4047,10 +4097,12 @@ nfp_flow_stats_get(struct rte_eth_dev *dev, void *data) { bool reset; + uint64_t cookie; uint32_t ctx_id; struct rte_flow *flow; struct nfp_flow_priv *priv; struct nfp_fl_stats *stats; + struct nfp_ct_map_entry *me; struct rte_flow_query_count *query; priv = nfp_flow_dev_to_priv(dev); @@ -4064,8 +4116,15 @@ nfp_flow_stats_get(struct rte_eth_dev *dev, reset = query->reset; memset(query, 0, sizeof(*query)); - ctx_id = rte_be_to_cpu_32(nfp_flow->payload.meta->host_ctx_id); - stats = &priv->stats[ctx_id]; + /* Find the flow in ct_map_table */ + cookie = rte_be_to_cpu_64(nfp_flow->payload.meta->host_cookie); + me = nfp_ct_map_table_search(priv, (char *)&cookie, sizeof(uint64_t)); + if (me != NULL) { + stats = nfp_ct_flow_stats_get(priv, me); + } else { + ctx_id = rte_be_to_cpu_32(nfp_flow->payload.meta->host_ctx_id); + stats = &priv->stats[ctx_id]; + } rte_spinlock_lock(&priv->stats_lock); if (stats->pkts != 0 && stats->bytes != 0) { diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h index df16cab8b5..ed06eca371 100644 --- a/drivers/net/nfp/nfp_flow.h +++ b/drivers/net/nfp/nfp_flow.h @@ -165,7 +165,9 @@ struct rte_flow { uint32_t port_id; bool install_flag; bool tcp_flag; /**< Used in the SET_TP_* action */ + bool merge_flag; enum nfp_flow_type type; + uint16_t ref_cnt; }; /* Forward declaration */ @@ -181,8 +183,9 @@ struct rte_flow *nfp_flow_process(struct nfp_flower_representor *representor, const struct rte_flow_action actions[], bool validate_flag, uint64_t cookie, - bool install_flag); -int nfp_flow_table_add(struct nfp_flow_priv *priv, + bool install_flag, + bool merge_flag); +int nfp_flow_table_add_merge(struct nfp_flow_priv *priv, struct rte_flow *nfp_flow); int nfp_flow_teardown(struct nfp_flow_priv *priv, struct rte_flow *nfp_flow,