[dpdk-dev] [PATCH v3 10/25] app/testpmd: add flow flush command

Adrien Mazarguil adrien.mazarguil at 6wind.com
Tue Dec 20 10:45:03 CET 2016


Hi Wei,

On Tue, Dec 20, 2016 at 07:32:29AM +0000, Zhao1, Wei wrote:
> Hi,  Adrien
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Adrien Mazarguil
> > Sent: Tuesday, December 20, 2016 1:49 AM
> > To: dev at dpdk.org
> > Subject: [dpdk-dev] [PATCH v3 10/25] app/testpmd: add flow flush
> > command
> > 
> > Syntax:
> > 
> >  flow flush {port_id}
> > 
> > Destroy all flow rules on a port.
> > 
> > Signed-off-by: Adrien Mazarguil <adrien.mazarguil at 6wind.com>
> > Acked-by: Olga Shern <olgas at mellanox.com>
> > ---
> >  app/test-pmd/cmdline.c      |  3 +++
> >  app/test-pmd/cmdline_flow.c | 43
> > +++++++++++++++++++++++++++++++++++++++-
> >  2 files changed, 45 insertions(+), 1 deletion(-)
> > 
> > diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> > 0dc6c63..6e2b289 100644
> > --- a/app/test-pmd/cmdline.c
> > +++ b/app/test-pmd/cmdline.c
> > @@ -811,6 +811,9 @@ static void cmd_help_long_parsed(void
> > *parsed_result,
> >  			" (select|add)\n"
> >  			"    Set the input set for FDir.\n\n"
> > 
> > +			"flow flush {port_id}\n"
> > +			"    Destroy all flow rules.\n\n"
> > +
> >  			"flow list {port_id} [group {group_id}] [...]\n"
> >  			"    List existing flow rules sorted by priority,"
> >  			" filtered by group identifiers.\n\n"
> > diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> > index bd3da38..49578eb 100644
> > --- a/app/test-pmd/cmdline_flow.c
> > +++ b/app/test-pmd/cmdline_flow.c
> > @@ -63,6 +63,7 @@ enum index {
> >  	FLOW,
> > 
> >  	/* Sub-level commands. */
> > +	FLUSH,
> >  	LIST,
> > 
> >  	/* List arguments. */
> > @@ -179,6 +180,9 @@ static const enum index next_list_attr[] = {  static int
> > parse_init(struct context *, const struct token *,
> >  		      const char *, unsigned int,
> >  		      void *, unsigned int);
> > +static int parse_flush(struct context *, const struct token *,
> > +		       const char *, unsigned int,
> > +		       void *, unsigned int);
> >  static int parse_list(struct context *, const struct token *,
> >  		      const char *, unsigned int,
> >  		      void *, unsigned int);
> > @@ -240,10 +244,19 @@ static const struct token token_list[] = {
> >  		.name = "flow",
> >  		.type = "{command} {port_id} [{arg} [...]]",
> >  		.help = "manage ingress/egress flow rules",
> > -		.next = NEXT(NEXT_ENTRY(LIST)),
> > +		.next = NEXT(NEXT_ENTRY
> > +			     (FLUSH,
> > +			      LIST)),
> >  		.call = parse_init,
> >  	},
> >  	/* Sub-level commands. */
> > +	[FLUSH] = {
> > +		.name = "flush",
> > +		.help = "destroy all flow rules",
> > +		.next = NEXT(NEXT_ENTRY(PORT_ID)),
> > +		.args = ARGS(ARGS_ENTRY(struct buffer, port)),
> > +		.call = parse_flush,
> > +	},
> >  	[LIST] = {
> >  		.name = "list",
> >  		.help = "list existing flow rules",
> > @@ -316,6 +329,31 @@ parse_init(struct context *ctx, const struct token
> > *token,
> >  	return len;
> >  }
> > 
> > +/** Parse tokens for flush command. */
> > +static int
> > +parse_flush(struct context *ctx, const struct token *token,
> > +	    const char *str, unsigned int len,
> > +	    void *buf, unsigned int size)
> > +{
> > +	struct buffer *out = 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 != FLUSH)
> > +			return -1;
> > +		if (sizeof(*out) > size)
> > +			return -1;
> > +		out->command = ctx->curr;
> > +		ctx->object = out;
> > +	}
> > +	return len;
> > +}
> > +
> >  /** Parse tokens for list command. */
> >  static int
> >  parse_list(struct context *ctx, const struct token *token, @@ -698,6 +736,9
> > @@ static void  cmd_flow_parsed(const struct buffer *in)  {
> >  	switch (in->command) {
> > +	case FLUSH:
> > +		port_flow_flush(in->port);
> > +		break;
> >  	case LIST:
> >  		port_flow_list(in->port, in->args.list.group_n,
> >  			       in->args.list.group);
> > --
> > 2.1.4
> 
> When user  flow flush cmd, PMD will flush all the rule on the specific port, and  the memory of which rte_flow point to must be flushed.

Right.

> This memory is returned when flow create, will rte layer flush this memory or PMD is responsible for that memory flush?

All handles are considered destroyed and their memory freed, i.e. no
rte_flow object remains valid after flush. Applications still need to clean
up the memory they allocated to manage these objects, but that's their
problem.

> BTW, there is no argument about rte_flow in flush function pass into PMD layer.

Right, that's because flush does not request the destruction of a specific
rule. PMDs that allocate memory for rte_flow objects must link them together
somehow to retrieve them during a flush event.

Note this is likely already necessary to clean up the memory allocated for
flow rules during dev_close().

-- 
Adrien Mazarguil
6WIND


More information about the dev mailing list