@@ -8,8 +8,8 @@ ovn_controller_ovn_controller_SOURCES = \
ovn/controller/chassis.h \
ovn/controller/encaps.c \
ovn/controller/encaps.h \
- ovn/controller/gchassis.c \
- ovn/controller/gchassis.h \
+ ovn/controller/ha-chassis.c \
+ ovn/controller/ha-chassis.h \
ovn/controller/lflow.c \
ovn/controller/lflow.h \
ovn/controller/lport.c \
@@ -15,7 +15,6 @@
#include <config.h>
#include "bfd.h"
-#include "gchassis.h"
#include "lport.h"
#include "ovn-controller.h"
@@ -89,184 +88,104 @@ bfd_calculate_active_tunnels(const struct ovsrec_bridge *br_int,
}
}
-struct local_datapath_node {
- struct ovs_list node;
- const struct local_datapath *dp;
-};
-
+/* Loops through the HA chassis groups in the SB DB and returns
+ * the set of chassis which the call can establish the BFD sessions
+ * with.
+ * Eg.
+ * If there are 2 HA chassis groups.
+ * Group name - hapgrp1
+ * - HA chassis - (HA1, HA2, HA3)
+ * - ref chassis - (C1, C2)
+ *
+ * Group name - hapgrp2
+ * - HA chassis - (HA1, HA4, HA5)
+ * - ref chassis - (C1, C3, C4)
+ *
+ * If 'our_chassis' is HA1 then this function returns
+ * bfd chassis set - (HA2, HA3, HA4 HA5, C1, C2, C3, C4)
+ *
+ * If 'our_chassis' is C1 then this function returns
+ * bfd chassis set - (HA1, HA2, HA3, HA4, HA5)
+ *
+ * If 'our_chassis' is HA5 then this function returns
+ * bfd chassis set - (HA1, HA4, C1, C3, C4)
+ *
+ * If 'our_chassis' is C2 then this function returns
+ * bfd chassis set - (HA1, HA2, HA3)
+ *
+ * If 'our_chassis' is C5 then this function returns empty bfd set.
+ */
static void
-bfd_travel_gw_related_chassis(
- struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
- const struct local_datapath *dp,
- const struct hmap *local_datapaths,
+bfd_calculate_chassis(
+ const struct sbrec_chassis *our_chassis,
+ const struct sbrec_ha_chassis_group_table *ha_chassis_grp_table,
struct sset *bfd_chassis)
{
- struct ovs_list dp_list;
- const struct sbrec_port_binding *pb;
- struct sset visited_dp = SSET_INITIALIZER(&visited_dp);
- const char *dp_key;
- struct local_datapath_node *dp_binding;
-
- if (!(dp_key = smap_get(&dp->datapath->external_ids, "logical-router")) &&
- !(dp_key = smap_get(&dp->datapath->external_ids, "logical-switch"))) {
- VLOG_INFO("datapath has no uuid, cannot travel graph");
- return;
- }
-
- sset_add(&visited_dp, dp_key);
-
- ovs_list_init(&dp_list);
- dp_binding = xmalloc(sizeof *dp_binding);
- dp_binding->dp = dp;
- ovs_list_push_back(&dp_list, &dp_binding->node);
-
- struct sbrec_port_binding *target = sbrec_port_binding_index_init_row(
- sbrec_port_binding_by_datapath);
-
- /* Go through whole graph to figure out all chassis which may deliver
- * packets to gateway. */
- LIST_FOR_EACH_POP (dp_binding, node, &dp_list) {
- dp = dp_binding->dp;
- free(dp_binding);
- for (size_t i = 0; i < dp->n_peer_dps; i++) {
- const struct sbrec_datapath_binding *pdp = dp->peer_dps[i];
- if (!pdp) {
- continue;
- }
-
- if (!(dp_key = smap_get(&pdp->external_ids, "logical-router")) &&
- !(dp_key = smap_get(&pdp->external_ids, "logical-switch"))) {
+ const struct sbrec_ha_chassis_group *ha_chassis_grp;
+ SBREC_HA_CHASSIS_GROUP_TABLE_FOR_EACH (ha_chassis_grp,
+ ha_chassis_grp_table) {
+ bool is_ha_chassis = false;
+ struct sset grp_chassis = SSET_INITIALIZER(&grp_chassis);
+ const struct sbrec_ha_chassis *ha_ch;
+ bool bfd_setup_required = false;
+ if (ha_chassis_grp->n_ha_chassis < 2) {
+ /* No need to consider the chassis group for BFD if
+ * there is 1 or no chassis in it. */
+ continue;
+ }
+ for (size_t i = 0; i < ha_chassis_grp->n_ha_chassis; i++) {
+ ha_ch = ha_chassis_grp->ha_chassis[i];
+ if (!ha_ch->chassis) {
continue;
}
-
- if (sset_contains(&visited_dp, dp_key)) {
- continue;
+ sset_add(&grp_chassis, ha_ch->chassis->name);
+ if (our_chassis == ha_ch->chassis) {
+ is_ha_chassis = true;
+ bfd_setup_required = true;
}
+ }
- sset_add(&visited_dp, dp_key);
-
- struct hmap_node *node = hmap_first_with_hash(local_datapaths,
- pdp->tunnel_key);
- if (!node) {
- continue;
+ if (is_ha_chassis) {
+ /* It's an HA chassis. So add the ref_chassis to the bfd set. */
+ for (size_t i = 0; i < ha_chassis_grp->n_ref_chassis; i++) {
+ sset_add(&grp_chassis, ha_chassis_grp->ref_chassis[i]->name);
}
-
- dp_binding = xmalloc(sizeof *dp_binding);
- dp_binding->dp = CONTAINER_OF(node, struct local_datapath,
- hmap_node);
- ovs_list_push_back(&dp_list, &dp_binding->node);
-
- sbrec_port_binding_index_set_datapath(target, pdp);
- SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, target,
- sbrec_port_binding_by_datapath) {
- if (pb->chassis) {
- const char *chassis_name = pb->chassis->name;
- if (chassis_name) {
- sset_add(bfd_chassis, chassis_name);
- }
+ } else {
+ /* This is not an HA chassis. Check if this chassis is present
+ * in the ref_chassis list. If so add the ha_chassis to the
+ * sset .*/
+ for (size_t i = 0; i < ha_chassis_grp->n_ref_chassis; i++) {
+ if (our_chassis == ha_chassis_grp->ref_chassis[i]) {
+ bfd_setup_required = true;
+ break;
}
}
}
- }
- sbrec_port_binding_index_destroy_row(target);
-
- sset_destroy(&visited_dp);
-}
-
-static struct ovs_list *
-bfd_find_ha_gateway_chassis(
- struct ovsdb_idl_index *sbrec_chassis_by_name,
- struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
- const struct sbrec_datapath_binding *datapath)
-{
- struct sbrec_port_binding *target = sbrec_port_binding_index_init_row(
- sbrec_port_binding_by_datapath);
- sbrec_port_binding_index_set_datapath(target, datapath);
-
- struct ovs_list *ha_gateway_chassis = NULL;
- const struct sbrec_port_binding *pb;
- SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, target,
- sbrec_port_binding_by_datapath) {
- if (strcmp(pb->type, "chassisredirect")) {
- continue;
- }
-
- struct ovs_list *gateway_chassis = gateway_chassis_get_ordered(
- sbrec_chassis_by_name, pb);
- if (!gateway_chassis || ovs_list_is_short(gateway_chassis)) {
- /* We don't need BFD for non-HA chassisredirect. */
- gateway_chassis_destroy(gateway_chassis);
- continue;
- }
-
- ha_gateway_chassis = gateway_chassis;
- break;
- }
- sbrec_port_binding_index_destroy_row(target);
- return ha_gateway_chassis;
-}
-
-static void
-bfd_calculate_chassis(
- struct ovsdb_idl_index *sbrec_chassis_by_name,
- struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
- const struct sbrec_chassis *our_chassis,
- const struct hmap *local_datapaths,
- struct sset *bfd_chassis)
-{
- /* Identify all chassis nodes to which we need to enable bfd.
- * 1) Any chassis hosting the chassisredirect ports for known
- * router datapaths.
- * 2) Chassis hosting peer datapaths (with ports) connected
- * to a router datapath when our chassis is hosting a router
- * with a chassis redirect port. */
- const struct local_datapath *dp;
- HMAP_FOR_EACH (dp, hmap_node, local_datapaths) {
- const char *is_router = smap_get(&dp->datapath->external_ids,
- "logical-router");
- bool our_chassis_is_gw_for_dp = false;
- if (is_router) {
- struct ovs_list *ha_gateway_chassis
- = bfd_find_ha_gateway_chassis(sbrec_chassis_by_name,
- sbrec_port_binding_by_datapath,
- dp->datapath);
- if (ha_gateway_chassis) {
- our_chassis_is_gw_for_dp = gateway_chassis_contains(
- ha_gateway_chassis, our_chassis);
- struct gateway_chassis *gwc;
- LIST_FOR_EACH (gwc, node, ha_gateway_chassis) {
- if (gwc->db->chassis) {
- sset_add(bfd_chassis, gwc->db->chassis->name);
- }
- }
- gateway_chassis_destroy(ha_gateway_chassis);
+ if (bfd_setup_required) {
+ const char *name;
+ SSET_FOR_EACH (name, &grp_chassis) {
+ sset_add(bfd_chassis, name);
}
}
- if (our_chassis_is_gw_for_dp) {
- bfd_travel_gw_related_chassis(sbrec_port_binding_by_datapath,
- dp, local_datapaths, bfd_chassis);
- }
+ sset_destroy(&grp_chassis);
}
}
void
-bfd_run(struct ovsdb_idl_index *sbrec_chassis_by_name,
- struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
- const struct ovsrec_interface_table *interface_table,
+bfd_run(const struct ovsrec_interface_table *interface_table,
const struct ovsrec_bridge *br_int,
const struct sbrec_chassis *chassis_rec,
- const struct sbrec_sb_global_table *sb_global_table,
- const struct hmap *local_datapaths)
+ const struct sbrec_ha_chassis_group_table *ha_chassis_grp_table,
+ const struct sbrec_sb_global_table *sb_global_table)
{
-
if (!chassis_rec) {
return;
}
struct sset bfd_chassis = SSET_INITIALIZER(&bfd_chassis);
- bfd_calculate_chassis(sbrec_chassis_by_name,
- sbrec_port_binding_by_datapath,
- chassis_rec, local_datapaths, &bfd_chassis);
+ bfd_calculate_chassis(chassis_rec, ha_chassis_grp_table,
+ &bfd_chassis);
+
/* Identify tunnels ports(connected to remote chassis id) to enable bfd */
struct sset tunnels = SSET_INITIALIZER(&tunnels);
struct sset bfd_ifaces = SSET_INITIALIZER(&bfd_ifaces);
@@ -336,7 +255,7 @@ bfd_run(struct ovsdb_idl_index *sbrec_chassis_by_name,
VLOG_INFO("Disabled BFD on interface %s", iface->name);
}
}
- }
+ }
}
smap_destroy(&bfd);
@@ -24,16 +24,17 @@ struct ovsrec_interface_table;
struct ovsrec_open_vswitch_table;
struct sbrec_chassis;
struct sbrec_sb_global_table;
+struct sbrec_ha_chassis_group_table;
struct sset;
void bfd_register_ovs_idl(struct ovsdb_idl *);
-void bfd_run(struct ovsdb_idl_index *sbrec_chassis_by_name,
- struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
- const struct ovsrec_interface_table *interface_table,
+
+void bfd_run(const struct ovsrec_interface_table *interface_table,
const struct ovsrec_bridge *br_int,
const struct sbrec_chassis *chassis_rec,
- const struct sbrec_sb_global_table *sb_global_table,
- const struct hmap *local_datapaths);
+ const struct sbrec_ha_chassis_group_table *ha_chassis_grp_table,
+ const struct sbrec_sb_global_table *sb_global_table);
+
void bfd_calculate_active_tunnels(const struct ovsrec_bridge *br_int,
struct sset *active_tunnels);
@@ -15,7 +15,7 @@
#include <config.h>
#include "binding.h"
-#include "gchassis.h"
+#include "ha-chassis.h"
#include "lflow.h"
#include "lport.h"
@@ -430,7 +430,6 @@ sbrec_get_port_encap(const struct sbrec_chassis *chassis_rec,
static void
consider_local_datapath(struct ovsdb_idl_txn *ovnsb_idl_txn,
struct ovsdb_idl_txn *ovs_idl_txn,
- struct ovsdb_idl_index *sbrec_chassis_by_name,
struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
@@ -445,7 +444,6 @@ consider_local_datapath(struct ovsdb_idl_txn *ovnsb_idl_txn,
{
const struct ovsrec_interface *iface_rec
= shash_find_data(lport_to_iface, binding_rec->logical_port);
- struct ovs_list *gateway_chassis = NULL;
bool our_chassis = false;
if (iface_rec
@@ -478,20 +476,17 @@ consider_local_datapath(struct ovsdb_idl_txn *ovnsb_idl_txn,
binding_rec->datapath, false, local_datapaths);
}
} else if (!strcmp(binding_rec->type, "chassisredirect")) {
- gateway_chassis = gateway_chassis_get_ordered(sbrec_chassis_by_name,
- binding_rec);
- if (gateway_chassis &&
- gateway_chassis_contains(gateway_chassis, chassis_rec)) {
-
- our_chassis = gateway_chassis_is_active(
- gateway_chassis, chassis_rec, active_tunnels);
+ if (ha_chassis_group_contains(binding_rec->ha_chassis_group,
+ chassis_rec)) {
+ our_chassis = ha_chassis_group_is_active(
+ binding_rec->ha_chassis_group,
+ active_tunnels, chassis_rec);
add_local_datapath(sbrec_datapath_binding_by_key,
sbrec_port_binding_by_datapath,
sbrec_port_binding_by_name,
binding_rec->datapath, false, local_datapaths);
}
- gateway_chassis_destroy(gateway_chassis);
} else if (!strcmp(binding_rec->type, "l3gateway")) {
const char *chassis_id = smap_get(&binding_rec->options,
"l3gateway-chassis");
@@ -592,7 +587,6 @@ consider_localnet_port(const struct sbrec_port_binding *binding_rec,
void
binding_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
struct ovsdb_idl_txn *ovs_idl_txn,
- struct ovsdb_idl_index *sbrec_chassis_by_name,
struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
@@ -625,7 +619,6 @@ binding_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
* directly connected logical ports and children of those ports. */
SBREC_PORT_BINDING_TABLE_FOR_EACH (binding_rec, port_binding_table) {
consider_local_datapath(ovnsb_idl_txn, ovs_idl_txn,
- sbrec_chassis_by_name,
sbrec_datapath_binding_by_key,
sbrec_port_binding_by_datapath,
sbrec_port_binding_by_name,
@@ -33,7 +33,6 @@ struct sset;
void binding_register_ovs_idl(struct ovsdb_idl *);
void binding_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
struct ovsdb_idl_txn *ovs_idl_txn,
- struct ovsdb_idl_index *sbrec_chassis_by_name,
struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
deleted file mode 100644
@@ -1,222 +0,0 @@
-/* Copyright (c) 2017, Red Hat, Inc.
- *
- * 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 "gchassis.h"
-#include "lport.h"
-#include "lib/sset.h"
-#include "openvswitch/vlog.h"
-#include "ovn/lib/chassis-index.h"
-#include "ovn/lib/ovn-sb-idl.h"
-
-VLOG_DEFINE_THIS_MODULE(gchassis);
-
-/* gateway_chassis ordering
- */
-static int
-compare_chassis_prio_(const void *a_, const void *b_)
-{
- const struct gateway_chassis *gc_a = a_;
- const struct gateway_chassis *gc_b = b_;
- int prio_diff = gc_b->db->priority - gc_a->db->priority;
- if (!prio_diff) {
- return strcmp(gc_b->db->name, gc_a->db->name);
- }
- return prio_diff;
-}
-
-struct ovs_list*
-gateway_chassis_get_ordered(struct ovsdb_idl_index *sbrec_chassis_by_name,
- const struct sbrec_port_binding *binding)
-{
- const char *redir_chassis_str;
- const struct sbrec_chassis *redirect_chassis = NULL;
-
- /* XXX: redirect-chassis SBDB option handling is supported for backwards
- * compatibility with N-1 version of ovn-northd. This support can
- * be removed in OVS 2.9 where Gateway_Chassis list on the port binding
- * will always be populated by northd */
- redir_chassis_str = smap_get(&binding->options, "redirect-chassis");
-
- if (redir_chassis_str) {
- redirect_chassis = chassis_lookup_by_name(sbrec_chassis_by_name,
- redir_chassis_str);
- if (!redirect_chassis) {
- static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
- VLOG_WARN_RL(&rl, "chassis name (%s) in redirect-chassis option "
- "of logical port %s not known",
- redir_chassis_str, binding->logical_port);
- }
- }
-
- if (!redirect_chassis && binding->n_gateway_chassis == 0) {
- return NULL;
- }
-
- struct gateway_chassis *gateway_chassis = NULL;
- int n = 0;
-
- if (binding->n_gateway_chassis) {
- gateway_chassis = xmalloc(sizeof *gateway_chassis *
- binding->n_gateway_chassis);
- for (n = 0; n < binding->n_gateway_chassis; n++) {
- gateway_chassis[n].db = binding->gateway_chassis[n];
- gateway_chassis[n].virtual_gwc = false;
- }
- qsort(gateway_chassis, n, sizeof *gateway_chassis,
- compare_chassis_prio_);
- } else if (redirect_chassis) {
- /* When only redirect_chassis is available, return a single
- * virtual entry that it's not on OVSDB, this way the code
- * handling the returned list will be uniform, regardless
- * of gateway_chassis being populated or redirect-chassis option
- * being used */
- gateway_chassis = xmalloc(sizeof *gateway_chassis);
- struct sbrec_gateway_chassis *gwc =
- xzalloc(sizeof *gateway_chassis->db);
- sbrec_gateway_chassis_init(gwc);
- gwc->name = xasprintf("%s_%s", binding->logical_port,
- redirect_chassis->name);
- gwc->chassis = CONST_CAST(struct sbrec_chassis *, redirect_chassis);
- gateway_chassis->db = gwc;
- gateway_chassis->virtual_gwc = true;
- n++;
- }
-
- struct ovs_list *list = NULL;
- if (n) {
- list = xmalloc(sizeof *list);
- ovs_list_init(list);
-
- int i;
- for (i = 0; i < n; i++) {
- ovs_list_push_back(list, &gateway_chassis[i].node);
- }
- }
-
- return list;
-}
-
-bool
-gateway_chassis_contains(const struct ovs_list *gateway_chassis,
- const struct sbrec_chassis *chassis) {
- struct gateway_chassis *chassis_item;
- if (gateway_chassis) {
- LIST_FOR_EACH (chassis_item, node, gateway_chassis) {
- if (chassis_item->db->chassis
- && !strcmp(chassis_item->db->chassis->name, chassis->name)) {
- return true;
- }
- }
- }
- return false;
-}
-
-void
-gateway_chassis_destroy(struct ovs_list *list)
-{
- if (!list) {
- return;
- }
-
- /* XXX: This loop is for backwards compatibility with redirect-chassis
- * which we insert as a single virtual Gateway_Chassis on the ordered
- * list */
- struct gateway_chassis *chassis_item;
- LIST_FOR_EACH (chassis_item, node, list) {
- if (chassis_item->virtual_gwc) {
- free(chassis_item->db->name);
- free(CONST_CAST(struct sbrec_gateway_chassis *, chassis_item->db));
- }
- }
-
- free(ovs_list_front(list));
- free(list);
-}
-
-bool
-gateway_chassis_in_pb_contains(const struct sbrec_port_binding *binding,
- const struct sbrec_chassis *chassis)
-{
- if (!binding || !chassis) {
- return false;
- }
-
- /* XXX: redirect-chassis handling for backwards compatibility,
- * with older ovs-northd during upgrade phase, can be removed
- * for OVS 2.9 */
- const char *redirect_chassis = smap_get(&binding->options,
- "redirect-chassis");
- if (binding->n_gateway_chassis) {
- int n;
- for (n = 0; n < binding->n_gateway_chassis; n++) {
- if (binding->gateway_chassis[n]->chassis
- && !strcmp(binding->gateway_chassis[n]->chassis->name,
- chassis->name)) {
- return true;
- }
- }
- } else if (redirect_chassis) {
- return !strcmp(redirect_chassis, chassis->name);
- }
-
- return false;
-}
-
-bool
-gateway_chassis_is_active(const struct ovs_list *gateway_chassis,
- const struct sbrec_chassis *local_chassis,
- const struct sset *active_tunnels)
-{
- struct gateway_chassis *gwc;
-
- if (!gateway_chassis
- || (gateway_chassis && ovs_list_is_empty(gateway_chassis))) {
- return false;
- }
- /* if there's only one chassis, and local chassis is on the list
- * it's not HA and it's the equivalent of being active */
- if (ovs_list_is_singleton(gateway_chassis) &&
- gateway_chassis_contains(gateway_chassis, local_chassis)) {
- return true;
- }
-
- /* if there are no other tunnels active, we assume that the
- * connection providing tunneling is down, hence we're down */
- if (sset_is_empty(active_tunnels)) {
- return false;
- }
-
- /* gateway_chassis is an ordered list, by priority, of chassis
- * hosting the redirect of the port */
- LIST_FOR_EACH (gwc, node, gateway_chassis) {
- if (!gwc->db->chassis) {
- continue;
- }
- /* if we found the chassis on the list, and we didn't exit before
- * on the active_tunnels check for other higher priority chassis
- * being active, then this chassis is master. */
- if (!strcmp(gwc->db->chassis->name, local_chassis->name)) {
- return true;
- }
- /* if we find this specific chassis on the list to have an active
- * tunnel, then 'local_chassis' is not master */
- if (sset_contains(active_tunnels, gwc->db->chassis->name)) {
- return false;
- }
- }
- return false;
-}
deleted file mode 100644
@@ -1,71 +0,0 @@
-/* Copyright (c) 2017 Red Hat, Inc.
- *
- * 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.
- */
-
-#ifndef OVN_GCHASSIS_H
-#define OVN_GCHASSIS_H 1
-
-#include <stdint.h>
-#include "lib/uuid.h"
-#include "openvswitch/hmap.h"
-#include "openvswitch/list.h"
-
-struct ovsdb_idl;
-struct ovsdb_idl_index;
-struct sbrec_chassis;
-struct sbrec_gateway_chassis;
-struct sbrec_port_binding;
-struct sset;
-
-
-/* Gateway_Chassis management
- * ==========================
- *
- * The following structure and methods handle ordering of Gateway_Chassis
- * entries in a chassisredirect port. And parsing redirect-chassis option
- * for backwards compatibility with older (N-1 version of ovn-northd).
- */
-struct gateway_chassis {
- struct ovs_list node;
- const struct sbrec_gateway_chassis *db; /* sbrec row for the gwc */
- bool virtual_gwc; /* db entry not from SBDB, but from redirect-chassis */
-};
-
-/* Gets, and orders by priority/name the list of Gateway_Chassis */
-struct ovs_list *gateway_chassis_get_ordered(
- struct ovsdb_idl_index *sbrec_chassis_by_name,
- const struct sbrec_port_binding *binding);
-
-/* Checks if an specific chassis is contained in the gateway_chassis
- * list */
-bool gateway_chassis_contains(const struct ovs_list *gateway_chassis,
- const struct sbrec_chassis *chassis);
-
-/* Destroy a gateway_chassis list from memory */
-void gateway_chassis_destroy(struct ovs_list *list);
-
-/* Checks if a chassis is referenced in the port_binding gateway_chassis
- * list or redirect-chassis option (backwards compatibility) */
-bool gateway_chassis_in_pb_contains(
- const struct sbrec_port_binding *binding,
- const struct sbrec_chassis *chassis);
-
-/* Returns true if the local chassis is the active gateway among a set
- * of gateway_chassis. Return false if the local chassis is currently a
- * backup in a set of multiple gateway_chassis. */
-bool gateway_chassis_is_active(
- const struct ovs_list *gateway_chassis,
- const struct sbrec_chassis *local_chassis,
- const struct sset *active_tunnels);
-#endif /* ovn/controller/gchassis.h */
new file mode 100644
@@ -0,0 +1,203 @@
+/* Copyright (c) 2019 Red Hat, Inc.
+ *
+ * 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 "ha-chassis.h"
+#include "lib/sset.h"
+#include "openvswitch/vlog.h"
+#include "ovn/lib/ovn-sb-idl.h"
+
+VLOG_DEFINE_THIS_MODULE(ha_chassis);
+
+static int
+compare_chassis_prio_(const void *a_, const void *b_)
+{
+ const struct sbrec_ha_chassis *ch_a = a_;
+ const struct sbrec_ha_chassis *ch_b = b_;
+ int prio_diff = ch_b->priority - ch_a->priority;
+ if (!prio_diff) {
+ return strcmp(ch_b->chassis->name, ch_a->chassis->name);
+ }
+ return prio_diff;
+}
+
+/* Returns the ordered HA chassis list in the HA chassis group.
+ * Eg. If an HA chassis group has 3 HA chassis
+ * - HA1 - pri 30
+ * - HA2 - pri 40 and
+ * - HA3 - pri 20
+ * and the ref_chassis of HA chassis group is set to - C1 and C2.
+ *
+ * If active_tunnels is NULL, then it returns the ordered list
+ * - (HA2, HA1, HA3)
+ *
+ * If active_tunnels is set to - (HA1, HA2, C1, C2) and
+ * local_chassis is HA3, then it returns the ordered list
+ * - (HA2, HA1, HA3)
+ *
+ * If active_tunnels is set to - (HA1, C1, C2) and
+ * local_chassis is HA3, then it returns the ordered list
+ * - (HA1, HA3)
+ *
+ * If active_tunnels is set to - (C1, C2) and
+ * local_chassis is HA3, then it returns the ordered list
+ * - (HA3)
+ *
+ * If active_tunnels is set is empty and local_chassis is HA3,
+ * then it returns NULL.
+ */
+static struct ha_chassis_ordered *
+get_ordered_ha_chassis_list(const struct sbrec_ha_chassis_group *ha_ch_grp,
+ const struct sset *active_tunnels,
+ const struct sbrec_chassis *local_chassis)
+{
+ struct sbrec_ha_chassis *ha_ch_order =
+ xzalloc(sizeof *ha_ch_order * ha_ch_grp->n_ha_chassis);
+
+ size_t n_ha_ch = 0;
+
+ for (size_t i = 0; i < ha_ch_grp->n_ha_chassis; i++) {
+ if (!ha_ch_grp->ha_chassis[i]->chassis) {
+ continue;
+ }
+
+ /* Don't add it to the list for ordering if it is not active. */
+ if (ha_ch_grp->ha_chassis[i]->chassis != local_chassis &&
+ active_tunnels &&
+ !sset_contains(active_tunnels,
+ ha_ch_grp->ha_chassis[i]->chassis->name)) {
+ continue;
+ }
+
+ ha_ch_order[n_ha_ch].chassis = ha_ch_grp->ha_chassis[i]->chassis;
+ ha_ch_order[n_ha_ch].priority = ha_ch_grp->ha_chassis[i]->priority;
+ n_ha_ch++;
+ }
+
+ if (!n_ha_ch) {
+ free(ha_ch_order);
+ return NULL;
+ }
+
+ struct ha_chassis_ordered *ordered_ha_ch;
+ if (n_ha_ch == 1) {
+ if (active_tunnels) {
+ /* If n_ha_ch is 1, it means only the local chassis is in the
+ * ha_ch_order list. Check if this local chassis has active
+ * bfd session with any of the referenced chassis. If so,
+ * then the local chassis can be active. Otherwise it can't.
+ * This can happen in the following scenario.
+ * Lets say we have chassis HA1 (prioirty 20) and HA2 (priority 10)
+ * in the ha_chasis_group and compute chassis C1 and C2 are in the
+ * reference chassis list. If HA1 chassis has lost the link and
+ * when this function is called for HA2 we need to consider
+ * HA2 as active since it has active BFD sessions with C1 and C2.
+ * On HA1 chassis, this function won't be called since
+ * active_tunnels set will be empty.
+ * */
+ bool can_local_chassis_be_active = false;
+ for (size_t i = 0; i < ha_ch_grp->n_ref_chassis; i++) {
+ if (sset_contains(active_tunnels,
+ ha_ch_grp->ref_chassis[i]->name)) {
+ can_local_chassis_be_active = true;
+ break;
+ }
+ }
+ if (!can_local_chassis_be_active) {
+ free(ha_ch_order);
+ return NULL;
+ }
+ }
+ } else {
+ qsort(ha_ch_order, n_ha_ch, sizeof *ha_ch_order,
+ compare_chassis_prio_);
+ }
+
+ ordered_ha_ch = xmalloc(sizeof *ordered_ha_ch);
+ ordered_ha_ch->ha_ch = ha_ch_order;
+ ordered_ha_ch->n_ha_ch = n_ha_ch;
+
+ return ordered_ha_ch;
+}
+
+void
+ha_chassis_destroy_ordered(struct ha_chassis_ordered *ordered_ha_ch)
+{
+ if (ordered_ha_ch) {
+ free(ordered_ha_ch->ha_ch);
+ free(ordered_ha_ch);
+ }
+}
+
+
+/* Returns true if the local_chassis is the master of
+ * the HA chassis group, false otherwise. */
+bool
+ha_chassis_group_is_active(
+ const struct sbrec_ha_chassis_group *ha_ch_grp,
+ const struct sset *active_tunnels,
+ const struct sbrec_chassis *local_chassis)
+{
+ if (!ha_ch_grp || !ha_ch_grp->n_ha_chassis) {
+ return false;
+ }
+
+ if (ha_ch_grp->n_ha_chassis == 1) {
+ return (ha_ch_grp->ha_chassis[0]->chassis == local_chassis);
+ }
+
+ if (sset_is_empty(active_tunnels)) {
+ /* If active tunnel sset is empty, it means it has lost
+ * connectivity with other chassis. */
+ return false;
+ }
+
+ struct ha_chassis_ordered *ordered_ha_ch =
+ get_ordered_ha_chassis_list(ha_ch_grp, active_tunnels, local_chassis);
+ if (!ordered_ha_ch) {
+ return false;
+ }
+
+ struct sbrec_chassis *active_ch = ordered_ha_ch->ha_ch[0].chassis;
+ ha_chassis_destroy_ordered(ordered_ha_ch);
+
+ return (active_ch == local_chassis);
+}
+
+bool
+ha_chassis_group_contains(
+ const struct sbrec_ha_chassis_group *ha_chassis_grp,
+ const struct sbrec_chassis *chassis)
+{
+ if (ha_chassis_grp && chassis) {
+ for (size_t i = 0; i < ha_chassis_grp->n_ha_chassis; i++) {
+ if (ha_chassis_grp->ha_chassis[i]->chassis == chassis) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+struct ha_chassis_ordered *
+ha_chassis_get_ordered(const struct sbrec_ha_chassis_group *ha_chassis_grp)
+{
+ if (!ha_chassis_grp || !ha_chassis_grp->n_ha_chassis) {
+ return NULL;
+ }
+
+ return get_ordered_ha_chassis_list(ha_chassis_grp, NULL, NULL);
+}
new file mode 100644
@@ -0,0 +1,50 @@
+/* Copyright (c) 2019 Red Hat, Inc.
+ *
+ * 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.
+ */
+
+#ifndef OVN_HA_CHASSIS_H
+#define OVN_HA_CHASSIS_H 1
+
+#include <stdint.h>
+#include "openvswitch/hmap.h"
+#include "openvswitch/list.h"
+
+struct sbrec_chassis;
+struct sbrec_ha_chassis_group;
+struct sset;
+
+struct ha_chassis_ordered {
+ struct sbrec_ha_chassis *ha_ch;
+ size_t n_ha_ch;
+};
+
+/* Returns true if the local chassis is the active gateway among a set
+ * of gateway_chassis. Return false if the local chassis is currently a
+ * backup in a set of multiple gateway_chassis. */
+bool ha_chassis_group_is_active(
+ const struct sbrec_ha_chassis_group *ha_chassis_grp,
+ const struct sset *active_tunnels,
+ const struct sbrec_chassis *local_chassis);
+
+bool ha_chassis_group_contains(
+ const struct sbrec_ha_chassis_group *ha_chassis_grp,
+ const struct sbrec_chassis *chassis);
+
+struct ha_chassis_ordered *ha_chassis_get_ordered(
+ const struct sbrec_ha_chassis_group *ha_chassis_grp);
+
+void ha_chassis_destroy_ordered(
+ struct ha_chassis_ordered *ordered_ha_ch);
+
+#endif /* OVN_HA_CHASSIS_H */
@@ -16,7 +16,7 @@
#include <config.h>
#include "lflow.h"
#include "coverage.h"
-#include "gchassis.h"
+#include "ha-chassis.h"
#include "lport.h"
#include "ofctrl.h"
#include "openvswitch/dynamic-string.h"
@@ -56,14 +56,12 @@ struct lookup_port_aux {
};
struct condition_aux {
- struct ovsdb_idl_index *sbrec_chassis_by_name;
struct ovsdb_idl_index *sbrec_port_binding_by_name;
const struct sbrec_chassis *chassis;
const struct sset *active_tunnels;
};
static void consider_logical_flow(
- struct ovsdb_idl_index *sbrec_chassis_by_name,
struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_logical_flow *,
@@ -117,14 +115,11 @@ is_chassis_resident_cb(const void *c_aux_, const char *port_name)
/* for non-chassisredirect ports */
return pb->chassis && pb->chassis == c_aux->chassis;
} else {
- struct ovs_list *gateway_chassis;
- gateway_chassis = gateway_chassis_get_ordered(
- c_aux->sbrec_chassis_by_name, pb);
- if (gateway_chassis) {
- bool active = gateway_chassis_is_active(gateway_chassis,
- c_aux->chassis,
- c_aux->active_tunnels);
- gateway_chassis_destroy(gateway_chassis);
+ if (ha_chassis_group_contains(pb->ha_chassis_group,
+ c_aux->chassis)) {
+ bool active = ha_chassis_group_is_active(pb->ha_chassis_group,
+ c_aux->active_tunnels,
+ c_aux->chassis);
return active;
}
return false;
@@ -141,7 +136,6 @@ is_switch(const struct sbrec_datapath_binding *ldp)
/* Adds the logical flows from the Logical_Flow table to flow tables. */
static void
add_logical_flows(
- struct ovsdb_idl_index *sbrec_chassis_by_name,
struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_dhcp_options_table *dhcp_options_table,
@@ -180,8 +174,7 @@ add_logical_flows(
nd_ra_opts_init(&nd_ra_opts);
SBREC_LOGICAL_FLOW_TABLE_FOR_EACH (lflow, logical_flow_table) {
- consider_logical_flow(sbrec_chassis_by_name,
- sbrec_multicast_group_by_name_datapath,
+ consider_logical_flow(sbrec_multicast_group_by_name_datapath,
sbrec_port_binding_by_name,
lflow, local_datapaths,
chassis, &dhcp_opts, &dhcpv6_opts, &nd_ra_opts,
@@ -197,7 +190,6 @@ add_logical_flows(
static void
consider_logical_flow(
- struct ovsdb_idl_index *sbrec_chassis_by_name,
struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_logical_flow *lflow,
@@ -295,7 +287,6 @@ consider_logical_flow(
.dp = lflow->logical_datapath
};
struct condition_aux cond_aux = {
- .sbrec_chassis_by_name = sbrec_chassis_by_name,
.sbrec_port_binding_by_name = sbrec_port_binding_by_name,
.chassis = chassis,
.active_tunnels = active_tunnels,
@@ -460,8 +451,7 @@ add_neighbor_flows(struct ovsdb_idl_index *sbrec_port_binding_by_name,
/* Translates logical flows in the Logical_Flow table in the OVN_SB database
* into OpenFlow flows. See ovn-architecture(7) for more information. */
void
-lflow_run(struct ovsdb_idl_index *sbrec_chassis_by_name,
- struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
+lflow_run(struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_dhcp_options_table *dhcp_options_table,
const struct sbrec_dhcpv6_options_table *dhcpv6_options_table,
@@ -479,8 +469,7 @@ lflow_run(struct ovsdb_idl_index *sbrec_chassis_by_name,
{
COVERAGE_INC(lflow_run);
- add_logical_flows(sbrec_chassis_by_name,
- sbrec_multicast_group_by_name_datapath,
+ add_logical_flows(sbrec_multicast_group_by_name_datapath,
sbrec_port_binding_by_name, dhcp_options_table,
dhcpv6_options_table, logical_flow_table,
local_datapaths, chassis, addr_sets, port_groups,
@@ -65,8 +65,7 @@ struct uuid;
#define LOG_PIPELINE_LEN 24
void lflow_init(void);
-void lflow_run(struct ovsdb_idl_index *sbrec_chassis_by_name,
- struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
+void lflow_run(struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_dhcp_options_table *,
const struct sbrec_dhcpv6_options_table *,
@@ -710,7 +710,7 @@ main(int argc, char *argv[])
bfd_calculate_active_tunnels(br_int, &active_tunnels);
}
- binding_run(ovnsb_idl_txn, ovs_idl_txn, sbrec_chassis_by_name,
+ binding_run(ovnsb_idl_txn, ovs_idl_txn,
sbrec_datapath_binding_by_key,
sbrec_port_binding_by_datapath,
sbrec_port_binding_by_name,
@@ -740,7 +740,7 @@ main(int argc, char *argv[])
enum mf_field_id mff_ovn_geneve = ofctrl_run(
br_int, &pending_ct_zones);
- pinctrl_run(ovnsb_idl_txn, sbrec_chassis_by_name,
+ pinctrl_run(ovnsb_idl_txn,
sbrec_datapath_binding_by_key,
sbrec_port_binding_by_datapath,
sbrec_port_binding_by_key,
@@ -760,7 +760,6 @@ main(int argc, char *argv[])
struct hmap flow_table = HMAP_INITIALIZER(&flow_table);
lflow_run(
- sbrec_chassis_by_name,
sbrec_multicast_group_by_name_datapath,
sbrec_port_binding_by_name,
sbrec_dhcp_options_table_get(ovnsb_idl_loop.idl),
@@ -774,15 +773,13 @@ main(int argc, char *argv[])
if (chassis_id) {
bfd_run(
- sbrec_chassis_by_name,
- sbrec_port_binding_by_datapath,
ovsrec_interface_table_get(ovs_idl_loop.idl),
br_int, chassis,
- sbrec_sb_global_table_get(ovnsb_idl_loop.idl),
- &local_datapaths);
+ sbrec_ha_chassis_group_table_get(
+ ovnsb_idl_loop.idl),
+ sbrec_sb_global_table_get(ovnsb_idl_loop.idl));
}
physical_run(
- sbrec_chassis_by_name,
sbrec_port_binding_by_name,
sbrec_multicast_group_table_get(
ovnsb_idl_loop.idl),
@@ -17,7 +17,7 @@
#include "binding.h"
#include "byte-order.h"
#include "flow.h"
-#include "gchassis.h"
+#include "ha-chassis.h"
#include "lflow.h"
#include "lport.h"
#include "lib/bundle.h"
@@ -377,8 +377,7 @@ load_logical_ingress_metadata(const struct sbrec_port_binding *binding,
}
static void
-consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name,
- struct ovsdb_idl_index *sbrec_port_binding_by_name,
+consider_port_binding(struct ovsdb_idl_index *sbrec_port_binding_by_name,
enum mf_field_id mff_ovn_geneve,
const struct simap *ct_zones,
const struct sset *active_tunnels,
@@ -446,13 +445,13 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name,
return;
}
- struct ovs_list *gateway_chassis
- = gateway_chassis_get_ordered(sbrec_chassis_by_name, binding);
+ struct ha_chassis_ordered *ha_ch_ordered
+ = ha_chassis_get_ordered(binding->ha_chassis_group);
if (!strcmp(binding->type, "chassisredirect")
&& (binding->chassis == chassis
- || gateway_chassis_is_active(gateway_chassis, chassis,
- active_tunnels))) {
+ || ha_chassis_group_is_active(binding->ha_chassis_group,
+ active_tunnels, chassis))) {
/* Table 33, priority 100.
* =======================
@@ -588,7 +587,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name,
goto out;
}
} else {
- if (!gateway_chassis || ovs_list_is_short(gateway_chassis)) {
+ if (!ha_ch_ordered || ha_ch_ordered->n_ha_ch < 2) {
/* It's on a single remote chassis */
if (!binding->chassis) {
goto out;
@@ -599,7 +598,8 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name,
}
ofport = tun->ofport;
} else {
- /* It's distributed across the "gateway_chassis" list */
+ /* It's distributed across the chassis belonging to
+ * an HA chassis group. */
is_ha_remote = true;
}
}
@@ -753,34 +753,36 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name,
/* Output to tunnel. */
ofpact_put_OUTPUT(ofpacts_p)->port = rem_tun->ofport;
} else {
- struct gateway_chassis *gwc;
/* Make sure all tunnel endpoints use the same encapsulation,
* and set it up */
- LIST_FOR_EACH (gwc, node, gateway_chassis) {
- if (gwc->db->chassis) {
- if (!tun) {
- tun = chassis_tunnel_find(gwc->db->chassis->name, NULL);
- } else {
- struct chassis_tunnel *chassis_tunnel =
- chassis_tunnel_find(gwc->db->chassis->name, NULL);
- if (chassis_tunnel &&
- tun->type != chassis_tunnel->type) {
- static struct vlog_rate_limit rl =
- VLOG_RATE_LIMIT_INIT(1, 1);
- VLOG_ERR_RL(&rl, "Port %s has Gateway_Chassis "
- "with mixed encapsulations, only "
- "uniform encapsulations are "
- "supported.",
- binding->logical_port);
- goto out;
- }
+ for (size_t i = 0; i < ha_ch_ordered->n_ha_ch; i++) {
+ const struct sbrec_chassis *ch =
+ ha_ch_ordered->ha_ch[i].chassis;
+ if (!ch) {
+ continue;
+ }
+ if (!tun) {
+ tun = chassis_tunnel_find(ch->name, NULL);
+ } else {
+ struct chassis_tunnel *chassis_tunnel =
+ chassis_tunnel_find(ch->name, NULL);
+ if (chassis_tunnel &&
+ tun->type != chassis_tunnel->type) {
+ static struct vlog_rate_limit rl =
+ VLOG_RATE_LIMIT_INIT(1, 1);
+ VLOG_ERR_RL(&rl, "Port %s has Gateway_Chassis "
+ "with mixed encapsulations, only "
+ "uniform encapsulations are "
+ "supported.",
+ binding->logical_port);
+ goto out;
}
}
}
if (!tun) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
- VLOG_ERR_RL(&rl, "No tunnel endpoint found for gateways in "
- "Gateway_Chassis of port %s",
+ VLOG_ERR_RL(&rl, "No tunnel endpoint found for HA chassis in "
+ "HA chassis group of port %s",
binding->logical_port);
goto out;
}
@@ -791,24 +793,27 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name,
/* Output to tunnels with active/backup */
struct ofpact_bundle *bundle = ofpact_put_BUNDLE(ofpacts_p);
- LIST_FOR_EACH (gwc, node, gateway_chassis) {
- if (gwc->db->chassis) {
- tun = chassis_tunnel_find(gwc->db->chassis->name, NULL);
- if (!tun) {
- continue;
- }
- if (bundle->n_slaves >= BUNDLE_MAX_SLAVES) {
- static struct vlog_rate_limit rl =
- VLOG_RATE_LIMIT_INIT(1, 1);
- VLOG_WARN_RL(&rl, "Remote endpoints for port beyond "
- "BUNDLE_MAX_SLAVES");
- break;
- }
- ofpbuf_put(ofpacts_p, &tun->ofport,
- sizeof tun->ofport);
- bundle = ofpacts_p->header;
- bundle->n_slaves++;
+ for (size_t i = 0; i < ha_ch_ordered->n_ha_ch; i++) {
+ const struct sbrec_chassis *ch =
+ ha_ch_ordered->ha_ch[i].chassis;
+ if (!ch) {
+ continue;
+ }
+ tun = chassis_tunnel_find(ch->name, NULL);
+ if (!tun) {
+ continue;
+ }
+ if (bundle->n_slaves >= BUNDLE_MAX_SLAVES) {
+ static struct vlog_rate_limit rl =
+ VLOG_RATE_LIMIT_INIT(1, 1);
+ VLOG_WARN_RL(&rl, "Remote endpoints for port beyond "
+ "BUNDLE_MAX_SLAVES");
+ break;
}
+ ofpbuf_put(ofpacts_p, &tun->ofport,
+ sizeof tun->ofport);
+ bundle = ofpacts_p->header;
+ bundle->n_slaves++;
}
bundle->algorithm = NX_BD_ALG_ACTIVE_BACKUP;
@@ -822,8 +827,8 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name,
&match, ofpacts_p);
}
out:
- if (gateway_chassis) {
- gateway_chassis_destroy(gateway_chassis);
+ if (ha_ch_ordered) {
+ ha_chassis_destroy_ordered(ha_ch_ordered);
}
}
@@ -967,8 +972,7 @@ update_ofports(struct simap *old, struct simap *new)
}
void
-physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name,
- struct ovsdb_idl_index *sbrec_port_binding_by_name,
+physical_run(struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_multicast_group_table *multicast_group_table,
const struct sbrec_port_binding_table *port_binding_table,
enum mf_field_id mff_ovn_geneve,
@@ -1119,8 +1123,7 @@ physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name,
* 64 for logical-to-physical translation. */
const struct sbrec_port_binding *binding;
SBREC_PORT_BINDING_TABLE_FOR_EACH (binding, port_binding_table) {
- consider_port_binding(sbrec_chassis_by_name,
- sbrec_port_binding_by_name,
+ consider_port_binding(sbrec_port_binding_by_name,
mff_ovn_geneve, ct_zones,
active_tunnels,
local_datapaths, binding, chassis,
@@ -43,8 +43,7 @@ struct sset;
#define OVN_GENEVE_LEN 4
void physical_register_ovs_idl(struct ovsdb_idl *);
-void physical_run(struct ovsdb_idl_index *sbrec_chassis_by_name,
- struct ovsdb_idl_index *sbrec_port_binding_by_name,
+void physical_run(struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_multicast_group_table *,
const struct sbrec_port_binding_table *,
enum mf_field_id mff_ovn_geneve,
@@ -23,7 +23,7 @@
#include "dirs.h"
#include "dp-packet.h"
#include "flow.h"
-#include "gchassis.h"
+#include "ha-chassis.h"
#include "lport.h"
#include "nx-match.h"
#include "ovn-controller.h"
@@ -81,7 +81,6 @@ static void init_send_garps(void);
static void destroy_send_garps(void);
static void send_garp_wait(void);
static void send_garp_run(
- struct ovsdb_idl_index *sbrec_chassis_by_name,
struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct ovsrec_bridge *,
@@ -1505,7 +1504,6 @@ pinctrl_recv(const struct sbrec_dns_table *dns_table,
void
pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
- struct ovsdb_idl_index *sbrec_chassis_by_name,
struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_key,
@@ -1554,7 +1552,7 @@ pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
run_put_mac_bindings(ovnsb_idl_txn, sbrec_datapath_binding_by_key,
sbrec_port_binding_by_key,
sbrec_mac_binding_by_lport_ip);
- send_garp_run(sbrec_chassis_by_name, sbrec_port_binding_by_datapath,
+ send_garp_run(sbrec_port_binding_by_datapath,
sbrec_port_binding_by_name, br_int, chassis,
local_datapaths, active_tunnels);
send_ipv6_ras(sbrec_port_binding_by_datapath,
@@ -2329,8 +2327,7 @@ get_localnet_vifs_l3gwports(
}
static bool
-pinctrl_is_chassis_resident(struct ovsdb_idl_index *sbrec_chassis_by_name,
- struct ovsdb_idl_index *sbrec_port_binding_by_name,
+pinctrl_is_chassis_resident(struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_chassis *chassis,
const struct sset *active_tunnels,
const char *port_name)
@@ -2343,13 +2340,8 @@ pinctrl_is_chassis_resident(struct ovsdb_idl_index *sbrec_chassis_by_name,
if (strcmp(pb->type, "chassisredirect")) {
return pb->chassis == chassis;
} else {
- struct ovs_list *gateway_chassis =
- gateway_chassis_get_ordered(sbrec_chassis_by_name, pb);
- bool active = gateway_chassis_is_active(gateway_chassis,
- chassis,
- active_tunnels);
- gateway_chassis_destroy(gateway_chassis);
- return active;
+ return ha_chassis_group_is_active(pb->ha_chassis_group,
+ active_tunnels, chassis);
}
}
@@ -2420,8 +2412,7 @@ extract_addresses_with_port(const char *addresses,
}
static void
-consider_nat_address(struct ovsdb_idl_index *sbrec_chassis_by_name,
- struct ovsdb_idl_index *sbrec_port_binding_by_name,
+consider_nat_address(struct ovsdb_idl_index *sbrec_port_binding_by_name,
const char *nat_address,
const struct sbrec_port_binding *pb,
struct sset *nat_address_keys,
@@ -2434,7 +2425,7 @@ consider_nat_address(struct ovsdb_idl_index *sbrec_chassis_by_name,
if (!extract_addresses_with_port(nat_address, laddrs, &lport)
|| (!lport && !strcmp(pb->type, "patch"))
|| (lport && !pinctrl_is_chassis_resident(
- sbrec_chassis_by_name, sbrec_port_binding_by_name, chassis,
+ sbrec_port_binding_by_name, chassis,
active_tunnels, lport))) {
destroy_lport_addresses(laddrs);
free(laddrs);
@@ -2454,8 +2445,7 @@ consider_nat_address(struct ovsdb_idl_index *sbrec_chassis_by_name,
}
static void
-get_nat_addresses_and_keys(struct ovsdb_idl_index *sbrec_chassis_by_name,
- struct ovsdb_idl_index *sbrec_port_binding_by_name,
+get_nat_addresses_and_keys(struct ovsdb_idl_index *sbrec_port_binding_by_name,
struct sset *nat_address_keys,
struct sset *local_l3gw_ports,
const struct sbrec_chassis *chassis,
@@ -2473,8 +2463,7 @@ get_nat_addresses_and_keys(struct ovsdb_idl_index *sbrec_chassis_by_name,
if (pb->n_nat_addresses) {
for (int i = 0; i < pb->n_nat_addresses; i++) {
- consider_nat_address(sbrec_chassis_by_name,
- sbrec_port_binding_by_name,
+ consider_nat_address(sbrec_port_binding_by_name,
pb->nat_addresses[i], pb,
nat_address_keys, chassis,
active_tunnels,
@@ -2486,8 +2475,7 @@ get_nat_addresses_and_keys(struct ovsdb_idl_index *sbrec_chassis_by_name,
const char *nat_addresses_options = smap_get(&pb->options,
"nat-addresses");
if (nat_addresses_options) {
- consider_nat_address(sbrec_chassis_by_name,
- sbrec_port_binding_by_name,
+ consider_nat_address(sbrec_port_binding_by_name,
nat_addresses_options, pb,
nat_address_keys, chassis,
active_tunnels,
@@ -2504,8 +2492,7 @@ send_garp_wait(void)
}
static void
-send_garp_run(struct ovsdb_idl_index *sbrec_chassis_by_name,
- struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+send_garp_run(struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct ovsrec_bridge *br_int,
const struct sbrec_chassis *chassis,
@@ -2524,8 +2511,7 @@ send_garp_run(struct ovsdb_idl_index *sbrec_chassis_by_name,
br_int, chassis, local_datapaths,
&localnet_vifs, &local_l3gw_ports);
- get_nat_addresses_and_keys(sbrec_chassis_by_name,
- sbrec_port_binding_by_name,
+ get_nat_addresses_and_keys(sbrec_port_binding_by_name,
&nat_ip_keys, &local_l3gw_ports,
chassis, active_tunnels,
&nat_addresses);
@@ -32,7 +32,6 @@ struct sbrec_dns_table;
void pinctrl_init(void);
void pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
- struct ovsdb_idl_index *sbrec_chassis_by_name,
struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_key,