From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id B44DA4256B;
	Mon, 11 Sep 2023 08:24:23 +0200 (CEST)
Received: from mails.dpdk.org (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id 35B18402C1;
	Mon, 11 Sep 2023 08:24:23 +0200 (CEST)
Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.31])
 by mails.dpdk.org (Postfix) with ESMTP id 0858D4026A
 for <dev@dpdk.org>; Mon, 11 Sep 2023 08:24:20 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple;
 d=intel.com; i=@intel.com; q=dns/txt; s=Intel;
 t=1694413461; x=1725949461;
 h=from:to:cc:subject:date:message-id:references:
 in-reply-to:content-transfer-encoding:mime-version;
 bh=/iCwe2guWEGKA/OwOJe+vFIun7+d78Tkk2n26RpxHxQ=;
 b=iZAnWVcGamjGDhHMqpdsEnjxes2/1NJDnPdqPjWqpHlNLaxlQl13eLsJ
 DDN6OwS0QERRX6KSIHsATPknQkzmW+ivGcnRsJc8DoteM8Aji2YIsWMsQ
 ICbTFTZUZ5ypWoM/tLI+NxuuI0UmBUM1KatElNydPdOTxT7tZiZceYazN
 s9TMHHGo3pwfK9+jSw08PvUywPMu73ovlO6d1LE8u15WrG0UoWG6FBREw
 frpOLXOPEZB0pef2R+TGyTsEgG+2Wh+unJgOVuuQVv8dyq+S9EVB/26qC
 DZpPzvUO7qg4gg38Xk0DLAcm+DT1DEMLgnDDFjBsKrEg9uunxDObFj8SA Q==;
X-IronPort-AV: E=McAfee;i="6600,9927,10829"; a="442000345"
X-IronPort-AV: E=Sophos;i="6.02,243,1688454000"; d="scan'208";a="442000345"
Received: from orsmga008.jf.intel.com ([10.7.209.65])
 by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;
 10 Sep 2023 23:24:19 -0700
X-ExtLoop1: 1
X-IronPort-AV: E=McAfee;i="6600,9927,10829"; a="772463954"
X-IronPort-AV: E=Sophos;i="6.02,243,1688454000"; d="scan'208";a="772463954"
Received: from orsmsx603.amr.corp.intel.com ([10.22.229.16])
 by orsmga008.jf.intel.com with ESMTP/TLS/AES256-GCM-SHA384;
 10 Sep 2023 23:24:19 -0700
Received: from orsmsx603.amr.corp.intel.com (10.22.229.16) by
 ORSMSX603.amr.corp.intel.com (10.22.229.16) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id
 15.1.2507.32; Sun, 10 Sep 2023 23:24:19 -0700
Received: from ORSEDG602.ED.cps.intel.com (10.7.248.7) by
 orsmsx603.amr.corp.intel.com (10.22.229.16) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id
 15.1.2507.32 via Frontend Transport; Sun, 10 Sep 2023 23:24:19 -0700
Received: from NAM02-DM3-obe.outbound.protection.outlook.com (104.47.56.45) by
 edgegateway.intel.com (134.134.137.103) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.1.2507.32; Sun, 10 Sep 2023 23:24:18 -0700
ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;
 b=Fx0IIQkceGUTRiUZFY7f35vffGB9m938HflYoq6DuCidi5bCxidpKhW4MCD7OG0CZlYv8fZ1QurCSnfsrOK+t3lgUyiY5mZ55V0mYch3vjJeIv2EKYL1ZvC7ZtBFDrCV0iaTStRXbFbXPgg2s8NJICB9hewgXrNEn+TMYRhvGhDcu72ewCXCJHvRKHDbjShl44SY2q+UB+J0NTq7oSUGlqmIDq2wmXuNdifFVZ8Fn0G0BsmbQqnMGPsm1aCHSLugyla9DXN1FDDAPUk1YaJ3N4mbrhDXfebj64eeSwdmyjus0jeRnHNvoK4xxWyeIZKgrTWmtmRd/qxODOhASm02rA==
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=Pfjo4F8SrlZBsK/1MoFxgLtjTZ46xUMAKSjYFBcGHIo=;
 b=XwzsxpD5H8HYurUqxBRK1l67kKW5ar/3+WnTMQPqcz8NQhlUA5VJkfCzw/SyTo2z9Jz9O1FtIuhbcgmmFhYlqsLGMlcBl09upddKEmdLZVWwsDgB1krpluBIbjHPJv9RhOk3f2vAs3uE3Jvq+S3Shq/eVDj5xGe5SoIexQ0EF+YDAoZLnEG69vJ/mmT3jGFU8cNwpssO5DXOpecCZ2/cPwTk3IyYZMVEmWKheUybpG5nGD9O5gbGa0ybodJHnYg1mxXbJ3SBDRMn3hfFcLh3I/4kJWz2jeFTMTw4c/h1ohl6jFP9UCCRcGiay4uGjJzNyfHHhM73E5kChtV5kwXS5g==
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass
 smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com;
 dkim=pass header.d=intel.com; arc=none
