Re: [ovs-dev] [PATCH v1 3/3 ovn] NAT: Parsing port_range options in ct_*nat actions

2020-04-01 Thread Ankur Sharma
Hi Mark,

Thanks a lot for review.
Addressed all the comments.
Please take a look at V2.

Regards,
Ankur

-Original Message-
From: dev  On Behalf Of Mark Michelson
Sent: Monday, March 30, 2020 12:21 PM
To: svc.mail.git ; ovs-dev@openvswitch.org
Subject: Re: [ovs-dev] [PATCH v1 3/3 ovn] NAT: Parsing port_range options in 
ct_*nat actions

This and patch 2 should be combined into one patch. Patch 2 in isolation adds 
invalid ct_snat and ct_dnat commands since the code for encoding them is not 
added until patch 3.

See below for additional in-line comments.

On 3/27/20 7:18 PM, Ankur Sharma wrote:
> From: Ankur Sharma 
> 
> Changes to parse the logical flow, which specifies port_range for 
> ct_nat action.
> 
> Example logical flow:
> ct_snat(10.15.24.135,1-3)
> 
> Signed-off-by: Ankur Sharma 
> ---
>   include/ovn/actions.h |  7 +++
>   include/ovn/lex.h |  1 +
>   lib/actions.c | 39 +++
>   lib/lex.c |  5 -
>   tests/ovn.at  | 24 ++--
>   5 files changed, 73 insertions(+), 3 deletions(-)
> 
> diff --git a/include/ovn/actions.h b/include/ovn/actions.h index 
> 9b01492..2cec369 100644
> --- a/include/ovn/actions.h
> +++ b/include/ovn/actions.h
> @@ -233,6 +233,13 @@ struct ovnact_ct_nat {
>   struct in6_addr ipv6;
>   ovs_be32 ipv4;
>   };
> +
> +struct {
> +   bool exists;
> +   uint16_t port_lo;
> +   uint16_t port_hi;
> +} port_range;
> +
>   uint8_t ltable; /* Logical table ID of next table. */
>   };
>   
> diff --git a/include/ovn/lex.h b/include/ovn/lex.h index 
> 8d55857..1da6ccc 100644
> --- a/include/ovn/lex.h
> +++ b/include/ovn/lex.h
> @@ -63,6 +63,7 @@ enum lex_type {
>   LEX_T_EXCHANGE, /* <-> */
>   LEX_T_DECREMENT,/* -- */
>   LEX_T_COLON,/* : */
> +LEX_T_HYPHEN,   /* - */
>   };
>   
>   /* Subtype for LEX_T_INTEGER and LEX_T_MASKED_INTEGER tokens.
> diff --git a/lib/actions.c b/lib/actions.c index f22acdd..07fbed8 
> 100644
> --- a/lib/actions.c
> +++ b/lib/actions.c
> @@ -770,6 +770,33 @@ parse_ct_nat(struct action_context *ctx, const char 
> *name,
>   }
>   lexer_get(ctx->lexer);
>   
> +if (lexer_match(ctx->lexer, LEX_T_COMMA)) {
> +
> +   if (ctx->lexer->token.type != LEX_T_INTEGER ||
> +   ctx->lexer->token.format != LEX_F_DECIMAL) {
> +  lexer_syntax_error(ctx->lexer, "expecting Integer for port "
> + "range");
> +   }
> +
> +   cn->port_range.port_lo = ntohll(ctx->lexer->token.value.integer);
> +   lexer_get(ctx->lexer);
> +
> +   if (!lexer_match(ctx->lexer, LEX_T_HYPHEN)) {
> +  lexer_syntax_error(ctx->lexer, "expecting - for port range");
> +  return;
> +   }
> +
> +   if (ctx->lexer->token.type != LEX_T_INTEGER) {
> +  lexer_syntax_error(ctx->lexer, "expecting Integer for port "
> + "range");
> +   }
> +
> +   cn->port_range.port_hi = 
> + ntohll(ctx->lexer->token.value.integer);

You should probably ensure that cn->port_range.port_hi is greater than 
cn->port_range.port_lo.

> +   lexer_get(ctx->lexer);
> +
> +   cn->port_range.exists = true;
> +}
> +
>   if (!lexer_force_match(ctx->lexer, LEX_T_RPAREN)) {
>   return;
>   }
> @@ -799,6 +826,13 @@ format_ct_nat(const struct ovnact_ct_nat *cn, const char 
> *name, struct ds *s)
>   ipv6_format_addr(>ipv6, s);
>   ds_put_char(s, ')');
>   }
> +
> +if (cn->port_range.exists) {
> +ds_chomp(s, ')');
> +ds_put_format(s, ",%d-%d)", cn->port_range.port_lo,
> +  cn->port_range.port_hi);
> +}
> +
>   ds_put_char(s, ';');
>   }
>   
> @@ -861,6 +895,11 @@ encode_ct_nat(const struct ovnact_ct_nat *cn,
>   }
>   }
>   
> +if (cn->port_range.exists) {
> +   nat->range.proto.min = cn->port_range.port_lo;
> +   nat->range.proto.max = cn->port_range.port_hi;
> +}
> +
>   ofpacts->header = ofpbuf_push_uninit(ofpacts, nat_offset);
>   ct = ofpacts->header;
>   if (cn->family == AF_INET || cn->family == AF_INET6) { diff 
> --git a/lib/lex.c b/lib/lex.c index 7a2ab41..94f6c77 100644
> --- a/lib/lex.c
> +++ b/lib/lex.c

Re: [ovs-dev] [PATCH v1 3/3 ovn] NAT: Parsing port_range options in ct_*nat actions

2020-03-30 Thread Mark Michelson
This and patch 2 should be combined into one patch. Patch 2 in isolation 
adds invalid ct_snat and ct_dnat commands since the code for encoding 
them is not added until patch 3.


See below for additional in-line comments.

On 3/27/20 7:18 PM, Ankur Sharma wrote:

From: Ankur Sharma 

Changes to parse the logical flow, which specifies port_range
for ct_nat action.

Example logical flow:
ct_snat(10.15.24.135,1-3)

Signed-off-by: Ankur Sharma 
---
  include/ovn/actions.h |  7 +++
  include/ovn/lex.h |  1 +
  lib/actions.c | 39 +++
  lib/lex.c |  5 -
  tests/ovn.at  | 24 ++--
  5 files changed, 73 insertions(+), 3 deletions(-)

diff --git a/include/ovn/actions.h b/include/ovn/actions.h
index 9b01492..2cec369 100644
--- a/include/ovn/actions.h
+++ b/include/ovn/actions.h
@@ -233,6 +233,13 @@ struct ovnact_ct_nat {
  struct in6_addr ipv6;
  ovs_be32 ipv4;
  };
+
+struct {
+   bool exists;
+   uint16_t port_lo;
+   uint16_t port_hi;
+} port_range;
+
  uint8_t ltable; /* Logical table ID of next table. */
  };
  
