bbaaef
From c0bdec23cc9967abdac8eeaa3b8d7cddafedacdb Mon Sep 17 00:00:00 2001
bbaaef
From: Ankur Sharma <ankur.sharma@nutanix.com>
bbaaef
Date: Wed, 28 Aug 2019 01:55:28 +0000
bbaaef
Subject: [PATCH 02/12] OVN: Vlan backed DVR N-S, redirect-type option
bbaaef
bbaaef
Background:
bbaaef
With 795d7f24ce0e ("OVN: Enable E-W Traffic, Vlan backed DVR"), we have added
bbaaef
support for E-W workflow for vlan backed DVRs.
bbaaef
bbaaef
This series enables N-S workflow for vlan backed DVRs.
bbaaef
bbaaef
Key difference between E-W and N-S traffic flow is that
bbaaef
N-S flow requires a gateway chassis. A gateway chassis
bbaaef
will be responsible for following:
bbaaef
a. Doing Network Address Translation (NAT).
bbaaef
b. Becoming entry and exit point for North->South
bbaaef
   and South->North traffic respectively.
bbaaef
bbaaef
OVN by default always uses overlay encapsulation to redirect
bbaaef
the packet to gateway chassis. This series will enable
bbaaef
the redirection to gateway chassis in the absence of encapsulation.
bbaaef
bbaaef
This patch:
bbaaef
a. Adds a new key-value in options of a router port.
bbaaef
b. This new config key will be used by ovn-controller
bbaaef
   to determine if a redirected packet will go out of
bbaaef
   tunnel port or localnet port.
bbaaef
c. key is "redirect-type" and it takes "overlay" and
bbaaef
   "bridged" as values.
bbaaef
d. Added ovn-nbctl command to set and get redirect-type
bbaaef
   option on a router port.
bbaaef
e. This new configuration is added because bridged or overlay
bbaaef
   based forwarding is considered to be a logical switch property,
bbaaef
   hence for a router configuration has to be done at the router port
bbaaef
   level.
bbaaef
bbaaef
Change-Id: Ic002afa5ddb1da22d5833df9d584de256ba3f65a
bbaaef
Signed-off-by: Ankur Sharma <ankur.sharma@nutanix.com>
bbaaef
Signed-off-by: Numan Siddique <nusiddiq@redhat.com>
bbaaef
---
bbaaef
 ovn/northd/ovn-northd.c   |  6 ++++
bbaaef
 ovn/ovn-nb.xml            | 43 ++++++++++++++++++++++++++
bbaaef
 ovn/utilities/ovn-nbctl.c | 64 +++++++++++++++++++++++++++++++++++++++
bbaaef
 tests/ovn-nbctl.at        | 25 +++++++++++++++
bbaaef
 tests/ovn-northd.at       | 30 ++++++++++++++++++
bbaaef
 5 files changed, 168 insertions(+)
