diff mbox series

[ovs-dev,RFC,ovn,09/10] ovn-ic: Interconnection gateway controller.

Message ID 1569623665-77390-10-git-send-email-hzhou8@ebay.com
State RFC
Headers show
Series OVN Interconnection | expand

Commit Message

Han Zhou Sept. 27, 2019, 10:34 p.m. UTC
From: Han Zhou <hzhou8@ebay.com>

Sync local and remote gateways between SB and ISB.

Signed-off-by: Han Zhou <hzhou8@ebay.com>
---
 ic/ovn-ic.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)
diff mbox series

Patch

diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c
index 4de3e17..ddc9d0a 100644
--- a/ic/ovn-ic.c
+++ b/ic/ovn-ic.c
@@ -234,6 +234,99 @@  ts_run(struct ic_context *ctx)
 }
 
 static void
+gateway_run(struct ic_context *ctx, const struct isbrec_availability_zone *az)
+{
+    if (!ctx->ovnisb_txn || !ctx->ovnsb_txn) {
+        return;
+    }
+
+    struct shash local_gws = SHASH_INITIALIZER(&local_gws);
+    struct shash remote_gws = SHASH_INITIALIZER(&remote_gws);
+    const struct isbrec_gateway *gw;
+    ISBREC_GATEWAY_FOR_EACH (gw, ctx->ovnisb_idl) {
+        if (gw->availability_zone == az) {
+            shash_add(&local_gws, gw->name, gw);
+        } else {
+            shash_add(&remote_gws, gw->name, gw);
+        }
+    }
+
+    const struct sbrec_chassis *chassis;
+    SBREC_CHASSIS_FOR_EACH (chassis, ctx->ovnsb_idl) {
+        if (chassis->is_interconn) {
+            gw = shash_find_and_delete(&local_gws, chassis->name);
+            if (!gw) {
+                gw = isbrec_gateway_insert(ctx->ovnisb_txn);
+                isbrec_gateway_set_availability_zone(gw, az);
+                isbrec_gateway_set_name(gw, chassis->name);
+                isbrec_gateway_set_hostname(gw, chassis->hostname);
+
+                /* Sync encaps used by this chassis. */
+                ovs_assert(chassis->n_encaps);
+                struct isbrec_encap *isb_encap;
+                struct isbrec_encap **isb_encaps =
+                    xmalloc(chassis->n_encaps * sizeof *isb_encap);
+                for (int i = 0; i < chassis->n_encaps; i++) {
+                    isb_encap = isbrec_encap_insert(ctx->ovnisb_txn);
+                    isbrec_encap_set_gateway_name(isb_encap,
+                                                  chassis->name);
+                    isbrec_encap_set_ip(isb_encap, chassis->encaps[i]->ip);
+                    isbrec_encap_set_type(isb_encap,
+                                          chassis->encaps[i]->type);
+                    isbrec_encap_set_options(isb_encap,
+                                             &chassis->encaps[i]->options);
+                    isb_encaps[i] = isb_encap;
+                }
+                isbrec_gateway_set_encaps(gw, isb_encaps,
+                                          chassis->n_encaps);
+                free(isb_encaps);
+            } else {
+                /* XXX Update ISB gateway/encaps, if any changes. */
+            }
+        } else if (chassis->is_remote) {
+            gw = shash_find_and_delete(&remote_gws, chassis->name);
+            if (!gw) {
+                sbrec_chassis_delete(chassis);
+            } else {
+                /* XXX Update SB chassis/encaps, if any changes. */
+            }
+        }
+    }
+
+    /* Delete extra gateways from ISB for the local AZ */
+    struct shash_node *node;
+    SHASH_FOR_EACH (node, &local_gws) {
+        isbrec_gateway_delete(node->data);
+    }
+    shash_destroy(&local_gws);
+
+    /* Create SB chassis for remote gateways in ISB */
+    SHASH_FOR_EACH (node, &remote_gws) {
+        gw = node->data;
+        chassis = sbrec_chassis_insert(ctx->ovnsb_txn);
+        sbrec_chassis_set_name(chassis, gw->name);
+        sbrec_chassis_set_hostname(chassis, gw->hostname);
+        sbrec_chassis_set_is_remote(chassis, true);
+        /* Sync encaps used by this gateway. */
+        ovs_assert(gw->n_encaps);
+        struct sbrec_encap *sb_encap;
+        struct sbrec_encap **sb_encaps =
+            xmalloc(gw->n_encaps * sizeof *sb_encap);
+        for (int i = 0; i < gw->n_encaps; i++) {
+            sb_encap = sbrec_encap_insert(ctx->ovnsb_txn);
+            sbrec_encap_set_chassis_name(sb_encap, gw->name);
+            sbrec_encap_set_ip(sb_encap, gw->encaps[i]->ip);
+            sbrec_encap_set_type(sb_encap, gw->encaps[i]->type);
+            sbrec_encap_set_options(sb_encap, &gw->encaps[i]->options);
+            sb_encaps[i] = sb_encap;
+        }
+        sbrec_chassis_set_encaps(chassis, sb_encaps, gw->n_encaps);
+        free(sb_encaps);
+    }
+    shash_destroy(&remote_gws);
+}
+
+static void
 ovn_db_run(struct ic_context *ctx)
 {
     const struct isbrec_availability_zone *az = az_run(ctx);
@@ -244,6 +337,7 @@  ovn_db_run(struct ic_context *ctx)
     }
 
     ts_run(ctx);
+    gateway_run(ctx, az);
 }
 
 static void