diff --git a/include/ovn/lex.h b/include/ovn/lex.h

index 8d55857..1da6ccc 100644
--- a/include/ovn/lex.h
+++ b/include/ovn/lex.h
@@ -63,6 +63,7 @@ enum lex_type {
  LEX_T_EXCHANGE, /* <-> */
  LEX_T_DECREMENT,/* -- */
  LEX_T_COLON,/* : */
+LEX_T_HYPHEN,   /* - */
  };
  
  /* Subtype for LEX_T_INTEGER and LEX_T_MASKED_INTEGER tokens.

diff --git a/lib/actions.c b/lib/actions.c
index f22acdd..07fbed8 100644
--- a/lib/actions.c
+++ b/lib/actions.c
@@ -770,6 +770,33 @@ parse_ct_nat(struct action_context *ctx, const char *name,
  }
  lexer_get(ctx->lexer);
  
+if (lexer_match(ctx->lexer, LEX_T_COMMA)) {

+
+   if (ctx->lexer->token.type != LEX_T_INTEGER ||
+   ctx->lexer->token.format != LEX_F_DECIMAL) {
+  lexer_syntax_error(ctx->lexer, "expecting Integer for port "
+ "range");
+   }
+
+   cn->port_range.port_lo = ntohll(ctx->lexer->token.value.integer);
+   lexer_get(ctx->lexer);
+
+   if (!lexer_match(ctx->lexer, LEX_T_HYPHEN)) {
+  lexer_syntax_error(ctx->lexer, "expecting - for port range");
+  return;
+   }
+
+   if (ctx->lexer->token.type != LEX_T_INTEGER) {
+  lexer_syntax_error(ctx->lexer, "expecting Integer for port "
+ "range");
+   }
+
+   cn->port_range.port_hi = ntohll(ctx->lexer->token.value.integer);


You should probably ensure that cn->port_range.port_hi is greater than 
cn->port_range.port_lo.



+   lexer_get(ctx->lexer);
+
+   cn->port_range.exists = true;
+}
+
  if (!lexer_force_match(ctx->lexer, LEX_T_RPAREN)) {
  return;
  }
@@ -799,6 +826,13 @@ format_ct_nat(const struct ovnact_ct_nat *cn, const char 
*name, struct ds *s)
  ipv6_format_addr(>ipv6, s);
  ds_put_char(s, ')');
  }
+
+if (cn->port_range.exists) {
+ds_chomp(s, ')');
+ds_put_format(s, ",%d-%d)", cn->port_range.port_lo,
+  cn->port_range.port_hi);
+}
+
  ds_put_char(s, ';');
  }
  
@@ -861,6 +895,11 @@ encode_ct_nat(const struct ovnact_ct_nat *cn,

  }
  }
  
+if (cn->port_range.exists) {

+   nat->range.proto.min = cn->port_range.port_lo;
+   nat->range.proto.max = cn->port_range.port_hi;
+}
+
  ofpacts->header = ofpbuf_push_uninit(ofpacts, nat_offset);
  ct = ofpacts->header;
  if (cn->family == AF_INET || cn->family == AF_INET6) {
diff --git a/lib/lex.c b/lib/lex.c
index 7a2ab41..94f6c77 100644
--- a/lib/lex.c
+++ b/lib/lex.c
@@ -301,6 +301,9 @@ lex_token_format(const struct lex_token *token, struct ds 
*s)
  case LEX_T_COLON:
  ds_put_char(s, ':');
  break;
+case LEX_T_HYPHEN:
+ds_put_char(s, '-');
+break;
  default:
  OVS_NOT_REACHED();
  }
@@ -757,7 +760,7 @@ next:
  token->type = LEX_T_DECREMENT;
  p++;
  } else {
-lex_error(token, "`-' is only valid as part of `--'.");
+   token->type = LEX_T_HYPHEN;
  }
  break;
  
diff --git a/tests/ovn.at b/tests/ovn.at

index 9a44f0a..d76db6f 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -1049,15 +1049,25 @@ ct_dnat(192.168.1.2);
  ct_dnat(fd11::2);
  encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=fd11::2))
  has prereqs ip
+ct_dnat(192.168.1.2, 1-3000);
+formats as ct_dnat(192.168.1.2,1-3000);
+encodes as 
ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2:1-3000))
+has prereqs ip
  
  ct_dnat(192.168.1.2, 192.168.1.3);

-Syntax error at `,' expecting `)'.
+Syntax error at `192.168.1.3' expecting 

[ovs-dev] [PATCH v1 3/3 ovn] NAT: Parsing port_range options in ct_*nat actions

2020-03-27 Thread Ankur Sharma
From: Ankur Sharma 

Changes to parse the logical flow, which specifies port_range
for ct_nat action.

Example logical flow:
ct_snat(10.15.24.135,1-3)

Signed-off-by: Ankur Sharma 
---
 include/ovn/actions.h |  7 +++
 include/ovn/lex.h |  1 +
 lib/actions.c | 39 +++
 lib/lex.c |  5 -
 tests/ovn.at  | 24 ++--
 5 files changed, 73 insertions(+), 3 deletions(-)

diff --git a/include/ovn/actions.h b/include/ovn/actions.h
index 9b01492..2cec369 100644
--- a/include/ovn/actions.h
+++ b/include/ovn/actions.h
@@ -233,6 +233,13 @@ struct ovnact_ct_nat {
 struct in6_addr ipv6;
 ovs_be32 ipv4;
 };
+
+struct {
+   bool exists;
+   uint16_t port_lo;
+   uint16_t port_hi;
+} port_range;
+
 uint8_t ltable; /* Logical table ID of next table. */
 };
 