bbaaef
bbaaef
diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
bbaaef
index 952d0ae8a..cd13f308e 100644
bbaaef
--- a/ovn/northd/ovn-northd.c
bbaaef
+++ b/ovn/northd/ovn-northd.c
bbaaef
@@ -2648,6 +2648,9 @@ ovn_port_update_sbrec(struct northd_context *ctx,
bbaaef
         if (op->derived) {
bbaaef
             const char *redirect_chassis = smap_get(&op->nbrp->options,
bbaaef
                                                     "redirect-chassis");
bbaaef
+            const char *redirect_type = smap_get(&op->nbrp->options,
bbaaef
+                                                 "redirect-type");
bbaaef
+
bbaaef
             int n_gw_options_set = 0;
bbaaef
             if (op->nbrp->ha_chassis_group) {
bbaaef
                 n_gw_options_set++;
bbaaef
@@ -2739,6 +2742,9 @@ ovn_port_update_sbrec(struct northd_context *ctx,
bbaaef
                 sbrec_port_binding_set_gateway_chassis(op->sb, NULL, 0);
bbaaef
             }
bbaaef
             smap_add(&new, "distributed-port", op->nbrp->name);
bbaaef
+            if (redirect_type) {
bbaaef
+                smap_add(&new, "redirect-type", redirect_type);
bbaaef
+            }
bbaaef
         } else {
bbaaef
             if (op->peer) {
bbaaef
                 smap_add(&new, "peer", op->peer->key);
bbaaef
diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml
bbaaef
index 0323a9d33..bce7463d2 100644
bbaaef
--- a/ovn/ovn-nb.xml
bbaaef
+++ b/ovn/ovn-nb.xml
bbaaef
@@ -2032,6 +2032,49 @@
bbaaef
           to true.
bbaaef
         

bbaaef
       </column>
bbaaef
+
bbaaef
+      <column name="options" key="redirect-type">
bbaaef
+        

bbaaef
+          This options dictates if a packet redirected to
bbaaef
+          gateway chassis will be overlay encapsulated
bbaaef
+          or go as a regular packet via the localnet port.
bbaaef
+        

bbaaef
+
bbaaef
+        

bbaaef
+          Option takes following values
bbaaef
+        

bbaaef
+
bbaaef
+        
    bbaaef
    +          
  • bbaaef
    +            OVERLAY
    bbaaef
    +          
    bbaaef
    +
    bbaaef
    +          
  • bbaaef
    +            BRIDGED
    bbaaef
    +          
    bbaaef
    +        
    bbaaef
    +
    bbaaef
    +        

    bbaaef
    +          OVERLAY option will ensure that redirected packet goes out as
    bbaaef
    +          encapsulation via the tunnel port.
    bbaaef
    +        

    bbaaef
    +
    bbaaef
    +        

    bbaaef
    +          BRIDGED option will ensure that redirected packet goes out
    bbaaef
    +          via the localnet port tagged with vlan (if configured).
    bbaaef
    +        

    bbaaef
    +
    bbaaef
    +        

    bbaaef
    +          OVERLAY is the default redirection type.
    bbaaef
    +        

    bbaaef
    +
    bbaaef
    +        

    bbaaef
    +          Option is applicable only to gateway chassis attached logical
    bbaaef
    +          router ports.
    bbaaef
    +        

    bbaaef
    +
    bbaaef
    +      </column>
    bbaaef
    +
    bbaaef
         </group>
    bbaaef
     
    bbaaef
         <group title="Attachment">
    bbaaef
    diff --git a/ovn/utilities/ovn-nbctl.c b/ovn/utilities/ovn-nbctl.c
    bbaaef
    index 497d6f231..112cc1d54 100644
    bbaaef
    --- a/ovn/utilities/ovn-nbctl.c
    bbaaef
    +++ b/ovn/utilities/ovn-nbctl.c
    bbaaef
    @@ -661,6 +661,14 @@ Logical router port commands:\n\
    bbaaef
                                 ('enabled' or 'disabled')\n\
    bbaaef
       lrp-get-enabled PORT      get administrative state PORT\n\
    bbaaef
                                 ('enabled' or 'disabled')\n\
    bbaaef
    +  lrp-set-redirect-type PORT TYPE\n\
    bbaaef
    +                            set whether redirected packet to gateway chassis\n\
    bbaaef
    +                            of PORT will be encapsulated or not\n\
    bbaaef
    +                            ('overlay' or 'vlan')\n\
    bbaaef
    +  lrp-get-redirect-type PORT\n\
    bbaaef
    +                            get whether redirected packet to gateway chassis\n\
    bbaaef
    +                            of PORT will be encapsulated or not\n\
    bbaaef
    +                            ('overlay' or 'vlan')\n\
    bbaaef
     \n\
    bbaaef
     Route commands:\n\
    bbaaef
       [--policy=POLICY] lr-route-add ROUTER PREFIX NEXTHOP [PORT]\n\
    bbaaef
    @@ -4617,6 +4625,58 @@ nbctl_lrp_get_enabled(struct ctl_context *ctx)
    bbaaef
                       *lrp->enabled ? "enabled" : "disabled");
    bbaaef
     }
    bbaaef
     
    bbaaef
    +/* Set the logical router port redirect type. */
    bbaaef
    +static void
    bbaaef
    +nbctl_lrp_set_redirect_type(struct ctl_context *ctx)
    bbaaef
    +{
    bbaaef
    +    const char *id = ctx->argv[1];
    bbaaef
    +    const char *type = ctx->argv[2];
    bbaaef
    +    const struct nbrec_logical_router_port *lrp = NULL;
    bbaaef
    +    struct smap lrp_options;
    bbaaef
    +
    bbaaef
    +    char *error = lrp_by_name_or_uuid(ctx, id, true, &lrp;;
    bbaaef
    +    if (error) {
    bbaaef
    +        ctx->error = error;
    bbaaef
    +        return;
    bbaaef
    +    }
    bbaaef
    +
    bbaaef
    +    if (strcasecmp(type, "bridged") && strcasecmp(type, "overlay")) {
    bbaaef
    +        error = xasprintf("Invalid redirect type: %s", type);
    bbaaef
    +        ctx->error = error;
    bbaaef
    +        return;
    bbaaef
    +    }
    bbaaef
    +
    bbaaef
    +    smap_init(&lrp_options);
    bbaaef
    +    smap_clone(&lrp_options, &lrp->options);
    bbaaef
    +
    bbaaef
    +    if (smap_get(&lrp_options, "redirect-type")) {
    bbaaef
    +        smap_replace(&lrp_options, "redirect-type", type);
    bbaaef
    +    } else {
    bbaaef
    +        smap_add(&lrp_options, "redirect-type", type);
    bbaaef
    +    }
    bbaaef
    +
    bbaaef
    +    nbrec_logical_router_port_set_options(lrp, &lrp_options);
    bbaaef
    +
    bbaaef
    +    smap_destroy(&lrp_options);
    bbaaef
    +}
    bbaaef
    +
    bbaaef
    +static void
    bbaaef
    +nbctl_lrp_get_redirect_type(struct ctl_context *ctx)
    bbaaef
    +{
    bbaaef
    +    const char *id = ctx->argv[1];
    bbaaef
    +    const struct nbrec_logical_router_port *lrp = NULL;
    bbaaef
    +
    bbaaef
    +    char *error = lrp_by_name_or_uuid(ctx, id, true, &lrp;;
    bbaaef
    +    if (error) {
    bbaaef
    +        ctx->error = error;
    bbaaef
    +        return;
    bbaaef
    +    }
    bbaaef
    +
    bbaaef
    +    const char *redirect_type = smap_get(&lrp->options, "redirect-type");
    bbaaef
    +    ds_put_format(&ctx->output, "%s\n",
    bbaaef
    +                  !redirect_type ? "overlay": redirect_type);
    bbaaef
    +}
    bbaaef
    +
    bbaaef
     struct ipv4_route {
    bbaaef
         int priority;
    bbaaef
         ovs_be32 addr;
    bbaaef
    @@ -5623,6 +5683,10 @@ static const struct ctl_command_syntax nbctl_commands[] = {
    bbaaef
           NULL, "", RW },
    bbaaef
         { "lrp-get-enabled", 1, 1, "PORT", NULL, nbctl_lrp_get_enabled,
    bbaaef
           NULL, "", RO },
    bbaaef
    +    { "lrp-set-redirect-type", 2, 2, "PORT TYPE", NULL,
    bbaaef
    +      nbctl_lrp_set_redirect_type, NULL, "", RW },
    bbaaef
    +    { "lrp-get-redirect-type", 1, 1, "PORT", NULL, nbctl_lrp_get_redirect_type,
    bbaaef
    +      NULL, "", RO },
    bbaaef
     
    bbaaef
         /* logical router route commands. */
    bbaaef
         { "lr-route-add", 3, 4, "ROUTER PREFIX NEXTHOP [PORT]", NULL,
    bbaaef
    diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at
    bbaaef
    index 30849682c..620b778b7 100644
    bbaaef
    --- a/tests/ovn-nbctl.at
    bbaaef
    +++ b/tests/ovn-nbctl.at
    bbaaef
    @@ -1243,6 +1243,31 @@ lrp0-chassis1     1
    bbaaef
     
    bbaaef
     dnl ---------------------------------------------------------------------
    bbaaef
     
    bbaaef
    +OVN_NBCTL_TEST([ovn_nbctl_redirect_type], [logical router port redirect type], [
    bbaaef
    +AT_CHECK([ovn-nbctl lr-add lr0])
    bbaaef
    +AT_CHECK([ovn-nbctl lrp-add lr0 lrp0 00:00:00:01:02:03 192.168.1.1/24])
    bbaaef
    +AT_CHECK([ovn-nbctl lrp-get-redirect-type lrp0], [0], [dnl
    bbaaef
    +overlay
    bbaaef
    +])
    bbaaef
    +AT_CHECK([ovn-nbctl lrp-set-redirect-type lp0 bridged], [1], [],
    bbaaef
    +[ovn-nbctl: lp0: port name not found
    bbaaef
    +])
    bbaaef
    +AT_CHECK([ovn-nbctl lrp-set-redirect-type lrp0 bridged], [0], [])
    bbaaef
    +AT_CHECK([ovn-nbctl lrp-get-redirect-type lrp0], [0], [dnl
    bbaaef
    +bridged
    bbaaef
    +])
    bbaaef
    +AT_CHECK([ovn-nbctl lrp-set-redirect-type lrp0 overlay], [0], [])
    bbaaef
    +AT_CHECK([ovn-nbctl lrp-get-redirect-type lrp0], [0], [dnl
    bbaaef
    +overlay
    bbaaef
    +])
    bbaaef
    +AT_CHECK([ovn-nbctl lrp-set-redirect-type lrp0 abcd], [1], [],
    bbaaef
    +[ovn-nbctl: Invalid redirect type: abcd
    bbaaef
    +])
    bbaaef
    +
    bbaaef
    +])
    bbaaef
    +
    bbaaef
    +dnl ---------------------------------------------------------------------
    bbaaef
    +
    bbaaef
     OVN_NBCTL_TEST([ovn_nbctl_lrp_enable], [logical router port enable and disable], [
    bbaaef
     AT_CHECK([ovn-nbctl lr-add lr0])
    bbaaef
     AT_CHECK([ovn-nbctl lrp-add lr0 lrp0 00:00:00:01:02:03 192.168.1.1/24])
    bbaaef
    diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
    bbaaef
    index 0dea04edc..42033d589 100644
    bbaaef
    --- a/tests/ovn-northd.at
    bbaaef
    +++ b/tests/ovn-northd.at
    bbaaef
    @@ -936,3 +936,33 @@ OVS_WAIT_UNTIL([
    bbaaef
         test 0 = $?])
    bbaaef
     
    bbaaef
     AT_CLEANUP
    bbaaef
    +
    bbaaef
    +AT_SETUP([ovn -- check Redirect Chassis propagation from NB to SB])
    bbaaef
    +AT_SKIP_IF([test $HAVE_PYTHON = no])
    bbaaef
    +ovn_start
    bbaaef
    +
    bbaaef
    +ovn-sbctl chassis-add gw1 geneve 127.0.0.1
    bbaaef
    +
    bbaaef
    +ovn-nbctl lr-add R1
    bbaaef
    +ovn-nbctl lrp-add R1 R1-S1 02:ac:10:01:00:01 172.16.1.1/24
    bbaaef
    +
    bbaaef
    +ovn-nbctl ls-add S1
    bbaaef
    +ovn-nbctl lsp-add S1 S1-R1
    bbaaef
    +ovn-nbctl lsp-set-type S1-R1 router
    bbaaef
    +ovn-nbctl lsp-set-addresses S1-R1 router
    bbaaef
    +ovn-nbctl --wait=sb lsp-set-options S1-R1 router-port=R1-S1
    bbaaef
    +
    bbaaef
    +ovn-nbctl lrp-set-gateway-chassis R1-S1 gw1
    bbaaef
    +
    bbaaef
    +uuid=`ovn-sbctl --columns=_uuid --bare find Port_Binding logical_port=cr-R1-S1`
    bbaaef
    +echo "CR-LRP UUID is: " $uuid
    bbaaef
    +
    bbaaef
    +ovn-nbctl lrp-set-redirect-type R1-S1 bridged
    bbaaef
    +OVS_WAIT_UNTIL([ovn-sbctl get Port_Binding ${uuid} options:redirect-type], [0], [bridged
    bbaaef
    +])
    bbaaef
    +
    bbaaef
    +ovn-nbctl lrp-set-redirect-type R1-S1 overlay
    bbaaef
    +OVS_WAIT_UNTIL([ovn-sbctl get Port_Binding ${uuid} options:redirect-type], [0], [overlay
    bbaaef
    +])
    bbaaef
    +
    bbaaef
    +AT_CLEANUP
    bbaaef
    -- 
    bbaaef
    2.23.0
    bbaaef