@@ -1088,7 +1088,10 @@ ovn_lb_datapaths_add_ls(struct ovn_lb_datapaths *lb_dps, size_t n,
struct ovn_datapath **ods)
{
for (size_t i = 0; i < n; i++) {
- bitmap_set1(lb_dps->nb_ls_map, ods[i]->index);
+ if (!bitmap_is_set(lb_dps->nb_ls_map, ods[i]->index)) {
+ bitmap_set1(lb_dps->nb_ls_map, ods[i]->index);
+ lb_dps->n_nb_ls++;
+ }
}
}
@@ -39,6 +39,14 @@ static void lb_data_destroy(struct ed_type_lb_data *);
static void build_lbs(const struct nbrec_load_balancer_table *,
const struct nbrec_load_balancer_group_table *,
struct hmap *lbs, struct hmap *lb_groups);
+static void build_od_lb_map(const struct nbrec_logical_switch_table *,
+ struct hmap *od_lb_map);
+static struct od_lb_data *find_od_lb_data(struct hmap *od_lb_map,
+ const struct uuid *od_uuid);
+static void destroy_od_lb_data(struct od_lb_data *od_lb_data);
+static struct od_lb_data *create_od_lb_data(struct hmap *od_lb_map,
+ const struct uuid *od_uuid);
+
static struct ovn_lb_group *create_lb_group(
const struct nbrec_load_balancer_group *, struct hmap *lbs,
struct hmap *lb_groups);
@@ -54,6 +62,7 @@ static struct crupdated_lb_group *
struct tracked_lb_data *);
static void add_deleted_lb_group_to_tracked_data(
struct ovn_lb_group *, struct tracked_lb_data *);
+static bool is_ls_lbs_changed(const struct nbrec_logical_switch *nbs);
/* 'lb_data' engine node manages the NB load balancers and load balancer
* groups. For each NB LB, it creates 'struct ovn_northd_lb' and
@@ -80,9 +89,13 @@ en_lb_data_run(struct engine_node *node, void *data)
EN_OVSDB_GET(engine_get_input("NB_load_balancer", node));
const struct nbrec_load_balancer_group_table *nb_lbg_table =
EN_OVSDB_GET(engine_get_input("NB_load_balancer_group", node));
+ const struct nbrec_logical_switch_table *nb_ls_table =
+ EN_OVSDB_GET(engine_get_input("NB_logical_switch", node));
lb_data->tracked = false;
build_lbs(nb_lb_table, nb_lbg_table, &lb_data->lbs, &lb_data->lb_groups);
+ build_od_lb_map(nb_ls_table, &lb_data->ls_lb_map);
+
engine_set_node_state(node, EN_UPDATED);
}
@@ -230,18 +243,104 @@ lb_data_load_balancer_group_handler(struct engine_node *node, void *data)
return true;
}
+struct od_lb_data {
+ struct hmap_node hmap_node;
+ struct uuid od_uuid;
+ struct uuidset *lbs;
+ struct uuidset *lbgrps;
+};
+
+bool
+lb_data_logical_switch_handler(struct engine_node *node, void *data)
+{
+ struct ed_type_lb_data *lb_data = (struct ed_type_lb_data *) data;
+ const struct nbrec_logical_switch_table *nb_ls_table =
+ EN_OVSDB_GET(engine_get_input("NB_logical_switch", node));
+
+ struct tracked_lb_data *trk_lb_data = &lb_data->tracked_lb_data;
+ lb_data->tracked = true;
+
+ bool changed = false;
+ const struct nbrec_logical_switch *nbs;
+ NBREC_LOGICAL_SWITCH_TABLE_FOR_EACH_TRACKED (nbs, nb_ls_table) {
+ if (nbrec_logical_switch_is_deleted(nbs)) {
+ struct od_lb_data *od_lb_data =
+ find_od_lb_data(&lb_data->ls_lb_map, &nbs->header_.uuid);
+ if (od_lb_data) {
+ hmap_remove(&lb_data->ls_lb_map, &od_lb_data->hmap_node);
+ destroy_od_lb_data(od_lb_data);
+ }
+ } else {
+ if (!is_ls_lbs_changed(nbs)) {
+ continue;
+ }
+ struct crupdated_od_lb_data *codlb = xzalloc(sizeof *codlb);
+ codlb->od_uuid = nbs->header_.uuid;
+ uuidset_init(&codlb->assoc_lbs);
+
+ struct od_lb_data *od_lb_data =
+ find_od_lb_data(&lb_data->ls_lb_map, &nbs->header_.uuid);
+ if (!od_lb_data) {
+ od_lb_data = create_od_lb_data(&lb_data->ls_lb_map,
+ &nbs->header_.uuid);
+ }
+
+ struct uuidset *pre_lb_uuids = od_lb_data->lbs;
+ od_lb_data->lbs = xzalloc(sizeof *od_lb_data->lbs);
+ uuidset_init(od_lb_data->lbs);
+
+ for (size_t i = 0; i < nbs->n_load_balancer; i++) {
+ const struct uuid *lb_uuid =
+ &nbs->load_balancer[i]->header_.uuid;
+ uuidset_insert(od_lb_data->lbs, lb_uuid);
+
+ struct uuidset_node *unode = uuidset_find(pre_lb_uuids,
+ lb_uuid);
+
+ if (!unode || (nbrec_load_balancer_row_get_seqno(
+ nbs->load_balancer[i], OVSDB_IDL_CHANGE_MODIFY) > 0)) {
+ /* Add this lb to the tracked data. */
+ uuidset_insert(&codlb->assoc_lbs, lb_uuid);
+ changed = true;
+ }
+
+ if (unode) {
+ uuidset_delete(pre_lb_uuids, unode);
+ }
+ }
+
+ if (!uuidset_is_empty(pre_lb_uuids)) {
+ trk_lb_data->has_dissassoc_lbs_from_od = true;
+ changed = true;
+ }
+
+ uuidset_destroy(pre_lb_uuids);
+ free(pre_lb_uuids);
+
+ ovs_list_insert(&trk_lb_data->crupdated_ls_lbs, &codlb->list_node);
+ }
+ }
+
+ if (changed) {
+ engine_set_node_state(node, EN_UPDATED);
+ }
+ return true;
+}
+
/* static functions. */
static void
lb_data_init(struct ed_type_lb_data *lb_data)
{
hmap_init(&lb_data->lbs);
hmap_init(&lb_data->lb_groups);
+ hmap_init(&lb_data->ls_lb_map);
struct tracked_lb_data *trk_lb_data = &lb_data->tracked_lb_data;
hmap_init(&trk_lb_data->crupdated_lbs);
hmapx_init(&trk_lb_data->deleted_lbs);
hmap_init(&trk_lb_data->crupdated_lb_groups);
hmapx_init(&trk_lb_data->deleted_lb_groups);
+ ovs_list_init(&trk_lb_data->crupdated_ls_lbs);
}
static void
@@ -259,6 +358,12 @@ lb_data_destroy(struct ed_type_lb_data *lb_data)
}
hmap_destroy(&lb_data->lb_groups);
+ struct od_lb_data *od_lb_data;
+ HMAP_FOR_EACH_POP (od_lb_data, hmap_node, &lb_data->ls_lb_map) {
+ destroy_od_lb_data(od_lb_data);
+ }
+ hmap_destroy(&lb_data->ls_lb_map);
+
destroy_tracked_data(lb_data);
hmap_destroy(&lb_data->tracked_lb_data.crupdated_lbs);
hmapx_destroy(&lb_data->tracked_lb_data.deleted_lbs);
@@ -301,12 +406,67 @@ create_lb_group(const struct nbrec_load_balancer_group *nbrec_lb_group,
return lb_group;
}
+static void
+build_od_lb_map(const struct nbrec_logical_switch_table *nbrec_ls_table,
+ struct hmap *od_lb_map)
+{
+ const struct nbrec_logical_switch *nbrec_ls;
+ NBREC_LOGICAL_SWITCH_TABLE_FOR_EACH (nbrec_ls, nbrec_ls_table) {
+ if (!nbrec_ls->n_load_balancer) {
+ continue;
+ }
+
+ struct od_lb_data *od_lb_data =
+ create_od_lb_data(od_lb_map, &nbrec_ls->header_.uuid);
+ for (size_t i = 0; i < nbrec_ls->n_load_balancer; i++) {
+ uuidset_insert(od_lb_data->lbs,
+ &nbrec_ls->load_balancer[i]->header_.uuid);
+ }
+ }
+}
+
+static struct od_lb_data *
+create_od_lb_data(struct hmap *od_lb_map, const struct uuid *od_uuid)
+{
+ struct od_lb_data *od_lb_data = xzalloc(sizeof *od_lb_data);
+ od_lb_data->od_uuid = *od_uuid;
+ od_lb_data->lbs = xzalloc(sizeof *od_lb_data->lbs);
+ uuidset_init(od_lb_data->lbs);
+
+ hmap_insert(od_lb_map, &od_lb_data->hmap_node,
+ uuid_hash(&od_lb_data->od_uuid));
+ return od_lb_data;
+}
+
+static struct od_lb_data *
+find_od_lb_data(struct hmap *od_lb_map, const struct uuid *od_uuid)
+{
+ struct od_lb_data *od_lb_data;
+ HMAP_FOR_EACH_WITH_HASH (od_lb_data, hmap_node, uuid_hash(od_uuid),
+ od_lb_map) {
+ if (uuid_equals(&od_lb_data->od_uuid, od_uuid)) {
+ return od_lb_data;
+ }
+ }
+
+ return NULL;
+}
+
+static void
+destroy_od_lb_data(struct od_lb_data *od_lb_data)
+{
+ uuidset_destroy(od_lb_data->lbs);
+ free(od_lb_data->lbs);
+ free(od_lb_data);
+}
+
static void
destroy_tracked_data(struct ed_type_lb_data *lb_data)
{
lb_data->tracked = false;
lb_data->tracked_lb_data.has_health_checks = false;
lb_data->tracked_lb_data.has_dissassoc_lbs_from_lb_grops = false;
+ lb_data->tracked_lb_data.has_dissassoc_lbs_from_od = false;
struct hmapx_node *node;
HMAPX_FOR_EACH_SAFE (node, &lb_data->tracked_lb_data.deleted_lbs) {
@@ -331,6 +491,15 @@ destroy_tracked_data(struct ed_type_lb_data *lb_data)
hmapx_destroy(&crupdated_lbg->assoc_lbs);
free(crupdated_lbg);
}
+
+ struct crupdated_od_lb_data *codlb;
+ LIST_FOR_EACH_SAFE (codlb, list_node,
+ &lb_data->tracked_lb_data.crupdated_ls_lbs) {
+ ovs_list_remove(&codlb->list_node);
+ uuidset_destroy(&codlb->assoc_lbs);
+
+ free(codlb);
+ }
}
static void
@@ -376,3 +545,10 @@ add_deleted_lb_group_to_tracked_data(struct ovn_lb_group *lbg,
{
hmapx_add(&tracked_lb_data->deleted_lb_groups, lbg);
}
+
+static bool
+is_ls_lbs_changed(const struct nbrec_logical_switch *nbs) {
+ return ((nbrec_logical_switch_is_new(nbs) && nbs->n_load_balancer)
+ || nbrec_logical_switch_is_updated(nbs,
+ NBREC_LOGICAL_SWITCH_COL_LOAD_BALANCER));
+}
@@ -6,6 +6,7 @@
#include "openvswitch/hmap.h"
#include "include/openvswitch/list.h"
#include "lib/hmapx.h"
+#include "lib/uuidset.h"
#include "lib/inc-proc-eng.h"
@@ -27,6 +28,13 @@ struct crupdated_lb_group {
struct hmapx assoc_lbs;
};
+struct crupdated_od_lb_data {
+ struct ovs_list list_node;
+
+ struct uuid od_uuid;
+ struct uuidset assoc_lbs;
+};
+
struct tracked_lb_data {
/* Both created and updated lbs. hmapx node is 'struct crupdated_lb *'. */
struct hmap crupdated_lbs;
@@ -41,12 +49,19 @@ struct tracked_lb_data {
/* Deleted lb_groups. hmapx node is 'struct ovn_lb_group *'. */
struct hmapx deleted_lb_groups;
+ /* List of logical switch <-> lb changes. List node is
+ * 'struct crupdated_od_lb_data' */
+ struct ovs_list crupdated_ls_lbs;
+
/* Indicates if any of the tracked lb has health checks enabled. */
bool has_health_checks;
/* Indicates if any lb got disassociated from a lb group
* but not deleted. */
bool has_dissassoc_lbs_from_lb_grops;
+
+ /* Indicates if a lb was disassociated from a logical switch. */
+ bool has_dissassoc_lbs_from_od;
};
/* struct which maintains the data of the engine node lb_data. */
@@ -56,6 +71,7 @@ struct ed_type_lb_data {
/* hmap of load balancer groups. hmap node is 'struct ovn_lb_group *' */
struct hmap lb_groups;
+ struct hmap ls_lb_map;
/* tracked data*/
bool tracked;
@@ -69,5 +85,6 @@ void en_lb_data_clear_tracked_data(void *data);
bool lb_data_load_balancer_handler(struct engine_node *, void *data);
bool lb_data_load_balancer_group_handler(struct engine_node *, void *data);
+bool lb_data_logical_switch_handler(struct engine_node *, void *data);
#endif /* end of EN_NORTHD_LB_DATA_H */
@@ -102,6 +102,12 @@ lflow_northd_handler(struct engine_node *node,
if (!northd_data->change_tracked) {
return false;
}
+
+ /* Fall back to recompute if lb related data has changed. */
+ if (northd_data->lb_changed) {
+ return false;
+ }
+
const struct engine_context *eng_ctx = engine_get_context();
struct lflow_data *lflow_data = data;
@@ -207,7 +207,7 @@ northd_sb_port_binding_handler(struct engine_node *node,
}
bool
-northd_lb_data_handler(struct engine_node *node, void *data)
+northd_lb_data_handler_pre_od(struct engine_node *node, void *data)
{
struct ed_type_lb_data *lb_data = engine_get_input_data("lb_data", node);
@@ -230,19 +230,47 @@ northd_lb_data_handler(struct engine_node *node, void *data)
/* Fall back to recompute if load balancer groups are deleted. */
if (!hmapx_is_empty(&lb_data->tracked_lb_data.deleted_lb_groups)) {
+ }
+
+ if (lb_data->tracked_lb_data.has_dissassoc_lbs_from_od) {
return false;
}
struct northd_data *nd = data;
- if (!northd_handle_lb_data_changes(&lb_data->tracked_lb_data,
- &nd->ls_datapaths,
- &nd->lr_datapaths,
- &nd->lb_datapaths_map,
- &nd->lb_group_datapaths_map)) {
+ if (!northd_handle_lb_data_changes_pre_od(&lb_data->tracked_lb_data,
+ &nd->ls_datapaths,
+ &nd->lr_datapaths,
+ &nd->lb_datapaths_map,
+ &nd->lb_group_datapaths_map)) {
+ return false;
+ }
+
+ engine_set_node_state(node, EN_UPDATED);
+ return true;
+}
+
+bool
+northd_lb_data_handler_post_od(struct engine_node *node, void *data)
+{
+ struct ed_type_lb_data *lb_data =
+ engine_get_input_data("lb_data", node);
+
+ ovs_assert(lb_data->tracked);
+ ovs_assert(!lb_data->tracked_lb_data.has_dissassoc_lbs_from_od);
+
+ struct northd_data *nd = data;
+
+ if (!northd_handle_lb_data_changes_post_od(&lb_data->tracked_lb_data,
+ &nd->ls_datapaths,
+ &nd->lb_datapaths_map)) {
return false;
}
+ /* Indicate the depedendant engine nodes that load balancer/group
+ * related data has changed (including association to logical
+ * switch/router). */
+ nd->lb_changed = true;
engine_set_node_state(node, EN_UPDATED);
return true;
}
@@ -17,6 +17,7 @@ void en_northd_clear_tracked_data(void *data);
bool northd_nb_nb_global_handler(struct engine_node *, void *data OVS_UNUSED);
bool northd_nb_logical_switch_handler(struct engine_node *, void *data);
bool northd_sb_port_binding_handler(struct engine_node *, void *data);
-bool northd_lb_data_handler(struct engine_node *, void *data);
+bool northd_lb_data_handler_pre_od(struct engine_node *, void *data);
+bool northd_lb_data_handler_post_od(struct engine_node *, void *data);
#endif /* EN_NORTHD_H */
@@ -152,6 +152,8 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
lb_data_load_balancer_handler);
engine_add_input(&en_lb_data, &en_nb_load_balancer_group,
lb_data_load_balancer_group_handler);
+ engine_add_input(&en_lb_data, &en_nb_logical_switch,
+ lb_data_logical_switch_handler);
engine_add_input(&en_northd, &en_nb_port_group, NULL);
engine_add_input(&en_northd, &en_nb_acl, NULL);
@@ -180,9 +182,10 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
northd_sb_port_binding_handler);
engine_add_input(&en_northd, &en_nb_nb_global,
northd_nb_nb_global_handler);
- engine_add_input(&en_northd, &en_lb_data, northd_lb_data_handler);
+ engine_add_input(&en_northd, &en_lb_data, northd_lb_data_handler_pre_od);
engine_add_input(&en_northd, &en_nb_logical_switch,
northd_nb_logical_switch_handler);
+ engine_add_input(&en_northd, &en_lb_data, northd_lb_data_handler_post_od);
engine_add_input(&en_mac_binding_aging, &en_nb_nb_global, NULL);
engine_add_input(&en_mac_binding_aging, &en_sb_mac_binding, NULL);
@@ -853,7 +853,6 @@ ovn_datapath_destroy(struct hmap *datapaths, struct ovn_datapath *od)
ovn_ls_port_group_destroy(&od->nb_pgs);
destroy_mcast_info_for_datapath(od);
destroy_ports_for_datapath(od);
-
free(od);
}
}
@@ -4919,6 +4918,7 @@ destroy_northd_data_tracked_changes(struct northd_data *nd)
}
nd->change_tracked = false;
+ nd->lb_changed = false;
}
/* Check if a changed LSP can be handled incrementally within the I-P engine
@@ -5034,6 +5034,7 @@ ls_port_create(struct ovsdb_idl_txn *ovnsb_txn, struct hmap *ls_ports,
* incrementally handled.
* Presently supports i-p for the below changes:
* - logical switch ports.
+ * - load balancers.
*/
static bool
ls_changes_can_be_handled(
@@ -5042,8 +5043,11 @@ ls_changes_can_be_handled(
/* Check if the columns are changed in this row. */
enum nbrec_logical_switch_column_id col;
for (col = 0; col < NBREC_LOGICAL_SWITCH_N_COLUMNS; col++) {
- if (nbrec_logical_switch_is_updated(ls, col) &&
- col != NBREC_LOGICAL_SWITCH_COL_PORTS) {
+ if (nbrec_logical_switch_is_updated(ls, col)) {
+ if (col == NBREC_LOGICAL_SWITCH_COL_PORTS ||
+ col == NBREC_LOGICAL_SWITCH_COL_LOAD_BALANCER) {
+ continue;
+ }
return false;
}
}
@@ -5072,12 +5076,6 @@ ls_changes_can_be_handled(
return false;
}
}
- for (size_t i = 0; i < ls->n_load_balancer; i++) {
- if (nbrec_load_balancer_row_get_seqno(ls->load_balancer[i],
- OVSDB_IDL_CHANGE_MODIFY) > 0) {
- return false;
- }
- }
for (size_t i = 0; i < ls->n_load_balancer_group; i++) {
if (nbrec_load_balancer_group_row_get_seqno(ls->load_balancer_group[i],
OVSDB_IDL_CHANGE_MODIFY) > 0) {
@@ -5139,7 +5137,9 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn *ovnsb_idl_txn,
const struct nbrec_logical_switch *changed_ls,
const struct northd_input *ni,
struct northd_data *nd,
- struct ovn_datapath *od)
+ struct ovn_datapath *od,
+ struct ls_change *ls_change,
+ bool *updated)
{
bool ls_ports_changed = false;
if (!nbrec_logical_switch_is_updated(changed_ls,
@@ -5160,12 +5160,6 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn *ovnsb_idl_txn,
return true;
}
- struct ls_change *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);
-
struct ovn_port *op;
HMAP_FOR_EACH (op, dp_node, &od->ports) {
op->visited = false;
@@ -5255,10 +5249,7 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn *ovnsb_idl_txn,
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)) {
- ovs_list_push_back(&nd->tracked_ls_changes.updated,
- &ls_change->list_node);
- } else {
- free(ls_change);
+ *updated = true;
}
return true;
@@ -5269,11 +5260,20 @@ fail_clean_deleted:
}
fail:
- free(ls_change);
+
+ LIST_FOR_EACH (op, list, &ls_change->added_ports) {
+ ovs_list_remove(&op->list);
+ }
+ LIST_FOR_EACH (op, list, &ls_change->updated_ports) {
+ ovs_list_remove(&op->list);
+ }
+ LIST_FOR_EACH_SAFE (op, list, &ls_change->deleted_ports) {
+ ovs_list_remove(&op->list);
+ ovn_port_destroy_orphan(op);
+ }
return false;
}
-
/* Return true if changes are handled incrementally, false otherwise.
* When there are any changes, try to track what's exactly changed and set
* northd_data->change_tracked accordingly: change tracked - true, otherwise,
@@ -5307,14 +5307,33 @@ northd_handle_ls_changes(struct ovsdb_idl_txn *ovnsb_idl_txn,
goto fail;
}
- if (!ls_handle_lsp_changes(ovnsb_idl_txn, changed_ls, ni, nd, od)) {
+ struct ls_change *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,
+ &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);
+ }
}
if (!ovs_list_is_empty(&nd->tracked_ls_changes.updated)) {
nd->change_tracked = true;
}
+
return true;
fail:
@@ -5376,16 +5395,21 @@ northd_handle_sb_port_binding_changes(
/* Handler for lb_data engine changes. For every tracked lb_data
* it creates or deletes the ovn_lb_datapaths/ovn_lb_group_datapaths
- * from the lb_datapaths hmap and lb_group_datapaths hmap. */
+ * from the lb_datapaths hmap and lb_group_datapaths hmap.
+ *
+ * This handler is called if there are any lb_data changes but before
+ * processing the logical switch changes.
+ * */
bool
-northd_handle_lb_data_changes(struct tracked_lb_data *trk_lb_data,
- struct ovn_datapaths *ls_datapaths,
- struct ovn_datapaths *lr_datapaths,
- struct hmap *lb_datapaths_map,
- struct hmap *lb_group_datapaths_map)
+northd_handle_lb_data_changes_pre_od(struct tracked_lb_data *trk_lb_data,
+ struct ovn_datapaths *ls_datapaths,
+ struct ovn_datapaths *lr_datapaths,
+ struct hmap *lb_datapaths_map,
+ struct hmap *lb_group_datapaths_map)
{
struct ovn_lb_datapaths *lb_dps;
struct ovn_northd_lb *lb;
+ struct ovn_datapath *od;
struct hmapx_node *hmapx_node;
HMAPX_FOR_EACH (hmapx_node, &trk_lb_data->deleted_lbs) {
lb = hmapx_node->data;
@@ -5393,6 +5417,16 @@ northd_handle_lb_data_changes(struct tracked_lb_data *trk_lb_data,
lb_dps = ovn_lb_datapaths_find(lb_datapaths_map, lb_uuid);
ovs_assert(lb_dps);
+
+ /* Re-evaluate 'od->has_lb_vip for od's associated with the
+ * deleted lb. */
+ size_t index;
+ BITMAP_FOR_EACH_1 (index, ods_size(ls_datapaths),
+ lb_dps->nb_ls_map) {
+ od = ls_datapaths->array[index];
+ init_lb_for_datapath(od);
+ }
+
hmap_remove(lb_datapaths_map, &lb_dps->hmap_node);
ovn_lb_datapaths_destroy(lb_dps);
}
@@ -5432,6 +5466,65 @@ northd_handle_lb_data_changes(struct tracked_lb_data *trk_lb_data,
return true;
}
+/* This handler is called if there are any lb_data changes but afer processing
+ * the logical switch changes.
+ *
+ * For every tracked data it does the following:
+ * For any changes to a created or updated logical switch due to
+ * association of a load balancer (eg. ovn-nbctl ls-lb-add sw0 lb1),
+ * the logical switch datapath is added to the load balancer (represented
+ * by 'struct ovn_lb_datapaths') by calling ovn_lb_datapaths_add_ls().
+ *
+ * For every created or updated load balancer in the tracked data,
+ * it gets the associated logical switches and for each switch it
+ * re-evaluates 'od->has_lb_vip'. Since this handler is called after
+ * handling any logical switch changes. */
+bool
+northd_handle_lb_data_changes_post_od(struct tracked_lb_data *trk_lb_data,
+ struct ovn_datapaths *ls_datapaths,
+ struct hmap *lb_datapaths_map)
+{
+ ovs_assert(!trk_lb_data->has_health_checks);
+
+ struct ovn_northd_lb *lb;
+ struct ovn_lb_datapaths *lb_dps;
+ struct ovn_datapath *od;
+ struct crupdated_od_lb_data *codlb;
+
+ LIST_FOR_EACH (codlb, list_node, &trk_lb_data->crupdated_ls_lbs) {
+ od = ovn_datapath_find(&ls_datapaths->datapaths, &codlb->od_uuid);
+ ovs_assert(od);
+
+ struct uuidset_node *uuidnode;
+ UUIDSET_FOR_EACH (uuidnode, &codlb->assoc_lbs) {
+ lb_dps = ovn_lb_datapaths_find(lb_datapaths_map, &uuidnode->uuid);
+ ovs_assert(lb_dps);
+ ovn_lb_datapaths_add_ls(lb_dps, 1, &od);
+ }
+
+ /* Re-evaluate 'od->has_lb_vip' */
+ init_lb_for_datapath(od);
+ }
+
+ struct crupdated_lb *clb;
+ HMAP_FOR_EACH (clb, hmap_node, &trk_lb_data->crupdated_lbs) {
+ lb = clb->lb;
+ const struct uuid *lb_uuid = &lb->nlb->header_.uuid;
+
+ lb_dps = ovn_lb_datapaths_find(lb_datapaths_map, lb_uuid);
+ ovs_assert(lb_dps);
+ size_t index;
+ BITMAP_FOR_EACH_1 (index, ods_size(ls_datapaths),
+ lb_dps->nb_ls_map) {
+ od = ls_datapaths->array[index];
+ /* Re-evaluate 'od->has_lb_vip' */
+ init_lb_for_datapath(od);
+ }
+ }
+
+ return true;
+}
+
struct multicast_group {
const char *name;
uint16_t key; /* OVN_MIN_MULTICAST...OVN_MAX_MULTICAST. */
@@ -16618,6 +16711,7 @@ bool lflow_handle_northd_ls_changes(struct ovsdb_idl_txn *ovnsb_txn,
struct hmap *lflows)
{
struct ls_change *ls_change;
+
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,
@@ -120,6 +120,8 @@ struct northd_data {
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 lflow_data {
@@ -348,11 +350,14 @@ bool northd_handle_sb_port_binding_changes(
const struct sbrec_port_binding_table *, struct hmap *ls_ports);
struct tracked_lb_data;
-bool northd_handle_lb_data_changes(struct tracked_lb_data *,
- struct ovn_datapaths *ls_datapaths,
- struct ovn_datapaths *lr_datapaths,
- struct hmap *lb_datapaths_map,
- struct hmap *lb_group_datapaths_map);
+bool northd_handle_lb_data_changes_pre_od(struct tracked_lb_data *,
+ struct ovn_datapaths *ls_datapaths,
+ struct ovn_datapaths *lr_datapaths,
+ struct hmap *lb_datapaths_map,
+ struct hmap *lb_group_datapaths_map);
+bool northd_handle_lb_data_changes_post_od(struct tracked_lb_data *,
+ struct ovn_datapaths *ls_datapaths,
+ struct hmap *lb_datapaths_map);
void build_bfd_table(struct ovsdb_idl_txn *ovnsb_txn,
const struct nbrec_bfd_table *,
@@ -9821,22 +9821,23 @@ ovn-nbctl lsp-set-type sw0-lr0 router
ovn-nbctl lsp-set-addresses sw0-lr0 00:00:00:00:ff:01
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
ovn-nbctl --wait=sb lsp-set-options sw0-lr0 router-port=lr0-sw0
-check_engine_stats lb_data norecompute nocompute
+check_engine_stats lb_data norecompute compute
check_engine_stats northd recompute nocompute
check_engine_stats lflow recompute nocompute
-# Associate lb1 to sw0. There should be a full recompute of northd engine node
+# Associate lb1 to sw0. There should be no recompute of northd engine node
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
check ovn-nbctl --wait=sb ls-lb-add sw0 lb1
-check_engine_stats lb_data norecompute nocompute
-check_engine_stats northd recompute nocompute
+check_engine_stats lb_data norecompute compute
+check_engine_stats northd norecompute compute
check_engine_stats lflow recompute nocompute
+CHECK_NO_CHANGE_AFTER_RECOMPUTE
# Modify the backend of the lb1 vip
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
check ovn-nbctl --wait=sb set load_balancer lb1 vips:'"10.0.0.10:80"'='"10.0.0.100:80"'
check_engine_stats lb_data norecompute compute
-check_engine_stats northd recompute nocompute
+check_engine_stats northd norecompute compute
check_engine_stats lflow recompute nocompute
CHECK_NO_CHANGE_AFTER_RECOMPUTE
@@ -9844,7 +9845,7 @@ CHECK_NO_CHANGE_AFTER_RECOMPUTE
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
check ovn-nbctl --wait=sb clear load_Balancer lb1 vips
check_engine_stats lb_data norecompute compute
-check_engine_stats northd recompute nocompute
+check_engine_stats northd norecompute compute
check_engine_stats lflow recompute nocompute
CHECK_NO_CHANGE_AFTER_RECOMPUTE
@@ -9852,7 +9853,7 @@ CHECK_NO_CHANGE_AFTER_RECOMPUTE
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
check ovn-nbctl --wait=sb lb-add lb1 10.0.0.10:80 10.0.0.3:80
check_engine_stats lb_data norecompute compute
-check_engine_stats northd recompute nocompute
+check_engine_stats northd norecompute compute
check_engine_stats lflow recompute nocompute
CHECK_NO_CHANGE_AFTER_RECOMPUTE
@@ -9860,14 +9861,33 @@ CHECK_NO_CHANGE_AFTER_RECOMPUTE
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
check ovn-nbctl --wait=sb lb-add lb1 10.0.0.20:80 10.0.0.30:8080
check_engine_stats lb_data norecompute compute
-check_engine_stats northd recompute nocompute
+check_engine_stats northd norecompute compute
check_engine_stats lflow recompute nocompute
CHECK_NO_CHANGE_AFTER_RECOMPUTE
# Disassociate lb1 from sw0. There should be a full recompute of northd engine node.
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
check ovn-nbctl --wait=sb ls-lb-del sw0 lb1
-check_engine_stats lb_data norecompute nocompute
+check_engine_stats lb_data norecompute compute
+check_engine_stats northd recompute nocompute
+check_engine_stats lflow recompute nocompute
+CHECK_NO_CHANGE_AFTER_RECOMPUTE
+
+# Associate lb1 to sw0 and also create a port sw0p1. This should result in
+# full recompute of lflow engine node.
+check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
+check ovn-nbctl --wait=sb ls-lb-add sw0 lb1 -- lsp-add sw0 sw0p1
+check_engine_stats lb_data norecompute compute
+check_engine_stats northd norecompute compute
+check_engine_stats lflow recompute nocompute
+
+CHECK_NO_CHANGE_AFTER_RECOMPUTE
+check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
+
+# Disassociate lb1 from sw0. There should be a recompute of northd engine node.
+check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
+check ovn-nbctl --wait=sb ls-lb-del sw0 lb1
+check_engine_stats lb_data norecompute compute
check_engine_stats northd recompute nocompute
check_engine_stats lflow recompute nocompute
CHECK_NO_CHANGE_AFTER_RECOMPUTE
@@ -9955,7 +9975,7 @@ CHECK_NO_CHANGE_AFTER_RECOMPUTE
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
check ovn-nbctl add logical_switch sw0 load_balancer_group $lbg1_uuid
-check_engine_stats lb_data norecompute nocompute
+check_engine_stats lb_data norecompute compute
check_engine_stats northd recompute nocompute
check_engine_stats lflow recompute nocompute
@@ -10000,7 +10020,7 @@ CHECK_NO_CHANGE_AFTER_RECOMPUTE
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
check ovn-nbctl clear logical_switch sw0 load_balancer_group
-check_engine_stats lb_data norecompute nocompute
+check_engine_stats lb_data norecompute compute
check_engine_stats northd recompute nocompute
check_engine_stats lflow recompute nocompute
@@ -10052,7 +10072,7 @@ check_engine_stats lflow recompute nocompute
# Add back lb group to logical switch and then delete it.
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
check ovn-nbctl add logical_switch sw0 load_balancer_group $lbg1_uuid
-check_engine_stats lb_data norecompute nocompute
+check_engine_stats lb_data norecompute compute
check_engine_stats northd recompute nocompute
check_engine_stats lflow recompute nocompute
@@ -10093,7 +10113,7 @@ check_engine_stats lflow recompute nocompute
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
check ovn-nbctl set logical_switch sw0 load_balancer_group=$lbg1_uuid
-check_engine_stats lb_data norecompute nocompute
+check_engine_stats lb_data norecompute compute
check_engine_stats northd recompute nocompute
check_engine_stats lflow recompute nocompute
CHECK_NO_CHANGE_AFTER_RECOMPUTE
@@ -10107,15 +10127,15 @@ CHECK_NO_CHANGE_AFTER_RECOMPUTE
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
check ovn-nbctl --wait=sb ls-lb-add sw0 lb2
-check_engine_stats lb_data norecompute nocompute
-check_engine_stats northd recompute nocompute
+check_engine_stats lb_data norecompute compute
+check_engine_stats northd norecompute compute
check_engine_stats lflow recompute nocompute
CHECK_NO_CHANGE_AFTER_RECOMPUTE
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
check ovn-nbctl --wait=sb ls-lb-add sw0 lb3
-check_engine_stats lb_data norecompute nocompute
-check_engine_stats northd recompute nocompute
+check_engine_stats lb_data norecompute compute
+check_engine_stats northd norecompute compute
check_engine_stats lflow recompute nocompute
CHECK_NO_CHANGE_AFTER_RECOMPUTE
@@ -10129,7 +10149,7 @@ CHECK_NO_CHANGE_AFTER_RECOMPUTE
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
check ovn-nbctl --wait=sb ls-lb-del sw0 lb2
-check_engine_stats lb_data norecompute nocompute
+check_engine_stats lb_data norecompute compute
check_engine_stats northd recompute nocompute
check_engine_stats lflow recompute nocompute
CHECK_NO_CHANGE_AFTER_RECOMPUTE