get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2227905,
    "url": "http://patchwork.ozlabs.org/api/patches/2227905/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/ovn/patch/20260424132342.3486635-4-amusil@redhat.com/",
    "project": {
        "id": 68,
        "url": "http://patchwork.ozlabs.org/api/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": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260424132342.3486635-4-amusil@redhat.com>",
    "list_archive_url": null,
    "date": "2026-04-24T13:23:38",
    "name": "[ovs-dev,3/7] controller: Add nexthop exchange node.",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "c3e6707b12731f411e5228cfbe1d4614f266c6fb",
    "submitter": {
        "id": 83634,
        "url": "http://patchwork.ozlabs.org/api/people/83634/?format=api",
        "name": "Ales Musil",
        "email": "amusil@redhat.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/ovn/patch/20260424132342.3486635-4-amusil@redhat.com/mbox/",
    "series": [
        {
            "id": 501360,
            "url": "http://patchwork.ozlabs.org/api/series/501360/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/ovn/list/?series=501360",
            "date": "2026-04-24T13:23:35",
            "name": "This series adds support for Equal-Cost Multi-Path (ECMP) FDB entries",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/501360/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2227905/comments/",
    "check": "warning",
    "checks": "http://patchwork.ozlabs.org/api/patches/2227905/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@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=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=Mm4oUr+x;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)",
            "smtp3.osuosl.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key)\n header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=Mm4oUr+x",
            "smtp4.osuosl.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com",
            "smtp4.osuosl.org;\n dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com\n header.a=rsa-sha256 header.s=mimecast20190719 header.b=Mm4oUr+x"
        ],
        "Received": [
            "from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136])\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 4g2DFd0Y4Zz1yD5\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 24 Apr 2026 23:24:21 +1000 (AEST)",
            "from localhost (localhost [127.0.0.1])\n\tby smtp3.osuosl.org (Postfix) with ESMTP id AB00961B4A;\n\tFri, 24 Apr 2026 13:24:19 +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 Y7cNXa29tGuB; Fri, 24 Apr 2026 13:24:18 +0000 (UTC)",
            "from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])\n\tby smtp3.osuosl.org (Postfix) with ESMTPS id 587FE61B32;\n\tFri, 24 Apr 2026 13:24:18 +0000 (UTC)",
            "from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id 1D55EC04FA;\n\tFri, 24 Apr 2026 13:24:18 +0000 (UTC)",
            "from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 01396C058F\n for <dev@openvswitch.org>; Fri, 24 Apr 2026 13:24:17 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n by smtp4.osuosl.org (Postfix) with ESMTP id 53452427EE\n for <dev@openvswitch.org>; Fri, 24 Apr 2026 13:24:00 +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 ISNhFtI_Gqx6 for <dev@openvswitch.org>;\n Fri, 24 Apr 2026 13:23:58 +0000 (UTC)",
            "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.129.124])\n by smtp4.osuosl.org (Postfix) with ESMTPS id 59AA0427F1\n for <dev@openvswitch.org>; Fri, 24 Apr 2026 13:23:58 +0000 (UTC)",
            "from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-677--_DBtKjVO0mwntoXqoC1BA-1; Fri,\n 24 Apr 2026 09:23:50 -0400",
            "from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 10B6A195608E\n for <dev@openvswitch.org>; Fri, 24 Apr 2026 13:23:50 +0000 (UTC)",
            "from amusil.redhat.com (unknown [10.44.32.61])\n by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id F23B9180047F; Fri, 24 Apr 2026 13:23:48 +0000 (UTC)"
        ],
        "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 smtp3.osuosl.org 587FE61B32",
            "OpenDKIM Filter v2.11.0 smtp4.osuosl.org 59AA0427F1"
        ],
        "Received-SPF": "Pass (mailfrom) identity=mailfrom; client-ip=170.10.129.124;\n helo=us-smtp-delivery-124.mimecast.com; envelope-from=amusil@redhat.com;\n receiver=<UNKNOWN>",
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 smtp4.osuosl.org 59AA0427F1",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1777037037;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=ekEAf1tNhMRfRWTshFIRP62P/++nP+/FSJ1BL4CEeb0=;\n b=Mm4oUr+x6xha7Fff2sisqmCmHw3a1Mv8m6KtYHNRS/AvCBUOW6GO73W0t70l3EZbUh1va3\n o+N1K08bQTh/b/gcT4RfMS2oE9b2uX4cobH2wD1AnvuNflWPHwhhM144Eu5HxjWoa57XcJ\n A3Y1qwDFvCsFOYKCMB4FCQPxneRt0eg=",
        "X-MC-Unique": "-_DBtKjVO0mwntoXqoC1BA-1",
        "X-Mimecast-MFC-AGG-ID": "-_DBtKjVO0mwntoXqoC1BA_1777037030",
        "To": "dev@openvswitch.org",
        "Date": "Fri, 24 Apr 2026 15:23:38 +0200",
        "Message-ID": "<20260424132342.3486635-4-amusil@redhat.com>",
        "In-Reply-To": "<20260424132342.3486635-1-amusil@redhat.com>",
        "References": "<20260424132342.3486635-1-amusil@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 3.4.1 on 10.30.177.93",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-MFC-PROC-ID": "htnJy1MWIU6n8A6a2CnaE9b7cxgIczoC0fI1c9cQP7A_1777037030",
        "X-Mimecast-Originator": "redhat.com",
        "Subject": "[ovs-dev] [PATCH ovn 3/7] controller: Add nexthop exchange node.",
        "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": "Ales Musil via dev <ovs-dev@openvswitch.org>",
        "Reply-To": "Ales Musil <amusil@redhat.com>",
        "Cc": "dceara@redhat.com",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "Errors-To": "ovs-dev-bounces@openvswitch.org",
        "Sender": "\"dev\" <ovs-dev-bounces@openvswitch.org>"
    },
    "content": "Add nexthop_exchange engine node that handles nexthop updates\nkeeping the internal nexthop mapping up to date. The noop handler\nfor evpn_fdb will be replaced by later commit.\n\nSigned-off-by: Ales Musil <amusil@redhat.com>\n---\n controller/nexthop-exchange-stub.c | 20 +++++++\n controller/nexthop-exchange.c      | 82 ++++++++++++++++++++++-----\n controller/nexthop-exchange.h      |  5 ++\n controller/ovn-controller.c        | 89 ++++++++++++++++++++++++++++++\n tests/ovn-inc-proc-graph-dump.at   |  3 +\n 5 files changed, 184 insertions(+), 15 deletions(-)",
    "diff": "diff --git a/controller/nexthop-exchange-stub.c b/controller/nexthop-exchange-stub.c\nindex 2742dc7e2..52c1bf028 100644\n--- a/controller/nexthop-exchange-stub.c\n+++ b/controller/nexthop-exchange-stub.c\n@@ -18,6 +18,7 @@\n #include \"lib/netlink.h\"\n #include \"openvswitch/hmap.h\"\n #include \"openvswitch/ofpbuf.h\"\n+#include \"vec.h\"\n \n #include \"nexthop-exchange.h\"\n \n@@ -34,9 +35,28 @@ nexthop_entry_format(struct ds *ds OVS_UNUSED,\n {\n }\n \n+struct nexthop_entry *\n+nexthop_entry_find(const struct hmap *nexthops OVS_UNUSED,\n+                   uint32_t id OVS_UNUSED)\n+{\n+    return NULL;\n+}\n+\n int\n nh_table_parse(struct ofpbuf *buf OVS_UNUSED,\n                struct nh_table_msg *change OVS_UNUSED)\n {\n     return 0;\n }\n+\n+bool\n+nexthops_handle_changes(struct hmap *nexthops OVS_UNUSED,\n+                        struct vector *msgs OVS_UNUSED)\n+{\n+    return false;\n+}\n+\n+void\n+nexthops_destroy(struct hmap *nexthops OVS_UNUSED)\n+{\n+}\ndiff --git a/controller/nexthop-exchange.c b/controller/nexthop-exchange.c\nindex a2ad643a6..8718b893f 100644\n--- a/controller/nexthop-exchange.c\n+++ b/controller/nexthop-exchange.c\n@@ -19,9 +19,11 @@\n \n #include \"lib/netlink.h\"\n #include \"lib/netlink-socket.h\"\n+#include \"hmapx.h\"\n #include \"openvswitch/ofpbuf.h\"\n #include \"openvswitch/vlog.h\"\n #include \"packets.h\"\n+#include \"vec.h\"\n \n #include \"nexthop-exchange.h\"\n \n@@ -109,6 +111,20 @@ nexthop_entry_format(struct ds *ds, const struct nexthop_entry *nhe)\n     }\n }\n \n+struct nexthop_entry *\n+nexthop_entry_find(const struct hmap *nexthops, uint32_t id)\n+{\n+    uint32_t hash = nexthop_entry_hash(id);\n+    struct nexthop_entry *nhe;\n+    HMAP_FOR_EACH_WITH_HASH (nhe, hmap_node, hash, nexthops) {\n+        if (nhe->id == id) {\n+            return nhe;\n+        }\n+    }\n+\n+    return NULL;\n+}\n+\n /* Parse Netlink message in buf, which is expected to contain a UAPI nhmsg\n  * header and associated nexthop attributes. This will allocate\n  * 'struct nexthop_entry' which needs to be freed by the caller.\n@@ -128,6 +144,56 @@ nh_table_parse(struct ofpbuf *buf, struct nh_table_msg *change)\n                             nlmsg, change);\n }\n \n+bool\n+nexthops_handle_changes(struct hmap *nexthops, struct vector *msgs)\n+{\n+    if (vector_is_empty(msgs)) {\n+        return false;\n+    }\n+\n+    struct hmapx updated_groups = HMAPX_INITIALIZER(&updated_groups);\n+\n+    struct nh_table_msg *msg;\n+    VECTOR_FOR_EACH_PTR (msgs, msg) {\n+        struct nexthop_entry *nhe = nexthop_entry_find(nexthops, msg->nhe->id);\n+        if (nhe) {\n+            hmap_remove(nexthops, &nhe->hmap_node);\n+            free(nhe);\n+        }\n+\n+        if (msg->nlmsg_type == RTM_NEWNEXTHOP) {\n+            hmap_insert(nexthops, &msg->nhe->hmap_node,\n+                        nexthop_entry_hash(msg->nhe->id));\n+\n+            if (msg->nhe->n_grps) {\n+                hmapx_add(&updated_groups, msg->nhe);\n+            }\n+\n+            /* The nexthop entry moved into the hmap, prevent double free. */\n+            msg->nhe = NULL;\n+        }\n+    }\n+\n+    struct hmapx_node *hmapx_node;\n+    HMAPX_FOR_EACH (hmapx_node, &updated_groups) {\n+        struct nexthop_entry *nhe = hmapx_node->data;\n+        nh_populate_grp_pointers(nhe, nexthops);\n+    }\n+\n+    hmapx_destroy(&updated_groups);\n+\n+    return true;\n+}\n+\n+void\n+nexthops_destroy(struct hmap *nexthops)\n+{\n+    struct nexthop_entry *entry;\n+    HMAP_FOR_EACH_POP (entry, hmap_node, nexthops) {\n+        free(entry);\n+    }\n+}\n+\n static int\n nh_table_parse__(struct ofpbuf *buf, size_t ofs, const struct nlmsghdr *nlmsg,\n                  struct nh_table_msg *change)\n@@ -214,25 +280,11 @@ nexthop_entry_hash(uint32_t id)\n     return hash_int(id, 0);\n }\n \n-static struct nexthop_entry *\n-nexthop_find(struct hmap *nexthops, uint32_t id)\n-{\n-    uint32_t hash = nexthop_entry_hash(id);\n-    struct nexthop_entry *nhe;\n-    HMAP_FOR_EACH_WITH_HASH (nhe, hmap_node, hash, nexthops) {\n-        if (nhe->id == id) {\n-            return nhe;\n-        }\n-    }\n-\n-    return NULL;\n-}\n-\n static void\n nh_populate_grp_pointers(struct nexthop_entry *nhe, struct hmap *nexthops)\n {\n     for (size_t i = 0; i < nhe->n_grps; i++) {\n         struct nexthop_grp_entry *grp = &nhe->grps[i];\n-        grp->gateway = nexthop_find(nexthops, grp->id);\n+        grp->gateway = nexthop_entry_find(nexthops, grp->id);\n     }\n }\ndiff --git a/controller/nexthop-exchange.h b/controller/nexthop-exchange.h\nindex e94fdc73a..73f08c2fe 100644\n--- a/controller/nexthop-exchange.h\n+++ b/controller/nexthop-exchange.h\n@@ -23,6 +23,7 @@\n \n struct ds;\n struct ofpbuf;\n+struct vector;\n \n struct nexthop_grp_entry {\n     /* The id of the nexthop gateway. */\n@@ -56,6 +57,10 @@ struct nh_table_msg {\n \n void nexthops_sync(struct hmap *nexthops);\n void nexthop_entry_format(struct ds *ds, const struct nexthop_entry *nhe);\n+struct nexthop_entry *nexthop_entry_find(const struct hmap *nexthops,\n+                                         uint32_t id);\n int nh_table_parse(struct ofpbuf *, struct nh_table_msg *change);\n+bool nexthops_handle_changes(struct hmap *nexthops, struct vector *msgs);\n+void nexthops_destroy(struct hmap *nexthops);\n \n #endif /* NEXTHOP_EXCHANGE_H */\ndiff --git a/controller/ovn-controller.c b/controller/ovn-controller.c\nindex 35a5cd0b4..c46530f90 100644\n--- a/controller/ovn-controller.c\n+++ b/controller/ovn-controller.c\n@@ -99,6 +99,7 @@\n #include \"neighbor.h\"\n #include \"neighbor-exchange.h\"\n #include \"neighbor-exchange-netlink.h\"\n+#include \"nexthop-exchange.h\"\n #include \"evpn-arp.h\"\n #include \"evpn-binding.h\"\n #include \"evpn-fdb.h\"\n@@ -6344,6 +6345,83 @@ en_neighbor_table_notify_run(struct engine_node *node OVS_UNUSED,\n     return state;\n }\n \n+/* The nexthop_exchange node is an input node, but is enabled/disabled\n+ * based on en_neighbor_exchange node. The reason being that engine\n+ * periodically runs input nodes to check if there are updates, so it could\n+ * be polled for updates without requiring other nodes to run first. */\n+struct ed_type_nexthop_exchange {\n+    struct hmap nexthops;\n+    bool enabled;\n+    bool recompute;\n+};\n+\n+static void *\n+en_nexthop_exchange_init(struct engine_node *node OVS_UNUSED,\n+                         struct engine_arg *arg OVS_UNUSED)\n+{\n+    struct ed_type_nexthop_exchange *nhe_data = xmalloc(sizeof *nhe_data);\n+    *nhe_data = (struct ed_type_nexthop_exchange) {\n+        .nexthops = HMAP_INITIALIZER(&nhe_data->nexthops),\n+        .enabled = false,\n+        .recompute = true,\n+    };\n+\n+    return nhe_data;\n+}\n+\n+static void\n+en_nexthop_exchange_cleanup(void *data)\n+{\n+    struct ed_type_nexthop_exchange *nhe_data = data;\n+    nexthops_destroy(&nhe_data->nexthops);\n+    hmap_destroy(&nhe_data->nexthops);\n+}\n+\n+static enum engine_node_state\n+en_nexthop_exchange_run(struct engine_node *node OVS_UNUSED, void *data)\n+{\n+    struct ed_type_nexthop_exchange *nhe_data = data;\n+\n+    if (!nhe_data->enabled) {\n+        return EN_UNCHANGED;\n+    }\n+\n+    if (nhe_data->recompute) {\n+        nexthops_destroy(&nhe_data->nexthops);\n+        nexthops_sync(&nhe_data->nexthops);\n+        /* We are doing a full sync, let's clear any data\n+         * that might accumulate in the meantime. */\n+        ovn_netlink_notifier_flush(OVN_NL_NOTIFIER_NEXTHOP);\n+\n+        nhe_data->recompute = false;\n+        return EN_UPDATED;\n+    }\n+\n+    struct vector *msgs = ovn_netlink_get_msgs(OVN_NL_NOTIFIER_NEXTHOP);\n+    bool updated = nexthops_handle_changes(&nhe_data->nexthops, msgs);\n+    ovn_netlink_notifier_flush(OVN_NL_NOTIFIER_NEXTHOP);\n+\n+    return updated ? EN_UPDATED : EN_UNCHANGED;\n+}\n+\n+static void\n+nexthop_exchange_update(struct ed_type_nexthop_exchange *nhe_data,\n+                        bool enabled)\n+{\n+    if (nhe_data->enabled == enabled) {\n+        return;\n+    }\n+\n+    if (nhe_data->enabled && !enabled) {\n+        nexthops_destroy(&nhe_data->nexthops);\n+    } else if (!nhe_data->enabled && enabled) {\n+        nhe_data->recompute = true;\n+    }\n+\n+    nhe_data->enabled = enabled;\n+    ovn_netlink_update_notifier(OVN_NL_NOTIFIER_NEXTHOP, enabled);\n+}\n+\n struct ed_type_neighbor_exchange {\n     /* Contains 'struct evpn_remote_vtep'. */\n     struct hmap remote_vteps;\n@@ -6389,6 +6467,8 @@ en_neighbor_exchange_run(struct engine_node *node, void *data_)\n         engine_get_input_data(\"neighbor\", node);\n     struct ed_type_neighbor_table_notify *nt_notify =\n         engine_get_input_data(\"neighbor_table_notify\", node);\n+    struct ed_type_nexthop_exchange *nhe_data =\n+        engine_get_input_data(\"nexthop_exchange\", node);\n \n     evpn_remote_vteps_clear(&data->remote_vteps);\n     evpn_static_entries_clear(&data->static_fdbs);\n@@ -6407,6 +6487,7 @@ en_neighbor_exchange_run(struct engine_node *node, void *data_)\n \n     neighbor_exchange_run(&n_ctx_in, &n_ctx_out);\n     neighbor_table_notify_update(&nt_notify->watches);\n+    nexthop_exchange_update(nhe_data, !vector_is_empty(&nt_notify->watches));\n \n     return EN_UPDATED;\n }\n@@ -6864,6 +6945,7 @@ static ENGINE_NODE(neighbor);\n static ENGINE_NODE(neighbor_table_notify);\n static ENGINE_NODE(neighbor_exchange);\n static ENGINE_NODE(neighbor_exchange_status);\n+static ENGINE_NODE(nexthop_exchange);\n static ENGINE_NODE(evpn_vtep_binding, CLEAR_TRACKED_DATA);\n static ENGINE_NODE(evpn_fdb, CLEAR_TRACKED_DATA);\n static ENGINE_NODE(evpn_arp, CLEAR_TRACKED_DATA);\n@@ -7117,6 +7199,10 @@ inc_proc_ovn_controller_init(\n     engine_add_input(&en_neighbor_exchange, &en_neighbor_table_notify, NULL);\n     engine_add_input(&en_neighbor_exchange, &en_neighbor_exchange_status,\n                      NULL);\n+    /* We just need to enable/disable the nexthop exchange based on\n+     * the neighbor status.  */\n+    engine_add_input(&en_neighbor_exchange, &en_nexthop_exchange,\n+                     engine_noop_handler);\n \n     engine_add_input(&en_evpn_vtep_binding, &en_ovs_open_vswitch, NULL);\n     engine_add_input(&en_evpn_vtep_binding, &en_ovs_bridge, NULL);\n@@ -7133,6 +7219,9 @@ inc_proc_ovn_controller_init(\n     engine_add_input(&en_evpn_fdb, &en_neighbor_exchange, NULL);\n     engine_add_input(&en_evpn_fdb, &en_evpn_vtep_binding,\n                      evpn_fdb_vtep_binding_handler);\n+    /* XXX: This is just a place holder and it will be updated later on. */\n+    engine_add_input(&en_evpn_fdb, &en_nexthop_exchange,\n+                     engine_noop_handler);\n \n     engine_add_input(&en_evpn_arp, &en_neighbor_exchange, NULL);\n     engine_add_input(&en_evpn_arp, &en_evpn_vtep_binding,\ndiff --git a/tests/ovn-inc-proc-graph-dump.at b/tests/ovn-inc-proc-graph-dump.at\nindex 178310978..6b4d94835 100644\n--- a/tests/ovn-inc-proc-graph-dump.at\n+++ b/tests/ovn-inc-proc-graph-dump.at\n@@ -401,11 +401,13 @@ digraph \"Incremental-Processing-Engine\" {\n \thost_if_monitor [[style=filled, shape=box, fillcolor=white, label=\"host_if_monitor\"]];\n \tneighbor_table_notify [[style=filled, shape=box, fillcolor=white, label=\"neighbor_table_notify\"]];\n \tneighbor_exchange_status [[style=filled, shape=box, fillcolor=white, label=\"neighbor_exchange_status\"]];\n+\tnexthop_exchange [[style=filled, shape=box, fillcolor=white, label=\"nexthop_exchange\"]];\n \tneighbor_exchange [[style=filled, shape=box, fillcolor=white, label=\"neighbor_exchange\"]];\n \tneighbor -> neighbor_exchange [[label=\"\"]];\n \thost_if_monitor -> neighbor_exchange [[label=\"\"]];\n \tneighbor_table_notify -> neighbor_exchange [[label=\"\"]];\n \tneighbor_exchange_status -> neighbor_exchange [[label=\"\"]];\n+\tnexthop_exchange -> neighbor_exchange [[label=\"engine_noop_handler\"]];\n \tevpn_vtep_binding [[style=filled, shape=box, fillcolor=white, label=\"evpn_vtep_binding\"]];\n \tOVS_open_vswitch -> evpn_vtep_binding [[label=\"\"]];\n \tOVS_bridge -> evpn_vtep_binding [[label=\"\"]];\n@@ -416,6 +418,7 @@ digraph \"Incremental-Processing-Engine\" {\n \tevpn_fdb [[style=filled, shape=box, fillcolor=white, label=\"evpn_fdb\"]];\n \tneighbor_exchange -> evpn_fdb [[label=\"\"]];\n \tevpn_vtep_binding -> evpn_fdb [[label=\"evpn_fdb_vtep_binding_handler\"]];\n+\tnexthop_exchange -> evpn_fdb [[label=\"engine_noop_handler\"]];\n \tevpn_arp [[style=filled, shape=box, fillcolor=white, label=\"evpn_arp\"]];\n \tneighbor_exchange -> evpn_arp [[label=\"\"]];\n \tevpn_vtep_binding -> evpn_arp [[label=\"evpn_arp_vtep_binding_handler\"]];\n",
    "prefixes": [
        "ovs-dev",
        "3/7"
    ]
}