[ovs-dev] [PATCH v3] ovn-controller: Assign zone-id consistently
Ramu Ramamurthy
ramu.ramamurthy at gmail.com
Fri Feb 12 01:18:11 UTC 2016
Currently, ovn-controller does not record the
lport->zoneid map, and so, after ovn-controller restart,
zone-ids may get set inconsistently on lports, resulting
in possible hits to already established connections.
Set zone-id as an external-id of the interface record,
and recover the zone-id from that record
Reported-by: Russell Bryant <russell at ovn.org>
Reported-at: https://bugs.launchpad.net/networking-ovn/+bug/1538696
Signed-off-by: Ramu Ramamurthy <ramu.ramamurthy at us.ibm.com>
---
Changes v1 to v2
* add check for null br-int
Changes v2 to v3
* updates per code-review comments
ovn/controller/binding.c | 64 +++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 60 insertions(+), 4 deletions(-)
diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c
index cb12cea..4aecffe 100644
--- a/ovn/controller/binding.c
+++ b/ovn/controller/binding.c
@@ -50,7 +50,8 @@ binding_register_ovs_idl(struct ovsdb_idl *ovs_idl)
}
static void
-get_local_iface_ids(const struct ovsrec_bridge *br_int, struct shash *lports)
+get_local_iface_ids(const struct ovsrec_bridge *br_int, struct shash *lports,
+ struct simap *ct_zones, unsigned long *ct_zone_bitmap)
{
int i;
@@ -65,6 +66,8 @@ get_local_iface_ids(const struct ovsrec_bridge *br_int, struct shash *lports)
for (j = 0; j < port_rec->n_interfaces; j++) {
const struct ovsrec_interface *iface_rec;
+ const char *zone;
+ int zone_id;
iface_rec = port_rec->interfaces[j];
iface_id = smap_get(&iface_rec->external_ids, "iface-id");
@@ -72,13 +75,65 @@ get_local_iface_ids(const struct ovsrec_bridge *br_int, struct shash *lports)
continue;
}
shash_add(lports, iface_id, iface_rec);
+ zone = smap_get(&iface_rec->external_ids, "ovn-zone-id");
+ if (zone && ovs_scan(zone, "%d", &zone_id)) {
+ bitmap_set1(ct_zone_bitmap, zone_id);
+ simap_put(ct_zones, iface_id, zone_id);
+ }
+ }
+ }
+}
+
+static void
+update_local_zone_ids(const struct ovsrec_bridge *br_int, struct simap *ct_zones,
+ struct controller_ctx *ctx)
+{
+ int i;
+
+ if (!ctx->ovs_idl_txn || !br_int) {
+ return;
+ }
+
+ for (i = 0; i < br_int->n_ports; i++) {
+ const struct ovsrec_port *port_rec = br_int->ports[i];
+ int j;
+
+ if (!strcmp(port_rec->name, br_int->name)) {
+ continue;
+ }
+
+ for (j = 0; j < port_rec->n_interfaces; j++) {
+ const struct ovsrec_interface *iface_rec;
+ const char *iface_id;
+ struct smap new;
+ int zone_id;
+ char zone[12];
+
+ iface_rec = port_rec->interfaces[j];
+ iface_id = smap_get(&iface_rec->external_ids, "iface-id");
+
+ if (!iface_id ||
+ smap_get(&iface_rec->external_ids, "ovn-zone-id") ||
+ !simap_contains(ct_zones, iface_id)) {
+ continue;
+ }
+
+ zone_id = simap_get(ct_zones, iface_id);
+ snprintf(zone, sizeof zone, "%d", zone_id);
+ smap_clone(&new, &iface_rec->external_ids);
+ smap_replace(&new, "ovn-zone-id", zone);
+ ovsrec_interface_verify_external_ids(iface_rec);
+ ovsrec_interface_set_external_ids(iface_rec, &new);
+ smap_destroy(&new);
}
}
}
static void
update_ct_zones(struct sset *lports, struct simap *ct_zones,
- unsigned long *ct_zone_bitmap)
+ unsigned long *ct_zone_bitmap,
+ const struct ovsrec_bridge *br_int,
+ struct controller_ctx *ctx)
{
struct simap_node *ct_zone, *ct_zone_next;
const char *iface_id;
@@ -119,6 +174,7 @@ update_ct_zones(struct sset *lports, struct simap *ct_zones,
* xxx zone, but we need a generic interface to the conntrack
* xxx table. */
}
+ update_local_zone_ids(br_int, ct_zones, ctx);
}
static void
@@ -165,7 +221,7 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
struct shash lports = SHASH_INITIALIZER(&lports);
if (br_int) {
- get_local_iface_ids(br_int, &lports);
+ get_local_iface_ids(br_int, &lports, ct_zones, ct_zone_bitmap);
} else {
/* We have no integration bridge, therefore no local logical ports.
* We'll remove our chassis from all port binding records below. */
@@ -224,7 +280,7 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
VLOG_DBG("No port binding record for lport %s", node->name);
}
- update_ct_zones(&all_lports, ct_zones, ct_zone_bitmap);
+ update_ct_zones(&all_lports, ct_zones, ct_zone_bitmap, br_int, ctx);
shash_destroy(&lports);
sset_destroy(&all_lports);
--
2.3.9
More information about the dev
mailing list