@@ -106,7 +106,7 @@ lflow_northd_handler(struct engine_node *node,
}
/* Fall back to recompute if lb related data has changed. */
- if (northd_data->lb_changed) {
+ if (northd_data->trk_northd_changes.lb_changed) {
return false;
}
@@ -116,9 +116,9 @@ lflow_northd_handler(struct engine_node *node,
struct lflow_input lflow_input;
lflow_get_input_data(node, &lflow_input);
- if (!lflow_handle_northd_ls_changes(eng_ctx->ovnsb_idl_txn,
- &northd_data->tracked_ls_changes,
- &lflow_input, lflow_data)) {
+ if (!lflow_handle_northd_changes(eng_ctx->ovnsb_idl_txn,
+ &northd_data->trk_northd_changes,
+ &lflow_input, lflow_data)) {
return false;
}
@@ -303,7 +303,7 @@ northd_lb_data_handler_post_od(struct engine_node *node, void *data)
/* Indicate the depedendant engine nodes that load balancer/group
* related data has changed (including association to logical
* switch/router). */
- nd->lb_changed = true;
+ nd->trk_northd_changes.lb_changed = true;
engine_set_node_state(node, EN_UPDATED);
return true;
}
@@ -4994,34 +4994,50 @@ build_ports(struct ovsdb_idl_txn *ovnsb_txn,
}
static void
-destroy_tracked_ls_change(struct ls_change *ls_change)
+destroy_tracked_ovn_ports(struct tracked_ovn_ports *trk_ovn_ports)
{
- struct ovn_port *op;
- LIST_FOR_EACH (op, list, &ls_change->added_ports) {
- ovs_list_remove(&op->list);
+ struct tracked_ovn_port *trk_op;
+ HMAP_FOR_EACH_POP (trk_op, hmap_node, &trk_ovn_ports->deleted) {
+ ovn_port_destroy_orphan(trk_op->op);
+ free(trk_op);
}
- LIST_FOR_EACH (op, list, &ls_change->updated_ports) {
- ovs_list_remove(&op->list);
+
+ HMAP_FOR_EACH_POP (trk_op, hmap_node, &trk_ovn_ports->created) {
+ free(trk_op);
}
- LIST_FOR_EACH_SAFE (op, list, &ls_change->deleted_ports) {
- ovs_list_remove(&op->list);
- ovn_port_destroy_orphan(op);
+
+ HMAP_FOR_EACH_POP (trk_op, hmap_node, &trk_ovn_ports->updated) {
+ free(trk_op);
}
}
void
destroy_northd_data_tracked_changes(struct northd_data *nd)
{
- struct ls_change *ls_change;
- LIST_FOR_EACH_SAFE (ls_change, list_node,
- &nd->tracked_ls_changes.updated) {
- destroy_tracked_ls_change(ls_change);
- ovs_list_remove(&ls_change->list_node);
- free(ls_change);
- }
+ struct northd_tracked_data *trk_changes = &nd->trk_northd_changes;
+ destroy_tracked_ovn_ports(&trk_changes->trk_ovn_ports);
nd->change_tracked = false;
- nd->lb_changed = false;
+ trk_changes->lb_changed = false;
+}
+
+static void
+add_op_to_northd_tracked_ports(struct hmap *tracked_ovn_ports,
+ struct ovn_port *op)
+{
+ struct tracked_ovn_port *trk_op;
+ uint32_t hash = hash_string(op->key, 0);
+ HMAP_FOR_EACH_WITH_HASH (trk_op, hmap_node, hash, tracked_ovn_ports) {
+ if (!strcmp(trk_op->op->key, op->key)) {
+ break;
+ }
+ }
+
+ if (!trk_op) {
+ trk_op = xzalloc(sizeof *trk_op);
+ trk_op->op = op;
+ hmap_insert(tracked_ovn_ports, &trk_op->hmap_node, hash);
+ }
}
/* Check if a changed LSP can be handled incrementally within the I-P engine
@@ -5272,7 +5288,7 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn *ovnsb_idl_txn,
const struct northd_input *ni,
struct northd_data *nd,
struct ovn_datapath *od,
- struct ls_change *ls_change,
+ struct tracked_ovn_ports *trk_ports,
bool *updated)
{
bool ls_ports_changed = false;
@@ -5333,8 +5349,7 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn *ovnsb_idl_txn,
if (!op) {
goto fail;
}
- ovs_list_push_back(&ls_change->added_ports,
- &op->list);
+ add_op_to_northd_tracked_ports(&trk_ports->created, op);
} else if (ls_port_has_changed(op->nbsp, new_nbsp)) {
/* Existing port updated */
bool temp = false;
@@ -5365,7 +5380,8 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn *ovnsb_idl_txn,
ni->sbrec_chassis_by_hostname)) {
goto fail;
}
- ovs_list_push_back(&ls_change->updated_ports, &op->list);
+
+ add_op_to_northd_tracked_ports(&trk_ports->updated, op);
}
op->visited = true;
}
@@ -5374,20 +5390,19 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn *ovnsb_idl_txn,
HMAP_FOR_EACH_SAFE (op, dp_node, &od->ports) {
if (!op->visited) {
if (!op->lsp_can_be_inc_processed) {
- goto fail_clean_deleted;
+ goto fail;
}
if (sset_contains(&nd->svc_monitor_lsps, op->key)) {
/* This port was used for svc monitor, which may be
* impacted by this deletion. Fallback to recompute. */
- goto fail_clean_deleted;
+ goto fail;
}
- ovs_list_push_back(&ls_change->deleted_ports,
- &op->list);
+ add_op_to_northd_tracked_ports(&trk_ports->deleted, op);
hmap_remove(&nd->ls_ports, &op->key_node);
hmap_remove(&od->ports, &op->dp_node);
sbrec_port_binding_delete(op->sb);
delete_fdb_entry(ni->sbrec_fdb_by_dp_and_port, od->tunnel_key,
- op->tunnel_key);
+ op->tunnel_key);
}
}
@@ -5404,23 +5419,19 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn *ovnsb_idl_txn,
only_rports = (od->n_router_ports
&& (od->n_router_ports == hmap_count(&od->ports)));
if (only_rports) {
- goto fail_clean_deleted;
+ goto fail;
}
- if (!ovs_list_is_empty(&ls_change->added_ports) ||
- !ovs_list_is_empty(&ls_change->updated_ports) ||
- !ovs_list_is_empty(&ls_change->deleted_ports)) {
+ if (!hmap_is_empty(&trk_ports->created)
+ || !hmap_is_empty(&trk_ports->updated)
+ || !hmap_is_empty(&trk_ports->deleted)) {
*updated = true;
}
return true;
-fail_clean_deleted:
- LIST_FOR_EACH_POP (op, list, &ls_change->deleted_ports) {
- ovn_port_destroy_orphan(op);
- }
-
fail:
+ destroy_tracked_ovn_ports(trk_ports);
return false;
}
@@ -5438,8 +5449,8 @@ northd_handle_ls_changes(struct ovsdb_idl_txn *ovnsb_idl_txn,
struct northd_data *nd)
{
const struct nbrec_logical_switch *changed_ls;
- struct ls_change *ls_change = NULL;
+ struct northd_tracked_data *trk_nd_changes = &nd->trk_northd_changes;
NBREC_LOGICAL_SWITCH_TABLE_FOR_EACH_TRACKED (changed_ls,
ni->nbrec_logical_switch_table) {
if (nbrec_logical_switch_is_new(changed_ls) ||
@@ -5462,33 +5473,18 @@ northd_handle_ls_changes(struct ovsdb_idl_txn *ovnsb_idl_txn,
goto fail;
}
- ls_change = xzalloc(sizeof *ls_change);
- ls_change->od = od;
- ovs_list_init(&ls_change->added_ports);
- ovs_list_init(&ls_change->deleted_ports);
- ovs_list_init(&ls_change->updated_ports);
-
bool updated = false;
if (!ls_handle_lsp_changes(ovnsb_idl_txn, changed_ls,
- ni, nd, od, ls_change,
+ ni, nd, od, &trk_nd_changes->trk_ovn_ports,
&updated)) {
- destroy_tracked_ls_change(ls_change);
- free(ls_change);
goto fail;
}
if (updated) {
- ovs_list_push_back(&nd->tracked_ls_changes.updated,
- &ls_change->list_node);
- } else {
- free(ls_change);
+ nd->change_tracked = true;
}
}
- if (!ovs_list_is_empty(&nd->tracked_ls_changes.updated)) {
- nd->change_tracked = true;
- }
-
return true;
fail:
@@ -17918,104 +17914,107 @@ unlink_and_sync_lflows(struct ovsdb_idl_txn *sb_txn, struct ovn_datapath *od,
lflow_data, lflowdep_mgr);
}
-bool lflow_handle_northd_ls_changes(struct ovsdb_idl_txn *ovnsb_txn,
- struct tracked_ls_changes *ls_changes,
- struct lflow_input *lflow_input,
- struct lflow_data *lflow_data)
+bool lflow_handle_northd_changes(struct ovsdb_idl_txn *ovnsb_txn,
+ struct northd_tracked_data *trk_nd_changes,
+ struct lflow_input *lflow_input,
+ struct lflow_data *lflow_data)
{
- struct ls_change *ls_change;
+ struct tracked_ovn_ports *trk_ovn_ports = &trk_nd_changes->trk_ovn_ports;
+
+ struct tracked_ovn_port *trk_op;
+ HMAP_FOR_EACH (trk_op, hmap_node, &trk_ovn_ports->deleted) {
+ struct ovn_port *op = trk_op->op;
+
+ /* unlink old lflows. */
+ unlink_and_sync_lflows(ovnsb_txn, op->od, OBJDEP_TYPE_LPORT,
+ op->nbsp->name, lflow_input, lflow_data,
+ &op->lflow_dep_mgr);
+ objdep_mgr_clear(&op->lflow_dep_mgr);
+
+ /* No need to update SB multicast groups, thanks to weak
+ * references. */
+ }
+
+ HMAP_FOR_EACH (trk_op, hmap_node, &trk_ovn_ports->updated) {
+ struct ovn_port *op = trk_op->op;
+
+ /* unlink old lflows. */
+ unlink_lflows(op->od, OBJDEP_TYPE_LPORT, op->nbsp->name,
+ lflow_data, &op->lflow_dep_mgr);
+
+ /* Generate new lflows. */
+ struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds actions = DS_EMPTY_INITIALIZER;
+ build_lswitch_and_lrouter_iterate_by_lsp(op, lflow_input->ls_ports,
+ lflow_input->lr_ports,
+ lflow_input->meter_groups,
+ &match, &actions,
+ lflow_data);
+ ds_destroy(&match);
+ ds_destroy(&actions);
+
+ /* SB port_binding is not deleted, so don't update SB multicast
+ * groups. */
+
+ /* Sync the new flows to SB. */
+ sync_lflows_for_res(ovnsb_txn, OBJDEP_TYPE_LPORT, op->nbsp->name,
+ lflow_input, lflow_data, &op->lflow_dep_mgr);
+ }
+
+ HMAP_FOR_EACH (trk_op, hmap_node, &trk_ovn_ports->created) {
+ struct ovn_port *op = trk_op->op;
- LIST_FOR_EACH (ls_change, list_node, &ls_changes->updated) {
const struct sbrec_multicast_group *sbmc_flood =
mcast_group_lookup(lflow_input->sbrec_mcast_group_by_name_dp,
- MC_FLOOD, ls_change->od->sb);
+ MC_FLOOD, op->od->sb);
const struct sbrec_multicast_group *sbmc_flood_l2 =
mcast_group_lookup(lflow_input->sbrec_mcast_group_by_name_dp,
- MC_FLOOD_L2, ls_change->od->sb);
+ MC_FLOOD_L2, op->od->sb);
const struct sbrec_multicast_group *sbmc_unknown =
mcast_group_lookup(lflow_input->sbrec_mcast_group_by_name_dp,
- MC_UNKNOWN, ls_change->od->sb);
-
- struct ovn_port *op;
- LIST_FOR_EACH (op, list, &ls_change->deleted_ports) {
- /* unlink old lflows. */
- unlink_and_sync_lflows(ovnsb_txn, op->od, OBJDEP_TYPE_LPORT,
- op->nbsp->name, lflow_input, lflow_data,
- &op->lflow_dep_mgr);
- objdep_mgr_clear(&op->lflow_dep_mgr);
-
- /* No need to update SB multicast groups, thanks to weak
- * references. */
- }
-
- LIST_FOR_EACH (op, list, &ls_change->updated_ports) {
- /* unlink old lflows. */
- unlink_lflows(op->od, OBJDEP_TYPE_LPORT, op->nbsp->name,
- lflow_data, &op->lflow_dep_mgr);
-
- /* Generate new lflows. */
- struct ds match = DS_EMPTY_INITIALIZER;
- struct ds actions = DS_EMPTY_INITIALIZER;
- build_lswitch_and_lrouter_iterate_by_lsp(op, lflow_input->ls_ports,
- lflow_input->lr_ports,
- lflow_input->meter_groups,
- &match, &actions,
- lflow_data);
- ds_destroy(&match);
- ds_destroy(&actions);
-
- /* SB port_binding is not deleted, so don't update SB multicast
- * groups. */
-
- /* Sync the new flows to SB. */
- sync_lflows_for_res(ovnsb_txn, OBJDEP_TYPE_LPORT,
- op->nbsp->name, lflow_input,
- lflow_data, &op->lflow_dep_mgr);
- }
-
- LIST_FOR_EACH (op, list, &ls_change->added_ports) {
- struct ds match = DS_EMPTY_INITIALIZER;
- struct ds actions = DS_EMPTY_INITIALIZER;
- build_lswitch_and_lrouter_iterate_by_lsp(op, lflow_input->ls_ports,
- lflow_input->lr_ports,
- lflow_input->meter_groups,
- &match, &actions,
- lflow_data);
- ds_destroy(&match);
- ds_destroy(&actions);
-
- /* Update SB multicast groups for the new port. */
- if (!sbmc_flood) {
- sbmc_flood = create_sb_multicast_group(ovnsb_txn,
- ls_change->od->sb, MC_FLOOD, OVN_MCAST_FLOOD_TUNNEL_KEY);
+ MC_UNKNOWN, op->od->sb);
+
+ struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds actions = DS_EMPTY_INITIALIZER;
+ build_lswitch_and_lrouter_iterate_by_lsp(op, lflow_input->ls_ports,
+ lflow_input->lr_ports,
+ lflow_input->meter_groups,
+ &match, &actions,
+ lflow_data);
+ ds_destroy(&match);
+ ds_destroy(&actions);
+
+ /* Update SB multicast groups for the new port. */
+ if (!sbmc_flood) {
+ sbmc_flood = create_sb_multicast_group(ovnsb_txn,
+ op->od->sb, MC_FLOOD, OVN_MCAST_FLOOD_TUNNEL_KEY);
+ }
+ sbrec_multicast_group_update_ports_addvalue(sbmc_flood, op->sb);
+
+ if (!sbmc_flood_l2) {
+ sbmc_flood_l2 = create_sb_multicast_group(ovnsb_txn,
+ op->od->sb, MC_FLOOD_L2,
+ OVN_MCAST_FLOOD_L2_TUNNEL_KEY);
+ }
+ sbrec_multicast_group_update_ports_addvalue(sbmc_flood_l2, op->sb);
+
+ if (op->has_unknown) {
+ if (!sbmc_unknown) {
+ sbmc_unknown = create_sb_multicast_group(ovnsb_txn,
+ op->od->sb, MC_UNKNOWN,
+ OVN_MCAST_UNKNOWN_TUNNEL_KEY);
}
- sbrec_multicast_group_update_ports_addvalue(sbmc_flood, op->sb);
-
- if (!sbmc_flood_l2) {
- sbmc_flood_l2 = create_sb_multicast_group(ovnsb_txn,
- ls_change->od->sb, MC_FLOOD_L2,
- OVN_MCAST_FLOOD_L2_TUNNEL_KEY);
- }
- sbrec_multicast_group_update_ports_addvalue(sbmc_flood_l2, op->sb);
-
- if (op->has_unknown) {
- if (!sbmc_unknown) {
- sbmc_unknown = create_sb_multicast_group(ovnsb_txn,
- ls_change->od->sb, MC_UNKNOWN,
- OVN_MCAST_UNKNOWN_TUNNEL_KEY);
- }
- sbrec_multicast_group_update_ports_addvalue(sbmc_unknown,
- op->sb);
- }
-
- /* Sync the newly added flows to SB. */
- sync_lflows_for_res(ovnsb_txn, OBJDEP_TYPE_LPORT,
- op->nbsp->name, lflow_input,
- lflow_data, &op->lflow_dep_mgr);
+ sbrec_multicast_group_update_ports_addvalue(sbmc_unknown,
+ op->sb);
}
+
+ /* Sync the newly added flows to SB. */
+ sync_lflows_for_res(ovnsb_txn, OBJDEP_TYPE_LPORT,
+ op->nbsp->name, lflow_input,
+ lflow_data, &op->lflow_dep_mgr);
}
- return true;
+ return true;
}
/* Each port group in Port_Group table in OVN_Northbound has a corresponding
@@ -18896,7 +18895,10 @@ northd_init(struct northd_data *data)
sset_init(&data->svc_monitor_lsps);
hmap_init(&data->svc_monitor_map);
data->change_tracked = false;
- ovs_list_init(&data->tracked_ls_changes.updated);
+
+ hmap_init(&data->trk_northd_changes.trk_ovn_ports.created);
+ hmap_init(&data->trk_northd_changes.trk_ovn_ports.updated);
+ hmap_init(&data->trk_northd_changes.trk_ovn_ports.deleted);
}
void
@@ -18949,6 +18951,10 @@ northd_destroy(struct northd_data *data)
destroy_debug_config();
sset_destroy(&data->svc_monitor_lsps);
+
+ hmap_destroy(&data->trk_northd_changes.trk_ovn_ports.created);
+ hmap_destroy(&data->trk_northd_changes.trk_ovn_ports.updated);
+ hmap_destroy(&data->trk_northd_changes.trk_ovn_ports.deleted);
}
void
@@ -19,6 +19,7 @@
#include "lib/ovn-sb-idl.h"
#include "lib/ovn-util.h"
#include "lib/ovs-atomic.h"
+#include "lib/hmapx.h"
#include "lib/objdep.h"
#include "lib/sset.h"
#include "northd/ipam.h"
@@ -87,21 +88,33 @@ struct ovn_datapaths {
struct ovn_datapath **array;
};
-/* Track what's changed for a single LS.
- * Now only track port changes. */
-struct ls_change {
- struct ovs_list list_node;
- struct ovn_datapath *od;
- struct ovs_list added_ports;
- struct ovs_list deleted_ports;
- struct ovs_list updated_ports;
+/* Represents a tracked ovn_port. */
+struct tracked_ovn_port {
+ struct hmap_node hmap_node;
+ struct ovn_port *op;
};
-/* Track what's changed for logical switches.
- * Now only track updated ones (added or deleted may be supported in the
- * future). */
-struct tracked_ls_changes {
- struct ovs_list updated; /* Contains struct ls_change */
+struct tracked_ovn_ports {
+ /* tracked created ports.
+ * hmap node data is 'struct tracked_ovn_port *' */
+ struct hmap created;
+
+ /* tracked updated ports.
+ * hmap node data is 'struct tracked_ovn_port *' */
+ struct hmap updated;
+
+ /* tracked deleted ports.
+ * hmap node data is 'struct tracked_ovn_port *' */
+ struct hmap deleted;
+};
+
+/* Track what's changed in the northd engine node.
+ * Now only tracks ovn_ports (of vif type) - created, updated
+ * and deleted and indicates if load balancers have changed. */
+struct northd_tracked_data {
+ struct tracked_ovn_ports trk_ovn_ports;
+ bool lb_changed; /* Indicates if load balancers changed or association of
+ * load balancer to logical switch/router changed. */
};
struct northd_data {
@@ -120,9 +133,7 @@ struct northd_data {
struct sset svc_monitor_lsps;
struct hmap svc_monitor_map;
bool change_tracked;
- struct tracked_ls_changes tracked_ls_changes;
- bool lb_changed; /* Indicates if load balancers changed or association of
- * load balancer to logical switch/router changed. */
+ struct northd_tracked_data trk_northd_changes;
};
struct lflow_data {
@@ -352,9 +363,9 @@ void northd_indices_create(struct northd_data *data,
void build_lflows(struct ovsdb_idl_txn *ovnsb_txn,
struct lflow_input *input_data,
struct lflow_data *lflow_data);
-bool lflow_handle_northd_ls_changes(struct ovsdb_idl_txn *ovnsb_txn,
- struct tracked_ls_changes *,
- struct lflow_input *, struct lflow_data *);
+bool lflow_handle_northd_changes(struct ovsdb_idl_txn *ovnsb_txn,
+ struct northd_tracked_data *,
+ struct lflow_input *, struct lflow_data *);
bool northd_handle_sb_port_binding_changes(
const struct sbrec_port_binding_table *, struct hmap *ls_ports);