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

Message ID 8a8d3efbf0258cc3afa5b334b180e049ce2f9ee3.1482168851.git.adrien.mazarguil@6wind.com (mailing list archive)
State Superseded, archived
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel compilation fail apply patch file failure

Commit Message

Adrien Mazarguil Dec. 19, 2016, 5:49 p.m. UTC
  Syntax:

 flow flush {port_id}

Destroy all flow rules on a port.

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Olga Shern <olgas@mellanox.com>
---
 app/test-pmd/cmdline.c      |  3 +++
 app/test-pmd/cmdline_flow.c | 43 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 45 insertions(+), 1 deletion(-)
  

Comments

Zhao1, Wei Dec. 20, 2016, 7:32 a.m. UTC | #1
Hi,  Adrien

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Adrien Mazarguil
> Sent: Tuesday, December 20, 2016 1:49 AM
> To: dev@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@6wind.com>
> Acked-by: Olga Shern <olgas@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.
This memory is returned when flow create, will rte layer flush this memory or PMD is responsible for that memory flush?
BTW, there is no argument about rte_flow in flush function pass into PMD layer.
  
Adrien Mazarguil Dec. 20, 2016, 9:45 a.m. UTC | #2
Hi Wei,

On Tue, Dec 20, 2016 at 07:32:29AM +0000, Zhao1, Wei wrote:
> Hi,  Adrien
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Adrien Mazarguil
> > Sent: Tuesday, December 20, 2016 1:49 AM
> > To: dev@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@6wind.com>
> > Acked-by: Olga Shern <olgas@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().
  

Patch

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);