Received: from MW3PR11MB4587.namprd11.prod.outlook.com (2603:10b6:303:58::7)
 by SJ1PR11MB6081.namprd11.prod.outlook.com (2603:10b6:a03:48c::5) with
 Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6768.31; Mon, 11 Sep
 2023 06:24:15 +0000
Received: from MW3PR11MB4587.namprd11.prod.outlook.com
 ([fe80::2ca6:1915:b67c:139]) by MW3PR11MB4587.namprd11.prod.outlook.com
 ([fe80::2ca6:1915:b67c:139%6]) with mapi id 15.20.6768.029; Mon, 11 Sep 2023
 06:24:15 +0000
From: "Wu, Jingjing" <jingjing.wu@intel.com>
To: "Qiao, Wenjing" <wenjing.qiao@intel.com>, "Zhang, Yuying"
 <yuying.zhang@intel.com>, "dev@dpdk.org" <dev@dpdk.org>, "Zhang, Qi Z"
 <qi.z.zhang@intel.com>, "Xing, Beilei" <beilei.xing@intel.com>
CC: "Liu, Mingxia" <mingxia.liu@intel.com>
Subject: RE: [PATCH v3 2/9] net/cpfl: add flow json parser
Thread-Topic: [PATCH v3 2/9] net/cpfl: add flow json parser
Thread-Index: AQHZ4KVW8OjNBAVkzkinRZX2ffvYNbAU3Iiw
Date: Mon, 11 Sep 2023 06:24:15 +0000
Message-ID: <MW3PR11MB45873285667F041C033E1A0CE3F2A@MW3PR11MB4587.namprd11.prod.outlook.com>
References: <20230901113158.1654044-1-yuying.zhang@intel.com>
 <20230906093407.3635038-1-wenjing.qiao@intel.com>
 <20230906093407.3635038-3-wenjing.qiao@intel.com>