diff --git a/include/ovn/lex.h b/include/ovn/lex.h
index 8d55857..1da6ccc 100644
--- a/include/ovn/lex.h
+++ b/include/ovn/lex.h
@@ -63,6 +63,7 @@ enum lex_type {
 LEX_T_EXCHANGE, /* <-> */
 LEX_T_DECREMENT,/* -- */
 LEX_T_COLON,/* : */
+LEX_T_HYPHEN,   /* - */
 };
 
 /* Subtype for LEX_T_INTEGER and LEX_T_MASKED_INTEGER tokens.
diff --git a/lib/actions.c b/lib/actions.c
index f22acdd..07fbed8 100644
--- a/lib/actions.c
+++ b/lib/actions.c
@@ -770,6 +770,33 @@ parse_ct_nat(struct action_context *ctx, const char *name,
 }
 lexer_get(ctx->lexer);
 
+if (lexer_match(ctx->lexer, LEX_T_COMMA)) {
+
+   if (ctx->lexer->token.type != LEX_T_INTEGER ||
+   ctx->lexer->token.format != LEX_F_DECIMAL) {
+  lexer_syntax_error(ctx->lexer, "expecting Integer for port "
+ "range");
+   }
+
+   cn->port_range.port_lo = ntohll(ctx->lexer->token.value.integer);
+   lexer_get(ctx->lexer);
+
+   if (!lexer_match(ctx->lexer, LEX_T_HYPHEN)) {
+  lexer_syntax_error(ctx->lexer, "expecting - for port range");
+  return;
+   }
+
+   if (ctx->lexer->token.type != LEX_T_INTEGER) {
+  lexer_syntax_error(ctx->lexer, "expecting Integer for port "
+ "range");
+   }
+
+   cn->port_range.port_hi = ntohll(ctx->lexer->token.value.integer);
+   lexer_get(ctx->lexer);
+
+   cn->port_range.exists = true;
+}
+
 if (!lexer_force_match(ctx->lexer, LEX_T_RPAREN)) {
 return;
 }
@@ -799,6 +826,13 @@ format_ct_nat(const struct ovnact_ct_nat *cn, const char 
*name, struct ds *s)
 ipv6_format_addr(>ipv6, s);
 ds_put_char(s, ')');
 }
+
+if (cn->port_range.exists) {
+ds_chomp(s, ')');
+ds_put_format(s, ",%d-%d)", cn->port_range.port_lo,
+  cn->port_range.port_hi);
+}
+
 ds_put_char(s, ';');
 }
 
@@ -861,6 +895,11 @@ encode_ct_nat(const struct ovnact_ct_nat *cn,
 }
 }
 
+if (cn->port_range.exists) {
+   nat->range.proto.min = cn->port_range.port_lo;
+   nat->range.proto.max = cn->port_range.port_hi;
+}
+
 ofpacts->header = ofpbuf_push_uninit(ofpacts, nat_offset);
 ct = ofpacts->header;
 if (cn->family == AF_INET || cn->family == AF_INET6) {
diff --git a/lib/lex.c b/lib/lex.c
index 7a2ab41..94f6c77 100644
--- a/lib/lex.c
+++ b/lib/lex.c
@@ -301,6 +301,9 @@ lex_token_format(const struct lex_token *token, struct ds 
*s)
 case LEX_T_COLON:
 ds_put_char(s, ':');
 break;
+case LEX_T_HYPHEN:
+ds_put_char(s, '-');
+break;
 default:
 OVS_NOT_REACHED();
 }
@@ -757,7 +760,7 @@ next:
 token->type = LEX_T_DECREMENT;
 p++;
 } else {
-lex_error(token, "`-' is only valid as part of `--'.");
+   token->type = LEX_T_HYPHEN;
 }
 break;
 
diff --git a/tests/ovn.at b/tests/ovn.at
index 9a44f0a..d76db6f 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -1049,15 +1049,25 @@ ct_dnat(192.168.1.2);
 ct_dnat(fd11::2);
 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=fd11::2))
 has prereqs ip
+ct_dnat(192.168.1.2, 1-3000);
+formats as ct_dnat(192.168.1.2,1-3000);
+encodes as 
ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2:1-3000))
+has prereqs ip
 
 ct_dnat(192.168.1.2, 192.168.1.3);
-Syntax error at `,' expecting `)'.
+Syntax error at `192.168.1.3' expecting Integer for port range.
 ct_dnat(foo);
 Syntax error at `foo' expecting IPv4 or IPv6 address.
 ct_dnat(foo, bar);
 Syntax error at `foo' expecting IPv4 or IPv6 address.
 ct_dnat();
 Syntax error at `)' expecting IPv4 or IPv6 address.
+ct_dnat(192.168.1.2, foo);
+Syntax error at `foo' expecting Integer for port range.
+ct_dnat(192.168.1.2, 1000-foo);
+Syntax error at `foo' expecting Integer for port range.