diff mbox

[ovs-dev,4/5] ovn-controller: Assign conntrack zones for gateway router.

Message ID 1462935081-18291-4-git-send-email-guru@ovn.org
State Not Applicable
Headers show

Commit Message

Gurucharan Shetty May 11, 2016, 2:51 a.m. UTC
OVS NAT currently cannot do snat and dnat in the same zone.
So we need two zones per gateway router.

Signed-off-by: Gurucharan Shetty <guru@ovn.org>
---
No v1. Newly added as part of v2.
---
 ovn/controller/ovn-controller.c |   50 +++++++++++++++++++++++++++++----------
 ovn/controller/ovn-controller.h |    2 ++
 ovn/controller/patch.c          |    6 +++--
 ovn/controller/physical.c       |   25 ++++++++++++++++++++
 ovn/lib/logical-fields.h        |   11 +++++----
 5 files changed, 76 insertions(+), 18 deletions(-)
diff mbox

Patch

diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c
index adca938..fc9a804 100644
--- a/ovn/controller/ovn-controller.c
+++ b/ovn/controller/ovn-controller.c
@@ -254,29 +254,54 @@  get_ovnsb_remote_probe_interval(struct ovsdb_idl *ovs_idl, int *value)
 }
 
 static void
-update_ct_zones(struct sset *lports, struct simap *ct_zones,
-                unsigned long *ct_zone_bitmap)
+update_ct_zones(struct sset *lports, struct hmap *patched_datapaths,
+                struct simap *ct_zones, unsigned long *ct_zone_bitmap)
 {
     struct simap_node *ct_zone, *ct_zone_next;
-    const char *iface_id;
     int scan_start = 1;
+    struct patched_datapath *pd;
+    const char *user;
+    struct sset all_users = SSET_INITIALIZER(&all_users);
 
-    /* xxx This is wasteful to assign a zone to each port--even if no
-     * xxx security policy is applied. */
+    SSET_FOR_EACH(user, lports) {
+        sset_add(&all_users, user);
+    }
+
+    /* Local patched datapath (gateway routers) need zones assigned. */
+    HMAP_FOR_EACH(pd, hmap_node, patched_datapaths) {
+        if (!pd->local) {
+            continue;
+        }
 
-    /* Delete any zones that are associated with removed ports. */
+        char *dnat = xasprintf(UUID_FMT"_%s",
+                        UUID_ARGS(&pd->port_binding->datapath->header_.uuid),
+                        "dnat");
+        char *snat = xasprintf(UUID_FMT"_%s",
+                       UUID_ARGS(&pd->port_binding->datapath->header_.uuid),
+                       "snat");
+        sset_add(&all_users, dnat);
+        sset_add(&all_users, snat);
+        free(dnat);
+        free(snat);
+    }
+
+    /* Delete zones that do not exist in above sset. */
     SIMAP_FOR_EACH_SAFE(ct_zone, ct_zone_next, ct_zones) {
-        if (!sset_contains(lports, ct_zone->name)) {
+        if (!sset_contains(&all_users, ct_zone->name)) {
             bitmap_set0(ct_zone_bitmap, ct_zone->data);
             simap_delete(ct_zones, ct_zone);
         }
     }
 
-    /* Assign a unique zone id for each logical port. */
-    SSET_FOR_EACH(iface_id, lports) {
+    /* xxx This is wasteful to assign a zone to each port--even if no
+     * xxx security policy is applied. */
+
+    /* Assign a unique zone id for each logical port and two zones
+     * to a gateway router. */
+    SSET_FOR_EACH(user, &all_users) {
         size_t zone;
 
-        if (simap_contains(ct_zones, iface_id)) {
+        if (simap_contains(ct_zones, user)) {
             continue;
         }
 
@@ -290,7 +315,7 @@  update_ct_zones(struct sset *lports, struct simap *ct_zones,
         scan_start = zone + 1;
 
         bitmap_set1(ct_zone_bitmap, zone);
-        simap_put(ct_zones, iface_id, zone);
+        simap_put(ct_zones, user, zone);
 
         /* xxx We should erase any old entries for this
          * xxx zone, but we need a generic interface to the conntrack
@@ -422,7 +447,8 @@  main(int argc, char *argv[])
             enum mf_field_id mff_ovn_geneve = ofctrl_run(br_int);
 
             pinctrl_run(&ctx, &lports, br_int);
-            update_ct_zones(&all_lports, &ct_zones, ct_zone_bitmap);
+            update_ct_zones(&all_lports, &patched_datapaths, &ct_zones,
+                            ct_zone_bitmap);
 
             struct hmap flow_table = HMAP_INITIALIZER(&flow_table);
             lflow_run(&ctx, &lports, &mcgroups, &local_datapaths,
diff --git a/ovn/controller/ovn-controller.h b/ovn/controller/ovn-controller.h
index 9af7959..ba50a98 100644
--- a/ovn/controller/ovn-controller.h
+++ b/ovn/controller/ovn-controller.h
@@ -48,6 +48,8 @@  struct local_datapath *get_local_datapath(const struct hmap *,
  * with at least one logical patch port binding. */
 struct patched_datapath {
     struct hmap_node hmap_node;
+    bool local; /* 'True' if the datapath is for gateway router. */
+    const struct sbrec_port_binding *port_binding;
 };
 
 struct patched_datapath *get_patched_datapath(const struct hmap *,
diff --git a/ovn/controller/patch.c b/ovn/controller/patch.c
index a88f7aa..33df362 100644
--- a/ovn/controller/patch.c
+++ b/ovn/controller/patch.c
@@ -230,7 +230,7 @@  add_bridge_mappings(struct controller_ctx *ctx,
 
 static void
 add_patched_datapath(struct hmap *patched_datapaths,
-                     const struct sbrec_port_binding *binding_rec)
+                     const struct sbrec_port_binding *binding_rec, bool local)
 {
     if (get_patched_datapath(patched_datapaths,
                              binding_rec->datapath->tunnel_key)) {
@@ -238,6 +238,8 @@  add_patched_datapath(struct hmap *patched_datapaths,
     }
 
     struct patched_datapath *pd = xzalloc(sizeof *pd);
+    pd->local = local;
+    pd->port_binding = binding_rec;
     hmap_insert(patched_datapaths, &pd->hmap_node,
                 binding_rec->datapath->tunnel_key);
 }
@@ -302,7 +304,7 @@  add_logical_patch_ports(struct controller_ctx *ctx,
                               existing_ports);
             free(dst_name);
             free(src_name);
-            add_patched_datapath(patched_datapaths, binding);
+            add_patched_datapath(patched_datapaths, binding, local_port);
             if (local_port) {
                 if (binding->chassis != chassis_rec) {
                     sbrec_port_binding_set_chassis(binding, chassis_rec);
diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c
index 576c695..b6e752c 100644
--- a/ovn/controller/physical.c
+++ b/ovn/controller/physical.c
@@ -367,6 +367,25 @@  physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
                 put_load(zone_id, MFF_LOG_CT_ZONE, 0, 32, &ofpacts);
             }
 
+            int zone_id_dnat, zone_id_snat;
+            char *dnat = xasprintf(UUID_FMT"_%s",
+                                   UUID_ARGS(&binding->datapath->header_.uuid),
+                                   "dnat");
+            char *snat = xasprintf(UUID_FMT"_%s",
+                                   UUID_ARGS(&binding->datapath->header_.uuid),
+                                   "snat");
+            zone_id_dnat = simap_get(ct_zones, dnat);
+            if (zone_id_dnat) {
+                put_load(zone_id_dnat, MFF_LOG_DNAT_ZONE, 0, 32, &ofpacts);
+            }
+            free(dnat);
+
+            zone_id_snat = simap_get(ct_zones, snat);
+            if (zone_id_snat) {
+                put_load(zone_id_snat, MFF_LOG_SNAT_ZONE, 0, 32, &ofpacts);
+            }
+            free(snat);
+
             /* Set MFF_LOG_DATAPATH and MFF_LOG_INPORT. */
             put_load(dp_key, MFF_LOG_DATAPATH, 0, 64, &ofpacts);
             put_load(port_key, MFF_LOG_INPORT, 0, 32, &ofpacts);
@@ -403,6 +422,12 @@  physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
             if (zone_id) {
                 put_load(zone_id, MFF_LOG_CT_ZONE, 0, 32, &ofpacts);
             }
+            if (zone_id_dnat) {
+                put_load(zone_id_dnat, MFF_LOG_DNAT_ZONE, 0, 32, &ofpacts);
+            }
+            if (zone_id_snat) {
+                put_load(zone_id_snat, MFF_LOG_SNAT_ZONE, 0, 32, &ofpacts);
+            }
 
             /* Resubmit to table 34. */
             put_resubmit(OFTABLE_DROP_LOOPBACK, &ofpacts);
diff --git a/ovn/lib/logical-fields.h b/ovn/lib/logical-fields.h
index 59f1cee..f0f97a9 100644
--- a/ovn/lib/logical-fields.h
+++ b/ovn/lib/logical-fields.h
@@ -23,7 +23,12 @@ 
  * These values are documented in ovn-architecture(7), please update the
  * documentation if you change any of them. */
 #define MFF_LOG_DATAPATH MFF_METADATA /* Logical datapath (64 bits). */
-#define MFF_LOG_CT_ZONE  MFF_REG5     /* Logical conntrack zone (32 bits). */
+#define MFF_LOG_DNAT_ZONE  MFF_REG3   /* conntrack dnat zone for gateway router
+                                       * (32 bits). */
+#define MFF_LOG_SNAT_ZONE  MFF_REG4   /* conntrack snat zone for gateway router
+                                       * (32 bits). */
+#define MFF_LOG_CT_ZONE  MFF_REG5     /* Logical conntrack zone for lports
+                                       * (32 bits). */
 #define MFF_LOG_INPORT   MFF_REG6     /* Logical input port (32 bits). */
 #define MFF_LOG_OUTPORT  MFF_REG7     /* Logical output port (32 bits). */
 
@@ -33,8 +38,6 @@ 
 #define MFF_LOG_REGS \
     MFF_LOG_REG(MFF_REG0) \
     MFF_LOG_REG(MFF_REG1) \
-    MFF_LOG_REG(MFF_REG2) \
-    MFF_LOG_REG(MFF_REG3) \
-    MFF_LOG_REG(MFF_REG4)
+    MFF_LOG_REG(MFF_REG2)
 
 #endif /* ovn/lib/logical-fields.h */