Blob Blame History Raw
From c0bdec23cc9967abdac8eeaa3b8d7cddafedacdb Mon Sep 17 00:00:00 2001
From: Ankur Sharma <ankur.sharma@nutanix.com>
Date: Wed, 28 Aug 2019 01:55:28 +0000
Subject: [PATCH 02/12] OVN: Vlan backed DVR N-S, redirect-type option

Background:
With 795d7f24ce0e ("OVN: Enable E-W Traffic, Vlan backed DVR"), we have added
support for E-W workflow for vlan backed DVRs.

This series enables N-S workflow for vlan backed DVRs.

Key difference between E-W and N-S traffic flow is that
N-S flow requires a gateway chassis. A gateway chassis
will be responsible for following:
a. Doing Network Address Translation (NAT).
b. Becoming entry and exit point for North->South
   and South->North traffic respectively.

OVN by default always uses overlay encapsulation to redirect
the packet to gateway chassis. This series will enable
the redirection to gateway chassis in the absence of encapsulation.

This patch:
a. Adds a new key-value in options of a router port.
b. This new config key will be used by ovn-controller
   to determine if a redirected packet will go out of
   tunnel port or localnet port.
c. key is "redirect-type" and it takes "overlay" and
   "bridged" as values.
d. Added ovn-nbctl command to set and get redirect-type
   option on a router port.
e. This new configuration is added because bridged or overlay
   based forwarding is considered to be a logical switch property,
   hence for a router configuration has to be done at the router port
   level.

Change-Id: Ic002afa5ddb1da22d5833df9d584de256ba3f65a
Signed-off-by: Ankur Sharma <ankur.sharma@nutanix.com>
Signed-off-by: Numan Siddique <nusiddiq@redhat.com>
---
 ovn/northd/ovn-northd.c   |  6 ++++
 ovn/ovn-nb.xml            | 43 ++++++++++++++++++++++++++
 ovn/utilities/ovn-nbctl.c | 64 +++++++++++++++++++++++++++++++++++++++
 tests/ovn-nbctl.at        | 25 +++++++++++++++
 tests/ovn-northd.at       | 30 ++++++++++++++++++
 5 files changed, 168 insertions(+)

diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index 952d0ae8a..cd13f308e 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -2648,6 +2648,9 @@ ovn_port_update_sbrec(struct northd_context *ctx,
         if (op->derived) {
             const char *redirect_chassis = smap_get(&op->nbrp->options,
                                                     "redirect-chassis");
+            const char *redirect_type = smap_get(&op->nbrp->options,
+                                                 "redirect-type");
+
             int n_gw_options_set = 0;
             if (op->nbrp->ha_chassis_group) {
                 n_gw_options_set++;
@@ -2739,6 +2742,9 @@ ovn_port_update_sbrec(struct northd_context *ctx,
                 sbrec_port_binding_set_gateway_chassis(op->sb, NULL, 0);
             }
             smap_add(&new, "distributed-port", op->nbrp->name);
+            if (redirect_type) {
+                smap_add(&new, "redirect-type", redirect_type);
+            }
         } else {
             if (op->peer) {
                 smap_add(&new, "peer", op->peer->key);
diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml
index 0323a9d33..bce7463d2 100644
--- a/ovn/ovn-nb.xml
+++ b/ovn/ovn-nb.xml
@@ -2032,6 +2032,49 @@
           to <code>true</code>.
         </p>
       </column>
+
+      <column name="options" key="redirect-type">
+        <p>
+          This options dictates if a packet redirected to
+          <code>gateway chassis</code> will be overlay encapsulated
+          or go as a regular packet via the localnet port.
+        </p>
+
+        <p>
+          Option takes following values
+        </p>
+
+        <ul>
+          <li>
+            OVERLAY
+          </li>
+
+          <li>
+            BRIDGED
+          </li>
+        </ul>
+
+        <p>
+          OVERLAY option will ensure that redirected packet goes out as
+          encapsulation via the tunnel port.
+        </p>
+
+        <p>
+          BRIDGED option will ensure that redirected packet goes out
+          via the localnet port tagged with vlan (if configured).
+        </p>
+
+        <p>
+          OVERLAY is the default redirection type.
+        </p>
+
+        <p>
+          Option is applicable only to gateway chassis attached logical
+          router ports.
+        </p>
+
+      </column>
+
     </group>
 
     <group title="Attachment">
diff --git a/ovn/utilities/ovn-nbctl.c b/ovn/utilities/ovn-nbctl.c
index 497d6f231..112cc1d54 100644
--- a/ovn/utilities/ovn-nbctl.c
+++ b/ovn/utilities/ovn-nbctl.c
@@ -661,6 +661,14 @@ Logical router port commands:\n\
                             ('enabled' or 'disabled')\n\
   lrp-get-enabled PORT      get administrative state PORT\n\
                             ('enabled' or 'disabled')\n\
+  lrp-set-redirect-type PORT TYPE\n\
+                            set whether redirected packet to gateway chassis\n\
+                            of PORT will be encapsulated or not\n\
+                            ('overlay' or 'vlan')\n\
+  lrp-get-redirect-type PORT\n\
+                            get whether redirected packet to gateway chassis\n\
+                            of PORT will be encapsulated or not\n\
+                            ('overlay' or 'vlan')\n\
 \n\
 Route commands:\n\
   [--policy=POLICY] lr-route-add ROUTER PREFIX NEXTHOP [PORT]\n\
@@ -4617,6 +4625,58 @@ nbctl_lrp_get_enabled(struct ctl_context *ctx)
                   *lrp->enabled ? "enabled" : "disabled");
 }
 
+/* Set the logical router port redirect type. */
+static void
+nbctl_lrp_set_redirect_type(struct ctl_context *ctx)
+{
+    const char *id = ctx->argv[1];
+    const char *type = ctx->argv[2];
+    const struct nbrec_logical_router_port *lrp = NULL;
+    struct smap lrp_options;
+
+    char *error = lrp_by_name_or_uuid(ctx, id, true, &lrp);
+    if (error) {
+        ctx->error = error;
+        return;
+    }
+
+    if (strcasecmp(type, "bridged") && strcasecmp(type, "overlay")) {
+        error = xasprintf("Invalid redirect type: %s", type);
+        ctx->error = error;
+        return;
+    }
+
+    smap_init(&lrp_options);
+    smap_clone(&lrp_options, &lrp->options);
+
+    if (smap_get(&lrp_options, "redirect-type")) {
+        smap_replace(&lrp_options, "redirect-type", type);
+    } else {
+        smap_add(&lrp_options, "redirect-type", type);
+    }
+
+    nbrec_logical_router_port_set_options(lrp, &lrp_options);
+
+    smap_destroy(&lrp_options);
+}
+
+static void
+nbctl_lrp_get_redirect_type(struct ctl_context *ctx)
+{
+    const char *id = ctx->argv[1];
+    const struct nbrec_logical_router_port *lrp = NULL;
+
+    char *error = lrp_by_name_or_uuid(ctx, id, true, &lrp);
+    if (error) {
+        ctx->error = error;
+        return;
+    }
+
+    const char *redirect_type = smap_get(&lrp->options, "redirect-type");
+    ds_put_format(&ctx->output, "%s\n",
+                  !redirect_type ? "overlay": redirect_type);
+}
+
 struct ipv4_route {
     int priority;
     ovs_be32 addr;
@@ -5623,6 +5683,10 @@ static const struct ctl_command_syntax nbctl_commands[] = {
       NULL, "", RW },
     { "lrp-get-enabled", 1, 1, "PORT", NULL, nbctl_lrp_get_enabled,
       NULL, "", RO },
+    { "lrp-set-redirect-type", 2, 2, "PORT TYPE", NULL,
+      nbctl_lrp_set_redirect_type, NULL, "", RW },
+    { "lrp-get-redirect-type", 1, 1, "PORT", NULL, nbctl_lrp_get_redirect_type,
+      NULL, "", RO },
 
     /* logical router route commands. */
     { "lr-route-add", 3, 4, "ROUTER PREFIX NEXTHOP [PORT]", NULL,
diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at
index 30849682c..620b778b7 100644
--- a/tests/ovn-nbctl.at
+++ b/tests/ovn-nbctl.at
@@ -1243,6 +1243,31 @@ lrp0-chassis1     1
 
 dnl ---------------------------------------------------------------------
 
+OVN_NBCTL_TEST([ovn_nbctl_redirect_type], [logical router port redirect type], [
+AT_CHECK([ovn-nbctl lr-add lr0])
+AT_CHECK([ovn-nbctl lrp-add lr0 lrp0 00:00:00:01:02:03 192.168.1.1/24])
+AT_CHECK([ovn-nbctl lrp-get-redirect-type lrp0], [0], [dnl
+overlay
+])
+AT_CHECK([ovn-nbctl lrp-set-redirect-type lp0 bridged], [1], [],
+[ovn-nbctl: lp0: port name not found
+])
+AT_CHECK([ovn-nbctl lrp-set-redirect-type lrp0 bridged], [0], [])
+AT_CHECK([ovn-nbctl lrp-get-redirect-type lrp0], [0], [dnl
+bridged
+])
+AT_CHECK([ovn-nbctl lrp-set-redirect-type lrp0 overlay], [0], [])
+AT_CHECK([ovn-nbctl lrp-get-redirect-type lrp0], [0], [dnl
+overlay
+])
+AT_CHECK([ovn-nbctl lrp-set-redirect-type lrp0 abcd], [1], [],
+[ovn-nbctl: Invalid redirect type: abcd
+])
+
+])
+
+dnl ---------------------------------------------------------------------
+
 OVN_NBCTL_TEST([ovn_nbctl_lrp_enable], [logical router port enable and disable], [
 AT_CHECK([ovn-nbctl lr-add lr0])
 AT_CHECK([ovn-nbctl lrp-add lr0 lrp0 00:00:00:01:02:03 192.168.1.1/24])
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 0dea04edc..42033d589 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -936,3 +936,33 @@ OVS_WAIT_UNTIL([
     test 0 = $?])
 
 AT_CLEANUP
+
+AT_SETUP([ovn -- check Redirect Chassis propagation from NB to SB])
+AT_SKIP_IF([test $HAVE_PYTHON = no])
+ovn_start
+
+ovn-sbctl chassis-add gw1 geneve 127.0.0.1
+
+ovn-nbctl lr-add R1
+ovn-nbctl lrp-add R1 R1-S1 02:ac:10:01:00:01 172.16.1.1/24
+
+ovn-nbctl ls-add S1
+ovn-nbctl lsp-add S1 S1-R1
+ovn-nbctl lsp-set-type S1-R1 router
+ovn-nbctl lsp-set-addresses S1-R1 router
+ovn-nbctl --wait=sb lsp-set-options S1-R1 router-port=R1-S1
+
+ovn-nbctl lrp-set-gateway-chassis R1-S1 gw1
+
+uuid=`ovn-sbctl --columns=_uuid --bare find Port_Binding logical_port=cr-R1-S1`
+echo "CR-LRP UUID is: " $uuid
+
+ovn-nbctl lrp-set-redirect-type R1-S1 bridged
+OVS_WAIT_UNTIL([ovn-sbctl get Port_Binding ${uuid} options:redirect-type], [0], [bridged
+])
+
+ovn-nbctl lrp-set-redirect-type R1-S1 overlay
+OVS_WAIT_UNTIL([ovn-sbctl get Port_Binding ${uuid} options:redirect-type], [0], [overlay
+])
+
+AT_CLEANUP
-- 
2.23.0