From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 8EAC0A04AF; Sun, 3 May 2020 16:58:57 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 778741D50B; Sun, 3 May 2020 16:58:57 +0200 (CEST) Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00080.outbound.protection.outlook.com [40.107.0.80]) by dpdk.org (Postfix) with ESMTP id AB8381D509 for ; Sun, 3 May 2020 16:58:55 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=YJJd99wTOUSvzH9eYyFeElu2qzjNNBPZ5Kw5fG2Ua/Ca4a1AzPtX+j5o7Qu5CDCQGG47dtT3AmARht9bDMHeoaL6ZyZM0hjWiGcd0uepXg+0ZnUQigwDozCXu6PTwFMY1/1illGf0h268+FVmYl+hvw7MNmLjCoNTp1X5+cpY0/LBDR/6wvBWApZxJfkf/QSQwDFOgh01HSWom4npDe1wZRvxcL1C+HpiroW/yKHF/kYW4qogSYOWrMS5bSDM6lYYGzjm7VrN/9Wp3yUve92+Uqv4LOkzC3BSSacnwrbCcaOay9hHkyVHBhA3TN/UKAkoqD3IgmsEKcQrYWhcoASNA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=8SlsvM5WtVT1WI6qcLub2Wt/6B/gZ0GGmrEweWGaMAo=; b=gCWEEVs9Kw/nToOSTnHm4OuwlovE4PTJo1bCByV0kx9a050PpW6fxCjjGR2CdAnd+Wyu27V3k5965I0wbZ2Kr6F7Dr/BQMQudYSWPsqS2zZt0igD+5QNtGeazVxPpREieRz7CRE1NbrZLN1HhNKpncnM4MJQMa+ty/tY+CUqtoFpUlmEMmqUjqp5QpPRWTJVaRp0Nwvz2mIcmXsI1GarMgg2IaHabTxeOt1HUxPITm0JsrfMRVfOW7CwQ6gWth7R6vfY+uzK+3m/QH9u4OOxBIj64fC5yP6NOFoeRtp6KqXryQRuekkWCrQt4PtyVDNTr9W2bXlnsJcni6WdenTjrQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=mellanox.com; dmarc=pass action=none header.from=mellanox.com; dkim=pass header.d=mellanox.com; arc=none 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=8SlsvM5WtVT1WI6qcLub2Wt/6B/gZ0GGmrEweWGaMAo=; b=jw8JfoobxtOkaUcF+Od/x/oN3loP1QtgKcQnodkDDTz3//5gWvnp4ETCXINkUnaRpVWOSsjWHrr8Zi7mgmyxApWopjtfYmHZeVg4yTHl/GxkZmerRm1LfVLA9Fd6cEBOLmgKozj8AP+zYl443bSDx16Pdoj68ChtRIs3g65keRI= Received: from AM6PR05MB5176.eurprd05.prod.outlook.com (2603:10a6:20b:63::30) by AM6PR05MB5319.eurprd05.prod.outlook.com (2603:10a6:20b:69::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2958.20; Sun, 3 May 2020 14:58:54 +0000 Received: from AM6PR05MB5176.eurprd05.prod.outlook.com ([fe80::f5cd:b10f:5f1b:4b22]) by AM6PR05MB5176.eurprd05.prod.outlook.com ([fe80::f5cd:b10f:5f1b:4b22%7]) with mapi id 15.20.2958.029; Sun, 3 May 2020 14:58:54 +0000 From: Ori Kam To: Bill Zhou , "ferruh.yigit@intel.com" , Matan Azrad , "wenzhuo.lu@intel.com" , "beilei.xing@intel.com" , "bernard.iremonger@intel.com" , "john.mcnamara@intel.com" , "marko.kovacevic@intel.com" CC: "dev@dpdk.org" Thread-Topic: [PATCH v4] app/testpmd: support flow aging Thread-Index: AQHWISk1lWw0EyHldk2H0QFh+KJZKaiWdC2A Date: Sun, 3 May 2020 14:58:54 +0000 Message-ID: References: <20200502140023.5274-1-dongz@mellanox.com> <20200503085948.27167-1-dongz@mellanox.com> In-Reply-To: <20200503085948.27167-1-dongz@mellanox.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: mellanox.com; dkim=none (message not signed) header.d=none;mellanox.com; dmarc=none action=none header.from=mellanox.com; x-originating-ip: [89.208.130.33] x-ms-publictraffictype: Email x-ms-office365-filtering-ht: Tenant x-ms-office365-filtering-correlation-id: 3ee179da-db87-483a-d34f-08d7ef727fae x-ms-traffictypediagnostic: AM6PR05MB5319:|AM6PR05MB5319: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:7219; x-forefront-prvs: 0392679D18 x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: 3Kbc6jsL/ADM7z/rh+t+XtaDp3yI+7/yXrq0omisIEr+i3tBTJ+1Y+MFy26apnwYRZKgLQNgfMdSCNL8sxiXb+mC3FpakEhG1olAOkJLlVzh++UfjBmnqW5QZTziJD4u/zjjOSUIL2HuoYfFapz75lmghCJs8tLpQqJRO/735j9hwW7qRSdCyp+5z9jBhf7LtvF9l3Y1FVm6CuSqZCyEZU+H0JQ4FgWSoWIqb8cTBlsFVXQ/DzwDzUeaQiB/WVCutZhE9PjiowlEVny8Qjc7yeACLguKutCwPHefthrMK6hyKqI+lXgbaKoOlorVNlNOrQwH5380NHC2Zcyt+vH/Ec/HK2OrqHth2IoVjFriSpnRexTxNeUaIloNpWlkxu/zoCY33hu9kf5PnCfVIveVyuINm07FsyzMH/TCOWl1gqu7qBQquNV2XZSipDqBuu1t x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM6PR05MB5176.eurprd05.prod.outlook.com; PTR:; CAT:NONE; SFTY:; SFS:(4636009)(136003)(366004)(39860400002)(396003)(346002)(376002)(86362001)(64756008)(66476007)(66556008)(76116006)(478600001)(4326008)(5660300002)(66446008)(8676002)(110136005)(9686003)(316002)(6506007)(66946007)(71200400001)(2906002)(30864003)(8936002)(7696005)(55016002)(186003)(26005)(33656002)(52536014); DIR:OUT; SFP:1101; x-ms-exchange-antispam-messagedata: SbGsolJoWFAOlWOUopUJDCdFQ4lQpAcU7Gw9IDgg51/aLrQNp3AoH2bp8+Ef2nUs5m5jUbalOl6n69s14gmz5ouw1aNk34NUikcg/DHKdwk78XUkkgEHRerzlLp/RKCeBw5plAblEqEumYb0Zl+rl1o/DPJ0lDPPhnbqwfNnrmPUDAHXbjKL9ACsqfd/F2xfinpxPpvZNIHq5R0ZAA8PsnuAYa1rO0ZwP9xX1ReISV/IKJeUOG7qRYoRbnxCrDXt5Sj1ynBhZy34QDrpT8TwT8hayTg4iaIaeAhGxmKF0dugJrojWG2rowBKvVWy4U37QjNNc4BRglcK8JXkVNSCzm4huXK90rMZf8KC1uqR8dznVaCtZ5seNEaenzHtXNsW9DYQ4GD+MFGzj/5H9+CdhR4qW17KaIbLAmi+3F8JgUPk6bDwhvs9vd7AL6MGTXK1kRBr43uu9gpBp1Sfm2Csx7SnJmxpdJj17vdkvpWiSMVMFNH8sl/3bYHgpYvoLeDgWQ11jN13Y8Uccm11JyQzTeZkxMy+0/VAGp+jvX7Kp6bpOlrERipumps0H7lHu0cDvDyYa2F0sMCGXqfA6vtPNvYSJSyo517FKMuIMG4/rk9VYrvRhCbECkJLxt1EXYdkc1mQ+4aTVziVmNOdkgPrB3W3+DOUPL9pjtc43N95X5aTxdixhXgUmOeNrcwG0ow7OptiRkunW9y4yelhRkfkdLrPS0Gcqey20Os+mXBpcf8YrRih6Dncn0zR6XT03pTtub0+xNTbJujOcSlyBlz0RaZgsCDKl7jdm3frRiavA6c= 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: 3ee179da-db87-483a-d34f-08d7ef727fae X-MS-Exchange-CrossTenant-originalarrivaltime: 03 May 2020 14:58:54.2849 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: vNdEOldWeWUfjbLzTiaSh/XSmL+lsrX5mUkxE+JZakGcLqj//d+6TDHBuVpb/VT6/w2ELptj8B4VzQiqUH0Lrg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6PR05MB5319 Subject: Re: [dpdk-dev] [PATCH v4] app/testpmd: support flow aging 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" > -----Original Message----- > From: Bill Zhou > Subject: [PATCH v4] app/testpmd: support flow aging >=20 > Currently, there is no way to check the aging event or to get the current > aged flows in testpmd, this patch include those implements, it's included= : >=20 > - Add new item "flow_aged" to the current print event command arguments. > - Add new command to list all aged flows, meanwhile, we can set parameter > to destroy it. >=20 > Signed-off-by: Bill Zhou > --- > v2: Update the way of registering aging event, add new command to control > if the event need be print or not. Update the output of the delete aged > flow command format. > v3: Change the command from only set aged flow output to set one gloable > verbose bitmap for all events output. > v4: Add the event output to current global print event arguments. > --- Acked-by: Ori Kam Thanks, Ori > app/test-pmd/cmdline.c | 4 + > app/test-pmd/cmdline_flow.c | 62 +++++++++++ > app/test-pmd/config.c | 108 ++++++++++++++++++-- > app/test-pmd/parameters.c | 6 +- > app/test-pmd/testpmd.c | 4 +- > app/test-pmd/testpmd.h | 3 + > doc/guides/testpmd_app_ug/testpmd_funcs.rst | 62 +++++++++++ > 7 files changed, 235 insertions(+), 14 deletions(-) >=20 > diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c > index 1375f223eb..bcf9080c48 100644 > --- a/app/test-pmd/cmdline.c > +++ b/app/test-pmd/cmdline.c > @@ -1125,6 +1125,10 @@ static void cmd_help_long_parsed(void > *parsed_result, > " Restrict ingress traffic to the defined" > " flow rules\n\n" >=20 > + "flow aged {port_id} [destroy]\n" > + " List and destroy aged flows" > + " flow rules\n\n" > + > "set vxlan ip-version (ipv4|ipv6) vni (vni) udp-src" > " (udp-src) udp-dst (udp-dst) ip-src (ip-src) ip-dst" > " (ip-dst) eth-src (eth-src) eth-dst (eth-dst)\n" > diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c > index 45bcff3cf5..4e2006c543 100644 > --- a/app/test-pmd/cmdline_flow.c > +++ b/app/test-pmd/cmdline_flow.c > @@ -67,6 +67,7 @@ enum index { > DUMP, > QUERY, > LIST, > + AGED, > ISOLATE, >=20 > /* Destroy arguments. */ > @@ -78,6 +79,9 @@ enum index { > /* List arguments. */ > LIST_GROUP, >=20 > + /* Destroy aged flow arguments. */ > + AGED_DESTROY, > + > /* Validate/create arguments. */ > GROUP, > PRIORITY, > @@ -664,6 +668,9 @@ struct buffer { > struct { > int set; > } isolate; /**< Isolated mode arguments. */ > + struct { > + int destroy; > + } aged; /**< Aged arguments. */ > } args; /**< Command arguments. */ > }; >=20 > @@ -719,6 +726,12 @@ static const enum index next_list_attr[] =3D { > ZERO, > }; >=20 > +static const enum index next_aged_attr[] =3D { > + AGED_DESTROY, > + END, > + ZERO, > +}; > + > static const enum index item_param[] =3D { > ITEM_PARAM_IS, > ITEM_PARAM_SPEC, > @@ -1466,6 +1479,9 @@ static int parse_action(struct context *, const str= uct > token *, > static int parse_list(struct context *, const struct token *, > const char *, unsigned int, > void *, unsigned int); > +static int parse_aged(struct context *, const struct token *, > + const char *, unsigned int, > + void *, unsigned int); > static int parse_isolate(struct context *, const struct token *, > const char *, unsigned int, > void *, unsigned int); > @@ -1649,6 +1665,7 @@ static const struct token token_list[] =3D { > FLUSH, > DUMP, > LIST, > + AGED, > QUERY, > ISOLATE)), > .call =3D parse_init, > @@ -1708,6 +1725,13 @@ static const struct token token_list[] =3D { > .args =3D ARGS(ARGS_ENTRY(struct buffer, port)), > .call =3D parse_list, > }, > + [AGED] =3D { > + .name =3D "aged", > + .help =3D "list and destroy aged flows", > + .next =3D NEXT(next_aged_attr, NEXT_ENTRY(PORT_ID)), > + .args =3D ARGS(ARGS_ENTRY(struct buffer, port)), > + .call =3D parse_aged, > + }, > [ISOLATE] =3D { > .name =3D "isolate", > .help =3D "restrict ingress traffic to the defined flow rules", > @@ -1741,6 +1765,12 @@ static const struct token token_list[] =3D { > .args =3D ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)), > .call =3D parse_list, > }, > + [AGED_DESTROY] =3D { > + .name =3D "destroy", > + .help =3D "specify aged flows need be destroyed", > + .call =3D parse_aged, > + .comp =3D comp_none, > + }, > /* Validate/create attributes. */ > [GROUP] =3D { > .name =3D "group", > @@ -5367,6 +5397,35 @@ parse_list(struct context *ctx, const struct token > *token, > return len; > } >=20 > +/** Parse tokens for list all aged flows command. */ > +static int > +parse_aged(struct context *ctx, const struct token *token, > + const char *str, unsigned int len, > + void *buf, unsigned int size) > +{ > + struct buffer *out =3D buf; > + > + /* Token name must match. */ > + if (parse_default(ctx, token, str, len, NULL, 0) < 0) > + return -1; > + /* Nothing else to do if there is no buffer. */ > + if (!out) > + return len; > + if (!out->command) { > + if (ctx->curr !=3D AGED) > + return -1; > + if (sizeof(*out) > size) > + return -1; > + out->command =3D ctx->curr; > + ctx->objdata =3D 0; > + ctx->object =3D out; > + ctx->objmask =3D NULL; > + } > + if (ctx->curr =3D=3D AGED_DESTROY) > + out->args.aged.destroy =3D 1; > + return len; > +} > + > /** Parse tokens for isolate command. */ > static int > parse_isolate(struct context *ctx, const struct token *token, > @@ -6367,6 +6426,9 @@ cmd_flow_parsed(const struct buffer *in) > case ISOLATE: > port_flow_isolate(in->port, in->args.isolate.set); > break; > + case AGED: > + port_flow_aged(in->port, in->args.aged.destroy); > + break; > default: > break; > } > diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c > index 72f25d1521..035d336ab5 100644 > --- a/app/test-pmd/config.c > +++ b/app/test-pmd/config.c > @@ -1367,6 +1367,26 @@ port_flow_validate(portid_t port_id, > return 0; > } >=20 > +/** Update age action context by port_flow pointer. */ > +void > +update_age_action_context(const struct rte_flow_action *actions, > + struct port_flow *pf) > +{ > + struct rte_flow_action_age *age =3D NULL; > + > + for (; actions->type !=3D RTE_FLOW_ACTION_TYPE_END; actions++) { > + switch (actions->type) { > + case RTE_FLOW_ACTION_TYPE_AGE: > + age =3D (struct rte_flow_action_age *) > + (uintptr_t)actions->conf; > + age->context =3D pf; > + return; > + default: > + break; > + } > + } > +} > + > /** Create flow rule. */ > int > port_flow_create(portid_t port_id, > @@ -1377,28 +1397,27 @@ port_flow_create(portid_t port_id, > struct rte_flow *flow; > struct rte_port *port; > struct port_flow *pf; > - uint32_t id; > + uint32_t id =3D 0; > struct rte_flow_error error; >=20 > - /* Poisoning to make sure PMDs update it in case of error. */ > - memset(&error, 0x22, sizeof(error)); > - flow =3D rte_flow_create(port_id, attr, pattern, actions, &error); > - if (!flow) > - return port_flow_complain(&error); > port =3D &ports[port_id]; > if (port->flow_list) { > if (port->flow_list->id =3D=3D UINT32_MAX) { > printf("Highest rule ID is already assigned, delete" > " it first"); > - rte_flow_destroy(port_id, flow, NULL); > return -ENOMEM; > } > id =3D port->flow_list->id + 1; > - } else > - id =3D 0; > + } > pf =3D port_flow_new(attr, pattern, actions, &error); > - if (!pf) { > - rte_flow_destroy(port_id, flow, NULL); > + if (!pf) > + return port_flow_complain(&error); > + update_age_action_context(actions, pf); > + /* Poisoning to make sure PMDs update it in case of error. */ > + memset(&error, 0x22, sizeof(error)); > + flow =3D rte_flow_create(port_id, attr, pattern, actions, &error); > + if (!flow) { > + free(pf); > return port_flow_complain(&error); > } > pf->next =3D port->flow_list; > @@ -1570,6 +1589,73 @@ port_flow_query(portid_t port_id, uint32_t rule, > return 0; > } >=20 > +/** List simply and destroy all aged flows. */ > +void > +port_flow_aged(portid_t port_id, uint8_t destroy) > +{ > + void **contexts; > + int nb_context, total =3D 0, idx; > + struct rte_flow_error error; > + struct port_flow *pf; > + > + if (port_id_is_invalid(port_id, ENABLED_WARN) || > + port_id =3D=3D (portid_t)RTE_PORT_ALL) > + return; > + total =3D rte_flow_get_aged_flows(port_id, NULL, 0, &error); > + printf("Port %u total aged flows: %d\n", port_id, total); > + if (total < 0) { > + port_flow_complain(&error); > + return; > + } > + if (total =3D=3D 0) > + return; > + contexts =3D malloc(sizeof(void *) * total); > + if (contexts =3D=3D NULL) { > + printf("Cannot allocate contexts for aged flow\n"); > + return; > + } > + printf("ID\tGroup\tPrio\tAttr\n"); > + nb_context =3D rte_flow_get_aged_flows(port_id, contexts, total, > &error); > + if (nb_context !=3D total) { > + printf("Port:%d get aged flows count(%d) !=3D total(%d)\n", > + port_id, nb_context, total); > + free(contexts); > + return; > + } > + for (idx =3D 0; idx < nb_context; idx++) { > + pf =3D (struct port_flow *)contexts[idx]; > + if (!pf) { > + printf("Error: get Null context in port %u\n", port_id); > + continue; > + } > + printf("%" PRIu32 "\t%" PRIu32 "\t%" PRIu32 "\t%c%c%c\t\n", > + pf->id, > + pf->rule.attr->group, > + pf->rule.attr->priority, > + pf->rule.attr->ingress ? 'i' : '-', > + pf->rule.attr->egress ? 'e' : '-', > + pf->rule.attr->transfer ? 't' : '-'); > + } > + if (destroy) { > + int ret; > + uint32_t flow_id; > + > + total =3D 0; > + printf("\n"); > + for (idx =3D 0; idx < nb_context; idx++) { > + pf =3D (struct port_flow *)contexts[idx]; > + if (!pf) > + continue; > + flow_id =3D pf->id; > + ret =3D port_flow_destroy(port_id, 1, &flow_id); > + if (!ret) > + total++; > + } > + printf("%d flows be destroyed\n", total); > + } > + free(contexts); > +} > + > /** List flow rules. */ > void > port_flow_list(portid_t port_id, uint32_t n, const uint32_t group[n]) > diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c > index 30c1753c32..92b5575626 100644 > --- a/app/test-pmd/parameters.c > +++ b/app/test-pmd/parameters.c > @@ -187,9 +187,9 @@ usage(char* progname) > printf(" --no-rmv-interrupt: disable device removal interrupt.\n"); > printf(" --bitrate-stats=3DN: set the logical core N to perform " > "bit-rate calculation.\n"); > - printf(" --print-event > : " > + printf(" --print-event > ged|all>: " > "enable print of designated event or all of them.\n"); > - printf(" --mask-event > : " > + printf(" --mask-event > ged|all>: " > "disable print of designated event or all of them.\n"); > printf(" --flow-isolate-all: " > "requests flow API isolated mode on all ports at initialization > time.\n"); > @@ -545,6 +545,8 @@ parse_event_printing_config(const char *optarg, int > enable) > mask =3D UINT32_C(1) << RTE_ETH_EVENT_NEW; > else if (!strcmp(optarg, "dev_released")) > mask =3D UINT32_C(1) << RTE_ETH_EVENT_DESTROY; > + else if (!strcmp(optarg, "flow_aged")) > + mask =3D UINT32_C(1) << RTE_ETH_EVENT_FLOW_AGED; > else if (!strcmp(optarg, "all")) > mask =3D ~UINT32_C(0); > else { > diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c > index 99bacddbfd..a2d0be56b3 100644 > --- a/app/test-pmd/testpmd.c > +++ b/app/test-pmd/testpmd.c > @@ -375,6 +375,7 @@ static const char * const eth_event_desc[] =3D { > [RTE_ETH_EVENT_INTR_RMV] =3D "device removal", > [RTE_ETH_EVENT_NEW] =3D "device probed", > [RTE_ETH_EVENT_DESTROY] =3D "device released", > + [RTE_ETH_EVENT_FLOW_AGED] =3D "flow aged", > [RTE_ETH_EVENT_MAX] =3D NULL, > }; >=20 > @@ -388,7 +389,8 @@ uint32_t event_print_mask =3D (UINT32_C(1) << > RTE_ETH_EVENT_UNKNOWN) | > (UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET) | > (UINT32_C(1) << RTE_ETH_EVENT_IPSEC) | > (UINT32_C(1) << RTE_ETH_EVENT_MACSEC) | > - (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV); > + (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV) | > + (UINT32_C(1) << RTE_ETH_EVENT_FLOW_AGED); > /* > * Decide if all memory are locked for performance. > */ > diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h > index 7ff4c5dba3..fb391672a8 100644 > --- a/app/test-pmd/testpmd.h > +++ b/app/test-pmd/testpmd.h > @@ -747,12 +747,15 @@ int port_flow_create(portid_t port_id, > const struct rte_flow_attr *attr, > const struct rte_flow_item *pattern, > const struct rte_flow_action *actions); > +void update_age_action_context(const struct rte_flow_action *actions, > + struct port_flow *pf); > int port_flow_destroy(portid_t port_id, uint32_t n, const uint32_t *rule= ); > int port_flow_flush(portid_t port_id); > int port_flow_dump(portid_t port_id, const char *file_name); > int port_flow_query(portid_t port_id, uint32_t rule, > const struct rte_flow_action *action); > void port_flow_list(portid_t port_id, uint32_t n, const uint32_t *group)= ; > +void port_flow_aged(portid_t port_id, uint8_t destroy); > int port_flow_isolate(portid_t port_id, int set); >=20 > void rx_ring_desc_display(portid_t port_id, queueid_t rxq_id, uint16_t r= xd_id); > diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst > b/doc/guides/testpmd_app_ug/testpmd_funcs.rst > index a360ecccfd..19260cc2d9 100644 > --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst > +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst > @@ -3616,6 +3616,10 @@ following sections. >=20 > flow dump {port_id} {output_file} >=20 > +- List and destroy aged flow rules:: > + > + flow aged {port_id} [destroy] > + > Validating flow rules > ~~~~~~~~~~~~~~~~~~~~~ >=20 > @@ -4503,6 +4507,64 @@ Otherwise, it will complain error occurred:: >=20 > Caught error type [...] ([...]): [...] >=20 > +Listing and destroying aged flow rules > +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + > +``flow aged`` simply lists aged flow rules be get from api > ``rte_flow_get_aged_flows``, > +and ``destroy`` parameter can be used to destroy those flow rules in PMD= . > + > + flow aged {port_id} [destroy] > + > +Listing current aged flow rules:: > + > + testpmd> flow aged 0 > + Port 0 total aged flows: 0 > + testpmd> flow create 0 ingress pattern eth / ipv4 src is 2.2.2.14 / e= nd > + actions age timeout 5 / queue index 0 / end > + Flow rule #0 created > + testpmd> flow create 0 ingress pattern eth / ipv4 src is 2.2.2.15 / e= nd > + actions age timeout 4 / queue index 0 / end > + Flow rule #1 created > + testpmd> flow create 0 ingress pattern eth / ipv4 src is 2.2.2.16 / e= nd > + actions age timeout 2 / queue index 0 / end > + Flow rule #2 created > + testpmd> flow create 0 ingress pattern eth / ipv4 src is 2.2.2.17 / e= nd > + actions age timeout 3 / queue index 0 / end > + Flow rule #3 created > + > + > +Aged Rules are simply list as command ``flow list {port_id}``, but strip= the > detail rule > +information, all the aged flows are sorted by the longest timeout time. = For > example, if > +those rules be configured in the same time, ID 2 will be the first aged = out rule, > the next > +will be ID 3, ID 1, ID 0:: > + > + testpmd> flow aged 0 > + Port 0 total aged flows: 4 > + ID Group Prio Attr > + 2 0 0 i-- > + 3 0 0 i-- > + 1 0 0 i-- > + 0 0 0 i-- > + > +If attach ``destroy`` parameter, the command will destroy all the list a= ged > flow rules. > + > + testpmd> flow aged 0 destroy > + Port 0 total aged flows: 4 > + ID Group Prio Attr > + 2 0 0 i-- > + 3 0 0 i-- > + 1 0 0 i-- > + 0 0 0 i-- > + > + Flow rule #2 destroyed > + Flow rule #3 destroyed > + Flow rule #1 destroyed > + Flow rule #0 destroyed > + 4 flows be destroyed > + testpmd> flow aged 0 > + Port 0 total aged flows: 0 > + > + > Sample QinQ flow rules > ~~~~~~~~~~~~~~~~~~~~~~ >=20 > -- > 2.21.0