@@ -794,6 +794,7 @@ ovn_lb_group_init(struct ovn_lb_group *lb_group,
const struct uuid *lb_uuid =
&nbrec_lb_group->load_balancer[i]->header_.uuid;
lb_group->lbs[i] = ovn_northd_lb_find(lbs, lb_uuid);
+ lb_group->has_routable_lb |= lb_group->lbs[i]->routable;
}
}
@@ -814,6 +815,7 @@ static void
ovn_lb_group_cleanup(struct ovn_lb_group *lb_group)
{
ovn_lb_ip_set_destroy(lb_group->lb_ips);
+ lb_group->has_routable_lb = false;
free(lb_group->lbs);
}
@@ -1078,7 +1080,10 @@ ovn_lb_datapaths_add_lr(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_lr_map, ods[i]->index);
+ if (!bitmap_is_set(lb_dps->nb_lr_map, ods[i]->index)) {
+ bitmap_set1(lb_dps->nb_lr_map, ods[i]->index);
+ lb_dps->n_nb_lr++;
+ }
}
}
@@ -145,6 +145,7 @@ struct ovn_lb_group {
size_t n_lbs;
struct ovn_northd_lb **lbs;
struct ovn_lb_ip_set *lb_ips;
+ bool has_routable_lb;
};
struct ovn_lb_group *ovn_lb_group_create(
@@ -39,12 +39,23 @@ 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);
+ const struct nbrec_logical_router_table *,
+ struct hmap *ls_lb_map, struct hmap *lr_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 void handle_od_lb_changes(struct nbrec_load_balancer **,
+ size_t n_nbrec_lbs,
+ struct od_lb_data *od_lb_data,
+ struct ed_type_lb_data *lb_data,
+ struct crupdated_od_lb_data *);
+static void handle_od_lbgrp_changes(struct nbrec_load_balancer_group **,
+ size_t n_nbrec_lbs,
+ struct od_lb_data *,
+ struct ed_type_lb_data *lb_data,
+ struct crupdated_od_lb_data *);
static struct ovn_lb_group *create_lb_group(
const struct nbrec_load_balancer_group *, struct hmap *lbs,
@@ -63,6 +74,8 @@ static inline 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);
static bool is_ls_lbgrps_changed(const struct nbrec_logical_switch *nbs);
+static bool is_lr_lbs_changed(const struct nbrec_logical_router *);
+static bool is_lr_lbgrps_changed(const struct nbrec_logical_router *);
/* 'lb_data' engine node manages the NB load balancers and load balancer
* groups. For each NB LB, it creates 'struct ovn_northd_lb' and
@@ -91,10 +104,13 @@ en_lb_data_run(struct engine_node *node, void *data)
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));
+ const struct nbrec_logical_router_table *nb_lr_table =
+ EN_OVSDB_GET(engine_get_input("NB_logical_router", 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);
+ build_od_lb_map(nb_ls_table, nb_lr_table, &lb_data->ls_lb_map,
+ &lb_data->lr_lb_map);
engine_set_node_state(node, EN_UPDATED);
}
@@ -136,6 +152,7 @@ lb_data_load_balancer_handler(struct engine_node *node, void *data)
uuid_hash(&tracked_lb->header_.uuid));
add_crupdated_lb_to_tracked_data(lb, trk_lb_data,
lb->health_checks);
+ trk_lb_data->has_routable_lb |= lb->routable;
} else if (nbrec_load_balancer_is_deleted(tracked_lb)) {
lb = ovn_northd_lb_find(&lb_data->lbs,
&tracked_lb->header_.uuid);
@@ -143,6 +160,7 @@ lb_data_load_balancer_handler(struct engine_node *node, void *data)
hmap_remove(&lb_data->lbs, &lb->hmap_node);
add_deleted_lb_to_tracked_data(lb, trk_lb_data,
lb->health_checks);
+ trk_lb_data->has_routable_lb |= lb->routable;
} else {
/* Load balancer updated. */
lb = ovn_northd_lb_find(&lb_data->lbs,
@@ -152,6 +170,7 @@ lb_data_load_balancer_handler(struct engine_node *node, void *data)
ovn_northd_lb_reinit(lb, tracked_lb);
health_checks |= lb->health_checks;
add_crupdated_lb_to_tracked_data(lb, trk_lb_data, health_checks);
+ trk_lb_data->has_routable_lb |= lb->routable;
}
}
@@ -180,6 +199,8 @@ lb_data_load_balancer_group_handler(struct engine_node *node, void *data)
for (size_t i = 0; i < lb_group->n_lbs; i++) {
hmapx_add(&clbg->assoc_lbs, lb_group->lbs[i]);
}
+
+ trk_lb_data->has_routable_lb |= lb_group->has_routable_lb;
} else if (nbrec_load_balancer_group_is_deleted(tracked_lb_group)) {
struct ovn_lb_group *lb_group;
lb_group = ovn_lb_group_find(&lb_data->lb_groups,
@@ -187,6 +208,7 @@ lb_data_load_balancer_group_handler(struct engine_node *node, void *data)
ovs_assert(lb_group);
hmap_remove(&lb_data->lb_groups, &lb_group->hmap_node);
add_deleted_lb_group_to_tracked_data(lb_group, trk_lb_data);
+ trk_lb_data->has_routable_lb |= lb_group->has_routable_lb;
} else if (nbrec_load_balancer_group_is_updated(tracked_lb_group,
NBREC_LOAD_BALANCER_GROUP_COL_LOAD_BALANCER)) {
@@ -209,6 +231,8 @@ lb_data_load_balancer_group_handler(struct engine_node *node, void *data)
build_lrouter_lb_ips(lb_group->lb_ips, lb_group->lbs[i]);
}
+ trk_lb_data->has_routable_lb |= lb_group->has_routable_lb;
+
struct crupdated_lb_group *clbg =
add_crupdated_lb_group_to_tracked_data(lb_group, trk_lb_data);
@@ -275,6 +299,7 @@ lb_data_logical_switch_handler(struct engine_node *node, void *data)
if (!is_ls_lbs_changed(nbs) && !is_ls_lbgrps_changed(nbs)) {
continue;
}
+ changed = true;
struct crupdated_od_lb_data *codlb = xzalloc(sizeof *codlb);
codlb->od_uuid = nbs->header_.uuid;
uuidset_init(&codlb->assoc_lbs);
@@ -288,59 +313,75 @@ lb_data_logical_switch_handler(struct engine_node *node, void *data)
}
if (is_ls_lbs_changed(nbs)) {
- 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);
-
- if (!uuidset_find_and_delete(pre_lb_uuids,
- lb_uuid)) {
- /* Add this lb to the tracked data. */
- uuidset_insert(&codlb->assoc_lbs, lb_uuid);
- changed = true;
- }
- }
+ handle_od_lb_changes(nbs->load_balancer, nbs->n_load_balancer,
+ od_lb_data, lb_data, codlb);
+ }
- if (!uuidset_is_empty(pre_lb_uuids)) {
- trk_lb_data->has_dissassoc_lbs_from_od = true;
- changed = true;
- }
+ if (is_ls_lbgrps_changed(nbs)) {
+ handle_od_lbgrp_changes(nbs->load_balancer_group,
+ nbs->n_load_balancer_group,
+ od_lb_data, lb_data, codlb);
+ }
+
+ ovs_list_insert(&trk_lb_data->crupdated_ls_lbs, &codlb->list_node);
+ }
+ }
+
+ if (changed) {
+ engine_set_node_state(node, EN_UPDATED);
+ }
+ return true;
+}
+
+bool
+lb_data_logical_router_handler(struct engine_node *node, void *data)
+{
+ struct ed_type_lb_data *lb_data = (struct ed_type_lb_data *) data;
+ const struct nbrec_logical_router_table *nbrec_lr_table =
+ EN_OVSDB_GET(engine_get_input("NB_logical_router", node));
+
+ struct tracked_lb_data *trk_lb_data = &lb_data->tracked_lb_data;
+ lb_data->tracked = true;
- uuidset_destroy(pre_lb_uuids);
- free(pre_lb_uuids);
+ bool changed = false;
+ const struct nbrec_logical_router *nbr;
+ NBREC_LOGICAL_ROUTER_TABLE_FOR_EACH_TRACKED (nbr, nbrec_lr_table) {
+ if (nbrec_logical_router_is_deleted(nbr)) {
+ struct od_lb_data *od_lb_data =
+ find_od_lb_data(&lb_data->lr_lb_map, &nbr->header_.uuid);
+ if (od_lb_data) {
+ hmap_remove(&lb_data->lr_lb_map, &od_lb_data->hmap_node);
+ destroy_od_lb_data(od_lb_data);
+ }
+ } else {
+ if (!is_lr_lbs_changed(nbr) && !is_lr_lbgrps_changed(nbr)) {
+ continue;
}
+ changed = true;
+ struct crupdated_od_lb_data *codlb = xzalloc(sizeof *codlb);
+ codlb->od_uuid = nbr->header_.uuid;
+ uuidset_init(&codlb->assoc_lbs);
+ uuidset_init(&codlb->assoc_lbgrps);
- if (is_ls_lbgrps_changed(nbs)) {
- struct uuidset *pre_lbgrp_uuids = od_lb_data->lbgrps;
- od_lb_data->lbgrps = xzalloc(sizeof *od_lb_data->lbgrps);
- uuidset_init(od_lb_data->lbgrps);
- for (size_t i = 0; i < nbs->n_load_balancer_group; i++) {
- const struct uuid *lbg_uuid =
- &nbs->load_balancer_group[i]->header_.uuid;
- uuidset_insert(od_lb_data->lbgrps, lbg_uuid);
-
- if (!uuidset_find_and_delete(pre_lbgrp_uuids,
- lbg_uuid)) {
- /* Add this lb group to the tracked data. */
- uuidset_insert(&codlb->assoc_lbgrps, lbg_uuid);
- changed = true;
- }
- }
+ struct od_lb_data *od_lb_data =
+ find_od_lb_data(&lb_data->lr_lb_map, &nbr->header_.uuid);
+ if (!od_lb_data) {
+ od_lb_data = create_od_lb_data(&lb_data->lr_lb_map,
+ &nbr->header_.uuid);
+ }
- if (!uuidset_is_empty(pre_lbgrp_uuids)) {
- trk_lb_data->has_dissassoc_lbgrps_from_od = true;
- changed = true;
- }
+ if (is_lr_lbs_changed(nbr)) {
+ handle_od_lb_changes(nbr->load_balancer, nbr->n_load_balancer,
+ od_lb_data, lb_data, codlb);
+ }
- uuidset_destroy(pre_lbgrp_uuids);
- free(pre_lbgrp_uuids);
+ if (is_lr_lbgrps_changed(nbr)) {
+ handle_od_lbgrp_changes(nbr->load_balancer_group,
+ nbr->n_load_balancer_group,
+ od_lb_data, lb_data, codlb);
}
- ovs_list_insert(&trk_lb_data->crupdated_ls_lbs, &codlb->list_node);
+ ovs_list_insert(&trk_lb_data->crupdated_lr_lbs, &codlb->list_node);
}
}
@@ -357,6 +398,7 @@ 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);
+ hmap_init(&lb_data->lr_lb_map);
struct tracked_lb_data *trk_lb_data = &lb_data->tracked_lb_data;
hmapx_init(&trk_lb_data->crupdated_lbs);
@@ -364,6 +406,7 @@ lb_data_init(struct ed_type_lb_data *lb_data)
hmapx_init(&trk_lb_data->crupdated_lb_groups);
hmapx_init(&trk_lb_data->deleted_lb_groups);
ovs_list_init(&trk_lb_data->crupdated_ls_lbs);
+ ovs_list_init(&trk_lb_data->crupdated_lr_lbs);
}
static void
@@ -387,6 +430,11 @@ lb_data_destroy(struct ed_type_lb_data *lb_data)
}
hmap_destroy(&lb_data->ls_lb_map);
+ HMAP_FOR_EACH_POP (od_lb_data, hmap_node, &lb_data->lr_lb_map) {
+ destroy_od_lb_data(od_lb_data);
+ }
+ hmap_destroy(&lb_data->lr_lb_map);
+
destroy_tracked_data(lb_data);
hmapx_destroy(&lb_data->tracked_lb_data.crupdated_lbs);
hmapx_destroy(&lb_data->tracked_lb_data.deleted_lbs);
@@ -430,7 +478,8 @@ create_lb_group(const struct nbrec_load_balancer_group *nbrec_lb_group,
static void
build_od_lb_map(const struct nbrec_logical_switch_table *nbrec_ls_table,
- struct hmap *ls_lb_map)
+ const struct nbrec_logical_router_table *nbrec_lr_table,
+ struct hmap *ls_lb_map, struct hmap *lr_lb_map)
{
const struct nbrec_logical_switch *nbrec_ls;
NBREC_LOGICAL_SWITCH_TABLE_FOR_EACH (nbrec_ls, nbrec_ls_table) {
@@ -438,17 +487,35 @@ build_od_lb_map(const struct nbrec_logical_switch_table *nbrec_ls_table,
continue;
}
- struct od_lb_data *od_lb_data =
+ struct od_lb_data *ls_lb_data =
create_od_lb_data(ls_lb_map, &nbrec_ls->header_.uuid);
for (size_t i = 0; i < nbrec_ls->n_load_balancer; i++) {
- uuidset_insert(od_lb_data->lbs,
+ uuidset_insert(ls_lb_data->lbs,
&nbrec_ls->load_balancer[i]->header_.uuid);
}
for (size_t i = 0; i < nbrec_ls->n_load_balancer_group; i++) {
- uuidset_insert(od_lb_data->lbgrps,
+ uuidset_insert(ls_lb_data->lbgrps,
&nbrec_ls->load_balancer_group[i]->header_.uuid);
}
}
+
+ const struct nbrec_logical_router *nbrec_lr;
+ NBREC_LOGICAL_ROUTER_TABLE_FOR_EACH (nbrec_lr, nbrec_lr_table) {
+ if (!nbrec_lr->n_load_balancer && !nbrec_lr->n_load_balancer_group) {
+ continue;
+ }
+
+ struct od_lb_data *lr_lb_data =
+ create_od_lb_data(lr_lb_map, &nbrec_lr->header_.uuid);
+ for (size_t i = 0; i < nbrec_lr->n_load_balancer; i++) {
+ uuidset_insert(lr_lb_data->lbs,
+ &nbrec_lr->load_balancer[i]->header_.uuid);
+ }
+ for (size_t i = 0; i < nbrec_lr->n_load_balancer_group; i++) {
+ uuidset_insert(lr_lb_data->lbgrps,
+ &nbrec_lr->load_balancer_group[i]->header_.uuid);
+ }
+ }
}
static struct od_lb_data *
@@ -490,6 +557,77 @@ destroy_od_lb_data(struct od_lb_data *od_lb_data)
free(od_lb_data);
}
+static void
+handle_od_lb_changes(struct nbrec_load_balancer **nbrec_lbs,
+ size_t n_nbrec_lbs, struct od_lb_data *od_lb_data,
+ struct ed_type_lb_data *lb_data,
+ struct crupdated_od_lb_data *codlb)
+{
+ struct tracked_lb_data *trk_lb_data = &lb_data->tracked_lb_data;
+ 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 < n_nbrec_lbs; i++) {
+ const struct uuid *lb_uuid = &nbrec_lbs[i]->header_.uuid;
+ uuidset_insert(od_lb_data->lbs, lb_uuid);
+
+ if (!uuidset_find_and_delete(pre_lb_uuids, lb_uuid)) {
+ /* Add this lb to the tracked data. */
+ uuidset_insert(&codlb->assoc_lbs, lb_uuid);
+
+ if (!trk_lb_data->has_routable_lb) {
+ struct ovn_northd_lb *lb = ovn_northd_lb_find(&lb_data->lbs,
+ lb_uuid);
+ ovs_assert(lb);
+ trk_lb_data->has_routable_lb |= lb->routable;
+ }
+ }
+ }
+
+ if (!uuidset_is_empty(pre_lb_uuids)) {
+ trk_lb_data->has_dissassoc_lbs_from_od = true;
+ }
+
+ uuidset_destroy(pre_lb_uuids);
+ free(pre_lb_uuids);
+}
+
+static void
+handle_od_lbgrp_changes(struct nbrec_load_balancer_group **nbrec_lbgrps,
+ size_t n_nbrec_lbgrps, struct od_lb_data *od_lb_data,
+ struct ed_type_lb_data *lb_data,
+ struct crupdated_od_lb_data *codlb)
+{
+ struct tracked_lb_data *trk_lb_data = &lb_data->tracked_lb_data;
+ struct uuidset *pre_lbgrp_uuids = od_lb_data->lbgrps;
+ od_lb_data->lbgrps = xzalloc(sizeof *od_lb_data->lbgrps);
+ uuidset_init(od_lb_data->lbgrps);
+ for (size_t i = 0; i < n_nbrec_lbgrps; i++) {
+ const struct uuid *lbgrp_uuid = &nbrec_lbgrps[i]->header_.uuid;
+ uuidset_insert(od_lb_data->lbgrps, lbgrp_uuid);
+
+ if (!uuidset_find_and_delete(pre_lbgrp_uuids, lbgrp_uuid)) {
+ /* Add this lb group to the tracked data. */
+ uuidset_insert(&codlb->assoc_lbgrps, lbgrp_uuid);
+
+ if (!trk_lb_data->has_routable_lb) {
+ struct ovn_lb_group *lbgrp =
+ ovn_lb_group_find(&lb_data->lb_groups, lbgrp_uuid);
+ ovs_assert(lbgrp);
+ trk_lb_data->has_routable_lb |= lbgrp->has_routable_lb;
+ }
+ }
+ }
+
+ if (!uuidset_is_empty(pre_lbgrp_uuids)) {
+ trk_lb_data->has_dissassoc_lbgrps_from_od = true;
+ }
+
+ uuidset_destroy(pre_lbgrp_uuids);
+ free(pre_lbgrp_uuids);
+}
+
static void
destroy_tracked_data(struct ed_type_lb_data *lb_data)
{
@@ -498,6 +636,7 @@ destroy_tracked_data(struct ed_type_lb_data *lb_data)
lb_data->tracked_lb_data.has_dissassoc_lbs_from_lb_grops = false;
lb_data->tracked_lb_data.has_dissassoc_lbs_from_od = false;
lb_data->tracked_lb_data.has_dissassoc_lbgrps_from_od = false;
+ lb_data->tracked_lb_data.has_routable_lb = false;
struct hmapx_node *node;
HMAPX_FOR_EACH_SAFE (node, &lb_data->tracked_lb_data.deleted_lbs) {
@@ -528,6 +667,13 @@ destroy_tracked_data(struct ed_type_lb_data *lb_data)
uuidset_destroy(&codlb->assoc_lbgrps);
free(codlb);
}
+ LIST_FOR_EACH_SAFE (codlb, list_node,
+ &lb_data->tracked_lb_data.crupdated_lr_lbs) {
+ ovs_list_remove(&codlb->list_node);
+ uuidset_destroy(&codlb->assoc_lbs);
+ uuidset_destroy(&codlb->assoc_lbgrps);
+ free(codlb);
+ }
}
static inline void
@@ -583,3 +729,17 @@ is_ls_lbgrps_changed(const struct nbrec_logical_switch *nbs) {
|| nbrec_logical_switch_is_updated(nbs,
NBREC_LOGICAL_SWITCH_COL_LOAD_BALANCER_GROUP));
}
+
+static bool
+is_lr_lbs_changed(const struct nbrec_logical_router *nbr) {
+ return ((nbrec_logical_router_is_new(nbr) && nbr->n_load_balancer)
+ || nbrec_logical_router_is_updated(nbr,
+ NBREC_LOGICAL_ROUTER_COL_LOAD_BALANCER));
+}
+
+static bool
+is_lr_lbgrps_changed(const struct nbrec_logical_router *nbr) {
+ return ((nbrec_logical_router_is_new(nbr) && nbr->n_load_balancer_group)
+ || nbrec_logical_router_is_updated(nbr,
+ NBREC_LOGICAL_ROUTER_COL_LOAD_BALANCER_GROUP));
+}
@@ -45,6 +45,10 @@ struct tracked_lb_data {
* 'struct crupdated_od_lb_data' */
struct ovs_list crupdated_ls_lbs;
+ /* List of logical router <-> lb changes. List node is
+ * 'struct crupdated_od_lb_data' */
+ struct ovs_list crupdated_lr_lbs;
+
/* Indicates if any of the tracked lb has health checks enabled. */
bool has_health_checks;
@@ -57,6 +61,9 @@ struct tracked_lb_data {
/* Indicates if a lb group was disassociated from a logical switch. */
bool has_dissassoc_lbgrps_from_od;
+
+ /* Indicates if any lb (in the tracked data) has 'routable' flag set. */
+ bool has_routable_lb;
};
/* struct which maintains the data of the engine node lb_data. */
@@ -67,6 +74,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;
+ struct hmap lr_lb_map;
/* tracked data*/
bool tracked;
@@ -81,5 +89,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);
+bool lb_data_logical_router_handler(struct engine_node *, void *data);
#endif /* end of EN_NORTHD_LB_DATA_H */
@@ -206,6 +206,26 @@ northd_sb_port_binding_handler(struct engine_node *node,
return true;
}
+bool
+northd_nb_logical_router_handler(struct engine_node *node,
+ void *data)
+{
+ struct northd_data *nd = data;
+ struct northd_input input_data;
+
+ northd_get_input_data(node, &input_data);
+
+ if (!northd_handle_lr_changes(&input_data, nd)) {
+ return false;
+ }
+
+ if (nd->change_tracked) {
+ engine_set_node_state(node, EN_UPDATED);
+ }
+
+ return true;
+}
+
bool
northd_lb_data_handler_pre_od(struct engine_node *node, void *data)
{
@@ -244,6 +264,10 @@ northd_lb_data_handler_pre_od(struct engine_node *node, void *data)
return false;
}
+ if (lb_data->tracked_lb_data.has_routable_lb) {
+ return false;
+ }
+
struct northd_data *nd = data;
if (!northd_handle_lb_data_changes_pre_od(&lb_data->tracked_lb_data,
@@ -268,11 +292,13 @@ northd_lb_data_handler_post_od(struct engine_node *node, void *data)
ovs_assert(!lb_data->tracked_lb_data.has_dissassoc_lbs_from_od);
ovs_assert(!lb_data->tracked_lb_data.has_dissassoc_lbgrps_from_od);
ovs_assert(!lb_data->tracked_lb_data.has_dissassoc_lbs_from_lb_grops);
+ ovs_assert(!lb_data->tracked_lb_data.has_routable_lb);
struct northd_data *nd = data;
if (!northd_handle_lb_data_changes_post_od(&lb_data->tracked_lb_data,
&nd->ls_datapaths,
+ &nd->lr_datapaths,
&nd->lb_datapaths_map,
&nd->lb_group_datapaths_map)) {
return false;
@@ -16,6 +16,7 @@ void en_northd_cleanup(void *data);
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_nb_logical_router_handler(struct engine_node *, void *data);
bool northd_sb_port_binding_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);
@@ -155,10 +155,11 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
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_lb_data, &en_nb_logical_router,
+ lb_data_logical_router_handler);
engine_add_input(&en_northd, &en_nb_port_group, NULL);
engine_add_input(&en_northd, &en_nb_acl, NULL);
- engine_add_input(&en_northd, &en_nb_logical_router, NULL);
engine_add_input(&en_northd, &en_nb_mirror, NULL);
engine_add_input(&en_northd, &en_nb_meter, NULL);
engine_add_input(&en_northd, &en_nb_static_mac_binding, NULL);
@@ -186,6 +187,8 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
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_nb_logical_router,
+ northd_nb_logical_router_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);
@@ -5360,6 +5360,95 @@ fail:
return false;
}
+/* Returns true if the logical router has changes which are not
+ * incrementally handled.
+ * Presently supports i-p for the below changes:
+ * - load balancers and load balancer groups.
+ */
+static bool
+check_unsupported_inc_proc_for_lr_changes(
+ const struct nbrec_logical_router *lr)
+{
+ /* Check if the columns are changed in this row. */
+ enum nbrec_logical_router_column_id col;
+ for (col = 0; col < NBREC_LOGICAL_ROUTER_N_COLUMNS; col++) {
+ if (nbrec_logical_router_is_updated(lr, col)) {
+ if (col == NBREC_LOGICAL_ROUTER_COL_LOAD_BALANCER ||
+ col == NBREC_LOGICAL_ROUTER_COL_LOAD_BALANCER_GROUP) {
+ continue;
+ }
+ return true;
+ }
+ }
+
+ /* Check if the referenced rows are changed.
+ XXX: Need a better OVSDB IDL interface for this check. */
+ for (size_t i = 0; i < lr->n_ports; i++) {
+ if (nbrec_logical_router_port_row_get_seqno(lr->ports[i],
+ OVSDB_IDL_CHANGE_MODIFY) > 0) {
+ return true;
+ }
+ }
+ if (lr->copp && nbrec_copp_row_get_seqno(lr->copp,
+ OVSDB_IDL_CHANGE_MODIFY) > 0) {
+ return true;
+ }
+ for (size_t i = 0; i < lr->n_nat; i++) {
+ if (nbrec_nat_row_get_seqno(lr->nat[i],
+ OVSDB_IDL_CHANGE_MODIFY) > 0) {
+ return true;
+ }
+ }
+ for (size_t i = 0; i < lr->n_policies; i++) {
+ if (nbrec_logical_router_policy_row_get_seqno(lr->policies[i],
+ OVSDB_IDL_CHANGE_MODIFY) > 0) {
+ return true;
+ }
+ }
+ for (size_t i = 0; i < lr->n_static_routes; i++) {
+ if (nbrec_logical_router_static_route_row_get_seqno(
+ lr->static_routes[i], OVSDB_IDL_CHANGE_MODIFY) > 0) {
+ return true;
+ }
+ }
+ 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,
+ * false.
+ * Note: Changes to load balancer and load balancer groups associated with
+ * the logical routers are handled separately in the lb_data change
+ * handlers (northd_handle_lb_data_changes_pre_od and
+ * northd_handle_lb_data_changes_post_od).
+ * */
+bool
+northd_handle_lr_changes(const struct northd_input *ni,
+ struct northd_data *nd)
+{
+ const struct nbrec_logical_router *changed_lr;
+
+ NBREC_LOGICAL_ROUTER_TABLE_FOR_EACH_TRACKED (changed_lr,
+ ni->nbrec_logical_router_table) {
+ if (nbrec_logical_router_is_new(changed_lr) ||
+ nbrec_logical_router_is_deleted(changed_lr)) {
+ goto fail;
+ }
+
+ /* Presently only able to handle load balancer and
+ * load balancer group changes. */
+ if (check_unsupported_inc_proc_for_lr_changes(changed_lr)) {
+ goto fail;
+ }
+ }
+
+ return true;
+fail:
+ destroy_northd_data_tracked_changes(nd);
+ return false;
+}
+
bool
northd_handle_sb_port_binding_changes(
const struct sbrec_port_binding_table *sbrec_port_binding_table,
@@ -5500,6 +5589,7 @@ northd_handle_lb_data_changes_pre_od(struct tracked_lb_data *trk_lb_data,
bool
northd_handle_lb_data_changes_post_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)
{
@@ -5544,6 +5634,45 @@ northd_handle_lb_data_changes_post_od(struct tracked_lb_data *trk_lb_data,
init_lb_for_datapath(od);
}
+ LIST_FOR_EACH (codlb, list_node, &trk_lb_data->crupdated_lr_lbs) {
+ od = ovn_datapath_find(&lr_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_lr(lb_dps, 1, &od);
+
+ /* Add the lb_ips of lb_dps to the od. */
+ build_lrouter_lb_ips(od->lb_ips, lb_dps->lb);
+ build_lrouter_lb_reachable_ips(od, lb_dps->lb);
+ }
+
+ UUIDSET_FOR_EACH (uuidnode, &codlb->assoc_lbgrps) {
+ lbgrp_dps = ovn_lb_group_datapaths_find(lb_group_datapaths_map,
+ &uuidnode->uuid);
+ ovs_assert(lbgrp_dps);
+ ovn_lb_group_datapaths_add_lr(lbgrp_dps, od);
+
+ /* Associate all the lbs of the lbgrp to the datapath 'od' */
+ for (size_t j = 0; j < lbgrp_dps->lb_group->n_lbs; j++) {
+ const struct uuid *lb_uuid
+ = &lbgrp_dps->lb_group->lbs[j]->nlb->header_.uuid;
+ lb_dps = ovn_lb_datapaths_find(lb_datapaths_map, lb_uuid);
+ ovs_assert(lb_dps);
+ ovn_lb_datapaths_add_lr(lb_dps, 1, &od);
+
+ /* Add the lb_ips of lb_dps to the od. */
+ build_lrouter_lb_ips(od->lb_ips, lb_dps->lb);
+ build_lrouter_lb_reachable_ips(od, lb_dps->lb);
+ }
+ }
+
+ /* Re-evaluate 'od->has_lb_vip' */
+ init_lb_for_datapath(od);
+ }
+
HMAPX_FOR_EACH (hmapx_node, &trk_lb_data->crupdated_lbs) {
lb = hmapx_node->data;
const struct uuid *lb_uuid = &lb->nlb->header_.uuid;
@@ -5576,8 +5705,19 @@ northd_handle_lb_data_changes_post_od(struct tracked_lb_data *trk_lb_data,
lb_uuid = &lb->nlb->header_.uuid;
lb_dps = ovn_lb_datapaths_find(lb_datapaths_map, lb_uuid);
ovs_assert(lb_dps);
+ for (size_t i = 0; i < lbgrp_dps->n_lr; i++) {
+ od = lbgrp_dps->lr[i];
+ ovn_lb_datapaths_add_lr(lb_dps, 1, &od);
+
+ /* Re-evaluate 'od->has_lb_vip' */
+ init_lb_for_datapath(od);
+
+ /* Add the lb_ips of lb_dps to the od. */
+ build_lrouter_lb_ips(od->lb_ips, lb_dps->lb);
+ }
+
for (size_t i = 0; i < lbgrp_dps->n_ls; i++) {
- od = lbgrp_dps->ls[i];
+ od = lbgrp_dps->ls[i];
ovn_lb_datapaths_add_ls(lb_dps, 1, &od);
/* Re-evaluate 'od->has_lb_vip' */
@@ -335,6 +335,8 @@ void ovnsb_db_run(struct ovsdb_idl_txn *ovnnb_txn,
bool northd_handle_ls_changes(struct ovsdb_idl_txn *,
const struct northd_input *,
struct northd_data *);
+bool northd_handle_lr_changes(const struct northd_input *,
+ struct northd_data *);
void destroy_northd_data_tracked_changes(struct northd_data *);
void northd_destroy(struct northd_data *data);
void northd_init(struct northd_data *data);
@@ -357,6 +359,7 @@ bool northd_handle_lb_data_changes_pre_od(struct tracked_lb_data *,
struct hmap *lb_group_datapaths_map);
bool northd_handle_lb_data_changes_post_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);
@@ -9869,7 +9869,7 @@ CHECK_NO_CHANGE_AFTER_RECOMPUTE
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
check ovn-nbctl add logical_router lr0 load_balancer_group $lbg1_uuid
-check_engine_stats recompute recompute
+check_engine_stats norecompute recompute
CHECK_NO_CHANGE_AFTER_RECOMPUTE
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
@@ -9918,7 +9918,7 @@ CHECK_NO_CHANGE_AFTER_RECOMPUTE
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
check ovn-nbctl set logical_router lr1 load_balancer_group=$lbg1_uuid
-check_engine_stats recompute recompute
+check_engine_stats norecompute recompute
CHECK_NO_CHANGE_AFTER_RECOMPUTE
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
@@ -9934,7 +9934,7 @@ CHECK_NO_CHANGE_AFTER_RECOMPUTE
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats
check ovn-nbctl --wait=sb lr-lb-add lr1 lb1
check ovn-nbctl --wait=sb lr-lb-add lr1 lb2
-check_engine_stats recompute recompute
+check_engine_stats norecompute recompute
CHECK_NO_CHANGE_AFTER_RECOMPUTE
check as northd ovn-appctl -t NORTHD_TYPE inc-engine/clear-stats