[ovs-dev] [PATCH v1 2/2 ovn] NAT: Northd and parser changes to support port
Ankur Sharma
svc.mail.git at nutanix.com
Mon May 4 20:46:46 UTC 2020
From: Ankur Sharma <ankur.sharma at nutanix.com>
This patch has following changes:
a. Northd changes to put port range hash in the
logical flow based on configuration.
b. Changes to parse the logical flow, which specifies
port_range_hash along with port_range for ct_nat action.
Example logical flow:
ct_snat(10.15.24.135,1-30000, hash)
Signed-off-by: Ankur Sharma <ankur.sharma at nutanix.com>
---
include/ovn/actions.h | 1 +
lib/actions.c | 51 +++++++++++++++++++++++++++++++++++++--
northd/ovn-northd.c | 16 +++++++++++++
tests/ovn-northd.at | 31 ++++++++++++++++++++++++
tests/ovn.at | 66 ++++++++++++++++++++++++++++++++++++++++++++-------
5 files changed, 155 insertions(+), 10 deletions(-)
diff --git a/include/ovn/actions.h b/include/ovn/actions.h
index 42d45a7..a6f65b2 100644
--- a/include/ovn/actions.h
+++ b/include/ovn/actions.h
@@ -239,6 +239,7 @@ struct ovnact_ct_nat {
bool exists;
uint16_t port_lo;
uint16_t port_hi;
+ char *port_hash;
} port_range;
uint8_t ltable; /* Logical table ID of next table. */
diff --git a/lib/actions.c b/lib/actions.c
index 21c0796..cac6247 100644
--- a/lib/actions.c
+++ b/lib/actions.c
@@ -768,6 +768,8 @@ parse_ct_nat(struct action_context *ctx, const char *name,
if (lexer_match(ctx->lexer, LEX_T_COMMA)) {
+ cn->port_range.port_hash = NULL;
+
if (ctx->lexer->token.type != LEX_T_INTEGER ||
ctx->lexer->token.format != LEX_F_DECIMAL) {
lexer_syntax_error(ctx->lexer, "expecting Integer for port "
@@ -794,8 +796,40 @@ parse_ct_nat(struct action_context *ctx, const char *name,
"greater than range low");
}
lexer_get(ctx->lexer);
+
+ if (lexer_match(ctx->lexer, LEX_T_COMMA)) {
+ if (ctx->lexer->token.type != LEX_T_ID) {
+ lexer_syntax_error(ctx->lexer, "expecting string for "
+ "port hash");
+ }
+
+ if (strcmp(ctx->lexer->token.s, "hash") &&
+ strcmp(ctx->lexer->token.s, "random")) {
+ lexer_syntax_error(ctx->lexer, "Invalid value for "
+ "port hash");
+ }
+
+ cn->port_range.port_hash = xstrdup(ctx->lexer->token.s);
+ lexer_get(ctx->lexer);
+ }
} else {
cn->port_range.port_hi = 0;
+
+ if (lexer_match(ctx->lexer, LEX_T_COMMA)) {
+ if (ctx->lexer->token.type != LEX_T_ID) {
+ lexer_syntax_error(ctx->lexer, "expecting string for "
+ "port hash");
+ }
+
+ if (strcmp(ctx->lexer->token.s, "hash") &&
+ strcmp(ctx->lexer->token.s, "random")) {
+ lexer_syntax_error(ctx->lexer, "Invalid value for "
+ "port hash");
+ }
+
+ cn->port_range.port_hash = xstrdup(ctx->lexer->token.s);
+ lexer_get(ctx->lexer);
+ }
}
cn->port_range.exists = true;
@@ -838,6 +872,10 @@ format_ct_nat(const struct ovnact_ct_nat *cn, const char *name, struct ds *s)
if (cn->port_range.port_hi) {
ds_put_format(s, "-%d", cn->port_range.port_hi);
}
+
+ if (cn->port_range.port_hash) {
+ ds_put_format(s, ",%s", cn->port_range.port_hash);
+ }
ds_put_char(s, ')');
}
@@ -904,8 +942,17 @@ 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;
+ const char *port_hash = cn->port_range.port_hash;
+ nat->range.proto.min = cn->port_range.port_lo;
+ nat->range.proto.max = cn->port_range.port_hi;
+
+ if (port_hash) {
+ if (!strcmp(port_hash, "hash")) {
+ nat->flags |= NX_NAT_F_PROTO_HASH;
+ } else {
+ nat->flags |= NX_NAT_F_PROTO_RANDOM;
+ }
+ }
}
ofpacts->header = ofpbuf_push_uninit(ofpacts, nat_offset);
diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
index e37b346..a7e2aef 100644
--- a/northd/ovn-northd.c
+++ b/northd/ovn-northd.c
@@ -8971,6 +8971,10 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
if (nat->external_port_range[0]) {
ds_put_format(&actions, ",%s",
nat->external_port_range);
+ if (nat->external_port_hash[0]) {
+ ds_put_format(&actions, ",%s",
+ nat->external_port_hash);
+ }
}
ds_put_format(&actions, ");");
}
@@ -9004,6 +9008,10 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
if (nat->external_port_range[0]) {
ds_put_format(&actions, ",%s",
nat->external_port_range);
+ if (nat->external_port_hash[0]) {
+ ds_put_format(&actions, ",%s",
+ nat->external_port_hash);
+ }
}
ds_put_format(&actions, ");");
}
@@ -9115,6 +9123,10 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
if (nat->external_port_range[0]) {
ds_put_format(&actions, ",%s",
nat->external_port_range);
+ if (nat->external_port_hash[0]) {
+ ds_put_format(&actions, ",%s",
+ nat->external_port_hash);
+ }
}
ds_put_format(&actions, ");");
}
@@ -9158,6 +9170,10 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
if (nat->external_port_range[0]) {
ds_put_format(&actions, ",%s",
nat->external_port_range);
+ if (nat->external_port_hash[0]) {
+ ds_put_format(&actions, ",%s",
+ nat->external_port_hash);
+ }
}
ds_put_format(&actions, ");");
}
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index a0109ae..75cc830 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -1470,3 +1470,34 @@ AT_CHECK([ovn-nbctl --wait=sb sync], [0])
AT_CHECK([test 0 = $(ovn-sbctl list Ha_Chassis_Group | wc -l)])
AT_CLEANUP
+
+AT_SETUP([ovn -- Port Range and Hash in NAT entries])
+AT_SKIP_IF([test $HAVE_PYTHON = no])
+ovn_start
+
+ovn-nbctl lr-add lr0
+ovn-nbctl lrp-add lr0 lr0-public 00:00:01:01:02:04 192.168.2.1/24
+ovn-nbctl lrp-add lr0 lr0-join 00:00:01:01:02:04 10.10.0.1/24
+
+ovn-nbctl set logical_router lr0 options:chassis=ch1
+
+ovn-nbctl --portrange lr-nat-add lr0 snat 192.168.2.1 10.0.0.0/24 1-1000 hash
+ovn-nbctl --portrange lr-nat-add lr0 dnat_and_snat 192.168.2.4 10.0.0.4 1100-2000 random
+ovn-nbctl --portrange lr-nat-add lr0 dnat 192.168.2.5 10.0.0.5 2100-3000
+
+ovn-sbctl dump-flows lr0
+
+AT_CHECK([ovn-sbctl dump-flows lr0 | grep lr_out_snat | \
+grep "ct_snat(192.168.2.1,1-1000,hash)" | wc -l], [0], [1
+])
+AT_CHECK([ovn-sbctl dump-flows lr0 | grep lr_in_dnat | \
+grep "ct_dnat(10.0.0.4,1100-2000,random)" | wc -l], [0], [1
+])
+AT_CHECK([ovn-sbctl dump-flows lr0 | grep lr_out_snat | \
+grep "ct_snat(192.168.2.4,1100-2000,random)" | wc -l], [0], [1
+])
+AT_CHECK([ovn-sbctl dump-flows lr0 | grep lr_in_dnat | \
+grep "ct_dnat(10.0.0.5,2100-3000)" | wc -l], [0], [1
+])
+
+AT_CLEANUP
diff --git a/tests/ovn.at b/tests/ovn.at
index c04cd06..d31965c 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -1059,6 +1059,22 @@ 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, 1000);
+ formats as ct_dnat(192.168.1.2,1000);
+ encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2:1000))
+ has prereqs ip
+ct_dnat(192.168.1.2, 1-3000, hash);
+ formats as ct_dnat(192.168.1.2,1-3000,hash);
+ encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2:1-3000,hash))
+ has prereqs ip
+ct_dnat(192.168.1.2, 1-3000, random);
+ formats as ct_dnat(192.168.1.2,1-3000,random);
+ encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2:1-3000,random))
+ has prereqs ip
+ct_dnat(192.168.1.2, 1000, hash);
+ formats as ct_dnat(192.168.1.2,1000,hash);
+ encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2:1000,hash))
+ has prereqs ip
ct_dnat(192.168.1.2, 192.168.1.3);
Syntax error at `192.168.1.3' expecting Integer for port range.
@@ -1072,12 +1088,20 @@ 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.
-ct_dnat(192.168.1.2, 1000);
- formats as ct_dnat(192.168.1.2,1000);
- encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2:1000))
- has prereqs ip
ct_dnat(192.168.1.2, 1000-100);
Syntax error at `100' range high should be greater than range low.
+ct_dnat(192.168.1.2, hash);
+ Syntax error at `hash' expecting Integer for port range.
+ct_dnat(192.168.1.2, random);
+ Syntax error at `random' expecting Integer for port range.
+ct_dnat(192.168.1.2, 192.168.1.3, hash);
+ Syntax error at `192.168.1.3' expecting Integer for port range.
+ct_dnat(192.168.1.2, foo, hash);
+ Syntax error at `foo' expecting Integer for port range.
+ct_dnat(192.168.1.2, 1000-foo, hash);
+ Syntax error at `foo' expecting Integer for port range.
+ct_dnat(192.168.1.2, 1000-100, hash);
+ Syntax error at `100' range high should be greater than range low.
# ct_snat
ct_snat;
@@ -1093,6 +1117,22 @@ ct_snat(192.168.1.2, 1-3000);
formats as ct_snat(192.168.1.2,1-3000);
encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2:1-3000))
has prereqs ip
+ct_snat(192.168.1.2, 1000);
+ formats as ct_snat(192.168.1.2,1000);
+ encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2:1000))
+ has prereqs ip
+ct_snat(192.168.1.2, 1-3000, hash);
+ formats as ct_snat(192.168.1.2,1-3000,hash);
+ encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2:1-3000,hash))
+ has prereqs ip
+ct_snat(192.168.1.2, 1-3000, random);
+ formats as ct_snat(192.168.1.2,1-3000,random);
+ encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2:1-3000,random))
+ has prereqs ip
+ct_snat(192.168.1.2, 1000, hash);
+ formats as ct_snat(192.168.1.2,1000,hash);
+ encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2:1000,hash))
+ has prereqs ip
ct_snat(192.168.1.2, 192.168.1.3);
Syntax error at `192.168.1.3' expecting Integer for port range.
@@ -1106,12 +1146,22 @@ ct_snat(192.168.1.2, foo);
Syntax error at `foo' expecting Integer for port range.
ct_snat(192.168.1.2, 1000-foo);
Syntax error at `foo' expecting Integer for port range.
-ct_snat(192.168.1.2, 1000);
- formats as ct_snat(192.168.1.2,1000);
- encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2:1000))
- has prereqs ip
ct_snat(192.168.1.2, 1000-100);
Syntax error at `100' range high should be greater than range low.
+ct_snat(192.168.1.2, hash);
+ Syntax error at `hash' expecting Integer for port range.
+ct_snat(192.168.1.2, random);
+ Syntax error at `random' expecting Integer for port range.
+ct_snat(192.168.1.2, 192.168.1.3, hash);
+ Syntax error at `192.168.1.3' expecting Integer for port range.
+ct_snat(192.168.1.2, foo, hash);
+ Syntax error at `foo' expecting Integer for port range.
+ct_snat(192.168.1.2, 1000-foo, hash);
+ Syntax error at `foo' expecting Integer for port range.
+ct_snat(192.168.1.2, 1000-100, hash);
+ Syntax error at `100' range high should be greater than range low.
+
+
# ct_clear
ct_clear;
encodes as ct_clear
--
1.8.3.1
More information about the dev
mailing list