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 14C66A0543; Tue, 25 Oct 2022 10:00:06 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 9E0BA42BA7; Tue, 25 Oct 2022 09:59:59 +0200 (CEST) Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11on2113.outbound.protection.outlook.com [40.107.223.113]) by mails.dpdk.org (Postfix) with ESMTP id 0647842B81 for ; Tue, 25 Oct 2022 09:59:57 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=RzJUw861NwGltgi2P1okBJMJGwLQnXKqqsLT3dAZlPMjwSFygI6t02TjdLzixPJgF7PQQr0wBR20CqU2UGJhv/pnk6Jt6L0GzY1/xBQncdPFazMtlF7EFND2Tuz8snufoLks0vJveRsYfV+sLLCUg8IjWKhf3YXIIGQB0nL0bhZDgitWsjzuwbYCoz4XVWx7hqGmvkf7tThxgC3QBHg5tIYnRCRHBU/un7TciAE/e0W5VLpQ1yKgR4udEMViZMBpywgUaMtGasQ+Tddnxho+USGEOMh0Z/j1zsQT/UrvrAJxKK6cqfGBLfR/EuqSH2Qk+oLPOKd5uFCPxJ8G0WvS5w== 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=IOdK0BFwvJk/V5ENo+oBpieLaCJMPdwG2DQKsJq9HOs=; b=DvL/3tBn7ORQJHDJZS2dRM0PyFkTwcAXFslRsVX5t7wZ3SVKMrsszoliRTeJ5IK/lPytmRZQvF9F+GosjRIVmakIJ3ISsgis4OrG4RjMszJbBV7/ixdceIZHaC3HEpXClaCHF+pJffocmNUgQaJ708c7WVub+LeuaXmWlY7l+Pto67cBlXo9iPOR4YT9TYI7BnUAtgUqODqTLpXKo1gjNjneFlaCSD+JxIHhLYYRGbnzaLecqwBsCSTSL7+9wIGlMoE/edIdWzYWTKSmzDM+mZpeDc8yn7IWcQrc4sDyBi3aig+Av2Kom3bnfIUd5kvYq/T8cQ79/j2JJgkaHeEu+Q== 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=IOdK0BFwvJk/V5ENo+oBpieLaCJMPdwG2DQKsJq9HOs=; b=tMO0sq85y+CooKWeH+QfMaQwZD2LuuiclOQF5Pdb06Lc4qz7WRWTljrx/DtGvktV1PJVBXdOyAnUR1ecPJCc04KnXkll2FsHz14u8SCXSZF7gsIH5V5LcpOghGy6C3oJIKDFprxG1mwF7jZtvPmAD5cRgJPsBqPzr4ERZJF+TUc= 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 MW5PR13MB5439.namprd13.prod.outlook.com (2603:10b6:303:196::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5723.20; Tue, 25 Oct 2022 07:59:55 +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, 25 Oct 2022 07:59:55 +0000 From: Chaoyong He To: dev@dpdk.org Cc: oss-drivers@corigine.com, niklas.soderlund@corigine.com, Chaoyong He Subject: [PATCH v3 02/26] net/nfp: support IPv4 VXLAN flow item Date: Tue, 25 Oct 2022 15:58:54 +0800 Message-Id: <20221025075918.7778-3-chaoyong.he@corigine.com> X-Mailer: git-send-email 2.29.3 In-Reply-To: <20221025075918.7778-1-chaoyong.he@corigine.com> References: <1666427069-10553-1-git-send-email-chaoyong.he@corigine.com> <20221025075918.7778-1-chaoyong.he@corigine.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-ClientProxiedBy: SG2PR01CA0142.apcprd01.prod.exchangelabs.com (2603:1096:4:8f::22) To SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ0PR13MB5545:EE_|MW5PR13MB5439:EE_ X-MS-Office365-Filtering-Correlation-Id: 953f49b4-9b74-4d47-590a-08dab65ee738 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: DCwuNsUDVGXBrI5drO05q1ZvnNxHOkVUjbP3BdVS8SC3/hMBRxR60iVjZVFW2H2ev3UbeizTu05f2wstQx1tZRwPUjmvhA/AzvRIMVi+OaRd47EDKHQR7HsSriGisFIa85DePH9qQ9sR0I4H0ftZKwKLOyNGI6KujA5VLW8ODnRXYvhR4Kix20ZDqWy6UR1vrGco252KdYq8WnHq8ZCmzG5oLJ1nW4kNz/wVpiaOryOGpXDPa2FSvgVnEGml+0jpwrEGsENQNHUsIW7np7Nry8q9vkE6Zq5BS3wIGskBf8qf3BrQo5+XBAgWo36NM91drqc+016erYFQpctUQKwA6ZW9tvxmPuNTevE+V7M+ZRPyi41QV2H6llykszbkjcZqbWSCLmLa/unCyI/emQs5J7cepzy6NQlWtyagqyP/bF+LDG8kgBt5pQabLSlqN0NeWjoZlzTSPBYVc2/i1lj50bD2SDrb/jKbkMs7xBl0X+Eayrzo4OAoq7Wfzqc7owaFVli2WDhU/G4CdAE8pDOrMCjiAHYBVQ5c8dS3VhRDXBandsRUAcLyRyWVi2p5LX6RCeAn+elwex9h7rdmzfXQcf6OXSp/+uIue+X5jY229XqNEc+W0tEwvn6cTZmCoV2MoVI3jfDDXeafrEL/9E6hKpYLyd+r5GxCSK0qMFl0iJ/57++9/xD420mmV21UpiYL+QKO1Cm6lrF/CNQGGGs3F0uFstmldiCJjsbkTXAk1tchynJS1HJ76f+mnOCRCqVZ 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)(39850400004)(366004)(396003)(346002)(376002)(136003)(451199015)(83380400001)(6506007)(478600001)(316002)(38100700002)(52116002)(38350700002)(2906002)(41300700001)(30864003)(5660300002)(6486002)(44832011)(66946007)(66476007)(4326008)(66556008)(8676002)(6916009)(66574015)(1076003)(8936002)(6512007)(86362001)(2616005)(26005)(107886003)(36756003)(186003); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?OXJJN1pmZ1hoSXZwU1BiWVpVYjNWTHdNaEx5SXZ6aHYxWFJuWUxoZDNXME9T?= =?utf-8?B?TmFTL1lyL3prMTFLSENRN1RRWDlmeWZUQ05rT1pGLzhGbEFZeE5PbDV6djdB?= =?utf-8?B?MEJuRHJaZGpuVzJDLzhxZUZGSitlUnNLZjJmM0pmaTBkVTR6WDRFTkQvbW1S?= =?utf-8?B?Q0hRQUZ0a25qVlhYaVNWUFhaRjJqQXhBUStBa05HUnZFNWhtWVRFZVRxL0N4?= =?utf-8?B?ZFdscDE4b28wMVhOUzgwVTFjNzhOZk1NTHJqbFFFU3Zlb0QvTGtpUVVWbTFI?= =?utf-8?B?NkVERTVjY20zL2dGWUlBMVlsc2J1QXJIRHVPYVVBOFFRN2s4OWZvYndsZG1F?= =?utf-8?B?UjZlUUVJUkplaUp2MmprTEtGZDNwbloyQncrRDBjOERBM3lJbitJUlZJYVdZ?= =?utf-8?B?VjRJQ21HNERIT0xacFVjbEd1alp1aWRieGo2MVhSZ0dudXQ3UDhteUd2VFgr?= =?utf-8?B?cldYMjRiZ0FNc3A2QnZGV2R1K3dhRU1pMGo2OTJrTHNaMEtpZ1hkUWcxcjRr?= =?utf-8?B?ZXdDTm5Qa1dMZWFPKzVQWWNrWUVLNFg3V2xyTlA4YUxHV1luN1ZnZlFrRlJX?= =?utf-8?B?VHlQWWpEMGgwUnhLRGhtdzB2RjY4a29BVjFBc200SElrRnZUZk92MzhTZUlv?= =?utf-8?B?RzRDQkpndk1hWTBFVmhFOEd5MUZBYWtOWldyT0N2bnA4Y3Y1bmpLMy9uREtL?= =?utf-8?B?Yy9sbXNlazZjc2M3WlpXZVh4elhKc25mV0wwUEI5V0FvdEp2TVdSdVNBNWlV?= =?utf-8?B?WFRFcEF4WVRiSHBuMnRKNzRkOCtPZjdReVlaZFptV05ibFBkTVlPUGxKRjh1?= =?utf-8?B?NmVPdFhMS3ZkU2ZIa2lRK1orN1VKQlhzQVAxeGRTT3d1eloxU0RJdjVWSFg1?= =?utf-8?B?MmV0ZWlmSDNUMTBrVUJ2QXlqd3ZLUjdHMTkwcVRvMktIUkVqTjRsNzVVWjRR?= =?utf-8?B?V3FDMlZvb092Umc1Rm5SWjVEUXRLbFVpd0xXS3p1aHV5R2R5V1MydUFPdWdR?= =?utf-8?B?aTZxRTh2MVFXVm9VNGFFWTJMV3hiMmgwNnJITy9zK1RzRHJFdGZRanVJcFR5?= =?utf-8?B?c1c5dzd3QW1CWnlqUExGT1pJZUFiRnUxdnp4REhYTS8yUEx0M2ZLblFJeXlG?= =?utf-8?B?blJyK3pkaFNMNVRWaUUwZVJZMXFJcHhRVnVXN3Z4dlg3bGtNYnJWbG42V1Jr?= =?utf-8?B?Qmc3TmJPanVNZ1dBYjlxeVVLclVXc2xVMHVNclk3SVhEREpwZGZ2Q0lGNG1o?= =?utf-8?B?YUhleHBFckpUMG50WiswM21SOTV2WURhTjRrVFNxNHhwd2V6eklSQTBPcEVK?= =?utf-8?B?NmxQWSt1OGFiWG5haDBWd2g1ZTUzYTNlbWlBWjZSZDhwMSs4emhuNHpWanZX?= =?utf-8?B?OVM1cHhrei9FNDNEU1NrYVVPc0l0Wm4rRUkyc0h4b2hMQmhmZ3AxeEk4b0ZK?= =?utf-8?B?SmpLQ0RPN2dXZktyWDlJY29BU0Rvd0J1VmpEQzFNRllBb05vMXZ2dm02M1Fn?= =?utf-8?B?SjFwUS9McnhybEV5NGkvTy9GdGJKeWprQ1FvamROV3BiaU8wd3MzZFJCZ0tT?= =?utf-8?B?b2djdU16UmlUTmk2enNNQ3VVWVV0NUNkeHNpZ2x4Z0g1d001MDgwTFNLSkJI?= =?utf-8?B?N0x0U0FWTkVXemNKQ0xpRUd6OE96NkhFcUNxSWh3KzZnVU00N1h1djdqS0hV?= =?utf-8?B?VTJ6TklPZGwrWG0wWjBhc005MUNlZE9XSEJKWmk0cUo1SHI4RDhicFE4am5X?= =?utf-8?B?TmVObk1sQll4aXlwSXZnUm94bG5DQ2lYTWtnc2NaZzZvYVBSckxxWlBOd2ha?= =?utf-8?B?TkJPVDJLeUNScUQ4K1FxOWl0bFAwQ3NhYWNaK0VnUGJFQU40SWRMWWszUUdu?= =?utf-8?B?REdJSXJJdURUK2dHSy9DRU8waDFyNitrQVdESDBiUFpJS0Rnc21lN3FDYmZB?= =?utf-8?B?aUlwRWNXK3M1Q28wc2RNVnhCcHFzK2Y0VXcwWWZqTUZ4bDVqTzJ3TDlqSkRm?= =?utf-8?B?WkVONFRpSGxibVZMaDQremttNEtpeXY4RDdDN3JVNnA0VTF3U3ZiT0V4N1hy?= =?utf-8?B?dnRKcElTclBOOEpNeFNCVmthbHU3dXJsMjQwRTdBQzBlNlo2eUhnQjVoMmw0?= =?utf-8?B?SlpYSlRhT1hGWkhnWElnOXVYQUJNUGl2SXJYaVVQZ2Nac2hqbG9jN0diK0t5?= =?utf-8?B?SVE9PQ==?= X-OriginatorOrg: corigine.com X-MS-Exchange-CrossTenant-Network-Message-Id: 953f49b4-9b74-4d47-590a-08dab65ee738 X-MS-Exchange-CrossTenant-AuthSource: SJ0PR13MB5545.namprd13.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Oct 2022 07:59:55.2037 (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: +KG7xfTye/pvTg5CSeIe76Dt9+hdJIjEXmvtXiIu581BV9aX7tfMGNgBFl3IfL//gZQQtxpkD9Fzn9r/XJ1jRoTkodRttB2pui2rSyNf1ZA= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW5PR13MB5439 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 0184980e88..faaa7da83c 100644 --- a/doc/guides/nics/features/nfp.ini +++ b/doc/guides/nics/features/nfp.ini @@ -35,6 +35,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 6bf8ff7d56..08e2873808 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 69fc8be7ed..0e1e5ea6b2 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; }; @@ -491,6 +492,7 @@ nfp_flow_key_layers_calculate_items(const struct rte_flow_item items[], 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; @@ -526,6 +528,8 @@ nfp_flow_key_layers_calculate_items(const struct rte_flow_item items[], 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"); @@ -547,6 +551,21 @@ nfp_flow_key_layers_calculate_items(const struct rte_flow_item items[], 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; @@ -719,12 +738,25 @@ nfp_flow_key_layers_calculate(const struct rte_flow_item items[], 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; @@ -760,7 +792,8 @@ nfp_flow_merge_vlan(struct rte_flow *nfp_flow, __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; @@ -789,41 +822,58 @@ nfp_flow_merge_ipv4(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, + 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; } @@ -833,7 +883,8 @@ nfp_flow_merge_ipv6(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_ipv6 *ipv6; const struct rte_ipv6_hdr *hdr; @@ -878,7 +929,8 @@ nfp_flow_merge_tcp(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) { uint8_t tcp_flags; struct nfp_flower_tp_ports *ports; @@ -950,7 +1002,8 @@ nfp_flow_merge_udp(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, + bool is_outer_layer) { char *ports_off; struct nfp_flower_tp_ports *ports; @@ -964,6 +1017,12 @@ nfp_flow_merge_udp(struct rte_flow *nfp_flow, 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) - @@ -991,7 +1050,8 @@ nfp_flow_merge_sctp(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) { char *ports_off; struct nfp_flower_tp_ports *ports; @@ -1027,10 +1087,42 @@ nfp_flow_merge_sctp(struct rte_flow *nfp_flow, 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, @@ -1113,6 +1205,7 @@ static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = { .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), @@ -1134,6 +1227,17 @@ static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = { .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 @@ -1187,21 +1291,53 @@ nfp_flow_item_check(const struct rte_flow_item *item, 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]; @@ -1230,14 +1366,14 @@ nfp_flow_compile_item_proc(const struct rte_flow_item items[], } 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; @@ -1257,6 +1393,9 @@ nfp_flow_compile_items(__rte_unused struct nfp_flower_representor *representor, 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) + @@ -1265,14 +1404,29 @@ nfp_flow_compile_items(__rte_unused struct nfp_flower_representor *representor, 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; } @@ -2119,12 +2273,35 @@ nfp_flow_query(struct rte_eth_dev *dev, 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 -- 2.29.3