From: RYAN D. MOATS <rmo...@us.ibm.com> Persisting these entries is a pre-requisite for incremental processing.
Signed-off-by: RYAN D. MOATS <rmo...@us.ibm.com> --- ovn/controller/lport.c | 135 ++++++++++++++++++++++++++++++++++---- ovn/controller/lport.h | 20 +++++- ovn/controller/ovn-controller.c | 14 ++-- 3 files changed, 146 insertions(+), 23 deletions(-) diff --git a/ovn/controller/lport.c b/ovn/controller/lport.c index e1ecf21..b0fa433 100644 --- a/ovn/controller/lport.c +++ b/ovn/controller/lport.c @@ -24,23 +24,51 @@ VLOG_DEFINE_THIS_MODULE(lport); /* A logical port. */ struct lport { - struct hmap_node name_node; /* Index by name. */ - struct hmap_node key_node; /* Index by (dp_key, port_key). */ + struct hmap_node name_node; /* Index by name. */ + struct hmap_node key_node; /* Index by (dp_key, port_key). */ + struct hmap_node uuid_node; /* Index by row uuid. */ + const struct uuid *uuid; const struct sbrec_port_binding *pb; }; void -lport_index_init(struct lport_index *lports, struct ovsdb_idl *ovnsb_idl) +lport_index_init(struct lport_index *lports) { hmap_init(&lports->by_name); hmap_init(&lports->by_key); + hmap_init(&lports->by_uuid); +} + +void +lport_index_remove(struct lport_index *lports, const struct uuid *uuid) +{ + const struct lport *port = lport_lookup_by_uuid(lports, uuid); + if (port) { + hmap_remove(&lports->by_name, &port->name_node); + hmap_remove(&lports->by_key, &port->key_node); + hmap_remove(&lports->by_uuid, &port->uuid_node); + free(port); + } +} +void +lport_index_fill(struct lport_index *lports, struct ovsdb_idl *ovnsb_idl) +{ const struct sbrec_port_binding *pb; - SBREC_PORT_BINDING_FOR_EACH (pb, ovnsb_idl) { + SBREC_PORT_BINDING_FOR_EACH_TRACKED (pb, ovnsb_idl) { + unsigned int del_seqno = sbrec_port_binding_row_get_seqno(pb, + OVSDB_IDL_CHANGE_DELETE); + + /* if the row has a del_seqno > 0, then trying to process the + * row isn't going to work (as it has already been freed). + * What we can do is pass the row uuid to lport_index_remove() + * to remove the port. */ + if (del_seqno > 0) { + lport_index_remove(lports, &pb->header_.uuid); + continue; + } + if (lport_lookup_by_name(lports, pb->logical_port)) { - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); - VLOG_WARN_RL(&rl, "duplicate logical port name '%s'", - pb->logical_port); continue; } @@ -49,24 +77,36 @@ lport_index_init(struct lport_index *lports, struct ovsdb_idl *ovnsb_idl) hash_string(pb->logical_port, 0)); hmap_insert(&lports->by_key, &p->key_node, hash_int(pb->tunnel_key, pb->datapath->tunnel_key)); + hmap_insert(&lports->by_uuid, &p->uuid_node, + uuid_hash(&pb->header_.uuid)); + p->uuid = &pb->header_.uuid; p->pb = pb; } } void -lport_index_destroy(struct lport_index *lports) +lport_index_clear(struct lport_index *lports) { /* Destroy all of the "struct lport"s. * - * We don't have to remove the node from both indexes. */ + * We have to remove the node from all indexes. */ struct lport *port, *next; HMAP_FOR_EACH_SAFE (port, next, name_node, &lports->by_name) { hmap_remove(&lports->by_name, &port->name_node); + hmap_remove(&lports->by_key, &port->key_node); + hmap_remove(&lports->by_uuid, &port->uuid_node); free(port); } +} + +void +lport_index_destroy(struct lport_index *lports) +{ + lport_index_clear(lports); hmap_destroy(&lports->by_name); hmap_destroy(&lports->by_key); + hmap_destroy(&lports->by_uuid); } /* Finds and returns the lport with the given 'name', or NULL if no such lport @@ -84,6 +124,20 @@ lport_lookup_by_name(const struct lport_index *lports, const char *name) return NULL; } +const struct lport * +lport_lookup_by_uuid(const struct lport_index *lports, + const struct uuid *uuid) +{ + const struct lport *lport; + HMAP_FOR_EACH_WITH_HASH (lport, uuid_node, uuid_hash(uuid), + &lports->by_uuid) { + if (uuid_equals(uuid, lport->uuid)) { + return lport; + } + } + return NULL; +} + const struct sbrec_port_binding * lport_lookup_by_key(const struct lport_index *lports, uint32_t dp_key, uint16_t port_key) @@ -101,43 +155,94 @@ lport_lookup_by_key(const struct lport_index *lports, struct mcgroup { struct hmap_node dp_name_node; /* Index by (logical datapath, name). */ + struct hmap_node uuid_node; /* Index by insert uuid. */ + const struct uuid *uuid; const struct sbrec_multicast_group *mg; }; void -mcgroup_index_init(struct mcgroup_index *mcgroups, struct ovsdb_idl *ovnsb_idl) +mcgroup_index_init(struct mcgroup_index *mcgroups) { hmap_init(&mcgroups->by_dp_name); + hmap_init(&mcgroups->by_uuid); +} + +void +mcgroup_index_remove(struct mcgroup_index *mcgroups, const struct uuid *uuid) +{ + const struct mcgroup *mcgroup = mcgroup_lookup_by_uuid(mcgroups, uuid); + if (mcgroup) { + hmap_remove(&mcgroups->by_dp_name, &mcgroup->dp_name_node); + hmap_remove(&mcgroups->by_uuid, &mcgroup->uuid_node); + free(mcgroup); + } +} +void +mcgroup_index_fill(struct mcgroup_index *mcgroups, struct ovsdb_idl *ovnsb_idl) +{ const struct sbrec_multicast_group *mg; - SBREC_MULTICAST_GROUP_FOR_EACH (mg, ovnsb_idl) { + SBREC_MULTICAST_GROUP_FOR_EACH_TRACKED (mg, ovnsb_idl) { + unsigned int del_seqno = sbrec_multicast_group_row_get_seqno(mg, + OVSDB_IDL_CHANGE_DELETE); + + /* if the row has a del_seqno > 0, then trying to process the + * row isn't going to work (as it has already been freed). + * What we can do is pass the row uuid to mcgroup_index_remove() + * to remove the port. */ + if (del_seqno > 0) { + mcgroup_index_remove(mcgroups, &mg->header_.uuid); + continue; + } + const struct uuid *dp_uuid = &mg->datapath->header_.uuid; if (mcgroup_lookup_by_dp_name(mcgroups, mg->datapath, mg->name)) { - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); - VLOG_WARN_RL(&rl, "datapath "UUID_FMT" contains duplicate " - "multicast group '%s'", UUID_ARGS(dp_uuid), mg->name); continue; } struct mcgroup *m = xmalloc(sizeof *m); hmap_insert(&mcgroups->by_dp_name, &m->dp_name_node, hash_string(mg->name, uuid_hash(dp_uuid))); + hmap_insert(&mcgroups->by_uuid, &m->uuid_node, + uuid_hash(&mg->header_.uuid)); + m->uuid = &mg->header_.uuid; m->mg = mg; } } void -mcgroup_index_destroy(struct mcgroup_index *mcgroups) +mcgroup_index_clear(struct mcgroup_index *mcgroups) { struct mcgroup *mcgroup, *next; HMAP_FOR_EACH_SAFE (mcgroup, next, dp_name_node, &mcgroups->by_dp_name) { hmap_remove(&mcgroups->by_dp_name, &mcgroup->dp_name_node); + hmap_remove(&mcgroups->by_uuid, &mcgroup->uuid_node); free(mcgroup); } +} + +void +mcgroup_index_destroy(struct mcgroup_index *mcgroups) +{ + mcgroup_index_clear(mcgroups); hmap_destroy(&mcgroups->by_dp_name); } +const struct mcgroup * +mcgroup_lookup_by_uuid(const struct mcgroup_index *mcgroups, + const struct uuid *uuid) +{ + const struct mcgroup *mcgroup; + HMAP_FOR_EACH_WITH_HASH (mcgroup, uuid_node, uuid_hash(uuid), + &mcgroups->by_uuid) { + if (uuid_equals(mcgroup->uuid, uuid)) { + return mcgroup; + } + } + return NULL; +} + const struct sbrec_multicast_group * mcgroup_lookup_by_dp_name(const struct mcgroup_index *mcgroups, const struct sbrec_datapath_binding *dp, diff --git a/ovn/controller/lport.h b/ovn/controller/lport.h index f09e2eb..350325a 100644 --- a/ovn/controller/lport.h +++ b/ovn/controller/lport.h @@ -18,6 +18,7 @@ #include <stdint.h> #include "hmap.h" +#include "uuid.h" struct ovsdb_idl; struct sbrec_datapath_binding; @@ -32,15 +33,23 @@ struct sbrec_datapath_binding; struct lport_index { struct hmap by_name; struct hmap by_key; + struct hmap by_uuid; }; -void lport_index_init(struct lport_index *, struct ovsdb_idl *); +void lport_index_init(struct lport_index *); +void lport_index_fill(struct lport_index *, struct ovsdb_idl *); +void lport_index_remove(struct lport_index *, const struct uuid *); +void lport_index_clear(struct lport_index *); void lport_index_destroy(struct lport_index *); const struct sbrec_port_binding *lport_lookup_by_name( const struct lport_index *, const char *name); const struct sbrec_port_binding *lport_lookup_by_key( const struct lport_index *, uint32_t dp_key, uint16_t port_key); + +const struct lport *lport_lookup_by_uuid( + const struct lport_index *, const struct uuid *uuid); + /* Multicast group index * ===================== @@ -54,9 +63,13 @@ const struct sbrec_port_binding *lport_lookup_by_key( struct mcgroup_index { struct hmap by_dp_name; + struct hmap by_uuid; }; -void mcgroup_index_init(struct mcgroup_index *, struct ovsdb_idl *); +void mcgroup_index_init(struct mcgroup_index *); +void mcgroup_index_fill(struct mcgroup_index *, struct ovsdb_idl *); +void mcgroup_index_remove(struct mcgroup_index *, const struct uuid *); +void mcgroup_index_clear(struct mcgroup_index *); void mcgroup_index_destroy(struct mcgroup_index *); const struct sbrec_multicast_group *mcgroup_lookup_by_dp_name( @@ -64,4 +77,7 @@ const struct sbrec_multicast_group *mcgroup_lookup_by_dp_name( const struct sbrec_datapath_binding *, const char *name); +const struct mcgroup *mcgroup_lookup_by_uuid( + const struct mcgroup_index *, const struct uuid *uuid); + #endif /* ovn/lport.h */ diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index c7cbd50..6edc04c 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -198,6 +198,9 @@ get_ovnsb_remote(struct ovsdb_idl *ovs_idl) } } +struct lport_index lports; +struct mcgroup_index mcgroups; + int main(int argc, char *argv[]) { @@ -228,6 +231,9 @@ main(int argc, char *argv[]) pinctrl_init(); lflow_init(); + lport_index_init(&lports); + mcgroup_index_init(&mcgroups); + /* Connect to OVS OVSDB instance. We do not monitor all tables by * default, so modules must register their interest explicitly. */ struct ovsdb_idl_loop ovs_idl_loop = OVSDB_IDL_LOOP_INITIALIZER( @@ -299,10 +305,8 @@ main(int argc, char *argv[]) if (br_int) { patch_run(&ctx, br_int, &local_datapaths); - struct lport_index lports; - struct mcgroup_index mcgroups; - lport_index_init(&lports, ctx.ovnsb_idl); - mcgroup_index_init(&mcgroups, ctx.ovnsb_idl); + lport_index_fill(&lports, ctx.ovnsb_idl); + mcgroup_index_fill(&mcgroups, ctx.ovnsb_idl); enum mf_field_id mff_ovn_geneve = ofctrl_run(br_int); @@ -316,8 +320,6 @@ main(int argc, char *argv[]) &local_datapaths); } ofctrl_put(); - mcgroup_index_destroy(&mcgroups); - lport_index_destroy(&lports); } struct local_datapath *cur_node, *next_node; -- 1.7.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev