Hi, Gentle reminder for reviewing this series.
Regards, Ankur ________________________________ From: Ankur Sharma <ankur.sha...@nutanix.com> Sent: Friday, October 4, 2019 1:13 PM To: ovs-dev@openvswitch.org <ovs-dev@openvswitch.org> Cc: Ankur Sharma <ankur.sha...@nutanix.com> Subject: [PATCH v2 1/2 ovn] OVN: ADD nbctl cli to mark a dnat_and_snat rule as stateless Adding ovn-nbctl to mark a dnat_and_snat rule as stateless. This configuration will added to "options" column of NAT table. Signed-off-by: Ankur Sharma <ankur.sha...@nutanix.com> --- ovn-nb.ovsschema | 6 ++++-- ovn-nb.xml | 5 +++++ tests/ovn-nbctl.at | 29 +++++++++++++++++++++++++++++ utilities/ovn-nbctl.8.xml | 12 +++++++++++- utilities/ovn-nbctl.c | 30 +++++++++++++++++++++++++++++- 5 files changed, 78 insertions(+), 4 deletions(-) diff --git a/ovn-nb.ovsschema b/ovn-nb.ovsschema index 2c87cbb..084305b 100644 --- a/ovn-nb.ovsschema +++ b/ovn-nb.ovsschema @@ -1,7 +1,7 @@ { "name": "OVN_Northbound", - "version": "5.16.0", - "cksum": "923459061 23095", + "version": "5.17.0", + "cksum": "1128988054 23237", "tables": { "NB_Global": { "columns": { @@ -345,6 +345,8 @@ "snat", "dnat_and_snat" ]]}}}, + "options": {"type": {"key": "string", "value": "string", + "min": 0, "max": "unlimited"}}, "external_ids": { "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}}, diff --git a/ovn-nb.xml b/ovn-nb.xml index b41b579..a1ebe05 100644 --- a/ovn-nb.xml +++ b/ovn-nb.xml @@ -2254,6 +2254,11 @@ </p> </column> + <column name="options" key="is_stateless"> + Indicates if a dnat_and_snat rule should lead to connection + tracking state or not. + </column> + <group title="Common Columns"> <column name="external_ids"> See <em>External IDs</em> at the beginning of this document. diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at index 01091dd..4ebc1bb 100644 --- a/tests/ovn-nbctl.at +++ b/tests/ovn-nbctl.at @@ -516,6 +516,31 @@ dnat_and_snat 30.0.0.2 192.168.1.3 snat 30.0.0.1 192.168.1.0/24 ]) +AT_CHECK([ovn-nbctl --bare --columns=options list nat | grep is_stateless=true| wc -l], [0], +[0 +]) +AT_CHECK([ovn-nbctl --stateless lr-nat-add lr0 dnat_and_snat 40.0.0.2 192.168.1.4]) +AT_CHECK([ovn-nbctl --bare --columns=options list nat | grep is_stateless=true| wc -l], [0], +[1 +]) +AT_CHECK([ovn-nbctl --stateless lr-nat-add lr0 dnat 40.0.0.2 192.168.1.4], [1], [], +[ovn-nbctl: is_stateless is not applicable to dnat or snat types +]) +AT_CHECK([ovn-nbctl --stateless lr-nat-add lr0 snat 40.0.0.2 192.168.1.4], [1], [], +[ovn-nbctl: is_stateless is not applicable to dnat or snat types +]) +AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 40.0.0.2 192.168.1.5], [1], [], +[ovn-nbctl: 40.0.0.2, 192.168.1.5: External ip cannot be shared across stateless and stateful NATs +]) +AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 40.0.0.2 192.168.1.5], [1], [], +[ovn-nbctl: 40.0.0.2, 192.168.1.5: External ip cannot be shared across stateless and stateful NATs +]) + +AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 40.0.0.3 192.168.1.6]) +AT_CHECK([ovn-nbctl --stateless lr-nat-add lr0 dnat_and_snat 40.0.0.3 192.168.1.7], [1], [], +[ovn-nbctl: 40.0.0.3, 192.168.1.7: External ip cannot be shared across stateless and stateful NATs +]) + dnl Deletes the NATs AT_CHECK([ovn-nbctl lr-nat-del lr0 dnat_and_snat 30.0.0.3], [1], [], [ovn-nbctl: no matching NAT with the type (dnat_and_snat) and external_ip (30.0.0.3) @@ -533,14 +558,18 @@ AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [dnl TYPE EXTERNAL_IP LOGICAL_IP EXTERNAL_MAC LOGICAL_PORT dnat 30.0.0.1 192.168.1.2 dnat_and_snat 30.0.0.2 192.168.1.3 +dnat_and_snat 40.0.0.2 192.168.1.4 snat 30.0.0.1 192.168.1.0/24 +snat 40.0.0.3 192.168.1.6 ]) AT_CHECK([ovn-nbctl lr-nat-del lr0 dnat]) AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [dnl TYPE EXTERNAL_IP LOGICAL_IP EXTERNAL_MAC LOGICAL_PORT dnat_and_snat 30.0.0.2 192.168.1.3 +dnat_and_snat 40.0.0.2 192.168.1.4 snat 30.0.0.1 192.168.1.0/24 +snat 40.0.0.3 192.168.1.6 ]) AT_CHECK([ovn-nbctl lr-nat-del lr0]) diff --git a/utilities/ovn-nbctl.8.xml b/utilities/ovn-nbctl.8.xml index fd75c0e..2161d8c 100644 --- a/utilities/ovn-nbctl.8.xml +++ b/utilities/ovn-nbctl.8.xml @@ -665,7 +665,7 @@ <h1>NAT Commands</h1> <dl> - <dt>[<code>--may-exist</code>] <code>lr-nat-add</code> <var>router</var> <var>type</var> <var>external_ip</var> <var>logical_ip</var> [<var>logical_port</var> <var>external_mac</var>]</dt> + <dt>[<code>--may-exist</code>] [<code>--stateless</code>]<code>lr-nat-add</code> <var>router</var> <var>type</var> <var>external_ip</var> <var>logical_ip</var> [<var>logical_port</var> <var>external_mac</var>]</dt> <dd> <p> Adds the specified NAT to <var>router</var>. @@ -681,8 +681,18 @@ The <var>logical_port</var> is the name of an existing logical switch port where the <var>logical_ip</var> resides. The <var>external_mac</var> is an Ethernet address. + The <var>--stateless</var> </p> <p> + When <code>--stateless</code> is specified then it implies that + we will be not use connection tracker, i.e internal ip and external + ip are 1:1 mapped. This implies that <code>--stateless</code> is + applicable only to dnat_and_snat type NAT rules. + An external ip with <code>--stateless</code> NAT cannot be shared + with any other NAT rule. + </p> + + <p> When <var>type</var> is <code>dnat</code>, the externally visible IP address <var>external_ip</var> is DNATted to the IP address <var>logical_ip</var> in the logical space. diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c index a89a9cb..7a3ac6e 100644 --- a/utilities/ovn-nbctl.c +++ b/utilities/ovn-nbctl.c @@ -691,6 +691,7 @@ Policy commands:\n\ lr-policy-list ROUTER print policies for ROUTER\n\ \n\ NAT commands:\n\ + [--stateless]\n\ lr-nat-add ROUTER TYPE EXTERNAL_IP LOGICAL_IP [LOGICAL_PORT EXTERNAL_MAC]\n\ add a NAT to ROUTER\n\ lr-nat-del ROUTER [TYPE [IP]]\n\ @@ -3926,6 +3927,13 @@ nbctl_lr_nat_add(struct ctl_context *ctx) } bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL; + bool is_stateless = shash_find(&ctx->options, "--stateless") != NULL; + + if (strcmp(nat_type, "dnat_and_snat") && is_stateless) { + ctl_error(ctx, "is_stateless is not applicable to dnat or snat types"); + return; + } + int is_snat = !strcmp("snat", nat_type); for (size_t i = 0; i < lr->n_nat; i++) { const struct nbrec_nat *nat = lr->nat[i]; @@ -3957,10 +3965,25 @@ nbctl_lr_nat_add(struct ctl_context *ctx) return; } } + + } + if (!strcmp(nat_type, "dnat_and_snat") || + !strcmp(nat->type, "dnat_and_snat")) { + + if (!strcmp(nat->external_ip, external_ip)) { + struct smap nat_options = SMAP_INITIALIZER(&nat_options); + if (!strcmp(smap_get(&nat->options, "is_stateless"), + "true") || is_stateless) { + ctl_error(ctx, "%s, %s: External ip cannot be shared " + "across stateless and stateful NATs", + external_ip, new_logical_ip); + } + } } } /* Create the NAT. */ + struct smap nat_options = SMAP_INITIALIZER(&nat_options); struct nbrec_nat *nat = nbrec_nat_insert(ctx->txn); nbrec_nat_set_type(nat, nat_type); nbrec_nat_set_external_ip(nat, external_ip); @@ -3969,7 +3992,12 @@ nbctl_lr_nat_add(struct ctl_context *ctx) nbrec_nat_set_logical_port(nat, logical_port); nbrec_nat_set_external_mac(nat, external_mac); } + + smap_add(&nat_options, "is_stateless", is_stateless ? "true":"false"); + nbrec_nat_set_options(nat, &nat_options); + free(new_logical_ip); + smap_destroy(&nat_options); /* Insert the NAT into the logical router. */ nbrec_logical_router_verify_nat(lr); @@ -5689,7 +5717,7 @@ static const struct ctl_command_syntax nbctl_commands[] = { /* NAT commands. */ { "lr-nat-add", 4, 6, "ROUTER TYPE EXTERNAL_IP LOGICAL_IP [LOGICAL_PORT EXTERNAL_MAC]", NULL, - nbctl_lr_nat_add, NULL, "--may-exist", RW }, + nbctl_lr_nat_add, NULL, "--may-exist,--stateless", RW }, { "lr-nat-del", 1, 3, "ROUTER [TYPE [IP]]", NULL, nbctl_lr_nat_del, NULL, "--if-exists", RW }, { "lr-nat-list", 1, 1, "ROUTER", NULL, nbctl_lr_nat_list, NULL, "", RO }, -- 1.8.3.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev