Hi Ryan,
> On Apr 13, 2016, at 6:38 AM, Ryan Moats <[email protected]> wrote:
>
> As a side effect, tunnel context is persisted.
>
> Signed-off-by: Ryan Moats <[email protected]>
> ---
> ovn/controller/encaps.c | 162 ++++++++++++++++++++++++++++------------
> ovn/controller/ovn-controller.c | 5 ++
> 2 files changed, 120 insertions(+), 47 deletions(-)
>
> diff --git a/ovn/controller/encaps.c b/ovn/controller/encaps.c
> index dfb11c0..4c2bb84 100644
> --- a/ovn/controller/encaps.c
> +++ b/ovn/controller/encaps.c
> @@ -15,6 +15,7 @@
>
> #include <config.h>
> #include "encaps.h"
> +#include "lflow.h"
>
> #include "lib/hash.h"
> #include "lib/sset.h"
> @@ -49,6 +50,7 @@ struct tunnel_ctx {
> * generated we remove them. After generating all the rows, any
> * remaining in 'tunnel_hmap' must be deleted from the database. */
> struct hmap tunnel_hmap;
> + struct hmap tunnel_hmap_by_uuid;
>
> /* Names of all ports in the bridge, to allow checking uniqueness when
> * adding a new tunnel. */
> @@ -58,8 +60,18 @@ struct tunnel_ctx {
> const struct ovsrec_bridge *br_int;
> };
>
> +struct tunnel_ctx tc = {
> + .tunnel_hmap = HMAP_INITIALIZER(&tc.tunnel_hmap),
> + .tunnel_hmap_by_uuid = HMAP_INITIALIZER(&tc.tunnel_hmap_by_uuid),
> + .port_names = SSET_INITIALIZER(&tc.port_names),
> +};
> +
> +bool process_full_encaps = false;
> +
> struct port_hash_node {
> struct hmap_node node;
> + struct hmap_node uuid_node;
> + const struct uuid *uuid;
> const struct ovsrec_port *port;
> const struct ovsrec_bridge *bridge;
> };
> @@ -92,7 +104,7 @@ port_hash_rec(const struct ovsrec_port *port)
> }
>
> static char *
> -tunnel_create_name(struct tunnel_ctx *tc, const char *chassis_id)
> +tunnel_create_name(const char *chassis_id)
> {
> int i;
>
> @@ -100,7 +112,7 @@ tunnel_create_name(struct tunnel_ctx *tc, const char
> *chassis_id)
> char *port_name;
> port_name = xasprintf("ovn-%.6s-%x", chassis_id, i);
>
> - if (!sset_contains(&tc->port_names, port_name)) {
> + if (!sset_contains(&tc.port_names, port_name)) {
> return port_name;
> }
>
> @@ -110,19 +122,32 @@ tunnel_create_name(struct tunnel_ctx *tc, const char
> *chassis_id)
> return NULL;
> }
>
> +static struct port_hash_node *
> +port_lookup_by_uuid(const struct uuid *uuid)
> +{
> + struct hmap_node *node = hmap_first_with_hash(&tc.tunnel_hmap_by_uuid,
> + uuid_hash(uuid));
> + if (node) {
> + return CONTAINER_OF(node, struct port_hash_node, uuid_node);
> + }
> + return NULL;
> +}
>
> static void
> -tunnel_add(struct tunnel_ctx *tc, const char *new_chassis_id,
> +tunnel_add(const struct sbrec_chassis *chassis_rec,
> const struct sbrec_encap *encap)
> {
> struct port_hash_node *hash_node;
> + const char *new_chassis_id = chassis_rec->name;
> +
> + /* Check whether such a row already exists in OVS. If so, update
> + * the uuid field and insert into the by uuid hashmap. If not,
> + * create the tunnel */
>
> - /* Check whether such a row already exists in OVS. If so, remove it
> - * from 'tc->tunnel_hmap' and we're done. */
> HMAP_FOR_EACH_WITH_HASH (hash_node, node,
> port_hash(new_chassis_id,
> encap->type, encap->ip),
> - &tc->tunnel_hmap) {
> + &tc.tunnel_hmap) {
> const struct ovsrec_port *port = hash_node->port;
> const char *chassis_id = smap_get(&port->external_ids,
> "ovn-chassis-id");
> @@ -142,8 +167,12 @@ tunnel_add(struct tunnel_ctx *tc, const char
> *new_chassis_id,
> if (!strcmp(new_chassis_id, chassis_id)
> && !strcmp(encap->type, iface->type)
> && !strcmp(encap->ip, ip)) {
> - hmap_remove(&tc->tunnel_hmap, &hash_node->node);
> - free(hash_node);
> +
> + hash_node->uuid = &chassis_rec->header_.uuid;
> + if (!port_lookup_by_uuid(hash_node->uuid)) {
> + hmap_insert(&tc.tunnel_hmap_by_uuid, &hash_node->uuid_node,
> + uuid_hash(hash_node->uuid));
> + }
> return;
> }
> }
> @@ -155,14 +184,14 @@ tunnel_add(struct tunnel_ctx *tc, const char
> *new_chassis_id,
> char *port_name;
> size_t i;
>
> - port_name = tunnel_create_name(tc, new_chassis_id);
> + port_name = tunnel_create_name(new_chassis_id);
> if (!port_name) {
> VLOG_WARN("Unable to allocate unique name for '%s' tunnel",
> new_chassis_id);
> return;
> }
>
> - iface = ovsrec_interface_insert(tc->ovs_txn);
> + iface = ovsrec_interface_insert(tc.ovs_txn);
> ovsrec_interface_set_name(iface, port_name);
> ovsrec_interface_set_type(iface, encap->type);
> smap_add(&options, "remote_ip", encap->ip);
> @@ -170,23 +199,25 @@ tunnel_add(struct tunnel_ctx *tc, const char
> *new_chassis_id,
> ovsrec_interface_set_options(iface, &options);
> smap_destroy(&options);
>
> - port = ovsrec_port_insert(tc->ovs_txn);
> + port = ovsrec_port_insert(tc.ovs_txn);
> ovsrec_port_set_name(port, port_name);
> ovsrec_port_set_interfaces(port, &iface, 1);
> const struct smap id = SMAP_CONST1(&id, "ovn-chassis-id", new_chassis_id);
> ovsrec_port_set_external_ids(port, &id);
>
> - ports = xmalloc(sizeof *tc->br_int->ports * (tc->br_int->n_ports + 1));
> - for (i = 0; i < tc->br_int->n_ports; i++) {
> - ports[i] = tc->br_int->ports[i];
> + ports = xmalloc(sizeof *tc.br_int->ports * (tc.br_int->n_ports + 1));
> + for (i = 0; i < tc.br_int->n_ports; i++) {
> + ports[i] = tc.br_int->ports[i];
> }
> - ports[tc->br_int->n_ports] = port;
> - ovsrec_bridge_verify_ports(tc->br_int);
> - ovsrec_bridge_set_ports(tc->br_int, ports, tc->br_int->n_ports + 1);
> + ports[tc.br_int->n_ports] = port;
> + ovsrec_bridge_verify_ports(tc.br_int);
> + ovsrec_bridge_set_ports(tc.br_int, ports, tc.br_int->n_ports + 1);
>
> - sset_add(&tc->port_names, port_name);
> + sset_add(&tc.port_names, port_name);
> free(port_name);
> free(ports);
> + // reset_flow_processing();
> + process_full_encaps = true;
> }
>
> static void
> @@ -224,6 +255,24 @@ preferred_encap(const struct sbrec_chassis *chassis_rec)
> return best_encap;
> }
>
> +<<<<<<< HEAD
> +=======
Some conflict?
> +static void
> +check_and_add_tunnel(const struct sbrec_chassis *chassis_rec,
> + const char *chassis_id)
> +{
> + if (strcmp(chassis_rec->name, chassis_id)) {
> + /* Create tunnels to the other chassis. */
> + const struct sbrec_encap *encap = preferred_encap(chassis_rec);
> + if (!encap) {
> + VLOG_INFO("No supported encaps for '%s'", chassis_rec->name);
> + return;
> + }
> + tunnel_add(chassis_rec, encap);
> + }
> +}
> +
> +>>>>>>> Change encaps_run to work incrementally
> void
> encaps_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
> const char *chassis_id)
> @@ -235,12 +284,7 @@ encaps_run(struct controller_ctx *ctx, const struct
> ovsrec_bridge *br_int,
> const struct sbrec_chassis *chassis_rec;
> const struct ovsrec_bridge *br;
>
> - struct tunnel_ctx tc = {
> - .tunnel_hmap = HMAP_INITIALIZER(&tc.tunnel_hmap),
> - .port_names = SSET_INITIALIZER(&tc.port_names),
> - .br_int = br_int
> - };
> -
> + tc.br_int = br_int;
> tc.ovs_txn = ctx->ovs_idl_txn;
> ovsdb_idl_txn_add_comment(tc.ovs_txn,
> "ovn-controller: modifying OVS tunnels '%s'",
> @@ -257,37 +301,61 @@ encaps_run(struct controller_ctx *ctx, const struct
> ovsrec_bridge *br_int,
>
> sset_add(&tc.port_names, port->name);
>
> - if (smap_get(&port->external_ids, "ovn-chassis-id")) {
> - struct port_hash_node *hash_node = xzalloc(sizeof
> *hash_node);
> - hash_node->bridge = br;
> - hash_node->port = port;
> - hmap_insert(&tc.tunnel_hmap, &hash_node->node,
> - port_hash_rec(port));
> + const char *old_chassis_id = smap_get(&port->external_ids,
> + "ovn-chassis-id");
> + if (old_chassis_id) {
> + if (!hmap_first_with_hash(&tc.tunnel_hmap,
> + port_hash_rec(port))) {
> + struct port_hash_node *hash_node =
> + xzalloc(sizeof *hash_node);
> + hash_node->bridge = br;
> + hash_node->port = port;
> + hmap_insert(&tc.tunnel_hmap, &hash_node->node,
> + port_hash_rec(port));
> + process_full_encaps = true;
> + }
> }
> }
> }
>
> - SBREC_CHASSIS_FOR_EACH(chassis_rec, ctx->ovnsb_idl) {
> - if (strcmp(chassis_rec->name, chassis_id)) {
> - /* Create tunnels to the other chassis. */
> - const struct sbrec_encap *encap = preferred_encap(chassis_rec);
> - if (!encap) {
> - VLOG_INFO("No supported encaps for '%s'", chassis_rec->name);
> + if (process_full_encaps) {
> + SBREC_CHASSIS_FOR_EACH (chassis_rec, ctx->ovnsb_idl) {
> + check_and_add_tunnel(chassis_rec, chassis_id);
> + }
> + process_full_encaps = false;
> + } else {
> + SBREC_CHASSIS_FOR_EACH_TRACKED (chassis_rec, ctx->ovnsb_idl) {
> + bool is_deleted = sbrec_chassis_row_get_seqno(chassis_rec,
> + OVSDB_IDL_CHANGE_DELETE) > 0;
> + bool is_new = sbrec_chassis_row_get_seqno(chassis_rec,
> + OVSDB_IDL_CHANGE_MODIFY) == 0;
> +
> + if (is_deleted) {
> + /* lookup the tunnel by row uuid and remove it */
> + struct port_hash_node *port_hash =
> + port_lookup_by_uuid(&chassis_rec->header_.uuid);
> + if (port_hash) {
> + bridge_delete_port(port_hash->bridge, port_hash->port);
> + sset_find_and_delete(&tc.port_names,
> + port_hash->port->name);
> + hmap_remove(&tc.tunnel_hmap, &port_hash->node);
> + hmap_remove(&tc.tunnel_hmap_by_uuid,
> + &port_hash->uuid_node);
> + free(port_hash);
> + }
> continue;
> }
> - tunnel_add(&tc, chassis_rec->name, encap);
> + if (!is_new) {
> + if (strcmp(chassis_rec->name, chassis_id)) {
> + /* TODO: find the tunnel by looking it up based on its
> + * uuid and then change it. */
> + ;
> + }
> + } else {
> + check_and_add_tunnel(chassis_rec, chassis_id);
> + }
> }
> }
> -
> - /* Delete any existing OVN tunnels that were not still around. */
> - struct port_hash_node *hash_node, *next_hash_node;
> - HMAP_FOR_EACH_SAFE (hash_node, next_hash_node, node, &tc.tunnel_hmap) {
> - hmap_remove(&tc.tunnel_hmap, &hash_node->node);
> - bridge_delete_port(hash_node->bridge, hash_node->port);
> - free(hash_node);
> - }
> - hmap_destroy(&tc.tunnel_hmap);
> - sset_destroy(&tc.port_names);
> }
>
> /* Returns true if the database is all cleaned up, false if more work is
> diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c
> index 7c68c9d..16731a4 100644
> --- a/ovn/controller/ovn-controller.c
> +++ b/ovn/controller/ovn-controller.c
> @@ -304,6 +304,10 @@ main(int argc, char *argv[])
> char *ovnsb_remote = get_ovnsb_remote(ovs_idl_loop.idl);
> struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(
> ovsdb_idl_create(ovnsb_remote, &sbrec_idl_class, true, true));
> +
> + /* track the southbound idl */
> + ovsdb_idl_track_add_all(ovnsb_idl_loop.idl);
> +
> ovsdb_idl_get_initial_snapshot(ovnsb_idl_loop.idl);
>
> int probe_interval = 0;
> @@ -398,6 +402,7 @@ main(int argc, char *argv[])
> }
> ovsdb_idl_loop_commit_and_wait(&ovnsb_idl_loop);
> ovsdb_idl_loop_commit_and_wait(&ovs_idl_loop);
> + ovsdb_idl_track_clear(ovnsb_idl_loop.idl);
> poll_block();
> if (should_service_stop()) {
> exiting = true;
> --
> 1.9.1
>
> _______________________________________________
> dev mailing list
> [email protected]
> http://openvswitch.org/mailman/listinfo/dev
Kei
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev