From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id BB30BA0560; Tue, 18 Oct 2022 05:23:04 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id A8DBB410E8; Tue, 18 Oct 2022 05:23:04 +0200 (CEST) Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11on2096.outbound.protection.outlook.com [40.107.223.96]) by mails.dpdk.org (Postfix) with ESMTP id 4C22F4021E for ; Tue, 18 Oct 2022 05:23:03 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=RArBzau5kF9z/8ZQTImoM8xrby4FT9+J76IjrhbV1UwLUuritabwu8dTKXNqdYIUrKbc0E2MwpnFYBwrDbuYODPm/8Pqvbq5N5j+kKHopL3LTcxWdzTwI5XqcU4/Bik4n0dRWmEw+C+uLEXhKd3WLWZNxkLNav1JTj2L0/30d7URYgnEX6YRifNJQNMndoqPvk6tEqifia+XdnqCaj+mtOE9ohRZQ2zuV12szuRvCn8pXDgj2V+kaCzfjqaTsR3kuPGOllASM0JzeZZPGnTPfLiMc/7IKDmuXmVYHbEssfBYw+XqnCYVNxt/eLmv3Ixj+uOSUaXySWSNvokJ3QDGrw== 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=J8r2eu8a0dxjQvAUfZ1XGdVcLRjBXgnB8L+CNoSGfVg=; b=WuYikm5cR6o4HXhd6Rftu7ABjuXDtSahdFlbCaEORXHsPQzsVTUy5Mtc6IkZNiV+XmBDBPmbrYghxwcLsSbbjWNvxucjE0V2NQdt4RK3rjRjlJeH8N3TnoKHXMeumY0l9lFEZyJz+CniwFJmwfmkHXCisxvX1foUCcv6ljvVIvbr1Mvb5ukzUYVJQEy2jQyhYDiNplZk8GyeFE1tj31x4K6+LxuT5esvs+r94t68nXLbxyT1+BOl7sNEFslfo2JVee5zPDVigRXYipWnnEAmmDDU1IsOIyl6XEIEpGJRsQyD88Om0mzapVUqtAhCycfZA9Xl9S4oxlRXLRGDMNptgw== 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=J8r2eu8a0dxjQvAUfZ1XGdVcLRjBXgnB8L+CNoSGfVg=; b=hyARB4FVDYeXC7IadhgtNKgLkZ4bvyeBf3/vNmxuUiWL661QHE02J7MEBZ8vr/ZDpSkykdLAtZlr6tN/9t+SsimdMDrbM5R6G8AjrsOteHIexlHGqGJT3J21Eckpi4sC01Ak8aWVKvmPSeZZUFA4t1mcn2zVie5XtlojIANKM5c= 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 MN2PR13MB4149.namprd13.prod.outlook.com (2603:10b6:208:24f::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5723.20; Tue, 18 Oct 2022 03:23:01 +0000 Received: from SJ0PR13MB5545.namprd13.prod.outlook.com ([fe80::7c26:1a0b:2825:6f4b]) by SJ0PR13MB5545.namprd13.prod.outlook.com ([fe80::7c26:1a0b:2825:6f4b%4]) with mapi id 15.20.5723.014; Tue, 18 Oct 2022 03:23:01 +0000 From: Chaoyong He To: dev@dpdk.org Cc: oss-drivers@corigine.com, niklas.soderlund@corigine.com, Chaoyong He Subject: [PATCH 01/25] net/nfp: add the offload support of IPv4 VXLAN item Date: Tue, 18 Oct 2022 11:22:15 +0800 Message-Id: <1666063359-34283-2-git-send-email-chaoyong.he@corigine.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1666063359-34283-1-git-send-email-chaoyong.he@corigine.com> References: <1666063359-34283-1-git-send-email-chaoyong.he@corigine.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-ClientProxiedBy: SG2PR01CA0184.apcprd01.prod.exchangelabs.com (2603:1096:4:189::9) To SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ0PR13MB5545:EE_|MN2PR13MB4149:EE_ X-MS-Office365-Filtering-Correlation-Id: bf69314a-3c7d-4fba-28c9-08dab0b80f8f X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: n3eD/e1lUKLmJjjm4TGpzU6eF9wJHRWMBpUIW66kYp0FT7Mv5g2shizKRXpMkWLcYsFieYamLfzt46Qpsv36vldpP1NaJL5r/ArYqEoAZLzfOAQfl2+eEMI4sqGIewefqvbU0rPQiogc9rPINjr3RLQWL1EDqCgNqYUZ7muNxWFyCuHnaVr8m3yoYHkzrUNgkS0F6J8Gy52X5OaSR5ZQFq5IcFByPQMOVJGrn3Y1H9Somwm+EO29ewzCM/lXb4/VC6LdB3SiRmjH5ICSM9at/SVrArG+JsmNqOGb9+RMggNe3rgP3pPPnWmnGXnutvGBjJkAa1QV3+caotzDFMEMdlv71/WvNuxV405Ci9XSL2Y47uiS1iKq7gWw9SWxoZ2z3yXBtJ0T2E8e0yyrA+tfTmwrxt7KCqOuJnkMQ0PedSy9zvZISAF+9MsYi3UGHt1UccjHO6aQlfe5HWaVuLQk56EmWSHEW2r8bjb4EVRvmz+go4grUJ1d7Pe+uQ46P3MLbvUh9fIzpV52V2OZiDVr3iqtkfXj76S8jNlhSBlyUbnjvlKFz2th45VhoDkT9uz8X0Zxe2FG4ZXVcAUwzrot5bRimLjUUapd3DOCdzriOI+sPByxawEOilb5+QRNiq2DMi5jKn6c1YOUTCjL8D819Vybd1sBFzvc/usnK/xdf4iNVjDox9RFnsbuon6TqJTrumgNMQdFaAZFBJhv2LBS7hE+V4BICviGY6xJoOeaZcGPOLbNLRurXi6DTdZycEgzBAfxi1Wq0dskH1pSGOCO3eiHZyQOTxJeTqbefaLdCR3A4WlEKYhk2YSgZoPhhYNO 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:(13230022)(4636009)(136003)(366004)(346002)(376002)(396003)(39840400004)(451199015)(38350700002)(86362001)(38100700002)(36756003)(83380400001)(66574015)(5660300002)(52116002)(30864003)(6506007)(2616005)(26005)(6512007)(186003)(6666004)(2906002)(6916009)(316002)(6486002)(107886003)(4326008)(66946007)(66556008)(478600001)(8936002)(44832011)(41300700001)(8676002)(66476007); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?SFBEQ0Fob1VydjBzbTJQSlRzdUdjVHRkL3pUMGlsbDNFaHNaeER5Qzk3ZFpU?= =?utf-8?B?dzV5ekczUWxSOHgzWFgyRWx2MEhPMnJBYmU4cHhJZk5La1J0VXZBMG9EWGgv?= =?utf-8?B?djBEbEZheSt2bUg0cXh0cmJ0YTFUeHRKejBCUVJSVGxNdzBYOGtkUjliUE9Z?= =?utf-8?B?d0p1TllQTGZHWVR2UmlMUXR2c0V3VnBsNTFqQVBtV3BHT001bVBYa0xGZFFh?= =?utf-8?B?Yzc2WFl1U1k3VCtGQmlBdVhGL2ZBT1B0c3g2eEd3cEg5aTl2bEdadXcyK0ZK?= =?utf-8?B?b1Z0emV6QVlReUphTVQ0OER6SlVBVGJtR3M0OUt5QUtJOTMyWGRQalIvUXMr?= =?utf-8?B?a3puRklGZE9CZVZkbTBUcGJyMnlVdEhXeHJxRWk0N2w2aFdBS1NtczZjaWMy?= =?utf-8?B?WjF2UVoycUJKc1lBbFVTUElKcFJ5UXZKNjlwR0dqNEJ0UVhHbTRINEwwTlBO?= =?utf-8?B?Qmd5ZUVIVWtJZjdEUXBVa0pkR05HQmVjVE1zVzdhTi9tTkQ0VGxOMll1V05Q?= =?utf-8?B?L1ZRR0laUGFjbEhmaTFnRnBRTlVneGNDS0tISjdDa2NMeXM2L24wZkYyNWMx?= =?utf-8?B?WXZVQndNTkY1bTRrUHlZUzdMaGwrc01oY2djeklRK1IxVWo1azVxQzVuL2l5?= =?utf-8?B?QUxIeUFUQUphMFQ3Z3ZUTTU0ckdlbHNOUGtQZXM2WWNKZHpCbHQzTmZoNjR2?= =?utf-8?B?UVFSbnNWaDU1WEdudXYrWDBoVnhiSjBFNXQ0SUlyVzNFckJQWTRLS2ZvWi85?= =?utf-8?B?anpmK016WDRtemh1YlNseGhzQUJ0QzVKTHdzTzhwOFAwVDdleEhuVHNFcU5u?= =?utf-8?B?ejFKbkJFN0NQeWEyY3ljQUU2dnRpZ001UUMvQUJnbTdMMVdOS3ZCRWdsWm5a?= =?utf-8?B?SkFSellZMnd6TmV2MlQzakdYenFtdm03RENaVVRwbmVxdjZONHJaa3hWMk00?= =?utf-8?B?ZUYyU0VCcVN6SDZDTVIzdFR3MG5LS0REbERZYVcyRnRBenFLeTJVZE0zLzBa?= =?utf-8?B?YlQ2eVhtYkhINWVWanlhZG5INlBPU2FsekRxYWY0dmU1RVMrZWpRaDlWWVdm?= =?utf-8?B?cVBjOXBhME54TEh6TlF4VVNCelhEV3Q1aVV5OGZQcnloSmNQaVlkb0RsWDZx?= =?utf-8?B?VHpLaWdNbXV0QjFOTWZnUkIrd2FqcWtuQU1uM2REUG1ZdUF5ZGlnT3RVUVB1?= =?utf-8?B?QmtVY1BOaUhPZWxvd1U2aThITitUM3VFRTdYcWgzbHJZTWlQNE85T1BkMVZi?= =?utf-8?B?K0pGbTF5NEFyWktnVEFTMk44MjQvM0VNK2tVakVtSzI4VnJtaW93REtZeWdI?= =?utf-8?B?THJvbE1qejFqQ0FIYVNOZUNGbDRQUFBmc3k1OTkveWY5ZVhOUnlzYWZHNUFu?= =?utf-8?B?M0RPeWFIOFpUc0tQTmN1OHZPS0UydjgxM1pqdWxGL1dmVVF1VlNaMTJtM0hn?= =?utf-8?B?VExHZnIwb01iS2RReDhHTzFjdWx4OTJXckp6Q2lvSks1Y3hsU01EQzhWdm1T?= =?utf-8?B?b0RlZ1h0TWdSNVhNQktuejBNazlnUElKSUcwa0JpYjJnR2Noci9HYTI3dnlr?= =?utf-8?B?VTlWbnYxV0xGTUp0NE1Bb20vZ1ZmOFFRMG04aG5YWGowZlFGZiswK2NIdHd6?= =?utf-8?B?L0oydFZMMFJ0L1djd2l5RnJ4Yi9yak1LeXFjbXFBakFabm1nS3VxMzFHMFNB?= =?utf-8?B?UFVSYnJGWDJ4ajBsdWdIQWpNNjlJbk1LL2pxVXpMcUlObDhmd2FPK3pFU2cr?= =?utf-8?B?NWlrR3NiL2tmdWJlck9KZ0xnUHJmSVRqUWY1emVVVWU1WThOcnJsU3JwSks3?= =?utf-8?B?Y0dibUhxQ2dlUExyN0hocElJeHY1Yk1pYVpBRS9iVVMwVTdEVzUvNFVpMWhr?= =?utf-8?B?V0F5VmxZeWVFeTZNbTBJd0s5a0p4RnhCRjVGR2JlcTVLMnAyTzVPRG4rMWFx?= =?utf-8?B?bHpnWS81U1BiNEhKZVdpQ1dyRGVrMWRsU0l1WGRhZ21xYWZWVGlUVVJLWjQx?= =?utf-8?B?TDU2d3BKeENZYVFGZW5PaU0xdmh3eW9Tb1ZTc3hqMm1VZVdsZWw2NzdGalRi?= =?utf-8?B?a3NFQmFvWTV3cklwbFhKOHpDZ29ZQUtxK0JneExVLzkycGdOUytuS0ZhQUFN?= =?utf-8?B?R0VJbWxHdnAzMC95bHZpNHovNUp2TER2RktacVFBU1lWNlRSSmh2VTFGMm9z?= =?utf-8?B?SkE9PQ==?= X-OriginatorOrg: corigine.com X-MS-Exchange-CrossTenant-Network-Message-Id: bf69314a-3c7d-4fba-28c9-08dab0b80f8f X-MS-Exchange-CrossTenant-AuthSource: SJ0PR13MB5545.namprd13.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Oct 2022 03:23:01.0982 (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: qJHDu/TqXeuj+k7nlzJtKwuWrC/g1OqwuptnXKT+K/YlcXEbyvDVkTYqXhrl3LBS6TxxPSM82avphOEeUr0IgHjdY46tZcuCGmQkBQ0JhQs= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR13MB4149 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 corresponding data structure and logics, to support the offload of IPv4 VXLAN item. Signed-off-by: Chaoyong He Reviewed-by: Niklas Söderlund --- doc/guides/nics/features/nfp.ini | 1 + drivers/net/nfp/flower/nfp_flower_cmsg.h | 35 +++++ drivers/net/nfp/nfp_flow.c | 243 ++++++++++++++++++++++++++----- 3 files changed, 246 insertions(+), 33 deletions(-) diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini index 1ad6c2c..40b9a4d 100644 --- a/doc/guides/nics/features/nfp.ini +++ b/doc/guides/nics/features/nfp.ini @@ -36,6 +36,7 @@ sctp = Y tcp = Y udp = Y vlan = Y +vxlan = Y [rte_flow actions] count = Y diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h index 6bf8ff7..08e2873 100644 --- a/drivers/net/nfp/flower/nfp_flower_cmsg.h +++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h @@ -324,6 +324,41 @@ struct nfp_flower_ipv6 { uint8_t ipv6_dst[16]; }; +struct nfp_flower_tun_ipv4 { + rte_be32_t src; + rte_be32_t dst; +}; + +struct nfp_flower_tun_ip_ext { + uint8_t tos; + uint8_t ttl; +}; + +/* + * Flow Frame IPv4 UDP TUNNEL --> Tunnel details (5W/20B) + * ----------------------------------------------------------------- + * 3 2 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | ipv4_addr_src | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | ipv4_addr_dst | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved | tos | ttl | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | VNI | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct nfp_flower_ipv4_udp_tun { + struct nfp_flower_tun_ipv4 ipv4; + rte_be16_t reserved1; + struct nfp_flower_tun_ip_ext ip_ext; + rte_be32_t reserved2; + rte_be32_t tun_id; +}; + struct nfp_fl_act_head { uint8_t jump_id; uint8_t len_lw; diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c index 823b020..5f6f800 100644 --- a/drivers/net/nfp/nfp_flow.c +++ b/drivers/net/nfp/nfp_flow.c @@ -38,7 +38,8 @@ struct nfp_flow_item_proc { char **mbuf_off, const struct rte_flow_item *item, const struct nfp_flow_item_proc *proc, - bool is_mask); + bool is_mask, + bool is_outer_layer); /* List of possible subsequent items. */ const enum rte_flow_item_type *const next_item; }; @@ -503,6 +504,7 @@ struct nfp_mask_id_entry { struct nfp_fl_key_ls *key_ls) { struct rte_eth_dev *ethdev; + bool outer_ip4_flag = false; const struct rte_flow_item *item; struct nfp_flower_representor *representor; const struct rte_flow_item_port_id *port_id; @@ -538,6 +540,8 @@ struct nfp_mask_id_entry { PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_IPV4 detected"); key_ls->key_layer |= NFP_FLOWER_LAYER_IPV4; key_ls->key_size += sizeof(struct nfp_flower_ipv4); + if (!outer_ip4_flag) + outer_ip4_flag = true; break; case RTE_FLOW_ITEM_TYPE_IPV6: PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_IPV6 detected"); @@ -559,6 +563,21 @@ struct nfp_mask_id_entry { key_ls->key_layer |= NFP_FLOWER_LAYER_TP; key_ls->key_size += sizeof(struct nfp_flower_tp_ports); break; + case RTE_FLOW_ITEM_TYPE_VXLAN: + PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_VXLAN detected"); + /* Clear IPv4 bits */ + key_ls->key_layer &= ~NFP_FLOWER_LAYER_IPV4; + key_ls->tun_type = NFP_FL_TUN_VXLAN; + key_ls->key_layer |= NFP_FLOWER_LAYER_VXLAN; + if (outer_ip4_flag) { + key_ls->key_size += sizeof(struct nfp_flower_ipv4_udp_tun); + /* + * The outer l3 layer information is + * in `struct nfp_flower_ipv4_udp_tun` + */ + key_ls->key_size -= sizeof(struct nfp_flower_ipv4); + } + break; default: PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type); return -ENOTSUP; @@ -737,12 +756,25 @@ struct nfp_mask_id_entry { return ret; } +static bool +nfp_flow_is_tunnel(struct rte_flow *nfp_flow) +{ + struct nfp_flower_meta_tci *meta_tci; + + meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data; + if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_VXLAN) + return true; + + return false; +} + static int nfp_flow_merge_eth(__rte_unused struct rte_flow *nfp_flow, char **mbuf_off, const struct rte_flow_item *item, const struct nfp_flow_item_proc *proc, - bool is_mask) + bool is_mask, + __rte_unused bool is_outer_layer) { struct nfp_flower_mac_mpls *eth; const struct rte_flow_item_eth *spec; @@ -778,7 +810,8 @@ struct nfp_mask_id_entry { __rte_unused char **mbuf_off, const struct rte_flow_item *item, const struct nfp_flow_item_proc *proc, - bool is_mask) + bool is_mask, + __rte_unused bool is_outer_layer) { struct nfp_flower_meta_tci *meta_tci; const struct rte_flow_item_vlan *spec; @@ -807,41 +840,58 @@ struct nfp_mask_id_entry { char **mbuf_off, const struct rte_flow_item *item, const struct nfp_flow_item_proc *proc, - bool is_mask) + bool is_mask, + bool is_outer_layer) { struct nfp_flower_ipv4 *ipv4; const struct rte_ipv4_hdr *hdr; struct nfp_flower_meta_tci *meta_tci; const struct rte_flow_item_ipv4 *spec; const struct rte_flow_item_ipv4 *mask; + struct nfp_flower_ipv4_udp_tun *ipv4_udp_tun; spec = item->spec; mask = item->mask ? item->mask : proc->mask_default; meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data; - if (spec == NULL) { - PMD_DRV_LOG(DEBUG, "nfp flow merge ipv4: no item->spec!"); - goto ipv4_end; - } + if (is_outer_layer && nfp_flow_is_tunnel(nfp_flow)) { + if (spec == NULL) { + PMD_DRV_LOG(DEBUG, "nfp flow merge ipv4: no item->spec!"); + return 0; + } - /* - * reserve space for L4 info. - * rte_flow has ipv4 before L4 but NFP flower fw requires L4 before ipv4 - */ - if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_TP) - *mbuf_off += sizeof(struct nfp_flower_tp_ports); + hdr = is_mask ? &mask->hdr : &spec->hdr; + ipv4_udp_tun = (struct nfp_flower_ipv4_udp_tun *)*mbuf_off; - hdr = is_mask ? &mask->hdr : &spec->hdr; - ipv4 = (struct nfp_flower_ipv4 *)*mbuf_off; + ipv4_udp_tun->ip_ext.tos = hdr->type_of_service; + ipv4_udp_tun->ip_ext.ttl = hdr->time_to_live; + ipv4_udp_tun->ipv4.src = hdr->src_addr; + ipv4_udp_tun->ipv4.dst = hdr->dst_addr; + } else { + if (spec == NULL) { + PMD_DRV_LOG(DEBUG, "nfp flow merge ipv4: no item->spec!"); + goto ipv4_end; + } + + /* + * reserve space for L4 info. + * rte_flow has ipv4 before L4 but NFP flower fw requires L4 before ipv4 + */ + if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_TP) + *mbuf_off += sizeof(struct nfp_flower_tp_ports); + + hdr = is_mask ? &mask->hdr : &spec->hdr; + ipv4 = (struct nfp_flower_ipv4 *)*mbuf_off; - ipv4->ip_ext.tos = hdr->type_of_service; - ipv4->ip_ext.proto = hdr->next_proto_id; - ipv4->ip_ext.ttl = hdr->time_to_live; - ipv4->ipv4_src = hdr->src_addr; - ipv4->ipv4_dst = hdr->dst_addr; + ipv4->ip_ext.tos = hdr->type_of_service; + ipv4->ip_ext.proto = hdr->next_proto_id; + ipv4->ip_ext.ttl = hdr->time_to_live; + ipv4->ipv4_src = hdr->src_addr; + ipv4->ipv4_dst = hdr->dst_addr; ipv4_end: - *mbuf_off += sizeof(struct nfp_flower_ipv4); + *mbuf_off += sizeof(struct nfp_flower_ipv4); + } return 0; } @@ -851,7 +901,8 @@ struct nfp_mask_id_entry { char **mbuf_off, const struct rte_flow_item *item, const struct nfp_flow_item_proc *proc, - bool is_mask) + bool is_mask, + __rte_unused bool is_outer_layer) { struct nfp_flower_ipv6 *ipv6; const struct rte_ipv6_hdr *hdr; @@ -896,7 +947,8 @@ struct nfp_mask_id_entry { char **mbuf_off, const struct rte_flow_item *item, const struct nfp_flow_item_proc *proc, - bool is_mask) + bool is_mask, + __rte_unused bool is_outer_layer) { uint8_t tcp_flags; struct nfp_flower_tp_ports *ports; @@ -968,7 +1020,8 @@ struct nfp_mask_id_entry { char **mbuf_off, const struct rte_flow_item *item, const struct nfp_flow_item_proc *proc, - bool is_mask) + bool is_mask, + bool is_outer_layer) { char *ports_off; struct nfp_flower_tp_ports *ports; @@ -982,6 +1035,12 @@ struct nfp_mask_id_entry { return 0; } + /* Don't add L4 info if working on a inner layer pattern */ + if (!is_outer_layer) { + PMD_DRV_LOG(INFO, "Detected inner layer UDP, skipping."); + return 0; + } + meta_tci = (struct nfp_flower_meta_tci *)nfp_flow->payload.unmasked_data; if (meta_tci->nfp_flow_key_layer & NFP_FLOWER_LAYER_IPV4) { ports_off = *mbuf_off - sizeof(struct nfp_flower_ipv4) - @@ -1009,7 +1068,8 @@ struct nfp_mask_id_entry { char **mbuf_off, const struct rte_flow_item *item, const struct nfp_flow_item_proc *proc, - bool is_mask) + bool is_mask, + __rte_unused bool is_outer_layer) { char *ports_off; struct nfp_flower_tp_ports *ports; @@ -1045,10 +1105,42 @@ struct nfp_mask_id_entry { return 0; } +static int +nfp_flow_merge_vxlan(__rte_unused struct rte_flow *nfp_flow, + char **mbuf_off, + const struct rte_flow_item *item, + const struct nfp_flow_item_proc *proc, + bool is_mask, + __rte_unused bool is_outer_layer) +{ + const struct rte_vxlan_hdr *hdr; + struct nfp_flower_ipv4_udp_tun *tun4; + const struct rte_flow_item_vxlan *spec; + const struct rte_flow_item_vxlan *mask; + + spec = item->spec; + if (spec == NULL) { + PMD_DRV_LOG(DEBUG, "nfp flow merge vxlan: no item->spec!"); + goto vxlan_end; + } + + mask = item->mask ? item->mask : proc->mask_default; + hdr = is_mask ? &mask->hdr : &spec->hdr; + + tun4 = (struct nfp_flower_ipv4_udp_tun *)*mbuf_off; + tun4->tun_id = hdr->vx_vni; + +vxlan_end: + *mbuf_off += sizeof(struct nfp_flower_ipv4_udp_tun); + + return 0; +} + /* Graph of supported items and associated process function */ static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = { [RTE_FLOW_ITEM_TYPE_END] = { - .next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH), + .next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4), }, [RTE_FLOW_ITEM_TYPE_ETH] = { .next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_VLAN, @@ -1131,6 +1223,7 @@ struct nfp_mask_id_entry { .merge = nfp_flow_merge_tcp, }, [RTE_FLOW_ITEM_TYPE_UDP] = { + .next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_VXLAN), .mask_support = &(const struct rte_flow_item_udp){ .hdr = { .src_port = RTE_BE16(0xffff), @@ -1152,6 +1245,17 @@ struct nfp_mask_id_entry { .mask_sz = sizeof(struct rte_flow_item_sctp), .merge = nfp_flow_merge_sctp, }, + [RTE_FLOW_ITEM_TYPE_VXLAN] = { + .next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH), + .mask_support = &(const struct rte_flow_item_vxlan){ + .hdr = { + .vx_vni = RTE_BE32(0xffffff00), + }, + }, + .mask_default = &rte_flow_item_vxlan_mask, + .mask_sz = sizeof(struct rte_flow_item_vxlan), + .merge = nfp_flow_merge_vxlan, + }, }; static int @@ -1205,21 +1309,53 @@ struct nfp_mask_id_entry { return ret; } +static bool +nfp_flow_is_tun_item(const struct rte_flow_item *item) +{ + if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN) + return true; + + return false; +} + +static bool +nfp_flow_inner_item_get(const struct rte_flow_item items[], + const struct rte_flow_item **inner_item) +{ + const struct rte_flow_item *item; + + *inner_item = items; + + for (item = items; item->type != RTE_FLOW_ITEM_TYPE_END; ++item) { + if (nfp_flow_is_tun_item(item)) { + *inner_item = ++item; + return true; + } + } + + return false; +} + static int nfp_flow_compile_item_proc(const struct rte_flow_item items[], struct rte_flow *nfp_flow, char **mbuf_off_exact, - char **mbuf_off_mask) + char **mbuf_off_mask, + bool is_outer_layer) { int i; int ret = 0; + bool continue_flag = true; const struct rte_flow_item *item; const struct nfp_flow_item_proc *proc_list; proc_list = nfp_flow_item_proc_list; - for (item = items; item->type != RTE_FLOW_ITEM_TYPE_END; ++item) { + for (item = items; item->type != RTE_FLOW_ITEM_TYPE_END && continue_flag; ++item) { const struct nfp_flow_item_proc *proc = NULL; + if (nfp_flow_is_tun_item(item)) + continue_flag = false; + for (i = 0; proc_list->next_item && proc_list->next_item[i]; ++i) { if (proc_list->next_item[i] == item->type) { proc = &nfp_flow_item_proc_list[item->type]; @@ -1248,14 +1384,14 @@ struct nfp_mask_id_entry { } ret = proc->merge(nfp_flow, mbuf_off_exact, item, - proc, false); + proc, false, is_outer_layer); if (ret != 0) { PMD_DRV_LOG(ERR, "nfp flow item %d exact merge failed", item->type); break; } ret = proc->merge(nfp_flow, mbuf_off_mask, item, - proc, true); + proc, true, is_outer_layer); if (ret != 0) { PMD_DRV_LOG(ERR, "nfp flow item %d mask merge failed", item->type); break; @@ -1275,6 +1411,9 @@ struct nfp_mask_id_entry { int ret; char *mbuf_off_mask; char *mbuf_off_exact; + bool is_tun_flow = false; + bool is_outer_layer = true; + const struct rte_flow_item *loop_item; mbuf_off_exact = nfp_flow->payload.unmasked_data + sizeof(struct nfp_flower_meta_tci) + @@ -1283,14 +1422,29 @@ struct nfp_mask_id_entry { sizeof(struct nfp_flower_meta_tci) + sizeof(struct nfp_flower_in_port); + /* Check if this is a tunnel flow and get the inner item*/ + is_tun_flow = nfp_flow_inner_item_get(items, &loop_item); + if (is_tun_flow) + is_outer_layer = false; + /* Go over items */ - ret = nfp_flow_compile_item_proc(items, nfp_flow, - &mbuf_off_exact, &mbuf_off_mask); + ret = nfp_flow_compile_item_proc(loop_item, nfp_flow, + &mbuf_off_exact, &mbuf_off_mask, is_outer_layer); if (ret != 0) { PMD_DRV_LOG(ERR, "nfp flow item compile failed."); return -EINVAL; } + /* Go over inner items */ + if (is_tun_flow) { + ret = nfp_flow_compile_item_proc(items, nfp_flow, + &mbuf_off_exact, &mbuf_off_mask, true); + if (ret != 0) { + PMD_DRV_LOG(ERR, "nfp flow outer item compile failed."); + return -EINVAL; + } + } + return 0; } @@ -2123,12 +2277,35 @@ struct nfp_mask_id_entry { return 0; } +static int +nfp_flow_tunnel_match(__rte_unused struct rte_eth_dev *dev, + __rte_unused struct rte_flow_tunnel *tunnel, + __rte_unused struct rte_flow_item **pmd_items, + uint32_t *num_of_items, + __rte_unused struct rte_flow_error *err) +{ + *num_of_items = 0; + + return 0; +} + +static int +nfp_flow_tunnel_item_release(__rte_unused struct rte_eth_dev *dev, + __rte_unused struct rte_flow_item *pmd_items, + __rte_unused uint32_t num_of_items, + __rte_unused struct rte_flow_error *err) +{ + return 0; +} + static const struct rte_flow_ops nfp_flow_ops = { .validate = nfp_flow_validate, .create = nfp_flow_create, .destroy = nfp_flow_destroy, .flush = nfp_flow_flush, .query = nfp_flow_query, + .tunnel_match = nfp_flow_tunnel_match, + .tunnel_item_release = nfp_flow_tunnel_item_release, }; int -- 1.8.3.1