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 195E3A052A; Wed, 27 Jan 2021 12:37:03 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7D892140CEF; Wed, 27 Jan 2021 12:37:02 +0100 (CET) Received: from hqnvemgate26.nvidia.com (hqnvemgate26.nvidia.com [216.228.121.65]) by mails.dpdk.org (Postfix) with ESMTP id 5D560140CEE for ; Wed, 27 Jan 2021 12:37:01 +0100 (CET) Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate26.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Wed, 27 Jan 2021 03:37:00 -0800 Received: from HQMAIL105.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Wed, 27 Jan 2021 03:37:00 -0800 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Wed, 27 Jan 2021 03:37:00 -0800 Received: from HQMAIL101.nvidia.com (172.20.187.10) by HQMAIL105.nvidia.com (172.20.187.12) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 27 Jan 2021 11:36:59 +0000 Received: from HQMAIL111.nvidia.com (172.20.187.18) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 27 Jan 2021 11:36:59 +0000 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (104.47.56.176) by HQMAIL111.nvidia.com (172.20.187.18) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Wed, 27 Jan 2021 11:36:59 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=kaxS8cwtjS/OHnUwoKoNGPSPopoLOd4LHLI+LRz6PdzIgxKQar6wFsutKGCOGJc1kPHlLzidZ1Kxv/jiI5G25W5OQ0OGRCQhSaHpt4ac5rY3uByi4DHgzigLLqzSJi3wXxqe7zrZnXMd8fOB/EP7a9F9CfxOlSj02LuvKXZtRC+dSalUljmBiKIGoWx7s9yc3gvDRFHyKVFYlm684oGJXjwj0AYzcMjDnTmWsqVE//QpxwaH5sFfeoSVnNROPGiJbUakwn3xVgTi57oJeCOne0hCIvXXJeq3d0yYF9DhYnq2fxq+oUzicJ+6mAMydWx2L55jmUQ8jrWCbkv2qMkLGQ== 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-SenderADCheck; bh=Zu7y2TRSZqi9JHJGM5hClIZK3u1Po+aKBqqqMAkqxGE=; b=PqOIGhm6itvEGQveV8dqYNhjpWWbLtGRXwobuQbA5jcrM7CEeeD+76FvfHm9rfU3/Yth9Fz2J8nA8OJHjt4iEcTKRjszMYB3PAgf/ZSQQRO8FqDizporfs8xCWb9cwQ/dUdnvLffXkl3KrVkzCiTZ5IE7yF0nYhDoauIMRASpK4RhA5f05F4miP5aaS+OUIbNToYw4UZzCDq/jIeCuop7bXFb4W7j7ggkr0i5n56UonvwHCmX9zfRkden2irhNhT/v2lCUwSHECPsILNPUmoFhqzPYju7353xIMnYu14j8nf3eW5P3RM4H8oXxYn9gOZvRYyjAtAMAgIMsUREVxhmw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none Received: from DM6PR12MB3753.namprd12.prod.outlook.com (2603:10b6:5:1c7::18) by DM6PR12MB5008.namprd12.prod.outlook.com (2603:10b6:5:1b7::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3784.13; Wed, 27 Jan 2021 11:36:58 +0000 Received: from DM6PR12MB3753.namprd12.prod.outlook.com ([fe80::e4a9:f9a1:d873:d07a]) by DM6PR12MB3753.namprd12.prod.outlook.com ([fe80::e4a9:f9a1:d873:d07a%5]) with mapi id 15.20.3784.019; Wed, 27 Jan 2021 11:36:57 +0000 From: Slava Ovsiienko To: Alexander Kozyrev , "dev@dpdk.org" CC: Raslan Darawsheh , Matan Azrad , Ori Kam Thread-Topic: [PATCH] net/mlx5: support modify field rte flow action Thread-Index: AQHW9Fb7RhETV+oDDkuItqJCBYrSiao7HjDQ Date: Wed, 27 Jan 2021 11:36:57 +0000 Message-ID: References: <20210127024852.819-1-akozyrev@nvidia.com> In-Reply-To: <20210127024852.819-1-akozyrev@nvidia.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: nvidia.com; dkim=none (message not signed) header.d=none;nvidia.com; dmarc=none action=none header.from=nvidia.com; x-originating-ip: [188.163.75.192] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: fbfba448-183d-48c7-19ff-08d8c2b7dadf x-ms-traffictypediagnostic: DM6PR12MB5008: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:8273; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: MzMeClSfBvJe4551qMQHaxIsgL/2q1PjbMHHqVlDsmJCvuyYHF6GSM2vT1Mh/T/txY8HkTIXfCj2fi09gUreR0gWlTbE09sdBfFrkbc7HrVeHmONYXdKGRGLO8DQI3p0/5MDkbWmB3sFH5Qg9WxXowXZ7gARs+X2g21nfjdOJi/WofO2YsC5QgeNmSrKfMaQYfmEdpx23MVZac9hxcWIKWrgoFxi9Qe6NfB48WhNIcmNIBIkVzY49L428JNqUVnGd2ncLyo3C0rloZoKkyISGzpiEgfd/7VtlSip44iVRMekUBcQ8uAbe2wT4FSjPQYMHzZvbh1wY9tEIuRdLsKG2XK00ru94iljrBhTgin725vMipQcvgn82TOqkukqZKUyKLVbtBbEtAERuGPiTGBQShUDesfKg36MqEZMmFINLewIUw46Ed6Jt7PUGKcvcvxbSoNgmy+s1AZhGzNI9CJ/LfaoJB2/rlQijnV7NxzV2MurGueeLPAk+NPWHwUpav6uoBOM6edGKyLSqZ2yNZb/Iw== x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DM6PR12MB3753.namprd12.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(376002)(39860400002)(346002)(366004)(136003)(396003)(71200400001)(8676002)(8936002)(478600001)(54906003)(316002)(110136005)(66946007)(7696005)(33656002)(53546011)(64756008)(55236004)(6506007)(26005)(186003)(4326008)(86362001)(2906002)(66446008)(9686003)(5660300002)(66556008)(30864003)(76116006)(66476007)(83380400001)(55016002)(52536014)(107886003)(579004); DIR:OUT; SFP:1101; x-ms-exchange-antispam-messagedata: =?us-ascii?Q?XUjPrn36U2jJkZPZhuD30FMbAAPj/cej7iThjnRCxmZtgtEX4AKJn9bRlbzQ?= =?us-ascii?Q?pjCI4LRBKV/Sl8xH38zljtpq86iueBpiu+AvVqErrOM+4sMElK/boC8HQGWQ?= =?us-ascii?Q?pCbD/8WZWC9NO2IPYzdZlvHFElNxUDNofjwEqlc43J07VwHYG1ATA06Ettyf?= =?us-ascii?Q?PFv8b+dRh8pZW6DtdkHySlzXjqpYLPsH+p41nQ+UqwBIGtOSR1kscvWidJEC?= =?us-ascii?Q?pcsMPxXp3uRvAh2pAbIkn5VoSC11dKfwjrdJ+DE3hwbm4JiXRxQhdxeN9RVO?= =?us-ascii?Q?LtPvSGL4hULoraTFBnixxJS7ikO7ZiOpnEEt7plkV0l48Q6BprRGun+3SWas?= =?us-ascii?Q?hQElxIiNN8PTPHN4WCQTkdoJWqCYH+CUWk84gO1r41IHWfhSxy7sDfbhVZJk?= =?us-ascii?Q?rIniLObaSgSJDSRebBdC4pAWDQilpMkfuWpbkLCMwAKp9BMCR5EcBhiDaQE5?= =?us-ascii?Q?bk/YDQUsOCPY+VgUITk4PbP4xJbXeAd5ITn/9gOZCu04g/ZVz3P3ijoBRPnM?= =?us-ascii?Q?hhRf01c7Jjrl208H95pe6lsJmnP20Dh5VHCziLYqTgRk5+GEOkyWU7PD+BWf?= =?us-ascii?Q?lk94pinJw5e+dwTRmeQCIIbC5lOkcH2YSYM+kNtpXxs98q0g/eijVlbz6r+u?= =?us-ascii?Q?MU4TtXanAbDuTR9jTO4ARntZ4SHTlOIQ/e1ypRmWJ3h0Dby71t2WJ/xd8tvZ?= =?us-ascii?Q?UxCmApPYDgEmToIW0cEDLFVOwKZbPlrhhc6caSNaNmgn6p/rxcIEYYCCBrek?= =?us-ascii?Q?beiSuJYVCscsVsQYDxdUI2UAFMjyAwtKRNq6DG3jH49Y2xxKRK7FR6ALe1JD?= =?us-ascii?Q?PkVAJ5JnbGn/xh/9+v8gfI+fkRNX4etmuaYL1KTVsuz/LJ8RAfyZljuvQcsy?= =?us-ascii?Q?qhlaMioubG+wHbvOpSvFqSUGikBd16WHAQL98KjZXx5AQneAtQBRIHNQ6Kwq?= =?us-ascii?Q?bJ6nNn96vmJ2WBaFaYgTNJuJxbjt/R5b47V9fs8iuOmZAUrnTgLgij2Q3YMU?= =?us-ascii?Q?VxIM0G1vySu/p0eY7Y9Oax8UMKf7RQyNwf/oH8AXOEwOTm13Fjnasr5XQgs7?= =?us-ascii?Q?7Omy6jRG?= Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: DM6PR12MB3753.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: fbfba448-183d-48c7-19ff-08d8c2b7dadf X-MS-Exchange-CrossTenant-originalarrivaltime: 27 Jan 2021 11:36:57.8204 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: SyCRGMee1xOiL/O1lZL6pRbvs1tMkk/YzpxcFJ0Io7l1/RqAhVPzUTEtZtLJiDFeCFBeFzf4ZvH2veJjUbOfTA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB5008 X-OriginatorOrg: Nvidia.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1611747420; bh=Zu7y2TRSZqi9JHJGM5hClIZK3u1Po+aKBqqqMAkqxGE=; h=X-PGP-Universal:ARC-Seal:ARC-Message-Signature: ARC-Authentication-Results:From:To:CC:Subject:Thread-Topic: Thread-Index:Date:Message-ID:References:In-Reply-To: Accept-Language:Content-Language:X-MS-Has-Attach: X-MS-TNEF-Correlator:authentication-results:x-originating-ip: x-ms-publictraffictype:x-ms-office365-filtering-correlation-id: x-ms-traffictypediagnostic:x-ms-exchange-transport-forked: x-microsoft-antispam-prvs:x-ms-oob-tlc-oobclassifiers: x-ms-exchange-senderadcheck:x-microsoft-antispam: x-microsoft-antispam-message-info:x-forefront-antispam-report: x-ms-exchange-antispam-messagedata:Content-Type: Content-Transfer-Encoding:MIME-Version: X-MS-Exchange-CrossTenant-AuthAs: X-MS-Exchange-CrossTenant-AuthSource: X-MS-Exchange-CrossTenant-Network-Message-Id: X-MS-Exchange-CrossTenant-originalarrivaltime: X-MS-Exchange-CrossTenant-fromentityheader: X-MS-Exchange-CrossTenant-id:X-MS-Exchange-CrossTenant-mailboxtype: X-MS-Exchange-CrossTenant-userprincipalname: X-MS-Exchange-Transport-CrossTenantHeadersStamped:X-OriginatorOrg; b=XnQjijypZdM+TDhwO3StIhYRVN6yfPu8uLGkbBp/STFl6tkcJXYW02H3GjyhwtgYW jkBnh6ULrkMCg1tBp9EcWP5lmppgIn9yABHR6cHSy0Tc4A4oYNz+BA8bH6VtLW32FG Cb+ciOEa0FNvHSPuYGM2ZC5CA5fdHsrDocwKpbr1Pc9uxgmvKuFsYQrQVX0SVRlBP8 w8Rwd9zP0ZWCK4tnAvBHyMZRnGAOWYBV+CGlmvShPA3InADAzprYDmUzGKQMOJeM/O 1bZarbmP7HIEweuLGVwtzmYlWFhnDsnfSZWDpXijtN9qCpKezC9bsbTUH2vMpfQR0W MCXy2PdF0UM6g== Subject: Re: [dpdk-dev] [PATCH] net/mlx5: support modify field rte flow action 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 Sender: "dev" Hi, Alexander Please, see my minor comments below. Besides this:=20 Acked-by: Viacheslav Ovsiienko > -----Original Message----- > From: Alexander Kozyrev > Sent: Wednesday, January 27, 2021 4:49 > To: dev@dpdk.org > Cc: Raslan Darawsheh ; Slava Ovsiienko > ; Matan Azrad ; Ori Kam > > Subject: [PATCH] net/mlx5: support modify field rte flow action >=20 > Add support for new MODIFY_FIELD action to the Mellanox PMD. > This is the generic API that allows to manipulate any packet header field= by > copying data from another packet field or mark, metadata, tag, or immedia= te > value (or pointer to it). >=20 > Since the API is generic and covers a lot of action under its umbrella it= makes > sense to implement all the mechanics gradually in order to move to this A= PI > for any packet field manipulations in the future. This is first step of R= TE flows Typo: "the first" > consolidation. >=20 > The modify field RTE flow supports three operations: set, add and sub. Th= is Missed API|action? Should it be "The modify field RTE flow action support= s" ? > patch brings to live only the "set" operation. > Support is provided for any packet header field as well as meta/tag/mark = and > immediate value can be used as a source. >=20 > There are few limitations for this first version of API support: > - encapsulation levels are not supported, just outermost header can be > manipulated for now. > - offsets can only be 4-bytes aligned: 32, 64 and 96 for IPv6. > - the special ITEM_START ID is not supported as we do not allow to cross > packet header field boundaries yet. >=20 > Signed-off-by: Alexander Kozyrev > --- > drivers/net/mlx5/mlx5_flow.h | 4 +- > drivers/net/mlx5/mlx5_flow_dv.c | 507 > +++++++++++++++++++++++++++++++- > 2 files changed, 508 insertions(+), 3 deletions(-) >=20 mlx5 documentation update? release notes update? > diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h > index 2178a04e3a..6f6828c6a1 100644 > --- a/drivers/net/mlx5/mlx5_flow.h > +++ b/drivers/net/mlx5/mlx5_flow.h > @@ -219,6 +219,7 @@ enum mlx5_feature_name { #define > MLX5_FLOW_ACTION_SAMPLE (1ull << 36) #define > MLX5_FLOW_ACTION_TUNNEL_SET (1ull << 37) #define > MLX5_FLOW_ACTION_TUNNEL_MATCH (1ull << 38) > +#define MLX5_FLOW_ACTION_MODIFY_FIELD (1ull << 39) >=20 > #define MLX5_FLOW_FATE_ACTIONS \ > (MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | \ > @@ -249,7 +250,8 @@ enum mlx5_feature_name { > MLX5_FLOW_ACTION_MARK_EXT | \ > MLX5_FLOW_ACTION_SET_META | \ > MLX5_FLOW_ACTION_SET_IPV4_DSCP | \ > - MLX5_FLOW_ACTION_SET_IPV6_DSCP) > + MLX5_FLOW_ACTION_SET_IPV6_DSCP | \ > + MLX5_FLOW_ACTION_MODIFY_FIELD) >=20 > #define MLX5_FLOW_VLAN_ACTIONS (MLX5_FLOW_ACTION_OF_POP_VLAN > | \ > MLX5_FLOW_ACTION_OF_PUSH_VLAN) > diff --git a/drivers/net/mlx5/mlx5_flow_dv.c > b/drivers/net/mlx5/mlx5_flow_dv.c index 1a0c0be680..d842dc9887 100644 > --- a/drivers/net/mlx5/mlx5_flow_dv.c > +++ b/drivers/net/mlx5/mlx5_flow_dv.c > @@ -209,6 +209,8 @@ rte_col_2_mlx5_col(enum rte_color rcol) > return MLX5_FLOW_COLOR_UNDEFINED; > } >=20 > +#define MLX5DV_FLOW_MAX_MOD_FIELDS 5 Let's move to the mlx5_flow.h, closer to other #defines > + > struct field_modify_info { > uint32_t size; /* Size of field in protocol header, in bytes. */ > uint32_t offset; /* Offset of field in protocol header, in bytes. */ @@= - > 431,6 +433,9 @@ flow_dv_convert_modify_action(struct rte_flow_item > *item, > (int)dcopy->offset < 0 ? off_b : dcopy->offset; > /* Convert entire record to big-endian format. */ > actions[i].data1 =3D rte_cpu_to_be_32(actions[i].data1); > + ++dcopy; > + if (!dcopy) > + break; Sorry, I do not follow. dcopy is the structure pointer (we assume it points= to the array). How pointer can be NULL after update ++dcopy ? > } else { > MLX5_ASSERT(item->spec); > data =3D flow_dv_fetch_field((const uint8_t *)item- > >spec + @@ -1324,6 +1329,339 @@ > flow_dv_convert_action_modify_ipv6_dscp > MLX5_MODIFICATION_TYPE_SET, > error); } >=20 > +static void > +mlx5_flow_field_id_to_modify_info > + (const struct rte_flow_action_modify_data *data, > + struct field_modify_info *info, > + uint32_t *mask, uint32_t *value, > + struct rte_eth_dev *dev, > + const struct rte_flow_attr *attr, > + struct rte_flow_error *error) > +{ > + uint32_t idx =3D 0; > + switch (data->field) { > + case RTE_FLOW_FIELD_START: > + /* not supported yet */ > + break; Let's move to default? To catch validation gap?=20 > + case RTE_FLOW_FIELD_MAC_DST: > + if (mask) { > + info[idx] =3D (struct field_modify_info){4, 0, > + > MLX5_MODI_OUT_DMAC_47_16}; > + mask[idx] =3D (data->offset =3D=3D 32) ? 0x0 : 0xffffffff; With zero mask we could just skip the element here=20 (not critical - anyway, it will be dropped at conversion stage to HW action= s) > + ++idx; > + info[idx] =3D (struct field_modify_info){2, 4, > + > MLX5_MODI_OUT_DMAC_15_0}; > + mask[idx] =3D 0xffff0000; > + } else { > + if (!data->offset) > + info[idx++] =3D (struct field_modify_info){4, 0, > + > MLX5_MODI_OUT_DMAC_47_16}; > + info[idx] =3D (struct field_modify_info){2, 0, > + > MLX5_MODI_OUT_DMAC_15_0}; > + } > + break; > + case RTE_FLOW_FIELD_MAC_SRC: > + if (mask) { > + info[idx] =3D (struct field_modify_info){4, 0, > + > MLX5_MODI_OUT_SMAC_47_16}; > + mask[idx] =3D (data->offset =3D=3D 32) ? 0x0 : 0xffffffff; > + ++idx; > + info[idx] =3D (struct field_modify_info){2, 4, > + > MLX5_MODI_OUT_SMAC_15_0}; > + mask[idx] =3D 0xffff0000; > + } else { > + if (!data->offset) > + info[idx++] =3D (struct field_modify_info){4, 0, > + > MLX5_MODI_OUT_SMAC_47_16}; > + info[idx] =3D (struct field_modify_info){2, 0, > + > MLX5_MODI_OUT_SMAC_15_0}; > + } > + break; > + case RTE_FLOW_FIELD_VLAN_TYPE: > + /* not supported yet */ > + break; > + case RTE_FLOW_FIELD_VLAN_ID: > + info[idx] =3D (struct field_modify_info){2, 0, > + MLX5_MODI_OUT_FIRST_VID}; > + if (mask) > + mask[idx] =3D 0xfffff000; > + break; > + case RTE_FLOW_FIELD_MAC_TYPE: > + info[idx] =3D (struct field_modify_info){2, 0, > + MLX5_MODI_OUT_ETHERTYPE}; > + if (mask) > + mask[idx] =3D 0xffff0000; > + break; > + case RTE_FLOW_FIELD_IPV4_DSCP: > + info[idx] =3D (struct field_modify_info){1, 0, > + MLX5_MODI_OUT_IP_DSCP}; > + if (mask) > + mask[idx] =3D 0xfc000000; > + break; > + case RTE_FLOW_FIELD_IPV4_TTL: > + info[idx] =3D (struct field_modify_info){1, 0, > + MLX5_MODI_OUT_IPV4_TTL}; > + if (mask) > + mask[idx] =3D 0xff000000; > + break; > + case RTE_FLOW_FIELD_IPV4_SRC: > + info[idx] =3D (struct field_modify_info){4, 0, > + MLX5_MODI_OUT_SIPV4}; > + if (mask) > + mask[idx] =3D 0xffffffff; > + break; > + case RTE_FLOW_FIELD_IPV4_DST: > + info[idx] =3D (struct field_modify_info){4, 0, > + MLX5_MODI_OUT_DIPV4}; > + if (mask) > + mask[idx] =3D 0xffffffff; > + break; > + case RTE_FLOW_FIELD_IPV6_HOPLIMIT: > + info[idx] =3D (struct field_modify_info){1, 0, > + MLX5_MODI_OUT_IPV6_HOPLIMIT}; > + if (mask) > + mask[idx] =3D 0xff000000; > + break; > + case RTE_FLOW_FIELD_IPV6_SRC: > + if (mask) { > + info[idx] =3D (struct field_modify_info){4, 0, > + > MLX5_MODI_OUT_SIPV6_127_96}; > + mask[idx] =3D (data->offset >=3D 32) ? 0x0 : 0xffffffff; > + ++idx; > + info[idx] =3D (struct field_modify_info){4, 4, > + > MLX5_MODI_OUT_SIPV6_95_64}; > + mask[idx] =3D (data->offset >=3D 64) ? 0x0 : 0xffffffff; > + ++idx; > + info[idx] =3D (struct field_modify_info){4, 8, > + > MLX5_MODI_OUT_SIPV6_63_32}; > + mask[idx] =3D (data->offset >=3D 96) ? 0x0 : 0xffffffff; > + ++idx; > + info[idx] =3D (struct field_modify_info){4, 12, > + > MLX5_MODI_OUT_SIPV6_31_0}; > + mask[idx] =3D 0xffffffff; > + } else { > + if (data->offset < 32) > + info[idx++] =3D (struct field_modify_info){4, 0, > + > MLX5_MODI_OUT_SIPV6_127_96}; > + if (data->offset < 64) > + info[idx++] =3D (struct field_modify_info){4, 0, > + > MLX5_MODI_OUT_SIPV6_95_64}; > + if (data->offset < 96) > + info[idx++] =3D (struct field_modify_info){4, 0, > + > MLX5_MODI_OUT_SIPV6_63_32}; > + if (data->offset < 128) > + info[idx++] =3D (struct field_modify_info){4, 0, > + > MLX5_MODI_OUT_SIPV6_31_0}; > + } > + break; > + case RTE_FLOW_FIELD_IPV6_DST: > + if (mask) { > + info[idx] =3D (struct field_modify_info){4, 0, > + > MLX5_MODI_OUT_DIPV6_127_96}; > + mask[idx] =3D (data->offset >=3D 32) ? 0x0 : 0xffffffff; > + ++idx; > + info[idx] =3D (struct field_modify_info){4, 4, > + > MLX5_MODI_OUT_DIPV6_95_64}; > + mask[idx] =3D (data->offset >=3D 64) ? 0x0 : 0xffffffff; > + ++idx; > + info[idx] =3D (struct field_modify_info){4, 8, > + > MLX5_MODI_OUT_DIPV6_63_32}; > + mask[idx] =3D (data->offset >=3D 96) ? 0x0 : 0xffffffff; > + ++idx; > + info[idx] =3D (struct field_modify_info){4, 12, > + > MLX5_MODI_OUT_DIPV6_31_0}; > + mask[idx] =3D 0xffffffff; > + } else { > + if (data->offset < 32) > + info[idx++] =3D (struct field_modify_info){4, 0, > + > MLX5_MODI_OUT_DIPV6_127_96}; > + if (data->offset < 64) > + info[idx++] =3D (struct field_modify_info){4, 0, > + > MLX5_MODI_OUT_DIPV6_95_64}; > + if (data->offset < 96) > + info[idx++] =3D (struct field_modify_info){4, 0, > + > MLX5_MODI_OUT_DIPV6_63_32}; > + if (data->offset < 128) > + info[idx++] =3D (struct field_modify_info){4, 0, > + > MLX5_MODI_OUT_DIPV6_31_0}; > + } > + break; > + case RTE_FLOW_FIELD_TCP_PORT_SRC: > + info[idx] =3D (struct field_modify_info){2, 0, > + MLX5_MODI_OUT_TCP_SPORT}; > + if (mask) > + mask[idx] =3D 0xffff0000; > + break; > + case RTE_FLOW_FIELD_TCP_PORT_DST: > + info[idx] =3D (struct field_modify_info){2, 0, > + MLX5_MODI_OUT_TCP_DPORT}; > + if (mask) > + mask[idx] =3D 0xffff0000; > + break; > + case RTE_FLOW_FIELD_TCP_SEQ_NUM: > + info[idx] =3D (struct field_modify_info){4, 0, > + MLX5_MODI_OUT_TCP_SEQ_NUM}; > + if (mask) > + mask[idx] =3D 0xffffffff; > + break; > + case RTE_FLOW_FIELD_TCP_ACK_NUM: > + info[idx] =3D (struct field_modify_info){4, 0, > + MLX5_MODI_OUT_TCP_ACK_NUM}; > + if (mask) > + mask[idx] =3D 0xffffffff; > + break; > + case RTE_FLOW_FIELD_TCP_FLAGS: > + info[idx] =3D (struct field_modify_info){1, 0, > + MLX5_MODI_IN_TCP_FLAGS}; > + if (mask) > + mask[idx] =3D 0xfc000000; > + break; > + case RTE_FLOW_FIELD_UDP_PORT_SRC: > + info[idx] =3D (struct field_modify_info){2, 0, > + MLX5_MODI_OUT_UDP_SPORT}; > + if (mask) > + mask[idx] =3D 0xffff0000; > + break; > + case RTE_FLOW_FIELD_UDP_PORT_DST: > + info[idx] =3D (struct field_modify_info){2, 0, > + MLX5_MODI_OUT_UDP_DPORT}; > + if (mask) > + mask[idx] =3D 0xffff0000; > + break; > + case RTE_FLOW_FIELD_VXLAN_VNI: > + /* not supported yet */ > + break; > + case RTE_FLOW_FIELD_GENEVE_VNI: > + /* not supported yet*/ > + break; > + case RTE_FLOW_FIELD_GTP_TEID: > + info[idx] =3D (struct field_modify_info){4, 0, 0x6E}; > + if (mask) > + mask[idx] =3D 0xffffffff; > + break; > + case RTE_FLOW_FIELD_TAG: > + { > + int ret; > + enum mlx5_modification_field reg_type; > + ret =3D mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, > + data->level, error); > + if (ret < 0) > + return; > + MLX5_ASSERT(ret !=3D REG_NON); > + MLX5_ASSERT((unsigned int)ret < > RTE_DIM(reg_to_field)); > + reg_type =3D reg_to_field[ret]; > + MLX5_ASSERT(reg_type > 0); > + info[idx] =3D (struct field_modify_info){4, 0, reg_type}; > + if (mask) > + mask[idx] =3D 0xffffffff; > + } > + break; > + case RTE_FLOW_FIELD_MARK: > + { > + int reg =3D mlx5_flow_get_reg_id(dev, > MLX5_FLOW_MARK, > + 0, error); > + if (reg < 0) > + return; > + MLX5_ASSERT(reg > 0); > + info[idx] =3D (struct field_modify_info){4, 0, > + reg_to_field[reg]}; > + if (mask) > + mask[idx] =3D 0xffffffff; > + } > + break; > + case RTE_FLOW_FIELD_META: > + { > + int reg =3D flow_dv_get_metadata_reg(dev, attr, error); > + if (reg < 0) > + return; > + MLX5_ASSERT(reg !=3D REG_NON); > + info[idx] =3D (struct field_modify_info){4, 0, > + reg_to_field[reg]}; > + if (mask) > + mask[idx] =3D 0xffffffff; > + } > + break; > + case RTE_FLOW_FIELD_POINTER: > + for (idx =3D 0; idx < MLX5DV_FLOW_MAX_MOD_FIELDS; idx++) { > + if (mask[idx]) { > + value[idx] =3D RTE_BE32(*(uint64_t *)data- > >value); > + break; > + } > + } > + case RTE_FLOW_FIELD_VALUE: > + for (idx =3D 0; idx < MLX5DV_FLOW_MAX_MOD_FIELDS; idx++) { > + if (mask[idx]) { > + value[idx] =3D RTE_BE32(data->value); > + break; > + } > + } > + break; > + default: > + MLX5_ASSERT(false); > + break; > + } > +} > + > +/** > + * Convert modify_field action to DV specification. > + * > + * @param[in] dev > + * Pointer to the rte_eth_dev structure. > + * @param[in,out] resource > + * Pointer to the modify-header resource. > + * @param[in] action > + * Pointer to action specification. > + * @param[in] attr > + * Attributes of flow that includes this item. > + * @param[out] error > + * Pointer to the error structure. > + * > + * @return > + * 0 on success, a negative errno value otherwise and rte_errno is set= . > + */ > +static int > +flow_dv_convert_action_modify_field > + (struct rte_eth_dev *dev, > + struct mlx5_flow_dv_modify_hdr_resource > *resource, > + const struct rte_flow_action *action, > + const struct rte_flow_attr *attr, > + struct rte_flow_error *error) > +{ > + const struct rte_flow_action_modify_field *conf =3D > + (const struct rte_flow_action_modify_field *)(action->conf); > + struct rte_flow_item item; > + struct field_modify_info field[MLX5DV_FLOW_MAX_MOD_FIELDS] =3D { > + {0, 0, 0} }; > + struct field_modify_info dcopy[MLX5DV_FLOW_MAX_MOD_FIELDS] > =3D { > + {0, 0, 0} }; > + uint32_t mask[MLX5DV_FLOW_MAX_MOD_FIELDS] =3D {0, 0, 0, 0, 0}; > + uint32_t value[MLX5DV_FLOW_MAX_MOD_FIELDS] =3D {0, 0, 0, 0, 0}; > + uint32_t type; > + > + if (conf->src.field =3D=3D RTE_FLOW_FIELD_POINTER || > + conf->src.field =3D=3D RTE_FLOW_FIELD_VALUE) { > + type =3D MLX5_MODIFICATION_TYPE_SET; > + /** For SET fill the destination field (field) first. */ > + mlx5_flow_field_id_to_modify_info(&conf->dst, field, mask, > + value, dev, attr, error); > + /** Then copy immediate value from source as per mask. */ > + mlx5_flow_field_id_to_modify_info(&conf->src, dcopy, mask, > + value, dev, attr, error); > + item.spec =3D &value; > + } else { > + type =3D MLX5_MODIFICATION_TYPE_COPY; > + /** For COPY fill the destination field (dcopy) without mask. > */ > + mlx5_flow_field_id_to_modify_info(&conf->dst, dcopy, NULL, > + value, dev, attr, error); > + /** Then cnstruct th source field (field) with mask. */ Typos: construct th > + mlx5_flow_field_id_to_modify_info(&conf->src, field, mask, > + value, dev, attr, error); > + } > + item.mask =3D &mask; > + return flow_dv_convert_modify_action(&item, > + field, dcopy, resource, type, error); } > + > /** > * Validate MARK item. > * > @@ -3985,6 +4323,148 @@ flow_dv_validate_action_modify_ttl(const > uint64_t action_flags, > return ret; > } >=20 > +static int > +mlx5_flow_item_field_width(enum rte_flow_field_id field) { > + switch (field) { > + case RTE_FLOW_FIELD_START: > + return 32; > + case RTE_FLOW_FIELD_MAC_DST: > + case RTE_FLOW_FIELD_MAC_SRC: > + return 48; > + case RTE_FLOW_FIELD_VLAN_TYPE: > + return 16; > + case RTE_FLOW_FIELD_VLAN_ID: > + return 12; > + case RTE_FLOW_FIELD_MAC_TYPE: > + return 16; > + case RTE_FLOW_FIELD_IPV4_DSCP: > + case RTE_FLOW_FIELD_IPV4_TTL: > + return 8; > + case RTE_FLOW_FIELD_IPV4_SRC: > + case RTE_FLOW_FIELD_IPV4_DST: > + return 32; > + case RTE_FLOW_FIELD_IPV6_HOPLIMIT: > + return 8; > + case RTE_FLOW_FIELD_IPV6_SRC: > + case RTE_FLOW_FIELD_IPV6_DST: > + return 128; > + case RTE_FLOW_FIELD_TCP_PORT_SRC: > + case RTE_FLOW_FIELD_TCP_PORT_DST: > + return 16; > + case RTE_FLOW_FIELD_TCP_SEQ_NUM: > + case RTE_FLOW_FIELD_TCP_ACK_NUM: > + return 32; > + case RTE_FLOW_FIELD_TCP_FLAGS: > + return 6; > + case RTE_FLOW_FIELD_UDP_PORT_SRC: > + case RTE_FLOW_FIELD_UDP_PORT_DST: > + return 16; > + case RTE_FLOW_FIELD_VXLAN_VNI: > + case RTE_FLOW_FIELD_GENEVE_VNI: > + return 24; > + case RTE_FLOW_FIELD_GTP_TEID: > + case RTE_FLOW_FIELD_TAG: > + case RTE_FLOW_FIELD_MARK: > + case RTE_FLOW_FIELD_META: > + case RTE_FLOW_FIELD_POINTER: > + case RTE_FLOW_FIELD_VALUE: > + return 32; > + default: > + MLX5_ASSERT(false); > + } > + return 0; > +} > + > +/** > + * Validate the generic modify field actions. > + * > + * @param[in] action_flags > + * Holds the actions detected until now. > + * @param[in] action > + * Pointer to the modify action. > + * @param[in] item_flags > + * Holds the items detected. > + * @param[out] error > + * Pointer to error structure. > + * > + * @return > + * Number of header fields to modify (0 or more) on success, > + * a negative errno value otherwise and rte_errno is set. > + */ > +static int > +flow_dv_validate_action_modify_field(const uint64_t action_flags, > + const struct rte_flow_action *action, > + struct rte_flow_error *error) > +{ > + int ret =3D 0; > + const struct rte_flow_action_modify_field *action_modify_field =3D > + action->conf; > + uint32_t dst_width =3D > + mlx5_flow_item_field_width(action_modify_field->dst.field); > + uint32_t src_width =3D > + mlx5_flow_item_field_width(action_modify_field->src.field); > + > + ret =3D flow_dv_validate_action_modify_hdr(action_flags, action, > error); > + if (ret) > + return ret; > + > + if (action_modify_field->src.field !=3D RTE_FLOW_FIELD_VALUE && > + action_modify_field->src.field !=3D RTE_FLOW_FIELD_POINTER) { > + if (action_modify_field->dst.offset >=3D dst_width || > + (action_modify_field->dst.offset % 32) || > + action_modify_field->src.offset >=3D src_width || > + (action_modify_field->src.offset % 32)) > + return rte_flow_error_set(error, EINVAL, > + > RTE_FLOW_ERROR_TYPE_ACTION, > + NULL, > + "offset is too big" > + " or not aligned to 4 bytes"); > + if ((action_modify_field->dst.level && > + action_modify_field->dst.field !=3D RTE_FLOW_FIELD_TAG) > || > + (action_modify_field->src.level && > + action_modify_field->src.field !=3D RTE_FLOW_FIELD_TAG)) > + return rte_flow_error_set(error, EINVAL, > + > RTE_FLOW_ERROR_TYPE_ACTION, > + NULL, > + "inner header modifications" > + " are not supported"); > + } > + if (action_modify_field->width =3D=3D 0) > + return rte_flow_error_set(error, EINVAL, > + > RTE_FLOW_ERROR_TYPE_ACTION, > + NULL, > + "width is required for modify > action"); > + if (action_modify_field->dst.field =3D=3D > + action_modify_field->src.field) > + return rte_flow_error_set(error, EINVAL, > + RTE_FLOW_ERROR_TYPE_ACTION, > + NULL, > + "source and destination fields" > + " cannot be the same"); > + if (action_modify_field->dst.field =3D=3D RTE_FLOW_FIELD_VALUE || > + action_modify_field->dst.field =3D=3D RTE_FLOW_FIELD_POINTER) > + return rte_flow_error_set(error, EINVAL, > + RTE_FLOW_ERROR_TYPE_ACTION, > + NULL, > + "immediate value or a pointer to it" > + " cannot be used as a destination"); > + if (action_modify_field->dst.field =3D=3D RTE_FLOW_FIELD_START) > + return rte_flow_error_set(error, EINVAL, > + RTE_FLOW_ERROR_TYPE_ACTION, > + NULL, > + "modifications of an arbitrary" > + " place in a packet is not supported"); > + if (action_modify_field->operation !=3D RTE_FLOW_MODIFY_SET) > + return rte_flow_error_set(error, EINVAL, > + RTE_FLOW_ERROR_TYPE_ACTION, > + NULL, > + "add and sub operations" > + " are not supported"); > + return (action_modify_field->width / 32) + > + !!(action_modify_field->width % 32); } > + > /** > * Validate jump action. > * > @@ -5373,7 +5853,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const > struct rte_flow_attr *attr, > struct mlx5_dev_config *dev_conf =3D &priv->config; > uint16_t queue_index =3D 0xFFFF; > const struct rte_flow_item_vlan *vlan_m =3D NULL; > - int16_t rw_act_num =3D 0; > + uint32_t rw_act_num =3D 0; > uint64_t is_root; > const struct mlx5_flow_tunnel *tunnel; > struct flow_grp_info grp_info =3D { > @@ -6169,6 +6649,23 @@ flow_dv_validate(struct rte_eth_dev *dev, const > struct rte_flow_attr *attr, >=20 > action_flags |=3D MLX5_FLOW_ACTION_TUNNEL_SET; > break; > + case RTE_FLOW_ACTION_TYPE_MODIFY_FIELD: > + if (!attr->transfer && !attr->group) > + return rte_flow_error_set(error, ENOTSUP, > + > RTE_FLOW_ERROR_TYPE_ACTION, > + NULL, "modify field action " > + "is not supported for group > 0"); > + ret =3D > flow_dv_validate_action_modify_field(action_flags, > + actions, > + error); > + if (ret < 0) > + return ret; > + /* Count all modify-header actions as one action. */ > + if (!(action_flags & > MLX5_FLOW_ACTION_MODIFY_FIELD)) > + ++actions_n; > + action_flags |=3D > MLX5_FLOW_ACTION_MODIFY_FIELD; > + rw_act_num +=3D ret; > + break; > default: > return rte_flow_error_set(error, ENOTSUP, >=20 > RTE_FLOW_ERROR_TYPE_ACTION, > @@ -6326,7 +6823,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const > struct rte_flow_attr *attr, > dev_conf->dv_xmeta_en !=3D MLX5_XMETA_MODE_LEGACY && > mlx5_flow_ext_mreg_supported(dev)) > rw_act_num +=3D MLX5_ACT_NUM_SET_TAG; > - if ((uint32_t)rw_act_num > > + if (rw_act_num > > flow_dv_modify_hdr_action_max(dev, is_root)) { > return rte_flow_error_set(error, ENOTSUP, > RTE_FLOW_ERROR_TYPE_ACTION, > @@ -10686,6 +11183,12 @@ flow_dv_translate(struct rte_eth_dev *dev, > sample_act->action_flags |=3D >=20 > MLX5_FLOW_ACTION_ENCAP; > break; > + case RTE_FLOW_ACTION_TYPE_MODIFY_FIELD: > + if (flow_dv_convert_action_modify_field > + (dev, mhdr_res, actions, attr, error)) > + return -rte_errno; > + action_flags |=3D > MLX5_FLOW_ACTION_MODIFY_FIELD; > + break; > case RTE_FLOW_ACTION_TYPE_END: > actions_end =3D true; > if (mhdr_res->actions_num) { > -- > 2.24.1