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 5612742542; Fri, 8 Sep 2023 08:27:08 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3A7DF40285; Fri, 8 Sep 2023 08:27:08 +0200 (CEST) Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.31]) by mails.dpdk.org (Postfix) with ESMTP id 1411740042 for ; Fri, 8 Sep 2023 08:27:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694154425; x=1725690425; h=from:to:subject:date:message-id:references:in-reply-to: content-transfer-encoding:mime-version; bh=C8x5t5/xx59Yjq0Oy5SBetd23zyKtrAmro8ppJgi0gE=; b=llH5OUERhFMTw3nk+7tCUzLFkwV3KzVjrlttt/hcgKPWXtVyBOEgH6WW 7NFNmQvtOIDZdq++8BWk3ogUBIf+KZ4+FqcqnMyJmv4Pxfdo1nmn79OnE 5xij7DlI80jRLDK1xiTeb+HVK94xMhjqtXYRXzUtB0ssLIppRdi8g3DQF kaNPBf7tbz92XSaFwX26MVPhZz8jqYK+BpsvW0cH8VqcpB6xPTVcweBV9 XNQNivq0O3ou05oKjmeQgdvwm7mLjMl6s9BP7/+NOoVuLhtwmL8LScgbw XMwmP+98w14n1YCxhKI0J0q+QsY4sGzP9BqD43rrYeSndNjYC/sgfviEp w==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="441592224" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="441592224" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Sep 2023 23:27:03 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="989114481" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="989114481" Received: from fmsmsx601.amr.corp.intel.com ([10.18.126.81]) by fmsmga006.fm.intel.com with ESMTP/TLS/AES256-GCM-SHA384; 07 Sep 2023 23:27:02 -0700 Received: from fmsmsx610.amr.corp.intel.com (10.18.126.90) by fmsmsx601.amr.corp.intel.com (10.18.126.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.32; Thu, 7 Sep 2023 23:27:02 -0700 Received: from fmsedg602.ED.cps.intel.com (10.1.192.136) by fmsmsx610.amr.corp.intel.com (10.18.126.90) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.32 via Frontend Transport; Thu, 7 Sep 2023 23:27:02 -0700 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (104.47.59.173) by edgegateway.intel.com (192.55.55.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.27; Thu, 7 Sep 2023 23:26:56 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=RIrISabKhSOH6iEDadpUGjqmWyOwHAeC1fFvpDGiu1lTs9nbqdWtbpqaxOUN2f2KVrZ5DV2Qu7OCT2lVobb8CUadS8Cgz1IHkvUwyMqcyJELao9s+gRjRVJZelG95fBJpK2xvipnydyIf2gP2c+++7zOv27iMxwTqWachffxd6+9geHGiNQiaK/rcL0Oh1gSa3YMPXfx6fclGBmsSRKNvVd4vkN53wvLwBhDLTjWT22+KSsK7uB4wlEer4AWH3EmptS3Gy5a+TkoFsFiuIBgck7xBb9KEcjYsssjVNOi4AWmBIaOTwZXY+qkVkQ+HAWoUbrTFyS0Jf61TMdXf7UQcA== 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=r7TMs9PfjFGATTp2mb8saq7EnevdGxuGI9QvgtUKskI=; b=Qm+9z8nZ0KxS3evURFIjezKf6Zmb0+s3//pzYk1LanMn0jycpi33YfQMG7pISIxssnVN1k/XJa4mgvd7K+6cQm1xKdhogSfXq4muDlCwWzXFsF/aSk2kZau7bipmD04a96CGIoiwJvjVQgkvOphPdVXU0iaqi2HWTSIxnS2fQ1QR0wQQPmaT9cJoHK4zCzZ3trM20+p2rVEHQXUDWjwcZ7i98DjR8GkDEtzXg/M9es5eJ7UQfB9RS0UVSpP++kfZKSRFEQ3XyAWBKRXsuWEB7eYLcod1DcLXevngJSf5LnL/0i7nyAmY6INzBU+GY82/2fFCtBDDZzTecEUG1FQp+Q== 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 PH0PR11MB5877.namprd11.prod.outlook.com (2603:10b6:510:141::12) by MW4PR11MB6809.namprd11.prod.outlook.com (2603:10b6:303:1e9::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6768.30; Fri, 8 Sep 2023 06:26:53 +0000 Received: from PH0PR11MB5877.namprd11.prod.outlook.com ([fe80::95b7:4291:8e30:e19f]) by PH0PR11MB5877.namprd11.prod.outlook.com ([fe80::95b7:4291:8e30:e19f%5]) with mapi id 15.20.6745.035; Fri, 8 Sep 2023 06:26:52 +0000 From: "Liu, Mingxia" To: "Qiao, Wenjing" , "Zhang, Yuying" , "dev@dpdk.org" , "Zhang, Qi Z" , "Wu, Jingjing" , "Xing, Beilei" 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: AQHZ4KVWJGy9V4UqoE+0+WBbre7JCLAQQb1Q Date: Fri, 8 Sep 2023 06:26:52 +0000 Message-ID: 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: PH0PR11MB5877:EE_|MW4PR11MB6809:EE_ x-ms-office365-filtering-correlation-id: 59f22372-0698-45e5-2955-08dbb0349763 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: e5/6vF/098WykBZSWPbbfx2PM6oIvr/hkonkDaoHUpYkubVNv2wk75uNLZ3ttm4WCTFrh5/KXGV2qPanBitLD98+p32kLWb/dlCxKtgxUgUX9Djeq6LkdVJBgkhfe0ZqQdY43Fug5nb4fmWp+niqeT5iOIQ56+cyU1oVnGA8x7vFdfBl6EBwF5CogRt7Zchn3QdcNUAcc4m4Ti7ydyVK8Ar3fqTRH5vrojDk6LbUu/fc1+aImeliawwbM8U/UURGiUXFyP/jiqlFx/vWiiJOVjROpmwT1/Z/lw99EOKW25rlou1nxbzZ55aXa/SLga+ku75jcmC6CpiT2J2Q8fH4SjZRd/5i2Isutl4Lq8HSB8QaIx0f/AspzIVOB6KmGNq59a4oT0hQ966vOcPb7XtojKM4k1kLeSvDXG438QzVEZ8+gOrmFByYQLOcpYr8et0Ji9iuEmGz4I/2SrxtxMOPROnqNw3qtoe63svZIMCriclo8EAUWj0wEU7Ukt1CEdReRFos1ry4FVOfItX5xNCS87/NFOgGGcXx6kuLVhgS0vIPOi3CptKeKQBH9cTXZZqoW1rMwW574upEmvPdtS66sjyVdEYgvqNUrxBWnO72XHHCMfzbFJWB28w5xn2Of1OmcR7Raa4jwq0o/w44RM+k9g== x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PH0PR11MB5877.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(376002)(39860400002)(346002)(366004)(136003)(396003)(1800799009)(451199024)(186009)(38100700002)(38070700005)(55016003)(82960400001)(83380400001)(122000001)(921005)(30864003)(2906002)(110136005)(71200400001)(76116006)(64756008)(66446008)(66476007)(66556008)(66946007)(53546011)(6636002)(316002)(6506007)(9686003)(33656002)(7696005)(86362001)(478600001)(26005)(52536014)(8936002)(8676002)(5660300002)(41300700001)(579004)(559001); DIR:OUT; SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?tSLEhcH6pRytM3ezVcLhRyEMQ5Po5tq67adre7DRDIU3hSEj7XOyjmc/eDG2?= =?us-ascii?Q?KPnXYOSi0zJTKD3gNqqN5gEfm/n5gaeZLkD0zUlbhJ7fEI0i56RtQnogUyJK?= =?us-ascii?Q?/1o3pdlQrKsz4vh4ipjFfaX8bNE2KGWGnmjM1IRi1KqpB/Qec9qkhJF6ZaJz?= =?us-ascii?Q?lbkoM1DuoYtFtIPyAfiq2t6xtOr6z74Rb+77Px/Oka2T2kW9i1dOztxh7ZWK?= =?us-ascii?Q?W3B7/pGzPRGo8PZH6G5NU4GNI0cjlIhegLeVMgXzgu46WPmhZBC3+De5n/lw?= =?us-ascii?Q?zS/jzMvVAswEIScDxo3X9Y8RrpquppCgd30fQAYgiSk0EpiPc0QDCB2Hgqss?= =?us-ascii?Q?Ep+j+VndiUekhpybthRWaHOx4rkcVTaFAZI5vb0UOLBSG0weSL9XVPLMc+BV?= =?us-ascii?Q?A6rwK76xhomy/DFX0W850ZZvWU7ian0hPhRdiU76aOXJZyoUxalKFDrcXrze?= =?us-ascii?Q?NXklT6eFHJS78AHn+Vq3nBMkg2jurR/yMOhbtUNRvjapZWW+beqGm8IGuDHv?= =?us-ascii?Q?kd0QhqzedD6Vk2xKQ9x/3NZeTwUcrUxKjj/9Dj3ia3XK+h5Y0M3+IEUaJ8q0?= =?us-ascii?Q?Bd4s7O+LyUIh1Dg2m85+lEVol8xTIfxnD28BLeqYuwU24T80WhC+4scANJoQ?= =?us-ascii?Q?IaUxtQjC56dM1DrAEXYGDdIi6t5fFnN5Ll/0ZH6aOO8+RBbKaI+lmxhLszCv?= =?us-ascii?Q?X/StQ76loUB1NVbfnbDPFgbot4RyYC6lpPuP2/SAF250MIzmasrcku0JQ6Wr?= =?us-ascii?Q?A795A8CcHIVmASapOZ03VfTF7/xnEo3e84NZfCBnfiEz3zc0f5Eq360AcHOd?= =?us-ascii?Q?rlJDNjq7mvWZ9jDOQIvOryAP02MbXwJzJl5qzx8g7sayDlUhK/KfRmYPQwgG?= =?us-ascii?Q?Rtpr6ZCEKuGhMlzsJ+N9B51tb21NKJMuHbVw1jDzaTJYN6ePo9loyLRJw2Ji?= =?us-ascii?Q?eRecNSIZ4zVyghBd6uKySIGbO0IBA4Z89qK21s0k4A7CvGXqsG4o6Uh4aLiB?= =?us-ascii?Q?f0w4sCqTdvF2bRx/NK5QQYIUp9e8haTOKoD2J/nkKwqqtb0+XcwTDxel3Az4?= =?us-ascii?Q?H35rVWkFch3uXQTAyRV1XCT79s5UvyyIPqpBEIF5h27H0duOKR1AK+c+/0EB?= =?us-ascii?Q?MbeD30MQvdxCEPMFAVAHgeb0fnKGjdfimEdHyT98U2hUmd1qgdmGPUfTlvPa?= =?us-ascii?Q?/xNsyonQq7QB/Av0T9xgfztSLaVZLrnG2JZ1i2gy/aEuGphzDstPz+QjttET?= =?us-ascii?Q?uK359IOZ78HeZJ+yQwDLCyCbVoBmXOdo7B858xaI7yt8t8XqcHVPDJ67NlMY?= =?us-ascii?Q?PPNUk+QX0f1kmUB86/BNOymHrMpYYqnKePPiQz015kL6VO2lU+N0NfclOiDo?= =?us-ascii?Q?FBrbC971/+EalI/K71f6PgZlpdPEeD+bUrpgJoWdqsnHr++g/nlDJnEwAo3C?= =?us-ascii?Q?Z6oEx6PjeMREi/Ii1tP0eHABNV8hR5vKPgo67UCtCEhiiZwh5AgIFwwbMrj0?= =?us-ascii?Q?7Nz/P29tLs0dPcoiCC1y39oFNVp4vXnWrx1BvF6nu02f0N/17j0ffz/ViEvI?= =?us-ascii?Q?g7cYthNrx+WGuF1c9WwhTWwg7tvIXi8clBoiEp1v?= 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: PH0PR11MB5877.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 59f22372-0698-45e5-2955-08dbb0349763 X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Sep 2023 06:26:52.7193 (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: hITbEWtVKfgSGlo/eOx5RODE0WwvhSM6/w2uCHUS/Ht0pbDVLQ7rCmdhl/8LwJ++r64nX36t5DkqOthRo4oFtw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW4PR11MB6809 X-OriginatorOrg: intel.com 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 > -----Original Message----- > From: Qiao, Wenjing > Sent: Wednesday, September 6, 2023 5:34 PM > To: Zhang, Yuying ; dev@dpdk.org; Zhang, Qi Z > ; Wu, Jingjing ; Xing, Beile= i > > Cc: Liu, Mingxia ; Qiao, Wenjing > > Subject: [PATCH v3 2/9] net/cpfl: add flow json parser >=20 > A JSON file will be used to direct DPDK CPF PMD to > parse rte_flow tokens into low level hardware resources > defined in a DDP package file. >=20 > Signed-off-by: Wenjing Qiao > --- > drivers/net/cpfl/cpfl_ethdev.h | 70 + > drivers/net/cpfl/cpfl_flow_parser.c | 1910 +++++++++++++++++++++++++++ > drivers/net/cpfl/cpfl_flow_parser.h | 236 ++++ > drivers/net/cpfl/meson.build | 3 + > 4 files changed, 2219 insertions(+) > create mode 100644 drivers/net/cpfl/cpfl_flow_parser.c > create mode 100644 drivers/net/cpfl/cpfl_flow_parser.h >=20 > +static int > +cpfl_flow_js_pattern_key_attr(json_object *cjson_pr_key_attr, struct > cpfl_flow_js_pr *js_pr) > +{ > + int i, len; > + struct cpfl_flow_js_pr_key_attr *attr; > + > + len =3D json_object_array_length(cjson_pr_key_attr); > + js_pr->key.attributes =3D rte_malloc(NULL, sizeof(struct > cpfl_flow_js_pr_key_attr), 0); > + if (!js_pr->key.attributes) { > + PMD_DRV_LOG(ERR, "Failed to alloc memory."); > + return -ENOMEM; > + } > + js_pr->key.attr_size =3D len; > + attr =3D js_pr->key.attributes; > + for (i =3D 0; i < len; i++) { > + json_object *object; > + const char *name; > + uint16_t value =3D 0; > + int ret; > + > + object =3D json_object_array_get_idx(cjson_pr_key_attr, i); > + name =3D cpfl_json_object_to_string(object, "Name"); > + if (!name) { > + rte_free(js_pr->key.attributes); > + PMD_DRV_LOG(ERR, "Can not parse string 'Name'."); > + return -EINVAL; [Liu, Mingxia] Better to use goto statement as other similar function do? > + } > + ret =3D cpfl_json_object_to_uint16(object, "Value", &value); > + if (ret < 0) { > + rte_free(js_pr->key.attributes); > + PMD_DRV_LOG(ERR, "Can not parse 'value'."); > + return -EINVAL; > + } > + if (strcmp(name, "ingress") =3D=3D 0) { > + attr->ingress =3D value; > + } else if (strcmp(name, "egress") =3D=3D 0) { > + attr->egress =3D value; > + } else { > + /* TODO: more... */ > + rte_free(js_pr->key.attributes); > + PMD_DRV_LOG(ERR, "Not support attr name: %s.", > name); > + return -EINVAL; > + } > + } > + > + return 0; > +} > + > +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) > + return 0; > + js_field->fields =3D > + rte_malloc(NULL, sizeof(struct cpfl_flow_js_pr_key_proto_field) * l= en, > 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)); > + > + 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)); [Liu, Mingxia] Need to check the length and validation of mask? > + } 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); > + 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'."); > + 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'."); > + 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); > + 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); > + js_pr->actions =3D rte_malloc(NULL, sizeof(struct cpfl_flow_js_pr_actio= n) > * len, 0); > + if (!js_pr->actions) { > + PMD_DRV_LOG(ERR, "Failed to alloc memory."); > + return -ENOMEM; > + } > + js_pr->actions_size =3D len; > + for (i =3D 0; i < len; i++) { > + struct cpfl_flow_js_pr_action *js_act; > + json_object *object; > + > + object =3D json_object_array_get_idx(cjson_pr_act, i); > + js_act =3D &js_pr->actions[i]; > + ret =3D cpfl_flow_js_pattern_per_act(object, js_act); > + if (ret < 0) { > + rte_free(js_pr->actions); > + PMD_DRV_LOG(ERR, "Can not parse pattern action."); > + return -EINVAL; > + } > + } > + > + return 0; > +} > + > +static int > +cpfl_flow_js_pattern_rule(json_object *json_root, struct cpfl_flow_js_pa= rser > *parser) > +{ > + json_object *cjson_pr; > + int i, len; > + > + /* Pattern Rules */ > + cjson_pr =3D json_object_object_get(json_root, "patterns"); > + if (!cjson_pr) { > + PMD_DRV_LOG(ERR, "The patterns is mandatory."); > + return -EINVAL; > + } > + > + len =3D json_object_array_length(cjson_pr); > + parser->patterns =3D rte_malloc(NULL, sizeof(struct cpfl_flow_js_pr) * = len, > 0); > + if (!parser->patterns) { > + PMD_DRV_LOG(ERR, "Failed to alloc memory."); > + return -ENOMEM; > + } > + parser->pr_size =3D len; > + for (i =3D 0; i < len; i++) { > + json_object *object, *cjson_pr_actions, *cjson_pr_key, > *cjson_pr_key_proto, > + *cjson_pr_key_attr; > + int ret; > + > + object =3D json_object_array_get_idx(cjson_pr, i); > + /* pr->key */ > + cjson_pr_key =3D json_object_object_get(object, "key"); > + /* pr->key->protocols */ > + cjson_pr_key_proto =3D json_object_object_get(cjson_pr_key, > "protocols"); > + ret =3D cpfl_flow_js_pattern_key_proto(cjson_pr_key_proto, > &parser->patterns[i]); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "Can not parse key->protocols."); > + goto err; > + } > + /* pr->key->attributes */ > + cjson_pr_key_attr =3D json_object_object_get(cjson_pr_key, > "attributes"); > + ret =3D cpfl_flow_js_pattern_key_attr(cjson_pr_key_attr, &parser- > >patterns[i]); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "Can not parse key->attributes."); > + goto err; > + } > + /* pr->actions */ > + cjson_pr_actions =3D json_object_object_get(object, "actions"); > + ret =3D cpfl_flow_js_pattern_act(cjson_pr_actions, &parser- > >patterns[i]); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "Can not parse pattern action."); > + goto err; > + } > + } > + > + return 0; > + > +err: > + rte_free(parser->patterns); > + return -EINVAL; > +} > + > +static int > +cpfl_flow_js_mr_key(json_object *cjson_mr_key, struct cpfl_flow_js_mr_ke= y > *js_mr_key) > +{ > + int len, i; > + > + len =3D json_object_array_length(cjson_mr_key); > + js_mr_key->actions =3D rte_malloc(NULL, sizeof(struct > cpfl_flow_js_mr_key_action) * len, 0); > + if (!js_mr_key->actions) { > + PMD_DRV_LOG(ERR, "Failed to alloc memory."); > + return -ENOMEM; > + } > + js_mr_key->actions_size =3D len; > + for (i =3D 0; i < len; i++) { > + json_object *object, *cjson_mr_key_data; > + const char *type; > + enum rte_flow_action_type act_type; > + > + object =3D json_object_array_get_idx(cjson_mr_key, i); > + /* mr->key->actions->type */ > + type =3D cpfl_json_object_to_string(object, "type"); > + if (!type) { > + PMD_DRV_LOG(ERR, "Can not parse string 'type'."); > + goto err; > + } > + act_type =3D cpfl_get_action_type_by_str(type); > + if (act_type =3D=3D RTE_FLOW_ACTION_TYPE_VOID) > + goto err; > + js_mr_key->actions[i].type =3D act_type; > + /* mr->key->actions->data */ > + cjson_mr_key_data =3D json_object_object_get(object, "data"); > + if (js_mr_key->actions[i].type =3D=3D > RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP) { > + json_object *cjson_mr_key_proto; > + int proto_size, j; > + struct cpfl_flow_js_mr_key_action_vxlan_encap > *encap; > + > + cjson_mr_key_proto =3D > json_object_object_get(cjson_mr_key_data, "protocols"); > + encap =3D &js_mr_key->actions[i].encap; > + if (!cjson_mr_key_proto) { > + encap->proto_size =3D 0; > + continue; > + } > + proto_size =3D > json_object_array_length(cjson_mr_key_proto); > + encap->proto_size =3D proto_size; > + for (j =3D 0; j < proto_size; j++) { > + const char *s; > + json_object *subobject; > + enum rte_flow_item_type proto_type; > + > + subobject =3D > json_object_array_get_idx(cjson_mr_key_proto, j); > + s =3D json_object_get_string(subobject); > + proto_type =3D cpfl_get_item_type_by_str(s); > + if (proto_type =3D=3D > RTE_FLOW_ITEM_TYPE_VOID) { > + PMD_DRV_LOG(ERR, "parse > VXLAN_ENCAP failed."); > + goto err; > + } > + encap->protocols[j] =3D proto_type; > + } > + } else if (js_mr_key->actions[i].type !=3D > RTE_FLOW_ACTION_TYPE_VXLAN_DECAP) { > + PMD_DRV_LOG(ERR, "not support this type: %d.", > js_mr_key->actions[i].type); > + goto err; > + } > + } > + > + return 0; > + > +err: > + rte_free(js_mr_key->actions); > + return -EINVAL; > +} > + > +static int > +cpfl_flow_js_mr_layout(json_object *cjson_layout, struct > cpfl_flow_js_mr_action_mod *js_mod) > +{ > + int len, i; > + > + len =3D json_object_array_length(cjson_layout); > + js_mod->layout_size =3D len; > + if (len =3D=3D 0) > + return 0; > + js_mod->layout =3D rte_malloc(NULL, sizeof(struct > cpfl_flow_js_mr_layout) * len, 0); > + if (!js_mod->layout) { > + PMD_DRV_LOG(ERR, "Failed to alloc memory."); > + return -ENOMEM; > + } > + > + for (i =3D 0; i < len; i++) { > + json_object *object; > + int index =3D 0, size =3D 0, offset =3D 0, ret; > + const char *hint; > + > + object =3D json_object_array_get_idx(cjson_layout, i); > + ret =3D cpfl_json_object_to_int(object, "index", &index); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "Can not parse 'index'."); > + goto err; > + } > + js_mod->layout[i].index =3D index; > + ret =3D cpfl_json_object_to_int(object, "size", &size); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "Can not parse 'size'."); > + goto err; > + } > + js_mod->layout[i].size =3D size; > + ret =3D cpfl_json_object_to_int(object, "offset", &offset); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "Can not parse 'offset'."); > + goto err; > + } > + js_mod->layout[i].offset =3D offset; > + hint =3D cpfl_json_object_to_string(object, "hint"); > + if (!hint) { > + PMD_DRV_LOG(ERR, "Can not parse string 'hint'."); > + goto err; > + } > + memcpy(js_mod->layout[i].hint, hint, strlen(hint)); > + } > + > + return 0; > + > +err: > + rte_free(js_mod->layout); > + return -EINVAL; > +} > + > +static int > +cpfl_flow_js_mr_action(json_object *cjson_mr_act, struct > cpfl_flow_js_mr_action *js_mr_act) > +{ > + json_object *cjson_mr_action_data; > + const char *type; > + > + /* mr->action->type */ > + type =3D cpfl_json_object_to_string(cjson_mr_act, "type"); > + if (!type) { > + PMD_DRV_LOG(ERR, "Can not parse string 'type'."); > + return -EINVAL; > + } > + /* mr->action->data */ > + cjson_mr_action_data =3D json_object_object_get(cjson_mr_act, "data"); > + if (strcmp(type, "mod") =3D=3D 0) { > + json_object *layout; > + uint16_t profile =3D 0; > + int ret; > + > + js_mr_act->type =3D CPFL_JS_MR_ACTION_TYPE_MOD; > + ret =3D cpfl_json_object_to_uint16(cjson_mr_action_data, > "profile", &profile); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "Can not parse 'profile'."); > + return -EINVAL; > + } > + js_mr_act->mod.prof =3D profile; > + layout =3D json_object_object_get(cjson_mr_action_data, > "layout"); > + ret =3D cpfl_flow_js_mr_layout(layout, &js_mr_act->mod); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "Can not parse layout."); > + return ret; > + } > + } else { > + PMD_DRV_LOG(ERR, "not support this type: %s.", type); > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int > +cpfl_flow_js_mod_rule(json_object *json_root, struct cpfl_flow_js_parser > *parser) > +{ > + json_object *cjson_mr; > + int i, len; > + > + cjson_mr =3D json_object_object_get(json_root, "modifications"); > + if (!cjson_mr) { > + PMD_DRV_LOG(INFO, "The modifications is optional."); > + return 0; > + } > + len =3D json_object_array_length(cjson_mr); > + parser->mr_size =3D len; > + if (len =3D=3D 0) > + return 0; > + parser->modifications =3D rte_malloc(NULL, sizeof(struct cpfl_flow_js_m= r) > * len, 0); > + if (!parser->modifications) { > + PMD_DRV_LOG(ERR, "Failed to alloc memory."); > + return -ENOMEM; > + } > + for (i =3D 0; i < len; i++) { > + int ret; > + json_object *object, *cjson_mr_key, *cjson_mr_action, > *cjson_mr_key_action; > + > + object =3D json_object_array_get_idx(cjson_mr, i); > + /* mr->key */ > + cjson_mr_key =3D json_object_object_get(object, "key"); > + /* mr->key->actions */ > + cjson_mr_key_action =3D json_object_object_get(cjson_mr_key, > "actions"); > + ret =3D cpfl_flow_js_mr_key(cjson_mr_key_action, &parser- > >modifications[i].key); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "parse mr_key failed."); > + goto err; > + } > + /* mr->action */ > + cjson_mr_action =3D json_object_object_get(object, "action"); > + ret =3D cpfl_flow_js_mr_action(cjson_mr_action, &parser- > >modifications[i].action); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "parse mr_action failed."); > + goto err; > + } > + } > + > + return 0; > + > +err: > + rte_free(parser->modifications); > + return -EINVAL; > +} > + > +static int > +cpfl_parser_init(json_object *json_root, struct cpfl_flow_js_parser *par= ser) > +{ > + int ret =3D 0; > + > + ret =3D cpfl_flow_js_pattern_rule(json_root, parser); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "parse pattern_rule failed."); > + return ret; > + } > + ret =3D cpfl_flow_js_mod_rule(json_root, parser); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "parse mod_rule failed."); > + return ret; > + } > + > + return 0; > +} > + > +int > +cpfl_parser_create(struct cpfl_flow_js_parser **flow_parser, const char > *filename) > +{ > + struct cpfl_flow_js_parser *parser; > + json_object *root; > + int ret; > + > + parser =3D rte_zmalloc("flow_parser", sizeof(struct cpfl_flow_js_parser= ), > 0); > + if (!parser) { > + PMD_DRV_LOG(ERR, "Not enough memory to create flow > parser."); > + return -ENOMEM; > + } > + root =3D json_object_from_file(filename); > + if (!root) { > + PMD_DRV_LOG(ERR, "Can not load JSON file: %s.", filename); > + rte_free(parser); > + return -EINVAL; [Liu, Mingxia] better to use goto free_parser; ? > + } > + ret =3D cpfl_parser_init(root, parser); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "parser init failed."); > + goto free_parser; [Liu, Mingxia] If failed, need to json_object_put(root) ? > + } > + *flow_parser =3D parser; > + ret =3D json_object_put(root); > + if (ret !=3D 1) { > + PMD_DRV_LOG(ERR, "Free json_object failed."); > + return -EINVAL; > + } > + > + return 0; > +free_parser: > + rte_free(parser); > + return -EINVAL; > +} > + > +static void > +cpfl_parser_free_pr_action(struct cpfl_flow_js_pr_action *pr_act) > +{ > + if (pr_act->type =3D=3D CPFL_JS_PR_ACTION_TYPE_SEM) > + rte_free(pr_act->sem.fv); > +} > + > +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; > + 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; > + rte_free(mr->key.actions); > + rte_free(mr->action.mod.layout); > + } > + rte_free(parser->modifications); > + rte_free(parser); > + > + return 0; > +} > + > +static int > +cpfl_get_items_length(const struct rte_flow_item *items) > +{ > + int length =3D 0; > + const struct rte_flow_item *item =3D items; > + > + while ((item + length++)->type !=3D RTE_FLOW_ITEM_TYPE_END) > + continue; > + return length; > +} > + > +static int > +cpfl_get_actions_length(const struct rte_flow_action *actions) > +{ > + int length =3D 0; > + const struct rte_flow_action *action =3D actions; > + > + while ((action + length++)->type !=3D RTE_FLOW_ACTION_TYPE_END) > + continue; > + return length; > +} > + > +static int > +cpfl_parse_fv_protocol(struct cpfl_flow_js_fv *js_fv, const struct rte_f= low_item > *items, > + uint16_t offset, uint8_t *fv) > +{ > + uint16_t v_layer, v_offset, v_mask; > + enum rte_flow_item_type v_header; > + int j, layer, length; > + uint16_t temp_fv; > + > + length =3D cpfl_get_items_length(items); > + v_layer =3D js_fv->proto.layer; > + v_header =3D js_fv->proto.header; > + v_offset =3D js_fv->proto.offset; > + v_mask =3D js_fv->proto.mask; > + layer =3D 0; > + for (j =3D 0; j < length - 1; j++) { > + if (items[j].type =3D=3D v_header) { > + if (layer =3D=3D v_layer) { > + /* copy out 16 bits from offset */ > + const uint8_t *pointer; > + > + pointer =3D &(((const uint8_t > *)(items[j].spec))[v_offset]); > + temp_fv =3D ntohs((*((const uint16_t *)pointer)) > & v_mask); > + fv[2 * offset] =3D (uint8_t)((temp_fv & 0xff00) >> > 8); [Liu, Mingxia] ((temp_fv & 0xff00) >> 8) can be simplified to temp_fv >> 8,= there are other places that has the same issue. > + fv[2 * offset + 1] =3D (uint8_t)(temp_fv & > 0x00ff); > + break; > + } > + layer++; > + } /* TODO: more type... */ > + } > + > + return 0; > +} > + > +static int > +cpfl_parse_fieldvectors(struct cpfl_itf *itf, struct cpfl_flow_js_fv *js= _fvs, int > size, > + uint8_t *fv, const struct rte_flow_item *items) > +{ > + int i, ret; > + > + for (i =3D 0; i < size; i++) { > + uint16_t offset, temp_fv, value_int; > + enum cpfl_flow_js_fv_type type; > + struct cpfl_flow_js_fv *js_fv; > + > + js_fv =3D &js_fvs[i]; > + offset =3D js_fv->offset; > + type =3D js_fv->type; > + if (type =3D=3D CPFL_FV_TYPE_IMMEDIATE) { > + value_int =3D js_fv->immediate; > + temp_fv =3D (value_int << 8) & 0xff00; > + fv[2 * offset] =3D (uint8_t)((temp_fv & 0xff00) >> 8); > + fv[2 * offset + 1] =3D (uint8_t)(temp_fv & 0x00ff); > + } else if (type =3D=3D CPFL_FV_TYPE_METADATA) { > + uint16_t type, v_offset, mask; > + > + type =3D js_fv->meta.type; > + v_offset =3D js_fv->meta.offset; > + mask =3D js_fv->meta.mask; > + temp_fv =3D cpfl_metadata_read16(&itf->adapter->meta, > type, v_offset) & mask; > + fv[2 * offset] =3D (uint8_t)(temp_fv & 0x00ff); > + fv[2 * offset + 1] =3D (uint8_t)((temp_fv & 0xff00) >> 8); > + } else if (type =3D=3D CPFL_FV_TYPE_PROTOCOL) { > + ret =3D cpfl_parse_fv_protocol(js_fv, items, offset, fv); > + if (ret) > + return ret; > + } else { > + PMD_DRV_LOG(DEBUG, "not support this type: %d.", > type); > + return -EINVAL; > + } > + } > + > + return 0; > +} > + > +static int > +cpfl_parse_pr_actions(struct cpfl_itf *itf, > + struct cpfl_flow_js_pr_action *actions, > + int size, > + const struct rte_flow_item *items, > + const struct rte_flow_attr *attr, > + struct cpfl_flow_pr_action *pr_action) > +{ > + int i, ret; > + > + for (i =3D 0; i < size; i++) { > + struct cpfl_flow_js_pr_action *pr_act; > + enum cpfl_flow_pr_action_type type; > + > + pr_act =3D &actions[i]; > + /* pr->actions->type */ > + type =3D pr_act->type; > + /* pr->actions->data */ > + if (attr->group % 10 =3D=3D 1 && type =3D=3D > CPFL_JS_PR_ACTION_TYPE_SEM) { > + struct cpfl_flow_js_pr_action_sem *sem =3D &pr_act- > >sem; > + > + pr_action->type =3D CPFL_JS_PR_ACTION_TYPE_SEM; > + pr_action->sem.prof =3D sem->prof; > + pr_action->sem.subprof =3D sem->subprof; > + pr_action->sem.keysize =3D sem->keysize; > + memset(pr_action->sem.cpfl_flow_pr_fv, 0, > + sizeof(pr_action->sem.cpfl_flow_pr_fv)); > + ret =3D cpfl_parse_fieldvectors(itf, sem->fv, sem->fv_size, > + pr_action- > >sem.cpfl_flow_pr_fv, items); > + return ret; > + } else if (attr->group > 4 || attr->group =3D=3D 0) { > + return -EPERM; > + } > + } > + > + return 0; > +} > + > +static int > +cpfl_str2mac(const char *mask, uint8_t *addr_bytes) > +{ > + int i, size, j; > + uint8_t n; > + > + size =3D strlen(mask); > + n =3D 0; > + j =3D 0; > + for (i =3D 0; i < size; i++) { > + char ch =3D mask[i]; > + > + if (ch =3D=3D ':') { > + if (j >=3D RTE_ETHER_ADDR_LEN) > + return -EINVAL; > + addr_bytes[j++] =3D n; > + n =3D 0; > + } else if (ch >=3D 'a' && ch <=3D 'f') { > + n =3D n * 16 + ch - 'a' + 10; > + } else if (ch >=3D 'A' && ch <=3D 'F') { > + n =3D n * 16 + ch - 'A' + 10; > + } else if (ch >=3D '0' && ch <=3D '9') { > + n =3D n * 16 + ch - '0'; > + } else { > + return -EINVAL; > + } > + } > + if (j < RTE_ETHER_ADDR_LEN) > + addr_bytes[j++] =3D n; > + > + if (j !=3D RTE_ETHER_ADDR_LEN) > + return -EINVAL; > + > + return 0; > +} > + > +static int > +cpfl_check_eth_mask(const char *mask, const uint8_t > addr_bytes[RTE_ETHER_ADDR_LEN]) > +{ > + int i, ret; > + uint8_t mask_bytes[RTE_ETHER_ADDR_LEN] =3D { 0 }; > + > + ret =3D cpfl_str2mac(mask, mask_bytes); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "translate mac address from string to > uint8_t[] failed."); > + return -EINVAL; > + } > + /* validate eth mask addr if match */ > + for (i =3D 0; i < RTE_ETHER_ADDR_LEN; i++) { > + if (mask_bytes[i] !=3D addr_bytes[i]) > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int > +cpfl_check_ipv4_mask(const char *mask, rte_be32_t addr) > +{ > + uint32_t out_addr; > + > + /* 0: success; -EINVAL: invalid; -ENOTSUP: fail */ > + int ret =3D inet_pton(AF_INET, mask, &out_addr); > + > + if (ret < 0) > + return -EINVAL; > + /* validate ipv4 mask addr if match */ > + if (out_addr !=3D addr) > + return -EINVAL; > + > + return 0; > +} > + > +static int > +cpfl_check_eth(struct cpfl_flow_js_pr_key_proto *proto, const struct > rte_flow_item_eth *eth_mask) > +{ > + int field_size, j; > + int flag_dst_addr, flag_src_addr, flag_ether_type; > + struct cpfl_flow_js_pr_key_proto_field *field; > + > + if (!proto) > + return 0; > + field_size =3D proto->fields_size; > + if (field_size !=3D 0 && !eth_mask) > + return -EINVAL; > + > + if (field_size =3D=3D 0 && eth_mask) > + return -EINVAL; > + > + if (field_size =3D=3D 0 && !eth_mask) > + return 0; > + > + flag_dst_addr =3D false; > + flag_src_addr =3D false; > + flag_ether_type =3D false; > + for (j =3D 0; j < field_size; j++) { > + const char *name, *s_mask; > + > + field =3D &proto->fields[j]; > + /* match: rte_flow_item_eth.dst, more see Field Mapping > + */ > + name =3D field->name; > + /* match: rte_flow_item->mask */ > + if (strcmp(name, "src_addr") =3D=3D 0) { > + s_mask =3D field->mask; > + if (cpfl_check_eth_mask(s_mask, eth_mask- > >src.addr_bytes) < 0) > + return -EINVAL; > + flag_src_addr =3D true; > + } else if (strcmp(name, "dst_addr") =3D=3D 0) { > + s_mask =3D field->mask; > + if (cpfl_check_eth_mask(s_mask, eth_mask- > >dst.addr_bytes) < 0) > + return -EINVAL; > + flag_dst_addr =3D true; > + } else if (strcmp(name, "ether_type") =3D=3D 0) { > + uint16_t mask =3D (uint16_t)field->mask_32b; > + > + if (mask !=3D eth_mask->type) > + return -EINVAL; > + flag_ether_type =3D true; > + } else { > + /* TODO: more type... */ > + PMD_DRV_LOG(ERR, "not support this name."); > + return -EINVAL; > + } > + } > + if (!flag_src_addr) { > + if (strcmp((const char *)eth_mask->src.addr_bytes, > "\x00\x00\x00\x00\x00\x00") !=3D 0) > + return -EINVAL; > + } > + if (!flag_dst_addr) { > + if (strcmp((const char *)eth_mask->dst.addr_bytes, > "\x00\x00\x00\x00\x00\x00") !=3D 0) > + return -EINVAL; > + } > + if (!flag_ether_type) { > + if (eth_mask->hdr.ether_type !=3D (rte_be16_t)0) > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int > +cpfl_check_ipv4(struct cpfl_flow_js_pr_key_proto *proto, const struct > rte_flow_item_ipv4 *ipv4_mask) > +{ > + int field_size, j; > + int flag_next_proto_id, flag_src_addr, flag_dst_addr; > + struct cpfl_flow_js_pr_key_proto_field *field; > + > + if (!proto) > + return 0; > + > + field_size =3D proto->fields_size; > + if (field_size !=3D 0 && !ipv4_mask) > + return -EINVAL; > + > + if (field_size =3D=3D 0 && ipv4_mask) > + return -EINVAL; > + > + if (field_size =3D=3D 0 && !ipv4_mask) > + return 0; > + > + flag_dst_addr =3D false; > + flag_src_addr =3D false; > + flag_next_proto_id =3D false; > + for (j =3D 0; j < field_size; j++) { > + const char *name; > + > + field =3D &proto->fields[j]; > + name =3D field->name; > + if (strcmp(name, "src_addr") =3D=3D 0) { > + /* match: rte_flow_item->mask */ > + const char *mask; > + > + mask =3D field->mask; > + if (cpfl_check_ipv4_mask(mask, ipv4_mask- > >hdr.src_addr) < 0) > + return -EINVAL; > + flag_src_addr =3D true; > + } else if (strcmp(name, "dst_addr") =3D=3D 0) { > + const char *mask; > + > + mask =3D field->mask; > + if (cpfl_check_ipv4_mask(mask, ipv4_mask- > >hdr.dst_addr) < 0) > + return -EINVAL; > + flag_dst_addr =3D true; > + } else if (strcmp(name, "next_proto_id") =3D=3D 0) { > + uint8_t mask; > + > + mask =3D (uint8_t)field->mask_32b; > + if (mask !=3D ipv4_mask->hdr.next_proto_id) > + return -EINVAL; > + flag_next_proto_id =3D true; > + } else { > + PMD_DRV_LOG(ERR, "not support this name."); > + return -EINVAL; > + } > + } > + if (!flag_src_addr) { > + if (ipv4_mask->hdr.src_addr !=3D (rte_be32_t)0) > + return -EINVAL; > + } > + if (!flag_dst_addr) { > + if (ipv4_mask->hdr.dst_addr !=3D (rte_be32_t)0) > + return -EINVAL; > + } > + if (!flag_next_proto_id) { > + if (ipv4_mask->hdr.next_proto_id !=3D (uint8_t)0) > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int > +cpfl_check_tcp(struct cpfl_flow_js_pr_key_proto *proto, const struct > rte_flow_item_tcp *tcp_mask) > +{ > + int field_size, j; > + int flag_src_port, flag_dst_port; > + struct cpfl_flow_js_pr_key_proto_field *field; > + > + if (!proto) > + return 0; > + > + field_size =3D proto->fields_size; > + if (field_size !=3D 0 && !tcp_mask) > + return -EINVAL; > + > + if (field_size =3D=3D 0 && tcp_mask) > + return -EINVAL; > + > + if (field_size =3D=3D 0 && !tcp_mask) > + return 0; > + > + flag_src_port =3D false; > + flag_dst_port =3D false; > + for (j =3D 0; j < field_size; j++) { > + const char *name; > + uint16_t mask; > + > + field =3D &proto->fields[j]; > + /* match: rte_flow_item_eth.dst */ > + name =3D field->name; > + /* match: rte_flow_item->mask */ > + mask =3D (uint16_t)field->mask_32b; > + if (strcmp(name, "src_port") =3D=3D 0) { > + if (tcp_mask->hdr.src_port !=3D mask) > + return -EINVAL; > + flag_src_port =3D true; > + } else if (strcmp(name, "dst_port") =3D=3D 0) { > + if (tcp_mask->hdr.dst_port !=3D mask) > + return -EINVAL; > + flag_dst_port =3D true; > + } else { > + PMD_DRV_LOG(ERR, "not support this name."); > + return -EINVAL; > + } > + } > + if (!flag_src_port) { > + if (tcp_mask->hdr.src_port !=3D (rte_be16_t)0) > + return -EINVAL; > + } > + if (!flag_dst_port) { > + if (tcp_mask->hdr.dst_port !=3D (rte_be16_t)0) > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int > +cpfl_check_udp(struct cpfl_flow_js_pr_key_proto *proto, const struct > rte_flow_item_udp *udp_mask) > +{ > + int field_size, j; > + bool flag_src_port, flag_dst_port; > + struct cpfl_flow_js_pr_key_proto_field *field; > + > + if (!proto) > + return 0; > + field_size =3D proto->fields_size; > + if (field_size !=3D 0 && !udp_mask) > + return -EINVAL; > + if (field_size =3D=3D 0 && udp_mask) > + return -EINVAL; > + if (field_size =3D=3D 0 && !udp_mask) > + return 0; > + flag_src_port =3D false; > + flag_dst_port =3D false; > + for (j =3D 0; j < field_size; j++) { > + const char *name; > + uint16_t mask; > + > + field =3D &proto->fields[j]; > + /* match: rte_flow_item_eth.dst */ > + name =3D field->name; /* match: rte_flow_item->mask */ > + mask =3D (uint16_t)field->mask_32b; > + if (strcmp(name, "src_port") =3D=3D 0) { > + if (udp_mask->hdr.src_port !=3D mask) > + return -EINVAL; > + flag_src_port =3D true; > + } else if (strcmp(name, "dst_port") =3D=3D 0) { > + if (udp_mask->hdr.dst_port !=3D mask) > + return -EINVAL; > + flag_dst_port =3D true; > + } else { > + PMD_DRV_LOG(ERR, "not support this name."); > + return -EINVAL; > + } > + } > + if (!flag_src_port) { > + if (udp_mask->hdr.src_port !=3D (rte_be16_t)0) > + return -EINVAL; > + } > + if (!flag_dst_port) { > + if (udp_mask->hdr.dst_port !=3D (rte_be16_t)0) > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int > +cpfl_check_vxlan(struct cpfl_flow_js_pr_key_proto *proto, > + const struct rte_flow_item_vxlan *vxlan_mask) > +{ > + int field_size, j; > + struct cpfl_flow_js_pr_key_proto_field *field; > + > + if (!proto) > + return 0; > + field_size =3D proto->fields_size; > + if (field_size !=3D 0 && !vxlan_mask) > + return -EINVAL; > + if (field_size =3D=3D 0 && vxlan_mask) > + return -EINVAL; > + if (field_size =3D=3D 0 && !vxlan_mask) > + return 0; > + for (j =3D 0; j < field_size; j++) { > + const char *name; > + int64_t mask; > + > + field =3D &proto->fields[j]; > + name =3D field->name; > + /* match: rte_flow_item->mask */ > + mask =3D (int64_t)field->mask_32b; > + if (strcmp(name, "vx_vni") =3D=3D 0) { > + if ((int64_t)RTE_BE32(vxlan_mask->hdr.vx_vni) !=3D > mask) > + return -EINVAL; > + } else { > + PMD_DRV_LOG(ERR, "not support this name."); > + return -EINVAL; > + } > + } > + > + return 0; > +} > + > +static int > +cpfl_check_icmp(struct cpfl_flow_js_pr_key_proto *proto, const struct > rte_flow_item_icmp *icmp_mask) > +{ > + int field_size; > + > + if (!proto) > + return 0; > + field_size =3D proto->fields_size; > + if (field_size !=3D 0 && !icmp_mask) > + return -EINVAL; > + if (field_size =3D=3D 0 && icmp_mask) > + return -EINVAL; > + if (field_size =3D=3D 0 && !icmp_mask) > + return 0; > + > + return 0; > +} > + > +static int > +cpfl_check_pattern_key_proto(struct cpfl_flow_js_pr_key_proto *protocols= , > + int proto_size, > + const struct rte_flow_item *items) > +{ > + int i, length; > + int j =3D 0; > + > + length =3D cpfl_get_items_length(items); > + if (proto_size > length - 1) > + return -EINVAL; > + for (i =3D 0; i < proto_size; i++) { > + struct cpfl_flow_js_pr_key_proto *key_proto; > + enum rte_flow_item_type type; > + > + key_proto =3D &protocols[i]; > + /* pr->key->proto->type */ > + type =3D key_proto->type; > + /* pr->key->proto->fields */ > + switch (type) { > + case RTE_FLOW_ITEM_TYPE_ETH: > + if (items[j++].type =3D=3D RTE_FLOW_ITEM_TYPE_ETH) { > + const struct rte_flow_item_eth *eth_mask; > + int ret; > + > + eth_mask =3D (const struct rte_flow_item_eth > *)items[i].mask; > + ret =3D cpfl_check_eth(key_proto, eth_mask); > + if (ret < 0) > + return ret; > + } else { > + return -EINVAL; > + } > + break; > + case RTE_FLOW_ITEM_TYPE_IPV4: > + if (items[j++].type =3D=3D RTE_FLOW_ITEM_TYPE_IPV4) { > + const struct rte_flow_item_ipv4 *ipv4_mask; > + int ret; > + > + ipv4_mask =3D (const struct rte_flow_item_ipv4 > *)items[i].mask; > + ret =3D cpfl_check_ipv4(key_proto, ipv4_mask); > + if (ret < 0) > + return ret; > + } else { > + return -EINVAL; > + } > + break; > + case RTE_FLOW_ITEM_TYPE_TCP: > + if (items[j++].type =3D=3D RTE_FLOW_ITEM_TYPE_TCP) { > + const struct rte_flow_item_tcp *tcp_mask; > + int ret; > + > + tcp_mask =3D (const struct rte_flow_item_tcp > *)items[i].mask; > + ret =3D cpfl_check_tcp(key_proto, tcp_mask); > + if (ret < 0) > + return ret; > + } else { > + return -EINVAL; > + } > + break; > + case RTE_FLOW_ITEM_TYPE_UDP: > + if (items[j++].type =3D=3D RTE_FLOW_ITEM_TYPE_UDP) { > + const struct rte_flow_item_udp *udp_mask; > + int ret; > + > + udp_mask =3D (const struct rte_flow_item_udp > *)items[i].mask; > + ret =3D cpfl_check_udp(key_proto, udp_mask); > + if (ret < 0) > + return ret; > + } else { > + return -EINVAL; > + } > + break; > + case RTE_FLOW_ITEM_TYPE_VXLAN: > + if (items[j++].type =3D=3D RTE_FLOW_ITEM_TYPE_VXLAN) { > + const struct rte_flow_item_vxlan *vxlan_mask; > + int ret; > + > + vxlan_mask =3D (const struct > rte_flow_item_vxlan *)items[i].mask; > + ret =3D cpfl_check_vxlan(key_proto, vxlan_mask); > + if (ret < 0) > + return ret; > + } else { > + return -EINVAL; > + } > + break; > + case RTE_FLOW_ITEM_TYPE_ICMP: > + if (items[j++].type =3D=3D RTE_FLOW_ITEM_TYPE_ICMP) { > + const struct rte_flow_item_icmp *icmp_mask; > + int ret; > + > + icmp_mask =3D (const struct rte_flow_item_icmp > *)items[i].mask; > + ret =3D cpfl_check_icmp(key_proto, icmp_mask); > + if (ret < 0) > + return ret; > + > + } else { > + return -EINVAL; > + } > + break; > + default: > + PMD_DRV_LOG(ERR, "Not support this type: %d.", > type); > + return -EPERM; > + } > + } > + if (items[j].type !=3D RTE_FLOW_ITEM_TYPE_END) > + return -EINVAL; > + > + return 0; > +} > + > +static int > +cpfl_check_pattern_key_attr(struct cpfl_flow_js_pr_key_attr *key_attr, > + const struct rte_flow_attr *attr) > +{ > + /* match: struct rte_flow_attr(ingress,egress) */ > + if (key_attr->ingress !=3D attr->ingress) { > + PMD_DRV_LOG(DEBUG, "ingress not match."); > + return -EINVAL; > + } > + if (key_attr->egress !=3D attr->egress) { > + PMD_DRV_LOG(DEBUG, "egress not match."); > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int > +cpfl_check_pattern_key(struct cpfl_flow_js_pr *pattern, > + const struct rte_flow_item *items, > + const struct rte_flow_attr *attr) > +{ > + int ret; > + > + /* pr->key */ > + /* pr->key->protocols */ > + ret =3D cpfl_check_pattern_key_proto(pattern->key.protocols, > + pattern->key.proto_size, items); > + if (ret < 0) > + return -EINVAL; > + /* pr->key->attributes */ > + ret =3D cpfl_check_pattern_key_attr(pattern->key.attributes, attr); > + if (ret < 0) > + return -EINVAL; > + > + return 0; > +} > + > +/* output: struct cpfl_flow_pr_action* pr_action */ > +static int > +cpfl_parse_pattern_rules(struct cpfl_itf *itf, > + struct cpfl_flow_js_parser *parser, > + const struct rte_flow_item *items, > + const struct rte_flow_attr *attr, > + struct cpfl_flow_pr_action *pr_action) > +{ > + int i, size; > + struct cpfl_flow_js_pr *pattern; > + > + size =3D parser->pr_size; > + for (i =3D 0; i < size; i++) { > + int ret; > + > + pattern =3D &parser->patterns[i]; > + ret =3D cpfl_check_pattern_key(pattern, items, attr); > + if (ret < 0) > + continue; > + /* pr->actions */ > + ret =3D cpfl_parse_pr_actions(itf, pattern->actions, pattern- > >actions_size, > + items, attr, pr_action); > + return ret; > + } > + > + return -EINVAL; > +} > + > +int > +cpfl_flow_parse_items(struct cpfl_itf *itf, > + struct cpfl_flow_js_parser *parser, > + const struct rte_flow_item *items, > + const struct rte_flow_attr *attr, > + struct cpfl_flow_pr_action *pr_action) > +{ > + int ret; > + > + /* Pattern Rules */ > + ret =3D cpfl_parse_pattern_rules(itf, parser, items, attr, pr_action); > + return ret; > +} > + > +/* modifications rules */ > +static int > +cpfl_check_actions_vxlan_encap(struct cpfl_flow_mr_key_action_vxlan_enca= p > *encap, > + const struct rte_flow_action *action) > +{ > + const struct rte_flow_action_vxlan_encap *action_vxlan_encap; > + struct rte_flow_item *definition; > + int def_length, i, proto_size; > + > + action_vxlan_encap =3D (const struct rte_flow_action_vxlan_encap > *)action->conf; > + definition =3D action_vxlan_encap->definition; > + def_length =3D cpfl_get_items_length(definition); > + proto_size =3D encap->proto_size; > + if (proto_size !=3D def_length - 1) { > + PMD_DRV_LOG(DEBUG, "protocols not match."); > + return -EINVAL; > + } > + for (i =3D 0; i < proto_size; i++) { > + enum rte_flow_item_type proto; > + > + proto =3D encap->protocols[i]; > + if (proto =3D=3D RTE_FLOW_ITEM_TYPE_VLAN) { > + if (definition[i].type !=3D RTE_FLOW_ITEM_TYPE_VOID) { > + PMD_DRV_LOG(DEBUG, "protocols not > match."); > + return -EINVAL; > + } > + } else if (proto !=3D definition[i].type) { > + PMD_DRV_LOG(DEBUG, "protocols not match."); > + return -EINVAL; > + } > + } > + > + return 0; > +} > + > +/* 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: action matches > RTE_FLOW_ACTION_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; > + } > + } > + > + 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; > + temp =3D mr_key_action + index; > + if (temp->type =3D=3D RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP) { > + const struct rte_flow_action_vxlan_encap > *action_vxlan_encap; > + struct rte_flow_item *definition; > + int def_length, k; > + > + action_vxlan_encap =3D > + (const struct rte_flow_action_vxlan_encap *)temp- > >encap.action->conf; > + definition =3D action_vxlan_encap->definition; > + def_length =3D cpfl_get_items_length(definition); > + for (k =3D 0; k < def_length - 1; k++) { > + if ((strcmp(hint, "eth") =3D=3D 0 && > + definition[k].type =3D=3D > RTE_FLOW_ITEM_TYPE_ETH) || > + (strcmp(hint, "ipv4") =3D=3D 0 && > + definition[k].type =3D=3D > RTE_FLOW_ITEM_TYPE_IPV4) || > + (strcmp(hint, "udp") =3D=3D 0 && > + definition[k].type =3D=3D > RTE_FLOW_ITEM_TYPE_UDP) || > + (strcmp(hint, "tcp") =3D=3D 0 && > + definition[k].type =3D=3D > RTE_FLOW_ITEM_TYPE_TCP) || > + (strcmp(hint, "vxlan") =3D=3D 0 && > + definition[k].type =3D=3D > RTE_FLOW_ITEM_TYPE_VXLAN)) { > + addr =3D (const uint8_t > *)(definition[k].spec); > + if (start > 255) { > + *byte_len =3D 0; > + PMD_DRV_LOG(ERR, "byte > length is too long%s", > + hint); > + return -EINVAL; > + } > + memcpy(buffer + start, addr + offset, > size); > + break; > + } /* TODO: more hint... */ > + } > + if (k =3D=3D def_length - 1) { > + *byte_len =3D 0; > + PMD_DRV_LOG(ERR, "can not find > corresponding hint: %s", hint); > + return -EINVAL; > + } > + } else { > + *byte_len =3D 0; > + PMD_DRV_LOG(ERR, "Not support this type: %d.", > temp->type); > + return -EINVAL; > + } > + /* else TODO: more type... */ > + > + start +=3D size; > + } > + *byte_len =3D start; > + > + return 0; > +} > + > +static int > +cpfl_parse_mr_action(struct cpfl_flow_js_mr_action *action, > + struct cpfl_flow_mr_key_action *mr_key_action, > + struct cpfl_flow_mr_action *mr_action) > +{ > + enum cpfl_flow_mr_action_type type; > + > + /* mr->action->type */ > + type =3D action->type; > + /* mr->action->data */ > + if (type =3D=3D CPFL_JS_MR_ACTION_TYPE_MOD) { > + struct cpfl_flow_js_mr_layout *layout; > + > + mr_action->type =3D CPFL_JS_MR_ACTION_TYPE_MOD; > + mr_action->mod.byte_len =3D 0; > + mr_action->mod.prof =3D action->mod.prof; > + layout =3D action->mod.layout; > + if (layout) { > + int ret; > + > + memset(mr_action->mod.data, 0, sizeof(mr_action- > >mod.data)); > + ret =3D cpfl_parse_layout(layout, action- > >mod.layout_size, mr_key_action, > + mr_action->mod.data, > &mr_action->mod.byte_len); > + if (ret < 0) > + return -EINVAL; > + } > + return 0; > + } > + PMD_DRV_LOG(ERR, "Not support this type: %d.", type); > + > + return -EINVAL; > +} > + > +static int > +cpfl_check_mod_key(struct cpfl_flow_js_mr *mr, const struct rte_flow_act= ion > *actions, > + struct cpfl_flow_mr_key_action *mr_key_action) > +{ > + int key_action_size; > + > + /* mr->key->actions */ > + key_action_size =3D mr->key.actions_size; > + return cpfl_parse_mr_key_action(mr->key.actions, key_action_size, > actions, mr_key_action); > +} > + > +/* output: struct cpfl_flow_mr_action *mr_action */ > +static int > +cpfl_parse_mod_rules(struct cpfl_flow_js_parser *parser, const struct > rte_flow_action *actions, > + struct cpfl_flow_mr_action *mr_action) > +{ > + int i, size; > + struct cpfl_flow_mr_key_action > mr_key_action[CPFL_MOD_KEY_NUM_MAX] =3D {0}; > + > + size =3D parser->mr_size; > + > + for (i =3D 0; i < size; i++) { > + int ret; > + struct cpfl_flow_js_mr *mr; > + > + mr =3D &parser->modifications[i]; > + ret =3D cpfl_check_mod_key(mr, actions, mr_key_action); > + if (ret < 0) > + continue; > + /* mr->action */ > + ret =3D cpfl_parse_mr_action(&mr->action, mr_key_action, > mr_action); > + if (!ret) > + return 0; > + } > + > + return -EINVAL; > +} > + > +int > +cpfl_flow_parse_actions(struct cpfl_flow_js_parser *parser, const struct > rte_flow_action *actions, > + struct cpfl_flow_mr_action *mr_action) > +{ > + /* modifications rules */ > + if (!parser->modifications) { > + PMD_DRV_LOG(INFO, "The modifications is optional."); > + return 0; > + } > + > + return cpfl_parse_mod_rules(parser, actions, mr_action); > +} > + > +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])); > +} > + > +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); [Liu, Mingxia] better to change the type of 'dev_id' to uint16_t? > + > + 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); > + [Liu, Mingxia] better to change the type of 'dev_id' to uint16_t? > + 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); > + [Liu, Mingxia] better to change the type of 'dev_id' to uint16_t? > + 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); > + [Liu, Mingxia] better to change the type of 'dev_id' to uint16_t? > + return true; > +}