Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/787925/?format=api
{ "id": 787925, "url": "http://patchwork.ozlabs.org/api/patches/787925/?format=api", "web_url": "http://patchwork.ozlabs.org/project/openvswitch/patch/1499965361-32021-5-git-send-email-majopela@redhat.com/", "project": { "id": 47, "url": "http://patchwork.ozlabs.org/api/projects/47/?format=api", "name": "Open vSwitch", "link_name": "openvswitch", "list_id": "ovs-dev.openvswitch.org", "list_email": "ovs-dev@openvswitch.org", "web_url": "http://openvswitch.org/", "scm_url": "git@github.com:openvswitch/ovs.git", "webscm_url": "https://github.com/openvswitch/ovs", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<1499965361-32021-5-git-send-email-majopela@redhat.com>", "list_archive_url": null, "date": "2017-07-13T17:02:38", "name": "[ovs-dev,v5,5/8] ovn: l3ha, enable bfd between tunnel endpoints", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "15b88c91d9b903dfb67d0576e63ba294de98b028", "submitter": { "id": 67170, "url": "http://patchwork.ozlabs.org/api/people/67170/?format=api", "name": "Miguel Angel Ajo", "email": "majopela@redhat.com" }, "delegate": { "id": 55721, "url": "http://patchwork.ozlabs.org/api/users/55721/?format=api", "username": "russellb", "first_name": "Russell", "last_name": "Bryant", "email": "rbryant@redhat.com" }, "mbox": "http://patchwork.ozlabs.org/project/openvswitch/patch/1499965361-32021-5-git-send-email-majopela@redhat.com/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/787925/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/787925/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<ovs-dev-bounces@openvswitch.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "dev@openvswitch.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "ovs-dev@mail.linuxfoundation.org" ], "Received": [ "from mail.linuxfoundation.org (mail.linuxfoundation.org\n\t[140.211.169.12])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3x7hzB1Wv3z9t2S\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 14 Jul 2017 03:05:42 +1000 (AEST)", "from mail.linux-foundation.org (localhost [127.0.0.1])\n\tby mail.linuxfoundation.org (Postfix) with ESMTP id 9F0BDB8E;\n\tThu, 13 Jul 2017 17:02:58 +0000 (UTC)", "from smtp1.linuxfoundation.org (smtp1.linux-foundation.org\n\t[172.17.192.35])\n\tby mail.linuxfoundation.org (Postfix) with ESMTPS id 61B4EB88\n\tfor <dev@openvswitch.org>; Thu, 13 Jul 2017 17:02:57 +0000 (UTC)", "from mail-wr0-f175.google.com (mail-wr0-f175.google.com\n\t[209.85.128.175])\n\tby smtp1.linuxfoundation.org (Postfix) with ESMTPS id 3DE7D19B\n\tfor <dev@openvswitch.org>; Thu, 13 Jul 2017 17:02:55 +0000 (UTC)", "by mail-wr0-f175.google.com with SMTP id k67so56085804wrc.2\n\tfor <dev@openvswitch.org>; Thu, 13 Jul 2017 10:02:55 -0700 (PDT)", "from ctl.localdomain (111.148.134.37.dynamic.jazztel.es.\n\t[37.134.148.111]) by smtp.gmail.com with ESMTPSA id\n\t46sm7134176wrz.8.2017.07.13.10.02.51\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tThu, 13 Jul 2017 10:02:51 -0700 (PDT)" ], "X-Greylist": "whitelisted by SQLgrey-1.7.6", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=2GINXoZfEEzrUBvnlfS/Sm8988EPEReM0rGWUjPzI18=;\n\tb=F6gznARzCJcHG8XoWzoaK4qEzZntFWlBbj2OQF2BhOnbo7cXKE8ntS+T2a2wGMqlfs\n\t58Ql/FU2vIoX9om3d3l7uIbguq3mmzwWc5ySwRod1Vklq3nLhX9SndDC+LPsvdF44fiU\n\txF/8/5Mxhg3S0nxoxKHPRY65N8oJvbLHdEhHpuHWeQ69nWXHC3GNhj9YIuF0ZegjawgD\n\tfn9lI72hLgaq9CCnuKgwdBdxuixK385wi3FKuchYg0CnTuknjnZvRKcNDf3o6QgVUwiS\n\tMZTa8nJhLUtBYjrpgTAG/ENhbEwDPnwNJgEV+ZmQ87ONV+a2PeSYcV0a+xgkGLIHBnEb\n\tml6A==", "X-Gm-Message-State": "AIVw110C8HF2V004RPPXdNYivoMelsHntlsqK9PnoeXuxtpooeP/RReJ\n\tgyaEA2YuaurC/Zf56TIAjQ==", "X-Received": "by 10.223.130.162 with SMTP id 31mr2218188wrc.202.1499965373376; \n\tThu, 13 Jul 2017 10:02:53 -0700 (PDT)", "From": "Miguel Angel Ajo <majopela@redhat.com>", "To": "dev@openvswitch.org", "Date": "Thu, 13 Jul 2017 17:02:38 +0000", "Message-Id": "<1499965361-32021-5-git-send-email-majopela@redhat.com>", "X-Mailer": "git-send-email 1.8.3.1", "In-Reply-To": "<1499965361-32021-1-git-send-email-majopela@redhat.com>", "References": "<1496930708-15441-1-git-send-email-majopela@redhat.com>\n\t<1499965361-32021-1-git-send-email-majopela@redhat.com>", "X-Spam-Status": "No, score=-1.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE,\n\tRCVD_IN_SORBS_SPAM autolearn=no version=3.3.1", "X-Spam-Checker-Version": "SpamAssassin 3.3.1 (2010-03-16) on\n\tsmtp1.linux-foundation.org", "Cc": "Miguel Angel Ajo <majopela@redhat.com>,\n\tVenkata Anil <anilvenkata@redhat.com>", "Subject": "[ovs-dev] [PATCH v5 5/8] ovn: l3ha,\n\tenable bfd between tunnel endpoints", "X-BeenThere": "ovs-dev@openvswitch.org", "X-Mailman-Version": "2.1.12", "Precedence": "list", "List-Id": "<ovs-dev.openvswitch.org>", "List-Unsubscribe": "<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n\t<mailto:ovs-dev-request@openvswitch.org?subject=unsubscribe>", "List-Archive": "<http://mail.openvswitch.org/pipermail/ovs-dev/>", "List-Post": "<mailto:ovs-dev@openvswitch.org>", "List-Help": "<mailto:ovs-dev-request@openvswitch.org?subject=help>", "List-Subscribe": "<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>,\n\t<mailto:ovs-dev-request@openvswitch.org?subject=subscribe>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Sender": "ovs-dev-bounces@openvswitch.org", "Errors-To": "ovs-dev-bounces@openvswitch.org" }, "content": "From: Venkata Anil <anilvenkata@redhat.com>\n\nThis patch enables bfd protocol between gateways and transport nodes,\nall gateway nodes with any HA chassisredirect port will enable BFD\nto all tunnel endpoints, while transport nodes will enable BFD\nto all tunnel endpoints hosting an HA gateway chassisredirect port.\n\nSigned-off-by: Venkata Anil <vkommadi@redhat.com>\nSigned-off-by: Miguel Angel Ajo <majopela@redhat.com>\nCo-Authored-by: Miguel Angel Ajo <majopela@redhat.com>\n---\n ovn/controller/automake.mk | 2 +\n ovn/controller/bfd.c | 201 ++++++++++++++++++++++++++++++++++++++++\n ovn/controller/bfd.h | 34 +++++++\n ovn/controller/binding.c | 47 +++++++---\n ovn/controller/binding.h | 3 +-\n ovn/controller/ovn-controller.c | 15 ++-\n ovn/controller/ovn-controller.h | 4 +\n tests/ovn.at | 62 +++++++++++++\n 8 files changed, 355 insertions(+), 13 deletions(-)\n create mode 100644 ovn/controller/bfd.c\n create mode 100644 ovn/controller/bfd.h", "diff": "diff --git a/ovn/controller/automake.mk b/ovn/controller/automake.mk\nindex d3828f5..cd5505c 100644\n--- a/ovn/controller/automake.mk\n+++ b/ovn/controller/automake.mk\n@@ -1,5 +1,7 @@\n bin_PROGRAMS += ovn/controller/ovn-controller\n ovn_controller_ovn_controller_SOURCES = \\\n+\tovn/controller/bfd.c \\\n+\tovn/controller/bfd.h \\\n \tovn/controller/binding.c \\\n \tovn/controller/binding.h \\\n \tovn/controller/chassis.c \\\ndiff --git a/ovn/controller/bfd.c b/ovn/controller/bfd.c\nnew file mode 100644\nindex 0000000..1a5d4bd\n--- /dev/null\n+++ b/ovn/controller/bfd.c\n@@ -0,0 +1,201 @@\n+/* Copyright (c) 2017 Red Hat, Inc.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at:\n+ *\n+ * http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+#include <config.h>\n+#include \"bfd.h\"\n+#include \"gchassis.h\"\n+#include \"lport.h\"\n+#include \"ovn-controller.h\"\n+\n+#include \"lib/hash.h\"\n+#include \"lib/sset.h\"\n+#include \"lib/util.h\"\n+#include \"lib/vswitch-idl.h\"\n+#include \"openvswitch/vlog.h\"\n+#include \"ovn/lib/ovn-sb-idl.h\"\n+#include \"ovn-controller.h\"\n+\n+VLOG_DEFINE_THIS_MODULE(ovn_bfd);\n+\n+void\n+bfd_register_ovs_idl(struct ovsdb_idl *ovs_idl)\n+{\n+ /* NOTE: this assumes that binding.c has added the\n+ * ovsrec_interface table */\n+ ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd);\n+ ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd_status);\n+}\n+\n+\n+static void\n+interface_set_bfd(const struct ovsrec_interface *iface, bool bfd_setting)\n+{\n+ const char *new_setting = bfd_setting ? \"true\":\"false\";\n+ const char *current_setting = smap_get(&iface->bfd, \"enable\");\n+ if (current_setting && !strcmp(current_setting, new_setting)) {\n+ /* If already set to true we skip setting it again\n+ * to avoid flapping to bfd initialization state */\n+ return;\n+ }\n+ const struct smap bfd = SMAP_CONST1(&bfd, \"enable\", new_setting);\n+ ovsrec_interface_verify_bfd(iface);\n+ ovsrec_interface_set_bfd(iface, &bfd);\n+ VLOG_INFO(\"%s BFD on interface %s\", bfd_setting?\"Enabled\":\"Disabled\",\n+ iface->name);\n+}\n+\n+void \n+bfd_calculate_active_tunnels(const struct ovsrec_bridge *br_int,\n+ struct sset *active_tunnels)\n+{\n+ int i;\n+\n+ for (i = 0; i < br_int->n_ports; i++) {\n+ const struct ovsrec_port *port_rec = br_int->ports[i];\n+\n+ if (!strcmp(port_rec->name, br_int->name)) {\n+ continue;\n+ }\n+\n+ int j;\n+ for (j = 0; j < port_rec->n_interfaces; j++) {\n+ const struct ovsrec_interface *iface_rec;\n+ iface_rec = port_rec->interfaces[j];\n+\n+ /* Check if this is a tunnel interface. */\n+ if (smap_get(&iface_rec->options, \"remote_ip\")) {\n+ /* Add ovn-chassis-id if the bfd_status of the tunnel\n+ * is active */\n+ const char *bfd = smap_get(&iface_rec->bfd, \"enable\");\n+ if (bfd && !strcmp(bfd, \"true\")) {\n+ const char *status = smap_get(&iface_rec->bfd_status,\n+ \"state\");\n+ if (status && !strcmp(status, \"up\")) {\n+ const char *id = smap_get(&port_rec->external_ids,\n+ \"ovn-chassis-id\");\n+ if (id) {\n+ sset_add(active_tunnels, id);\n+ }\n+ }\n+ }\n+ }\n+ }\n+ }\n+}\n+\n+static void\n+bfd_calculate_chassis(const struct sbrec_chassis *our_chassis,\n+ struct hmap *local_datapaths,\n+ const struct chassis_index *chassis_index,\n+ struct sset *bfd_chassis)\n+{\n+ /* Identify all chassis nodes to which we need to enable bfd.\n+ * 1) Any chassis hosting the chassisredirect ports for known\n+ * router datapaths.\n+ * 2) Chassis hosting peer datapaths (with ports) connected\n+ * to a router datapath when our chassis is hosting a router\n+ * with a chassis redirect port. */\n+ struct local_datapath *dp;\n+ HMAP_FOR_EACH (dp, hmap_node, local_datapaths) {\n+ const char *is_router = smap_get(&dp->datapath->external_ids,\n+ \"logical-router\");\n+ bool our_chassis_is_gw_for_dp = false;\n+ if (is_router) {\n+ for (size_t j = 0; j < dp->ldatapath->n_lports; j++) {\n+ const struct sbrec_port_binding *pb = dp->ldatapath->lports[j];\n+ if (!strcmp(pb->type, \"chassisredirect\")) {\n+ struct ovs_list *gateway_chassis = NULL;\n+ gateway_chassis =\n+ gateway_chassis_get_ordered(pb, chassis_index);\n+ /* we don't need BFD for non-HA chassisredirect */\n+ if (!gateway_chassis ||\n+ ovs_list_is_short(gateway_chassis)) {\n+ continue;\n+ }\n+ our_chassis_is_gw_for_dp = gateway_chassis_contains(\n+ gateway_chassis, our_chassis);\n+ struct gateway_chassis *gwc;\n+ LIST_FOR_EACH (gwc, node, gateway_chassis) {\n+ if (gwc->db->chassis) {\n+ sset_add(bfd_chassis, gwc->db->chassis->name);\n+ }\n+ }\n+ gateway_chassis_destroy(gateway_chassis);\n+ break;\n+ }\n+ }\n+ }\n+ if (our_chassis_is_gw_for_dp) {\n+ for (size_t i = 0; i < dp->n_peer_dps; i++) {\n+ const struct ldatapath *pdp = dp->peer_dps[i];\n+ if (!pdp) {\n+ continue;\n+ }\n+ for (size_t j = 0; j < pdp->n_lports; j++) {\n+ const struct sbrec_port_binding *pb = pdp->lports[j];\n+ if (pb->chassis) {\n+ /* Gateway node has to enable bfd to all nodes hosting\n+ * connected network ports */\n+ const char *chassis_name = pb->chassis->name;\n+ if (chassis_name) {\n+ sset_add(bfd_chassis, chassis_name);\n+ }\n+ }\n+ }\n+ }\n+ }\n+ }\n+}\n+\n+void\n+bfd_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,\n+ const struct sbrec_chassis *chassis_rec, struct hmap *local_datapaths,\n+ const struct chassis_index *chassis_index)\n+{\n+\n+ if (!chassis_rec) {\n+ return;\n+ }\n+ struct sset bfd_chassis = SSET_INITIALIZER(&bfd_chassis);\n+ bfd_calculate_chassis(chassis_rec, local_datapaths, chassis_index,\n+ &bfd_chassis);\n+ /* Identify tunnels ports(connected to remote chassis id) to enable bfd */\n+ struct sset tunnels = SSET_INITIALIZER(&tunnels);\n+ struct sset bfd_ifaces = SSET_INITIALIZER(&bfd_ifaces);\n+ for (size_t k = 0; k < br_int->n_ports; k++) {\n+ const char *chassis_id = smap_get(&br_int->ports[k]->external_ids,\n+ \"ovn-chassis-id\");\n+ if (chassis_id) {\n+ char *port_name = br_int->ports[k]->name;\n+ sset_add(&tunnels, port_name);\n+ if (sset_contains(&bfd_chassis, chassis_id)) {\n+ sset_add(&bfd_ifaces, port_name);\n+ }\n+ }\n+ }\n+\n+ /* Enable or disable bfd */\n+ const struct ovsrec_interface *iface;\n+ OVSREC_INTERFACE_FOR_EACH (iface, ctx->ovs_idl) {\n+ if (sset_contains(&tunnels, iface->name)) {\n+ interface_set_bfd(\n+ iface, sset_contains(&bfd_ifaces, iface->name));\n+ }\n+ }\n+\n+ sset_destroy(&tunnels);\n+ sset_destroy(&bfd_ifaces);\n+ sset_destroy(&bfd_chassis);\n+}\ndiff --git a/ovn/controller/bfd.h b/ovn/controller/bfd.h\nnew file mode 100644\nindex 0000000..91d0d91\n--- /dev/null\n+++ b/ovn/controller/bfd.h\n@@ -0,0 +1,34 @@\n+/* Copyright (c) 2017 Red Hat, Inc.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at:\n+ *\n+ * http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+#ifndef OVN_BFD_H\n+#define OVN_BFD_H 1\n+\n+struct chassis_index;\n+struct controller_ctx;\n+struct hmap;\n+struct ovsdb_idl;\n+struct ovsrec_bridge;\n+struct sbrec_chassis;\n+struct sset;\n+\n+void bfd_register_ovs_idl(struct ovsdb_idl *);\n+void bfd_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,\n+ const struct sbrec_chassis *chassis_rec,\n+ struct hmap *local_datapaths, const struct chassis_index *);\n+void bfd_calculate_active_tunnels(const struct ovsrec_bridge *br_int,\n+ struct sset *active_tunnels);\n+\n+#endif\ndiff --git a/ovn/controller/binding.c b/ovn/controller/binding.c\nindex cc4563d..4744cf0 100644\n--- a/ovn/controller/binding.c\n+++ b/ovn/controller/binding.c\n@@ -60,6 +60,8 @@ binding_register_ovs_idl(struct ovsdb_idl *ovs_idl)\n ovsdb_idl_add_table(ovs_idl, &ovsrec_table_interface);\n ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_name);\n ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_external_ids);\n+ ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd);\n+ ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd_status);\n ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_status);\n \n ovsdb_idl_add_table(ovs_idl, &ovsrec_table_qos);\n@@ -149,6 +151,12 @@ add_local_datapath__(const struct ldatapath_index *ldatapaths,\n if (peer && peer->datapath) {\n add_local_datapath__(ldatapaths, lports, peer->datapath,\n false, depth + 1, local_datapaths);\n+ ld->n_peer_dps++;\n+ ld->peer_dps = xrealloc(\n+ ld->peer_dps,\n+ ld->n_peer_dps * sizeof *ld->peer_dps);\n+ ld->peer_dps[ld->n_peer_dps - 1] = ldatapath_lookup_by_key(\n+ ldatapaths, peer->datapath->tunnel_key);\n }\n }\n }\n@@ -359,6 +367,8 @@ static void\n consider_local_datapath(struct controller_ctx *ctx,\n const struct ldatapath_index *ldatapaths,\n const struct lport_index *lports,\n+ const struct chassis_index *chassis_index,\n+ struct sset *active_tunnels,\n const struct sbrec_chassis *chassis_rec,\n const struct sbrec_port_binding *binding_rec,\n struct hmap *qos_map,\n@@ -368,6 +378,7 @@ consider_local_datapath(struct controller_ctx *ctx,\n {\n const struct ovsrec_interface *iface_rec\n = shash_find_data(lport_to_iface, binding_rec->logical_port);\n+ struct ovs_list *gateway_chassis = NULL;\n \n bool our_chassis = false;\n if (iface_rec\n@@ -396,16 +407,28 @@ consider_local_datapath(struct controller_ctx *ctx,\n false, local_datapaths);\n }\n } else if (!strcmp(binding_rec->type, \"chassisredirect\")) {\n- if (gateway_chassis_in_pb_contains(binding_rec, chassis_rec)) {\n+ gateway_chassis = gateway_chassis_get_ordered(binding_rec,\n+ chassis_index);\n+ if (gateway_chassis &&\n+ gateway_chassis_contains(gateway_chassis, chassis_rec)) {\n+ struct gateway_chassis *gwc;\n+ LIST_FOR_EACH (gwc, node, gateway_chassis) {\n+ if (!gwc->db->chassis) {\n+ continue;\n+ }\n+ if (!strcmp(gwc->db->chassis->name, chassis_rec->name)) {\n+ /* sb_rec_port_binding->chassis should reflect master */\n+ our_chassis = true;\n+ break;\n+ }\n+ if (sset_contains(active_tunnels, gwc->db->chassis->name)) {\n+ break;\n+ }\n+ }\n add_local_datapath(ldatapaths, lports, binding_rec->datapath,\n false, local_datapaths);\n- /* XXX this should only be set to true if our chassis\n- * (chassis_rec) is the master for this chassisredirect port\n- * but for now we'll bind it only when not bound, this is\n- * handled in subsequent patches */\n- our_chassis = !binding_rec->chassis ||\n- chassis_rec == binding_rec->chassis;\n }\n+ gateway_chassis_destroy(gateway_chassis);\n } else if (!strcmp(binding_rec->type, \"l3gateway\")) {\n const char *chassis_id = smap_get(&binding_rec->options,\n \"l3gateway-chassis\");\n@@ -475,8 +498,10 @@ void\n binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,\n const struct sbrec_chassis *chassis_rec,\n const struct ldatapath_index *ldatapaths,\n- const struct lport_index *lports, struct hmap *local_datapaths,\n- struct sset *local_lports)\n+ const struct lport_index *lports,\n+ const struct chassis_index *chassis_index,\n+ struct sset *active_tunnels,\n+ struct hmap *local_datapaths, struct sset *local_lports)\n {\n if (!chassis_rec) {\n return;\n@@ -497,8 +522,8 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,\n * chassis and update the binding accordingly. This includes both\n * directly connected logical ports and children of those ports. */\n SBREC_PORT_BINDING_FOR_EACH(binding_rec, ctx->ovnsb_idl) {\n- consider_local_datapath(ctx, ldatapaths, lports,\n- chassis_rec, binding_rec,\n+ consider_local_datapath(ctx, ldatapaths, lports, chassis_index,\n+ active_tunnels, chassis_rec, binding_rec,\n sset_is_empty(&egress_ifaces) ? NULL :\n &qos_map, local_datapaths, &lport_to_iface,\n local_lports);\ndiff --git a/ovn/controller/binding.h b/ovn/controller/binding.h\nindex 136b3a7..9195061 100644\n--- a/ovn/controller/binding.h\n+++ b/ovn/controller/binding.h\n@@ -32,7 +32,8 @@ struct sset;\n void binding_register_ovs_idl(struct ovsdb_idl *);\n void binding_run(struct controller_ctx *, const struct ovsrec_bridge *br_int,\n const struct sbrec_chassis *, const struct ldatapath_index *,\n- const struct lport_index *, struct hmap *local_datapaths,\n+ const struct lport_index *, const struct chassis_index *,\n+ struct sset *active_tunnels, struct hmap *local_datapaths,\n struct sset *all_lports);\n bool binding_cleanup(struct controller_ctx *, const struct sbrec_chassis *);\n \ndiff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c\nindex 9fceeca..9715371 100644\n--- a/ovn/controller/ovn-controller.c\n+++ b/ovn/controller/ovn-controller.c\n@@ -23,6 +23,7 @@\n #include <stdlib.h>\n #include <string.h>\n \n+#include \"bfd.h\"\n #include \"binding.h\"\n #include \"chassis.h\"\n #include \"command-line.h\"\n@@ -502,6 +503,8 @@ ctrl_register_ovs_idl(struct ovsdb_idl *ovs_idl)\n ovsdb_idl_add_column(ovs_idl, &ovsrec_open_vswitch_col_bridges);\n ovsdb_idl_add_table(ovs_idl, &ovsrec_table_interface);\n ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_name);\n+ ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd);\n+ ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_bfd_status);\n ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_type);\n ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_options);\n ovsdb_idl_add_column(ovs_idl, &ovsrec_interface_col_ofport);\n@@ -523,6 +526,7 @@ ctrl_register_ovs_idl(struct ovsdb_idl *ovs_idl)\n chassis_register_ovs_idl(ovs_idl);\n encaps_register_ovs_idl(ovs_idl);\n binding_register_ovs_idl(ovs_idl);\n+ bfd_register_ovs_idl(ovs_idl);\n physical_register_ovs_idl(ovs_idl);\n }\n \n@@ -621,6 +625,7 @@ main(int argc, char *argv[])\n * l2gateway ports for which options:l2gateway-chassis designates the\n * local hypervisor, and localnet ports. */\n struct sset local_lports = SSET_INITIALIZER(&local_lports);\n+ struct sset active_tunnels = SSET_INITIALIZER(&active_tunnels);\n \n const struct ovsrec_bridge *br_int = get_br_int(&ctx);\n const char *chassis_id = get_chassis_id(ctx.ovs_idl);\n@@ -639,8 +644,10 @@ main(int argc, char *argv[])\n if (chassis_id) {\n chassis = chassis_run(&ctx, chassis_id, br_int);\n encaps_run(&ctx, br_int, chassis_id);\n+ bfd_calculate_active_tunnels(br_int, &active_tunnels);\n binding_run(&ctx, br_int, chassis, &ldatapaths, &lports,\n- &local_datapaths, &local_lports);\n+ &chassis_index, &active_tunnels, &local_datapaths,\n+ &local_lports);\n }\n \n if (br_int && chassis) {\n@@ -664,6 +671,10 @@ main(int argc, char *argv[])\n &local_datapaths, &group_table,\n &addr_sets, &flow_table);\n \n+ if (chassis_id) {\n+ bfd_run(&ctx, br_int, chassis, &local_datapaths,\n+ &chassis_index);\n+ }\n physical_run(&ctx, mff_ovn_geneve,\n br_int, chassis, &ct_zones, &lports,\n &flow_table, &local_datapaths, &local_lports,\n@@ -717,9 +728,11 @@ main(int argc, char *argv[])\n chassis_index_destroy(&chassis_index);\n \n sset_destroy(&local_lports);\n+ sset_destroy(&active_tunnels);\n \n struct local_datapath *cur_node, *next_node;\n HMAP_FOR_EACH_SAFE (cur_node, next_node, hmap_node, &local_datapaths) {\n+ free(cur_node->peer_dps);\n hmap_remove(&local_datapaths, &cur_node->hmap_node);\n free(cur_node);\n }\ndiff --git a/ovn/controller/ovn-controller.h b/ovn/controller/ovn-controller.h\nindex 4bc0467..35a9e21 100644\n--- a/ovn/controller/ovn-controller.h\n+++ b/ovn/controller/ovn-controller.h\n@@ -23,6 +23,8 @@\n /* Linux supports a maximum of 64K zones, which seems like a fine default. */\n #define MAX_CT_ZONES 65535\n \n+struct sset;\n+\n struct controller_ctx {\n struct ovsdb_idl *ovnsb_idl;\n struct ovsdb_idl_txn *ovnsb_idl_txn;\n@@ -66,6 +68,8 @@ struct local_datapath {\n /* True if this datapath contains an l3gateway port located on this\n * hypervisor. */\n bool has_local_l3gateway;\n+ const struct ldatapath **peer_dps;\n+ size_t n_peer_dps;\n };\n \n struct local_datapath *get_local_datapath(const struct hmap *,\ndiff --git a/tests/ovn.at b/tests/ovn.at\nindex 0cbbc27..e4dd090 100644\n--- a/tests/ovn.at\n+++ b/tests/ovn.at\n@@ -7787,6 +7787,22 @@ echo \"------ Port_Binding chassisredirect -------\"\n ovn-sbctl find Port_Binding type=chassisredirect\n echo \"-------------------------------------------\"\n \n+for chassis in gw1 gw2 hv1 hv2; do\n+ as $chassis\n+ echo \"------ $chassis dump ----------\"\n+ ovs-ofctl show br-int\n+ ovs-ofctl dump-flows br-int\n+ echo \"\"\n+ echo \"BFD (from $chassis):\"\n+ # dump BFD config and status to the other chassis\n+ for chassis2 in gw1 gw2 hv1 hv2; do\n+ if [[ \"$chassis\" != \"$chassis2\" ]]; then\n+ echo \" -> $chassis2:\"\n+ echo \" $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)\"\n+ fi\n+ done\n+ echo \"--------------------------\"\n+done\n \n hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)\n hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)\n@@ -7828,6 +7844,52 @@ AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep active_backup | gre\n ])\n \n \n+# check BFD enablement on tunnel ports from gw1 #########\n+as gw1\n+for chassis in gw2 hv1 hv2; do\n+ echo \"checking gw1 -> $chassis\"\n+ AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],\n+ [[enable=true\n+]])\n+done\n+\n+\n+# check BFD enablement on tunnel ports from gw2 ##########\n+as gw2\n+for chassis in gw1 hv1 hv2; do\n+ echo \"checking gw2 -> $chassis\"\n+ AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],\n+ [[enable=true\n+]])\n+done\n+\n+# check BFD enablement on tunnel ports from hv1 ###########\n+as hv1\n+for chassis in gw1 gw2; do\n+ echo \"checking hv1 -> $chassis\"\n+ AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],\n+ [[enable=true\n+]])\n+done\n+# make sure BFD is not enabled to hv2, we don't need it\n+AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],\n+ [[enable=false\n+]])\n+\n+\n+# check BFD enablement on tunnel ports from hv2 ##########\n+as hv2\n+for chassis in gw1 gw2; do\n+ echo \"checking hv2 -> $chassis\"\n+ AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],\n+ [[enable=true\n+]])\n+done\n+# make sure BFD is not enabled to hv1, we don't need it\n+AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],\n+ [[enable=false\n+]])\n+\n OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])\n \n AT_CLEANUP\n", "prefixes": [ "ovs-dev", "v5", "5/8" ] }