In-Reply-To: <20230906093407.3635038-3-wenjing.qiao@intel.com>
Accept-Language: en-US
Content-Language: en-US
X-MS-Has-Attach: 
X-MS-TNEF-Correlator: 
authentication-results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=intel.com;
x-ms-publictraffictype: Email
x-ms-traffictypediagnostic: MW3PR11MB4587:EE_|SJ1PR11MB6081:EE_
x-ms-office365-filtering-correlation-id: 1904700d-3a06-41d1-7819-08dbb28fb91f
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam: BCL:0;
x-microsoft-antispam-message-info: 2J4fE5Pa3cUiaKcroB2L2dMD4MIaszScfq9QW+GPCbQlCBzZ2kpaSCEqF/M9YO2b9OO/j8RiEoq6cM1vYDqfIx2gpEoO7bUJfAKJEe6I4KR57X15fQnodVelqQylbXm4kuuODwV3biCi1p6l5rCmyDCiPI6x+cFWgfw0yGTdeqjroigJY68P72qtTC/+Ld3ztmZK/bsPAUL2PrUcfUD5lKcqS90hCEtrFCWIc3cZ50koLbTcmDzne4+q59WyEiyIm47L8vobCTT56EF9dI9JoSSkvZHTeLtAkoKp/R3EFEMW2u7S8SMP6KHlgOwdph+6cqiKJ4L3k4LxeydzWXmOI3v3bP7zfuZaPtU8RMM2HzI7lWFxKH4rJyROcMqShrDhXHamQsshGRwZDNMe2+19x669u/o8zuzHPLLnX/k4Nt5vYhl/q3MPmFI0FAdqnLcrnNa7fY98m+EHHAuEOo+388NrNtDg7odZ7ouiz/GCeaN7PW6buCOjaTdCM6fapBR1iMHUfbAio2O0aIRqvQvjtALYHRSzJ7qqD2GBDpVBLBG4lM8EeiLaKQQM62fdSJGl28PXxOEaE2uV92312kNeFPmbOCnv6pqIlT60hE/JF7qzThv4Yh6vfRU/gywa7ksD
x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;
 IPV:NLI; SFV:NSPM; H:MW3PR11MB4587.namprd11.prod.outlook.com; PTR:; CAT:NONE;
 SFS:(13230031)(39860400002)(366004)(396003)(136003)(346002)(376002)(1800799009)(186009)(451199024)(82960400001)(9686003)(55016003)(122000001)(38100700002)(86362001)(110136005)(71200400001)(7696005)(478600001)(6506007)(38070700005)(26005)(8676002)(5660300002)(52536014)(4326008)(8936002)(316002)(76116006)(6636002)(66476007)(66446008)(64756008)(66946007)(33656002)(66556008)(41300700001)(30864003)(2906002)(107886003)(579004);
 DIR:OUT; SFP:1102; 
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?7V5iLCaDW6xq7db2tlmleQLXJLqF7RB9nL69ptNZH4RXBXwwvaTG2djxdn9N?=
 =?us-ascii?Q?pH+l7HuyqOQFPb0KA5w39WDIS9pFpz1H+JaEkvml7X2fY3Rn4f8eDYYq76Jp?=
 =?us-ascii?Q?lLxYtxJCQ69KmLFEqzf2i+eLlExSxhRBIqwcGbbYom5o1WYTk1huSNVkD9cT?=
 =?us-ascii?Q?mh0vmFR51winzYU+dNrEgfhHgBNo6kfkzt4EZrMwWQ63Uss/4uKYmVR/mRUa?=
 =?us-ascii?Q?fVqRKgNPwNtCkObvLtgomKUAeiiCumihyfE6wJpxwd1JKqM0ogXQmAvQtZ2e?=
 =?us-ascii?Q?TGpzoFEeoUKQf7L78c8rW2qKwMpezBOnWbs9FHia1sGXoT30iRHgC7S+dqng?=
 =?us-ascii?Q?HhkC2QQqspjTcInQGqLv7/5+7KE+QS0op9+CoGtcLyENcpwCUzhuvqtUoxNp?=
 =?us-ascii?Q?qvH1NnD8lO7BctJj66zNvT1bE/hUNh4fPtO32vdV74jtBPo+bCdwE9pBUluJ?=
 =?us-ascii?Q?ozt6rzPnaAlzEULmM5MPgOQ5ja2Uz9vUIGpqcozo1XUNToE8R7m005ELBrH2?=
 =?us-ascii?Q?eKyhQ8vnK/ZBrCHJ1UREKgnuS/c99y+EX89bfgLZNAckLweYdmoTSGSJnXyC?=
 =?us-ascii?Q?4IDAsAUU6jHd3wiI0KYwzYZx54gJvpPhDNdeAovgY+scYHYF8nH/fr5Ob4Zx?=
 =?us-ascii?Q?Q387MwBkyYhHA8VrVrBKvA7pjnUgk2hvS5rh7HmyjnetJHe4rNpMlSvQzgGO?=
 =?us-ascii?Q?6x/1GDoOQI5j3mbMwbmbSY5KuAfuEMmyzdW+q69kfxHNNLiIxuMDTePJkdBN?=
 =?us-ascii?Q?mOaJM2T/WB3kG1vgSGCyGKfSMj0m/Bt0ARjawbFgQPNO5Hq9+Fx5n4ZHswGy?=
 =?us-ascii?Q?mc3sP/47Wwj0ZIORvnYctSpuJuhUJahgt1YwBl6W8jrvdLq8rfgcapAXuXEr?=
 =?us-ascii?Q?GfDUe9j82at/WQic/WFKyNJveKb7BPGrtEEMn3VOOCuaQavYwebjPDkyAuLs?=
 =?us-ascii?Q?Af7tIPLuq9ImG1XeY2Qa2eBunYh0pNe3EDcRwgkyjJUAWoIJtjuRyFi66mSs?=
 =?us-ascii?Q?Glmau7fskkB9tIKOCXIqsOuZd7hu3OQ85hBQc9wr8URkqqJRdEV3OzxRkF45?=
 =?us-ascii?Q?TrtWzhNpJynkNGBGf9B+dkxkVkGGI3rCtgbJuBpeBLY/ulwzTWoFbU3bhh4T?=
 =?us-ascii?Q?0zXlTYwRsKopzQD50i/F+P6ObZoM5piDKdyPrKIYPJG9POSbuW3QWy3ic4P9?=
 =?us-ascii?Q?bD9/xewPbeKJ56bPnYrGor+U6BbLrMFGM3OZLEfNua/sbN3s8/Rs1WF7Tc+h?=
 =?us-ascii?Q?wBaO2kxVPViADHv4l0iqFM0+MUMG4eo2MKPBTVOpueT2LHO12tvWSCKwGzWW?=
 =?us-ascii?Q?uW6wWZBtGLsTVWPA+YOi0IowCfXrkmhS4UVSsgUAGlQvyZrnhnOWN/7s1pxk?=
 =?us-ascii?Q?bUrGN8HCSdk4hepL1K90bPDSYwXipu8vkw+4xJYcF0/WwuBsl1brZyOwaLn+?=
 =?us-ascii?Q?9TMJIhbdOOmPyeFMvLJuPZLHXfidqA3MdCvNYSvm7jYZt4wtNri8TXBGYCVY?=
 =?us-ascii?Q?qbvI/OJyFrryRD2dqJ1a9+h9ylz+4xUWWdyIs7Q79RJy8Qn8YKm1BJLGF5kx?=
 =?us-ascii?Q?N/JTiMc5K75li2Bw/tHXz6GWraspbHes8rS7WRYP?=
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: MW3PR11MB4587.namprd11.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: 1904700d-3a06-41d1-7819-08dbb28fb91f
X-MS-Exchange-CrossTenant-originalarrivaltime: 11 Sep 2023 06:24:15.8427 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: aw786DposzBmfpbAegiUPjn91NRea19PCnc8RiVm4OI4eQ9gh8+pFcBBsFOMDwOkiXHm7nkvE6y0YckIUcFynw==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ1PR11MB6081
X-OriginatorOrg: intel.com
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org

