@@ -50,6 +50,10 @@ struct tunnel_ctx {
* adding a new tunnel. */
struct sset port_names;
+ /* IP,type of all tunnel ports in bridge, to allow checking uniqueness
+ * when adding a new tunnel. */
+ struct sset tunnel_type_ips;
+
struct ovsdb_idl_txn *ovs_txn;
const struct ovsrec_bridge *br_int;
};
@@ -78,6 +82,19 @@ tunnel_create_name(struct tunnel_ctx *tc, const char *chassis_id)
return NULL;
}
+static char*
+create_tunnel_type_ip_key(struct tunnel_ctx *tc, const char *type,
+ const char *ip)
+{
+ char *tunnel_type_ip = xasprintf("%s-%s", type, ip);
+ if (!sset_contains(&tc->tunnel_type_ips, tunnel_type_ip)) {
+ return tunnel_type_ip;
+ }
+
+ free(tunnel_type_ip);
+ return NULL;
+}
+
static void
tunnel_add(struct tunnel_ctx *tc, const char *new_chassis_id,
const struct sbrec_encap *encap)
@@ -116,6 +133,15 @@ tunnel_add(struct tunnel_ctx *tc, const char *new_chassis_id,
goto exit;
}
+ char *tunnel_type_ip = create_tunnel_type_ip_key(tc, encap->type,
+ encap->ip);
+ if (!tunnel_type_ip) {
+ VLOG_WARN("Unable to allocate unique remote_ip for '%s' %s tunnel",
+ encap->type, new_chassis_id);
+ free(port_name);
+ goto exit;
+ }
+
struct ovsrec_interface *iface = ovsrec_interface_insert(tc->ovs_txn);
ovsrec_interface_set_name(iface, port_name);
ovsrec_interface_set_type(iface, encap->type);
@@ -130,6 +156,7 @@ tunnel_add(struct tunnel_ctx *tc, const char *new_chassis_id,
ovsrec_bridge_update_ports_addvalue(tc->br_int, port);
sset_add_and_free(&tc->port_names, port_name);
+ sset_add_and_free(&tc->tunnel_type_ips, tunnel_type_ip);
exit:
smap_destroy(&options);
@@ -166,6 +193,7 @@ encaps_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
struct tunnel_ctx tc = {
.chassis = SHASH_INITIALIZER(&tc.chassis),
.port_names = SSET_INITIALIZER(&tc.port_names),
+ .tunnel_type_ips = SSET_INITIALIZER(&tc.tunnel_type_ips),
.br_int = br_int
};
@@ -194,6 +222,24 @@ encaps_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
* to delete this one. */
ovsrec_bridge_update_ports_delvalue(br, port);
}
+ for (size_t i = 0; i< port->n_interfaces; i++) {
+ const struct ovsrec_interface *iface = port->interfaces[i];
+ if (strcmp(iface->type, "geneve")
+ && strcmp(iface->type, "stt")
+ && strcmp(iface->type, "vxlan")) {
+ continue;
+ }
+ const char *if_remote_ip = smap_get(&iface->options,
+ "remote_ip");
+ char *tunnel_type_ip;
+ tunnel_type_ip = create_tunnel_type_ip_key(&tc,
+ iface->type,
+ if_remote_ip);
+ if (!tunnel_type_ip) {
+ continue;
+ }
+ sset_add_and_free(&tc.tunnel_type_ips, tunnel_type_ip);
+ }
}
}
}
1. ovs cannot create two ports with same tunnel type and options:remote_ip 2. add santity check to detect if two chassises have same encap ip 3. add a sset to store tunnel ports' type & encap ip information Signed-off-by: Zhenyu Gao <sysugaozhenyu@gmail.com> --- ovn/controller/encaps.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)