From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-eopbgr130058.outbound.protection.outlook.com [40.107.13.58]) by dpdk.org (Postfix) with ESMTP id BDD221B0F7 for ; Thu, 6 Dec 2018 08:23:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Q3Q981iYNNRy5O9US1jOHcJ2PjOJNZODUmbQJ+lgtK4=; b=BvE7Z4OIg5jmWuI8fNDAK01cL78F5TyHibYL/JMEmI/OAvZzwSUhhtJqVT1JkGtiYyNK9ygboSOHYqo2cOeQvxlBX/ZtvEFZ82xwpsxGwpjA0bdBBbpRG67gx2xoYxFRO98kBZH29D2Gz71gqUB9YATGWKW8xvFweIs6DvPv6qs= Received: from AM0PR05MB4180.eurprd05.prod.outlook.com (52.134.90.157) by AM0PR05MB4308.eurprd05.prod.outlook.com (52.134.91.141) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1404.20; Thu, 6 Dec 2018 07:23:18 +0000 Received: from AM0PR05MB4180.eurprd05.prod.outlook.com ([fe80::417b:c46a:46cb:3830]) by AM0PR05MB4180.eurprd05.prod.outlook.com ([fe80::417b:c46a:46cb:3830%4]) with mapi id 15.20.1382.023; Thu, 6 Dec 2018 07:23:18 +0000 From: Asaf Penso To: "dev@dpdk.org" CC: Shahaf Shuler , Ori Kam , Thomas Monjalon , Adrien Mazarguil Thread-Topic: [PATCH] ethdev: add function to print a flow Thread-Index: AQHUhy6uk2CN7DZIq0ujCLWKDIF8yaVxWoYg Date: Thu, 6 Dec 2018 07:23:18 +0000 Message-ID: References: <1543418758-23748-1-git-send-email-asafp@mellanox.com> In-Reply-To: <1543418758-23748-1-git-send-email-asafp@mellanox.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=asafp@mellanox.com; x-originating-ip: [193.47.165.251] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; AM0PR05MB4308; 6:6l4sAgYajXxbnaN80n7oRxnY1XwBB7wsQNvMZAJ448a1H0El9tQhScumasOJZ3epv2HQew0eAHItXR1bH6BGP4Q+36FOowWylHYTm92Reumyrveg6jqXcufZ/ZZBeUntlbDhV8SxPYCk+wCSVC5gOr0ucR81ZVlr+Z6vuafSKCoBBst84xw+RTxuc6oRmHAtwcwDUzf7E7jQ6tO6kgPOR4MkZocX5NduP06tx7G3tAkjJ7O4NPTm4KmxQoLk58GGC4nSsbMzXbkQR3mZG5NOxYLadBHicOob2NdBzYcQOViE0TSMfKCfPFyBh8xR95XP8VrW4LpONsK5vica6aI5umBxKCufPigMvcTDpGsRSUIa3kb9rsldlejemKdxQxnE4h3CQuuqm6/IyqOQoWTLpHRYeXERzl0Mg8NeNUrke3h3wKp7zA6fsb9DIbwBTDWDyMiQoGVTiNR/vML0wwxm+w==; 5:av7iEkwKzCFEcFW8M5JuBIJqVBPDtzIUG8FqJ85QvNukrP7V5M1NggLvD0mOOWUubkK0J47y55H6UzQK6LcCfaLI1Jzo6TdPG0/UDv53YXZjqt1Q9Qt9CypNX0QH3dYah6e8B4e3eq3c05P+AATRpS3kR0L2fGrGCUaVdyAd0I4=; 7:TsKjYqKfHUR0HxtHB+ctwqSWLA0lAlkaGSBp/bwLxJrSbxTUfKHiQGjOgyn9JCDYMHiXdxXUaj3BoEpZb3NhbYolYB9AMfkcff4oaopygx98UDt2nuRCQGWUUmnm7ZEQY4A4Nj897frO6c32Dp5cjg== x-ms-exchange-antispam-srfa-diagnostics: SOS; x-ms-office365-filtering-correlation-id: 2e06c956-59da-4be1-6c91-08d65b4bb1ea x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390098)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:AM0PR05MB4308; x-ms-traffictypediagnostic: AM0PR05MB4308: x-ld-processed: a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr x-microsoft-antispam-prvs: x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(10201501046)(3002001)(3231455)(999002)(944501520)(52105112)(93006095)(93001095)(6055026)(148016)(149066)(150057)(6041310)(20161123558120)(20161123562045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123564045)(201708071742011)(7699051); SRVR:AM0PR05MB4308; BCL:0; PCL:0; RULEID:; SRVR:AM0PR05MB4308; x-forefront-prvs: 087894CD3C x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(376002)(396003)(39860400002)(346002)(136003)(366004)(13464003)(53754006)(189003)(199004)(53936002)(14454004)(53546011)(6436002)(6506007)(7696005)(76176011)(4744004)(68736007)(14444005)(476003)(256004)(74316002)(8936002)(6916009)(446003)(86362001)(575784001)(4326008)(11346002)(229853002)(478600001)(66066001)(99286004)(1730700003)(81166006)(71190400001)(2906002)(71200400001)(81156014)(105586002)(106356001)(486006)(102836004)(26005)(97736004)(2351001)(8676002)(6246003)(25786009)(33656002)(6116002)(3846002)(9686003)(5640700003)(316002)(186003)(2501003)(5660300001)(305945005)(55016002)(54906003)(7736002); DIR:OUT; SFP:1101; SCL:1; SRVR:AM0PR05MB4308; H:AM0PR05MB4180.eurprd05.prod.outlook.com; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: A7mzm/pfcg23FMD546dSx3qUDYWQlarboY0TKzMtUy9bUuCwtkf67NcCtAO8dBiLxsfGThz9XZuFZGlubLd8rGmjdviV3UAWeUvYcLmeB2Ig5CzaagrJc3phaNa0Z4OBCtBik87oxUcc0N32ZabSkpFOiUz0bxjxXo+B5OOnC/pgjV6ullStBpZ9t9TmlTCm97vNka6MZkI2nCrlEmhkSxQr8mvCWJGn4AN8D0OwlLmqfQa5tuDHanslRVeQJac7Vo2vABRjzDvtyZXvkq34Ld3QPkYthqzTlQC0Ubf1FgJ5uMQ9ElgHdoSFKXUl+FXEg8VI+3lbBzFBgpdtJK03FbyGGy+8vh4xowevTqN1ctc= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2e06c956-59da-4be1-6c91-08d65b4bb1ea X-MS-Exchange-CrossTenant-originalarrivaltime: 06 Dec 2018 07:23:18.4038 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR05MB4308 Subject: Re: [dpdk-dev] [PATCH] ethdev: add function to print a flow X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Dec 2018 07:23:20 -0000 Hi All, would be glad to have comments on this patch. Good day! Regards, Asaf Penso > -----Original Message----- > From: Asaf Penso > Sent: Wednesday, November 28, 2018 5:26 PM > To: Adrien Mazarguil > Cc: Asaf Penso ; dev@dpdk.org; Shahaf Shuler > ; Ori Kam ; Thomas > Monjalon > Subject: [PATCH] ethdev: add function to print a flow >=20 > Flow contains the following information: port id, attributes, patterns an= d > actions. > The function rte_flow_print prints all above information. >=20 > It can be used for debugging purposes to validate the behavior of differe= nt > dpdk applications. >=20 > Example: running testpmd with the following flow create: > flow create 1 transfer ingress > pattern eth src is 52:54:00:15:b1:b1 dst is 24:8A:07:8D:AE:C6 / end actio= ns > of_push_vlan ethertype 0x8100 / of_set_vlan_vid vlan_vid 0x888 / > of_set_vlan_pcp vlan_pcp 7 / port_id id 0 / end Will result in this outpu= t: > Print flow info > port_id =3D1 > group =3D0 > priority =3D0 > ingress =3D1 > egress =3D0 > transfer =3D1 > group =3D0 > reserved =3D0 > pattern type =3D9 > name=3DRTE_FLOW_ITEM_TYPE_ETH > spec type=3D0x0, src=3D52:54:00:15:b1:b1, dst=3D24:8a:07:8d:ae:c6 > mask type=3D0x0, src=3Dff:ff:ff:ff:ff:ff, dst=3Dff:ff:ff:ff:ff:ff actio= ns type =3D23 > name=3DRTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN > ethertype=3D0x81 > actions type =3D24 > name=3DRTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID > vlan_vid=3D0x8808 > actions type =3D25 > name=3DRTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP > vlan_pcp=3D7 > actions type =3D13 > name=3DRTE_FLOW_ACTION_TYPE_PORT_ID > id=3D0 > reserved=3D0 >=20 > Signed-off-by: Asaf Penso > --- > lib/librte_ethdev/rte_ethdev_version.map | 1 + > lib/librte_ethdev/rte_flow.c | 226 > ++++++++++++++++++++++++++++++ > lib/librte_ethdev/rte_flow.h | 31 ++++ > 3 files changed, 258 insertions(+), 0 deletions(-) >=20 > diff --git a/lib/librte_ethdev/rte_ethdev_version.map > b/lib/librte_ethdev/rte_ethdev_version.map > index 92ac3de..7676983 100644 > --- a/lib/librte_ethdev/rte_ethdev_version.map > +++ b/lib/librte_ethdev/rte_ethdev_version.map > @@ -249,6 +249,7 @@ EXPERIMENTAL { > rte_eth_switch_domain_free; > rte_flow_conv; > rte_flow_expand_rss; > + rte_flow_print; > rte_mtr_capabilities_get; > rte_mtr_create; > rte_mtr_destroy; > diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c = index > 3277be1..742d892 100644 > --- a/lib/librte_ethdev/rte_flow.c > +++ b/lib/librte_ethdev/rte_flow.c > @@ -16,6 +16,8 @@ > #include "rte_flow_driver.h" > #include "rte_flow.h" >=20 > +int rte_flow_logtype; > + > /** > * Flow elements description tables. > */ > @@ -202,6 +204,222 @@ struct rte_flow_desc_data { > NULL, rte_strerror(ENOSYS)); > } >=20 > +/* Example: > + * > + * struct eth_addr mac; > + * [...] > + * printf("The Ethernet address is "RTE_ETH_ADDR_FMT"\n", > + * RTE_ETH_ADDR_ARGS(mac)); > + * > + */ > +#define RTE_ETH_ADDR_FMT \ > + > "%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"P > RIx8 > +#define RTE_ETH_ADDR_ARGS(addr) > RTE_ETH_ADDR_BYTES_ARGS((addr).ea) > +#define RTE_ETH_ADDR_BYTES_ARGS(bytes) \ > + (bytes)[0], (bytes)[1], (bytes)[2], (bytes)[3], (bytes)[4], (bytes)[5] > + > +/* Print the flow fields. */ > +void __rte_experimental > +rte_flow_print(uint16_t port_id, > + const struct rte_flow_attr *attr, > + const struct rte_flow_item pattern[], > + const struct rte_flow_action actions[]) { > + RTE_FLOW_LOG(INFO, "Print flow info\n"); > + RTE_FLOW_LOG(INFO, "port_id =3D%u\n", port_id); > + RTE_FLOW_LOG(INFO, "group =3D%u\n", attr->group); > + RTE_FLOW_LOG(INFO, "priority =3D%u\n", attr->priority); > + RTE_FLOW_LOG(INFO, "ingress =3D%u\n", attr->ingress); > + RTE_FLOW_LOG(INFO, "egress =3D%u\n", attr->egress); > + RTE_FLOW_LOG(INFO, "transfer =3D%u\n", attr->transfer); > + RTE_FLOW_LOG(INFO, "group =3D%u\n", attr->group); > + RTE_FLOW_LOG(INFO, "reserved =3D%u\n", attr->reserved); > + > + for (; pattern->type !=3D RTE_FLOW_ITEM_TYPE_END; pattern++) { > + RTE_FLOW_LOG(INFO, "pattern type =3D%u\n", pattern- > >type); > + switch (pattern->type) { > + case RTE_FLOW_ITEM_TYPE_ETH: { > + RTE_FLOW_LOG(INFO, " > name=3DRTE_FLOW_ITEM_TYPE_ETH\n"); > + if (pattern->spec) { > + const struct rte_flow_item_eth *spec =3D > + pattern->spec; > + RTE_FLOW_LOG(INFO, " spec type=3D0x%x, " > + "src=3D"RTE_ETH_ADDR_FMT", > dst=3D"RTE_ETH_ADDR_FMT > + "\n", > + spec->type, > + RTE_ETH_ADDR_BYTES_ARGS(spec- > >src.addr_bytes), > + RTE_ETH_ADDR_BYTES_ARGS(spec- > >dst.addr_bytes)); > + } > + > + if (pattern->mask) { > + const struct rte_flow_item_eth *mask =3D > + pattern->mask; > + RTE_FLOW_LOG(INFO, " mask type=3D0x%x, " > + "src=3D"RTE_ETH_ADDR_FMT", > dst=3D"RTE_ETH_ADDR_FMT > + "\n", > + mask->type, > + RTE_ETH_ADDR_BYTES_ARGS(mask- > >src.addr_bytes), > + RTE_ETH_ADDR_BYTES_ARGS(mask- > >dst.addr_bytes)); > + } > + break; > + } > + case RTE_FLOW_ITEM_TYPE_VLAN: { > + RTE_FLOW_LOG(INFO, " > name=3DRTE_FLOW_ITEM_TYPE_VLAN\n"); > + if (pattern->spec) { > + const struct rte_flow_item_vlan *spec =3D > + pattern->spec; > + RTE_FLOW_LOG(INFO, " spec tci=3D0x%x\n", > + spec->tci); > + RTE_FLOW_LOG(INFO, " spec > inner_type=3D%u\n", > + spec->inner_type); > + } > + if (pattern->mask) { > + const struct rte_flow_item_vlan *mask =3D > + pattern->mask; > + RTE_FLOW_LOG(INFO, " mask tci=3D0x%x\n", > + mask->tci); > + RTE_FLOW_LOG(INFO, " mask > inner_type=3D%u\n", > + mask->inner_type); > + } > + break; > + } > + case RTE_FLOW_ITEM_TYPE_IPV4: { > + RTE_FLOW_LOG(INFO, " > name=3DRTE_FLOW_ITEM_TYPE_IPV4\n"); > + if (pattern->spec) { > + const struct rte_flow_item_ipv4 *spec =3D > + pattern->spec; > + RTE_FLOW_LOG(INFO, " spec > version_ihl=3D%u\n", > + spec->hdr.version_ihl); > + RTE_FLOW_LOG(INFO, " spec > type_of_service=3D%u\n", > + spec->hdr.type_of_service); > + RTE_FLOW_LOG(INFO, " spec > total_length=3D%u\n", > + spec->hdr.total_length); > + RTE_FLOW_LOG(INFO, " spec > packet_id=3D%u\n", > + spec->hdr.packet_id); > + RTE_FLOW_LOG(INFO, " spec > fragment_offset=3D%u\n", > + spec->hdr.fragment_offset); > + RTE_FLOW_LOG(INFO, " spec > time_to_live=3D%u\n", > + spec->hdr.time_to_live); > + RTE_FLOW_LOG(INFO, " spec > next_proto_id=3D%u\n", > + spec->hdr.next_proto_id); > + RTE_FLOW_LOG(INFO, " spec > hdr_checksum=3D0x%x\n", > + spec->hdr.hdr_checksum); > + RTE_FLOW_LOG(INFO, > + " spec src_addr=3D%d.%d.%d.%d\n", > + (spec->hdr.src_addr & 0x000000FF), > + (spec->hdr.src_addr & 0x0000FF00) > >> 8, > + (spec->hdr.src_addr & 0x00FF0000) > >> 16, > + (spec->hdr.src_addr & 0xFF000000) > + >> 24); > + RTE_FLOW_LOG(INFO, > + " spec dst_addr=3D%d.%d.%d.%d\n", > + (spec->hdr.dst_addr & 0x000000FF), > + (spec->hdr.dst_addr & 0x0000FF00) > >> 8, > + (spec->hdr.dst_addr & 0x00FF0000) > >> 16, > + (spec->hdr.dst_addr & 0xFF000000) > + >> 24); > + } > + > + if (pattern->mask) { > + const struct rte_flow_item_ipv4 *mask =3D > + pattern->mask; > + RTE_FLOW_LOG(INFO, " mask > version_ihl=3D%u\n", > + mask->hdr.version_ihl); > + RTE_FLOW_LOG(INFO, " mask > type_of_service=3D%u\n", > + mask->hdr.type_of_service); > + RTE_FLOW_LOG(INFO, " mask > total_length=3D%u\n", > + mask->hdr.total_length); > + RTE_FLOW_LOG(INFO, " mask > packet_id=3D%u\n", > + mask->hdr.packet_id); > + RTE_FLOW_LOG(INFO, " mask > fragment_offset=3D%u\n", > + mask->hdr.fragment_offset); > + RTE_FLOW_LOG(INFO, " mask > time_to_live=3D%u\n", > + mask->hdr.time_to_live); > + RTE_FLOW_LOG(INFO, " mask > next_proto_id=3D%u\n", > + mask->hdr.next_proto_id); > + RTE_FLOW_LOG(INFO, " mask > hdr_checksum=3D0x%x\n", > + mask->hdr.hdr_checksum); > + RTE_FLOW_LOG(INFO, > + " mask src_addr=3D%d.%d.%d.%d\n", > + (mask->hdr.src_addr & 0x000000FF), > + (mask->hdr.src_addr & 0x0000FF00) > >> 8, > + (mask->hdr.src_addr & 0x00FF0000) > >> 16, > + (mask->hdr.src_addr & 0xFF000000) > + >> 24); > + RTE_FLOW_LOG(INFO, > + " mask dst_addr=3D%d.%d.%d.%d\n", > + (mask->hdr.dst_addr & 0x000000FF), > + (mask->hdr.dst_addr & 0x0000FF00) > >> 8, > + (mask->hdr.dst_addr & 0x00FF0000) > >> 16, > + (mask->hdr.dst_addr & 0xFF000000) > + >> 24); > + } > + break; > + } > + default: > + RTE_FLOW_LOG(INFO, "unfamiliar pattern item\n"); > + } > + } > + > + for (; actions->type !=3D RTE_FLOW_ACTION_TYPE_END; actions++) { > + RTE_FLOW_LOG(INFO, "actions type =3D%u\n", actions- > >type); > + switch (actions->type) { > + case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN: { > + RTE_FLOW_LOG(INFO, > + " > name=3DRTE_FLOW_ACTION_TYPE_OF_POP_VLAN\n"); > + break; > + } > + case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN: { > + RTE_FLOW_LOG(INFO, > + " > name=3DRTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN\n"); > + if (actions->conf) { > + const struct rte_flow_action_of_push_vlan > + *conf =3D actions->conf; > + RTE_FLOW_LOG(INFO, " > ethertype=3D0x%x\n", > + conf->ethertype); > + } > + break; > + } > + case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID: { > + RTE_FLOW_LOG(INFO, > + " > name=3DRTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID\n"); > + if (actions->conf) { > + const struct > rte_flow_action_of_set_vlan_vid > + *conf =3D actions->conf; > + RTE_FLOW_LOG(INFO, " vlan_vid=3D0x%x\n", > + conf->vlan_vid); > + } > + break; > + } > + case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP: { > + RTE_FLOW_LOG(INFO, > + " > name=3DRTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP\n"); > + if (actions->conf) { > + const struct > rte_flow_action_of_set_vlan_pcp > + *conf =3D actions->conf; > + RTE_FLOW_LOG(INFO, " vlan_pcp=3D%u\n", > + conf->vlan_pcp); > + } > + break; > + } > + case RTE_FLOW_ACTION_TYPE_PORT_ID: { > + RTE_FLOW_LOG(INFO, > + " > name=3DRTE_FLOW_ACTION_TYPE_PORT_ID\n"); > + if (actions->conf) { > + const struct rte_flow_action_port_id > + *conf =3D actions->conf; > + RTE_FLOW_LOG(INFO, " id=3D%u\n", conf- > >id); > + RTE_FLOW_LOG(INFO, " reserved=3D%u\n", > + conf->reserved); > + } > + break; > + } > + default: > + RTE_FLOW_LOG(INFO, "unfamiliar action item\n"); > + } > + } > +} > + > /* Create a flow rule on a given port. */ struct rte_flow * > rte_flow_create(uint16_t port_id, @@ -1001,3 +1219,11 @@ enum > rte_flow_conv_item_spec_type { > }; > return lsize; > } > + > +RTE_INIT(flow_init_log) > +{ > + rte_flow_logtype =3D rte_log_register("lib.flow"); > + if (rte_flow_logtype >=3D 0) > + rte_log_set_level(rte_flow_logtype, RTE_LOG_INFO); } > + > diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h = index > c0fe879..0a7e70b 100644 > --- a/lib/librte_ethdev/rte_flow.h > +++ b/lib/librte_ethdev/rte_flow.h > @@ -28,6 +28,12 @@ > #include > #include > #include > +#include > + > +extern int rte_flow_logtype; > + > +#define RTE_FLOW_LOG(level, ...) \ > + rte_log(RTE_LOG_ ## level, rte_flow_logtype, "" __VA_ARGS__) >=20 > #ifdef __cplusplus > extern "C" { > @@ -2414,6 +2420,31 @@ enum rte_flow_conv_op { > struct rte_flow_error *error); >=20 > /** > + * Print the flow fields. > + * > + * The flow contains the port id, different attributes, the pattern's > + * items and the action's items, which are all being printed. > + * > + * @b EXPERIMENTAL: this API may change without prior notice > + * > + * @param port_id > + * Port identifier of Ethernet device. > + * @param[in] attr > + * Flow rule attributes. > + * @param[in] pattern > + * Pattern specification (list terminated by the END pattern item). > + * @param[in] actions > + * Associated actions (list terminated by the END action). > + * > + * @note not all enum values of patterns and actions are printed. > + */ > +void __rte_experimental > +rte_flow_print(uint16_t port_id, > + const struct rte_flow_attr *attr, > + const struct rte_flow_item pattern[], > + const struct rte_flow_action actions[]); > + > +/** > * Create a flow rule on a given port. > * > * @param port_id > -- > 1.7.1