> +static int
> +cpfl_json_object_to_int(json_object *object, const char *name, int *valu=
e)
> +{
> +	json_object *subobject;
> +
> +	if (!object) {
> +		PMD_DRV_LOG(ERR, "object doesn't exist.");
> +		return -EINVAL;
> +	}
> +	subobject =3D json_object_object_get(object, name);
> +	if (!subobject) {
> +		PMD_DRV_LOG(ERR, "%s doesn't exist.", name);
> +		return -EINVAL;
> +	}
> +	*value =3D json_object_get_int(subobject);
> +
> +	return 0;
> +}
> +
> +static int
> +cpfl_json_object_to_uint16(json_object *object, const char *name, uint16=
_t
> *value)
> +{
Looks no need to define a new function as there is no difference with cpfl_=
json_object_to_int func beside the type of return value.
[...]

> +
> +static int
> +cpfl_flow_js_pattern_key_proto_field(json_object *cjson_field,
> +				     struct cpfl_flow_js_pr_key_proto *js_field)
> +{
> +	int len, i;
> +
> +	if (!cjson_field)
> +		return 0;
> +	len =3D json_object_array_length(cjson_field);
> +	js_field->fields_size =3D len;
> +	if (len =3D=3D 0)
Move if check above, before set js_field->fields_size?

> +		return 0;
> +	js_field->fields =3D
> +	    rte_malloc(NULL, sizeof(struct cpfl_flow_js_pr_key_proto_field) *
> len, 0);
> +	if (!js_field->fields) {
> +		PMD_DRV_LOG(ERR, "Failed to alloc memory.");
> +		return -ENOMEM;
> +	}
> +	for (i =3D 0; i < len; i++) {
> +		json_object *object;
> +		const char *name, *mask;
> +
> +		object =3D json_object_array_get_idx(cjson_field, i);
> +		name =3D cpfl_json_object_to_string(object, "name");
> +		if (!name) {
> +			PMD_DRV_LOG(ERR, "Can not parse string 'name'.");
> +			goto err;
> +		}
> +		if (strlen(name) > CPFL_FLOW_JSON_STR_SIZE_MAX) {
> +			PMD_DRV_LOG(ERR, "The 'name' is too long.");
> +			goto err;
> +		}
> +		memcpy(js_field->fields[i].name, name, strlen(name));
Is js_field->fields[i].name zeroed? If not, using strlen() cannot guarantee=
 string copy correct.=20

> +		if (js_field->type =3D=3D RTE_FLOW_ITEM_TYPE_ETH ||
> +		    js_field->type =3D=3D RTE_FLOW_ITEM_TYPE_IPV4) {
> +			mask =3D cpfl_json_object_to_string(object, "mask");
> +			if (!mask) {
> +				PMD_DRV_LOG(ERR, "Can not parse string
> 'mask'.");
> +				goto err;
> +			}
> +			memcpy(js_field->fields[i].mask, mask, strlen(mask));
The same as above.

> +		} else {
> +			uint32_t mask_32b;
> +			int ret;
> +
> +			ret =3D cpfl_json_object_to_uint32(object, "mask",
> &mask_32b);
> +			if (ret < 0) {
> +				PMD_DRV_LOG(ERR, "Can not parse uint32
> 'mask'.");
> +				goto err;
> +			}
> +			js_field->fields[i].mask_32b =3D mask_32b;
> +		}
> +	}
> +
> +	return 0;
> +
> +err:
> +	rte_free(js_field->fields);
> +	return -EINVAL;
> +}
> +
> +static int
> +cpfl_flow_js_pattern_key_proto(json_object *cjson_pr_key_proto, struct
> cpfl_flow_js_pr *js_pr)
> +{
> +	int len, i, ret;
> +
> +	len =3D json_object_array_length(cjson_pr_key_proto);
> +	js_pr->key.proto_size =3D len;
> +	js_pr->key.protocols =3D rte_malloc(NULL, sizeof(struct
> cpfl_flow_js_pr_key_proto) * len, 0);
> +	if (!js_pr->key.protocols) {
> +		PMD_DRV_LOG(ERR, "Failed to alloc memory.");
> +		return -ENOMEM;
> +	}
> +
> +	for (i =3D 0; i < len; i++) {
> +		json_object *object, *cjson_pr_key_proto_fields;
> +		const char *type;
> +		enum rte_flow_item_type item_type;
> +
> +		object =3D json_object_array_get_idx(cjson_pr_key_proto, i);
> +		/* pr->key->proto->type */
> +		type =3D cpfl_json_object_to_string(object, "type");
> +		if (!type) {
> +			PMD_DRV_LOG(ERR, "Can not parse string 'type'.");
> +			goto err;
> +		}
> +		item_type =3D cpfl_get_item_type_by_str(type);
> +		if (item_type =3D=3D RTE_FLOW_ITEM_TYPE_VOID)
> +			goto err;
> +		js_pr->key.protocols[i].type =3D item_type;
> +		/* pr->key->proto->fields */
> +		cjson_pr_key_proto_fields =3D json_object_object_get(object,
> "fields");
> +		ret =3D
> cpfl_flow_js_pattern_key_proto_field(cjson_pr_key_proto_fields,
> +							   &js_pr-
> >key.protocols[i]);
> +		if (ret < 0)
> +			goto err;
> +	}
> +
> +	return 0;
> +
> +err:
> +	rte_free(js_pr->key.protocols);
> +	return -EINVAL;
> +}
> +
> +static int
> +cpfl_flow_js_pattern_act_fv_proto(json_object *cjson_value, struct
> cpfl_flow_js_fv *js_fv)
> +{
> +	uint16_t layer =3D 0, offset =3D 0, mask =3D 0;
> +	const char *header;
> +	enum rte_flow_item_type type;
> +	int ret;
> +
> +	ret =3D cpfl_json_object_to_uint16(cjson_value, "layer", &layer);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Can not parse 'value'.");
> +		return -EINVAL;
> +	}
> +
> +	header =3D cpfl_json_object_to_string(cjson_value, "header");
> +	if (!header) {
> +		PMD_DRV_LOG(ERR, "Can not parse string 'header'.");
> +		return -EINVAL;
> +	}
> +	ret =3D cpfl_json_object_to_uint16(cjson_value, "offset", &offset);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Can not parse 'offset'.");
> +		return -EINVAL;
> +	}
> +	ret =3D cpfl_json_object_to_uint16(cjson_value, "mask", &mask);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Can not parse 'mask'.");
> +		return -EINVAL;
> +	}
> +	js_fv->proto.layer =3D layer;
> +	js_fv->proto.offset =3D offset;
> +	js_fv->proto.mask =3D mask;
> +	type =3D cpfl_get_item_type_by_str(header);
You can put this after get header, if no item type, return earlier.

> +	if (type =3D=3D RTE_FLOW_ITEM_TYPE_VOID)
> +		return -EINVAL;
> +	js_fv->proto.header =3D type;
> +
> +	return 0;
> +}
> +
> +static int
> +cpfl_flow_js_pattern_act_fv_metadata(json_object *cjson_value, struct
> cpfl_flow_js_fv *js_fv)
> +{
> +	int ret;
> +
> +	ret =3D cpfl_json_object_to_uint16(cjson_value, "type", &js_fv-
> >meta.type);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Can not parse 'size'.");
Is the log correct?

> +		return ret;
> +	}
> +	ret =3D cpfl_json_object_to_uint16(cjson_value, "offset", &js_fv-
> >meta.offset);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Can not parse 'size'.");
Same as above.
> +		return ret;
> +	}
> +	ret =3D cpfl_json_object_to_uint16(cjson_value, "mask", &js_fv-
> >meta.mask);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Can not parse 'size'.");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +cpfl_flow_js_pattern_act_fv(json_object *cjson_fv, struct
> cpfl_flow_js_pr_action *js_act)
> +{
> +	int len, i;
> +
> +	len =3D json_object_array_length(cjson_fv);
Better to check the len here?

> +	js_act->sem.fv =3D rte_malloc(NULL, sizeof(struct cpfl_flow_js_fv) * le=
n,
> 0);
> +	if (!js_act->sem.fv) {
> +		PMD_DRV_LOG(ERR, "Failed to alloc memory.");
> +		return -ENOMEM;
> +	}
> +	js_act->sem.fv_size =3D len;
> +	for (i =3D 0; i < len; i++) {
> +		struct cpfl_flow_js_fv *js_fv;
> +		json_object *object, *cjson_value;
> +		uint16_t offset =3D 0;
> +		const char *type;
> +		int ret;
> +
> +		object =3D json_object_array_get_idx(cjson_fv, i);
> +		js_fv =3D &js_act->sem.fv[i];
> +		ret =3D cpfl_json_object_to_uint16(object, "offset", &offset);
> +		if (ret < 0) {
> +			PMD_DRV_LOG(ERR, "Can not parse 'offset'.");
> +			goto err;
> +		}
> +		js_fv->offset =3D offset;
> +		type =3D cpfl_json_object_to_string(object, "type");
> +		if (!type) {
> +			PMD_DRV_LOG(ERR, "Can not parse string 'type'.");
> +			goto err;
> +		}
> +		cjson_value =3D json_object_object_get(object, "value");
> +		if (strcmp(type, "immediate") =3D=3D 0) {
> +			js_fv->type =3D CPFL_FV_TYPE_IMMEDIATE;
> +			js_fv->immediate =3D json_object_get_int(cjson_value);
> +		} else if (strcmp(type, "metadata") =3D=3D 0) {
> +			js_fv->type =3D CPFL_FV_TYPE_METADATA;
> +			cpfl_flow_js_pattern_act_fv_metadata(cjson_value,
> js_fv);
> +		} else if (strcmp(type, "protocol") =3D=3D 0) {
> +			js_fv->type =3D CPFL_FV_TYPE_PROTOCOL;
> +			cpfl_flow_js_pattern_act_fv_proto(cjson_value,
> js_fv);
> +		} else {
> +			PMD_DRV_LOG(ERR, "Not support this type: %s.",
> type);
> +			goto err;
> +		}
> +	}
> +
> +	return 0;
> +
> +err:
> +	rte_free(js_act->sem.fv);
> +	return -EINVAL;
> +}
> +
> +static int
> +cpfl_flow_js_pattern_per_act(json_object *cjson_per_act, struct
> cpfl_flow_js_pr_action *js_act)
> +{
> +	const char *type;
> +	int ret;
> +
> +	/* pr->actions->type */
> +	type =3D cpfl_json_object_to_string(cjson_per_act, "type");
> +	if (!type) {
> +		PMD_DRV_LOG(ERR, "Can not parse string 'type'.");
> +		return -EINVAL;
> +	}
> +	/* pr->actions->data */
> +	if (strcmp(type, "sem") =3D=3D 0) {
> +		json_object *cjson_fv, *cjson_pr_action_sem;
> +
> +		js_act->type =3D CPFL_JS_PR_ACTION_TYPE_SEM;
> +		cjson_pr_action_sem =3D
> json_object_object_get(cjson_per_act, "data");
> +		ret =3D cpfl_json_object_to_uint16(cjson_pr_action_sem,
> "profile",
> +						 &js_act->sem.prof);
> +		if (ret < 0) {
> +			PMD_DRV_LOG(ERR, "Can not parse 'profile'.");
> +			return -EINVAL;
> +		}
> +		ret =3D cpfl_json_object_to_uint16(cjson_pr_action_sem,
> "subprofile",
> +						 &js_act->sem.subprof);
> +		if (ret < 0) {
> +			PMD_DRV_LOG(ERR, "Can not parse 'subprofile'.");
> +			return -EINVAL;
> +		}
> +		ret =3D cpfl_json_object_to_uint16(cjson_pr_action_sem,
> "keysize",
> +						 &js_act->sem.keysize);
> +		if (ret < 0) {
> +			PMD_DRV_LOG(ERR, "Can not parse 'keysize'.");
> +			return -EINVAL;
> +		}
> +		cjson_fv =3D json_object_object_get(cjson_pr_action_sem,
> "fieldvectors");
> +		ret =3D cpfl_flow_js_pattern_act_fv(cjson_fv, js_act);
> +		if (ret < 0)
> +			return ret;
> +	} else {
> +		PMD_DRV_LOG(ERR, "Not support this type: %s.", type);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +cpfl_flow_js_pattern_act(json_object *cjson_pr_act, struct cpfl_flow_js_=
pr
> *js_pr)
> +{
> +	int i, len, ret;
> +
> +	len =3D json_object_array_length(cjson_pr_act);
Check len?
The same comments for following code where get length and them allocate mem=
ory,=20
[...]

> +int
> +cpfl_parser_destroy(struct cpfl_flow_js_parser *parser)
> +{
> +	int i, j;
> +
> +	if (!parser)
> +		return 0;
> +
> +	for (i =3D 0; i < parser->pr_size; i++) {
> +		struct cpfl_flow_js_pr *pattern =3D &parser->patterns[i];
> +
> +		if (!pattern)
> +			return -EINVAL;
I think the destroy might continue, if so, use continue but not just return=
.

> +		for (j =3D 0; j < pattern->key.proto_size; j++)
> +			rte_free(pattern->key.protocols[j].fields);
> +		rte_free(pattern->key.protocols);
> +		rte_free(pattern->key.attributes);
> +
> +		for (j =3D 0; j < pattern->actions_size; j++) {
> +			struct cpfl_flow_js_pr_action *pr_act;
> +
> +			pr_act =3D &pattern->actions[j];
> +			cpfl_parser_free_pr_action(pr_act);
> +		}
> +		rte_free(pattern->actions);
> +	}
> +	rte_free(parser->patterns);
> +	for (i =3D 0; i < parser->mr_size; i++) {
> +		struct cpfl_flow_js_mr *mr =3D &parser->modifications[i];
> +
> +		if (!mr)
> +			return -EINVAL;
I think the destroy might continue, if so, use continue but not just return=
.
[...]

> +static int
> +cpfl_str2mac(const char *mask, uint8_t *addr_bytes)
How about to use rte_ether_unformat_addr instead of defining a new one?
[...]

> +
> +/* output: struct cpfl_flow_mr_key_action *mr_key_action */
> +/* check and parse */
> +static int
> +cpfl_parse_mr_key_action(struct cpfl_flow_js_mr_key_action *key_acts, in=
t
> size,
> +			 const struct rte_flow_action *actions,
> +			 struct cpfl_flow_mr_key_action *mr_key_action)
> +{
> +	int actions_length, i;
> +	int j =3D 0;
> +	int ret;
> +
> +	actions_length =3D cpfl_get_actions_length(actions);
> +	if (size > actions_length - 1)
> +		return -EINVAL;
> +	for (i =3D 0; i < size; i++) {
> +		enum rte_flow_action_type type;
> +		struct cpfl_flow_js_mr_key_action *key_act;
> +
> +		key_act =3D &key_acts[i];
> +		/* mr->key->actions->type */
> +		type =3D key_act->type;
> +		/* mr->key->actions->data */
> +		/* match: <type> action matches
> RTE_FLOW_ACTION_TYPE_<type> */
> +		if (type =3D=3D RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP) {
> +			int proto_size, k;
> +			struct cpfl_flow_mr_key_action_vxlan_encap *encap;
> +
> +			while (j < actions_length &&
> +			       actions[j].type !=3D
> RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP) {
> +				j++;
> +			}
> +			if (j >=3D actions_length)
> +				return -EINVAL;
> +			mr_key_action[i].type =3D
> RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP;
> +			mr_key_action[i].encap.action =3D &actions[j];
> +			encap =3D &mr_key_action[i].encap;
> +
> +			proto_size =3D key_act->encap.proto_size;
> +			encap->proto_size =3D proto_size;
> +			for (k =3D 0; k < proto_size; k++) {
> +				enum rte_flow_item_type proto;
> +
> +				proto =3D key_act->encap.protocols[k];
> +				encap->protocols[k] =3D proto;
> +			}
> +			ret =3D cpfl_check_actions_vxlan_encap(encap,
> &actions[j]);
> +			if (ret < 0)
> +				return -EINVAL;
> +
> +			j++;
> +		} else if (type =3D=3D RTE_FLOW_ACTION_TYPE_VXLAN_DECAP) {
> +			while (j < actions_length &&
> +			       actions[j].type !=3D
> RTE_FLOW_ACTION_TYPE_VXLAN_DECAP) {
> +				j++;
> +			}
> +			if (j >=3D actions_length)
> +				return -EINVAL;
> +
> +			mr_key_action[i].type =3D
> RTE_FLOW_ACTION_TYPE_VXLAN_DECAP;
> +			j++;
> +		} else {
> +			PMD_DRV_LOG(ERR, "Not support this type: %d.",
> type);
> +			return -EPERM;
> +		}
Shouldn't reset j to 0 after one loop?

> +	}
> +
> +	return 0;
> +}
> +
> +/* output: uint8_t *buffer, uint16_t *byte_len */
> +static int
> +cpfl_parse_layout(struct cpfl_flow_js_mr_layout *layouts, int layout_siz=
e,
> +		  struct cpfl_flow_mr_key_action *mr_key_action,
> +		  uint8_t *buffer, uint16_t *byte_len)
> +{
> +	int i;
> +	int start =3D 0;
> +
> +	for (i =3D 0; i < layout_size; i++) {
> +		int index, size, offset;
> +		const char *hint;
> +		const uint8_t *addr;
> +		struct cpfl_flow_mr_key_action *temp;
> +		struct cpfl_flow_js_mr_layout *layout;
> +
> +		layout =3D &layouts[i];
> +		/* index links to the element of the actions array. */
> +		index =3D layout->index;
> +		size =3D layout->size;
> +		offset =3D layout->offset;
> +		if (index =3D=3D -1) {
> +			hint =3D "dummpy";
> +			start +=3D size;
> +			continue;
> +		}
> +		hint =3D layout->hint;
> +		addr =3D NULL;
Why set it to NULL here?
[...]

> +void
> +cpfl_metadata_write16(struct cpfl_metadata *meta, int type, int offset,
> uint16_t data)
> +{
> +	rte_memcpy(&meta->chunks[type].data[offset],
> +		   &data,
> +		   sizeof(uint16_t));
> +}
> +
> +void
> +cpfl_metadata_write32(struct cpfl_metadata *meta, int type, int offset,
> uint32_t data)
> +{
> +	rte_memcpy(&meta->chunks[type].data[offset],
> +		   &data,
> +		   sizeof(uint32_t));
> +}
> +
> +uint16_t
> +cpfl_metadata_read16(struct cpfl_metadata *meta, int type, int offset)
> +{
> +	return *((uint16_t *)(&meta->chunks[type].data[offset]));
> +}
> +

Those functions seem short enough, how about to define them as inline or ma=
cro?

> +bool
> +cpfl_metadata_write_port_id(struct cpfl_itf *itf)
> +{
> +	uint32_t dev_id;
> +	const int type =3D 0;
> +	const int offset =3D 5;
> +
> +	dev_id =3D cpfl_get_port_id(itf);
> +	if (dev_id =3D=3D CPFL_INVALID_HW_ID) {
> +		PMD_DRV_LOG(ERR, "fail to get hw ID\n");
> +		return false;
> +	}
> +	dev_id =3D dev_id << 3;
> +	cpfl_metadata_write16(&itf->adapter->meta, type, offset, dev_id);
> +
> +	return true;
> +}
> +
> +bool
> +cpfl_metadata_write_targetvsi(struct cpfl_itf *itf)
> +{
> +	uint32_t dev_id;
> +	const int type =3D 6;
> +	const int offset =3D 2;
> +
> +	dev_id =3D cpfl_get_vsi_id(itf);
> +	if (dev_id =3D=3D CPFL_INVALID_HW_ID) {
> +		PMD_DRV_LOG(ERR, "fail to get hw ID");
> +		return false;
> +	}
> +	dev_id =3D dev_id << 1;
> +	cpfl_metadata_write16(&itf->adapter->meta, type, offset, dev_id);
> +
> +	return true;
> +}
> +
> +bool
> +cpfl_metadata_write_sourcevsi(struct cpfl_itf *itf)
> +{
> +	uint32_t dev_id;
> +	const int type =3D 6;
> +	const int offset =3D 0;
> +
> +	dev_id =3D cpfl_get_vsi_id(itf);
> +	if (dev_id =3D=3D CPFL_INVALID_HW_ID) {
> +		PMD_DRV_LOG(ERR, "fail to get hw ID");
> +		return false;
> +	}
> +	cpfl_metadata_write16(&itf->adapter->meta, type, offset, dev_id);
> +
> +	return true;
> +}
> +
> +void
> +cpfl_metadata_init(struct cpfl_metadata *meta)
> +{
> +	int i;
> +
> +	for (i =3D 0; i < CPFL_META_LENGTH; i++)
> +		meta->chunks[i].type =3D i;
> +}
> +
> +bool cpfl_metadata_write_vsi(struct cpfl_itf *itf)
> +{
> +	uint32_t dev_id;
> +	const int type =3D 0;
> +	const int offset =3D 24;
> +
> +	dev_id =3D cpfl_get_vsi_id(itf);
> +	if (dev_id =3D=3D CPFL_INVALID_HW_ID) {
> +		PMD_DRV_LOG(ERR, "fail to get hw ID");
> +		return false;
> +	}
> +	cpfl_metadata_write16(&itf->adapter->meta, type, offset, dev_id);
> +
> +	return true;
> +}

In general, this patch is too large,  better to split for review.