get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2186656,
    "url": "http://patchwork.ozlabs.org/api/1.0/patches/2186656/?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-7-guilherme.paulo@luizalabs.com>",
    "date": "2026-01-20T11:49:45",
    "name": "[ovs-dev,v0,6/9] ovn-ic: Add a new engine-node 'transit-router'.",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "ad608dac1f069f832b6c19c6ae1b4e4c26522b63",
    "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-7-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/2186656/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=J+jgjoKo;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=140.211.166.138; helo=smtp1.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)",
            "smtp1.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=J+jgjoKo",
            "smtp3.osuosl.org; dmarc=pass (p=quarantine dis=none)\n header.from=luizalabs.com",
            "smtp3.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=J+jgjoKo"
        ],
        "Received": [
            "from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138])\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 4dwQdJ254wz1xsW\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 20 Jan 2026 22:51:00 +1100 (AEDT)",
            "from localhost (localhost [127.0.0.1])\n\tby smtp1.osuosl.org (Postfix) with ESMTP id C8FAA859AC;\n\tTue, 20 Jan 2026 11:50:58 +0000 (UTC)",
            "from smtp1.osuosl.org ([127.0.0.1])\n by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id oA2tnvIlh6Y6; Tue, 20 Jan 2026 11:50:56 +0000 (UTC)",
            "from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])\n\tby smtp1.osuosl.org (Postfix) with ESMTPS id 1B4F5859AA;\n\tTue, 20 Jan 2026 11:50:56 +0000 (UTC)",
            "from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id F23A7C02A6;\n\tTue, 20 Jan 2026 11:50:55 +0000 (UTC)",
            "from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 39378C02A5\n for <dev@openvswitch.org>; Tue, 20 Jan 2026 11:50:54 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n by smtp3.osuosl.org (Postfix) with ESMTP id 389AD6FD24\n for <dev@openvswitch.org>; Tue, 20 Jan 2026 11:50:33 +0000 (UTC)",
            "from smtp3.osuosl.org ([127.0.0.1])\n by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id 2o67KW0MkrDi for <dev@openvswitch.org>;\n Tue, 20 Jan 2026 11:50:31 +0000 (UTC)",
            "from mail-dy1-x132c.google.com (mail-dy1-x132c.google.com\n [IPv6:2607:f8b0:4864:20::132c])\n by smtp3.osuosl.org (Postfix) with ESMTPS id B222C6FD25\n for <dev@openvswitch.org>; Tue, 20 Jan 2026 11:50:29 +0000 (UTC)",
            "by mail-dy1-x132c.google.com with SMTP id\n 5a478bee46e88-2b6f5a9cecaso1368760eec.0\n for <dev@openvswitch.org>; Tue, 20 Jan 2026 03:50:29 -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.26\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 20 Jan 2026 03:50:27 -0800 (PST)"
        ],
        "X-Virus-Scanned": [
            "amavis at osuosl.org",
            "amavis at osuosl.org"
        ],
        "X-Comment": "SPF check N/A for local connections - client-ip=140.211.9.56;\n helo=lists.linuxfoundation.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN> ",
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 smtp1.osuosl.org 1B4F5859AA",
            "OpenDKIM Filter v2.11.0 smtp3.osuosl.org B222C6FD25"
        ],
        "Received-SPF": "Pass (mailfrom) identity=mailfrom;\n client-ip=2607:f8b0:4864:20::132c; helo=mail-dy1-x132c.google.com;\n envelope-from=guilherme.paulo@luizalabs.com; receiver=<UNKNOWN>",
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 smtp3.osuosl.org B222C6FD25",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=luizalabs.com; s=google; t=1768909828; x=1769514628; 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=EepOtQWYTmLcx7W9JOc/sU1bilVX8mKxwp+nkhaK7c0=;\n b=J+jgjoKoonyBKk28P/mXAMnHejqz652WkAoffwddSn7PAXDzNgxTqWVC4T9mnzg8kA\n fiaNUU8z6Q1lpXMLQovOn4OfkUKyllrax3M0pNHP7+GJazHTX8KJBszK1scrY9xICtIB\n zZkrdImO7Tf4Sv2AGeaOkqszC6+sJ7hTF/S8U=",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1768909828; x=1769514628;\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=EepOtQWYTmLcx7W9JOc/sU1bilVX8mKxwp+nkhaK7c0=;\n b=uNOqPCJ8fFEcKDPMgOUaCYGKRsW3xmUorQYKal83DulUTMaQgDyWCr849CCYA9LCGd\n izqwXgqg2C0hk7G1Qi4EkL5/H3I+O52nTF01bkIKJazVK1V6oWjAi5D2whJWbKOa1fda\n 0r7anXWsl5R6nIcnQdEkpEsk+xJJWyX3OEn6EeKsFWWPQK9tWat0xiorKTX1Aib3eNcm\n gR1fl0uVj9+yEh8ssJsqIyD9tHMevFVJTUDKdl+yluq2lic1OhgrbZh6vyE/ZcWiiJVl\n Kdp+MLKFoG/xyda7WaTu6ysjWfSZ4WXolp8mXYTxtRCgTSYpJDBOR3i/pQeLBHTj1Ubw\n fKuw==",
        "X-Gm-Message-State": "AOJu0Yz6D6IRLemJ1Khlxos5NEggQXyFKwWsTy9x/Iw90mBhhpcMbMTx\n 6tAF5lI1vQRDXJcQspI5pnG5EmbVZ938R0cO4j2x3B00q9SN+G6vLdI9hzKBpQAaBmYCpkOVFRG\n UTtCdxNLMzaEpHciClNKnb70HpPPYnysaiYacI5b0uvagb5UbgoFBtj4LhgZO",
        "X-Gm-Gg": "AZuq6aJ7p1OMOdLj0jvDt/J5kt86UUf0Umw15Ubw5QSzCpzPurjsUp/KPNNOBs28E8E\n dnQB5gxu5uLr0JcnU8RxcYTTP7KazoHFNGFOCnUKhjQbZzFz5dcYGXJonbquSVi8qc13S7Gjrjg\n Iqo7QeSHd/jwcFhRJckyuVRFz0eZqehlnoES1USbax+VZG5LisJdrndb8kCP+UvsF+h4j2Ohs3l\n FMDt0/aJ0VpJg44gsLVYjP5Fyz0uZgItIaDRegl8cBxK7Lutq1D9eaF7b442W4WCzN7HKiiJykW\n UKZYLAONyWCXkqx49vNKIF7tCOFJ63XR7Wa6FPx/o2kEBebVgoLYI4iUo6Zosbf0bzOETqUvHF5\n j6zdMlXRXUuHerNZy9zFNVobbgpURMQGY1+gJXN3vP6rm74cLk46GdNEEkYQ5vrGWJ6xGVNyGkk\n +SvC3SiWKEpVTzIrlGHp/ccBDYeaQ=",
        "X-Received": "by 2002:a05:7300:3206:b0:2ae:533d:19ee with SMTP id\n 5a478bee46e88-2b6fd7b5e37mr1279839eec.21.1768909827848;\n Tue, 20 Jan 2026 03:50:27 -0800 (PST)",
        "To": "dev@openvswitch.org",
        "Date": "Tue, 20 Jan 2026 08:49:45 -0300",
        "Message-Id": "<20260120114948.2289909-7-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 6/9] ovn-ic: Add a new engine-node\n 'transit-router'.",
        "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 transit-router related data for ovn-ic\ndaemon which was earlier maintained by the ic engine node invoked the\ntr_run() function. The inputs to this engine node are:\n   en_enum_datapaths;\n   en_icsb_datapath_binding;\n   en_nb_logical_router;\n   en_icnb_transit_router;\n   en_icnb_transit_router_port;\n\nIn order to achieve this, we refactor in the following way:\n* Introduce tr_init() which initializes this data.\n* Introduce tr_destroy() which clears this data for a new iteration.\n* Introduce tr_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            |   2 -\n ic/en-tr.c            | 181 ++++++++++++++++++++++++++++++++++++++++++\n ic/en-tr.h            |  23 ++++++\n ic/inc-proc-ic.c      |  11 ++-\n ic/ovn-ic.c           |  87 +-------------------\n ic/ovn-ic.h           |   3 +-\n lib/stopwatch-names.h |   1 +\n 8 files changed, 220 insertions(+), 90 deletions(-)\n create mode 100644 ic/en-tr.c\n create mode 100644 ic/en-tr.h",
    "diff": "diff --git a/ic/automake.mk b/ic/automake.mk\nindex 1fca1eb38..180fcb252 100644\n--- a/ic/automake.mk\n+++ b/ic/automake.mk\n@@ -8,6 +8,8 @@ ic_ovn_ic_SOURCES = ic/ovn-ic.c \\\n \tic/en-gateway.h \\\n \tic/en-enum-datapaths.c \\\n \tic/en-enum-datapaths.h \\\n+\tic/en-tr.c \\\n+\tic/en-tr.h \\\n \tic/en-port-binding.c \\\n \tic/en-port-binding.h \\\n \tic/en-route.c \\\ndiff --git a/ic/en-ic.c b/ic/en-ic.c\nindex af240c20a..e9450a290 100644\n--- a/ic/en-ic.c\n+++ b/ic/en-ic.c\n@@ -56,8 +56,6 @@ ic_get_input_data(struct engine_node *node,\n         EN_OVSDB_GET(engine_get_input(\"ICNB_ic_nb_global\", node));\n     input_data->icnbrec_transit_switch_table =\n         EN_OVSDB_GET(engine_get_input(\"ICNB_transit_switch\", node));\n-    input_data->icnbrec_transit_router_table =\n-        EN_OVSDB_GET(engine_get_input(\"ICNB_transit_router\", 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 =\ndiff --git a/ic/en-tr.c b/ic/en-tr.c\nnew file mode 100644\nindex 000000000..642d11b85\n--- /dev/null\n+++ b/ic/en-tr.c\n@@ -0,0 +1,181 @@\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-tr.h\"\n+#include \"en-enum-datapaths.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-ic-nb-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_transit_router);\n+COVERAGE_DEFINE(tr_run);\n+\n+static void\n+tr_run(const struct engine_context *eng_ctx,\n+       struct ed_type_transit_router *tr_data,\n+       struct ed_type_enum_datapaths *dp_node_data,\n+       const struct nbrec_logical_router_table *nbrec_lr_table,\n+       const struct icnbrec_transit_router_table *icnbrec_tr_table);\n+static void tr_init(struct ed_type_transit_router *data);\n+static void tr_destroy(struct ed_type_transit_router *data);\n+\n+enum engine_node_state\n+en_tr_run(struct engine_node *node, void *data)\n+{\n+    const struct engine_context *eng_ctx = engine_get_context();\n+    struct ed_type_transit_router *tr_data = data;\n+\n+    struct ed_type_enum_datapaths *dp_node_data =\n+        engine_get_input_data(\"enum_datapaths\", node);\n+\n+    const struct nbrec_logical_router_table *nbrec_lr_table =\n+        EN_OVSDB_GET(engine_get_input(\"NB_logical_router\", node));\n+    const struct icnbrec_transit_router_table *icnbrec_tr_table =\n+        EN_OVSDB_GET(engine_get_input(\"ICNB_transit_router\", node));\n+\n+    COVERAGE_INC(tr_run);\n+    stopwatch_start(OVN_IC_TRANSIT_ROUTER_RUN_STOPWATCH_NAME, time_usec());\n+    tr_run(eng_ctx, tr_data, dp_node_data, nbrec_lr_table, icnbrec_tr_table);\n+    stopwatch_stop(OVN_IC_TRANSIT_ROUTER_RUN_STOPWATCH_NAME, time_usec());\n+\n+    return EN_UPDATED;\n+}\n+\n+void *\n+en_tr_init(struct engine_node *node OVS_UNUSED,\n+           struct engine_arg *arg OVS_UNUSED)\n+{\n+    struct ed_type_transit_router *data = xzalloc(sizeof *data);\n+    tr_init(data);\n+    return data;\n+}\n+\n+void\n+en_tr_cleanup(void *data)\n+{\n+    tr_destroy(data);\n+}\n+\n+static void\n+tr_init(struct ed_type_transit_router *data)\n+{\n+    shash_init(&data->isb_tr_dps);\n+    hmap_init(&data->dp_tnlids);\n+}\n+\n+static void\n+tr_destroy(struct ed_type_transit_router *data)\n+{\n+    shash_destroy(&data->isb_tr_dps);\n+    ovn_destroy_tnlids(&data->dp_tnlids);\n+}\n+\n+static void\n+tr_run(const struct engine_context *eng_ctx,\n+       struct ed_type_transit_router *tr_data OVS_UNUSED,\n+       struct ed_type_enum_datapaths *dp_node_data,\n+       const struct nbrec_logical_router_table *nbrec_lr_table,\n+       const struct icnbrec_transit_router_table *icnbrec_tr_table)\n+{\n+    const struct nbrec_logical_router *lr;\n+    if (eng_ctx->ovnnb_idl_txn) {\n+        struct shash nb_tres = SHASH_INITIALIZER(&nb_tres);\n+        NBREC_LOGICAL_ROUTER_TABLE_FOR_EACH (lr, nbrec_lr_table) {\n+            const char *tr_name = smap_get(&lr->options, \"interconn-tr\");\n+            if (tr_name) {\n+                shash_add(&nb_tres, tr_name, lr);\n+            }\n+        }\n+\n+        const struct icnbrec_transit_router *tr;\n+        ICNBREC_TRANSIT_ROUTER_TABLE_FOR_EACH (tr, icnbrec_tr_table) {\n+            lr = shash_find_and_delete(&nb_tres, tr->name);\n+            if (!lr) {\n+                lr = nbrec_logical_router_insert(eng_ctx->ovnnb_idl_txn);\n+                nbrec_logical_router_set_name(lr, tr->name);\n+                nbrec_logical_router_update_options_setkey(\n+                    lr, \"interconn-tr\", tr->name);\n+            }\n+            char *uuid_str = uuid_to_string(&tr->header_.uuid);\n+            struct icsbrec_datapath_binding *isb_dp = shash_find_data(\n+                &dp_node_data->isb_tr_dps, uuid_str);\n+            free(uuid_str);\n+\n+            if (isb_dp) {\n+                char *tnl_key_str = xasprintf(\"%\"PRId64, isb_dp->tunnel_key);\n+                nbrec_logical_router_update_options_setkey(\n+                    lr, \"requested-tnl-key\", tnl_key_str);\n+                free(tnl_key_str);\n+            }\n+        }\n+\n+        struct shash_node *node;\n+        SHASH_FOR_EACH (node, &nb_tres) {\n+            nbrec_logical_router_delete(node->data);\n+        }\n+        shash_destroy(&nb_tres);\n+    }\n+\n+    /* Sync TR between INB and ISB.  This is performed after syncing with AZ\n+     * SB, to avoid uncommitted ISB datapath tunnel key to be synced back to\n+     * AZ. */\n+    if (eng_ctx->ovnisb_idl_txn) {\n+        /* Create ISB Datapath_Binding */\n+        const struct icnbrec_transit_router *tr;\n+        ICNBREC_TRANSIT_ROUTER_TABLE_FOR_EACH (tr, icnbrec_tr_table) {\n+            char *uuid_str = uuid_to_string(&tr->header_.uuid);\n+            struct icsbrec_datapath_binding *isb_dp =\n+                shash_find_and_delete(&dp_node_data->isb_tr_dps, uuid_str);\n+            free(uuid_str);\n+\n+            if (!isb_dp) {\n+                int dp_key = allocate_dp_key(&dp_node_data->dp_tnlids, false,\n+                                             \"transit router datapath\");\n+                if (!dp_key) {\n+                    continue;\n+                }\n+\n+                isb_dp = icsbrec_datapath_binding_insert(\n+                    eng_ctx->ovnisb_idl_txn);\n+                icsbrec_datapath_binding_set_tunnel_key(isb_dp, dp_key);\n+                icsbrec_datapath_binding_set_nb_ic_uuid(isb_dp,\n+                                                        &tr->header_.uuid, 1);\n+                icsbrec_datapath_binding_set_type(isb_dp, \"transit-router\");\n+            }\n+        }\n+\n+        struct shash_node *node;\n+        SHASH_FOR_EACH (node, &dp_node_data->isb_tr_dps) {\n+            icsbrec_datapath_binding_delete(node->data);\n+        }\n+    }\n+}\ndiff --git a/ic/en-tr.h b/ic/en-tr.h\nnew file mode 100644\nindex 000000000..674e1c07d\n--- /dev/null\n+++ b/ic/en-tr.h\n@@ -0,0 +1,23 @@\n+#ifndef EN_IC_TR_RUN_H\n+#define EN_IC_TR_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+/* OVN includes. */\n+#include \"lib/inc-proc-eng.h\"\n+\n+struct ed_type_transit_router {\n+    struct hmap dp_tnlids;\n+    struct shash isb_tr_dps;\n+};\n+\n+void *en_tr_init(struct engine_node *, struct engine_arg *);\n+enum engine_node_state en_tr_run(struct engine_node *, void *data);\n+void en_tr_cleanup(void *data);\n+\n+#endif\ndiff --git a/ic/inc-proc-ic.c b/ic/inc-proc-ic.c\nindex dc625d759..6ac60c677 100644\n--- a/ic/inc-proc-ic.c\n+++ b/ic/inc-proc-ic.c\n@@ -29,6 +29,7 @@\n #include \"en-ic.h\"\n #include \"en-gateway.h\"\n #include \"en-enum-datapaths.h\"\n+#include \"en-tr.h\"\n #include \"en-port-binding.h\"\n #include \"en-route.h\"\n #include \"unixctl.h\"\n@@ -164,6 +165,7 @@ VLOG_DEFINE_THIS_MODULE(inc_proc_ic);\n static ENGINE_NODE(ic, SB_WRITE);\n static ENGINE_NODE(gateway, SB_WRITE);\n static ENGINE_NODE(enum_datapaths);\n+static ENGINE_NODE(tr);\n static ENGINE_NODE(port_binding, SB_WRITE);\n static ENGINE_NODE(route);\n \n@@ -180,6 +182,12 @@ void inc_proc_ic_init(struct ovsdb_idl_loop *nb,\n     engine_add_input(&en_enum_datapaths, &en_icnb_transit_switch, NULL);\n     engine_add_input(&en_enum_datapaths, &en_icsb_datapath_binding, NULL);\n \n+    engine_add_input(&en_tr, &en_enum_datapaths, NULL);\n+    engine_add_input(&en_tr, &en_icsb_datapath_binding, NULL);\n+    engine_add_input(&en_tr, &en_nb_logical_router, NULL);\n+    engine_add_input(&en_tr, &en_icnb_transit_router, NULL);\n+    engine_add_input(&en_tr, &en_icnb_transit_router_port, NULL);\n+\n     engine_add_input(&en_port_binding, &en_icnb_transit_switch, NULL);\n     engine_add_input(&en_port_binding, &en_icnb_transit_router, NULL);\n     engine_add_input(&en_port_binding, &en_icsb_port_binding, NULL);\n@@ -198,6 +206,7 @@ void inc_proc_ic_init(struct ovsdb_idl_loop *nb,\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_tr, NULL);\n     engine_add_input(&en_ic, &en_port_binding, NULL);\n     engine_add_input(&en_ic, &en_route, NULL);\n \n@@ -217,8 +226,6 @@ void inc_proc_ic_init(struct ovsdb_idl_loop *nb,\n \n     engine_add_input(&en_ic, &en_icnb_ic_nb_global, NULL);\n     engine_add_input(&en_ic, &en_icnb_transit_switch, NULL);\n-    engine_add_input(&en_ic, &en_icnb_transit_router, NULL);\n-    engine_add_input(&en_ic, &en_icnb_transit_router_port, NULL);\n \n     engine_add_input(&en_ic, &en_icsb_port_binding, NULL);\n     engine_add_input(&en_ic, &en_icsb_ic_sb_global, NULL);\ndiff --git a/ic/ovn-ic.c b/ic/ovn-ic.c\nindex ffd814846..08241337d 100644\n--- a/ic/ovn-ic.c\n+++ b/ic/ovn-ic.c\n@@ -159,7 +159,7 @@ az_run(struct ovsdb_idl *ovnnb_idl,\n     return NULL;\n }\n \n-static uint32_t\n+uint32_t\n allocate_dp_key(struct hmap *dp_tnlids, bool vxlan_mode, const char *name)\n {\n     uint32_t hint = vxlan_mode ? OVN_MIN_DP_VXLAN_KEY_GLOBAL\n@@ -346,89 +346,6 @@ ts_run(struct engine_context *ctx,\n     }\n }\n \n-static void\n-tr_run(struct engine_context *ctx,\n-       struct ic_input *ic,\n-       struct hmap *dp_tnlids,\n-       struct shash *isb_tr_dps)\n-{\n-    const struct nbrec_logical_router *lr;\n-\n-    if (ctx->ovnnb_idl_txn) {\n-        struct shash nb_tres = SHASH_INITIALIZER(&nb_tres);\n-        NBREC_LOGICAL_ROUTER_TABLE_FOR_EACH (lr,\n-                                             ic->nbrec_logical_router_table) {\n-            const char *tr_name = smap_get(&lr->options, \"interconn-tr\");\n-            if (tr_name) {\n-                shash_add(&nb_tres, tr_name, lr);\n-            }\n-        }\n-\n-        const struct icnbrec_transit_router *tr;\n-        ICNBREC_TRANSIT_ROUTER_TABLE_FOR_EACH (tr,\n-            ic->icnbrec_transit_router_table) {\n-            lr = shash_find_and_delete(&nb_tres, tr->name);\n-            if (!lr) {\n-                lr = nbrec_logical_router_insert(ctx->ovnnb_idl_txn);\n-                nbrec_logical_router_set_name(lr, tr->name);\n-                nbrec_logical_router_update_options_setkey(\n-                    lr, \"interconn-tr\", tr->name);\n-            }\n-            char *uuid_str = uuid_to_string(&tr->header_.uuid);\n-            struct icsbrec_datapath_binding *isb_dp = shash_find_data(\n-                isb_tr_dps, uuid_str);\n-            free(uuid_str);\n-\n-            if (isb_dp) {\n-                char *tnl_key_str = xasprintf(\"%\"PRId64, isb_dp->tunnel_key);\n-                nbrec_logical_router_update_options_setkey(\n-                    lr, \"requested-tnl-key\", tnl_key_str);\n-                free(tnl_key_str);\n-            }\n-        }\n-\n-        struct shash_node *node;\n-        SHASH_FOR_EACH (node, &nb_tres) {\n-            nbrec_logical_router_delete(node->data);\n-        }\n-        shash_destroy(&nb_tres);\n-    }\n-\n-    /* Sync TR between INB and ISB.  This is performed after syncing with AZ\n-     * SB, to avoid uncommitted ISB datapath tunnel key to be synced back to\n-     * AZ. */\n-    if (ctx->ovnisb_idl_txn) {\n-        /* Create ISB Datapath_Binding */\n-        const struct icnbrec_transit_router *tr;\n-        ICNBREC_TRANSIT_ROUTER_TABLE_FOR_EACH (tr,\n-            ic->icnbrec_transit_router_table) {\n-            char *uuid_str = uuid_to_string(&tr->header_.uuid);\n-            struct icsbrec_datapath_binding *isb_dp =\n-                shash_find_and_delete(isb_tr_dps, uuid_str);\n-            free(uuid_str);\n-\n-            if (!isb_dp) {\n-                int dp_key = allocate_dp_key(dp_tnlids, false,\n-                                             \"transit router datapath\");\n-                if (!dp_key) {\n-                    continue;\n-                }\n-\n-                isb_dp = icsbrec_datapath_binding_insert(ctx->ovnisb_idl_txn);\n-                icsbrec_datapath_binding_set_tunnel_key(isb_dp, dp_key);\n-                icsbrec_datapath_binding_set_nb_ic_uuid(isb_dp,\n-                                                        &tr->header_.uuid, 1);\n-                icsbrec_datapath_binding_set_type(isb_dp, \"transit-router\");\n-            }\n-        }\n-\n-        struct shash_node *node;\n-        SHASH_FOR_EACH (node, isb_tr_dps) {\n-            icsbrec_datapath_binding_delete(node->data);\n-        }\n-    }\n-}\n-\n const struct nbrec_logical_router_port *\n get_lrp_by_lrp_name(struct ovsdb_idl_index *nbrec_lrp_by_name,\n                     const char *lrp_name)\n@@ -1046,7 +963,6 @@ ovn_db_run(struct ic_input *input_data,\n            struct engine_context *eng_ctx)\n {\n     ts_run(eng_ctx, input_data, ic_data->dp_tnlids, ic_data->isb_ts_dps);\n-    tr_run(eng_ctx, input_data, ic_data->dp_tnlids, ic_data->isb_tr_dps);\n     sync_service_monitor(eng_ctx, input_data);\n }\n \f\n@@ -1454,6 +1370,7 @@ main(int argc, char *argv[])\n     stopwatch_create(OVN_IC_PORT_BINDING_RUN_STOPWATCH_NAME, SW_MS);\n     stopwatch_create(OVN_IC_ROUTE_RUN_STOPWATCH_NAME, SW_MS);\n     stopwatch_create(OVN_IC_GATEWAY_RUN_STOPWATCH_NAME, SW_MS);\n+    stopwatch_create(OVN_IC_TRANSIT_ROUTER_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 e6918c8d2..225dc73f5 100644\n--- a/ic/ovn-ic.h\n+++ b/ic/ovn-ic.h\n@@ -30,7 +30,6 @@ struct ic_input {\n     /* InterconnectNorthbound table references */\n     const struct icnbrec_transit_switch_table *icnbrec_transit_switch_table;\n     const struct icnbrec_ic_nb_global_table *icnbrec_ic_nb_global_table;\n-    const struct icnbrec_transit_router_table *icnbrec_transit_router_table;\n \n     /* InterconnectSouthbound table references */\n     const struct icsbrec_encap_table *icsbrec_encap_table;\n@@ -73,6 +72,8 @@ struct icsbrec_port_binding;\n enum ic_datapath_type { IC_SWITCH, IC_ROUTER, IC_DATAPATH_MAX };\n enum ic_port_binding_type { IC_SWITCH_PORT, IC_ROUTER_PORT, IC_PORT_MAX };\n \n+uint32_t\n+allocate_dp_key(struct hmap *dp_tnlids, bool vxlan_mode, const char *name);\n const struct nbrec_logical_router_port *\n get_lrp_by_lrp_name(struct ovsdb_idl_index *nbrec_lrp_by_name,\n                     const char *lrp_name);\ndiff --git a/lib/stopwatch-names.h b/lib/stopwatch-names.h\nindex cd75376d9..f6e1bc023 100644\n--- a/lib/stopwatch-names.h\n+++ b/lib/stopwatch-names.h\n@@ -44,6 +44,7 @@\n #define IC_OVN_DB_RUN_STOPWATCH_NAME \"ovn_db_run\"\n #define OVN_IC_GATEWAY_RUN_STOPWATCH_NAME \"gateway_run\"\n #define OVN_IC_ENUM_DATAPATHS_RUN_STOPWATCH_NAME \"enum_datapaths_run\"\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 \n",
    "prefixes": [
        "ovs-dev",
        "v0",
        "6/9"
    ]
}