get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2095638,
    "url": "http://patchwork.ozlabs.org/api/patches/2095638/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/ovn/patch/20250609173539.1636916-14-mmichels@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": "<20250609173539.1636916-14-mmichels@redhat.com>",
    "list_archive_url": null,
    "date": "2025-06-09T17:35:32",
    "name": "[ovs-dev,13/14] lflow: Remove northd dependency from en-lflow-sync.",
    "commit_ref": null,
    "pull_url": null,
    "state": "deferred",
    "archived": false,
    "hash": "cefeba286a9531cadfe6c936b49566d7d08a2b4c",
    "submitter": {
        "id": 71978,
        "url": "http://patchwork.ozlabs.org/api/people/71978/?format=api",
        "name": "Mark Michelson",
        "email": "mmichels@redhat.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/ovn/patch/20250609173539.1636916-14-mmichels@redhat.com/mbox/",
    "series": [
        {
            "id": 460139,
            "url": "http://patchwork.ozlabs.org/api/series/460139/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/ovn/list/?series=460139",
            "date": "2025-06-09T17:35:19",
            "name": "Logical Flow Sync Refactor.",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/460139/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2095638/comments/",
    "check": "success",
    "checks": "http://patchwork.ozlabs.org/api/patches/2095638/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=XJ3eW74e;\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=XJ3eW74e",
            "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=XJ3eW74e"
        ],
        "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 4bGJxZ6gjcz1yDx\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 10 Jun 2025 03:36:18 +1000 (AEST)",
            "from localhost (localhost [127.0.0.1])\n\tby smtp3.osuosl.org (Postfix) with ESMTP id 2ADA261458;\n\tMon,  9 Jun 2025 17:36:31 +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 095tm4HEWv1x; Mon,  9 Jun 2025 17:36:27 +0000 (UTC)",
            "from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])\n\tby smtp3.osuosl.org (Postfix) with ESMTPS id BCAB761552;\n\tMon,  9 Jun 2025 17:36:20 +0000 (UTC)",
            "from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id 99ED8C0AC5;\n\tMon,  9 Jun 2025 17:36:20 +0000 (UTC)",
            "from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 19206C0AC8\n for <dev@openvswitch.org>; Mon,  9 Jun 2025 17:36:19 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n by smtp4.osuosl.org (Postfix) with ESMTP id 0C95241D73\n for <dev@openvswitch.org>; Mon,  9 Jun 2025 17:36:03 +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 JOQ5EfxEHQ-t for <dev@openvswitch.org>;\n Mon,  9 Jun 2025 17:35:59 +0000 (UTC)",
            "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by smtp4.osuosl.org (Postfix) with ESMTPS id 2720641BF3\n for <dev@openvswitch.org>; Mon,  9 Jun 2025 17:35:53 +0000 (UTC)",
            "from mx-prod-mc-03.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-544-hExdRn9YOpyVHyE_Fy0QNw-1; Mon,\n 09 Jun 2025 13:35:51 -0400",
            "from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111])\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-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 188C319560B0\n for <dev@openvswitch.org>; Mon,  9 Jun 2025 17:35:51 +0000 (UTC)",
            "from localhost.localdomain.com (unknown [10.22.58.15])\n by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id 9BE8E18003FC\n for <dev@openvswitch.org>; Mon,  9 Jun 2025 17:35:50 +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 BCAB761552",
            "OpenDKIM Filter v2.11.0 smtp4.osuosl.org 2720641BF3"
        ],
        "Received-SPF": "Pass (mailfrom) identity=mailfrom; client-ip=170.10.133.124;\n helo=us-smtp-delivery-124.mimecast.com; envelope-from=mmichels@redhat.com;\n receiver=<UNKNOWN>",
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 smtp4.osuosl.org 2720641BF3",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1749490553;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to: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=bsobASl2yoNWADQBB4XF5t8kvTslRrwZJXrnq657sEI=;\n b=XJ3eW74eNDdYXNaQ+rs2quuoGGVdaIJCBcDouOlbcv+3cO41q/oKm1joSy1DSxZ2ajVjCG\n bvQo4irnf6ROlocJCIjDf+e5yjGdmxzqeP0jFBBYCAtL187n1mYdLT9wXzZ0FdRFNp4QBr\n kyKyaOc0uipJqLjgbxq0t10JyFGuzW8=",
        "X-MC-Unique": "hExdRn9YOpyVHyE_Fy0QNw-1",
        "X-Mimecast-MFC-AGG-ID": "hExdRn9YOpyVHyE_Fy0QNw_1749490551",
        "To": "dev@openvswitch.org",
        "Date": "Mon,  9 Jun 2025 13:35:32 -0400",
        "Message-ID": "<20250609173539.1636916-14-mmichels@redhat.com>",
        "In-Reply-To": "<20250609173539.1636916-1-mmichels@redhat.com>",
        "References": "<20250609173539.1636916-1-mmichels@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 3.4.1 on 10.30.177.111",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-MFC-PROC-ID": "msBhDBYiEx-DWnK1Sybb9SmukPbR-yhLFOnNDUMCWCo_1749490551",
        "X-Mimecast-Originator": "redhat.com",
        "Subject": "[ovs-dev] [PATCH ovn 13/14] lflow: Remove northd dependency from\n en-lflow-sync.",
        "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": "Mark Michelson via dev <ovs-dev@openvswitch.org>",
        "Reply-To": "Mark Michelson <mmichels@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": "The previous commit established that ovn_datapath array indices\ncorrespond with synced logical datapath array indices. Because of that,\nwe can use the synced datapath indices when syncing logical flows now.\n\nThis removal of the northd dependency frees up new nodes to be able to\ncreate logical flow tables using the synced datapath indices instead of\novn_datapath indices, and the syncing will work no matter which set of\nindices are used.\n\nCurrently, the macros to add logical flows to the logical flow table\nstill require an ovn_datapath but we'll change that in the next commit.\n\nThis change expanded out beyond the lflow code since en-sync-sb uses\novn_dp_groups. Luckily, the only thing the en-sync-sb needed from\nnorthd's ovn_datapaths was the datapath indices. This meant the\nconversion to using the synced datapath indices very easy.\n\nSigned-off-by: Mark Michelson <mmichels@redhat.com>\n---\n northd/en-lflow.c        |  13 +++--\n northd/en-lflow.h        |   2 +-\n northd/en-sync-sb.c      | 102 ++++++++++++++++++++++-----------------\n northd/inc-proc-northd.c |  10 ++--\n northd/lflow-mgr.c       |  63 +++++++++++++-----------\n northd/lflow-mgr.h       |   2 +-\n 6 files changed, 105 insertions(+), 87 deletions(-)",
    "diff": "diff --git a/northd/en-lflow.c b/northd/en-lflow.c\nindex e9363a2e4..fdd11651b 100644\n--- a/northd/en-lflow.c\n+++ b/northd/en-lflow.c\n@@ -370,8 +370,8 @@ static void\n lflow_sync_data_init(struct lflow_sync_data *lflow_sync,\n                      const struct sbrec_logical_flow_table *sb_lflow_table,\n                      const struct lflow_data *lflow_data,\n-                     const struct ovn_datapaths *ls_datapaths,\n-                     const struct ovn_datapaths *lr_datapaths)\n+                     const struct ovn_synced_logical_switch_map *synced_lses,\n+                     const struct ovn_synced_logical_router_map *synced_lrs)\n {\n     hmap_init(&lflow_sync->sb_lflows.valid);\n     hmap_init(&lflow_sync->sb_lflows.to_delete);\n@@ -381,9 +381,9 @@ lflow_sync_data_init(struct lflow_sync_data *lflow_sync,\n     }\n \n     ovn_dp_groups_init(&lflow_sync->all_dp_info[DP_SWITCH].dp_groups);\n-    lflow_sync->all_dp_info[DP_SWITCH].datapaths = ls_datapaths;\n+    lflow_sync->all_dp_info[DP_SWITCH].datapaths = &synced_lses->datapaths;\n     ovn_dp_groups_init(&lflow_sync->all_dp_info[DP_ROUTER].dp_groups);\n-    lflow_sync->all_dp_info[DP_ROUTER].datapaths = lr_datapaths;\n+    lflow_sync->all_dp_info[DP_ROUTER].datapaths = &synced_lrs->datapaths;\n \n     if (!sb_lflow_table) {\n         return;\n@@ -430,18 +430,17 @@ en_lflow_sync_run(struct engine_node *node, void *data)\n         engine_get_input_data(\"datapath_synced_logical_router\", node);\n     const struct lflow_data *lflow_data =\n         engine_get_input_data(\"lflow\", node);\n-    const struct northd_data *northd =\n-        engine_get_input_data(\"northd\", node);\n     struct ed_type_global_config *global_config =\n         engine_get_input_data(\"global_config\", node);\n     const struct sbrec_logical_dp_group_table *sb_dp_group_table =\n         EN_OVSDB_GET(engine_get_input(\"SB_logical_dp_group\", node));\n     const struct engine_context *eng_ctx = engine_get_context();\n \n+\n     struct lflow_sync_data *lflow_sync = data;\n     lflow_sync_data_destroy(lflow_sync);\n     lflow_sync_data_init(lflow_sync, sb_lflow_table, lflow_data,\n-                         &northd->ls_datapaths, &northd->lr_datapaths);\n+                         synced_lses, synced_lrs);\n \n     stopwatch_start(LFLOWS_TO_SB_STOPWATCH_NAME, time_msec());\n \ndiff --git a/northd/en-lflow.h b/northd/en-lflow.h\nindex d99d7f9cf..a94ca17d5 100644\n--- a/northd/en-lflow.h\n+++ b/northd/en-lflow.h\n@@ -49,7 +49,7 @@ lflow_group_ecmp_route_change_handler(struct engine_node *node, void *data);\n struct sb_lflows;\n struct dp_info {\n     struct hmap dp_groups;\n-    const struct ovn_datapaths *datapaths;\n+    const struct ovn_datapath_binding_hashvec *datapaths;\n };\n \n struct lflow_sync_data {\ndiff --git a/northd/en-sync-sb.c b/northd/en-sync-sb.c\nindex 52f1c8206..6673b42cf 100644\n--- a/northd/en-sync-sb.c\n+++ b/northd/en-sync-sb.c\n@@ -35,6 +35,8 @@\n #include \"lib/ovn-util.h\"\n #include \"lflow-mgr.h\"\n #include \"northd.h\"\n+#include \"en-datapath-logical-switch.h\"\n+#include \"en-datapath-logical-router.h\"\n \n #include \"openvswitch/vlog.h\"\n \n@@ -243,30 +245,33 @@ static void sb_lb_table_destroy(struct sb_lb_table *);\n \n static struct sb_lb_record *sb_lb_table_find(struct hmap *sb_lbs,\n                                              const struct uuid *);\n-static void sb_lb_table_build_and_sync(struct sb_lb_table *,\n-                                struct ovsdb_idl_txn *ovnsb_txn,\n-                                const struct sbrec_load_balancer_table *,\n-                                const struct sbrec_logical_dp_group_table *,\n-                                struct hmap *lb_dps_map,\n-                                struct ovn_datapaths *ls_datapaths,\n-                                struct ovn_datapaths *lr_datapaths,\n-                                struct chassis_features *);\n-static bool sync_sb_lb_record(struct sb_lb_record *,\n-                              const struct sbrec_load_balancer *,\n-                              const struct sbrec_logical_dp_group_table *,\n-                              struct sb_lb_table *,\n-                              struct ovsdb_idl_txn *ovnsb_txn,\n-                              struct ovn_datapaths *ls_datapaths,\n-                              struct ovn_datapaths *lr_datapaths,\n-                              struct chassis_features *);\n-static bool sync_changed_lbs(struct sb_lb_table *,\n-                             struct ovsdb_idl_txn *ovnsb_txn,\n-                             const struct sbrec_load_balancer_table *,\n-                             const struct sbrec_logical_dp_group_table *,\n-                             struct tracked_lbs *,\n-                             struct ovn_datapaths *ls_datapaths,\n-                             struct ovn_datapaths *lr_datapaths,\n-                             struct chassis_features *);\n+static void sb_lb_table_build_and_sync(\n+    struct sb_lb_table *,\n+    struct ovsdb_idl_txn *ovnsb_txn,\n+    const struct sbrec_load_balancer_table *,\n+    const struct sbrec_logical_dp_group_table *,\n+    struct hmap *lb_dps_map,\n+    const struct ovn_datapath_binding_hashvec *ls_datapaths,\n+    const struct ovn_datapath_binding_hashvec *lr_datapaths,\n+    struct chassis_features *);\n+static bool sync_sb_lb_record(\n+    struct sb_lb_record *,\n+    const struct sbrec_load_balancer *,\n+    const struct sbrec_logical_dp_group_table *,\n+    struct sb_lb_table *,\n+    struct ovsdb_idl_txn *ovnsb_txn,\n+    const struct ovn_datapath_binding_hashvec *ls_datapaths,\n+    const struct ovn_datapath_binding_hashvec *lr_datapaths,\n+    struct chassis_features *);\n+static bool sync_changed_lbs(\n+    struct sb_lb_table *,\n+    struct ovsdb_idl_txn *ovnsb_txn,\n+    const struct sbrec_load_balancer_table *,\n+    const struct sbrec_logical_dp_group_table *,\n+    struct tracked_lbs *,\n+    const struct ovn_datapath_binding_hashvec *ls_datapaths,\n+    const struct ovn_datapath_binding_hashvec *lr_datapaths,\n+    struct chassis_features *);\n \n void *\n en_sync_to_sb_lb_init(struct engine_node *node OVS_UNUSED,\n@@ -288,6 +293,10 @@ en_sync_to_sb_lb_run(struct engine_node *node, void *data_)\n         EN_OVSDB_GET(engine_get_input(\"SB_logical_dp_group\", node));\n     struct ed_type_global_config *global_config =\n         engine_get_input_data(\"global_config\", node);\n+    const struct ovn_synced_logical_switch_map *synced_lses =\n+        engine_get_input_data(\"datapath_synced_logical_switch\", node);\n+    const struct ovn_synced_logical_switch_map *synced_lrs =\n+        engine_get_input_data(\"datapath_synced_logical_router\", node);\n     const struct engine_context *eng_ctx = engine_get_context();\n     struct ed_type_sync_to_sb_lb_data *data = data_;\n \n@@ -296,8 +305,8 @@ en_sync_to_sb_lb_run(struct engine_node *node, void *data_)\n                                sb_load_balancer_table,\n                                sb_dpgrp_table,\n                                &northd_data->lb_datapaths_map,\n-                               &northd_data->ls_datapaths,\n-                               &northd_data->lr_datapaths,\n+                               &synced_lses->datapaths,\n+                               &synced_lrs->datapaths,\n                                &global_config->features);\n \n     return EN_UPDATED;\n@@ -331,11 +340,15 @@ sync_to_sb_lb_northd_handler(struct engine_node *node, void *data_)\n         EN_OVSDB_GET(engine_get_input(\"SB_load_balancer\", node));\n     struct ed_type_global_config *global_config =\n         engine_get_input_data(\"global_config\", node);\n+    const struct ovn_synced_logical_switch_map *synced_lses =\n+        engine_get_input_data(\"datapath_synced_logical_switch\", node);\n+    const struct ovn_synced_logical_switch_map *synced_lrs =\n+        engine_get_input_data(\"datapath_synced_logical_router\", node);\n     struct ed_type_sync_to_sb_lb_data *data = data_;\n \n     if (!sync_changed_lbs(&data->sb_lbs, eng_ctx->ovnsb_idl_txn, sb_lb_table,\n                           sb_dpgrp_table, &nd->trk_data.trk_lbs,\n-                          &nd->ls_datapaths, &nd->lr_datapaths,\n+                          &synced_lses->datapaths, &synced_lrs->datapaths,\n                           &global_config->features)) {\n         return EN_UNHANDLED;\n     }\n@@ -672,8 +685,9 @@ sb_lb_table_build_and_sync(\n     struct sb_lb_table *sb_lbs, struct ovsdb_idl_txn *ovnsb_txn,\n     const struct sbrec_load_balancer_table *sb_lb_table,\n     const struct sbrec_logical_dp_group_table *sb_dpgrp_table,\n-    struct hmap *lb_dps_map, struct ovn_datapaths *ls_datapaths,\n-    struct ovn_datapaths *lr_datapaths,\n+    struct hmap *lb_dps_map,\n+    const struct ovn_datapath_binding_hashvec *ls_datapaths,\n+    const struct ovn_datapath_binding_hashvec *lr_datapaths,\n     struct chassis_features *chassis_features)\n {\n     struct hmap tmp_sb_lbs = HMAP_INITIALIZER(&tmp_sb_lbs);\n@@ -733,8 +747,8 @@ sync_sb_lb_record(struct sb_lb_record *sb_lb,\n                   const struct sbrec_logical_dp_group_table *sb_dpgrp_table,\n                   struct sb_lb_table *sb_lbs,\n                   struct ovsdb_idl_txn *ovnsb_txn,\n-                  struct ovn_datapaths *ls_datapaths,\n-                  struct ovn_datapaths *lr_datapaths,\n+                  const struct ovn_datapath_binding_hashvec *ls_datapaths,\n+                  const struct ovn_datapath_binding_hashvec *lr_datapaths,\n                   struct chassis_features *chassis_features)\n {\n     struct sbrec_logical_dp_group *sbrec_ls_dp_group = NULL;\n@@ -760,10 +774,11 @@ sync_sb_lb_record(struct sb_lb_record *sb_lb,\n     }\n \n     if (lb_dps->n_nb_ls) {\n-        sb_lb->ls_dpg = ovn_dp_group_get(&sb_lbs->ls_dp_groups,\n-                                         lb_dps->n_nb_ls,\n-                                         lb_dps->nb_ls_map,\n-                                         ods_size(ls_datapaths));\n+        sb_lb->ls_dpg = ovn_dp_group_get(\n+            &sb_lbs->ls_dp_groups,\n+            lb_dps->n_nb_ls,\n+            lb_dps->nb_ls_map,\n+            hmap_count(&ls_datapaths->bindings_map));\n         if (sb_lb->ls_dpg) {\n             /* Update the dpg's sb dp_group. */\n             sb_lb->ls_dpg->dp_group =\n@@ -793,7 +808,7 @@ sync_sb_lb_record(struct sb_lb_record *sb_lb,\n             sb_lb->ls_dpg = ovn_dp_group_create(\n                 ovnsb_txn, &sb_lbs->ls_dp_groups, sbrec_ls_dp_group,\n                 lb_dps->n_nb_ls, lb_dps->nb_ls_map,\n-                ods_size(ls_datapaths), ls_datapaths);\n+                hmap_count(&ls_datapaths->bindings_map), ls_datapaths);\n         }\n \n         if (chassis_features->ls_dpg_column) {\n@@ -814,10 +829,11 @@ sync_sb_lb_record(struct sb_lb_record *sb_lb,\n \n \n     if (lb_dps->n_nb_lr) {\n-        sb_lb->lr_dpg = ovn_dp_group_get(&sb_lbs->lr_dp_groups,\n-                                         lb_dps->n_nb_lr,\n-                                         lb_dps->nb_lr_map,\n-                                         ods_size(lr_datapaths));\n+        sb_lb->lr_dpg = ovn_dp_group_get(\n+            &sb_lbs->lr_dp_groups,\n+            lb_dps->n_nb_lr,\n+            lb_dps->nb_lr_map,\n+            hmap_count(&lr_datapaths->bindings_map));\n         if (sb_lb->lr_dpg) {\n             /* Update the dpg's sb dp_group. */\n             sb_lb->lr_dpg->dp_group =\n@@ -847,7 +863,7 @@ sync_sb_lb_record(struct sb_lb_record *sb_lb,\n             sb_lb->lr_dpg = ovn_dp_group_create(\n                 ovnsb_txn, &sb_lbs->lr_dp_groups, sbrec_lr_dp_group,\n                 lb_dps->n_nb_lr, lb_dps->nb_lr_map,\n-                ods_size(lr_datapaths), lr_datapaths);\n+                hmap_count(&lr_datapaths->bindings_map), lr_datapaths);\n         }\n \n         sbrec_load_balancer_set_lr_datapath_group(sbrec_lb,\n@@ -892,8 +908,8 @@ sync_changed_lbs(struct sb_lb_table *sb_lbs,\n                  const struct sbrec_load_balancer_table *sb_lb_table,\n                  const struct sbrec_logical_dp_group_table *sb_dpgrp_table,\n                  struct tracked_lbs *trk_lbs,\n-                 struct ovn_datapaths *ls_datapaths,\n-                 struct ovn_datapaths *lr_datapaths,\n+                 const struct ovn_datapath_binding_hashvec *ls_datapaths,\n+                 const struct ovn_datapath_binding_hashvec *lr_datapaths,\n                  struct chassis_features *chassis_features)\n {\n     struct ovn_lb_datapaths *lb_dps;\ndiff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c\nindex 3e6ff47b9..eca9726ff 100644\n--- a/northd/inc-proc-northd.c\n+++ b/northd/inc-proc-northd.c\n@@ -454,12 +454,6 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,\n     engine_add_input(&en_lflow_sync, &en_global_config,\n                      node_global_config_handler);\n     engine_add_input(&en_lflow_sync, &en_lflow, lflow_sync_lflow_handler);\n-    /* en_lflow reacts to en_northd's changes and recalculates flows.\n-     * en_lflow_sync needs en_northd's data, but only needs to handle the\n-     * flow changes that en_northd caused in en_lflow. Changes in en_northd\n-     * can be ignored, so we use engine_noop_handler here.\n-     */\n-    engine_add_input(&en_lflow_sync, &en_northd, engine_noop_handler);\n     engine_add_input(&en_lflow_sync, &en_sb_logical_dp_group, NULL);\n \n     engine_add_input(&en_sync_to_sb_addr_set, &en_northd, NULL);\n@@ -487,6 +481,10 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,\n     engine_add_input(&en_sync_to_sb_lb, &en_sb_load_balancer,\n                      sync_to_sb_lb_sb_load_balancer);\n     engine_add_input(&en_sync_to_sb_lb, &en_sb_logical_dp_group, NULL);\n+    engine_add_input(&en_sync_to_sb_lb, &en_datapath_synced_logical_router,\n+                     engine_noop_handler);\n+    engine_add_input(&en_sync_to_sb_lb, &en_datapath_synced_logical_switch,\n+                     engine_noop_handler);\n \n     engine_add_input(&en_sync_to_sb_pb, &en_northd,\n                      sync_to_sb_pb_northd_handler);\ndiff --git a/northd/lflow-mgr.c b/northd/lflow-mgr.c\nindex 334353902..1e4614873 100644\n--- a/northd/lflow-mgr.c\n+++ b/northd/lflow-mgr.c\n@@ -67,7 +67,7 @@ static struct sbrec_logical_dp_group *ovn_sb_insert_or_update_logical_dp_group(\n     struct ovsdb_idl_txn *ovnsb_txn,\n     struct sbrec_logical_dp_group *,\n     const unsigned long *dpg_bitmap,\n-    const struct ovn_datapaths *);\n+    const struct ovn_datapath_binding_hashvec *);\n static struct ovn_dp_group *ovn_dp_group_find(const struct hmap *dp_groups,\n                                               const unsigned long *dpg_bitmap,\n                                               size_t bitmap_len,\n@@ -88,13 +88,14 @@ static bool lflow_ref_sync_lflows__(\n     bool ovn_internal_version_changed,\n     const struct sbrec_logical_flow_table *,\n     const struct sbrec_logical_dp_group_table *);\n-static bool sync_lflow_to_sb(struct ovn_lflow *,\n-                             struct ovsdb_idl_txn *ovnsb_txn,\n-                             struct hmap *dp_groups,\n-                             const struct ovn_datapaths *datapaths,\n-                             bool ovn_internal_version_changed,\n-                             const struct sbrec_logical_flow *sbflow,\n-                             const struct sbrec_logical_dp_group_table *);\n+static bool sync_lflow_to_sb(\n+    struct ovn_lflow *,\n+    struct ovsdb_idl_txn *ovnsb_txn,\n+    struct hmap *dp_groups,\n+    const struct ovn_datapath_binding_hashvec *datapaths,\n+    bool ovn_internal_version_changed,\n+    const struct sbrec_logical_flow *sbflow,\n+    const struct sbrec_logical_dp_group_table *);\n \n /* TODO:  Move the parallization logic to this module to avoid accessing\n  * and modifying in both northd.c and lflow-mgr.c. */\n@@ -298,7 +299,7 @@ lflow_table_sync_to_sb(struct lflow_table *lflow_table,\n             sbflow->priority, sbflow->match, sbflow->actions,\n             sbflow->controller_meter, sbflow->hash);\n         if (lflow) {\n-            const struct ovn_datapaths *datapaths =\n+            const struct ovn_datapath_binding_hashvec *datapaths =\n                 all_dp_info[dp_type].datapaths;\n             struct hmap *dp_groups = &all_dp_info[dp_type].dp_groups;\n             sync_lflow_to_sb(lflow, ovnsb_txn, dp_groups, datapaths,\n@@ -316,7 +317,8 @@ lflow_table_sync_to_sb(struct lflow_table *lflow_table,\n         enum ovn_datapath_type dp_type =\n             ovn_stage_to_datapath_type(lflow->stage);\n         struct hmap *dp_groups = &all_dp_info[dp_type].dp_groups;\n-        const struct ovn_datapaths *datapaths = all_dp_info[dp_type].datapaths;\n+        const struct ovn_datapath_binding_hashvec *datapaths =\n+            all_dp_info[dp_type].datapaths;\n         sync_lflow_to_sb(lflow, ovnsb_txn, dp_groups, datapaths,\n                          ovn_internal_version_changed, NULL, dpgrp_table);\n \n@@ -736,7 +738,7 @@ ovn_dp_group_create(struct ovsdb_idl_txn *ovnsb_txn,\n                     size_t desired_n,\n                     const unsigned long *desired_bitmap,\n                     size_t bitmap_len,\n-                    const struct ovn_datapaths *datapaths)\n+                    const struct ovn_datapath_binding_hashvec *datapaths)\n {\n     struct ovn_dp_group *dpg;\n \n@@ -746,14 +748,13 @@ ovn_dp_group_create(struct ovsdb_idl_txn *ovnsb_txn,\n \n     dpg_bitmap = sb_group ? bitmap_allocate(bitmap_len) : NULL;\n     for (i = 0; sb_group && i < sb_group->n_datapaths; i++) {\n-        struct ovn_datapath *datapath_od;\n+        const struct ovn_datapath_binding *binding;\n \n-        datapath_od = ovn_datapath_from_sbrec_(&datapaths->datapaths,\n-                                               sb_group->datapaths[i]);\n-        if (!datapath_od || ovn_datapath_is_stale(datapath_od)) {\n+        binding = ovn_datapath_binding_find(datapaths, sb_group->datapaths[i]);\n+        if (!binding) {\n             break;\n         }\n-        bitmap_set1(dpg_bitmap, datapath_od->index);\n+        bitmap_set1(dpg_bitmap, binding->index);\n         n++;\n     }\n     if (!sb_group || i != sb_group->n_datapaths) {\n@@ -976,18 +977,18 @@ static bool\n sync_lflow_to_sb(struct ovn_lflow *lflow,\n                  struct ovsdb_idl_txn *ovnsb_txn,\n                  struct hmap *dp_groups,\n-                 const struct ovn_datapaths *datapaths,\n+                 const struct ovn_datapath_binding_hashvec *datapaths,\n                  bool ovn_internal_version_changed,\n                  const struct sbrec_logical_flow *sbflow,\n                  const struct sbrec_logical_dp_group_table *sb_dpgrp_table)\n {\n     struct sbrec_logical_dp_group *sbrec_dp_group = NULL;\n     struct ovn_dp_group *pre_sync_dpg = lflow->dpg;\n-    struct ovn_datapath **datapaths_array;\n+    struct ovn_datapath_binding **datapaths_array;\n     size_t n_datapaths;\n \n-    n_datapaths = ods_size(datapaths);\n-    datapaths_array = datapaths->array;\n+    n_datapaths = hmap_count(&datapaths->bindings_map);\n+    datapaths_array = vector_get_array(&datapaths->bindings_vec);\n \n     lflow->n_ods = bitmap_count1(lflow->dpg_bitmap, n_datapaths);\n     ovs_assert(lflow->n_ods);\n@@ -1186,17 +1187,20 @@ ovn_dp_group_destroy(struct ovn_dp_group *dpg)\n \n static struct sbrec_logical_dp_group *\n ovn_sb_insert_or_update_logical_dp_group(\n-                            struct ovsdb_idl_txn *ovnsb_txn,\n-                            struct sbrec_logical_dp_group *dp_group,\n-                            const unsigned long *dpg_bitmap,\n-                            const struct ovn_datapaths *datapaths)\n+                        struct ovsdb_idl_txn *ovnsb_txn,\n+                        struct sbrec_logical_dp_group *dp_group,\n+                        const unsigned long *dpg_bitmap,\n+                        const struct ovn_datapath_binding_hashvec *datapaths)\n {\n     const struct sbrec_datapath_binding **sb;\n     size_t n = 0, index;\n+    size_t n_datapaths = hmap_count(&datapaths->bindings_map);\n+    struct ovn_datapath_binding **bindings =\n+        vector_get_array(&datapaths->bindings_vec);\n \n-    sb = xmalloc(bitmap_count1(dpg_bitmap, ods_size(datapaths)) * sizeof *sb);\n-    BITMAP_FOR_EACH_1 (index, ods_size(datapaths), dpg_bitmap) {\n-        sb[n++] = datapaths->array[index]->sb;\n+    sb = xmalloc(bitmap_count1(dpg_bitmap, n_datapaths) * sizeof *sb);\n+    BITMAP_FOR_EACH_1 (index, n_datapaths, dpg_bitmap) {\n+        sb[n++] = bindings[index]->sb;\n     }\n     if (!dp_group) {\n         struct uuid dpg_uuid = uuid_random();\n@@ -1250,8 +1254,9 @@ lflow_ref_sync_lflows__(struct lflow_ref  *lflow_ref,\n         enum ovn_datapath_type dp_type =\n             ovn_stage_to_datapath_type(lflow->stage);\n         struct hmap *dp_groups = &all_dp_info[dp_type].dp_groups;\n-        const struct ovn_datapaths *datapaths = all_dp_info[dp_type].datapaths;\n-        n_datapaths = ods_size(datapaths);\n+        const struct ovn_datapath_binding_hashvec *datapaths =\n+            all_dp_info[dp_type].datapaths;\n+        n_datapaths = hmap_count(&datapaths->bindings_map);\n \n         size_t n_ods = bitmap_count1(lflow->dpg_bitmap, n_datapaths);\n \ndiff --git a/northd/lflow-mgr.h b/northd/lflow-mgr.h\nindex ada1756f3..80e7965c8 100644\n--- a/northd/lflow-mgr.h\n+++ b/northd/lflow-mgr.h\n@@ -199,7 +199,7 @@ struct ovn_dp_group *ovn_dp_group_create(\n     struct ovsdb_idl_txn *ovnsb_txn, struct hmap *dp_groups,\n     struct sbrec_logical_dp_group *sb_group,\n     size_t desired_n, const unsigned long *desired_bitmap,\n-    size_t bitmap_len, const struct ovn_datapaths *datapaths);\n+    size_t bitmap_len, const struct ovn_datapath_binding_hashvec *datapaths);\n \n static inline void\n inc_ovn_dp_group_ref(struct ovn_dp_group *dpg)\n",
    "prefixes": [
        "ovs-dev",
        "13/14"
    ]
}