#include "binding.h"
#include "lib/bitmap.h"
+#include "lib/hmap.h"
#include "lib/sset.h"
#include "lib/util.h"
#include "lib/vswitch-idl.h"
}
}
+static void
+add_local_datapath(struct hmap *local_datapaths,
+ const struct sbrec_port_binding *binding_rec)
+{
+ struct hmap_node *ld;
+ ld = hmap_first_with_hash(local_datapaths,
+ binding_rec->datapath->tunnel_key);
+ if (!ld) {
+ ld = xmalloc(sizeof *ld);
+ hmap_insert(local_datapaths, ld,
+ binding_rec->datapath->tunnel_key);
+ }
+}
+
void
binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
const char *chassis_id, struct simap *ct_zones,
- unsigned long *ct_zone_bitmap)
+ unsigned long *ct_zone_bitmap, struct hmap *local_datapaths)
{
const struct sbrec_chassis *chassis_rec;
const struct sbrec_port_binding *binding_rec;
/* Add child logical port to the set of all local ports. */
sset_add(&all_lports, binding_rec->logical_port);
}
+ add_local_datapath(local_datapaths, binding_rec);
if (binding_rec->chassis == chassis_rec) {
continue;
}
#include <stdbool.h>
struct controller_ctx;
+struct hmap;
struct ovsdb_idl;
struct ovsrec_bridge;
struct simap;
void binding_register_ovs_idl(struct ovsdb_idl *);
void binding_run(struct controller_ctx *, const struct ovsrec_bridge *br_int,
const char *chassis_id, struct simap *ct_zones,
- unsigned long *ct_zone_bitmap);
+ unsigned long *ct_zone_bitmap, struct hmap *local_datapaths);
bool binding_cleanup(struct controller_ctx *, const char *chassis_id);
#endif /* ovn/binding.h */
#include "ovn/lib/ovn-sb-idl.h"
#include "poll-loop.h"
#include "fatal-signal.h"
+#include "lib/hmap.h"
#include "lib/vswitch-idl.h"
#include "smap.h"
#include "stream.h"
.ovnsb_idl_txn = ovsdb_idl_loop_run(&ovnsb_idl_loop),
};
+ /* Contains bare "struct hmap_node"s whose hash values are the tunnel_key
+ * of datapaths with at least one local port binding. */
+ struct hmap local_datapaths = HMAP_INITIALIZER(&local_datapaths);
+
const struct ovsrec_bridge *br_int = get_br_int(&ctx);
const char *chassis_id = get_chassis_id(ctx.ovs_idl);
if (chassis_id) {
chassis_run(&ctx, chassis_id);
encaps_run(&ctx, br_int, chassis_id);
- binding_run(&ctx, br_int, chassis_id, &ct_zones, ct_zone_bitmap);
+ binding_run(&ctx, br_int, chassis_id, &ct_zones, ct_zone_bitmap,
+ &local_datapaths);
}
if (br_int) {
lflow_run(&ctx, &flow_table, &ct_zones);
if (chassis_id) {
physical_run(&ctx, mff_ovn_geneve,
- br_int, chassis_id, &ct_zones, &flow_table);
+ br_int, chassis_id, &ct_zones, &flow_table,
+ &local_datapaths);
}
ofctrl_put(&flow_table);
hmap_destroy(&flow_table);
}
+ /* local_datapaths contains bare hmap_node instances.
+ * We use this wrapper so that we can make use of
+ * HMAP_FOR_EACH_SAFE to tear down the hmap. */
+ struct {
+ struct hmap_node node;
+ } *cur_node, *next_node;
+ HMAP_FOR_EACH_SAFE (cur_node, next_node, node, &local_datapaths) {
+ hmap_remove(&local_datapaths, &cur_node->node);
+ free(cur_node);
+ }
+ hmap_destroy(&local_datapaths);
+
unixctl_server_run(unixctl);
unixctl_server_wait(unixctl);
void
physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
const struct ovsrec_bridge *br_int, const char *this_chassis_id,
- const struct simap *ct_zones, struct hmap *flow_table)
+ const struct simap *ct_zones, struct hmap *flow_table,
+ struct hmap *local_datapaths)
{
struct simap localvif_to_ofport = SIMAP_INITIALIZER(&localvif_to_ofport);
struct hmap tunnels = HMAP_INITIALIZER(&tunnels);
/* Maps from network name to "struct localnet_bindings". */
struct shash localnet_inputs = SHASH_INITIALIZER(&localnet_inputs);
- /* Contains bare "struct hmap_node"s whose hash values are the tunnel_key
- * of datapaths with at least one local port binding. */
- struct hmap local_datapaths = HMAP_INITIALIZER(&local_datapaths);
-
/* Set up flows in table 0 for physical-to-logical translation and in table
* 64 for logical-to-physical translation. */
const struct sbrec_port_binding *binding;
b->binding = binding;
list_insert(&ln_vlan->bindings, &b->list_elem);
} else {
- struct hmap_node *ld;
- ld = hmap_first_with_hash(&local_datapaths,
- binding->datapath->tunnel_key);
- if (!ld) {
- ld = xmalloc(sizeof *ld);
- hmap_insert(&local_datapaths, ld,
- binding->datapath->tunnel_key);
- }
-
ofpbuf_clear(&ofpacts);
match_init_catchall(&match);
match_set_in_port(&match, ofport);
struct binding_elem *b;
LIST_FOR_EACH_POP (b, list_elem, &ln_vlan->bindings) {
struct hmap_node *ld;
- ld = hmap_first_with_hash(&local_datapaths,
+ ld = hmap_first_with_hash(local_datapaths,
b->binding->datapath->tunnel_key);
if (ld) {
/* Set MFF_LOG_DATAPATH and MFF_LOG_INPORT. */
}
shash_destroy(&localnet_inputs);
- struct hmap_node *node;
- while ((node = hmap_first(&local_datapaths))) {
- hmap_remove(&local_datapaths, node);
- free(node);
- }
- hmap_destroy(&local_datapaths);
-
simap_destroy(&localnet_to_ofport);
}
void physical_register_ovs_idl(struct ovsdb_idl *);
void physical_run(struct controller_ctx *, enum mf_field_id mff_ovn_geneve,
const struct ovsrec_bridge *br_int, const char *chassis_id,
- const struct simap *ct_zones, struct hmap *flow_table);
+ const struct simap *ct_zones, struct hmap *flow_table,
+ struct hmap *local_datapaths);
#endif /* ovn/physical.h */