get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.0/patches/2186659/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2186659,
    "url": "http://patchwork.ozlabs.org/api/1.0/patches/2186659/?format=api",
    "project": {
        "id": 68,
        "url": "http://patchwork.ozlabs.org/api/1.0/projects/68/?format=api",
        "name": "Open Virtual Network development",
        "link_name": "ovn",
        "list_id": "ovs-dev.openvswitch.org",
        "list_email": "ovs-dev@openvswitch.org",
        "web_url": "http://openvswitch.org/",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20260120114948.2289909-9-guilherme.paulo@luizalabs.com>",
    "date": "2026-01-20T11:49:47",
    "name": "[ovs-dev,v0,8/9] ovn-ic: Add a new engine-node 'service-monitor'.",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "d304c491e9dead0e20060021bdc6bd0aa6ee2a4c",
    "submitter": {
        "id": 90256,
        "url": "http://patchwork.ozlabs.org/api/1.0/people/90256/?format=api",
        "name": "Paulo Guilherme Silva",
        "email": "guilherme.paulo@luizalabs.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/ovn/patch/20260120114948.2289909-9-guilherme.paulo@luizalabs.com/mbox/",
    "series": [
        {
            "id": 489037,
            "url": "http://patchwork.ozlabs.org/api/1.0/series/489037/?format=api",
            "date": "2026-01-20T11:49:40",
            "name": "Create multiple engines nodes for ovn-ic.",
            "version": 0,
            "mbox": "http://patchwork.ozlabs.org/series/489037/mbox/"
        }
    ],
    "check": "success",
    "checks": "http://patchwork.ozlabs.org/api/patches/2186659/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<ovs-dev-bounces@openvswitch.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "dev@openvswitch.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@legolas.ozlabs.org",
            "ovs-dev@lists.linuxfoundation.org"
        ],
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n unprotected) header.d=luizalabs.com header.i=@luizalabs.com\n header.a=rsa-sha256 header.s=google header.b=AN+LEYhh;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)",
            "smtp4.osuosl.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key)\n header.d=luizalabs.com header.i=@luizalabs.com header.a=rsa-sha256\n header.s=google header.b=AN+LEYhh",
            "smtp2.osuosl.org; dmarc=pass (p=quarantine dis=none)\n header.from=luizalabs.com",
            "smtp2.osuosl.org;\n dkim=pass (1024-bit key) header.d=luizalabs.com header.i=@luizalabs.com\n header.a=rsa-sha256 header.s=google header.b=AN+LEYhh"
        ],
        "Received": [
            "from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4dwQdn0NMJz1xsW\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 20 Jan 2026 22:51:25 +1100 (AEDT)",
            "from localhost (localhost [127.0.0.1])\n\tby smtp4.osuosl.org (Postfix) with ESMTP id 7000242DEE;\n\tTue, 20 Jan 2026 11:51:23 +0000 (UTC)",
            "from smtp4.osuosl.org ([127.0.0.1])\n by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id o0tkfIQQkUeJ; Tue, 20 Jan 2026 11:51:19 +0000 (UTC)",
            "from lists.linuxfoundation.org (lf-lists.osuosl.org\n [IPv6:2605:bc80:3010:104::8cd3:938])\n\tby smtp4.osuosl.org (Postfix) with ESMTPS id EB23540FD4;\n\tTue, 20 Jan 2026 11:51:07 +0000 (UTC)",
            "from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id 7CE62C02A6;\n\tTue, 20 Jan 2026 11:51:07 +0000 (UTC)",
            "from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 142BBC02A5\n for <dev@openvswitch.org>; Tue, 20 Jan 2026 11:51:06 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n by smtp2.osuosl.org (Postfix) with ESMTP id 1DD1B42FF4\n for <dev@openvswitch.org>; Tue, 20 Jan 2026 11:50:43 +0000 (UTC)",
            "from smtp2.osuosl.org ([127.0.0.1])\n by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id LbCZ3kpR2zpV for <dev@openvswitch.org>;\n Tue, 20 Jan 2026 11:50:36 +0000 (UTC)",
            "from mail-dy1-x1336.google.com (mail-dy1-x1336.google.com\n [IPv6:2607:f8b0:4864:20::1336])\n by smtp2.osuosl.org (Postfix) with ESMTPS id 8810E42F57\n for <dev@openvswitch.org>; Tue, 20 Jan 2026 11:50:36 +0000 (UTC)",
            "by mail-dy1-x1336.google.com with SMTP id\n 5a478bee46e88-2b6f5a9cecaso1368900eec.0\n for <dev@openvswitch.org>; Tue, 20 Jan 2026 03:50:36 -0800 (PST)",
            "from WNLEC-CW22RF4.. ([177.75.155.81])\n by smtp.gmail.com with ESMTPSA id\n 5a478bee46e88-2b6b367cbc9sm18630559eec.32.2026.01.20.03.50.31\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 20 Jan 2026 03:50:32 -0800 (PST)"
        ],
        "X-Virus-Scanned": [
            "amavis at osuosl.org",
            "amavis at osuosl.org"
        ],
        "X-Comment": "SPF check N/A for local connections -\n client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN> ",
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 smtp4.osuosl.org EB23540FD4",
            "OpenDKIM Filter v2.11.0 smtp2.osuosl.org 8810E42F57"
        ],
        "Received-SPF": "Pass (mailfrom) identity=mailfrom;\n client-ip=2607:f8b0:4864:20::1336; helo=mail-dy1-x1336.google.com;\n envelope-from=guilherme.paulo@luizalabs.com; receiver=<UNKNOWN>",
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 smtp2.osuosl.org 8810E42F57",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=luizalabs.com; s=google; t=1768909835; x=1769514635; darn=openvswitch.org;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=+VgCmqfL/f3KqfuCqqjFuFCkDpS0OkQo/Z+JIzb4h3g=;\n b=AN+LEYhhcCFs2jDrIEvelWFDakhoZX3NJj4nCAGdEXiugqtw5n2wgKd5YDMry8+JkZ\n lVr+P+lDNmk4BxwQnHRT8mpzMycl1fOjtLCO20ykBF0hh8bE9cPasriw0PP82w6R6zQ2\n bcQFRMAI91DnyiGg6GCCITYSu2wI92891UxhA=",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1768909835; x=1769514635;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=+VgCmqfL/f3KqfuCqqjFuFCkDpS0OkQo/Z+JIzb4h3g=;\n b=EEV7JQ5SqqjzYnqDMwe9pSK0OjvuZdoFqHflXLIFo5osd+8w8UUNfY46E/3rkZLzDG\n C5hKD3DU2/5Qp6OnFcsd2fx65LlPwwzOHUnIsgp9z17MMz7dm82sJ0VnzZaTXiqs+ghu\n BbzQT1jHUPFqKlPJC7lR1lTS3d+UGA3pJ/XG5mjDD3jtYHFb0914qVP0yEmi57W6mD0z\n uhPm9OHJrTL4RT86aDraTGOcJcXUeLRSspmRMgRiwRRdfenYsJaGttC9+/nZMK0ArSM3\n gQ9OdUDpt1KT2yuSUNXYmb1jX8gwI4SXrS7Dvol0DBXODRnK7WvKnpilZ7NW+pjS2zFS\n cCoA==",
        "X-Gm-Message-State": "AOJu0YyeVOpk0GIWbGA/41lV4u2Bk3J/rYhALVeu1CSV+ndGnBkv5ULx\n 1kXrDKW4jy380kQf7YmuHbGC38NFN0OvYT4fyvLug8NXI7DyO8Rddk0vbcKDAoRSczRMCoVNsTi\n lnVNs54q4BiWfsmoZqqLFmQfd4n9VVDXkU8KYyNMZSpQmyzs4EBOstuUbVMSR",
        "X-Gm-Gg": "AZuq6aJAHZBI2E2XBvS/RopDZdWnQL5KoKaMTzUt/O+5huby2Jsdbg4aPYfsDr2w+oC\n cKqe13IoZj8E47KstxaOdP4NDBfyND9Clb1Xg9SmJHeL3vWkzychGwATnl2SceGdGJlK2jgoGxs\n StTpJv8ZjwXNT4SGsV8LLzR18QuCeKmiiKEClCxl922oql+uv6TpyOFfGwGxJG1qdiEYCDRPIgV\n iHAkATvuc6+ArVUHk/4eR+NnL9+vM2Lok2q4epfuNuLIjqbdpdkkBIbPviwdvHIxSViun7845Zk\n f9VcYAC4hQQHeUWWspw6pPPPZ+sOaQR9utBO/q+62iobEeNmwroxy8NFMc8ls0/Pxnf9NFdpmtP\n gnZtg68K8PCuDT3/QbdK/VpZO7mf7Pu2e2iaLIJoNw48OXzbTUg+0Ft6QOwcAUZIZXXqx+DwZBN\n q2QgoTZdkeQ7+CJLprkwkMYQZyvrZgQjsB2wi8IQ==",
        "X-Received": "by 2002:a05:7301:9f18:b0:2b1:76f9:e094 with SMTP id\n 5a478bee46e88-2b6fd7d80a5mr1017998eec.36.1768909833233;\n Tue, 20 Jan 2026 03:50:33 -0800 (PST)",
        "To": "dev@openvswitch.org",
        "Date": "Tue, 20 Jan 2026 08:49:47 -0300",
        "Message-Id": "<20260120114948.2289909-9-guilherme.paulo@luizalabs.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20260120114948.2289909-1-guilherme.paulo@luizalabs.com>",
        "References": "<20260120114948.2289909-1-guilherme.paulo@luizalabs.com>",
        "MIME-Version": "1.0",
        "Subject": "[ovs-dev] [PATCH ovn v0 8/9] ovn-ic: Add a new engine-node\n 'service-monitor'.",
        "X-BeenThere": "ovs-dev@openvswitch.org",
        "X-Mailman-Version": "2.1.30",
        "Precedence": "list",
        "List-Id": "<ovs-dev.openvswitch.org>",
        "List-Unsubscribe": "<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n <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 <mailto:ovs-dev-request@openvswitch.org?subject=subscribe>",
        "From": "Paulo Guilherme Silva via dev <ovs-dev@openvswitch.org>",
        "Reply-To": "Paulo Guilherme Silva <guilherme.paulo@luizalabs.com>",
        "Content-Type": "text/plain; charset=\"iso-8859-1\"",
        "Content-Transfer-Encoding": "quoted-printable",
        "Errors-To": "ovs-dev-bounces@openvswitch.org",
        "Sender": "\"dev\" <ovs-dev-bounces@openvswitch.org>"
    },
    "content": "This new engine now maintains the service-monitor related data for ovn-ic\ndaemon which was earlier maintained by the ic engine node invoked the\nsync_service_monitor() function. The inputs to this engine node are:\n   en_icsb_service_monitor;\n   en_sb_sb_global;\n   en_sb_service_monitor;\n   en_nb_load_balancer;\n   en_nb_load_balancer_group;\n   en_sb_port_binding;\n\nIn order to achieve this, we refactor in the following way:\n* Introduce srv_mon_init() which initializes this data.\n* Introduce srv_mon_destroy() which clears this data for a new iteration.\n* Introduce srv_mon_run() which invokes the full recompute of the engine.\n\nThis engine node becomes an input to 'ic' node.\n\nSigned-off-by: Paulo Guilherme Silva <guilherme.paulo@luizalabs.com>\n---\n ic/automake.mk        |   2 +\n ic/en-ic.c            |  30 ---\n ic/en-srv-mon.c       | 586 ++++++++++++++++++++++++++++++++++++++++++\n ic/en-srv-mon.h       |  67 +++++\n ic/inc-proc-ic.c      |  16 +-\n ic/ovn-ic.c           | 439 +------------------------------\n ic/ovn-ic.h           |   7 -\n lib/stopwatch-names.h |   1 +\n 8 files changed, 670 insertions(+), 478 deletions(-)\n create mode 100644 ic/en-srv-mon.c\n create mode 100644 ic/en-srv-mon.h",
    "diff": "diff --git a/ic/automake.mk b/ic/automake.mk\nindex 84a487dc1..b84685f60 100644\n--- a/ic/automake.mk\n+++ b/ic/automake.mk\n@@ -16,6 +16,8 @@ ic_ovn_ic_SOURCES = ic/ovn-ic.c \\\n \tic/en-port-binding.h \\\n \tic/en-route.c \\\n \tic/en-route.h \\\n+\tic/en-srv-mon.c \\\n+\tic/en-srv-mon.h \\\n \tic/inc-proc-ic.c \\\n \tic/inc-proc-ic.h\n ic_ovn_ic_LDADD = \\\ndiff --git a/ic/en-ic.c b/ic/en-ic.c\nindex 14c5c29cb..ecdc1ab5d 100644\n--- a/ic/en-ic.c\n+++ b/ic/en-ic.c\n@@ -50,8 +50,6 @@ ic_get_input_data(struct engine_node *node,\n         EN_OVSDB_GET(engine_get_input(\"NB_logical_router\", node));\n     input_data->sbrec_chassis_table =\n         EN_OVSDB_GET(engine_get_input(\"SB_chassis\", node));\n-    input_data->sbrec_sb_global_table =\n-        EN_OVSDB_GET(engine_get_input(\"SB_sb_global\", node));\n     input_data->icsbrec_ic_sb_global_table =\n         EN_OVSDB_GET(engine_get_input(\"ICSB_ic_sb_global\", node));\n     input_data->icsbrec_availability_zone_table =\n@@ -78,34 +76,6 @@ ic_get_input_data(struct engine_node *node,\n         engine_ovsdb_node_get_index(\n             engine_get_input(\"SB_chassis\", node),\n             \"sbrec_chassis_by_name\");\n-    input_data->sbrec_port_binding_by_name =\n-        engine_ovsdb_node_get_index(\n-            engine_get_input(\"SB_port_binding\", node),\n-            \"sbrec_port_binding_by_name\");\n-    input_data->sbrec_service_monitor_by_remote_type =\n-        engine_ovsdb_node_get_index(\n-            engine_get_input(\"SB_service_monitor\", node),\n-            \"sbrec_service_monitor_by_remote_type\");\n-    input_data->sbrec_service_monitor_by_ic_learned =\n-        engine_ovsdb_node_get_index(\n-            engine_get_input(\"SB_service_monitor\", node),\n-            \"sbrec_service_monitor_by_ic_learned\");\n-    input_data->sbrec_service_monitor_by_remote_type_logical_port =\n-        engine_ovsdb_node_get_index(\n-            engine_get_input(\"SB_service_monitor\", node),\n-            \"sbrec_service_monitor_by_remote_type_logical_port\");\n-    input_data->icsbrec_service_monitor_by_source_az =\n-        engine_ovsdb_node_get_index(\n-            engine_get_input(\"ICSB_service_monitor\", node),\n-            \"icsbrec_service_monitor_by_source_az\");\n-    input_data->icsbrec_service_monitor_by_target_az =\n-        engine_ovsdb_node_get_index(\n-            engine_get_input(\"ICSB_service_monitor\", node),\n-            \"icsbrec_service_monitor_by_target_az\");\n-    input_data->icsbrec_service_monitor_by_target_az_logical_port =\n-        engine_ovsdb_node_get_index(\n-            engine_get_input(\"ICSB_service_monitor\", node),\n-            \"icsbrec_service_monitor_by_target_az_logical_port\");\n }\n \n enum engine_node_state\ndiff --git a/ic/en-srv-mon.c b/ic/en-srv-mon.c\nnew file mode 100644\nindex 000000000..a2d6739de\n--- /dev/null\n+++ b/ic/en-srv-mon.c\n@@ -0,0 +1,586 @@\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+\n+#include <getopt.h>\n+#include <stdlib.h>\n+#include <stdio.h>\n+\n+/* OVS includes. */\n+#include \"openvswitch/vlog.h\"\n+\n+/* OVN includes. */\n+#include \"ovn-ic.h\"\n+#include \"en-srv-mon.h\"\n+#include \"inc-proc-ic.h\"\n+#include \"lib/inc-proc-eng.h\"\n+#include \"lib/ovn-nb-idl.h\"\n+#include \"lib/ovn-sb-idl.h\"\n+#include \"lib/ovn-ic-sb-idl.h\"\n+#include \"lib/ovn-util.h\"\n+#include \"lib/stopwatch-names.h\"\n+#include \"coverage.h\"\n+#include \"stopwatch.h\"\n+#include \"stopwatch-names.h\"\n+\n+VLOG_DEFINE_THIS_MODULE(en_srv_mon);\n+COVERAGE_DEFINE(srv_monitor_run);\n+\n+static void\n+srv_mon_run(const struct engine_context *eng_ctx,\n+            struct ed_type_sync_service_monitor *srv_mon_data,\n+            struct srv_mon_input *srv_mon_input,\n+            const struct sbrec_sb_global_table *sbrec_sb_global_table);\n+\n+static void srv_mon_init(struct ed_type_sync_service_monitor *data);\n+static void srv_mon_destroy(struct ed_type_sync_service_monitor *data);\n+static void srv_mon_clear(struct ed_type_sync_service_monitor *data);\n+\n+static void\n+create_service_monitor_info(struct hmap *svc_map,\n+                            const void *db_rec,\n+                            const struct uuid *uuid,\n+                            const char *src_az_name,\n+                            const char *target_az_name,\n+                            const char *chassis_name,\n+                            bool ic_rec);\n+static void\n+destroy_service_monitor_info(struct service_monitor_info *svc_mon);\n+static void\n+refresh_sb_record_cache(struct hmap *svc_mon_map,\n+                        const struct sbrec_service_monitor *lookup_rec);\n+static void\n+refresh_ic_record_cache(struct hmap *svc_mon_map,\n+                        const struct icsbrec_service_monitor *lookup_rec);\n+static void\n+remove_unused_ic_records(struct hmap *local_ic_svcs_map);\n+static void\n+remove_unused_sb_records(struct hmap *local_sb_svcs_map);\n+static void\n+create_pushed_svcs_mon(struct srv_mon_input *srv_mon_input,\n+                       struct hmap *pushed_svcs_map);\n+static void\n+create_synced_svcs_mon(struct srv_mon_input *srv_mon_input,\n+                       struct hmap *synced_svcs_map);\n+static void\n+create_local_ic_svcs_map(struct srv_mon_input *srv_mon_input,\n+                         struct hmap *owned_svc_map);\n+static void\n+create_local_sb_svcs_map(struct srv_mon_input *srv_mon_input,\n+                         struct hmap *owned_svc_map);\n+static const struct sbrec_service_monitor *\n+lookup_sb_svc_rec(struct srv_mon_input *srv_mon_input,\n+                  const struct service_monitor_info *svc_mon);\n+static const struct icsbrec_service_monitor *\n+lookup_icsb_svc_rec(struct srv_mon_input *srv_mon_input,\n+                    const struct service_monitor_info *svc_mon);\n+static void\n+create_service_monitor_data(struct srv_mon_input *srv_mon_input,\n+    const struct sbrec_sb_global_table *sbrec_sb_global_table,\n+    struct ed_type_sync_service_monitor *sync_data);\n+static void\n+destroy_service_monitor_data(struct ed_type_sync_service_monitor *sync_data);\n+\n+static void\n+srv_mon_get_input_data(struct engine_node *node,\n+                       struct srv_mon_input *input_data)\n+{\n+    /* Indexes */\n+    input_data->sbrec_port_binding_by_name =\n+        engine_ovsdb_node_get_index(\n+            engine_get_input(\"SB_port_binding\", node),\n+            \"sbrec_port_binding_by_name\");\n+    input_data->sbrec_service_monitor_by_remote_type =\n+        engine_ovsdb_node_get_index(\n+            engine_get_input(\"SB_service_monitor\", node),\n+            \"sbrec_service_monitor_by_remote_type\");\n+    input_data->sbrec_service_monitor_by_ic_learned =\n+        engine_ovsdb_node_get_index(\n+            engine_get_input(\"SB_service_monitor\", node),\n+            \"sbrec_service_monitor_by_ic_learned\");\n+    input_data->sbrec_service_monitor_by_remote_type_logical_port =\n+        engine_ovsdb_node_get_index(\n+            engine_get_input(\"SB_service_monitor\", node),\n+            \"sbrec_service_monitor_by_remote_type_logical_port\");\n+    input_data->icsbrec_service_monitor_by_source_az =\n+        engine_ovsdb_node_get_index(\n+            engine_get_input(\"ICSB_service_monitor\", node),\n+            \"icsbrec_service_monitor_by_source_az\");\n+    input_data->icsbrec_service_monitor_by_target_az =\n+        engine_ovsdb_node_get_index(\n+            engine_get_input(\"ICSB_service_monitor\", node),\n+            \"icsbrec_service_monitor_by_target_az\");\n+    input_data->icsbrec_service_monitor_by_target_az_logical_port =\n+        engine_ovsdb_node_get_index(\n+            engine_get_input(\"ICSB_service_monitor\", node),\n+            \"icsbrec_service_monitor_by_target_az_logical_port\");\n+}\n+\n+enum engine_node_state\n+en_srv_mon_run(struct engine_node *node, void *data)\n+{\n+    const struct engine_context *eng_ctx = engine_get_context();\n+    struct ed_type_sync_service_monitor *srv_mon_data = data;\n+    struct srv_mon_input srv_mon_input;\n+\n+    srv_mon_clear(srv_mon_data);\n+\n+    const struct sbrec_sb_global_table *sbrec_sb_global_table =\n+        EN_OVSDB_GET(engine_get_input(\"SB_sb_global\", node));\n+\n+    srv_mon_get_input_data(node, &srv_mon_input);\n+    srv_mon_input.runned_az = eng_ctx->client_ctx;\n+\n+    COVERAGE_INC(srv_monitor_run);\n+    stopwatch_start(OVN_IC_SERVICE_MONITOR_RUN_STOPWATCH_NAME, time_usec());\n+    srv_mon_run(eng_ctx, srv_mon_data, &srv_mon_input, sbrec_sb_global_table);\n+    stopwatch_stop(OVN_IC_SERVICE_MONITOR_RUN_STOPWATCH_NAME, time_usec());\n+\n+    return EN_UPDATED;\n+}\n+\n+void *\n+en_srv_mon_init(struct engine_node *node OVS_UNUSED,\n+           struct engine_arg *arg OVS_UNUSED)\n+{\n+    struct ed_type_sync_service_monitor *data = xzalloc(sizeof *data);\n+    srv_mon_init(data);\n+    return data;\n+}\n+\n+void\n+en_srv_mon_cleanup(void *data)\n+{\n+    srv_mon_destroy(data);\n+}\n+\n+static void\n+srv_mon_init(struct ed_type_sync_service_monitor *data)\n+{\n+    hmap_init(&data->pushed_svcs_map);\n+    hmap_init(&data->synced_svcs_map);\n+    hmap_init(&data->local_ic_svcs_map);\n+    hmap_init(&data->local_sb_svcs_map);\n+    data->prpg_svc_monitor_mac = NULL;\n+    data->tracked = false;\n+}\n+\n+static void\n+srv_mon_destroy(struct ed_type_sync_service_monitor *data)\n+{\n+    destroy_service_monitor_data(data);\n+}\n+\n+static void\n+srv_mon_clear(struct ed_type_sync_service_monitor *data)\n+{\n+    destroy_service_monitor_data(data);\n+    srv_mon_init(data);\n+}\n+\n+static void\n+srv_mon_run(const struct engine_context *eng_ctx,\n+            struct ed_type_sync_service_monitor *srv_mon_data,\n+            struct srv_mon_input *srv_mon_input,\n+            const struct sbrec_sb_global_table *sbrec_sb_global_table)\n+{\n+    if (!eng_ctx->ovnisb_idl_txn || !eng_ctx->ovnsb_idl_txn) {\n+        return;\n+    }\n+\n+    create_service_monitor_data(srv_mon_input, sbrec_sb_global_table,\n+                                srv_mon_data);\n+\n+    struct service_monitor_info *svc_mon;\n+    HMAP_FOR_EACH_SAFE (svc_mon, hmap_node, &srv_mon_data->pushed_svcs_map) {\n+        const struct sbrec_service_monitor *db_rec = svc_mon->db_rec.sb_rec;\n+        const struct icsbrec_service_monitor *ic_rec =\n+            lookup_icsb_svc_rec(srv_mon_input, svc_mon);\n+\n+        if (ic_rec) {\n+            sbrec_service_monitor_set_status(db_rec, ic_rec->status);\n+        } else {\n+            ic_rec = icsbrec_service_monitor_insert(eng_ctx->ovnisb_idl_txn);\n+            icsbrec_service_monitor_set_type(ic_rec, db_rec->type);\n+            icsbrec_service_monitor_set_ip(ic_rec, db_rec->ip);\n+            icsbrec_service_monitor_set_port(ic_rec, db_rec->port);\n+            icsbrec_service_monitor_set_src_ip(ic_rec, db_rec->src_ip);\n+            icsbrec_service_monitor_set_src_mac(ic_rec,\n+                srv_mon_data->prpg_svc_monitor_mac);\n+            icsbrec_service_monitor_set_protocol(ic_rec, db_rec->protocol);\n+            icsbrec_service_monitor_set_logical_port(ic_rec,\n+                db_rec->logical_port);\n+            icsbrec_service_monitor_set_target_availability_zone(ic_rec,\n+                svc_mon->dst_az_name);\n+            icsbrec_service_monitor_set_source_availability_zone(ic_rec,\n+                svc_mon->src_az_name);\n+        }\n+\n+        /* Always update options because they change from NB. */\n+        icsbrec_service_monitor_set_options(ic_rec, &db_rec->options);\n+        refresh_ic_record_cache(&srv_mon_data->local_ic_svcs_map, ic_rec);\n+    }\n+\n+    HMAP_FOR_EACH_SAFE (svc_mon, hmap_node, &srv_mon_data->synced_svcs_map) {\n+        const struct icsbrec_service_monitor *db_rec =\n+            svc_mon->db_rec.ic_rec;\n+        const struct sbrec_service_monitor *sb_rec =\n+            lookup_sb_svc_rec(srv_mon_input, svc_mon);\n+\n+        if (sb_rec) {\n+            icsbrec_service_monitor_set_status(svc_mon->db_rec.ic_rec,\n+                                               sb_rec->status);\n+        } else {\n+            sb_rec = sbrec_service_monitor_insert(eng_ctx->ovnsb_idl_txn);\n+            sbrec_service_monitor_set_type(sb_rec, db_rec->type);\n+            sbrec_service_monitor_set_ip(sb_rec, db_rec->ip);\n+            sbrec_service_monitor_set_port(sb_rec, db_rec->port);\n+            sbrec_service_monitor_set_src_ip(sb_rec, db_rec->src_ip);\n+            /* Set svc_monitor_mac from local SBDB. */\n+            sbrec_service_monitor_set_src_mac(sb_rec,\n+                srv_mon_data->prpg_svc_monitor_mac);\n+            sbrec_service_monitor_set_protocol(sb_rec,\n+                db_rec->protocol);\n+            sbrec_service_monitor_set_logical_port(sb_rec,\n+                db_rec->logical_port);\n+            sbrec_service_monitor_set_remote(sb_rec, false);\n+            sbrec_service_monitor_set_ic_learned(sb_rec, true);\n+        }\n+\n+        /* Always update options since they may change via\n+         * NB configuration. Also update chassis_name if\n+         * the port has been reassigned to a different chassis.\n+         */\n+        if (svc_mon->chassis_name) {\n+            sbrec_service_monitor_set_chassis_name(sb_rec,\n+                svc_mon->chassis_name);\n+        }\n+        sbrec_service_monitor_set_options(sb_rec, &db_rec->options);\n+        refresh_sb_record_cache(&srv_mon_data->local_sb_svcs_map, sb_rec);\n+    }\n+\n+    /* Delete local created records that are no longer used. */\n+    remove_unused_ic_records(&srv_mon_data->local_ic_svcs_map);\n+    remove_unused_sb_records(&srv_mon_data->local_sb_svcs_map);\n+}\n+\n+static void\n+create_service_monitor_info(struct hmap *svc_map,\n+                            const void *db_rec,\n+                            const struct uuid *uuid,\n+                            const char *src_az_name,\n+                            const char *target_az_name,\n+                            const char *chassis_name,\n+                            bool ic_rec)\n+{\n+    struct service_monitor_info *svc_mon = xzalloc(sizeof(*svc_mon));\n+    size_t hash = uuid_hash(uuid);\n+\n+    if (ic_rec) {\n+        svc_mon->db_rec.ic_rec =\n+            (const struct icsbrec_service_monitor *) db_rec;\n+    } else {\n+        svc_mon->db_rec.sb_rec =\n+            (const struct sbrec_service_monitor *) db_rec;\n+    }\n+\n+    svc_mon->dst_az_name = target_az_name ? xstrdup(target_az_name) : NULL;\n+    svc_mon->chassis_name = chassis_name ? xstrdup(chassis_name) : NULL;\n+    svc_mon->src_az_name = xstrdup(src_az_name);\n+\n+    hmap_insert(svc_map, &svc_mon->hmap_node, hash);\n+}\n+\n+static void\n+destroy_service_monitor_info(struct service_monitor_info *svc_mon)\n+{\n+    free(svc_mon->src_az_name);\n+    free(svc_mon->dst_az_name);\n+    free(svc_mon->chassis_name);\n+    free(svc_mon);\n+}\n+\n+static void\n+refresh_sb_record_cache(struct hmap *svc_mon_map,\n+                        const struct sbrec_service_monitor *lookup_rec)\n+{\n+    size_t hash = uuid_hash(&lookup_rec->header_.uuid);\n+    struct service_monitor_info *svc_mon;\n+\n+    HMAP_FOR_EACH_WITH_HASH (svc_mon, hmap_node, hash, svc_mon_map) {\n+        ovs_assert(svc_mon->db_rec.sb_rec);\n+        if (svc_mon->db_rec.sb_rec == lookup_rec) {\n+            hmap_remove(svc_mon_map, &svc_mon->hmap_node);\n+            destroy_service_monitor_info(svc_mon);\n+            return;\n+        }\n+    }\n+}\n+\n+static void\n+refresh_ic_record_cache(struct hmap *svc_mon_map,\n+                        const struct icsbrec_service_monitor *lookup_rec)\n+{\n+    size_t hash = uuid_hash(&lookup_rec->header_.uuid);\n+    struct service_monitor_info *svc_mon;\n+\n+    HMAP_FOR_EACH_WITH_HASH (svc_mon, hmap_node, hash, svc_mon_map) {\n+        ovs_assert(svc_mon->db_rec.ic_rec);\n+        if (svc_mon->db_rec.ic_rec == lookup_rec) {\n+            hmap_remove(svc_mon_map, &svc_mon->hmap_node);\n+            destroy_service_monitor_info(svc_mon);\n+            return;\n+        }\n+    }\n+}\n+\n+static void\n+remove_unused_ic_records(struct hmap *local_ic_svcs_map)\n+{\n+    struct service_monitor_info *svc_mon;\n+    HMAP_FOR_EACH_SAFE (svc_mon, hmap_node, local_ic_svcs_map) {\n+        icsbrec_service_monitor_delete(svc_mon->db_rec.ic_rec);\n+        destroy_service_monitor_info(svc_mon);\n+    }\n+\n+    hmap_destroy(local_ic_svcs_map);\n+}\n+\n+static void\n+remove_unused_sb_records(struct hmap *local_sb_svcs_map)\n+{\n+    struct service_monitor_info *svc_mon;\n+    HMAP_FOR_EACH_SAFE (svc_mon, hmap_node, local_sb_svcs_map) {\n+        sbrec_service_monitor_delete(svc_mon->db_rec.sb_rec);\n+        destroy_service_monitor_info(svc_mon);\n+    }\n+\n+    hmap_destroy(local_sb_svcs_map);\n+}\n+\n+static void\n+create_pushed_svcs_mon(struct srv_mon_input *srv_mon_input,\n+                       struct hmap *pushed_svcs_map)\n+{\n+    struct sbrec_service_monitor *key =\n+        sbrec_service_monitor_index_init_row(\n+            srv_mon_input->sbrec_service_monitor_by_remote_type);\n+\n+    sbrec_service_monitor_index_set_remote(key, true);\n+\n+    const struct sbrec_service_monitor *sb_rec;\n+    SBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (sb_rec, key,\n+        srv_mon_input->sbrec_service_monitor_by_remote_type) {\n+        const char *target_az_name = smap_get(&sb_rec->options,\n+                                              \"az-name\");\n+        if (!target_az_name) {\n+            continue;\n+        }\n+        create_service_monitor_info(pushed_svcs_map, sb_rec,\n+                                    &sb_rec->header_.uuid,\n+                                    srv_mon_input->runned_az->name,\n+                                    target_az_name, NULL, false);\n+    }\n+\n+    sbrec_service_monitor_index_destroy_row(key);\n+}\n+\n+static void\n+create_synced_svcs_mon(struct srv_mon_input *srv_mon_input,\n+                       struct hmap *synced_svcs_map)\n+{\n+    struct icsbrec_service_monitor *key =\n+        icsbrec_service_monitor_index_init_row(\n+          srv_mon_input->icsbrec_service_monitor_by_target_az);\n+\n+    icsbrec_service_monitor_index_set_target_availability_zone(\n+        key, srv_mon_input->runned_az->name);\n+\n+    const struct icsbrec_service_monitor *ic_rec;\n+    ICSBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (ic_rec, key,\n+        srv_mon_input->icsbrec_service_monitor_by_target_az) {\n+\n+        const struct sbrec_port_binding *pb =\n+            find_sb_pb_by_name(srv_mon_input->sbrec_port_binding_by_name,\n+                               ic_rec->logical_port);\n+\n+        if (!pb || !pb->up) {\n+            continue;\n+        }\n+\n+        const char *chassis_name = pb->chassis ? pb->chassis->name : NULL;\n+        create_service_monitor_info(synced_svcs_map, ic_rec,\n+                                    &ic_rec->header_.uuid,\n+                                    srv_mon_input->runned_az->name, NULL,\n+                                    chassis_name, true);\n+    }\n+\n+    icsbrec_service_monitor_index_destroy_row(key);\n+}\n+\n+static void\n+create_local_ic_svcs_map(struct srv_mon_input *srv_mon_input,\n+                         struct hmap *owned_svc_map)\n+{\n+    struct icsbrec_service_monitor *key =\n+        icsbrec_service_monitor_index_init_row(\n+          srv_mon_input->icsbrec_service_monitor_by_source_az);\n+\n+    icsbrec_service_monitor_index_set_source_availability_zone(\n+        key, srv_mon_input->runned_az->name);\n+\n+    const struct icsbrec_service_monitor *ic_rec;\n+    ICSBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (ic_rec, key,\n+        srv_mon_input->icsbrec_service_monitor_by_source_az) {\n+        create_service_monitor_info(owned_svc_map, ic_rec,\n+                                    &ic_rec->header_.uuid,\n+                                    srv_mon_input->runned_az->name, NULL,\n+                                    NULL, true);\n+    }\n+\n+    icsbrec_service_monitor_index_destroy_row(key);\n+}\n+\n+static void\n+create_local_sb_svcs_map(struct srv_mon_input *srv_mon_input,\n+                         struct hmap *owned_svc_map)\n+{\n+    struct sbrec_service_monitor *key =\n+        sbrec_service_monitor_index_init_row(\n+          srv_mon_input->sbrec_service_monitor_by_ic_learned);\n+\n+    sbrec_service_monitor_index_set_ic_learned(\n+        key, true);\n+\n+    const struct sbrec_service_monitor *sb_rec;\n+    SBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (sb_rec, key,\n+        srv_mon_input->sbrec_service_monitor_by_ic_learned) {\n+        create_service_monitor_info(owned_svc_map, sb_rec,\n+                                    &sb_rec->header_.uuid,\n+                                    srv_mon_input->runned_az->name, NULL,\n+                                    NULL, false);\n+    }\n+\n+    sbrec_service_monitor_index_destroy_row(key);\n+}\n+\n+static const struct sbrec_service_monitor *\n+lookup_sb_svc_rec(struct srv_mon_input *srv_mon_input,\n+                  const struct service_monitor_info *svc_mon)\n+{\n+    const struct icsbrec_service_monitor *db_rec =\n+        svc_mon->db_rec.ic_rec;\n+    struct sbrec_service_monitor *key =\n+        sbrec_service_monitor_index_init_row(\n+            srv_mon_input->sbrec_service_monitor_by_remote_type_logical_port);\n+\n+    sbrec_service_monitor_index_set_remote(key, false);\n+    sbrec_service_monitor_index_set_logical_port(key, db_rec->logical_port);\n+\n+    const struct sbrec_service_monitor *sb_rec;\n+    SBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (sb_rec, key,\n+        srv_mon_input->sbrec_service_monitor_by_remote_type_logical_port) {\n+        if (db_rec->port == sb_rec->port &&\n+            ((db_rec->type && sb_rec->type &&\n+              !strcmp(db_rec->type, sb_rec->type)) ||\n+             (!db_rec->type && !sb_rec->type)) &&\n+            !strcmp(db_rec->ip, sb_rec->ip) &&\n+            !strcmp(db_rec->src_ip, sb_rec->src_ip) &&\n+            !strcmp(db_rec->protocol, sb_rec->protocol)) {\n+            sbrec_service_monitor_index_destroy_row(key);\n+            return sb_rec;\n+        }\n+    }\n+\n+    sbrec_service_monitor_index_destroy_row(key);\n+\n+    return NULL;\n+}\n+\n+static const struct icsbrec_service_monitor *\n+lookup_icsb_svc_rec(struct srv_mon_input *srv_mon_input,\n+                    const struct service_monitor_info *svc_mon)\n+{\n+    const struct sbrec_service_monitor *db_rec =\n+       svc_mon->db_rec.sb_rec;\n+    struct icsbrec_service_monitor *key =\n+        icsbrec_service_monitor_index_init_row(\n+        srv_mon_input->icsbrec_service_monitor_by_target_az_logical_port);\n+\n+    ovs_assert(svc_mon->dst_az_name);\n+    icsbrec_service_monitor_index_set_target_availability_zone(\n+        key, svc_mon->dst_az_name);\n+\n+    icsbrec_service_monitor_index_set_logical_port(\n+        key, db_rec->logical_port);\n+\n+    const struct icsbrec_service_monitor *ic_rec;\n+    ICSBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (ic_rec, key,\n+        srv_mon_input->icsbrec_service_monitor_by_target_az_logical_port) {\n+        if (db_rec->port == ic_rec->port &&\n+            ((db_rec->type && ic_rec->type &&\n+              !strcmp(db_rec->type, ic_rec->type)) ||\n+             (!db_rec->type && !ic_rec->type)) &&\n+            !strcmp(db_rec->ip, ic_rec->ip) &&\n+            !strcmp(db_rec->src_ip, ic_rec->src_ip) &&\n+            !strcmp(db_rec->protocol, ic_rec->protocol) &&\n+            !strcmp(db_rec->logical_port, ic_rec->logical_port)) {\n+            icsbrec_service_monitor_index_destroy_row(key);\n+            return ic_rec;\n+        }\n+    }\n+\n+    icsbrec_service_monitor_index_destroy_row(key);\n+\n+    return NULL;\n+}\n+\n+static void\n+create_service_monitor_data(struct srv_mon_input *srv_mon_input,\n+    const struct sbrec_sb_global_table *sbrec_sb_global_table,\n+    struct ed_type_sync_service_monitor *sync_data)\n+{\n+    const struct sbrec_sb_global *ic_sb =\n+        sbrec_sb_global_table_first(sbrec_sb_global_table);\n+    const char *svc_monitor_mac = smap_get(&ic_sb->options,\n+                                           \"svc_monitor_mac\");\n+\n+    if (!svc_monitor_mac) {\n+        return;\n+    }\n+\n+    sync_data->prpg_svc_monitor_mac = xstrdup(svc_monitor_mac);\n+    create_pushed_svcs_mon(srv_mon_input, &sync_data->pushed_svcs_map);\n+    create_synced_svcs_mon(srv_mon_input, &sync_data->synced_svcs_map);\n+    create_local_ic_svcs_map(srv_mon_input, &sync_data->local_ic_svcs_map);\n+    create_local_sb_svcs_map(srv_mon_input, &sync_data->local_sb_svcs_map);\n+}\n+\n+static void\n+destroy_service_monitor_data(struct ed_type_sync_service_monitor *sync_data)\n+{\n+    struct service_monitor_info *svc_mon;\n+    HMAP_FOR_EACH_SAFE (svc_mon, hmap_node, &sync_data->pushed_svcs_map) {\n+        destroy_service_monitor_info(svc_mon);\n+    }\n+\n+    HMAP_FOR_EACH_SAFE (svc_mon, hmap_node, &sync_data->synced_svcs_map) {\n+        destroy_service_monitor_info(svc_mon);\n+    }\n+\n+    hmap_destroy(&sync_data->pushed_svcs_map);\n+    hmap_destroy(&sync_data->synced_svcs_map);\n+    free(sync_data->prpg_svc_monitor_mac);\n+}\ndiff --git a/ic/en-srv-mon.h b/ic/en-srv-mon.h\nnew file mode 100644\nindex 000000000..1b160dd4d\n--- /dev/null\n+++ b/ic/en-srv-mon.h\n@@ -0,0 +1,67 @@\n+#ifndef EN_IC_SRV_MONITOR_RUN_H\n+#define EN_IC_SRV_MONITOR_RUN_H 1\n+\n+#include <config.h>\n+\n+#include <stdbool.h>\n+#include <getopt.h>\n+#include <stdlib.h>\n+#include <stdio.h>\n+\n+/* OVS includes. */\n+#include \"openvswitch/hmap.h\"\n+\n+/* OVN includes. */\n+#include \"lib/inc-proc-eng.h\"\n+\n+/*\n+ * Data structures and functions related to\n+ * synchronize health checks for load balancers\n+ * between availability zones.\n+ */\n+struct ed_type_sync_service_monitor {\n+    /* Map of service monitors to be pushed to other AZs. */\n+    struct hmap pushed_svcs_map;\n+    /* Map of service monitors synced from other AZs to our. */\n+    struct hmap synced_svcs_map;\n+    /* Map of local service monitors in the ICSBDB. */\n+    struct hmap local_ic_svcs_map;\n+    /* Map of local service monitors in SBDB. */\n+    struct hmap local_sb_svcs_map;\n+    /* MAC address used for service monitor.  */\n+    char *prpg_svc_monitor_mac;\n+\n+    bool tracked;\n+};\n+\n+struct service_monitor_info {\n+    struct hmap_node hmap_node;\n+    union {\n+        const struct sbrec_service_monitor *sb_rec;\n+        const struct icsbrec_service_monitor *ic_rec;\n+    } db_rec;\n+    /* Destination availability zone name. */\n+    char *dst_az_name;\n+    /* Source availability zone name. */\n+    char *src_az_name;\n+    /* Chassis name associated with monitor logical port. */\n+    char *chassis_name;\n+};\n+\n+struct srv_mon_input {\n+    /* Indexes */\n+    const struct icsbrec_availability_zone *runned_az;\n+    struct ovsdb_idl_index *sbrec_port_binding_by_name;\n+    struct ovsdb_idl_index *sbrec_service_monitor_by_remote_type;\n+    struct ovsdb_idl_index *sbrec_service_monitor_by_ic_learned;\n+    struct ovsdb_idl_index *sbrec_service_monitor_by_remote_type_logical_port;\n+    struct ovsdb_idl_index *icsbrec_service_monitor_by_source_az;\n+    struct ovsdb_idl_index *icsbrec_service_monitor_by_target_az;\n+    struct ovsdb_idl_index *icsbrec_service_monitor_by_target_az_logical_port;\n+};\n+\n+void *en_srv_mon_init(struct engine_node *, struct engine_arg *);\n+enum engine_node_state en_srv_mon_run(struct engine_node *, void *data);\n+void en_srv_mon_cleanup(void *data);\n+\n+#endif\ndiff --git a/ic/inc-proc-ic.c b/ic/inc-proc-ic.c\nindex af282fad6..0fe787a19 100644\n--- a/ic/inc-proc-ic.c\n+++ b/ic/inc-proc-ic.c\n@@ -33,6 +33,7 @@\n #include \"en-tr.h\"\n #include \"en-port-binding.h\"\n #include \"en-route.h\"\n+#include \"en-srv-mon.h\"\n #include \"unixctl.h\"\n #include \"util.h\"\n \n@@ -170,6 +171,7 @@ static ENGINE_NODE(tr);\n static ENGINE_NODE(ts, SB_WRITE);\n static ENGINE_NODE(port_binding, SB_WRITE);\n static ENGINE_NODE(route);\n+static ENGINE_NODE(srv_mon, SB_WRITE);\n \n void inc_proc_ic_init(struct ovsdb_idl_loop *nb,\n                       struct ovsdb_idl_loop *sb,\n@@ -213,30 +215,32 @@ void inc_proc_ic_init(struct ovsdb_idl_loop *nb,\n     engine_add_input(&en_route, &en_icsb_route, NULL);\n     engine_add_input(&en_route, &en_nb_logical_router_static_route, NULL);\n \n+    engine_add_input(&en_srv_mon, &en_icsb_service_monitor, NULL);\n+    engine_add_input(&en_srv_mon, &en_sb_sb_global, NULL);\n+    engine_add_input(&en_srv_mon, &en_sb_service_monitor, NULL);\n+    engine_add_input(&en_srv_mon, &en_nb_load_balancer, NULL);\n+    engine_add_input(&en_srv_mon, &en_nb_load_balancer_group, NULL);\n+    engine_add_input(&en_srv_mon, &en_sb_port_binding, NULL);\n+\n     engine_add_input(&en_ic, &en_gateway, NULL);\n     engine_add_input(&en_ic, &en_enum_datapaths, NULL);\n     engine_add_input(&en_ic, &en_ts, NULL);\n     engine_add_input(&en_ic, &en_tr, NULL);\n     engine_add_input(&en_ic, &en_port_binding, NULL);\n     engine_add_input(&en_ic, &en_route, NULL);\n+    engine_add_input(&en_ic, &en_srv_mon, NULL);\n \n     engine_add_input(&en_ic, &en_nb_logical_router, NULL);\n     engine_add_input(&en_ic, &en_nb_logical_router_port, NULL);\n     engine_add_input(&en_ic, &en_nb_logical_switch, NULL);\n     engine_add_input(&en_ic, &en_nb_logical_switch_port, NULL);\n-    engine_add_input(&en_ic, &en_nb_load_balancer, NULL);\n-    engine_add_input(&en_ic, &en_nb_load_balancer_group, NULL);\n \n-    engine_add_input(&en_ic, &en_sb_sb_global, NULL);\n     engine_add_input(&en_ic, &en_sb_chassis, NULL);\n     engine_add_input(&en_ic, &en_sb_encap, NULL);\n     engine_add_input(&en_ic, &en_sb_datapath_binding, NULL);\n-    engine_add_input(&en_ic, &en_sb_port_binding, NULL);\n-    engine_add_input(&en_ic, &en_sb_service_monitor, NULL);\n \n     engine_add_input(&en_ic, &en_icsb_ic_sb_global, NULL);\n     engine_add_input(&en_ic, &en_icsb_availability_zone, NULL);\n-    engine_add_input(&en_ic, &en_icsb_service_monitor, NULL);\n \n     struct engine_arg engine_arg = {\n         .nb_idl = nb->idl,\ndiff --git a/ic/ovn-ic.c b/ic/ovn-ic.c\nindex 301b54fb2..3406c4d5d 100644\n--- a/ic/ovn-ic.c\n+++ b/ic/ovn-ic.c\n@@ -247,438 +247,6 @@ find_sb_pb_by_name(struct ovsdb_idl_index *sbrec_port_binding_by_name,\n     return pb;\n }\n \n-/*\n- * Data structures and functions related to\n- * synchronize health checks for load balancers\n- * between availability zones.\n- */\n-struct sync_service_monitor_data {\n-    /* Map of service monitors to be pushed to other AZs. */\n-    struct hmap pushed_svcs_map;\n-    /* Map of service monitors synced from other AZs to our. */\n-    struct hmap synced_svcs_map;\n-    /* Map of local service monitors in the ICSBDB. */\n-    struct hmap local_ic_svcs_map;\n-    /* Map of local service monitors in SBDB. */\n-    struct hmap local_sb_svcs_map;\n-    /* MAC address used for service monitor.  */\n-    char *prpg_svc_monitor_mac;\n-};\n-\n-struct service_monitor_info {\n-    struct hmap_node hmap_node;\n-    union {\n-        const struct sbrec_service_monitor *sb_rec;\n-        const struct icsbrec_service_monitor *ic_rec;\n-    } db_rec;\n-    /* Destination availability zone name. */\n-    char *dst_az_name;\n-    /* Source availability zone name. */\n-    char *src_az_name;\n-    /* Chassis name associated with monitor logical port. */\n-    char *chassis_name;\n-};\n-\n-static void\n-create_service_monitor_info(struct hmap *svc_map,\n-                            const void *db_rec,\n-                            const struct uuid *uuid,\n-                            const char *src_az_name,\n-                            const char *target_az_name,\n-                            const char *chassis_name,\n-                            bool ic_rec)\n-{\n-    struct service_monitor_info *svc_mon = xzalloc(sizeof(*svc_mon));\n-    size_t hash = uuid_hash(uuid);\n-\n-    if (ic_rec) {\n-        svc_mon->db_rec.ic_rec =\n-            (const struct icsbrec_service_monitor *) db_rec;\n-    } else {\n-        svc_mon->db_rec.sb_rec =\n-            (const struct sbrec_service_monitor *) db_rec;\n-    }\n-\n-    svc_mon->dst_az_name = target_az_name ? xstrdup(target_az_name) : NULL;\n-    svc_mon->chassis_name = chassis_name ? xstrdup(chassis_name) : NULL;\n-    svc_mon->src_az_name = xstrdup(src_az_name);\n-\n-    hmap_insert(svc_map, &svc_mon->hmap_node, hash);\n-}\n-\n-static void\n-destroy_service_monitor_info(struct service_monitor_info *svc_mon)\n-{\n-    free(svc_mon->src_az_name);\n-    free(svc_mon->dst_az_name);\n-    free(svc_mon->chassis_name);\n-    free(svc_mon);\n-}\n-\n-static void\n-refresh_sb_record_cache(struct hmap *svc_mon_map,\n-                        const struct sbrec_service_monitor *lookup_rec)\n-{\n-    size_t hash = uuid_hash(&lookup_rec->header_.uuid);\n-    struct service_monitor_info *svc_mon;\n-\n-    HMAP_FOR_EACH_WITH_HASH (svc_mon, hmap_node, hash, svc_mon_map) {\n-        ovs_assert(svc_mon->db_rec.sb_rec);\n-        if (svc_mon->db_rec.sb_rec == lookup_rec) {\n-            hmap_remove(svc_mon_map, &svc_mon->hmap_node);\n-            destroy_service_monitor_info(svc_mon);\n-            return;\n-        }\n-    }\n-}\n-\n-static void\n-refresh_ic_record_cache(struct hmap *svc_mon_map,\n-                        const struct icsbrec_service_monitor *lookup_rec)\n-{\n-    size_t hash = uuid_hash(&lookup_rec->header_.uuid);\n-    struct service_monitor_info *svc_mon;\n-\n-    HMAP_FOR_EACH_WITH_HASH (svc_mon, hmap_node, hash, svc_mon_map) {\n-        ovs_assert(svc_mon->db_rec.ic_rec);\n-        if (svc_mon->db_rec.ic_rec == lookup_rec) {\n-            hmap_remove(svc_mon_map, &svc_mon->hmap_node);\n-            destroy_service_monitor_info(svc_mon);\n-            return;\n-        }\n-    }\n-}\n-\n-static void\n-remove_unused_ic_records(struct hmap *local_ic_svcs_map)\n-{\n-    struct service_monitor_info *svc_mon;\n-    HMAP_FOR_EACH_SAFE (svc_mon, hmap_node, local_ic_svcs_map) {\n-        icsbrec_service_monitor_delete(svc_mon->db_rec.ic_rec);\n-        destroy_service_monitor_info(svc_mon);\n-    }\n-\n-    hmap_destroy(local_ic_svcs_map);\n-}\n-\n-static void\n-remove_unused_sb_records(struct hmap *local_sb_svcs_map)\n-{\n-    struct service_monitor_info *svc_mon;\n-    HMAP_FOR_EACH_SAFE (svc_mon, hmap_node, local_sb_svcs_map) {\n-        sbrec_service_monitor_delete(svc_mon->db_rec.sb_rec);\n-        destroy_service_monitor_info(svc_mon);\n-    }\n-\n-    hmap_destroy(local_sb_svcs_map);\n-}\n-\n-static void\n-create_pushed_svcs_mon(struct ic_input *ic,\n-                       struct hmap *pushed_svcs_map)\n-{\n-    struct sbrec_service_monitor *key =\n-        sbrec_service_monitor_index_init_row(\n-            ic->sbrec_service_monitor_by_remote_type);\n-\n-    sbrec_service_monitor_index_set_remote(key, true);\n-\n-    const struct sbrec_service_monitor *sb_rec;\n-    SBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (sb_rec, key,\n-        ic->sbrec_service_monitor_by_remote_type) {\n-        const char *target_az_name = smap_get(&sb_rec->options,\n-                                              \"az-name\");\n-        if (!target_az_name) {\n-            continue;\n-        }\n-        create_service_monitor_info(pushed_svcs_map, sb_rec,\n-                                    &sb_rec->header_.uuid,\n-                                    ic->runned_az->name, target_az_name,\n-                                    NULL, false);\n-    }\n-\n-    sbrec_service_monitor_index_destroy_row(key);\n-}\n-\n-static void\n-create_synced_svcs_mon(struct ic_input *ic,\n-                       struct hmap *synced_svcs_map)\n-{\n-    struct icsbrec_service_monitor *key =\n-        icsbrec_service_monitor_index_init_row(\n-          ic->icsbrec_service_monitor_by_target_az);\n-\n-    icsbrec_service_monitor_index_set_target_availability_zone(\n-        key, ic->runned_az->name);\n-\n-    const struct icsbrec_service_monitor *ic_rec;\n-    ICSBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (ic_rec, key,\n-        ic->icsbrec_service_monitor_by_target_az) {\n-\n-        const struct sbrec_port_binding *pb =\n-            find_sb_pb_by_name(ic->sbrec_port_binding_by_name,\n-                               ic_rec->logical_port);\n-\n-        if (!pb || !pb->up) {\n-            continue;\n-        }\n-\n-        const char *chassis_name = pb->chassis ? pb->chassis->name : NULL;\n-        create_service_monitor_info(synced_svcs_map, ic_rec,\n-                                    &ic_rec->header_.uuid,\n-                                    ic->runned_az->name,\n-                                    NULL, chassis_name, true);\n-    }\n-\n-    icsbrec_service_monitor_index_destroy_row(key);\n-}\n-\n-static void\n-create_local_ic_svcs_map(struct ic_input *ic,\n-                         struct hmap *owned_svc_map)\n-{\n-    struct icsbrec_service_monitor *key =\n-        icsbrec_service_monitor_index_init_row(\n-          ic->icsbrec_service_monitor_by_source_az);\n-\n-    icsbrec_service_monitor_index_set_source_availability_zone(\n-        key, ic->runned_az->name);\n-\n-    const struct icsbrec_service_monitor *ic_rec;\n-    ICSBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (ic_rec, key,\n-        ic->icsbrec_service_monitor_by_source_az) {\n-        create_service_monitor_info(owned_svc_map, ic_rec,\n-                                    &ic_rec->header_.uuid,\n-                                    ic->runned_az->name, NULL,\n-                                    NULL, true);\n-    }\n-\n-    icsbrec_service_monitor_index_destroy_row(key);\n-}\n-\n-static void\n-create_local_sb_svcs_map(struct ic_input *ic,\n-                         struct hmap *owned_svc_map)\n-{\n-    struct sbrec_service_monitor *key =\n-        sbrec_service_monitor_index_init_row(\n-          ic->sbrec_service_monitor_by_ic_learned);\n-\n-    sbrec_service_monitor_index_set_ic_learned(\n-        key, true);\n-\n-    const struct sbrec_service_monitor *sb_rec;\n-    SBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (sb_rec, key,\n-        ic->sbrec_service_monitor_by_ic_learned) {\n-        create_service_monitor_info(owned_svc_map, sb_rec,\n-                                    &sb_rec->header_.uuid,\n-                                    ic->runned_az->name, NULL,\n-                                    NULL, false);\n-    }\n-\n-    sbrec_service_monitor_index_destroy_row(key);\n-}\n-\n-static const struct sbrec_service_monitor *\n-lookup_sb_svc_rec(struct ic_input *ic,\n-                  const struct service_monitor_info *svc_mon)\n-{\n-    const struct icsbrec_service_monitor *db_rec =\n-        svc_mon->db_rec.ic_rec;\n-    struct sbrec_service_monitor *key =\n-        sbrec_service_monitor_index_init_row(\n-            ic->sbrec_service_monitor_by_remote_type_logical_port);\n-\n-    sbrec_service_monitor_index_set_remote(key, false);\n-    sbrec_service_monitor_index_set_logical_port(key, db_rec->logical_port);\n-\n-    const struct sbrec_service_monitor *sb_rec;\n-    SBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (sb_rec, key,\n-        ic->sbrec_service_monitor_by_remote_type_logical_port) {\n-        if (db_rec->port == sb_rec->port &&\n-            ((db_rec->type && sb_rec->type &&\n-              !strcmp(db_rec->type, sb_rec->type)) ||\n-             (!db_rec->type && !sb_rec->type)) &&\n-            !strcmp(db_rec->ip, sb_rec->ip) &&\n-            !strcmp(db_rec->src_ip, sb_rec->src_ip) &&\n-            !strcmp(db_rec->protocol, sb_rec->protocol)) {\n-            sbrec_service_monitor_index_destroy_row(key);\n-            return sb_rec;\n-        }\n-    }\n-\n-    sbrec_service_monitor_index_destroy_row(key);\n-\n-    return NULL;\n-}\n-\n-static const struct icsbrec_service_monitor *\n-lookup_icsb_svc_rec(struct ic_input *ic,\n-                    const struct service_monitor_info *svc_mon)\n-{\n-    const struct sbrec_service_monitor *db_rec =\n-       svc_mon->db_rec.sb_rec;\n-    struct icsbrec_service_monitor *key =\n-        icsbrec_service_monitor_index_init_row(\n-        ic->icsbrec_service_monitor_by_target_az_logical_port);\n-\n-    ovs_assert(svc_mon->dst_az_name);\n-    icsbrec_service_monitor_index_set_target_availability_zone(\n-        key, svc_mon->dst_az_name);\n-\n-    icsbrec_service_monitor_index_set_logical_port(\n-        key, db_rec->logical_port);\n-\n-    const struct icsbrec_service_monitor *ic_rec;\n-    ICSBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (ic_rec, key,\n-        ic->icsbrec_service_monitor_by_target_az_logical_port) {\n-        if (db_rec->port == ic_rec->port &&\n-            ((db_rec->type && ic_rec->type &&\n-              !strcmp(db_rec->type, ic_rec->type)) ||\n-             (!db_rec->type && !ic_rec->type)) &&\n-            !strcmp(db_rec->ip, ic_rec->ip) &&\n-            !strcmp(db_rec->src_ip, ic_rec->src_ip) &&\n-            !strcmp(db_rec->protocol, ic_rec->protocol) &&\n-            !strcmp(db_rec->logical_port, ic_rec->logical_port)) {\n-            icsbrec_service_monitor_index_destroy_row(key);\n-            return ic_rec;\n-        }\n-    }\n-\n-    icsbrec_service_monitor_index_destroy_row(key);\n-\n-    return NULL;\n-}\n-\n-static void\n-create_service_monitor_data(struct ic_input *ic,\n-                            struct sync_service_monitor_data *sync_data)\n-{\n-    const struct sbrec_sb_global *ic_sb =\n-        sbrec_sb_global_table_first(ic->sbrec_sb_global_table);\n-    const char *svc_monitor_mac = smap_get(&ic_sb->options,\n-                                           \"svc_monitor_mac\");\n-\n-    if (!svc_monitor_mac) {\n-        return;\n-    }\n-\n-    sync_data->prpg_svc_monitor_mac = xstrdup(svc_monitor_mac);\n-    create_pushed_svcs_mon(ic, &sync_data->pushed_svcs_map);\n-    create_synced_svcs_mon(ic, &sync_data->synced_svcs_map);\n-    create_local_ic_svcs_map(ic, &sync_data->local_ic_svcs_map);\n-    create_local_sb_svcs_map(ic, &sync_data->local_sb_svcs_map);\n-}\n-\n-static void\n-destroy_service_monitor_data(struct sync_service_monitor_data *sync_data)\n-{\n-    struct service_monitor_info *svc_mon;\n-    HMAP_FOR_EACH_SAFE (svc_mon, hmap_node, &sync_data->pushed_svcs_map) {\n-        destroy_service_monitor_info(svc_mon);\n-    }\n-\n-    HMAP_FOR_EACH_SAFE (svc_mon, hmap_node, &sync_data->synced_svcs_map) {\n-        destroy_service_monitor_info(svc_mon);\n-    }\n-\n-    hmap_destroy(&sync_data->pushed_svcs_map);\n-    hmap_destroy(&sync_data->synced_svcs_map);\n-    free(sync_data->prpg_svc_monitor_mac);\n-}\n-\n-static void\n-sync_service_monitor(struct engine_context *ctx,\n-                     struct ic_input *ic)\n-{\n-    if (!ctx->ovnisb_idl_txn || !ctx->ovnsb_idl_txn) {\n-        return;\n-    }\n-\n-    struct sync_service_monitor_data sync_data;\n-    memset(&sync_data, 0, sizeof(sync_data));\n-    hmap_init(&sync_data.pushed_svcs_map);\n-    hmap_init(&sync_data.synced_svcs_map);\n-    hmap_init(&sync_data.local_ic_svcs_map);\n-    hmap_init(&sync_data.local_sb_svcs_map);\n-\n-    create_service_monitor_data(ic, &sync_data);\n-\n-    struct service_monitor_info *svc_mon;\n-    HMAP_FOR_EACH_SAFE (svc_mon, hmap_node, &sync_data.pushed_svcs_map) {\n-        const struct sbrec_service_monitor *db_rec = svc_mon->db_rec.sb_rec;\n-        const struct icsbrec_service_monitor *ic_rec =\n-            lookup_icsb_svc_rec(ic, svc_mon);\n-\n-        if (ic_rec) {\n-            sbrec_service_monitor_set_status(db_rec, ic_rec->status);\n-        } else {\n-            ic_rec = icsbrec_service_monitor_insert(ctx->ovnisb_idl_txn);\n-            icsbrec_service_monitor_set_type(ic_rec, db_rec->type);\n-            icsbrec_service_monitor_set_ip(ic_rec, db_rec->ip);\n-            icsbrec_service_monitor_set_port(ic_rec, db_rec->port);\n-            icsbrec_service_monitor_set_src_ip(ic_rec, db_rec->src_ip);\n-            icsbrec_service_monitor_set_src_mac(ic_rec,\n-                sync_data.prpg_svc_monitor_mac);\n-            icsbrec_service_monitor_set_protocol(ic_rec, db_rec->protocol);\n-            icsbrec_service_monitor_set_logical_port(ic_rec,\n-                db_rec->logical_port);\n-            icsbrec_service_monitor_set_target_availability_zone(ic_rec,\n-                svc_mon->dst_az_name);\n-            icsbrec_service_monitor_set_source_availability_zone(ic_rec,\n-                svc_mon->src_az_name);\n-        }\n-\n-        /* Always update options because they change from NB. */\n-        icsbrec_service_monitor_set_options(ic_rec, &db_rec->options);\n-        refresh_ic_record_cache(&sync_data.local_ic_svcs_map, ic_rec);\n-    }\n-\n-    HMAP_FOR_EACH_SAFE (svc_mon, hmap_node, &sync_data.synced_svcs_map) {\n-        const struct icsbrec_service_monitor *db_rec =\n-            svc_mon->db_rec.ic_rec;\n-        const struct sbrec_service_monitor *sb_rec =\n-            lookup_sb_svc_rec(ic, svc_mon);\n-\n-        if (sb_rec) {\n-            icsbrec_service_monitor_set_status(svc_mon->db_rec.ic_rec,\n-                                               sb_rec->status);\n-        } else {\n-            sb_rec = sbrec_service_monitor_insert(ctx->ovnsb_idl_txn);\n-            sbrec_service_monitor_set_type(sb_rec, db_rec->type);\n-            sbrec_service_monitor_set_ip(sb_rec, db_rec->ip);\n-            sbrec_service_monitor_set_port(sb_rec, db_rec->port);\n-            sbrec_service_monitor_set_src_ip(sb_rec, db_rec->src_ip);\n-            /* Set svc_monitor_mac from local SBDB. */\n-            sbrec_service_monitor_set_src_mac(sb_rec,\n-                sync_data.prpg_svc_monitor_mac);\n-            sbrec_service_monitor_set_protocol(sb_rec,\n-                db_rec->protocol);\n-            sbrec_service_monitor_set_logical_port(sb_rec,\n-                db_rec->logical_port);\n-            sbrec_service_monitor_set_remote(sb_rec, false);\n-            sbrec_service_monitor_set_ic_learned(sb_rec, true);\n-        }\n-\n-        /* Always update options since they may change via\n-         * NB configuration. Also update chassis_name if\n-         * the port has been reassigned to a different chassis.\n-         */\n-        if (svc_mon->chassis_name) {\n-            sbrec_service_monitor_set_chassis_name(sb_rec,\n-                svc_mon->chassis_name);\n-        }\n-        sbrec_service_monitor_set_options(sb_rec, &db_rec->options);\n-        refresh_sb_record_cache(&sync_data.local_sb_svcs_map, sb_rec);\n-    }\n-\n-    /* Delete local created records that are no longer used. */\n-    remove_unused_ic_records(&sync_data.local_ic_svcs_map);\n-    remove_unused_sb_records(&sync_data.local_sb_svcs_map);\n-\n-    destroy_service_monitor_data(&sync_data);\n-}\n-\n /*\n  * This function implements a sequence number protocol that can be used by\n  * the INB end user to verify that ISB is synced with all the changes that\n@@ -791,11 +359,11 @@ inc_proc_graph_dump(const char *end_node)\n }\n \n void\n-ovn_db_run(struct ic_input *input_data,\n+ovn_db_run(struct ic_input *input_data OVS_UNUSED,\n            struct ic_data *ic_data OVS_UNUSED,\n-           struct engine_context *eng_ctx)\n+           struct engine_context *eng_ctx OVS_UNUSED)\n {\n-    sync_service_monitor(eng_ctx, input_data);\n+\n }\n \f\n static void\n@@ -1204,6 +772,7 @@ main(int argc, char *argv[])\n     stopwatch_create(OVN_IC_GATEWAY_RUN_STOPWATCH_NAME, SW_MS);\n     stopwatch_create(OVN_IC_TRANSIT_ROUTER_RUN_STOPWATCH_NAME, SW_MS);\n     stopwatch_create(OVN_IC_TRANSIT_SWITCH_RUN_STOPWATCH_NAME, SW_MS);\n+    stopwatch_create(OVN_IC_SERVICE_MONITOR_RUN_STOPWATCH_NAME, SW_MS);\n \n     /* Initialize incremental processing engine for ovn-northd */\n     inc_proc_ic_init(&ovnnb_idl_loop, &ovnsb_idl_loop,\ndiff --git a/ic/ovn-ic.h b/ic/ovn-ic.h\nindex 7e057cc1b..f60e218f6 100644\n--- a/ic/ovn-ic.h\n+++ b/ic/ovn-ic.h\n@@ -46,13 +46,6 @@ struct ic_input {\n     struct ovsdb_idl_index *nbrec_port_by_name;\n     struct ovsdb_idl_index *sbrec_chassis_by_name;\n     struct ovsdb_idl_index *sbrec_port_binding_by_name;\n-    struct ovsdb_idl_index *sbrec_service_monitor_by_remote_type;\n-    struct ovsdb_idl_index *sbrec_service_monitor_by_ic_learned;\n-    struct ovsdb_idl_index *sbrec_service_monitor_by_remote_type_logical_port;\n-    struct ovsdb_idl_index *icnbrec_transit_switch_by_name;\n-    struct ovsdb_idl_index *icsbrec_service_monitor_by_source_az;\n-    struct ovsdb_idl_index *icsbrec_service_monitor_by_target_az;\n-    struct ovsdb_idl_index *icsbrec_service_monitor_by_target_az_logical_port;\n };\n \n struct ic_data {\ndiff --git a/lib/stopwatch-names.h b/lib/stopwatch-names.h\nindex c9fe2e639..ec4edf83c 100644\n--- a/lib/stopwatch-names.h\n+++ b/lib/stopwatch-names.h\n@@ -48,5 +48,6 @@\n #define OVN_IC_TRANSIT_ROUTER_RUN_STOPWATCH_NAME \"transit_router_run\"\n #define OVN_IC_PORT_BINDING_RUN_STOPWATCH_NAME \"port_binding_run\"\n #define OVN_IC_ROUTE_RUN_STOPWATCH_NAME \"route_run\"\n+#define OVN_IC_SERVICE_MONITOR_RUN_STOPWATCH_NAME \"service_monitor_run\"\n \n #endif\n",
    "prefixes": [
        "ovs-dev",
        "v0",
        "8/9"
    ]
}