@@ -26,6 +26,7 @@
#include "openvswitch/vlog.h"
#include "lib/bitmap.h"
#include "lib/smap.h"
+#include "socket-util.h"
VLOG_DEFINE_THIS_MODULE(lb);
@@ -431,11 +432,62 @@ void ovn_northd_lb_vip_init(struct ovn_northd_lb_vip *lb_vip_nb,
ovn_lb_get_health_check(nbrec_lb, vip_port_str, template);
}
+static void
+ovn_lb_vip_backends_health_check_init(const struct ovn_northd_lb *lb,
+ const struct ovn_lb_vip *lb_vip,
+ struct ovn_northd_lb_vip *lb_vip_nb)
+{
+ struct ds key = DS_EMPTY_INITIALIZER;
+
+ for (size_t j = 0; j < lb_vip->n_backends; j++) {
+ struct ovn_lb_backend *backend = &lb_vip->backends[j];
+ ds_clear(&key);
+ ds_put_format(&key, IN6_IS_ADDR_V4MAPPED(&lb_vip->vip)
+ ? "%s" : "[%s]", backend->ip_str);
+
+ const char *s = smap_get(&lb->nlb->ip_port_mappings, ds_cstr(&key));
+ if (!s) {
+ continue;
+ }
+
+ char *svc_mon_src_ip = NULL;
+ char *port_name = xstrdup(s);
+ char *p = strstr(port_name, ":");
+ if (p) {
+ *p = 0;
+ p++;
+ struct sockaddr_storage svc_mon_src_addr;
+ if (!inet_parse_address(p, &svc_mon_src_addr)) {
+ static struct vlog_rate_limit rl =
+ VLOG_RATE_LIMIT_INIT(5, 1);
+ VLOG_WARN_RL(&rl, "Invalid svc mon src IP %s", p);
+ } else {
+ struct ds src_ip_s = DS_EMPTY_INITIALIZER;
+ ss_format_address_nobracks(&svc_mon_src_addr,
+ &src_ip_s);
+ svc_mon_src_ip = ds_steal_cstr(&src_ip_s);
+ }
+ }
+
+ if (svc_mon_src_ip) {
+ struct ovn_northd_lb_backend *backend_nb =
+ &lb_vip_nb->backends_nb[j];
+ backend_nb->health_check = true;
+ backend_nb->logical_port = xstrdup(port_name);
+ backend_nb->svc_mon_src_ip = svc_mon_src_ip;
+ }
+ free(port_name);
+ }
+
+ ds_destroy(&key);
+}
+
static
void ovn_northd_lb_vip_destroy(struct ovn_northd_lb_vip *vip)
{
free(vip->backend_ips);
for (size_t i = 0; i < vip->n_backends; i++) {
+ free(vip->backends_nb[i].logical_port);
free(vip->backends_nb[i].svc_mon_src_ip);
}
free(vip->backends_nb);
@@ -555,8 +607,7 @@ ovn_lb_get_health_check(const struct nbrec_load_balancer *nbrec_lb,
}
struct ovn_northd_lb *
-ovn_northd_lb_create(const struct nbrec_load_balancer *nbrec_lb,
- size_t n_ls_datapaths, size_t n_lr_datapaths)
+ovn_northd_lb_create(const struct nbrec_load_balancer *nbrec_lb)
{
bool template = smap_get_bool(&nbrec_lb->options, "template", false);
bool is_udp = nullable_string_is_equal(nbrec_lb->protocol, "udp");
@@ -595,9 +646,6 @@ ovn_northd_lb_create(const struct nbrec_load_balancer *nbrec_lb,
}
lb->affinity_timeout = affinity_timeout;
- lb->nb_ls_map = bitmap_allocate(n_ls_datapaths);
- lb->nb_lr_map = bitmap_allocate(n_lr_datapaths);
-
sset_init(&lb->ips_v4);
sset_init(&lb->ips_v6);
struct smap_node *node;
@@ -631,7 +679,12 @@ ovn_northd_lb_create(const struct nbrec_load_balancer *nbrec_lb,
ovn_lb_vip6_template_format_internal(lb_vip),
xstrdup(node->value));
}
+
n_vips++;
+
+ if (lb_vip_nb->lb_health_check) {
+ ovn_lb_vip_backends_health_check_init(lb, lb_vip, lb_vip_nb);
+ }
}
/* It's possible that parsing VIPs fails. Update the lb->n_vips to the
@@ -639,6 +692,7 @@ ovn_northd_lb_create(const struct nbrec_load_balancer *nbrec_lb,
*/
lb->n_vips = n_vips;
+
if (nbrec_lb->n_selection_fields) {
char *proto = NULL;
if (nbrec_lb->protocol && nbrec_lb->protocol[0]) {
@@ -684,24 +738,6 @@ ovn_northd_lb_get_vips(const struct ovn_northd_lb *lb)
return &lb->nlb->vips;
}
-void
-ovn_northd_lb_add_lr(struct ovn_northd_lb *lb, size_t n,
- struct ovn_datapath **ods)
-{
- for (size_t i = 0; i < n; i++) {
- bitmap_set1(lb->nb_lr_map, ods[i]->index);
- }
-}
-
-void
-ovn_northd_lb_add_ls(struct ovn_northd_lb *lb, size_t n,
- struct ovn_datapath **ods)
-{
- for (size_t i = 0; i < n; i++) {
- bitmap_set1(lb->nb_ls_map, ods[i]->index);
- }
-}
-
void
ovn_northd_lb_destroy(struct ovn_northd_lb *lb)
{
@@ -715,8 +751,6 @@ ovn_northd_lb_destroy(struct ovn_northd_lb *lb)
sset_destroy(&lb->ips_v4);
sset_destroy(&lb->ips_v6);
free(lb->selection_fields);
- bitmap_free(lb->nb_lr_map);
- bitmap_free(lb->nb_ls_map);
free(lb);
}
@@ -727,8 +761,7 @@ ovn_northd_lb_destroy(struct ovn_northd_lb *lb)
* with ovn_lb_group_add_ls() and ovn_lb_group_add_lr() respectively. */
struct ovn_lb_group *
ovn_lb_group_create(const struct nbrec_load_balancer_group *nbrec_lb_group,
- const struct hmap *lbs, size_t max_ls_datapaths,
- size_t max_lr_datapaths)
+ const struct hmap *lbs)
{
struct ovn_lb_group *lb_group;
@@ -736,8 +769,6 @@ ovn_lb_group_create(const struct nbrec_load_balancer_group *nbrec_lb_group,
lb_group->uuid = nbrec_lb_group->header_.uuid;
lb_group->n_lbs = nbrec_lb_group->n_load_balancer;
lb_group->lbs = xmalloc(lb_group->n_lbs * sizeof *lb_group->lbs);
- lb_group->ls = xmalloc(max_ls_datapaths * sizeof *lb_group->ls);
- lb_group->lr = xmalloc(max_lr_datapaths * sizeof *lb_group->lr);
lb_group->lb_ips = ovn_lb_ip_set_create();
for (size_t i = 0; i < nbrec_lb_group->n_load_balancer; i++) {
@@ -758,8 +789,6 @@ ovn_lb_group_destroy(struct ovn_lb_group *lb_group)
ovn_lb_ip_set_destroy(lb_group->lb_ips);
free(lb_group->lbs);
- free(lb_group->ls);
- free(lb_group->lr);
free(lb_group);
}
@@ -943,3 +972,113 @@ ovn_lb_5tuples_destroy(struct hmap *tuples)
hmap_destroy(tuples);
}
+
+void
+build_lrouter_lb_ips(struct ovn_lb_ip_set *lb_ips,
+ const struct ovn_northd_lb *lb)
+{
+ const char *ip_address;
+
+ SSET_FOR_EACH (ip_address, &lb->ips_v4) {
+ sset_add(&lb_ips->ips_v4, ip_address);
+ if (lb->routable) {
+ sset_add(&lb_ips->ips_v4_routable, ip_address);
+ }
+ }
+ SSET_FOR_EACH (ip_address, &lb->ips_v6) {
+ sset_add(&lb_ips->ips_v6, ip_address);
+ if (lb->routable) {
+ sset_add(&lb_ips->ips_v6_routable, ip_address);
+ }
+ }
+}
+
+/* lb datapaths functions */
+struct ovn_lb_datapaths *
+ovn_lb_datapaths_create(const struct ovn_northd_lb *lb, size_t n_ls_datapaths,
+ size_t n_lr_datapaths)
+{
+ struct ovn_lb_datapaths *lb_dps = xzalloc(sizeof *lb_dps);
+ lb_dps->lb = lb;
+ lb_dps->nb_ls_map = bitmap_allocate(n_ls_datapaths);
+ lb_dps->nb_lr_map = bitmap_allocate(n_lr_datapaths);
+
+ return lb_dps;
+}
+
+struct ovn_lb_datapaths *
+ovn_lb_datapaths_find(const struct hmap *lb_dps_map,
+ const struct uuid *lb_uuid)
+{
+ struct ovn_lb_datapaths *lb_dps;
+ size_t hash = uuid_hash(lb_uuid);
+ HMAP_FOR_EACH_WITH_HASH (lb_dps, hmap_node, hash, lb_dps_map) {
+ if (uuid_equals(&lb_dps->lb->nlb->header_.uuid, lb_uuid)) {
+ return lb_dps;
+ }
+ }
+ return NULL;
+}
+
+void
+ovn_lb_datapaths_destroy(struct ovn_lb_datapaths *lb_dps)
+{
+ bitmap_free(lb_dps->nb_lr_map);
+ bitmap_free(lb_dps->nb_ls_map);
+ free(lb_dps);
+}
+
+void
+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);
+ }
+}
+
+void
+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);
+ }
+}
+
+struct ovn_lb_group_datapaths *
+ovn_lb_group_datapaths_create(const struct ovn_lb_group *lb_group,
+ size_t max_ls_datapaths,
+ size_t max_lr_datapaths)
+{
+ struct ovn_lb_group_datapaths *lb_group_dps =
+ xzalloc(sizeof *lb_group_dps);
+ lb_group_dps->lb_group = lb_group;
+ lb_group_dps->ls = xmalloc(max_ls_datapaths * sizeof *lb_group_dps->ls);
+ lb_group_dps->lr = xmalloc(max_lr_datapaths * sizeof *lb_group_dps->lr);
+
+ return lb_group_dps;
+}
+
+void
+ovn_lb_group_datapaths_destroy(struct ovn_lb_group_datapaths *lb_group_dps)
+{
+ free(lb_group_dps->ls);
+ free(lb_group_dps->lr);
+ free(lb_group_dps);
+}
+
+struct ovn_lb_group_datapaths *
+ovn_lb_group_datapaths_find(const struct hmap *lb_group_dps_map,
+ const struct uuid *lb_group_uuid)
+{
+ struct ovn_lb_group_datapaths *lb_group_dps;
+ size_t hash = uuid_hash(lb_group_uuid);
+
+ HMAP_FOR_EACH_WITH_HASH (lb_group_dps, hmap_node, hash, lb_group_dps_map) {
+ if (uuid_equals(&lb_group_dps->lb_group->uuid, lb_group_uuid)) {
+ return lb_group_dps;
+ }
+ }
+ return NULL;
+}
@@ -59,7 +59,6 @@ struct ovn_northd_lb {
struct hmap_node hmap_node;
const struct nbrec_load_balancer *nlb; /* May be NULL. */
- const struct sbrec_load_balancer *slb; /* May be NULL. */
const char *proto;
char *selection_fields;
struct ovn_lb_vip *vips;
@@ -78,14 +77,6 @@ struct ovn_northd_lb {
struct sset ips_v4;
struct sset ips_v6;
-
- size_t n_nb_ls;
- unsigned long *nb_ls_map;
-
- size_t n_nb_lr;
- unsigned long *nb_lr_map;
-
- struct ovn_dp_group *dpg;
};
struct ovn_lb_vip {
@@ -129,23 +120,19 @@ struct ovn_northd_lb_vip {
};
struct ovn_northd_lb_backend {
- struct ovn_port *op; /* Logical port to which the ip belong to. */
bool health_check;
+ char *logical_port; /* Logical port to which the ip belong to. */
char *svc_mon_src_ip; /* Source IP to use for monitoring. */
- const struct sbrec_service_monitor *sbrec_monitor;
};
-struct ovn_northd_lb *ovn_northd_lb_create(const struct nbrec_load_balancer *,
- size_t n_ls_datapaths,
- size_t n_lr_datapaths);
+struct ovn_northd_lb *ovn_northd_lb_create(const struct nbrec_load_balancer *);
struct ovn_northd_lb *ovn_northd_lb_find(const struct hmap *,
const struct uuid *);
const struct smap *ovn_northd_lb_get_vips(const struct ovn_northd_lb *);
void ovn_northd_lb_destroy(struct ovn_northd_lb *);
-void ovn_northd_lb_add_lr(struct ovn_northd_lb *lb, size_t n,
- struct ovn_datapath **ods);
-void ovn_northd_lb_add_ls(struct ovn_northd_lb *lb, size_t n,
- struct ovn_datapath **ods);
+
+void build_lrouter_lb_ips(struct ovn_lb_ip_set *,
+ const struct ovn_northd_lb *);
struct ovn_lb_group {
struct hmap_node hmap_node;
@@ -153,35 +140,70 @@ struct ovn_lb_group {
size_t n_lbs;
struct ovn_northd_lb **lbs;
struct ovn_lb_ip_set *lb_ips;
+};
+
+struct ovn_lb_group *ovn_lb_group_create(
+ const struct nbrec_load_balancer_group *,
+ const struct hmap *lbs);
+void ovn_lb_group_destroy(struct ovn_lb_group *lb_group);
+struct ovn_lb_group *ovn_lb_group_find(const struct hmap *lb_groups,
+ const struct uuid *);
+
+struct ovn_lb_datapaths {
+ struct hmap_node hmap_node;
- /* Datapaths to which this LB group is applied. */
+ const struct ovn_northd_lb *lb;
+ size_t n_nb_ls;
+ unsigned long *nb_ls_map;
+
+ size_t n_nb_lr;
+ unsigned long *nb_lr_map;
+};
+
+struct ovn_lb_datapaths *ovn_lb_datapaths_create(const struct ovn_northd_lb *,
+ size_t n_ls_datapaths,
+ size_t n_lr_datapaths);
+struct ovn_lb_datapaths *ovn_lb_datapaths_find(const struct hmap *,
+ const struct uuid *);
+void ovn_lb_datapaths_destroy(struct ovn_lb_datapaths *);
+void ovn_lb_datapaths_add_lr(struct ovn_lb_datapaths *, size_t n,
+ struct ovn_datapath **);
+void ovn_lb_datapaths_add_ls(struct ovn_lb_datapaths *, size_t n,
+ struct ovn_datapath **);
+
+struct ovn_lb_group_datapaths {
+ struct hmap_node hmap_node;
+
+ const struct ovn_lb_group *lb_group;
+
+ /* Datapaths to which 'lb_group' is applied. */
size_t n_ls;
struct ovn_datapath **ls;
size_t n_lr;
struct ovn_datapath **lr;
};
-struct ovn_lb_group *ovn_lb_group_create(
- const struct nbrec_load_balancer_group *,
- const struct hmap *lbs,
- size_t max_ls_datapaths,
+struct ovn_lb_group_datapaths *ovn_lb_group_datapaths_create(
+ const struct ovn_lb_group *, size_t max_ls_datapaths,
size_t max_lr_datapaths);
-void ovn_lb_group_destroy(struct ovn_lb_group *lb_group);
-struct ovn_lb_group *ovn_lb_group_find(const struct hmap *lb_groups,
- const struct uuid *);
+
+void ovn_lb_group_datapaths_destroy(struct ovn_lb_group_datapaths *);
+struct ovn_lb_group_datapaths *ovn_lb_group_datapaths_find(
+ const struct hmap *lb_group_dps, const struct uuid *);
static inline void
-ovn_lb_group_add_ls(struct ovn_lb_group *lb_group, size_t n,
- struct ovn_datapath **ods)
+ovn_lb_group_datapaths_add_ls(struct ovn_lb_group_datapaths *lbg_dps, size_t n,
+ struct ovn_datapath **ods)
{
- memcpy(&lb_group->ls[lb_group->n_ls], ods, n * sizeof *ods);
- lb_group->n_ls += n;
+ memcpy(&lbg_dps->ls[lbg_dps->n_ls], ods, n * sizeof *ods);
+ lbg_dps->n_ls += n;
}
static inline void
-ovn_lb_group_add_lr(struct ovn_lb_group *lb_group, struct ovn_datapath *lr)
+ovn_lb_group_datapaths_add_lr(struct ovn_lb_group_datapaths *lbg_dps,
+ struct ovn_datapath *lr)
{
- lb_group->lr[lb_group->n_lr++] = lr;
+ lbg_dps->lr[lbg_dps->n_lr++] = lr;
}
struct ovn_controller_lb {
@@ -18,6 +18,8 @@ northd_ovn_northd_SOURCES = \
northd/en-sync-sb.h \
northd/en-sync-from-sb.c \
northd/en-sync-from-sb.h \
+ northd/en-northd-lb-data.c \
+ northd/en-northd-lb-data.h \
northd/inc-proc-northd.c \
northd/inc-proc-northd.h \
northd/ipam.c \
@@ -57,7 +57,8 @@ lflow_get_input_data(struct engine_node *node,
lflow_input->lr_ports = &northd_data->lr_ports;
lflow_input->port_groups = &northd_data->port_groups;
lflow_input->meter_groups = &northd_data->meter_groups;
- lflow_input->lbs = &northd_data->lbs;
+ lflow_input->lb_datapaths_map = &northd_data->lb_datapaths_map;
+ lflow_input->svc_monitor_map = &northd_data->svc_monitor_map;
lflow_input->features = &northd_data->features;
lflow_input->ovn_internal_version_changed =
northd_data->ovn_internal_version_changed;
new file mode 100644
@@ -0,0 +1,126 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+
+#include <getopt.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "openvswitch/util.h"
+
+#include "en-northd-lb-data.h"
+#include "lib/inc-proc-eng.h"
+#include "lib/lb.h"
+#include "lib/ovn-nb-idl.h"
+#include "lib/ovn-sb-idl.h"
+#include "lib/ovn-util.h"
+#include "northd.h"
+
+#include "openvswitch/vlog.h"
+
+VLOG_DEFINE_THIS_MODULE(en_northd_lb_data);
+
+static void northd_lb_data_init(struct northd_lb_data *);
+static void northd_lb_data_destroy(struct northd_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);
+
+void *
+en_northd_lb_data_init(struct engine_node *node OVS_UNUSED,
+ struct engine_arg *arg OVS_UNUSED)
+{
+ struct northd_lb_data *data = xzalloc(sizeof *data);
+
+ northd_lb_data_init(data);
+
+ return data;
+}
+
+void
+en_northd_lb_data_run(struct engine_node *node, void *data)
+{
+ struct northd_lb_data *lb_data = (struct northd_lb_data *) data;
+ northd_lb_data_destroy(lb_data);
+ northd_lb_data_init(lb_data);
+
+ const struct nbrec_load_balancer_table *nb_lb_table =
+ 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));
+
+ build_lbs(nb_lb_table, nb_lbg_table, &lb_data->lbs, &lb_data->lb_groups);
+ engine_set_node_state(node, EN_UPDATED);
+}
+
+void
+en_northd_lb_data_cleanup(void *data)
+{
+ struct northd_lb_data *lb_data = (struct northd_lb_data *) data;
+ northd_lb_data_destroy(lb_data);
+}
+
+/* static functions. */
+static void
+northd_lb_data_init(struct northd_lb_data *lb_data)
+{
+ hmap_init(&lb_data->lbs);
+ hmap_init(&lb_data->lb_groups);
+}
+
+static void
+northd_lb_data_destroy(struct northd_lb_data *lb_data)
+{
+ struct ovn_northd_lb *lb;
+ HMAP_FOR_EACH_POP (lb, hmap_node, &lb_data->lbs) {
+ ovn_northd_lb_destroy(lb);
+ }
+ hmap_destroy(&lb_data->lbs);
+
+ struct ovn_lb_group *lb_group;
+ HMAP_FOR_EACH_POP (lb_group, hmap_node, &lb_data->lb_groups) {
+ ovn_lb_group_destroy(lb_group);
+ }
+ hmap_destroy(&lb_data->lb_groups);
+}
+
+static void
+build_lbs(const struct nbrec_load_balancer_table *nbrec_load_balancer_table,
+ const struct nbrec_load_balancer_group_table *nbrec_lb_group_table,
+ struct hmap *lbs, struct hmap *lb_groups)
+{
+ struct ovn_lb_group *lb_group;
+ struct ovn_northd_lb *lb_nb;
+
+ const struct nbrec_load_balancer *nbrec_lb;
+ NBREC_LOAD_BALANCER_TABLE_FOR_EACH (nbrec_lb, nbrec_load_balancer_table) {
+ lb_nb = ovn_northd_lb_create(nbrec_lb);
+ hmap_insert(lbs, &lb_nb->hmap_node,
+ uuid_hash(&nbrec_lb->header_.uuid));
+ }
+
+ const struct nbrec_load_balancer_group *nbrec_lb_group;
+ NBREC_LOAD_BALANCER_GROUP_TABLE_FOR_EACH (nbrec_lb_group,
+ nbrec_lb_group_table) {
+ lb_group = ovn_lb_group_create(nbrec_lb_group, lbs);
+
+ for (size_t i = 0; i < lb_group->n_lbs; i++) {
+ build_lrouter_lb_ips(lb_group->lb_ips, lb_group->lbs[i]);
+ }
+
+ hmap_insert(lb_groups, &lb_group->hmap_node,
+ uuid_hash(&lb_group->uuid));
+ }
+}
new file mode 100644
@@ -0,0 +1,19 @@
+#ifndef EN_NORTHD_LB_DATA_H
+#define EN_NORTHD_LB_DATA_H 1
+
+#include <config.h>
+
+#include "openvswitch/hmap.h"
+
+#include "lib/inc-proc-eng.h"
+
+struct northd_lb_data {
+ struct hmap lbs;
+ struct hmap lb_groups;
+};
+
+void *en_northd_lb_data_init(struct engine_node *, struct engine_arg *);
+void en_northd_lb_data_run(struct engine_node *, void *data);
+void en_northd_lb_data_cleanup(void *data);
+
+#endif /* end of EN_NORTHD_LB_DATA_H */
@@ -20,6 +20,7 @@
#include "coverage.h"
#include "en-northd.h"
+#include "en-northd-lb-data.h"
#include "lib/inc-proc-eng.h"
#include "lib/ovn-nb-idl.h"
#include "openvswitch/list.h" /* TODO This is needed for ovn-parallel-hmap.h.
@@ -70,10 +71,6 @@ northd_get_input_data(struct engine_node *node,
EN_OVSDB_GET(engine_get_input("NB_logical_switch", node));
input_data->nbrec_logical_router_table =
EN_OVSDB_GET(engine_get_input("NB_logical_router", node));
- input_data->nbrec_load_balancer_table =
- EN_OVSDB_GET(engine_get_input("NB_load_balancer", node));
- input_data->nbrec_load_balancer_group_table =
- EN_OVSDB_GET(engine_get_input("NB_load_balancer_group", node));
input_data->nbrec_port_group_table =
EN_OVSDB_GET(engine_get_input("NB_port_group", node));
input_data->nbrec_meter_table =
@@ -117,6 +114,11 @@ northd_get_input_data(struct engine_node *node,
EN_OVSDB_GET(engine_get_input("SB_chassis_template_var", node));
input_data->sbrec_mirror_table =
EN_OVSDB_GET(engine_get_input("SB_mirror", node));
+
+ struct northd_lb_data *lb_data =
+ engine_get_input_data("northd_lb_data", node);
+ input_data->lbs = &lb_data->lbs;
+ input_data->lb_groups = &lb_data->lb_groups;
}
void
@@ -130,6 +132,7 @@ en_northd_run(struct engine_node *node, void *data)
northd_init(data);
northd_get_input_data(node, &input_data);
+
COVERAGE_INC(northd_run);
stopwatch_start(OVNNB_DB_RUN_STOPWATCH_NAME, time_msec());
ovnnb_db_run(&input_data, data, eng_ctx->ovnnb_idl_txn,
@@ -230,7 +230,7 @@ en_sync_to_sb_lb_run(struct engine_node *node, void *data OVS_UNUSED)
struct northd_data *northd_data = engine_get_input_data("northd", node);
sync_lbs(eng_ctx->ovnsb_idl_txn, sb_load_balancer_table,
- &northd_data->ls_datapaths, &northd_data->lbs);
+ &northd_data->ls_datapaths, &northd_data->lb_datapaths_map);
engine_set_node_state(node, EN_UPDATED);
}
@@ -35,6 +35,7 @@
#include "en-northd-output.h"
#include "en-sync-sb.h"
#include "en-sync-from-sb.h"
+#include "en-northd-lb-data.h"
#include "unixctl.h"
#include "util.h"
@@ -140,6 +141,7 @@ static ENGINE_NODE(sync_to_sb_addr_set, "sync_to_sb_addr_set");
static ENGINE_NODE(fdb_aging, "fdb_aging");
static ENGINE_NODE(fdb_aging_waker, "fdb_aging_waker");
static ENGINE_NODE(sync_to_sb_lb, "sync_to_sb_lb");
+static ENGINE_NODE(northd_lb_data, "northd_lb_data");
void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
struct ovsdb_idl_loop *sb)
@@ -147,8 +149,6 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
/* Define relationships between nodes where first argument is dependent
* on the second argument */
engine_add_input(&en_northd, &en_nb_port_group, NULL);
- engine_add_input(&en_northd, &en_nb_load_balancer, NULL);
- engine_add_input(&en_northd, &en_nb_load_balancer_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);
@@ -178,6 +178,10 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
engine_add_input(&en_northd, &en_nb_logical_switch,
northd_nb_logical_switch_handler);
+ engine_add_input(&en_northd_lb_data, &en_nb_load_balancer, NULL);
+ engine_add_input(&en_northd_lb_data, &en_nb_load_balancer_group, NULL);
+ engine_add_input(&en_northd, &en_northd_lb_data, NULL);
+
engine_add_input(&en_mac_binding_aging, &en_nb_nb_global, NULL);
engine_add_input(&en_mac_binding_aging, &en_sb_mac_binding, NULL);
engine_add_input(&en_mac_binding_aging, &en_northd, NULL);
@@ -3818,14 +3818,11 @@ struct service_monitor_info {
static struct service_monitor_info *
-create_or_get_service_mon(struct ovsdb_idl_txn *ovnsb_txn,
- struct hmap *monitor_map,
- const char *ip, const char *logical_port,
- uint16_t service_port, const char *protocol)
+get_service_mon(const struct hmap *monitor_map,
+ const char *ip, const char *logical_port,
+ uint16_t service_port, const char *protocol,
+ uint32_t hash)
{
- uint32_t hash = service_port;
- hash = hash_string(ip, hash);
- hash = hash_string(logical_port, hash);
struct service_monitor_info *mon_info;
HMAP_FOR_EACH_WITH_HASH (mon_info, hmap_node, hash, monitor_map) {
@@ -3837,6 +3834,26 @@ create_or_get_service_mon(struct ovsdb_idl_txn *ovnsb_txn,
}
}
+ return NULL;
+}
+
+static struct service_monitor_info *
+create_or_get_service_mon(struct ovsdb_idl_txn *ovnsb_txn,
+ struct hmap *monitor_map,
+ const char *ip, const char *logical_port,
+ uint16_t service_port, const char *protocol)
+{
+ uint32_t hash = service_port;
+ hash = hash_string(ip, hash);
+ hash = hash_string(logical_port, hash);
+ struct service_monitor_info *mon_info =
+ get_service_mon(monitor_map, ip, logical_port, service_port,
+ protocol, hash);
+
+ if (mon_info) {
+ return mon_info;
+ }
+
struct sbrec_service_monitor *sbrec_mon =
sbrec_service_monitor_insert(ovnsb_txn);
sbrec_service_monitor_set_ip(sbrec_mon, ip);
@@ -3850,7 +3867,8 @@ create_or_get_service_mon(struct ovsdb_idl_txn *ovnsb_txn,
}
static void
-ovn_lb_svc_create(struct ovsdb_idl_txn *ovnsb_txn, struct ovn_northd_lb *lb,
+ovn_lb_svc_create(struct ovsdb_idl_txn *ovnsb_txn,
+ const struct ovn_northd_lb *lb,
struct hmap *monitor_map, struct hmap *ls_ports,
struct sset *svc_monitor_lsps)
{
@@ -3867,58 +3885,27 @@ ovn_lb_svc_create(struct ovsdb_idl_txn *ovnsb_txn, struct ovn_northd_lb *lb,
struct ovn_northd_lb_backend *backend_nb =
&lb_vip_nb->backends_nb[j];
- struct ovn_port *op = NULL;
- char *svc_mon_src_ip = NULL;
-
- struct ds key = DS_EMPTY_INITIALIZER;
- ds_put_format(&key,
- IN6_IS_ADDR_V4MAPPED(&lb_vip->vip)
- ? "%s" : "[%s]", backend->ip_str);
-
- const char *s = smap_get(&lb->nlb->ip_port_mappings,
- ds_cstr(&key));
- if (s) {
- char *port_name = xstrdup(s);
- char *p = strstr(port_name, ":");
- if (p) {
- *p = 0;
- p++;
- sset_add(svc_monitor_lsps, port_name);
- op = ovn_port_find(ls_ports, port_name);
- struct sockaddr_storage svc_mon_src_addr;
- if (!inet_parse_address(p, &svc_mon_src_addr)) {
- static struct vlog_rate_limit rl =
- VLOG_RATE_LIMIT_INIT(5, 1);
- VLOG_WARN_RL(&rl, "Invalid svc mon src IP %s", p);
- } else {
- struct ds src_ip_s = DS_EMPTY_INITIALIZER;
- ss_format_address_nobracks(&svc_mon_src_addr,
- &src_ip_s);
- svc_mon_src_ip = ds_steal_cstr(&src_ip_s);
- }
- }
- free(port_name);
+ if (!backend_nb->health_check) {
+ continue;
}
- ds_destroy(&key);
- if (!lb_vip_nb->lb_health_check || !op || !svc_mon_src_ip ||
- !lsp_is_enabled(op->nbsp)) {
- free(svc_mon_src_ip);
+ sset_add(svc_monitor_lsps, backend_nb->logical_port);
+ struct ovn_port *op = ovn_port_find(ls_ports,
+ backend_nb->logical_port);
+
+ if (!op || !lsp_is_enabled(op->nbsp)) {
continue;
}
- backend_nb->op = op;
- backend_nb->svc_mon_src_ip = svc_mon_src_ip;
-
const char *protocol = lb->nlb->protocol;
if (!protocol || !protocol[0]) {
protocol = "tcp";
}
- backend_nb->health_check = true;
+
struct service_monitor_info *mon_info =
create_or_get_service_mon(ovnsb_txn, monitor_map,
backend->ip_str,
- backend_nb->op->nbsp->name,
+ backend_nb->logical_port,
backend->port,
protocol);
ovs_assert(mon_info);
@@ -3947,18 +3934,20 @@ ovn_lb_svc_create(struct ovsdb_idl_txn *ovnsb_txn, struct ovn_northd_lb *lb,
"offline");
}
- backend_nb->sbrec_monitor = mon_info->sbrec_mon;
mon_info->required = true;
}
}
}
static bool
-build_lb_vip_actions(struct ovn_lb_vip *lb_vip,
- struct ovn_northd_lb_vip *lb_vip_nb,
+build_lb_vip_actions(const struct ovn_northd_lb *lb,
+ const struct ovn_lb_vip *lb_vip,
+ const struct ovn_northd_lb_vip *lb_vip_nb,
struct ds *action, char *selection_fields,
- struct ds *skip_snat_action, struct ds *force_snat_action,
- bool ls_dp, const struct chassis_features *features)
+ struct ds *skip_snat_action,
+ struct ds *force_snat_action,
+ bool ls_dp, const struct chassis_features *features,
+ const struct hmap *svc_monitor_map)
{
const char *ct_lb_action =
features->ct_no_masked_label ? "ct_lb_mark" : "ct_lb";
@@ -3973,10 +3962,31 @@ build_lb_vip_actions(struct ovn_lb_vip *lb_vip,
struct ovn_lb_backend *backend = &lb_vip->backends[i];
struct ovn_northd_lb_backend *backend_nb =
&lb_vip_nb->backends_nb[i];
- if (!backend_nb->health_check ||
- (backend_nb->health_check && backend_nb->sbrec_monitor &&
- backend_nb->sbrec_monitor->status &&
- strcmp(backend_nb->sbrec_monitor->status, "online"))) {
+
+ if (!backend_nb->health_check) {
+ continue;
+ }
+
+ const char *protocol = lb->nlb->protocol;
+ if (!protocol || !protocol[0]) {
+ protocol = "tcp";
+ }
+
+ uint32_t hash = backend->port;
+ hash = hash_string(backend->ip_str, hash);
+ hash = hash_string(backend_nb->logical_port, hash);
+
+ struct service_monitor_info *mon_info = get_service_mon(
+ svc_monitor_map, backend->ip_str, backend_nb->logical_port,
+ backend->port, protocol, hash);
+
+ if (!mon_info) {
+ continue;
+ }
+
+ ovs_assert(mon_info->sbrec_mon);
+ if (mon_info->sbrec_mon->status &&
+ strcmp(mon_info->sbrec_mon->status, "online")) {
continue;
}
@@ -4026,59 +4036,32 @@ build_lb_vip_actions(struct ovn_lb_vip *lb_vip,
}
static void
-build_lrouter_lb_ips(struct ovn_lb_ip_set *lb_ips,
- const struct ovn_northd_lb *lb)
-{
- const char *ip_address;
-
- SSET_FOR_EACH (ip_address, &lb->ips_v4) {
- sset_add(&lb_ips->ips_v4, ip_address);
- if (lb->routable) {
- sset_add(&lb_ips->ips_v4_routable, ip_address);
- }
- }
- SSET_FOR_EACH (ip_address, &lb->ips_v6) {
- sset_add(&lb_ips->ips_v6, ip_address);
- if (lb->routable) {
- sset_add(&lb_ips->ips_v6_routable, ip_address);
- }
- }
-}
-
-static void
-build_lbs(const struct nbrec_load_balancer_table *nbrec_load_balancer_table,
- const struct nbrec_load_balancer_group_table *nbrec_lb_group_table,
- struct ovn_datapaths *ls_datapaths,
- struct ovn_datapaths *lr_datapaths,
- struct hmap *lbs, struct hmap *lb_groups)
+build_lb_datapaths(const struct hmap *lbs, const struct hmap *lb_groups,
+ struct ovn_datapaths *ls_datapaths,
+ struct ovn_datapaths *lr_datapaths,
+ struct hmap *lb_datapaths_map,
+ struct hmap *lb_group_datapaths_map)
{
const struct nbrec_load_balancer_group *nbrec_lb_group;
- struct ovn_lb_group *lb_group;
- struct ovn_northd_lb *lb;
+ struct ovn_lb_group_datapaths *lb_group_dps;
+ const struct ovn_lb_group *lb_group;
+ struct ovn_lb_datapaths *lb_dps;
+ const struct ovn_northd_lb *lb;
- hmap_init(lbs);
- hmap_init(lb_groups);
+ hmap_init(lb_datapaths_map);
+ hmap_init(lb_group_datapaths_map);
- const struct nbrec_load_balancer *nbrec_lb;
- NBREC_LOAD_BALANCER_TABLE_FOR_EACH (nbrec_lb, nbrec_load_balancer_table) {
- struct ovn_northd_lb *lb_nb = ovn_northd_lb_create(nbrec_lb,
- ods_size(ls_datapaths),
- ods_size(lr_datapaths));
- hmap_insert(lbs, &lb_nb->hmap_node,
- uuid_hash(&nbrec_lb->header_.uuid));
+ HMAP_FOR_EACH (lb, hmap_node, lbs) {
+ lb_dps = ovn_lb_datapaths_create(lb, ods_size(ls_datapaths),
+ ods_size(lr_datapaths));
+ hmap_insert(lb_datapaths_map, &lb_dps->hmap_node,
+ uuid_hash(&lb->nlb->header_.uuid));
}
- NBREC_LOAD_BALANCER_GROUP_TABLE_FOR_EACH (nbrec_lb_group,
- nbrec_lb_group_table) {
- lb_group = ovn_lb_group_create(nbrec_lb_group, lbs,
- ods_size(ls_datapaths),
- ods_size(lr_datapaths));
-
- for (size_t i = 0; i < lb_group->n_lbs; i++) {
- build_lrouter_lb_ips(lb_group->lb_ips, lb_group->lbs[i]);
- }
-
- hmap_insert(lb_groups, &lb_group->hmap_node,
+ HMAP_FOR_EACH (lb_group, hmap_node, lb_groups) {
+ lb_group_dps = ovn_lb_group_datapaths_create(
+ lb_group, ods_size(ls_datapaths), ods_size(lr_datapaths));
+ hmap_insert(lb_group_datapaths_map, &lb_group_dps->hmap_node,
uuid_hash(&lb_group->uuid));
}
@@ -4091,22 +4074,19 @@ build_lbs(const struct nbrec_load_balancer_table *nbrec_load_balancer_table,
for (size_t i = 0; i < od->nbs->n_load_balancer; i++) {
const struct uuid *lb_uuid =
&od->nbs->load_balancer[i]->header_.uuid;
- lb = ovn_northd_lb_find(lbs, lb_uuid);
- ovn_northd_lb_add_ls(lb, 1, &od);
+ lb_dps = ovn_lb_datapaths_find(lb_datapaths_map, lb_uuid);
+ ovs_assert(lb_dps);
+ ovn_lb_datapaths_add_ls(lb_dps, 1, &od);
}
for (size_t i = 0; i < od->nbs->n_load_balancer_group; i++) {
nbrec_lb_group = od->nbs->load_balancer_group[i];
- lb_group = ovn_lb_group_find(lb_groups,
- &nbrec_lb_group->header_.uuid);
- ovn_lb_group_add_ls(lb_group, 1, &od);
- }
- }
-
- HMAP_FOR_EACH (lb_group, hmap_node, lb_groups) {
- for (size_t j = 0; j < lb_group->n_lbs; j++) {
- ovn_northd_lb_add_ls(lb_group->lbs[j], lb_group->n_ls,
- lb_group->ls);
+ const struct uuid *lb_group_uuid = &nbrec_lb_group->header_.uuid;
+ lb_group_dps =
+ ovn_lb_group_datapaths_find(lb_group_datapaths_map,
+ lb_group_uuid);
+ ovs_assert(lb_group_dps);
+ ovn_lb_group_datapaths_add_ls(lb_group_dps, 1, &od);
}
}
@@ -4128,15 +4108,21 @@ build_lbs(const struct nbrec_load_balancer_table *nbrec_load_balancer_table,
size_t idx = (i + largest_group) % od->nbr->n_load_balancer_group;
nbrec_lb_group = od->nbr->load_balancer_group[idx];
- lb_group = ovn_lb_group_find(lb_groups,
- &nbrec_lb_group->header_.uuid);
- ovn_lb_group_add_lr(lb_group, od);
+ const struct uuid *lb_group_uuid = &nbrec_lb_group->header_.uuid;
+
+ lb_group_dps =
+ ovn_lb_group_datapaths_find(lb_group_datapaths_map,
+ lb_group_uuid);
+ ovs_assert(lb_group_dps);
+ ovn_lb_group_datapaths_add_lr(lb_group_dps, od);
if (!od->lb_ips) {
- od->lb_ips = ovn_lb_ip_set_clone(lb_group->lb_ips);
+ od->lb_ips =
+ ovn_lb_ip_set_clone(lb_group_dps->lb_group->lb_ips);
} else {
- for (size_t j = 0; j < lb_group->n_lbs; j++) {
- build_lrouter_lb_ips(od->lb_ips, lb_group->lbs[j]);
+ for (size_t j = 0; j < lb_group_dps->lb_group->n_lbs; j++) {
+ build_lrouter_lb_ips(od->lb_ips,
+ lb_group_dps->lb_group->lbs[j]);
}
}
}
@@ -4148,16 +4134,23 @@ build_lbs(const struct nbrec_load_balancer_table *nbrec_load_balancer_table,
for (size_t i = 0; i < od->nbr->n_load_balancer; i++) {
const struct uuid *lb_uuid =
&od->nbr->load_balancer[i]->header_.uuid;
- lb = ovn_northd_lb_find(lbs, lb_uuid);
- ovn_northd_lb_add_lr(lb, 1, &od);
- build_lrouter_lb_ips(od->lb_ips, lb);
+ lb_dps = ovn_lb_datapaths_find(lb_datapaths_map, lb_uuid);
+ ovs_assert(lb_dps);
+ ovn_lb_datapaths_add_lr(lb_dps, 1, &od);
+ build_lrouter_lb_ips(od->lb_ips, lb_dps->lb);
}
}
- HMAP_FOR_EACH (lb_group, hmap_node, lb_groups) {
- for (size_t j = 0; j < lb_group->n_lbs; j++) {
- ovn_northd_lb_add_lr(lb_group->lbs[j], lb_group->n_lr,
- lb_group->lr);
+ HMAP_FOR_EACH (lb_group_dps, hmap_node, lb_group_datapaths_map) {
+ for (size_t j = 0; j < lb_group_dps->lb_group->n_lbs; j++) {
+ const struct uuid *lb_uuid =
+ &lb_group_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_ls(lb_dps, lb_group_dps->n_ls,
+ lb_group_dps->ls);
+ ovn_lb_datapaths_add_lr(lb_dps, lb_group_dps->n_lr,
+ lb_group_dps->lr);
}
}
}
@@ -4166,10 +4159,10 @@ static void
build_lb_svcs(
struct ovsdb_idl_txn *ovnsb_txn,
const struct sbrec_service_monitor_table *sbrec_service_monitor_table,
- struct hmap *ls_ports, struct hmap *lbs, struct sset *svc_monitor_lsps)
+ struct hmap *ls_ports, struct hmap *lb_dps_map,
+ struct sset *svc_monitor_lsps,
+ struct hmap *svc_monitor_map)
{
- struct hmap monitor_map = HMAP_INITIALIZER(&monitor_map);
-
const struct sbrec_service_monitor *sbrec_mon;
SBREC_SERVICE_MONITOR_TABLE_FOR_EACH (sbrec_mon,
sbrec_service_monitor_table) {
@@ -4179,24 +4172,23 @@ build_lb_svcs(
struct service_monitor_info *mon_info = xzalloc(sizeof *mon_info);
mon_info->sbrec_mon = sbrec_mon;
mon_info->required = false;
- hmap_insert(&monitor_map, &mon_info->hmap_node, hash);
+ hmap_insert(svc_monitor_map, &mon_info->hmap_node, hash);
}
- struct ovn_northd_lb *lb;
- HMAP_FOR_EACH (lb, hmap_node, lbs) {
- ovn_lb_svc_create(ovnsb_txn, lb, &monitor_map, ls_ports,
+ struct ovn_lb_datapaths *lb_dps;
+ HMAP_FOR_EACH (lb_dps, hmap_node, lb_dps_map) {
+ ovn_lb_svc_create(ovnsb_txn, lb_dps->lb, svc_monitor_map, ls_ports,
svc_monitor_lsps);
}
struct service_monitor_info *mon_info;
- HMAP_FOR_EACH_POP (mon_info, hmap_node, &monitor_map) {
+ HMAP_FOR_EACH_SAFE (mon_info, hmap_node, svc_monitor_map) {
if (!mon_info->required) {
sbrec_service_monitor_delete(mon_info->sbrec_mon);
+ hmap_remove(svc_monitor_map, &mon_info->hmap_node);
+ free(mon_info);
}
-
- free(mon_info);
}
- hmap_destroy(&monitor_map);
}
static bool lrouter_port_ipv4_reachable(const struct ovn_port *op,
@@ -4281,7 +4273,8 @@ build_lrouter_lbs_check(const struct ovn_datapaths *lr_datapaths)
static void
build_lrouter_lbs_reachable_ips(struct ovn_datapaths *lr_datapaths,
- struct hmap *lbs, struct hmap *lb_groups)
+ struct hmap *lb_dps_map,
+ struct hmap *lb_group_dps_map)
{
struct ovn_datapath *od;
@@ -4291,21 +4284,25 @@ build_lrouter_lbs_reachable_ips(struct ovn_datapaths *lr_datapaths,
}
for (size_t i = 0; i < od->nbr->n_load_balancer; i++) {
- struct ovn_northd_lb *lb =
- ovn_northd_lb_find(lbs,
- &od->nbr->load_balancer[i]->header_.uuid);
- build_lrouter_lb_reachable_ips(od, lb);
+ struct ovn_lb_datapaths *lb_dps =
+ ovn_lb_datapaths_find(lb_dps_map,
+ &od->nbr->load_balancer[i]->header_.uuid);
+ ovs_assert(lb_dps);
+ build_lrouter_lb_reachable_ips(od, lb_dps->lb);
}
for (size_t i = 0; i < od->nbr->n_load_balancer_group; i++) {
const struct nbrec_load_balancer_group *nbrec_lb_group =
od->nbr->load_balancer_group[i];
- struct ovn_lb_group *lb_group;
-
- lb_group = ovn_lb_group_find(lb_groups,
- &nbrec_lb_group->header_.uuid);
- for (size_t j = 0; j < lb_group->n_lbs; j++) {
- build_lrouter_lb_reachable_ips(od, lb_group->lbs[j]);
+ struct ovn_lb_group_datapaths *lb_group_dps;
+
+ lb_group_dps =
+ ovn_lb_group_datapaths_find(lb_group_dps_map,
+ &nbrec_lb_group->header_.uuid);
+ ovs_assert(lb_group_dps);
+ for (size_t j = 0; j < lb_group_dps->lb_group->n_lbs; j++) {
+ build_lrouter_lb_reachable_ips(od,
+ lb_group_dps->lb_group->lbs[j]);
}
}
}
@@ -4313,45 +4310,50 @@ build_lrouter_lbs_reachable_ips(struct ovn_datapaths *lr_datapaths,
static void
build_lswitch_lbs_from_lrouter(struct ovn_datapaths *lr_datapaths,
- struct hmap *lbs, struct hmap *lb_groups)
+ struct hmap *lb_dps_map,
+ struct hmap *lb_group_dps_map)
{
if (!install_ls_lb_from_router) {
return;
}
- struct ovn_northd_lb *lb;
+ struct ovn_lb_datapaths *lb_dps;
size_t index;
- HMAP_FOR_EACH (lb, hmap_node, lbs) {
- BITMAP_FOR_EACH_1 (index, ods_size(lr_datapaths), lb->nb_lr_map) {
+ HMAP_FOR_EACH (lb_dps, hmap_node, lb_dps_map) {
+ BITMAP_FOR_EACH_1 (index, ods_size(lr_datapaths), lb_dps->nb_lr_map) {
struct ovn_datapath *od = lr_datapaths->array[index];
- ovn_northd_lb_add_ls(lb, od->n_ls_peers, od->ls_peers);
- }
- }
-
- struct ovn_lb_group *lb_group;
- HMAP_FOR_EACH (lb_group, hmap_node, lb_groups) {
- for (size_t i = 0; i < lb_group->n_lr; i++) {
- struct ovn_datapath *od = lb_group->lr[i];
- ovn_lb_group_add_ls(lb_group, od->n_ls_peers, od->ls_peers);
- for (size_t j = 0; j < lb_group->n_lbs; j++) {
- ovn_northd_lb_add_ls(lb_group->lbs[j], od->n_ls_peers,
- od->ls_peers);
+ ovn_lb_datapaths_add_ls(lb_dps, od->n_ls_peers, od->ls_peers);
+ }
+ }
+
+ struct ovn_lb_group_datapaths *lb_group_dps;
+ HMAP_FOR_EACH (lb_group_dps, hmap_node, lb_group_dps_map) {
+ for (size_t i = 0; i < lb_group_dps->n_lr; i++) {
+ struct ovn_datapath *od = lb_group_dps->lr[i];
+ ovn_lb_group_datapaths_add_ls(lb_group_dps, od->n_ls_peers,
+ od->ls_peers);
+ for (size_t j = 0; j < lb_group_dps->lb_group->n_lbs; j++) {
+ const struct uuid *lb_uuid =
+ &lb_group_dps->lb_group->lbs[j]->nlb->header_.uuid;
+ lb_dps = ovn_lb_datapaths_find(lb_dps_map, lb_uuid);
+ ovs_assert(lb_dps);
+ ovn_lb_datapaths_add_ls(lb_dps, od->n_ls_peers, od->ls_peers);
}
}
}
}
static void
-build_lb_count_dps(struct hmap *lbs,
+build_lb_count_dps(struct hmap *lb_dps_map,
size_t n_ls_datapaths,
size_t n_lr_datapaths)
{
- struct ovn_northd_lb *lb;
+ struct ovn_lb_datapaths *lb_dps;
- HMAP_FOR_EACH (lb, hmap_node, lbs) {
- lb->n_nb_lr = bitmap_count1(lb->nb_lr_map, n_lr_datapaths);
- lb->n_nb_ls = bitmap_count1(lb->nb_ls_map, n_ls_datapaths);
+ HMAP_FOR_EACH (lb_dps, hmap_node, lb_dps_map) {
+ lb_dps->n_nb_lr = bitmap_count1(lb_dps->nb_lr_map, n_lr_datapaths);
+ lb_dps->n_nb_ls = bitmap_count1(lb_dps->nb_ls_map, n_ls_datapaths);
}
}
@@ -4364,13 +4366,16 @@ build_lb_port_related_data(
struct ovsdb_idl_txn *ovnsb_txn,
const struct sbrec_service_monitor_table *sbrec_service_monitor_table,
struct ovn_datapaths *lr_datapaths, struct hmap *ls_ports,
- struct hmap *lbs, struct hmap *lb_groups, struct sset *svc_monitor_lsps)
+ struct hmap *lb_dps_map, struct hmap *lb_group_dps_map,
+ struct sset *svc_monitor_lsps,
+ struct hmap *svc_monitor_map)
{
build_lrouter_lbs_check(lr_datapaths);
- build_lrouter_lbs_reachable_ips(lr_datapaths, lbs, lb_groups);
- build_lb_svcs(ovnsb_txn, sbrec_service_monitor_table, ls_ports, lbs,
- svc_monitor_lsps);
- build_lswitch_lbs_from_lrouter(lr_datapaths, lbs, lb_groups);
+ build_lrouter_lbs_reachable_ips(lr_datapaths, lb_dps_map,
+ lb_group_dps_map);
+ build_lb_svcs(ovnsb_txn, sbrec_service_monitor_table, ls_ports, lb_dps_map,
+ svc_monitor_lsps, svc_monitor_map);
+ build_lswitch_lbs_from_lrouter(lr_datapaths, lb_dps_map, lb_group_dps_map);
}
@@ -4491,17 +4496,39 @@ ovn_dp_group_get_or_create(struct ovsdb_idl_txn *ovnsb_txn,
return dpg;
}
+struct sb_lb {
+ struct hmap_node hmap_node;
+
+ const struct sbrec_load_balancer *slb;
+ struct ovn_dp_group *dpg;
+ struct uuid lb_uuid;
+};
+
+static struct sb_lb *
+find_slb_in_sb_lbs(struct hmap *sb_lbs, const struct uuid *lb_uuid)
+{
+ struct sb_lb *sb_lb;
+ HMAP_FOR_EACH_WITH_HASH (sb_lb, hmap_node, uuid_hash(lb_uuid), sb_lbs) {
+ if (uuid_equals(&sb_lb->lb_uuid, lb_uuid)) {
+ return sb_lb;
+ }
+ }
+
+ return NULL;
+}
+
/* Syncs relevant load balancers (applied to logical switches) to the
* Southbound database.
*/
void
sync_lbs(struct ovsdb_idl_txn *ovnsb_txn,
const struct sbrec_load_balancer_table *sbrec_load_balancer_table,
- struct ovn_datapaths *ls_datapaths, struct hmap *lbs)
+ struct ovn_datapaths *ls_datapaths, struct hmap *lb_dps_map)
{
struct hmap dp_groups = HMAP_INITIALIZER(&dp_groups);
size_t bitmap_len = ods_size(ls_datapaths);
- struct ovn_northd_lb *lb;
+ struct ovn_lb_datapaths *lb_dps;
+ struct hmap sb_lbs = HMAP_INITIALIZER(&sb_lbs);
/* Delete any stale SB load balancer rows and create datapath
* groups for existing ones. */
@@ -4524,28 +4551,32 @@ sync_lbs(struct ovsdb_idl_txn *ovnsb_txn,
* "at-least-once" consistency for clustered database tables that
* are not indexed in any way.
*/
- lb = ovn_northd_lb_find(lbs, &lb_uuid);
- if (!lb || !lb->n_nb_ls || !hmapx_add(&existing_lbs, lb)) {
+ lb_dps = ovn_lb_datapaths_find(lb_dps_map, &lb_uuid);
+ if (!lb_dps || !lb_dps->n_nb_ls || !hmapx_add(&existing_lbs, lb_dps)) {
sbrec_load_balancer_delete(sbrec_lb);
continue;
}
- lb->slb = sbrec_lb;
+ struct sb_lb *sb_lb = xzalloc(sizeof *sb_lb);
+ sb_lb->lb_uuid = lb_uuid;
+ sb_lb->slb = sbrec_lb;
+ hmap_insert(&sb_lbs, &sb_lb->hmap_node, uuid_hash(&lb_uuid));
/* Find or create datapath group for this load balancer. */
- lb->dpg = ovn_dp_group_get_or_create(ovnsb_txn, &dp_groups,
- lb->slb->datapath_group,
- lb->n_nb_ls, lb->nb_ls_map,
- bitmap_len, true,
- ls_datapaths, NULL);
+ sb_lb->dpg = ovn_dp_group_get_or_create(ovnsb_txn, &dp_groups,
+ sb_lb->slb->datapath_group,
+ lb_dps->n_nb_ls,
+ lb_dps->nb_ls_map,
+ bitmap_len, true,
+ ls_datapaths, NULL);
}
hmapx_destroy(&existing_lbs);
/* Create SB Load balancer records if not present and sync
* the SB load balancer columns. */
- HMAP_FOR_EACH (lb, hmap_node, lbs) {
+ HMAP_FOR_EACH (lb_dps, hmap_node, lb_dps_map) {
- if (!lb->n_nb_ls) {
+ if (!lb_dps->n_nb_ls) {
continue;
}
@@ -4553,37 +4584,44 @@ sync_lbs(struct ovsdb_idl_txn *ovnsb_txn,
* transport port) tuple.
*/
struct smap options;
- smap_clone(&options, &lb->nlb->options);
+ smap_clone(&options, &lb_dps->lb->nlb->options);
smap_replace(&options, "hairpin_orig_tuple", "true");
- if (!lb->slb) {
+ struct sb_lb *sb_lb = find_slb_in_sb_lbs(&sb_lbs,
+ &lb_dps->lb->nlb->header_.uuid);
+ ovs_assert(!sb_lb || (sb_lb->slb && sb_lb->dpg));
+ struct ovn_dp_group *lb_dpg = NULL;
+ if (!sb_lb) {
sbrec_lb = sbrec_load_balancer_insert(ovnsb_txn);
- lb->slb = sbrec_lb;
char *lb_id = xasprintf(
- UUID_FMT, UUID_ARGS(&lb->nlb->header_.uuid));
+ UUID_FMT, UUID_ARGS(&lb_dps->lb->nlb->header_.uuid));
const struct smap external_ids =
SMAP_CONST1(&external_ids, "lb_id", lb_id);
sbrec_load_balancer_set_external_ids(sbrec_lb, &external_ids);
free(lb_id);
+ } else {
+ sbrec_lb = sb_lb->slb;
+ lb_dpg = sb_lb->dpg;
}
/* Find or create datapath group for this load balancer. */
- if (!lb->dpg) {
- lb->dpg = ovn_dp_group_get_or_create(ovnsb_txn, &dp_groups,
- lb->slb->datapath_group,
- lb->n_nb_ls, lb->nb_ls_map,
- bitmap_len, true,
- ls_datapaths, NULL);
+ if (!lb_dpg) {
+ lb_dpg = ovn_dp_group_get_or_create(ovnsb_txn, &dp_groups,
+ sbrec_lb->datapath_group,
+ lb_dps->n_nb_ls,
+ lb_dps->nb_ls_map, bitmap_len,
+ true, ls_datapaths, NULL);
}
/* Update columns. */
- sbrec_load_balancer_set_name(lb->slb, lb->nlb->name);
- sbrec_load_balancer_set_vips(lb->slb, ovn_northd_lb_get_vips(lb));
- sbrec_load_balancer_set_protocol(lb->slb, lb->nlb->protocol);
- sbrec_load_balancer_set_datapath_group(lb->slb, lb->dpg->dp_group);
- sbrec_load_balancer_set_options(lb->slb, &options);
+ sbrec_load_balancer_set_name(sbrec_lb, lb_dps->lb->nlb->name);
+ sbrec_load_balancer_set_vips(sbrec_lb,
+ ovn_northd_lb_get_vips(lb_dps->lb));
+ sbrec_load_balancer_set_protocol(sbrec_lb, lb_dps->lb->nlb->protocol);
+ sbrec_load_balancer_set_datapath_group(sbrec_lb, lb_dpg->dp_group);
+ sbrec_load_balancer_set_options(sbrec_lb, &options);
/* Clearing 'datapaths' column, since 'dp_group' is in use. */
- sbrec_load_balancer_set_datapaths(lb->slb, NULL, 0);
+ sbrec_load_balancer_set_datapaths(sbrec_lb, NULL, 0);
smap_destroy(&options);
}
@@ -4594,6 +4632,12 @@ sync_lbs(struct ovsdb_idl_txn *ovnsb_txn,
}
hmap_destroy(&dp_groups);
+ struct sb_lb *sb_lb;
+ HMAP_FOR_EACH_POP (sb_lb, hmap_node, &sb_lbs) {
+ free(sb_lb);
+ }
+ hmap_destroy(&sb_lbs);
+
/* Datapath_Binding.load_balancers is not used anymore, it's still in the
* schema for compatibility reasons. Reset it to empty, just in case.
*/
@@ -7741,15 +7785,17 @@ build_qos(struct ovn_datapath *od, struct hmap *lflows) {
}
static void
-build_lb_rules_pre_stateful(struct hmap *lflows, struct ovn_northd_lb *lb,
+build_lb_rules_pre_stateful(struct hmap *lflows,
+ struct ovn_lb_datapaths *lb_dps,
bool ct_lb_mark,
const struct ovn_datapaths *ls_datapaths,
struct ds *match, struct ds *action)
{
- if (!lb->n_nb_ls) {
+ if (!lb_dps->n_nb_ls) {
return;
}
+ const struct ovn_northd_lb *lb = lb_dps->lb;
for (size_t i = 0; i < lb->n_vips; i++) {
struct ovn_lb_vip *lb_vip = &lb->vips[i];
ds_clear(action);
@@ -7795,7 +7841,7 @@ build_lb_rules_pre_stateful(struct hmap *lflows, struct ovn_northd_lb *lb,
}
ovn_lflow_add_with_dp_group(
- lflows, lb->nb_ls_map, ods_size(ls_datapaths),
+ lflows, lb_dps->nb_ls_map, ods_size(ls_datapaths),
S_SWITCH_IN_PRE_STATEFUL, 120, ds_cstr(match), ds_cstr(action),
&lb->nlb->header_);
}
@@ -7841,7 +7887,7 @@ build_lb_rules_pre_stateful(struct hmap *lflows, struct ovn_northd_lb *lb,
*
*/
static void
-build_lb_affinity_lr_flows(struct hmap *lflows, struct ovn_northd_lb *lb,
+build_lb_affinity_lr_flows(struct hmap *lflows, const struct ovn_northd_lb *lb,
struct ovn_lb_vip *lb_vip, char *new_lb_match,
char *lb_action, const unsigned long *dp_bitmap,
const struct ovn_datapaths *lr_datapaths)
@@ -8027,14 +8073,16 @@ build_lb_affinity_lr_flows(struct hmap *lflows, struct ovn_northd_lb *lb,
*
*/
static void
-build_lb_affinity_ls_flows(struct hmap *lflows, struct ovn_northd_lb *lb,
+build_lb_affinity_ls_flows(struct hmap *lflows,
+ struct ovn_lb_datapaths *lb_dps,
struct ovn_lb_vip *lb_vip,
const struct ovn_datapaths *ls_datapaths)
{
- if (!lb->affinity_timeout || !lb->n_nb_ls) {
+ if (!lb_dps->lb->affinity_timeout || !lb_dps->n_nb_ls) {
return;
}
+ const struct ovn_northd_lb *lb = lb_dps->lb;
struct ds new_lb_match = DS_EMPTY_INITIALIZER;
if (IN6_IS_ADDR_V4MAPPED(&lb_vip->vip)) {
ds_put_format(&new_lb_match,
@@ -8054,9 +8102,9 @@ build_lb_affinity_ls_flows(struct hmap *lflows, struct ovn_northd_lb *lb,
static char *aff_check = REGBIT_KNOWN_LB_SESSION" = chk_lb_aff(); next;";
ovn_lflow_add_with_dp_group(
- lflows, lb->nb_ls_map, ods_size(ls_datapaths),
+ lflows, lb_dps->nb_ls_map, ods_size(ls_datapaths),
S_SWITCH_IN_LB_AFF_CHECK, 100, ds_cstr(&new_lb_match), aff_check,
- &lb->nlb->header_);
+ &lb_dps->lb->nlb->header_);
ds_destroy(&new_lb_match);
struct ds aff_action = DS_EMPTY_INITIALIZER;
@@ -8144,14 +8192,15 @@ build_lb_affinity_ls_flows(struct hmap *lflows, struct ovn_northd_lb *lb,
/* Forward to OFTABLE_CHK_LB_AFFINITY table to store flow tuple. */
ovn_lflow_add_with_dp_group(
- lflows, lb->nb_ls_map, ods_size(ls_datapaths),
+ lflows, lb_dps->nb_ls_map, ods_size(ls_datapaths),
S_SWITCH_IN_LB_AFF_LEARN, 100, ds_cstr(&aff_match_learn),
ds_cstr(&aff_action_learn), &lb->nlb->header_);
/* Use already selected backend within affinity timeslot. */
ovn_lflow_add_with_dp_group(
- lflows, lb->nb_ls_map, ods_size(ls_datapaths), S_SWITCH_IN_LB, 150,
- ds_cstr(&aff_match), ds_cstr(&aff_action), &lb->nlb->header_);
+ lflows, lb_dps->nb_ls_map, ods_size(ls_datapaths),
+ S_SWITCH_IN_LB, 150, ds_cstr(&aff_match), ds_cstr(&aff_action),
+ &lb->nlb->header_);
ds_truncate(&aff_action, aff_action_len);
ds_truncate(&aff_action_learn, aff_action_learn_len);
@@ -8184,11 +8233,13 @@ build_lrouter_lb_affinity_default_flows(struct ovn_datapath *od,
}
static void
-build_lb_rules(struct hmap *lflows, struct ovn_northd_lb *lb,
+build_lb_rules(struct hmap *lflows, struct ovn_lb_datapaths *lb_dps,
const struct ovn_datapaths *ls_datapaths,
const struct chassis_features *features, struct ds *match,
- struct ds *action, const struct shash *meter_groups)
+ struct ds *action, const struct shash *meter_groups,
+ const struct hmap *svc_monitor_map)
{
+ const struct ovn_northd_lb *lb = lb_dps->lb;
for (size_t i = 0; i < lb->n_vips; i++) {
struct ovn_lb_vip *lb_vip = &lb->vips[i];
struct ovn_northd_lb_vip *lb_vip_nb = &lb->vips_nb[i];
@@ -8209,9 +8260,10 @@ build_lb_rules(struct hmap *lflows, struct ovn_northd_lb *lb,
/* New connections in Ingress table. */
const char *meter = NULL;
- bool reject = build_lb_vip_actions(lb_vip, lb_vip_nb, action,
- lb->selection_fields, NULL,
- NULL, true, features);
+ bool reject = build_lb_vip_actions(lb, lb_vip, lb_vip_nb, action,
+ lb->selection_fields,
+ NULL, NULL, true, features,
+ svc_monitor_map);
ds_put_format(match, "ct.new && %s.dst == %s", ip_match,
lb_vip->vip_str);
@@ -8222,15 +8274,17 @@ build_lb_rules(struct hmap *lflows, struct ovn_northd_lb *lb,
priority = 120;
}
- build_lb_affinity_ls_flows(lflows, lb, lb_vip, ls_datapaths);
+ build_lb_affinity_ls_flows(lflows, lb_dps, lb_vip, ls_datapaths);
unsigned long *dp_non_meter = NULL;
bool build_non_meter = false;
if (reject) {
size_t index;
- dp_non_meter = bitmap_clone(lb->nb_ls_map, ods_size(ls_datapaths));
- BITMAP_FOR_EACH_1 (index, ods_size(ls_datapaths), lb->nb_ls_map) {
+ dp_non_meter = bitmap_clone(lb_dps->nb_ls_map,
+ ods_size(ls_datapaths));
+ BITMAP_FOR_EACH_1 (index, ods_size(ls_datapaths),
+ lb_dps->nb_ls_map) {
struct ovn_datapath *od = ls_datapaths->array[index];
meter = copp_meter_get(COPP_REJECT, od->nbs->copp,
@@ -8248,7 +8302,7 @@ build_lb_rules(struct hmap *lflows, struct ovn_northd_lb *lb,
}
if (!reject || build_non_meter) {
ovn_lflow_add_with_dp_group(
- lflows, dp_non_meter ? dp_non_meter : lb->nb_ls_map,
+ lflows, dp_non_meter ? dp_non_meter : lb_dps->nb_ls_map,
ods_size(ls_datapaths), S_SWITCH_IN_LB, priority,
ds_cstr(match), ds_cstr(action), &lb->nlb->header_);
}
@@ -9463,7 +9517,8 @@ build_lswitch_arp_nd_responder_default(struct ovn_datapath *od,
/* Ingress table 19: ARP/ND responder for service monitor source ip.
* (priority 110)*/
static void
-build_lswitch_arp_nd_service_monitor(struct ovn_northd_lb *lb,
+build_lswitch_arp_nd_service_monitor(const struct ovn_northd_lb *lb,
+ const struct hmap *ls_ports,
struct hmap *lflows,
struct ds *actions,
struct ds *match)
@@ -9478,7 +9533,14 @@ build_lswitch_arp_nd_service_monitor(struct ovn_northd_lb *lb,
for (size_t j = 0; j < lb_vip_nb->n_backends; j++) {
struct ovn_northd_lb_backend *backend_nb =
&lb_vip_nb->backends_nb[j];
- if (!backend_nb->op || !backend_nb->svc_mon_src_ip) {
+
+ if (!backend_nb->health_check) {
+ continue;
+ }
+
+ struct ovn_port *op = ovn_port_find(ls_ports,
+ backend_nb->logical_port);
+ if (!op || !backend_nb->svc_mon_src_ip) {
continue;
}
@@ -9520,7 +9582,7 @@ build_lswitch_arp_nd_service_monitor(struct ovn_northd_lb *lb,
svc_monitor_mac);
}
ovn_lflow_add_with_hint(lflows,
- backend_nb->op->od,
+ op->od,
S_SWITCH_IN_ARP_ND_RSP, 110,
ds_cstr(match), ds_cstr(actions),
&lb->nlb->header_);
@@ -11245,7 +11307,7 @@ struct lrouter_nat_lb_flows_ctx {
struct ds *gw_redir_action;
struct ovn_lb_vip *lb_vip;
- struct ovn_northd_lb *lb;
+ const struct ovn_northd_lb *lb;
bool reject;
int prio;
@@ -11377,14 +11439,16 @@ build_gw_lrouter_nat_flows_for_lb(struct lrouter_nat_lb_flows_ctx *ctx,
static void
build_lrouter_nat_flows_for_lb(struct ovn_lb_vip *lb_vip,
- struct ovn_northd_lb *lb,
+ struct ovn_lb_datapaths *lb_dps,
struct ovn_northd_lb_vip *vips_nb,
const struct ovn_datapaths *lr_datapaths,
struct hmap *lflows,
struct ds *match, struct ds *action,
const struct shash *meter_groups,
- const struct chassis_features *features)
+ const struct chassis_features *features,
+ const struct hmap *svc_monitor_map)
{
+ const struct ovn_northd_lb *lb = lb_dps->lb;
bool ipv4 = lb_vip->address_family == AF_INET;
const char *ip_match = ipv4 ? "ip4" : "ip6";
@@ -11399,9 +11463,10 @@ build_lrouter_nat_flows_for_lb(struct ovn_lb_vip *lb_vip,
ds_clear(match);
ds_clear(action);
- bool reject = build_lb_vip_actions(lb_vip, vips_nb, action,
+ bool reject = build_lb_vip_actions(lb, lb_vip, vips_nb, action,
lb->selection_fields, &skip_snat_act,
- &force_snat_act, false, features);
+ &force_snat_act, false, features,
+ svc_monitor_map);
/* Higher priority rules are added for load-balancing in DNAT
* table. For every match (on a VIP[:port]), we add two flows.
@@ -11476,7 +11541,7 @@ build_lrouter_nat_flows_for_lb(struct ovn_lb_vip *lb_vip,
* lflow generation for them.
*/
size_t index;
- BITMAP_FOR_EACH_1 (index, bitmap_len, lb->nb_lr_map) {
+ BITMAP_FOR_EACH_1 (index, bitmap_len, lb_dps->nb_lr_map) {
struct ovn_datapath *od = lr_datapaths->array[index];
enum lrouter_nat_lb_flow_type type;
@@ -11556,16 +11621,19 @@ build_lrouter_nat_flows_for_lb(struct ovn_lb_vip *lb_vip,
}
static void
-build_lswitch_flows_for_lb(struct ovn_northd_lb *lb, struct hmap *lflows,
+build_lswitch_flows_for_lb(struct ovn_lb_datapaths *lb_dps,
+ struct hmap *lflows,
const struct shash *meter_groups,
const struct ovn_datapaths *ls_datapaths,
const struct chassis_features *features,
+ const struct hmap *svc_monitor_map,
struct ds *match, struct ds *action)
{
- if (!lb->n_nb_ls) {
+ if (!lb_dps->n_nb_ls) {
return;
}
+ const struct ovn_northd_lb *lb = lb_dps->lb;
for (size_t i = 0; i < lb->n_vips; i++) {
struct ovn_lb_vip *lb_vip = &lb->vips[i];
@@ -11575,7 +11643,7 @@ build_lswitch_flows_for_lb(struct ovn_northd_lb *lb, struct hmap *lflows,
}
size_t index;
- BITMAP_FOR_EACH_1 (index, ods_size(ls_datapaths), lb->nb_ls_map) {
+ BITMAP_FOR_EACH_1 (index, ods_size(ls_datapaths), lb_dps->nb_ls_map) {
struct ovn_datapath *od = ls_datapaths->array[index];
ovn_lflow_add_with_hint__(lflows, od,
@@ -11599,10 +11667,10 @@ build_lswitch_flows_for_lb(struct ovn_northd_lb *lb, struct hmap *lflows,
* a higher priority rule for load balancing below also commits the
* connection, so it is okay if we do not hit the above match on
* REGBIT_CONNTRACK_COMMIT. */
- build_lb_rules_pre_stateful(lflows, lb, features->ct_no_masked_label,
+ build_lb_rules_pre_stateful(lflows, lb_dps, features->ct_no_masked_label,
ls_datapaths, match, action);
- build_lb_rules(lflows, lb, ls_datapaths, features, match, action,
- meter_groups);
+ build_lb_rules(lflows, lb_dps, ls_datapaths, features, match, action,
+ meter_groups, svc_monitor_map);
}
/* If there are any load balancing rules, we should send the packet to
@@ -11614,17 +11682,17 @@ build_lswitch_flows_for_lb(struct ovn_northd_lb *lb, struct hmap *lflows,
* defragmentation to match on L4 ports.
*/
static void
-build_lrouter_defrag_flows_for_lb(struct ovn_northd_lb *lb,
+build_lrouter_defrag_flows_for_lb(struct ovn_lb_datapaths *lb_dps,
struct hmap *lflows,
const struct ovn_datapaths *lr_datapaths,
struct ds *match)
{
- if (!lb->n_nb_lr) {
+ if (!lb_dps->n_nb_lr) {
return;
}
- for (size_t i = 0; i < lb->n_vips; i++) {
- struct ovn_lb_vip *lb_vip = &lb->vips[i];
+ for (size_t i = 0; i < lb_dps->lb->n_vips; i++) {
+ struct ovn_lb_vip *lb_vip = &lb_dps->lb->vips[i];
bool ipv6 = lb_vip->address_family == AF_INET6;
int prio = 100;
@@ -11633,36 +11701,41 @@ build_lrouter_defrag_flows_for_lb(struct ovn_northd_lb *lb,
lb_vip->vip_str);
ovn_lflow_add_with_dp_group(
- lflows, lb->nb_lr_map, ods_size(lr_datapaths), S_ROUTER_IN_DEFRAG,
- prio, ds_cstr(match), "ct_dnat;", &lb->nlb->header_);
+ lflows, lb_dps->nb_lr_map, ods_size(lr_datapaths),
+ S_ROUTER_IN_DEFRAG, prio, ds_cstr(match), "ct_dnat;",
+ &lb_dps->lb->nlb->header_);
}
}
static void
-build_lrouter_flows_for_lb(struct ovn_northd_lb *lb, struct hmap *lflows,
+build_lrouter_flows_for_lb(struct ovn_lb_datapaths *lb_dps,
+ struct hmap *lflows,
const struct shash *meter_groups,
const struct ovn_datapaths *lr_datapaths,
const struct chassis_features *features,
+ const struct hmap *svc_monitor_map,
struct ds *match, struct ds *action)
{
size_t index;
- if (!lb->n_nb_lr) {
+ if (!lb_dps->n_nb_lr) {
return;
}
+ const struct ovn_northd_lb *lb = lb_dps->lb;
for (size_t i = 0; i < lb->n_vips; i++) {
struct ovn_lb_vip *lb_vip = &lb->vips[i];
- build_lrouter_nat_flows_for_lb(lb_vip, lb, &lb->vips_nb[i],
+ build_lrouter_nat_flows_for_lb(lb_vip, lb_dps, &lb->vips_nb[i],
lr_datapaths, lflows, match, action,
- meter_groups, features);
+ meter_groups, features,
+ svc_monitor_map);
if (!build_empty_lb_event_flow(lb_vip, lb, match, action)) {
continue;
}
- BITMAP_FOR_EACH_1 (index, ods_size(lr_datapaths), lb->nb_lr_map) {
+ BITMAP_FOR_EACH_1 (index, ods_size(lr_datapaths), lb_dps->nb_lr_map) {
struct ovn_datapath *od = lr_datapaths->array[index];
ovn_lflow_add_with_hint__(lflows, od, S_ROUTER_IN_DNAT,
@@ -11676,7 +11749,7 @@ build_lrouter_flows_for_lb(struct ovn_northd_lb *lb, struct hmap *lflows,
}
if (lb->skip_snat) {
- BITMAP_FOR_EACH_1 (index, ods_size(lr_datapaths), lb->nb_lr_map) {
+ BITMAP_FOR_EACH_1 (index, ods_size(lr_datapaths), lb_dps->nb_lr_map) {
struct ovn_datapath *od = lr_datapaths->array[index];
ovn_lflow_add(lflows, od, S_ROUTER_OUT_SNAT, 120,
@@ -15393,7 +15466,8 @@ struct lswitch_flow_build_info {
struct hmap *lflows;
struct hmap *igmp_groups;
const struct shash *meter_groups;
- const struct hmap *lbs;
+ const struct hmap *lb_dps_map;
+ const struct hmap *svc_monitor_map;
const struct hmap *bfd_connections;
const struct chassis_features *features;
char *svc_check_match;
@@ -15533,7 +15607,7 @@ build_lflows_thread(void *arg)
struct ovn_datapath *od;
struct ovn_port *op;
- struct ovn_northd_lb *lb;
+ struct ovn_lb_datapaths *lb_dps;
struct ovn_igmp_group *igmp_group;
int bnum;
@@ -15600,28 +15674,33 @@ build_lflows_thread(void *arg)
}
}
for (bnum = control->id;
- bnum <= lsi->lbs->mask;
+ bnum <= lsi->lb_dps_map->mask;
bnum += control->pool->size)
{
- HMAP_FOR_EACH_IN_PARALLEL (lb, hmap_node, bnum, lsi->lbs) {
+ HMAP_FOR_EACH_IN_PARALLEL (lb_dps, hmap_node, bnum,
+ lsi->lb_dps_map) {
if (stop_parallel_processing()) {
return NULL;
}
- build_lswitch_arp_nd_service_monitor(lb, lsi->lflows,
+ build_lswitch_arp_nd_service_monitor(lb_dps->lb,
+ lsi->ls_ports,
+ lsi->lflows,
&lsi->match,
&lsi->actions);
- build_lrouter_defrag_flows_for_lb(lb, lsi->lflows,
+ build_lrouter_defrag_flows_for_lb(lb_dps, lsi->lflows,
lsi->lr_datapaths,
&lsi->match);
- build_lrouter_flows_for_lb(lb, lsi->lflows,
+ build_lrouter_flows_for_lb(lb_dps, lsi->lflows,
lsi->meter_groups,
lsi->lr_datapaths,
lsi->features,
+ lsi->svc_monitor_map,
&lsi->match, &lsi->actions);
- build_lswitch_flows_for_lb(lb, lsi->lflows,
+ build_lswitch_flows_for_lb(lb_dps, lsi->lflows,
lsi->meter_groups,
lsi->ls_datapaths,
lsi->features,
+ lsi->svc_monitor_map,
&lsi->match, &lsi->actions);
}
}
@@ -15687,7 +15766,8 @@ build_lswitch_and_lrouter_flows(const struct ovn_datapaths *ls_datapaths,
struct hmap *lflows,
struct hmap *igmp_groups,
const struct shash *meter_groups,
- const struct hmap *lbs,
+ const struct hmap *lb_dps_map,
+ const struct hmap *svc_monitor_map,
const struct hmap *bfd_connections,
const struct chassis_features *features)
{
@@ -15714,7 +15794,8 @@ build_lswitch_and_lrouter_flows(const struct ovn_datapaths *ls_datapaths,
lsiv[index].port_groups = port_groups;
lsiv[index].igmp_groups = igmp_groups;
lsiv[index].meter_groups = meter_groups;
- lsiv[index].lbs = lbs;
+ lsiv[index].lb_dps_map = lb_dps_map;
+ lsiv[index].svc_monitor_map = svc_monitor_map;
lsiv[index].bfd_connections = bfd_connections;
lsiv[index].features = features;
lsiv[index].svc_check_match = svc_check_match;
@@ -15737,7 +15818,7 @@ build_lswitch_and_lrouter_flows(const struct ovn_datapaths *ls_datapaths,
} else {
struct ovn_datapath *od;
struct ovn_port *op;
- struct ovn_northd_lb *lb;
+ struct ovn_lb_datapaths *lb_dps;
struct ovn_igmp_group *igmp_group;
struct lswitch_flow_build_info lsi = {
.ls_datapaths = ls_datapaths,
@@ -15748,7 +15829,8 @@ build_lswitch_and_lrouter_flows(const struct ovn_datapaths *ls_datapaths,
.lflows = lflows,
.igmp_groups = igmp_groups,
.meter_groups = meter_groups,
- .lbs = lbs,
+ .lb_dps_map = lb_dps_map,
+ .svc_monitor_map = svc_monitor_map,
.bfd_connections = bfd_connections,
.features = features,
.svc_check_match = svc_check_match,
@@ -15780,17 +15862,19 @@ build_lswitch_and_lrouter_flows(const struct ovn_datapaths *ls_datapaths,
}
stopwatch_stop(LFLOWS_PORTS_STOPWATCH_NAME, time_msec());
stopwatch_start(LFLOWS_LBS_STOPWATCH_NAME, time_msec());
- HMAP_FOR_EACH (lb, hmap_node, lbs) {
- build_lswitch_arp_nd_service_monitor(lb, lsi.lflows,
- &lsi.actions,
+ HMAP_FOR_EACH (lb_dps, hmap_node, lb_dps_map) {
+ build_lswitch_arp_nd_service_monitor(lb_dps->lb, lsi.ls_ports,
+ lsi.lflows, &lsi.actions,
&lsi.match);
- build_lrouter_defrag_flows_for_lb(lb, lsi.lflows, lsi.lr_datapaths,
- &lsi.match);
- build_lrouter_flows_for_lb(lb, lsi.lflows, lsi.meter_groups,
+ build_lrouter_defrag_flows_for_lb(lb_dps, lsi.lflows,
+ lsi.lr_datapaths, &lsi.match);
+ build_lrouter_flows_for_lb(lb_dps, lsi.lflows, lsi.meter_groups,
lsi.lr_datapaths, lsi.features,
+ lsi.svc_monitor_map,
&lsi.match, &lsi.actions);
- build_lswitch_flows_for_lb(lb, lsi.lflows, lsi.meter_groups,
+ build_lswitch_flows_for_lb(lb_dps, lsi.lflows, lsi.meter_groups,
lsi.ls_datapaths, lsi.features,
+ lsi.svc_monitor_map,
&lsi.match, &lsi.actions);
}
stopwatch_stop(LFLOWS_LBS_STOPWATCH_NAME, time_msec());
@@ -15890,7 +15974,9 @@ void build_lflows(struct ovsdb_idl_txn *ovnsb_txn,
input_data->lr_ports,
input_data->port_groups, lflows,
&igmp_groups,
- input_data->meter_groups, input_data->lbs,
+ input_data->meter_groups,
+ input_data->lb_datapaths_map,
+ input_data->svc_monitor_map,
input_data->bfd_connections,
input_data->features);
@@ -17215,8 +17301,8 @@ northd_init(struct northd_data *data)
hmap_init(&data->lr_ports);
hmap_init(&data->port_groups);
shash_init(&data->meter_groups);
- hmap_init(&data->lbs);
- hmap_init(&data->lb_groups);
+ hmap_init(&data->lb_datapaths_map);
+ hmap_init(&data->lb_group_datapaths_map);
ovs_list_init(&data->lr_list);
data->features = (struct chassis_features) {
.ct_no_masked_label = true,
@@ -17226,6 +17312,7 @@ northd_init(struct northd_data *data)
};
data->ovn_internal_version_changed = false;
sset_init(&data->svc_monitor_lsps);
+ hmap_init(&data->svc_monitor_map);
data->change_tracked = false;
ovs_list_init(&data->tracked_ls_changes.updated);
}
@@ -17233,17 +17320,18 @@ northd_init(struct northd_data *data)
void
northd_destroy(struct northd_data *data)
{
- struct ovn_northd_lb *lb;
- HMAP_FOR_EACH_POP (lb, hmap_node, &data->lbs) {
- ovn_northd_lb_destroy(lb);
+ struct ovn_lb_datapaths *lb_dps;
+ HMAP_FOR_EACH_POP (lb_dps, hmap_node, &data->lb_datapaths_map) {
+ ovn_lb_datapaths_destroy(lb_dps);
}
- hmap_destroy(&data->lbs);
+ hmap_destroy(&data->lb_datapaths_map);
- struct ovn_lb_group *lb_group;
- HMAP_FOR_EACH_POP (lb_group, hmap_node, &data->lb_groups) {
- ovn_lb_group_destroy(lb_group);
+ struct ovn_lb_group_datapaths *lb_group_dps;
+ HMAP_FOR_EACH_POP (lb_group_dps, hmap_node,
+ &data->lb_group_datapaths_map) {
+ ovn_lb_group_datapaths_destroy(lb_group_dps);
}
- hmap_destroy(&data->lb_groups);
+ hmap_destroy(&data->lb_group_datapaths_map);
struct ovn_port_group *pg;
HMAP_FOR_EACH_SAFE (pg, key_node, &data->port_groups) {
@@ -17258,6 +17346,12 @@ northd_destroy(struct northd_data *data)
}
shash_destroy(&data->meter_groups);
+ struct service_monitor_info *mon_info;
+ HMAP_FOR_EACH_POP (mon_info, hmap_node, &data->svc_monitor_map) {
+ free(mon_info);
+ }
+ hmap_destroy(&data->svc_monitor_map);
+
/* XXX Having to explicitly clean up macam here
* is a bit strange. We don't explicitly initialize
* macam in this module, but this is the logical place
@@ -17366,10 +17460,9 @@ ovnnb_db_run(struct northd_input *input_data,
input_data->sbrec_chassis_table,
&data->ls_datapaths,
&data->lr_datapaths, &data->lr_list);
- build_lbs(input_data->nbrec_load_balancer_table,
- input_data->nbrec_load_balancer_group_table,
- &data->ls_datapaths, &data->lr_datapaths, &data->lbs,
- &data->lb_groups);
+ build_lb_datapaths(input_data->lbs, input_data->lb_groups,
+ &data->ls_datapaths, &data->lr_datapaths,
+ &data->lb_datapaths_map, &data->lb_group_datapaths_map);
build_ports(ovnsb_txn,
input_data->sbrec_port_binding_table,
input_data->sbrec_chassis_table,
@@ -17384,9 +17477,11 @@ ovnnb_db_run(struct northd_input *input_data,
build_lb_port_related_data(ovnsb_txn,
input_data->sbrec_service_monitor_table,
&data->lr_datapaths, &data->ls_ports,
- &data->lbs, &data->lb_groups,
- &data->svc_monitor_lsps);
- build_lb_count_dps(&data->lbs,
+ &data->lb_datapaths_map,
+ &data->lb_group_datapaths_map,
+ &data->svc_monitor_lsps,
+ &data->svc_monitor_map);
+ build_lb_count_dps(&data->lb_datapaths_map,
ods_size(&data->ls_datapaths),
ods_size(&data->lr_datapaths));
build_ipam(&data->ls_datapaths.datapaths, &data->ls_ports);
@@ -28,9 +28,6 @@ struct northd_input {
const struct nbrec_nb_global_table *nbrec_nb_global_table;
const struct nbrec_logical_switch_table *nbrec_logical_switch_table;
const struct nbrec_logical_router_table *nbrec_logical_router_table;
- const struct nbrec_load_balancer_table *nbrec_load_balancer_table;
- const struct nbrec_load_balancer_group_table
- *nbrec_load_balancer_group_table;
const struct nbrec_port_group_table *nbrec_port_group_table;
const struct nbrec_meter_table *nbrec_meter_table;
const struct nbrec_acl_table *nbrec_acl_table;
@@ -59,6 +56,10 @@ struct northd_input {
*sbrec_chassis_template_var_table;
const struct sbrec_mirror_table *sbrec_mirror_table;
+ /* Northd lb data node inputs*/
+ const struct hmap *lbs;
+ const struct hmap *lb_groups;
+
/* Indexes */
struct ovsdb_idl_index *sbrec_chassis_by_name;
struct ovsdb_idl_index *sbrec_chassis_by_hostname;
@@ -110,12 +111,13 @@ struct northd_data {
struct hmap lr_ports;
struct hmap port_groups;
struct shash meter_groups;
- struct hmap lbs;
- struct hmap lb_groups;
+ struct hmap lb_datapaths_map;
+ struct hmap lb_group_datapaths_map;
struct ovs_list lr_list;
bool ovn_internal_version_changed;
struct chassis_features features;
struct sset svc_monitor_lsps;
+ struct hmap svc_monitor_map;
bool change_tracked;
struct tracked_ls_changes tracked_ls_changes;
};
@@ -146,9 +148,10 @@ struct lflow_input {
const struct hmap *lr_ports;
const struct hmap *port_groups;
const struct shash *meter_groups;
- const struct hmap *lbs;
+ const struct hmap *lb_datapaths_map;
const struct hmap *bfd_connections;
const struct chassis_features *features;
+ const struct hmap *svc_monitor_map;
bool ovn_internal_version_changed;
};