Acked-by: Mark Michelson <[email protected]>

On 11/18/21 13:13, [email protected] wrote:
From: Numan Siddique <[email protected]>

These actions are very similar to ct_dnat and ct_snat respectively
with one difference.  These new actions use the same zone id
for natting.  Upcoming patch will make use of these actions.

Signed-off-by: Numan Siddique <[email protected]>
---

v1 -> v2
----
  * No changes.

  include/ovn/actions.h        |  2 ++
  include/ovn/logical-fields.h |  2 ++
  lib/actions.c                | 59 +++++++++++++++++++++++++-----
  ovn-sb.xml                   | 44 +++++++++++++++++++++++
  tests/ovn.at                 | 69 ++++++++++++++++++++++++++++++++++++
  utilities/ovn-trace.c        | 18 ++++++++--
  6 files changed, 184 insertions(+), 10 deletions(-)

diff --git a/include/ovn/actions.h b/include/ovn/actions.h
index f023a37b9..ede5eb93c 100644
--- a/include/ovn/actions.h
+++ b/include/ovn/actions.h
@@ -66,6 +66,8 @@ struct ovn_extend_table;
      OVNACT(CT_COMMIT_V2,      ovnact_nest)            \
      OVNACT(CT_DNAT,           ovnact_ct_nat)          \
      OVNACT(CT_SNAT,           ovnact_ct_nat)          \
+    OVNACT(CT_DNAT_IN_CZONE,  ovnact_ct_nat)          \
+    OVNACT(CT_SNAT_IN_CZONE,  ovnact_ct_nat)          \
      OVNACT(CT_LB,             ovnact_ct_lb)           \
      OVNACT(SELECT,            ovnact_select)          \
      OVNACT(CT_CLEAR,          ovnact_null)            \
diff --git a/include/ovn/logical-fields.h b/include/ovn/logical-fields.h
index ef97117b9..c9675f81c 100644
--- a/include/ovn/logical-fields.h
+++ b/include/ovn/logical-fields.h
@@ -36,6 +36,8 @@ enum ovn_controller_event {
                                         * (32 bits). */
  #define MFF_LOG_SNAT_ZONE  MFF_REG12  /* conntrack snat zone for gateway 
router
                                         * (32 bits). */
+#define MFF_LOG_NAT_ZONE   MFF_LOG_DNAT_ZONE /* conntrack zone for both snat
+                                              * and dnat. */
  #define MFF_LOG_CT_ZONE    MFF_REG13  /* Logical conntrack zone for lports
                                         * (32 bits). */
  #define MFF_LOG_INPORT     MFF_REG14  /* Logical input port (32 bits). */
diff --git a/lib/actions.c b/lib/actions.c
index 7cf6be308..6b9a426ae 100644
--- a/lib/actions.c
+++ b/lib/actions.c
@@ -917,6 +917,20 @@ parse_CT_SNAT(struct action_context *ctx)
      parse_ct_nat(ctx, "ct_snat", ovnact_put_CT_SNAT(ctx->ovnacts));
  }
+static void
+parse_CT_DNAT_IN_CZONE(struct action_context *ctx)
+{
+    parse_ct_nat(ctx, "ct_dnat_in_czone",
+                 ovnact_put_CT_DNAT_IN_CZONE(ctx->ovnacts));
+}
+
+static void
+parse_CT_SNAT_IN_CZONE(struct action_context *ctx)
+{
+    parse_ct_nat(ctx, "ct_snat_in_czone",
+                 ovnact_put_CT_SNAT_IN_CZONE(ctx->ovnacts));
+}
+
  static void
  format_ct_nat(const struct ovnact_ct_nat *cn, const char *name, struct ds *s)
  {
@@ -954,21 +968,30 @@ format_CT_SNAT(const struct ovnact_ct_nat *cn, struct ds 
*s)
      format_ct_nat(cn, "ct_snat", s);
  }
