|
|
ebb439 |
From 58f78bf44b9df97a45d7dbe08c8f95770a295a68 Mon Sep 17 00:00:00 2001
|
|
|
ebb439 |
From: Dumitru Ceara <dceara@redhat.com>
|
|
|
ebb439 |
Date: Mon, 12 Oct 2020 17:52:38 +0530
|
|
|
ebb439 |
Subject: [PATCH 05/10] northd: Refactor load balancer vip parsing.
|
|
|
ebb439 |
|
|
|
ebb439 |
Parsing of the load balancer VIPs is moved to a separate file - lib/lb.c.
|
|
|
ebb439 |
ovn-northd makes use of these functions. Upcoming patch will make use of these
|
|
|
ebb439 |
util functions for parsing SB Load_Balancers.
|
|
|
ebb439 |
|
|
|
ebb439 |
Co-authored-by: Numan Siddique <numans@ovn.org>
|
|
|
ebb439 |
Signed-off-by: Numan Siddique <numans@ovn.org>
|
|
|
ebb439 |
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
|
|
|
ebb439 |
Acked-by: Mark Michelson <mmichels@redhat.com>
|
|
|
ebb439 |
|
|
|
ebb439 |
(cherry-picked from master commit f1119c1257652702e0ee88cf634f2ee19cc92c44)
|
|
|
ebb439 |
Conflicts:
|
|
|
ebb439 |
northd/ovn-northd.c
|
|
|
ebb439 |
---
|
|
|
ebb439 |
lib/automake.mk | 4 +-
|
|
|
ebb439 |
lib/lb.c | 301 ++++++++++++++++++++++++++++++++
|
|
|
ebb439 |
lib/lb.h | 97 +++++++++++
|
|
|
ebb439 |
northd/ovn-northd.c | 416 +++++++++++++-------------------------------
|
|
|
ebb439 |
4 files changed, 518 insertions(+), 300 deletions(-)
|
|
|
ebb439 |
create mode 100644 lib/lb.c
|
|
|
ebb439 |
create mode 100644 lib/lb.h
|
|
|
ebb439 |
|
|
|
ebb439 |
diff --git a/lib/automake.mk b/lib/automake.mk
|
|
|
ebb439 |
index f3e9c8818..430cd11fc 100644
|
|
|
ebb439 |
--- a/lib/automake.mk
|
|
|
ebb439 |
+++ b/lib/automake.mk
|
|
|
ebb439 |
@@ -23,7 +23,9 @@ lib_libovn_la_SOURCES = \
|
|
|
ebb439 |
lib/ovn-util.h \
|
|
|
ebb439 |
lib/logical-fields.c \
|
|
|
ebb439 |
lib/inc-proc-eng.c \
|
|
|
ebb439 |
- lib/inc-proc-eng.h
|
|
|
ebb439 |
+ lib/inc-proc-eng.h \
|
|
|
ebb439 |
+ lib/lb.c \
|
|
|
ebb439 |
+ lib/lb.h
|
|
|
ebb439 |
nodist_lib_libovn_la_SOURCES = \
|
|
|
ebb439 |
lib/ovn-dirs.c \
|
|
|
ebb439 |
lib/ovn-nb-idl.c \
|
|
|
ebb439 |
diff --git a/lib/lb.c b/lib/lb.c
|
|
|
ebb439 |
new file mode 100644
|
|
|
ebb439 |
index 000000000..a90042e58
|
|
|
ebb439 |
--- /dev/null
|
|
|
ebb439 |
+++ b/lib/lb.c
|
|
|
ebb439 |
@@ -0,0 +1,301 @@
|
|
|
ebb439 |
+/* Copyright (c) 2020, Red Hat, Inc.
|
|
|
ebb439 |
+ *
|
|
|
ebb439 |
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
ebb439 |
+ * you may not use this file except in compliance with the License.
|
|
|
ebb439 |
+ * You may obtain a copy of the License at:
|
|
|
ebb439 |
+ *
|
|
|
ebb439 |
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
|
ebb439 |
+ *
|
|
|
ebb439 |
+ * Unless required by applicable law or agreed to in writing, software
|
|
|
ebb439 |
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
ebb439 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
ebb439 |
+ * See the License for the specific language governing permissions and
|
|
|
ebb439 |
+ * limitations under the License.
|
|
|
ebb439 |
+ */
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+#include <config.h>
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+#include "lb.h"
|
|
|
ebb439 |
+#include "lib/ovn-nb-idl.h"
|
|
|
ebb439 |
+#include "lib/ovn-sb-idl.h"
|
|
|
ebb439 |
+#include "lib/ovn-util.h"
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+/* OpenvSwitch lib includes. */
|
|
|
ebb439 |
+#include "openvswitch/vlog.h"
|
|
|
ebb439 |
+#include "lib/smap.h"
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+VLOG_DEFINE_THIS_MODULE(lb);
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+static
|
|
|
ebb439 |
+bool ovn_lb_vip_init(struct ovn_lb_vip *lb_vip, const char *lb_key,
|
|
|
ebb439 |
+ const char *lb_value)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ int addr_family;
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ if (!ip_address_and_port_from_lb_key(lb_key, &lb_vip->vip_str,
|
|
|
ebb439 |
+ &lb_vip->vip_port, &addr_family)) {
|
|
|
ebb439 |
+ return false;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ if (addr_family == AF_INET) {
|
|
|
ebb439 |
+ ovs_be32 vip4;
|
|
|
ebb439 |
+ ip_parse(lb_vip->vip_str, &vip4);
|
|
|
ebb439 |
+ in6_addr_set_mapped_ipv4(&lb_vip->vip, vip4);
|
|
|
ebb439 |
+ } else {
|
|
|
ebb439 |
+ ipv6_parse(lb_vip->vip_str, &lb_vip->vip);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ /* Format for backend ips: "IP1:port1,IP2:port2,...". */
|
|
|
ebb439 |
+ size_t n_backends = 0;
|
|
|
ebb439 |
+ size_t n_allocated_backends = 0;
|
|
|
ebb439 |
+ char *tokstr = xstrdup(lb_value);
|
|
|
ebb439 |
+ char *save_ptr = NULL;
|
|
|
ebb439 |
+ for (char *token = strtok_r(tokstr, ",", &save_ptr);
|
|
|
ebb439 |
+ token != NULL;
|
|
|
ebb439 |
+ token = strtok_r(NULL, ",", &save_ptr)) {
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ if (n_backends == n_allocated_backends) {
|
|
|
ebb439 |
+ lb_vip->backends = x2nrealloc(lb_vip->backends,
|
|
|
ebb439 |
+ &n_allocated_backends,
|
|
|
ebb439 |
+ sizeof *lb_vip->backends);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ struct ovn_lb_backend *backend = &lb_vip->backends[n_backends];
|
|
|
ebb439 |
+ int backend_addr_family;
|
|
|
ebb439 |
+ if (!ip_address_and_port_from_lb_key(token, &backend->ip_str,
|
|
|
ebb439 |
+ &backend->port,
|
|
|
ebb439 |
+ &backend_addr_family)) {
|
|
|
ebb439 |
+ continue;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ if (addr_family != backend_addr_family) {
|
|
|
ebb439 |
+ free(backend->ip_str);
|
|
|
ebb439 |
+ continue;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ if (addr_family == AF_INET) {
|
|
|
ebb439 |
+ ovs_be32 ip4;
|
|
|
ebb439 |
+ ip_parse(backend->ip_str, &ip4;;
|
|
|
ebb439 |
+ in6_addr_set_mapped_ipv4(&backend->ip, ip4);
|
|
|
ebb439 |
+ } else {
|
|
|
ebb439 |
+ ipv6_parse(backend->ip_str, &backend->ip);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ n_backends++;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ free(tokstr);
|
|
|
ebb439 |
+ lb_vip->n_backends = n_backends;
|
|
|
ebb439 |
+ return true;
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+static
|
|
|
ebb439 |
+void ovn_lb_vip_destroy(struct ovn_lb_vip *vip)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ free(vip->vip_str);
|
|
|
ebb439 |
+ for (size_t i = 0; i < vip->n_backends; i++) {
|
|
|
ebb439 |
+ free(vip->backends[i].ip_str);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ free(vip->backends);
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+static
|
|
|
ebb439 |
+void ovn_northd_lb_vip_init(struct ovn_northd_lb_vip *lb_vip_nb,
|
|
|
ebb439 |
+ const struct ovn_lb_vip *lb_vip,
|
|
|
ebb439 |
+ const struct nbrec_load_balancer *nbrec_lb,
|
|
|
ebb439 |
+ const char *vip_port_str, const char *backend_ips,
|
|
|
ebb439 |
+ struct hmap *ports,
|
|
|
ebb439 |
+ void * (*ovn_port_find)(const struct hmap *ports,
|
|
|
ebb439 |
+ const char *name))
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ lb_vip_nb->vip_port_str = xstrdup(vip_port_str);
|
|
|
ebb439 |
+ lb_vip_nb->backend_ips = xstrdup(backend_ips);
|
|
|
ebb439 |
+ lb_vip_nb->n_backends = lb_vip->n_backends;
|
|
|
ebb439 |
+ lb_vip_nb->backends_nb = xcalloc(lb_vip_nb->n_backends,
|
|
|
ebb439 |
+ sizeof *lb_vip_nb->backends_nb);
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ struct nbrec_load_balancer_health_check *lb_health_check = NULL;
|
|
|
ebb439 |
+ if (nbrec_lb->protocol && !strcmp(nbrec_lb->protocol, "sctp")) {
|
|
|
ebb439 |
+ if (nbrec_lb->n_health_check > 0) {
|
|
|
ebb439 |
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
|
|
|
ebb439 |
+ VLOG_WARN_RL(&rl,
|
|
|
ebb439 |
+ "SCTP load balancers do not currently support "
|
|
|
ebb439 |
+ "health checks. Not creating health checks for "
|
|
|
ebb439 |
+ "load balancer " UUID_FMT,
|
|
|
ebb439 |
+ UUID_ARGS(&nbrec_lb->header_.uuid));
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ } else {
|
|
|
ebb439 |
+ for (size_t j = 0; j < nbrec_lb->n_health_check; j++) {
|
|
|
ebb439 |
+ if (!strcmp(nbrec_lb->health_check[j]->vip,
|
|
|
ebb439 |
+ lb_vip_nb->vip_port_str)) {
|
|
|
ebb439 |
+ lb_health_check = nbrec_lb->health_check[j];
|
|
|
ebb439 |
+ break;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ lb_vip_nb->lb_health_check = lb_health_check;
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ for (size_t j = 0; j < lb_vip_nb->n_backends; j++) {
|
|
|
ebb439 |
+ struct ovn_lb_backend *backend = &lb_vip->backends[j];
|
|
|
ebb439 |
+ struct ovn_northd_lb_backend *backend_nb = &lb_vip_nb->backends_nb[j];
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ struct ovn_port *op = NULL;
|
|
|
ebb439 |
+ char *svc_mon_src_ip = NULL;
|
|
|
ebb439 |
+ const char *s = smap_get(&nbrec_lb->ip_port_mappings,
|
|
|
ebb439 |
+ backend->ip_str);
|
|
|
ebb439 |
+ if (s) {
|
|
|
ebb439 |
+ char *port_name = xstrdup(s);
|
|
|
ebb439 |
+ char *p = strstr(port_name, ":");
|
|
|
ebb439 |
+ if (p) {
|
|
|
ebb439 |
+ *p = 0;
|
|
|
ebb439 |
+ p++;
|
|
|
ebb439 |
+ op = ovn_port_find(ports, port_name);
|
|
|
ebb439 |
+ svc_mon_src_ip = xstrdup(p);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ free(port_name);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ backend_nb->op = op;
|
|
|
ebb439 |
+ backend_nb->svc_mon_src_ip = svc_mon_src_ip;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+static
|
|
|
ebb439 |
+void ovn_northd_lb_vip_destroy(struct ovn_northd_lb_vip *vip)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ free(vip->vip_port_str);
|
|
|
ebb439 |
+ free(vip->backend_ips);
|
|
|
ebb439 |
+ for (size_t i = 0; i < vip->n_backends; i++) {
|
|
|
ebb439 |
+ free(vip->backends_nb[i].svc_mon_src_ip);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ free(vip->backends_nb);
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+struct ovn_northd_lb *
|
|
|
ebb439 |
+ovn_northd_lb_create(const struct nbrec_load_balancer *nbrec_lb,
|
|
|
ebb439 |
+ struct hmap *ports,
|
|
|
ebb439 |
+ void * (*ovn_port_find)(const struct hmap *ports,
|
|
|
ebb439 |
+ const char *name))
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ struct ovn_northd_lb *lb = xzalloc(sizeof *lb);
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ lb->nlb = nbrec_lb;
|
|
|
ebb439 |
+ lb->n_vips = smap_count(&nbrec_lb->vips);
|
|
|
ebb439 |
+ lb->vips = xcalloc(lb->n_vips, sizeof *lb->vips);
|
|
|
ebb439 |
+ lb->vips_nb = xcalloc(lb->n_vips, sizeof *lb->vips_nb);
|
|
|
ebb439 |
+ struct smap_node *node;
|
|
|
ebb439 |
+ size_t n_vips = 0;
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ SMAP_FOR_EACH (node, &nbrec_lb->vips) {
|
|
|
ebb439 |
+ struct ovn_lb_vip *lb_vip = &lb->vips[n_vips];
|
|
|
ebb439 |
+ struct ovn_northd_lb_vip *lb_vip_nb = &lb->vips_nb[n_vips];
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ if (!ovn_lb_vip_init(lb_vip, node->key, node->value)) {
|
|
|
ebb439 |
+ continue;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ ovn_northd_lb_vip_init(lb_vip_nb, lb_vip, nbrec_lb,
|
|
|
ebb439 |
+ node->key, node->value, ports, ovn_port_find);
|
|
|
ebb439 |
+ n_vips++;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ /* It's possible that parsing VIPs fails. Update the lb->n_vips to the
|
|
|
ebb439 |
+ * correct value.
|
|
|
ebb439 |
+ */
|
|
|
ebb439 |
+ lb->n_vips = n_vips;
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ if (nbrec_lb->n_selection_fields) {
|
|
|
ebb439 |
+ char *proto = NULL;
|
|
|
ebb439 |
+ if (nbrec_lb->protocol && nbrec_lb->protocol[0]) {
|
|
|
ebb439 |
+ proto = nbrec_lb->protocol;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ struct ds sel_fields = DS_EMPTY_INITIALIZER;
|
|
|
ebb439 |
+ for (size_t i = 0; i < lb->nlb->n_selection_fields; i++) {
|
|
|
ebb439 |
+ char *field = lb->nlb->selection_fields[i];
|
|
|
ebb439 |
+ if (!strcmp(field, "tp_src") && proto) {
|
|
|
ebb439 |
+ ds_put_format(&sel_fields, "%s_src,", proto);
|
|
|
ebb439 |
+ } else if (!strcmp(field, "tp_dst") && proto) {
|
|
|
ebb439 |
+ ds_put_format(&sel_fields, "%s_dst,", proto);
|
|
|
ebb439 |
+ } else {
|
|
|
ebb439 |
+ ds_put_format(&sel_fields, "%s,", field);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ ds_chomp(&sel_fields, ',');
|
|
|
ebb439 |
+ lb->selection_fields = ds_steal_cstr(&sel_fields);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ return lb;
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+struct ovn_northd_lb *
|
|
|
ebb439 |
+ovn_northd_lb_find(struct hmap *lbs, const struct uuid *uuid)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ struct ovn_northd_lb *lb;
|
|
|
ebb439 |
+ size_t hash = uuid_hash(uuid);
|
|
|
ebb439 |
+ HMAP_FOR_EACH_WITH_HASH (lb, hmap_node, hash, lbs) {
|
|
|
ebb439 |
+ if (uuid_equals(&lb->nlb->header_.uuid, uuid)) {
|
|
|
ebb439 |
+ return lb;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ return NULL;
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+void
|
|
|
ebb439 |
+ovn_northd_lb_add_datapath(struct ovn_northd_lb *lb,
|
|
|
ebb439 |
+ const struct sbrec_datapath_binding *sb)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ if (lb->n_allocated_dps == lb->n_dps) {
|
|
|
ebb439 |
+ lb->dps = x2nrealloc(lb->dps, &lb->n_allocated_dps, sizeof *lb->dps);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ lb->dps[lb->n_dps++] = sb;
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+void
|
|
|
ebb439 |
+ovn_northd_lb_destroy(struct ovn_northd_lb *lb)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ for (size_t i = 0; i < lb->n_vips; i++) {
|
|
|
ebb439 |
+ ovn_lb_vip_destroy(&lb->vips[i]);
|
|
|
ebb439 |
+ ovn_northd_lb_vip_destroy(&lb->vips_nb[i]);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ free(lb->vips);
|
|
|
ebb439 |
+ free(lb->vips_nb);
|
|
|
ebb439 |
+ free(lb->selection_fields);
|
|
|
ebb439 |
+ free(lb->dps);
|
|
|
ebb439 |
+ free(lb);
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+struct ovn_controller_lb *
|
|
|
ebb439 |
+ovn_controller_lb_create(const struct sbrec_load_balancer *sbrec_lb)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ struct ovn_controller_lb *lb = xzalloc(sizeof *lb);
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ lb->slb = sbrec_lb;
|
|
|
ebb439 |
+ lb->n_vips = smap_count(&sbrec_lb->vips);
|
|
|
ebb439 |
+ lb->vips = xcalloc(lb->n_vips, sizeof *lb->vips);
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ struct smap_node *node;
|
|
|
ebb439 |
+ size_t n_vips = 0;
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ SMAP_FOR_EACH (node, &sbrec_lb->vips) {
|
|
|
ebb439 |
+ struct ovn_lb_vip *lb_vip = &lb->vips[n_vips];
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ if (!ovn_lb_vip_init(lb_vip, node->key, node->value)) {
|
|
|
ebb439 |
+ continue;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ n_vips++;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ /* It's possible that parsing VIPs fails. Update the lb->n_vips to the
|
|
|
ebb439 |
+ * correct value.
|
|
|
ebb439 |
+ */
|
|
|
ebb439 |
+ lb->n_vips = n_vips;
|
|
|
ebb439 |
+ return lb;
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+void
|
|
|
ebb439 |
+ovn_controller_lb_destroy(struct ovn_controller_lb *lb)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ for (size_t i = 0; i < lb->n_vips; i++) {
|
|
|
ebb439 |
+ ovn_lb_vip_destroy(&lb->vips[i]);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ free(lb->vips);
|
|
|
ebb439 |
+ free(lb);
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
diff --git a/lib/lb.h b/lib/lb.h
|
|
|
ebb439 |
new file mode 100644
|
|
|
ebb439 |
index 000000000..6644ad0d8
|
|
|
ebb439 |
--- /dev/null
|
|
|
ebb439 |
+++ b/lib/lb.h
|
|
|
ebb439 |
@@ -0,0 +1,97 @@
|
|
|
ebb439 |
+/* Copyright (c) 2020, Red Hat, Inc.
|
|
|
ebb439 |
+ *
|
|
|
ebb439 |
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
ebb439 |
+ * you may not use this file except in compliance with the License.
|
|
|
ebb439 |
+ * You may obtain a copy of the License at:
|
|
|
ebb439 |
+ *
|
|
|
ebb439 |
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
|
ebb439 |
+ *
|
|
|
ebb439 |
+ * Unless required by applicable law or agreed to in writing, software
|
|
|
ebb439 |
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
ebb439 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
ebb439 |
+ * See the License for the specific language governing permissions and
|
|
|
ebb439 |
+ * limitations under the License.
|
|
|
ebb439 |
+ */
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+#ifndef OVN_LIB_LB_H
|
|
|
ebb439 |
+#define OVN_LIB_LB_H 1
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+#include <sys/types.h>
|
|
|
ebb439 |
+#include <netinet/in.h>
|
|
|
ebb439 |
+#include "openvswitch/hmap.h"
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+struct nbrec_load_balancer;
|
|
|
ebb439 |
+struct sbrec_load_balancer;
|
|
|
ebb439 |
+struct sbrec_datapath_binding;
|
|
|
ebb439 |
+struct ovn_port;
|
|
|
ebb439 |
+struct uuid;
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+struct ovn_northd_lb {
|
|
|
ebb439 |
+ struct hmap_node hmap_node;
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ const struct nbrec_load_balancer *nlb; /* May be NULL. */
|
|
|
ebb439 |
+ const struct sbrec_load_balancer *slb; /* May be NULL. */
|
|
|
ebb439 |
+ char *selection_fields;
|
|
|
ebb439 |
+ struct ovn_lb_vip *vips;
|
|
|
ebb439 |
+ struct ovn_northd_lb_vip *vips_nb;
|
|
|
ebb439 |
+ size_t n_vips;
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ size_t n_dps;
|
|
|
ebb439 |
+ size_t n_allocated_dps;
|
|
|
ebb439 |
+ const struct sbrec_datapath_binding **dps;
|
|
|
ebb439 |
+};
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+struct ovn_lb_vip {
|
|
|
ebb439 |
+ struct in6_addr vip;
|
|
|
ebb439 |
+ char *vip_str;
|
|
|
ebb439 |
+ uint16_t vip_port;
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ struct ovn_lb_backend *backends;
|
|
|
ebb439 |
+ size_t n_backends;
|
|
|
ebb439 |
+};
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+struct ovn_lb_backend {
|
|
|
ebb439 |
+ struct in6_addr ip;
|
|
|
ebb439 |
+ char *ip_str;
|
|
|
ebb439 |
+ uint16_t port;
|
|
|
ebb439 |
+};
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+/* ovn-northd specific backend information. */
|
|
|
ebb439 |
+struct ovn_northd_lb_vip {
|
|
|
ebb439 |
+ char *vip_port_str;
|
|
|
ebb439 |
+ char *backend_ips;
|
|
|
ebb439 |
+ struct ovn_northd_lb_backend *backends_nb;
|
|
|
ebb439 |
+ size_t n_backends;
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ struct nbrec_load_balancer_health_check *lb_health_check;
|
|
|
ebb439 |
+};
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+struct ovn_northd_lb_backend {
|
|
|
ebb439 |
+ struct ovn_port *op; /* Logical port to which the ip belong to. */
|
|
|
ebb439 |
+ bool health_check;
|
|
|
ebb439 |
+ char *svc_mon_src_ip; /* Source IP to use for monitoring. */
|
|
|
ebb439 |
+ const struct sbrec_service_monitor *sbrec_monitor;
|
|
|
ebb439 |
+};
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+struct ovn_northd_lb *ovn_northd_lb_create(
|
|
|
ebb439 |
+ const struct nbrec_load_balancer *,
|
|
|
ebb439 |
+ struct hmap *ports,
|
|
|
ebb439 |
+ void * (*ovn_port_find)(const struct hmap *ports, const char *name));
|
|
|
ebb439 |
+struct ovn_northd_lb * ovn_northd_lb_find(struct hmap *, const struct uuid *);
|
|
|
ebb439 |
+void ovn_northd_lb_destroy(struct ovn_northd_lb *);
|
|
|
ebb439 |
+void ovn_northd_lb_add_datapath(struct ovn_northd_lb *,
|
|
|
ebb439 |
+ const struct sbrec_datapath_binding *);
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+struct ovn_controller_lb {
|
|
|
ebb439 |
+ const struct sbrec_load_balancer *slb; /* May be NULL. */
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ struct ovn_lb_vip *vips;
|
|
|
ebb439 |
+ size_t n_vips;
|
|
|
ebb439 |
+};
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+struct ovn_controller_lb *ovn_controller_lb_create(
|
|
|
ebb439 |
+ const struct sbrec_load_balancer *);
|
|
|
ebb439 |
+void ovn_controller_lb_destroy(struct ovn_controller_lb *);
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+#endif /* OVN_LIB_LB_H 1 */
|
|
|
ebb439 |
diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
|
|
|
ebb439 |
index c32e25c3d..a7695bc63 100644
|
|
|
ebb439 |
--- a/northd/ovn-northd.c
|
|
|
ebb439 |
+++ b/northd/ovn-northd.c
|
|
|
ebb439 |
@@ -35,6 +35,7 @@
|
|
|
ebb439 |
#include "lib/ovn-nb-idl.h"
|
|
|
ebb439 |
#include "lib/ovn-sb-idl.h"
|
|
|
ebb439 |
#include "lib/ovn-util.h"
|
|
|
ebb439 |
+#include "lib/lb.h"
|
|
|
ebb439 |
#include "ovn/actions.h"
|
|
|
ebb439 |
#include "ovn/logical-fields.h"
|
|
|
ebb439 |
#include "packets.h"
|
|
|
ebb439 |
@@ -3329,66 +3330,6 @@ cleanup_sb_ha_chassis_groups(struct northd_context *ctx,
|
|
|
ebb439 |
}
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
-struct ovn_lb {
|
|
|
ebb439 |
- struct hmap_node hmap_node;
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- const struct nbrec_load_balancer *nlb; /* May be NULL. */
|
|
|
ebb439 |
- const struct sbrec_load_balancer *slb; /* May be NULL. */
|
|
|
ebb439 |
- char *selection_fields;
|
|
|
ebb439 |
- struct lb_vip *vips;
|
|
|
ebb439 |
- size_t n_vips;
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- size_t n_dps;
|
|
|
ebb439 |
- size_t n_allocated_dps;
|
|
|
ebb439 |
- const struct sbrec_datapath_binding **dps;
|
|
|
ebb439 |
-};
|
|
|
ebb439 |
-
|
|
|
ebb439 |
-struct lb_vip {
|
|
|
ebb439 |
- char *vip;
|
|
|
ebb439 |
- uint16_t vip_port;
|
|
|
ebb439 |
- int addr_family;
|
|
|
ebb439 |
- char *backend_ips;
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- bool health_check;
|
|
|
ebb439 |
- struct lb_vip_backend *backends;
|
|
|
ebb439 |
- size_t n_backends;
|
|
|
ebb439 |
-};
|
|
|
ebb439 |
-
|
|
|
ebb439 |
-struct lb_vip_backend {
|
|
|
ebb439 |
- char *ip;
|
|
|
ebb439 |
- uint16_t port;
|
|
|
ebb439 |
- int addr_family;
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- struct ovn_port *op; /* Logical port to which the ip belong to. */
|
|
|
ebb439 |
- bool health_check;
|
|
|
ebb439 |
- char *svc_mon_src_ip; /* Source IP to use for monitoring. */
|
|
|
ebb439 |
- const struct sbrec_service_monitor *sbrec_monitor;
|
|
|
ebb439 |
-};
|
|
|
ebb439 |
-
|
|
|
ebb439 |
-
|
|
|
ebb439 |
-static inline struct ovn_lb *
|
|
|
ebb439 |
-ovn_lb_find(struct hmap *lbs, const struct uuid *uuid)
|
|
|
ebb439 |
-{
|
|
|
ebb439 |
- struct ovn_lb *lb;
|
|
|
ebb439 |
- size_t hash = uuid_hash(uuid);
|
|
|
ebb439 |
- HMAP_FOR_EACH_WITH_HASH (lb, hmap_node, hash, lbs) {
|
|
|
ebb439 |
- if (uuid_equals(&lb->nlb->header_.uuid, uuid)) {
|
|
|
ebb439 |
- return lb;
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- return NULL;
|
|
|
ebb439 |
-}
|
|
|
ebb439 |
-
|
|
|
ebb439 |
-static void
|
|
|
ebb439 |
-ovn_lb_add_datapath(struct ovn_lb *lb, struct ovn_datapath *od)
|
|
|
ebb439 |
-{
|
|
|
ebb439 |
- if (lb->n_allocated_dps == lb->n_dps) {
|
|
|
ebb439 |
- lb->dps = x2nrealloc(lb->dps, &lb->n_allocated_dps, sizeof *lb->dps);
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
- lb->dps[lb->n_dps++] = od->sb;
|
|
|
ebb439 |
-}
|
|
|
ebb439 |
-
|
|
|
ebb439 |
struct service_monitor_info {
|
|
|
ebb439 |
struct hmap_node hmap_node;
|
|
|
ebb439 |
const struct sbrec_service_monitor *sbrec_mon;
|
|
|
ebb439 |
@@ -3428,126 +3369,39 @@ create_or_get_service_mon(struct northd_context *ctx,
|
|
|
ebb439 |
return mon_info;
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
-static struct ovn_lb *
|
|
|
ebb439 |
-ovn_lb_create(struct northd_context *ctx, struct hmap *lbs,
|
|
|
ebb439 |
- const struct nbrec_load_balancer *nbrec_lb,
|
|
|
ebb439 |
- struct hmap *ports, struct hmap *monitor_map)
|
|
|
ebb439 |
+static void
|
|
|
ebb439 |
+ovn_lb_svc_create(struct northd_context *ctx, struct ovn_northd_lb *lb,
|
|
|
ebb439 |
+ struct hmap *monitor_map)
|
|
|
ebb439 |
{
|
|
|
ebb439 |
- struct ovn_lb *lb = xzalloc(sizeof *lb);
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- size_t hash = uuid_hash(&nbrec_lb->header_.uuid);
|
|
|
ebb439 |
- lb->nlb = nbrec_lb;
|
|
|
ebb439 |
- hmap_insert(lbs, &lb->hmap_node, hash);
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- lb->n_vips = smap_count(&nbrec_lb->vips);
|
|
|
ebb439 |
- lb->vips = xcalloc(lb->n_vips, sizeof (struct lb_vip));
|
|
|
ebb439 |
- struct smap_node *node;
|
|
|
ebb439 |
- size_t n_vips = 0;
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- SMAP_FOR_EACH (node, &nbrec_lb->vips) {
|
|
|
ebb439 |
- char *vip;
|
|
|
ebb439 |
- uint16_t port;
|
|
|
ebb439 |
- int addr_family;
|
|
|
ebb439 |
+ for (size_t i = 0; i < lb->n_vips; i++) {
|
|
|
ebb439 |
+ struct ovn_lb_vip *lb_vip = &lb->vips[i];
|
|
|
ebb439 |
+ struct ovn_northd_lb_vip *lb_vip_nb = &lb->vips_nb[i];
|
|
|
ebb439 |
|
|
|
ebb439 |
- if (!ip_address_and_port_from_lb_key(node->key, &vip, &port,
|
|
|
ebb439 |
- &addr_family)) {
|
|
|
ebb439 |
+ if (!lb_vip_nb->lb_health_check) {
|
|
|
ebb439 |
continue;
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
- lb->vips[n_vips].vip = vip;
|
|
|
ebb439 |
- lb->vips[n_vips].vip_port = port;
|
|
|
ebb439 |
- lb->vips[n_vips].addr_family = addr_family;
|
|
|
ebb439 |
- lb->vips[n_vips].backend_ips = xstrdup(node->value);
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- struct nbrec_load_balancer_health_check *lb_health_check = NULL;
|
|
|
ebb439 |
- if (nbrec_lb->protocol && !strcmp(nbrec_lb->protocol, "sctp")) {
|
|
|
ebb439 |
- if (nbrec_lb->n_health_check > 0) {
|
|
|
ebb439 |
- static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
|
|
|
ebb439 |
- VLOG_WARN_RL(&rl,
|
|
|
ebb439 |
- "SCTP load balancers do not currently support "
|
|
|
ebb439 |
- "health checks. Not creating health checks for "
|
|
|
ebb439 |
- "load balancer " UUID_FMT,
|
|
|
ebb439 |
- UUID_ARGS(&nbrec_lb->header_.uuid));
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
- } else {
|
|
|
ebb439 |
- for (size_t i = 0; i < nbrec_lb->n_health_check; i++) {
|
|
|
ebb439 |
- if (!strcmp(nbrec_lb->health_check[i]->vip, node->key)) {
|
|
|
ebb439 |
- lb_health_check = nbrec_lb->health_check[i];
|
|
|
ebb439 |
- break;
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- char *tokstr = xstrdup(node->value);
|
|
|
ebb439 |
- char *save_ptr = NULL;
|
|
|
ebb439 |
- char *token;
|
|
|
ebb439 |
- size_t n_backends = 0;
|
|
|
ebb439 |
- /* Format for a backend ips : IP1:port1,IP2:port2,...". */
|
|
|
ebb439 |
- for (token = strtok_r(tokstr, ",", &save_ptr);
|
|
|
ebb439 |
- token != NULL;
|
|
|
ebb439 |
- token = strtok_r(NULL, ",", &save_ptr)) {
|
|
|
ebb439 |
- n_backends++;
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- free(tokstr);
|
|
|
ebb439 |
- tokstr = xstrdup(node->value);
|
|
|
ebb439 |
- save_ptr = NULL;
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- lb->vips[n_vips].n_backends = n_backends;
|
|
|
ebb439 |
- lb->vips[n_vips].backends = xcalloc(n_backends,
|
|
|
ebb439 |
- sizeof (struct lb_vip_backend));
|
|
|
ebb439 |
- lb->vips[n_vips].health_check = lb_health_check ? true: false;
|
|
|
ebb439 |
+ for (size_t j = 0; j < lb_vip->n_backends; j++) {
|
|
|
ebb439 |
+ struct ovn_lb_backend *backend = &lb_vip->backends[j];
|
|
|
ebb439 |
+ struct ovn_northd_lb_backend *backend_nb =
|
|
|
ebb439 |
+ &lb_vip_nb->backends_nb[j];
|
|
|
ebb439 |
|
|
|
ebb439 |
- size_t i = 0;
|
|
|
ebb439 |
- for (token = strtok_r(tokstr, ",", &save_ptr);
|
|
|
ebb439 |
- token != NULL;
|
|
|
ebb439 |
- token = strtok_r(NULL, ",", &save_ptr)) {
|
|
|
ebb439 |
- char *backend_ip;
|
|
|
ebb439 |
- uint16_t backend_port;
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- if (!ip_address_and_port_from_lb_key(token, &backend_ip,
|
|
|
ebb439 |
- &backend_port,
|
|
|
ebb439 |
- &addr_family)) {
|
|
|
ebb439 |
- continue;
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- /* Get the logical port to which this ip belongs to. */
|
|
|
ebb439 |
- struct ovn_port *op = NULL;
|
|
|
ebb439 |
- char *svc_mon_src_ip = NULL;
|
|
|
ebb439 |
- const char *s = smap_get(&nbrec_lb->ip_port_mappings,
|
|
|
ebb439 |
- backend_ip);
|
|
|
ebb439 |
- if (s) {
|
|
|
ebb439 |
- char *port_name = xstrdup(s);
|
|
|
ebb439 |
- char *p = strstr(port_name, ":");
|
|
|
ebb439 |
- if (p) {
|
|
|
ebb439 |
- *p = 0;
|
|
|
ebb439 |
- p++;
|
|
|
ebb439 |
- op = ovn_port_find(ports, port_name);
|
|
|
ebb439 |
- svc_mon_src_ip = xstrdup(p);
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
- free(port_name);
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- lb->vips[n_vips].backends[i].ip = backend_ip;
|
|
|
ebb439 |
- lb->vips[n_vips].backends[i].port = backend_port;
|
|
|
ebb439 |
- lb->vips[n_vips].backends[i].addr_family = addr_family;
|
|
|
ebb439 |
- lb->vips[n_vips].backends[i].op = op;
|
|
|
ebb439 |
- lb->vips[n_vips].backends[i].svc_mon_src_ip = svc_mon_src_ip;
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- if (lb_health_check && op && svc_mon_src_ip) {
|
|
|
ebb439 |
- const char *protocol = nbrec_lb->protocol;
|
|
|
ebb439 |
+ if (backend_nb->op && backend_nb->svc_mon_src_ip) {
|
|
|
ebb439 |
+ const char *protocol = lb->nlb->protocol;
|
|
|
ebb439 |
if (!protocol || !protocol[0]) {
|
|
|
ebb439 |
protocol = "tcp";
|
|
|
ebb439 |
}
|
|
|
ebb439 |
- lb->vips[n_vips].backends[i].health_check = true;
|
|
|
ebb439 |
+ backend_nb->health_check = true;
|
|
|
ebb439 |
struct service_monitor_info *mon_info =
|
|
|
ebb439 |
- create_or_get_service_mon(ctx, monitor_map, backend_ip,
|
|
|
ebb439 |
- op->nbsp->name, backend_port,
|
|
|
ebb439 |
+ create_or_get_service_mon(ctx, monitor_map,
|
|
|
ebb439 |
+ backend->ip_str,
|
|
|
ebb439 |
+ backend_nb->op->nbsp->name,
|
|
|
ebb439 |
+ backend->port,
|
|
|
ebb439 |
protocol);
|
|
|
ebb439 |
|
|
|
ebb439 |
ovs_assert(mon_info);
|
|
|
ebb439 |
sbrec_service_monitor_set_options(
|
|
|
ebb439 |
- mon_info->sbrec_mon, &lb_health_check->options);
|
|
|
ebb439 |
+ mon_info->sbrec_mon, &lb_vip_nb->lb_health_check->options);
|
|
|
ebb439 |
struct eth_addr ea;
|
|
|
ebb439 |
if (!mon_info->sbrec_mon->src_mac ||
|
|
|
ebb439 |
!eth_addr_from_string(mon_info->sbrec_mon->src_mac, &ea) ||
|
|
|
ebb439 |
@@ -3557,89 +3411,45 @@ ovn_lb_create(struct northd_context *ctx, struct hmap *lbs,
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
if (!mon_info->sbrec_mon->src_ip ||
|
|
|
ebb439 |
- strcmp(mon_info->sbrec_mon->src_ip, svc_mon_src_ip)) {
|
|
|
ebb439 |
- sbrec_service_monitor_set_src_ip(mon_info->sbrec_mon,
|
|
|
ebb439 |
- svc_mon_src_ip);
|
|
|
ebb439 |
+ strcmp(mon_info->sbrec_mon->src_ip,
|
|
|
ebb439 |
+ backend_nb->svc_mon_src_ip)) {
|
|
|
ebb439 |
+ sbrec_service_monitor_set_src_ip(
|
|
|
ebb439 |
+ mon_info->sbrec_mon,
|
|
|
ebb439 |
+ backend_nb->svc_mon_src_ip);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
- lb->vips[n_vips].backends[i].sbrec_monitor =
|
|
|
ebb439 |
- mon_info->sbrec_mon;
|
|
|
ebb439 |
+ backend_nb->sbrec_monitor = mon_info->sbrec_mon;
|
|
|
ebb439 |
mon_info->required = true;
|
|
|
ebb439 |
- } else {
|
|
|
ebb439 |
- lb->vips[n_vips].backends[i].health_check = false;
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- i++;
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- free(tokstr);
|
|
|
ebb439 |
- n_vips++;
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- char *proto = NULL;
|
|
|
ebb439 |
- if (nbrec_lb->protocol && nbrec_lb->protocol[0]) {
|
|
|
ebb439 |
- proto = nbrec_lb->protocol;
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- if (lb->nlb->n_selection_fields) {
|
|
|
ebb439 |
- struct ds sel_fields = DS_EMPTY_INITIALIZER;
|
|
|
ebb439 |
- for (size_t i = 0; i < lb->nlb->n_selection_fields; i++) {
|
|
|
ebb439 |
- char *field = lb->nlb->selection_fields[i];
|
|
|
ebb439 |
- if (!strcmp(field, "tp_src") && proto) {
|
|
|
ebb439 |
- ds_put_format(&sel_fields, "%s_src,", proto);
|
|
|
ebb439 |
- } else if (!strcmp(field, "tp_dst") && proto) {
|
|
|
ebb439 |
- ds_put_format(&sel_fields, "%s_dst,", proto);
|
|
|
ebb439 |
- } else {
|
|
|
ebb439 |
- ds_put_format(&sel_fields, "%s,", field);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
}
|
|
|
ebb439 |
- ds_chomp(&sel_fields, ',');
|
|
|
ebb439 |
- lb->selection_fields = ds_steal_cstr(&sel_fields);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- return lb;
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
-static void
|
|
|
ebb439 |
-ovn_lb_destroy(struct ovn_lb *lb)
|
|
|
ebb439 |
-{
|
|
|
ebb439 |
- for (size_t i = 0; i < lb->n_vips; i++) {
|
|
|
ebb439 |
- free(lb->vips[i].vip);
|
|
|
ebb439 |
- free(lb->vips[i].backend_ips);
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- for (size_t j = 0; j < lb->vips[i].n_backends; j++) {
|
|
|
ebb439 |
- free(lb->vips[i].backends[j].ip);
|
|
|
ebb439 |
- free(lb->vips[i].backends[j].svc_mon_src_ip);
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- free(lb->vips[i].backends);
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
- free(lb->vips);
|
|
|
ebb439 |
- free(lb->selection_fields);
|
|
|
ebb439 |
- free(lb->dps);
|
|
|
ebb439 |
-}
|
|
|
ebb439 |
-
|
|
|
ebb439 |
-static void build_lb_vip_ct_lb_actions(struct lb_vip *lb_vip,
|
|
|
ebb439 |
- struct ds *action,
|
|
|
ebb439 |
- char *selection_fields)
|
|
|
ebb439 |
+static
|
|
|
ebb439 |
+void build_lb_vip_ct_lb_actions(struct ovn_lb_vip *lb_vip,
|
|
|
ebb439 |
+ struct ovn_northd_lb_vip *lb_vip_nb,
|
|
|
ebb439 |
+ struct ds *action,
|
|
|
ebb439 |
+ char *selection_fields)
|
|
|
ebb439 |
{
|
|
|
ebb439 |
bool skip_hash_fields = false;
|
|
|
ebb439 |
|
|
|
ebb439 |
- if (lb_vip->health_check) {
|
|
|
ebb439 |
+ if (lb_vip_nb->lb_health_check) {
|
|
|
ebb439 |
ds_put_cstr(action, "ct_lb(backends=");
|
|
|
ebb439 |
|
|
|
ebb439 |
size_t n_active_backends = 0;
|
|
|
ebb439 |
- for (size_t k = 0; k < lb_vip->n_backends; k++) {
|
|
|
ebb439 |
- struct lb_vip_backend *backend = &lb_vip->backends[k];
|
|
|
ebb439 |
- if (backend->health_check && backend->sbrec_monitor &&
|
|
|
ebb439 |
- backend->sbrec_monitor->status &&
|
|
|
ebb439 |
- strcmp(backend->sbrec_monitor->status, "online")) {
|
|
|
ebb439 |
+ for (size_t i = 0; i < lb_vip->n_backends; i++) {
|
|
|
ebb439 |
+ struct ovn_lb_backend *backend = &lb_vip->backends[i];
|
|
|
ebb439 |
+ struct ovn_northd_lb_backend *backend_nb =
|
|
|
ebb439 |
+ &lb_vip_nb->backends_nb[i];
|
|
|
ebb439 |
+ if (backend_nb->health_check && backend_nb->sbrec_monitor &&
|
|
|
ebb439 |
+ backend_nb->sbrec_monitor->status &&
|
|
|
ebb439 |
+ strcmp(backend_nb->sbrec_monitor->status, "online")) {
|
|
|
ebb439 |
continue;
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
n_active_backends++;
|
|
|
ebb439 |
ds_put_format(action, "%s:%"PRIu16",",
|
|
|
ebb439 |
- backend->ip, backend->port);
|
|
|
ebb439 |
+ backend->ip_str, backend->port);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
if (!n_active_backends) {
|
|
|
ebb439 |
@@ -3651,7 +3461,7 @@ static void build_lb_vip_ct_lb_actions(struct lb_vip *lb_vip,
|
|
|
ebb439 |
ds_put_cstr(action, ");");
|
|
|
ebb439 |
}
|
|
|
ebb439 |
} else {
|
|
|
ebb439 |
- ds_put_format(action, "ct_lb(backends=%s);", lb_vip->backend_ips);
|
|
|
ebb439 |
+ ds_put_format(action, "ct_lb(backends=%s);", lb_vip_nb->backend_ips);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
if (!skip_hash_fields && selection_fields && selection_fields[0]) {
|
|
|
ebb439 |
@@ -3681,7 +3491,14 @@ build_ovn_lbs(struct northd_context *ctx, struct hmap *datapaths,
|
|
|
ebb439 |
|
|
|
ebb439 |
const struct nbrec_load_balancer *nbrec_lb;
|
|
|
ebb439 |
NBREC_LOAD_BALANCER_FOR_EACH (nbrec_lb, ctx->ovnnb_idl) {
|
|
|
ebb439 |
- ovn_lb_create(ctx, lbs, nbrec_lb, ports, &monitor_map);
|
|
|
ebb439 |
+ struct ovn_northd_lb *lb =
|
|
|
ebb439 |
+ ovn_northd_lb_create(nbrec_lb, ports, (void *)ovn_port_find);
|
|
|
ebb439 |
+ hmap_insert(lbs, &lb->hmap_node, uuid_hash(&nbrec_lb->header_.uuid));
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ struct ovn_northd_lb *lb;
|
|
|
ebb439 |
+ HMAP_FOR_EACH (lb, hmap_node, lbs) {
|
|
|
ebb439 |
+ ovn_lb_svc_create(ctx, lb, &monitor_map);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
struct ovn_datapath *od;
|
|
|
ebb439 |
@@ -3693,14 +3510,12 @@ build_ovn_lbs(struct northd_context *ctx, struct hmap *datapaths,
|
|
|
ebb439 |
for (size_t i = 0; i < od->nbs->n_load_balancer; i++) {
|
|
|
ebb439 |
const struct uuid *lb_uuid =
|
|
|
ebb439 |
&od->nbs->load_balancer[i]->header_.uuid;
|
|
|
ebb439 |
- struct ovn_lb *lb = ovn_lb_find(lbs, lb_uuid);
|
|
|
ebb439 |
+ lb = ovn_northd_lb_find(lbs, lb_uuid);
|
|
|
ebb439 |
|
|
|
ebb439 |
- ovn_lb_add_datapath(lb, od);
|
|
|
ebb439 |
+ ovn_northd_lb_add_datapath(lb, od->sb);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
- struct ovn_lb *lb;
|
|
|
ebb439 |
-
|
|
|
ebb439 |
/* Delete any stale SB load balancer rows. */
|
|
|
ebb439 |
const struct sbrec_load_balancer *sbrec_lb, *next;
|
|
|
ebb439 |
SBREC_LOAD_BALANCER_FOR_EACH_SAFE (sbrec_lb, next, ctx->ovnsb_idl) {
|
|
|
ebb439 |
@@ -3711,7 +3526,7 @@ build_ovn_lbs(struct northd_context *ctx, struct hmap *datapaths,
|
|
|
ebb439 |
continue;
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
- lb = ovn_lb_find(lbs, &lb_uuid);
|
|
|
ebb439 |
+ lb = ovn_northd_lb_find(lbs, &lb_uuid);
|
|
|
ebb439 |
if (lb && lb->n_dps) {
|
|
|
ebb439 |
lb->slb = sbrec_lb;
|
|
|
ebb439 |
} else {
|
|
|
ebb439 |
@@ -3756,7 +3571,7 @@ build_ovn_lbs(struct northd_context *ctx, struct hmap *datapaths,
|
|
|
ebb439 |
for (size_t i = 0; i < od->nbs->n_load_balancer; i++) {
|
|
|
ebb439 |
const struct uuid *lb_uuid =
|
|
|
ebb439 |
&od->nbs->load_balancer[i]->header_.uuid;
|
|
|
ebb439 |
- lb = ovn_lb_find(lbs, lb_uuid);
|
|
|
ebb439 |
+ lb = ovn_northd_lb_find(lbs, lb_uuid);
|
|
|
ebb439 |
sbrec_lbs[i] = lb->slb;
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
@@ -3777,16 +3592,6 @@ build_ovn_lbs(struct northd_context *ctx, struct hmap *datapaths,
|
|
|
ebb439 |
hmap_destroy(&monitor_map);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
-static void
|
|
|
ebb439 |
-destroy_ovn_lbs(struct hmap *lbs)
|
|
|
ebb439 |
-{
|
|
|
ebb439 |
- struct ovn_lb *lb;
|
|
|
ebb439 |
- HMAP_FOR_EACH_POP (lb, hmap_node, lbs) {
|
|
|
ebb439 |
- ovn_lb_destroy(lb);
|
|
|
ebb439 |
- free(lb);
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
-}
|
|
|
ebb439 |
-
|
|
|
ebb439 |
/* Updates the southbound Port_Binding table so that it contains the logical
|
|
|
ebb439 |
* switch ports specified by the northbound database.
|
|
|
ebb439 |
*
|
|
|
ebb439 |
@@ -5171,7 +4976,7 @@ ls_has_dns_records(const struct nbrec_logical_switch *nbs)
|
|
|
ebb439 |
|
|
|
ebb439 |
static void
|
|
|
ebb439 |
build_empty_lb_event_flow(struct ovn_datapath *od, struct hmap *lflows,
|
|
|
ebb439 |
- struct lb_vip *lb_vip,
|
|
|
ebb439 |
+ struct ovn_lb_vip *lb_vip,
|
|
|
ebb439 |
struct nbrec_load_balancer *lb,
|
|
|
ebb439 |
int pl, struct shash *meter_groups)
|
|
|
ebb439 |
{
|
|
|
ebb439 |
@@ -5179,7 +4984,7 @@ build_empty_lb_event_flow(struct ovn_datapath *od, struct hmap *lflows,
|
|
|
ebb439 |
return;
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
- bool ipv4 = (lb_vip->addr_family == AF_INET);
|
|
|
ebb439 |
+ bool ipv4 = IN6_IS_ADDR_V4MAPPED(&lb_vip->vip);
|
|
|
ebb439 |
struct ds match = DS_EMPTY_INITIALIZER;
|
|
|
ebb439 |
char *meter = "", *action;
|
|
|
ebb439 |
|
|
|
ebb439 |
@@ -5188,13 +4993,13 @@ build_empty_lb_event_flow(struct ovn_datapath *od, struct hmap *lflows,
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
ds_put_format(&match, "ip%s.dst == %s && %s",
|
|
|
ebb439 |
- ipv4 ? "4": "6", lb_vip->vip, lb->protocol);
|
|
|
ebb439 |
+ ipv4 ? "4": "6", lb_vip->vip_str, lb->protocol);
|
|
|
ebb439 |
|
|
|
ebb439 |
- char *vip = lb_vip->vip;
|
|
|
ebb439 |
+ char *vip = lb_vip->vip_str;
|
|
|
ebb439 |
if (lb_vip->vip_port) {
|
|
|
ebb439 |
ds_put_format(&match, " && %s.dst == %u", lb->protocol,
|
|
|
ebb439 |
lb_vip->vip_port);
|
|
|
ebb439 |
- vip = xasprintf("%s%s%s:%u", ipv4 ? "" : "[", lb_vip->vip,
|
|
|
ebb439 |
+ vip = xasprintf("%s%s%s:%u", ipv4 ? "" : "[", lb_vip->vip_str,
|
|
|
ebb439 |
ipv4 ? "" : "]", lb_vip->vip_port);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
@@ -5268,12 +5073,12 @@ build_pre_lb(struct ovn_datapath *od, struct hmap *lflows,
|
|
|
ebb439 |
bool vip_configured = false;
|
|
|
ebb439 |
for (int i = 0; i < od->nbs->n_load_balancer; i++) {
|
|
|
ebb439 |
struct nbrec_load_balancer *nb_lb = od->nbs->load_balancer[i];
|
|
|
ebb439 |
- struct ovn_lb *lb =
|
|
|
ebb439 |
- ovn_lb_find(lbs, &nb_lb->header_.uuid);
|
|
|
ebb439 |
+ struct ovn_northd_lb *lb =
|
|
|
ebb439 |
+ ovn_northd_lb_find(lbs, &nb_lb->header_.uuid);
|
|
|
ebb439 |
ovs_assert(lb);
|
|
|
ebb439 |
|
|
|
ebb439 |
for (size_t j = 0; j < lb->n_vips; j++) {
|
|
|
ebb439 |
- struct lb_vip *lb_vip = &lb->vips[j];
|
|
|
ebb439 |
+ struct ovn_lb_vip *lb_vip = &lb->vips[j];
|
|
|
ebb439 |
build_empty_lb_event_flow(od, lflows, lb_vip, nb_lb,
|
|
|
ebb439 |
S_SWITCH_IN_PRE_LB, meter_groups);
|
|
|
ebb439 |
|
|
|
ebb439 |
@@ -6008,7 +5813,8 @@ build_lb(struct ovn_datapath *od, struct hmap *lflows)
|
|
|
ebb439 |
|
|
|
ebb439 |
static void
|
|
|
ebb439 |
build_lb_hairpin_rules(struct ovn_datapath *od, struct hmap *lflows,
|
|
|
ebb439 |
- struct ovn_lb *lb, struct lb_vip *lb_vip,
|
|
|
ebb439 |
+ struct ovn_northd_lb *lb,
|
|
|
ebb439 |
+ struct ovn_lb_vip *lb_vip,
|
|
|
ebb439 |
const char *ip_match, const char *proto)
|
|
|
ebb439 |
{
|
|
|
ebb439 |
if (lb_vip->n_backends == 0) {
|
|
|
ebb439 |
@@ -6030,7 +5836,7 @@ build_lb_hairpin_rules(struct ovn_datapath *od, struct hmap *lflows,
|
|
|
ebb439 |
*/
|
|
|
ebb439 |
ds_put_char(&match_reply, '(');
|
|
|
ebb439 |
for (size_t i = 0; i < lb_vip->n_backends; i++) {
|
|
|
ebb439 |
- struct lb_vip_backend *backend = &lb_vip->backends[i];
|
|
|
ebb439 |
+ struct ovn_lb_backend *backend = &lb_vip->backends[i];
|
|
|
ebb439 |
|
|
|
ebb439 |
/* Packets that after load balancing have equal source and
|
|
|
ebb439 |
* destination IPs should be hairpinned.
|
|
|
ebb439 |
@@ -6040,7 +5846,7 @@ build_lb_hairpin_rules(struct ovn_datapath *od, struct hmap *lflows,
|
|
|
ebb439 |
proto, backend->port);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
ds_put_format(&match_initiator, "(%s.src == %s && %s.dst == %s%s)",
|
|
|
ebb439 |
- ip_match, backend->ip, ip_match, backend->ip,
|
|
|
ebb439 |
+ ip_match, backend->ip_str, ip_match, backend->ip_str,
|
|
|
ebb439 |
ds_cstr(&proto_match));
|
|
|
ebb439 |
|
|
|
ebb439 |
/* Replies to hairpinned traffic are originated by backend->ip:port. */
|
|
|
ebb439 |
@@ -6049,8 +5855,8 @@ build_lb_hairpin_rules(struct ovn_datapath *od, struct hmap *lflows,
|
|
|
ebb439 |
ds_put_format(&proto_match, " && %s.src == %"PRIu16, proto,
|
|
|
ebb439 |
backend->port);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
- ds_put_format(&match_reply, "(%s.src == %s%s)", ip_match, backend->ip,
|
|
|
ebb439 |
- ds_cstr(&proto_match));
|
|
|
ebb439 |
+ ds_put_format(&match_reply, "(%s.src == %s%s)",
|
|
|
ebb439 |
+ ip_match, backend->ip_str, ds_cstr(&proto_match));
|
|
|
ebb439 |
ds_clear(&proto_match);
|
|
|
ebb439 |
|
|
|
ebb439 |
if (i < lb_vip->n_backends - 1) {
|
|
|
ebb439 |
@@ -6064,13 +5870,13 @@ build_lb_hairpin_rules(struct ovn_datapath *od, struct hmap *lflows,
|
|
|
ebb439 |
* also directed through OVN.
|
|
|
ebb439 |
*/
|
|
|
ebb439 |
ds_put_format(&action, REGBIT_HAIRPIN " = 1; ct_snat(%s);",
|
|
|
ebb439 |
- lb_vip->vip);
|
|
|
ebb439 |
+ lb_vip->vip_str);
|
|
|
ebb439 |
ovn_lflow_add_with_hint(lflows, od, S_SWITCH_IN_PRE_HAIRPIN, 2,
|
|
|
ebb439 |
ds_cstr(&match_initiator), ds_cstr(&action),
|
|
|
ebb439 |
&lb->nlb->header_);
|
|
|
ebb439 |
|
|
|
ebb439 |
/* Replies to hairpinned traffic are destined to the LB VIP. */
|
|
|
ebb439 |
- ds_put_format(&match_reply, " && %s.dst == %s", ip_match, lb_vip->vip);
|
|
|
ebb439 |
+ ds_put_format(&match_reply, " && %s.dst == %s", ip_match, lb_vip->vip_str);
|
|
|
ebb439 |
|
|
|
ebb439 |
/* UNSNAT replies for hairpinned traffic. */
|
|
|
ebb439 |
ovn_lflow_add_with_hint(lflows, od, S_SWITCH_IN_PRE_HAIRPIN, 1,
|
|
|
ebb439 |
@@ -6085,13 +5891,15 @@ build_lb_hairpin_rules(struct ovn_datapath *od, struct hmap *lflows,
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
static void
|
|
|
ebb439 |
-build_lb_rules(struct ovn_datapath *od, struct hmap *lflows, struct ovn_lb *lb)
|
|
|
ebb439 |
+build_lb_rules(struct ovn_datapath *od, struct hmap *lflows,
|
|
|
ebb439 |
+ struct ovn_northd_lb *lb)
|
|
|
ebb439 |
{
|
|
|
ebb439 |
for (size_t i = 0; i < lb->n_vips; i++) {
|
|
|
ebb439 |
- struct lb_vip *lb_vip = &lb->vips[i];
|
|
|
ebb439 |
+ struct ovn_lb_vip *lb_vip = &lb->vips[i];
|
|
|
ebb439 |
+ struct ovn_northd_lb_vip *lb_vip_nb = &lb->vips_nb[i];
|
|
|
ebb439 |
|
|
|
ebb439 |
const char *ip_match = NULL;
|
|
|
ebb439 |
- if (lb_vip->addr_family == AF_INET) {
|
|
|
ebb439 |
+ if (IN6_IS_ADDR_V4MAPPED(&lb_vip->vip)) {
|
|
|
ebb439 |
ip_match = "ip4";
|
|
|
ebb439 |
} else {
|
|
|
ebb439 |
ip_match = "ip6";
|
|
|
ebb439 |
@@ -6111,10 +5919,12 @@ build_lb_rules(struct ovn_datapath *od, struct hmap *lflows, struct ovn_lb *lb)
|
|
|
ebb439 |
|
|
|
ebb439 |
/* New connections in Ingress table. */
|
|
|
ebb439 |
struct ds action = DS_EMPTY_INITIALIZER;
|
|
|
ebb439 |
- build_lb_vip_ct_lb_actions(lb_vip, &action, lb->selection_fields);
|
|
|
ebb439 |
+ build_lb_vip_ct_lb_actions(lb_vip, lb_vip_nb, &action,
|
|
|
ebb439 |
+ lb->selection_fields);
|
|
|
ebb439 |
|
|
|
ebb439 |
struct ds match = DS_EMPTY_INITIALIZER;
|
|
|
ebb439 |
- ds_put_format(&match, "ct.new && %s.dst == %s", ip_match, lb_vip->vip);
|
|
|
ebb439 |
+ ds_put_format(&match, "ct.new && %s.dst == %s", ip_match,
|
|
|
ebb439 |
+ lb_vip->vip_str);
|
|
|
ebb439 |
if (lb_vip->vip_port) {
|
|
|
ebb439 |
ds_put_format(&match, " && %s.dst == %d", proto, lb_vip->vip_port);
|
|
|
ebb439 |
ovn_lflow_add_with_hint(lflows, od, S_SWITCH_IN_STATEFUL, 120,
|
|
|
ebb439 |
@@ -6174,8 +5984,8 @@ build_stateful(struct ovn_datapath *od, struct hmap *lflows, struct hmap *lbs)
|
|
|
ebb439 |
* connection, so it is okay if we do not hit the above match on
|
|
|
ebb439 |
* REGBIT_CONNTRACK_COMMIT. */
|
|
|
ebb439 |
for (int i = 0; i < od->nbs->n_load_balancer; i++) {
|
|
|
ebb439 |
- struct ovn_lb *lb =
|
|
|
ebb439 |
- ovn_lb_find(lbs, &od->nbs->load_balancer[i]->header_.uuid);
|
|
|
ebb439 |
+ struct ovn_northd_lb *lb =
|
|
|
ebb439 |
+ ovn_northd_lb_find(lbs, &od->nbs->load_balancer[i]->header_.uuid);
|
|
|
ebb439 |
|
|
|
ebb439 |
ovs_assert(lb);
|
|
|
ebb439 |
build_lb_rules(od, lflows, lb);
|
|
|
ebb439 |
@@ -7110,22 +6920,24 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
|
|
|
ebb439 |
|
|
|
ebb439 |
/* Ingress table 13: ARP/ND responder for service monitor source ip.
|
|
|
ebb439 |
* (priority 110)*/
|
|
|
ebb439 |
- struct ovn_lb *lb;
|
|
|
ebb439 |
+ struct ovn_northd_lb *lb;
|
|
|
ebb439 |
HMAP_FOR_EACH (lb, hmap_node, lbs) {
|
|
|
ebb439 |
for (size_t i = 0; i < lb->n_vips; i++) {
|
|
|
ebb439 |
- if (!lb->vips[i].health_check) {
|
|
|
ebb439 |
+ struct ovn_northd_lb_vip *lb_vip_nb = &lb->vips_nb[i];
|
|
|
ebb439 |
+ if (!lb_vip_nb->lb_health_check) {
|
|
|
ebb439 |
continue;
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
- for (size_t j = 0; j < lb->vips[i].n_backends; j++) {
|
|
|
ebb439 |
- if (!lb->vips[i].backends[j].op ||
|
|
|
ebb439 |
- !lb->vips[i].backends[j].svc_mon_src_ip) {
|
|
|
ebb439 |
+ for (size_t j = 0; j < lb_vip_nb->n_backends; j++) {
|
|
|
ebb439 |
+ struct ovn_northd_lb_backend *backend_nb =
|
|
|
ebb439 |
+ &lb_vip_nb->backends_nb[i];
|
|
|
ebb439 |
+ if (!backend_nb->op || !backend_nb->svc_mon_src_ip) {
|
|
|
ebb439 |
continue;
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
ds_clear(&match);
|
|
|
ebb439 |
ds_put_format(&match, "arp.tpa == %s && arp.op == 1",
|
|
|
ebb439 |
- lb->vips[i].backends[j].svc_mon_src_ip);
|
|
|
ebb439 |
+ backend_nb->svc_mon_src_ip);
|
|
|
ebb439 |
ds_clear(&actions);
|
|
|
ebb439 |
ds_put_format(&actions,
|
|
|
ebb439 |
"eth.dst = eth.src; "
|
|
|
ebb439 |
@@ -7139,9 +6951,9 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
|
|
|
ebb439 |
"flags.loopback = 1; "
|
|
|
ebb439 |
"output;",
|
|
|
ebb439 |
svc_monitor_mac, svc_monitor_mac,
|
|
|
ebb439 |
- lb->vips[i].backends[j].svc_mon_src_ip);
|
|
|
ebb439 |
+ backend_nb->svc_mon_src_ip);
|
|
|
ebb439 |
ovn_lflow_add_with_hint(lflows,
|
|
|
ebb439 |
- lb->vips[i].backends[j].op->od,
|
|
|
ebb439 |
+ backend_nb->op->od,
|
|
|
ebb439 |
S_SWITCH_IN_ARP_ND_RSP, 110,
|
|
|
ebb439 |
ds_cstr(&match), ds_cstr(&actions),
|
|
|
ebb439 |
&lb->nlb->header_);
|
|
|
ebb439 |
@@ -8319,7 +8131,7 @@ get_force_snat_ip(struct ovn_datapath *od, const char *key_type,
|
|
|
ebb439 |
static void
|
|
|
ebb439 |
add_router_lb_flow(struct hmap *lflows, struct ovn_datapath *od,
|
|
|
ebb439 |
struct ds *match, struct ds *actions, int priority,
|
|
|
ebb439 |
- bool lb_force_snat_ip, struct lb_vip *lb_vip,
|
|
|
ebb439 |
+ bool lb_force_snat_ip, struct ovn_lb_vip *lb_vip,
|
|
|
ebb439 |
const char *proto, struct nbrec_load_balancer *lb,
|
|
|
ebb439 |
struct shash *meter_groups, struct sset *nat_entries)
|
|
|
ebb439 |
{
|
|
|
ebb439 |
@@ -8355,13 +8167,13 @@ add_router_lb_flow(struct hmap *lflows, struct ovn_datapath *od,
|
|
|
ebb439 |
free(est_match);
|
|
|
ebb439 |
|
|
|
ebb439 |
const char *ip_match = NULL;
|
|
|
ebb439 |
- if (lb_vip->addr_family == AF_INET) {
|
|
|
ebb439 |
+ if (IN6_IS_ADDR_V4MAPPED(&lb_vip->vip)) {
|
|
|
ebb439 |
ip_match = "ip4";
|
|
|
ebb439 |
} else {
|
|
|
ebb439 |
ip_match = "ip6";
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
- if (sset_contains(nat_entries, lb_vip->vip)) {
|
|
|
ebb439 |
+ if (sset_contains(nat_entries, lb_vip->vip_str)) {
|
|
|
ebb439 |
/* The load balancer vip is also present in the NAT entries.
|
|
|
ebb439 |
* So add a high priority lflow to advance the the packet
|
|
|
ebb439 |
* destined to the vip (and the vip port if defined)
|
|
|
ebb439 |
@@ -8375,7 +8187,7 @@ add_router_lb_flow(struct hmap *lflows, struct ovn_datapath *od,
|
|
|
ebb439 |
* S_ROUTER_IN_DNAT stage. */
|
|
|
ebb439 |
struct ds unsnat_match = DS_EMPTY_INITIALIZER;
|
|
|
ebb439 |
ds_put_format(&unsnat_match, "%s && %s.dst == %s && %s",
|
|
|
ebb439 |
- ip_match, ip_match, lb_vip->vip, proto);
|
|
|
ebb439 |
+ ip_match, ip_match, lb_vip->vip_str, proto);
|
|
|
ebb439 |
if (lb_vip->vip_port) {
|
|
|
ebb439 |
ds_put_format(&unsnat_match, " && %s.dst == %d", proto,
|
|
|
ebb439 |
lb_vip->vip_port);
|
|
|
ebb439 |
@@ -8399,8 +8211,9 @@ add_router_lb_flow(struct hmap *lflows, struct ovn_datapath *od,
|
|
|
ebb439 |
ds_put_format(&undnat_match, "%s && (", ip_match);
|
|
|
ebb439 |
|
|
|
ebb439 |
for (size_t i = 0; i < lb_vip->n_backends; i++) {
|
|
|
ebb439 |
- struct lb_vip_backend *backend = &lb_vip->backends[i];
|
|
|
ebb439 |
- ds_put_format(&undnat_match, "(%s.src == %s", ip_match, backend->ip);
|
|
|
ebb439 |
+ struct ovn_lb_backend *backend = &lb_vip->backends[i];
|
|
|
ebb439 |
+ ds_put_format(&undnat_match, "(%s.src == %s", ip_match,
|
|
|
ebb439 |
+ backend->ip_str);
|
|
|
ebb439 |
|
|
|
ebb439 |
if (backend->port) {
|
|
|
ebb439 |
ds_put_format(&undnat_match, " && %s.src == %d) || ",
|
|
|
ebb439 |
@@ -10095,18 +9908,19 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
|
|
|
ebb439 |
|
|
|
ebb439 |
for (int i = 0; i < od->nbr->n_load_balancer; i++) {
|
|
|
ebb439 |
struct nbrec_load_balancer *nb_lb = od->nbr->load_balancer[i];
|
|
|
ebb439 |
- struct ovn_lb *lb =
|
|
|
ebb439 |
- ovn_lb_find(lbs, &nb_lb->header_.uuid);
|
|
|
ebb439 |
+ struct ovn_northd_lb *lb =
|
|
|
ebb439 |
+ ovn_northd_lb_find(lbs, &nb_lb->header_.uuid);
|
|
|
ebb439 |
ovs_assert(lb);
|
|
|
ebb439 |
|
|
|
ebb439 |
for (size_t j = 0; j < lb->n_vips; j++) {
|
|
|
ebb439 |
- struct lb_vip *lb_vip = &lb->vips[j];
|
|
|
ebb439 |
+ struct ovn_lb_vip *lb_vip = &lb->vips[j];
|
|
|
ebb439 |
+ struct ovn_northd_lb_vip *lb_vip_nb = &lb->vips_nb[j];
|
|
|
ebb439 |
ds_clear(&actions);
|
|
|
ebb439 |
- build_lb_vip_ct_lb_actions(lb_vip, &actions,
|
|
|
ebb439 |
+ build_lb_vip_ct_lb_actions(lb_vip, lb_vip_nb, &actions,
|
|
|
ebb439 |
lb->selection_fields);
|
|
|
ebb439 |
|
|
|
ebb439 |
- if (!sset_contains(&all_ips, lb_vip->vip)) {
|
|
|
ebb439 |
- sset_add(&all_ips, lb_vip->vip);
|
|
|
ebb439 |
+ if (!sset_contains(&all_ips, lb_vip->vip_str)) {
|
|
|
ebb439 |
+ sset_add(&all_ips, lb_vip->vip_str);
|
|
|
ebb439 |
/* If there are any load balancing rules, we should send
|
|
|
ebb439 |
* the packet to conntrack for defragmentation and
|
|
|
ebb439 |
* tracking. This helps with two things.
|
|
|
ebb439 |
@@ -10116,12 +9930,12 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
|
|
|
ebb439 |
* 2. If there are L4 ports in load balancing rules, we
|
|
|
ebb439 |
* need the defragmentation to match on L4 ports. */
|
|
|
ebb439 |
ds_clear(&match);
|
|
|
ebb439 |
- if (lb_vip->addr_family == AF_INET) {
|
|
|
ebb439 |
+ if (IN6_IS_ADDR_V4MAPPED(&lb_vip->vip)) {
|
|
|
ebb439 |
ds_put_format(&match, "ip && ip4.dst == %s",
|
|
|
ebb439 |
- lb_vip->vip);
|
|
|
ebb439 |
- } else if (lb_vip->addr_family == AF_INET6) {
|
|
|
ebb439 |
+ lb_vip->vip_str);
|
|
|
ebb439 |
+ } else {
|
|
|
ebb439 |
ds_put_format(&match, "ip && ip6.dst == %s",
|
|
|
ebb439 |
- lb_vip->vip);
|
|
|
ebb439 |
+ lb_vip->vip_str);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_DEFRAG,
|
|
|
ebb439 |
100, ds_cstr(&match), "ct_next;",
|
|
|
ebb439 |
@@ -10134,12 +9948,12 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
|
|
|
ebb439 |
* on ct.new with an action of "ct_lb($targets);". The other
|
|
|
ebb439 |
* flow is for ct.est with an action of "ct_dnat;". */
|
|
|
ebb439 |
ds_clear(&match);
|
|
|
ebb439 |
- if (lb_vip->addr_family == AF_INET) {
|
|
|
ebb439 |
+ if (IN6_IS_ADDR_V4MAPPED(&lb_vip->vip)) {
|
|
|
ebb439 |
ds_put_format(&match, "ip && ip4.dst == %s",
|
|
|
ebb439 |
- lb_vip->vip);
|
|
|
ebb439 |
- } else if (lb_vip->addr_family == AF_INET6) {
|
|
|
ebb439 |
+ lb_vip->vip_str);
|
|
|
ebb439 |
+ } else {
|
|
|
ebb439 |
ds_put_format(&match, "ip && ip6.dst == %s",
|
|
|
ebb439 |
- lb_vip->vip);
|
|
|
ebb439 |
+ lb_vip->vip_str);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
int prio = 110;
|
|
|
ebb439 |
@@ -12287,7 +12101,11 @@ ovnnb_db_run(struct northd_context *ctx,
|
|
|
ebb439 |
sync_port_groups(ctx, &port_groups);
|
|
|
ebb439 |
sync_meters(ctx);
|
|
|
ebb439 |
sync_dns_entries(ctx, datapaths);
|
|
|
ebb439 |
- destroy_ovn_lbs(&lbs;;
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ struct ovn_northd_lb *lb;
|
|
|
ebb439 |
+ HMAP_FOR_EACH_POP (lb, hmap_node, &lbs) {
|
|
|
ebb439 |
+ ovn_northd_lb_destroy(lb);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
hmap_destroy(&lbs;;
|
|
|
ebb439 |
|
|
|
ebb439 |
struct ovn_igmp_group *igmp_group, *next_igmp_group;
|
|
|
ebb439 |
--
|
|
|
ebb439 |
2.28.0
|
|
|
ebb439 |
|