+static void
+format_CT_DNAT_IN_CZONE(const struct ovnact_ct_nat *cn, struct ds *s)
+{
+    format_ct_nat(cn, "ct_dnat_in_czone", s);
+}
+
+static void
+format_CT_SNAT_IN_CZONE(const struct ovnact_ct_nat *cn, struct ds *s)
+{
+    format_ct_nat(cn, "ct_snat_in_czone", s);
+}
+
  static void
  encode_ct_nat(const struct ovnact_ct_nat *cn,
                const struct ovnact_encode_params *ep,
-              bool snat, struct ofpbuf *ofpacts)
+              bool snat, enum mf_field_id zone_src,
+              struct ofpbuf *ofpacts)
  {
      const size_t ct_offset = ofpacts->size;
      ofpbuf_pull(ofpacts, ct_offset);
struct ofpact_conntrack *ct = ofpact_put_CT(ofpacts);
      ct->recirc_table = cn->ltable + first_ptable(ep, ep->pipeline);
-    if (snat) {
-        ct->zone_src.field = mf_from_id(MFF_LOG_SNAT_ZONE);
-    } else {
-        ct->zone_src.field = mf_from_id(MFF_LOG_DNAT_ZONE);
-    }
+    ct->zone_src.field = mf_from_id(zone_src);
      ct->zone_src.ofs = 0;
      ct->zone_src.n_bits = 16;
      ct->flags = 0;
@@ -1020,7 +1043,7 @@ encode_CT_DNAT(const struct ovnact_ct_nat *cn,
                 const struct ovnact_encode_params *ep,
                 struct ofpbuf *ofpacts)
  {
-    encode_ct_nat(cn, ep, false, ofpacts);
+    encode_ct_nat(cn, ep, false, MFF_LOG_DNAT_ZONE, ofpacts);
  }
static void
@@ -1028,7 +1051,23 @@ encode_CT_SNAT(const struct ovnact_ct_nat *cn,
                 const struct ovnact_encode_params *ep,
                 struct ofpbuf *ofpacts)
  {
-    encode_ct_nat(cn, ep, true, ofpacts);
+    encode_ct_nat(cn, ep, true, MFF_LOG_SNAT_ZONE, ofpacts);
+}
+
+static void
+encode_CT_DNAT_IN_CZONE(const struct ovnact_ct_nat *cn,
+                        const struct ovnact_encode_params *ep,
+                        struct ofpbuf *ofpacts)
+{
+    encode_ct_nat(cn, ep, false, MFF_LOG_NAT_ZONE, ofpacts);
+}
+
+static void
+encode_CT_SNAT_IN_CZONE(const struct ovnact_ct_nat *cn,
+                        const struct ovnact_encode_params *ep,
+                        struct ofpbuf *ofpacts)
+{
+    encode_ct_nat(cn, ep, true, MFF_LOG_NAT_ZONE, ofpacts);
  }
static void
@@ -4017,6 +4056,10 @@ parse_action(struct action_context *ctx)
          parse_CT_DNAT(ctx);
      } else if (lexer_match_id(ctx->lexer, "ct_snat")) {
          parse_CT_SNAT(ctx);
+    } else if (lexer_match_id(ctx->lexer, "ct_dnat_in_czone")) {
+        parse_CT_DNAT_IN_CZONE(ctx);
+    } else if (lexer_match_id(ctx->lexer, "ct_snat_in_czone")) {
+        parse_CT_SNAT_IN_CZONE(ctx);
      } else if (lexer_match_id(ctx->lexer, "ct_lb")) {
          parse_ct_lb_action(ctx);
      } else if (lexer_match_id(ctx->lexer, "ct_clear")) {
diff --git a/ovn-sb.xml b/ovn-sb.xml
index 150051f26..9ddacdf09 100644
--- a/ovn-sb.xml
+++ b/ovn-sb.xml
@@ -1383,6 +1383,50 @@
            </p>
          </dd>
+ <dt><code>ct_dnat_in_czone;</code></dt>
+        <dt><code>ct_dnat_in_czone(<var>IP</var>);</code></dt>
+        <dd>
+          <p>
+            <code>ct_dnat_in_czone</code> sends the packet through the common
+            NAT zone (used for both DNAT and SNAT) in connection tracking table
+            to unDNAT any packet that was DNATed in the opposite direction.
+            The packet is then automatically sent to to the next tables as if
+            followed by <code>next;</code> action.  The next tables will see
+            the changes in the packet caused by the connection tracker.
+          </p>
+          <p>
+            <code>ct_dnat_in_czone(<var>IP</var>)</code> sends the packet
+            through the common NAT zone to change the destination IP address
+            of the packet to the one provided inside the parentheses and
+            commits the connection.  The packet is then automatically sent to
+            the next tables as if followed by <code>next;</code> action.  The
+            next tables will see the changes in the packet caused by the
+            connection tracker.
+          </p>
+        </dd>
+
+        <dt><code>ct_snat_in_czone;</code></dt>
+        <dt><code>ct_snat_in_czone(<var>IP</var>);</code></dt>
+        <dd>
+          <p>
+            <code>ct_snat_in_czone</code> sends the packet through the common
+            NAT zone to unSNAT any packet that was SNATed in the opposite
+            direction.  The packet is automatically sent to the next tables as
+            if followed by the <code>next;</code> action.   The next tables
+            will see the changes in the packet caused by the connection
+            tracker.
+          </p>
+          <p>
+            <code>ct_snat_in_czone(<var>IP</var>)</code> sends the packet\
+            through the common NAT zone to change the source IP address of
+            the packet to the one provided inside the parenthesis and commits
+            the connection.  The packet is then automatically sent to the next
+            tables as if followed by <code>next;</code> action.  The next
+            tables will see the changes in the packet caused by the connection
+            tracker.
+          </p>
+        </dd>
+
          <dt><code>ct_clear;</code></dt>
          <dd>
            Clears connection tracking state.
diff --git a/tests/ovn.at b/tests/ovn.at
index ae832918c..0d606b42f 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -1193,6 +1193,40 @@ ct_dnat(192.168.1.2, 1000);
  ct_dnat(192.168.1.2, 1000-100);
      Syntax error at `100' range high should be greater than range low.
+# ct_dnat_in_czone
+ct_dnat_in_czone;
+    encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
+    has prereqs ip
+ct_dnat_in_czone(192.168.1.2);
+    encodes as 
ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
+    has prereqs ip
+ct_dnat_in_czone(fd11::2);
+    encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=fd11::2))
+    has prereqs ip
+ct_dnat_in_czone(192.168.1.2, 1-3000);
+    formats as ct_dnat_in_czone(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_in_czone(192.168.1.2, 192.168.1.3);
+    Syntax error at `192.168.1.3' expecting Integer for port range.
+ct_dnat_in_czone(foo);
+    Syntax error at `foo' expecting IPv4 or IPv6 address.
+ct_dnat_in_czone(foo, bar);
+    Syntax error at `foo' expecting IPv4 or IPv6 address.
+ct_dnat_in_czone();
+    Syntax error at `)' expecting IPv4 or IPv6 address.
+ct_dnat_in_czone(192.168.1.2, foo);
+    Syntax error at `foo' expecting Integer for port range.
+ct_dnat_in_czone(192.168.1.2, 1000-foo);
+    Syntax error at `foo' expecting Integer for port range.
+ct_dnat_in_czone(192.168.1.2, 1000);
+    formats as ct_dnat_in_czone(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_in_czone(192.168.1.2, 1000-100);
+    Syntax error at `100' range high should be greater than range low.
+
  # ct_snat
  ct_snat;
      encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
@@ -1226,6 +1260,41 @@ ct_snat(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_in_czone
+ct_snat_in_czone;
+    encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
+    has prereqs ip
+ct_snat_in_czone(192.168.1.2);
+    encodes as 
ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(src=192.168.1.2))
+    has prereqs ip
+ct_snat_in_czone(fd11::2);
+    encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(src=fd11::2))
+    has prereqs ip
+ct_snat_in_czone(192.168.1.2, 1-3000);
+    formats as ct_snat_in_czone(192.168.1.2,1-3000);
+    encodes as 
ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(src=192.168.1.2:1-3000))
+    has prereqs ip
+
+ct_snat_in_czone(192.168.1.2, 192.168.1.3);
+    Syntax error at `192.168.1.3' expecting Integer for port range.
+ct_snat_in_czone(foo);
+    Syntax error at `foo' expecting IPv4 or IPv6 address.
+ct_snat_in_czone(foo, bar);
+    Syntax error at `foo' expecting IPv4 or IPv6 address.
+ct_snat_in_czone();
+    Syntax error at `)' expecting IPv4 or IPv6 address.
+ct_snat_in_czone(192.168.1.2, foo);
+    Syntax error at `foo' expecting Integer for port range.
+ct_snat_in_czone(192.168.1.2, 1000-foo);
+    Syntax error at `foo' expecting Integer for port range.
+ct_snat_in_czone(192.168.1.2, 1000);
+    formats as ct_snat_in_czone(192.168.1.2,1000);
+    encodes as 
ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(src=192.168.1.2:1000))
+    has prereqs ip
+ct_snat_in_czone(192.168.1.2, 1000-100);
+    Syntax error at `100' range high should be greater than range low.
+
  # ct_clear
  ct_clear;
      encodes as ct_clear
diff --git a/utilities/ovn-trace.c b/utilities/ovn-trace.c
index 65a1822ea..617ad834c 100644
--- a/utilities/ovn-trace.c
+++ b/utilities/ovn-trace.c
@@ -2286,7 +2286,10 @@ execute_ct_nat(const struct ovnact_ct_nat *ct_nat,
                 const struct ovntrace_datapath *dp, struct flow *uflow,
                 enum ovnact_pipeline pipeline, struct ovs_list *super)
  {
-    bool is_dst = ct_nat->ovnact.type == OVNACT_CT_DNAT;
+    bool is_dst = (ct_nat->ovnact.type == OVNACT_CT_DNAT ||
+                   ct_nat->ovnact.type == OVNACT_CT_DNAT_IN_CZONE);
+    bool nat_in_czone = (ct_nat->ovnact.type == OVNACT_CT_DNAT_IN_CZONE ||
+                         ct_nat->ovnact.type == OVNACT_CT_SNAT_IN_CZONE);
      if (!is_dst && dp->has_local_l3gateway && ct_nat->family == AF_UNSPEC) {
          /* "ct_snat;" has no visible effect in a gateway router. */
          return;
@@ -2297,7 +2300,8 @@ execute_ct_nat(const struct ovnact_ct_nat *ct_nat,
       * and figure out the changes if any. */
      struct flow ct_flow = *uflow;
      struct ds s = DS_EMPTY_INITIALIZER;
-    ds_put_format(&s, "ct_%cnat", direction[0]);
+    ds_put_format(&s, "ct_%cnat%s", direction[0],
+                  nat_in_czone ? "in_czone" : "");
      if (ct_nat->family != AF_UNSPEC) {
          if (ct_nat->family == AF_INET) {
              ds_put_format(&s, "(ip4.%s="IP_FMT")", direction,
@@ -2610,6 +2614,16 @@ trace_actions(const struct ovnact *ovnacts, size_t 
ovnacts_len,
              execute_ct_nat(ovnact_get_CT_SNAT(a), dp, uflow, pipeline, super);
              break;
+ case OVNACT_CT_DNAT_IN_CZONE:
+            execute_ct_nat(ovnact_get_CT_DNAT_IN_CZONE(a), dp, uflow,
+                           pipeline, super);
+            break;
+
+        case OVNACT_CT_SNAT_IN_CZONE:
+            execute_ct_nat(ovnact_get_CT_SNAT_IN_CZONE(a), dp, uflow,
+                           pipeline, super);
+            break;
+
          case OVNACT_CT_LB:
              execute_ct_lb(ovnact_get_CT_LB(a), dp, uflow, pipeline, super);
              break;


_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to