get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2095636,
    "url": "http://patchwork.ozlabs.org/api/patches/2095636/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/ovn/patch/20250609173539.1636916-8-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-8-mmichels@redhat.com>",
    "list_archive_url": null,
    "date": "2025-06-09T17:35:26",
    "name": "[ovs-dev,07/14] en-lflow-sync: Separate syncing from datapaths and from the lflow table.",
    "commit_ref": null,
    "pull_url": null,
    "state": "deferred",
    "archived": false,
    "hash": "564ed79d3e29eb8fbd208a4d157ad8175c333754",
    "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-8-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/2095636/comments/",
    "check": "success",
    "checks": "http://patchwork.ozlabs.org/api/patches/2095636/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=FemQ7vuD;\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=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=FemQ7vuD",
            "smtp3.osuosl.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com",
            "smtp3.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=FemQ7vuD"
        ],
        "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 4bGJxB2TNbz1yZ1\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 10 Jun 2025 03:35:58 +1000 (AEST)",
            "from localhost (localhost [127.0.0.1])\n\tby smtp4.osuosl.org (Postfix) with ESMTP id 8D07340C71;\n\tMon,  9 Jun 2025 17:36:10 +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 TjRXy9dpDYXZ; Mon,  9 Jun 2025 17:36:08 +0000 (UTC)",
            "from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])\n\tby smtp4.osuosl.org (Postfix) with ESMTPS id AC48D41D33;\n\tMon,  9 Jun 2025 17:35:59 +0000 (UTC)",
            "from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id 565B0C0AC7;\n\tMon,  9 Jun 2025 17:35:59 +0000 (UTC)",
            "from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 06329C0AC5\n for <dev@openvswitch.org>; Mon,  9 Jun 2025 17:35:58 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n by smtp3.osuosl.org (Postfix) with ESMTP id B06796149D\n for <dev@openvswitch.org>; Mon,  9 Jun 2025 17:35:53 +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 Q4ltkYZFeUOd for <dev@openvswitch.org>;\n Mon,  9 Jun 2025 17:35:50 +0000 (UTC)",
            "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by smtp3.osuosl.org (Postfix) with ESMTPS id 862C961452\n for <dev@openvswitch.org>; Mon,  9 Jun 2025 17:35:49 +0000 (UTC)",
            "from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-528-hrJ7oAioPIOJD9QDGPw9XA-1; Mon,\n 09 Jun 2025 13:35:47 -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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 686381808993\n for <dev@openvswitch.org>; Mon,  9 Jun 2025 17:35:46 +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 EBD3918003FC\n for <dev@openvswitch.org>; Mon,  9 Jun 2025 17:35:45 +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 smtp4.osuosl.org AC48D41D33",
            "OpenDKIM Filter v2.11.0 smtp3.osuosl.org 862C961452"
        ],
        "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 smtp3.osuosl.org 862C961452",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1749490548;\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=gJkt/G85DVZXUzDTQeR5YO1yYBwxweptgceK1lAQ1BU=;\n b=FemQ7vuDRE/3BQWBpet/SrA4zJWkN5oN1QiRjKEEHZnZe1CkBESKHqQYWbRi3RosiKGlBr\n 0/eo7QYqBOJGV58q5TLmsPLRgQk0oou21IjtSwAsuOWvvR8S41WNO8S+Qv6slcJm+d/s1p\n 4VqH1S7Pimj2LDFhrlBcbP7/rwFqyEs=",
        "X-MC-Unique": "hrJ7oAioPIOJD9QDGPw9XA-1",
        "X-Mimecast-MFC-AGG-ID": "hrJ7oAioPIOJD9QDGPw9XA_1749490546",
        "To": "dev@openvswitch.org",
        "Date": "Mon,  9 Jun 2025 13:35:26 -0400",
        "Message-ID": "<20250609173539.1636916-8-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": "ddFKmAkthfiqkUilbtWEIbi1MKkDTshXSQMzkq5fKQE_1749490546",
        "X-Mimecast-Originator": "redhat.com",
        "Subject": "[ovs-dev] [PATCH ovn 07/14] en-lflow-sync: Separate syncing from\n datapaths and from the lflow table.",
        "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": "lflow_table_sync_to_sb() synced southbound logical flows based on two\ncriteria:\n* Is the southbound logical flow's datapath or datapath group valid?\n* Is there a matching flow in the lflow_table?\n\nUpcoming commits will allow for multiple lflow_tables to be synced, so\nthe syncing based on datapaths only needs to happen once. Moving this\nsyncing to its own function allows us to avoid redundant processing of\nlogical flows we already know have valid datapath information.\n\nSigned-off-by: Mark Michelson <mmichels@redhat.com>\n---\n northd/en-datapath-logical-router.c | 15 ++++++\n northd/en-datapath-logical-router.h |  5 ++\n northd/en-datapath-logical-switch.c | 15 ++++++\n northd/en-datapath-logical-switch.h |  5 ++\n northd/en-lflow.c                   | 73 +++++++++++++++++++++++++++++\n northd/inc-proc-northd.c            |  4 ++\n northd/lflow-mgr.c                  | 56 ++++++++++------------\n 7 files changed, 143 insertions(+), 30 deletions(-)",
    "diff": "diff --git a/northd/en-datapath-logical-router.c b/northd/en-datapath-logical-router.c\nindex 1c70b32de..b8ec7073e 100644\n--- a/northd/en-datapath-logical-router.c\n+++ b/northd/en-datapath-logical-router.c\n@@ -172,3 +172,18 @@ void en_datapath_synced_logical_router_cleanup(void *data)\n     struct ovn_synced_logical_router_map *router_map = data;\n     synced_logical_router_map_destroy(router_map);\n }\n+\n+const struct ovn_synced_logical_router *\n+ovn_synced_logical_router_find(const struct ovn_synced_logical_router_map *map,\n+                               const struct uuid *nb_uuid)\n+{\n+    uint32_t hash = uuid_hash(nb_uuid);\n+    const struct ovn_synced_logical_router *router;\n+    HMAP_FOR_EACH_WITH_HASH (router, hmap_node, hash, &map->synced_routers) {\n+        if (uuid_equals(&router->nb->header_.uuid, nb_uuid)) {\n+            return router;\n+        }\n+    }\n+\n+    return NULL;\n+}\ndiff --git a/northd/en-datapath-logical-router.h b/northd/en-datapath-logical-router.h\nindex 587de8393..eb0923f9c 100644\n--- a/northd/en-datapath-logical-router.h\n+++ b/northd/en-datapath-logical-router.h\n@@ -46,4 +46,9 @@ enum engine_node_state en_datapath_synced_logical_router_run(\n \n void en_datapath_synced_logical_router_cleanup(void *data);\n \n+struct uuid;\n+const struct ovn_synced_logical_router *\n+ovn_synced_logical_router_find(const struct ovn_synced_logical_router_map *map,\n+                               const struct uuid *nb_uuid);\n+\n #endif /* EN_DATAPATH_LOGICAL_ROUTER_H */\ndiff --git a/northd/en-datapath-logical-switch.c b/northd/en-datapath-logical-switch.c\nindex b667db4db..6dd2adf3c 100644\n--- a/northd/en-datapath-logical-switch.c\n+++ b/northd/en-datapath-logical-switch.c\n@@ -170,3 +170,18 @@ void en_datapath_synced_logical_switch_cleanup(void *data)\n     struct ovn_synced_logical_switch_map *switch_map = data;\n     synced_logical_switch_map_destroy(switch_map);\n }\n+\n+const struct ovn_synced_logical_switch *\n+ovn_synced_logical_switch_find(const struct ovn_synced_logical_switch_map *map,\n+                               const struct uuid *nb_uuid)\n+{\n+    uint32_t hash = uuid_hash(nb_uuid);\n+    const struct ovn_synced_logical_switch *ls;\n+    HMAP_FOR_EACH_WITH_HASH (ls, hmap_node, hash, &map->synced_switches) {\n+        if (uuid_equals(&ls->nb->header_.uuid, nb_uuid)) {\n+            return ls;\n+        }\n+    }\n+\n+    return NULL;\n+}\ndiff --git a/northd/en-datapath-logical-switch.h b/northd/en-datapath-logical-switch.h\nindex 1190b7be8..3f00b9996 100644\n--- a/northd/en-datapath-logical-switch.h\n+++ b/northd/en-datapath-logical-switch.h\n@@ -45,4 +45,9 @@ enum engine_node_state en_datapath_synced_logical_switch_run(\n     struct engine_node *, void *data);\n void en_datapath_synced_logical_switch_cleanup(void *data);\n \n+struct uuid;\n+const struct ovn_synced_logical_switch *\n+ovn_synced_logical_switch_find(const struct ovn_synced_logical_switch_map *map,\n+                               const struct uuid *nb_uuid);\n+\n #endif /* EN_DATAPATH_LOGICAL_SWITCH_H */\ndiff --git a/northd/en-lflow.c b/northd/en-lflow.c\nindex 4992f7ea5..aa92755cc 100644\n--- a/northd/en-lflow.c\n+++ b/northd/en-lflow.c\n@@ -29,6 +29,8 @@\n #include \"en-sampling-app.h\"\n #include \"en-group-ecmp-route.h\"\n #include \"lflow-mgr.h\"\n+#include \"en-datapath-logical-switch.h\"\n+#include \"en-datapath-logical-router.h\"\n \n #include \"lib/inc-proc-eng.h\"\n #include \"northd.h\"\n@@ -348,6 +350,71 @@ void en_lflow_clear_tracked_data(void *data_)\n     data->handled_incrementally = true;\n }\n \n+static bool\n+datapath_is_valid(const struct sbrec_datapath_binding *dp,\n+                  const struct ovn_synced_logical_switch_map *synced_lses,\n+                  const struct ovn_synced_logical_router_map *synced_lrs)\n+{\n+    enum ovn_datapath_type dp_type = ovn_datapath_type_from_string(dp->type);\n+    if (dp_type == DP_MAX) {\n+        return false;\n+    }\n+    struct uuid nb_dp_key;\n+    if (!smap_get_uuid(&dp->external_ids, \"nb_uuid\", &nb_dp_key)) {\n+        return false;\n+    }\n+    if (dp_type == DP_SWITCH) {\n+        if (ovn_synced_logical_switch_find(synced_lses, &nb_dp_key)) {\n+            return true;\n+        } else {\n+            return false;\n+        }\n+    } else if (dp_type == DP_ROUTER) {\n+        if (ovn_synced_logical_router_find(synced_lrs, &nb_dp_key)) {\n+            return true;\n+        } else {\n+            return false;\n+        }\n+    }\n+\n+    return false;\n+}\n+\n+static void\n+sb_lflows_sync_for_datapaths(\n+    const struct ovn_synced_logical_switch_map *switches,\n+    const struct ovn_synced_logical_router_map *routers,\n+    struct sb_lflows *sb_lflows)\n+{\n+    struct sb_lflow *sb_lflow;\n+    HMAP_FOR_EACH_SAFE (sb_lflow, hmap_node, &sb_lflows->valid) {\n+        struct sbrec_datapath_binding *dp = sb_lflow->flow->logical_datapath;\n+        if (dp) {\n+            if (!datapath_is_valid(dp, switches, routers)) {\n+                hmap_remove(&sb_lflows->valid, &sb_lflow->hmap_node);\n+                hmap_insert(&sb_lflows->to_delete, &sb_lflow->hmap_node,\n+                            hmap_node_hash(&sb_lflow->hmap_node));\n+            }\n+        } else if (sb_lflow->flow->logical_dp_group) {\n+            const struct sbrec_logical_dp_group *dp_group;\n+            dp_group = sb_lflow->flow->logical_dp_group;\n+            for (size_t i = 0; i < dp_group->n_datapaths; i++) {\n+                dp = dp_group->datapaths[i];\n+                if (datapath_is_valid(dp, switches, routers)) {\n+                    break;\n+                }\n+                dp = NULL;\n+            }\n+\n+        }\n+        if (!dp) {\n+            hmap_remove(&sb_lflows->valid, &sb_lflow->hmap_node);\n+            hmap_insert(&sb_lflows->to_delete, &sb_lflow->hmap_node,\n+                        hmap_node_hash(&sb_lflow->hmap_node));\n+        }\n+    }\n+}\n+\n static void\n lflow_sync_data_init(struct lflow_sync_data *lflow_sync,\n                      const struct sbrec_logical_flow_table *sb_lflow_table)\n@@ -391,6 +458,10 @@ en_lflow_sync_run(struct engine_node *node, void *data)\n {\n     const struct sbrec_logical_flow_table *sb_lflow_table =\n         EN_OVSDB_GET(engine_get_input(\"SB_logical_flow\", 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_router_map *synced_lrs =\n+        engine_get_input_data(\"datapath_synced_logical_router\", node);\n     /* XXX The lflow table is currently not treated as const because it\n      * contains mutable logical datapath groups. A future commit will\n      * separate the dp groups from the lflow_table so that this can be\n@@ -412,6 +483,8 @@ en_lflow_sync_run(struct engine_node *node, void *data)\n \n     stopwatch_start(LFLOWS_TO_SB_STOPWATCH_NAME, time_msec());\n \n+    sb_lflows_sync_for_datapaths(synced_lses, synced_lrs,\n+                                 &lflow_sync->sb_lflows);\n     lflow_table_sync_to_sb(lflow_data->lflow_table, eng_ctx->ovnsb_idl_txn,\n                            &northd->ls_datapaths,\n                            &northd->lr_datapaths,\ndiff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c\nindex 18b0ba9a5..3e6ff47b9 100644\n--- a/northd/inc-proc-northd.c\n+++ b/northd/inc-proc-northd.c\n@@ -447,6 +447,10 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,\n     engine_add_input(&en_lflow, &en_sb_acl_id, NULL);\n \n     engine_add_input(&en_lflow_sync, &en_sb_logical_flow, NULL);\n+    engine_add_input(&en_lflow_sync, &en_datapath_synced_logical_router,\n+                     engine_noop_handler);\n+    engine_add_input(&en_lflow_sync, &en_datapath_synced_logical_switch,\n+                     engine_noop_handler);\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);\ndiff --git a/northd/lflow-mgr.c b/northd/lflow-mgr.c\nindex 5973179b2..a4f061b1f 100644\n--- a/northd/lflow-mgr.c\n+++ b/northd/lflow-mgr.c\n@@ -249,6 +249,26 @@ lflow_table_set_size(struct lflow_table *lflow_table, size_t size)\n     lflow_table->entries.n = size;\n }\n \n+static enum ovn_datapath_type\n+datapath_type_from_sb_lflow(const struct sbrec_logical_flow *sb_lflow)\n+{\n+    const char *dp_type_str = NULL;\n+    if (sb_lflow->logical_datapath) {\n+        dp_type_str = sb_lflow->logical_datapath->type;\n+    } else if (sb_lflow->logical_dp_group) {\n+        /* All datapaths in a dp_group are of the same type, so just use the\n+         * first datapath in the group to determine the type.\n+         */\n+        dp_type_str = sb_lflow->logical_dp_group->datapaths[0]->type;\n+    }\n+\n+    if (!dp_type_str) {\n+        return DP_MAX;\n+    }\n+\n+    return ovn_datapath_type_from_string(dp_type_str);\n+}\n+\n void\n lflow_table_sync_to_sb(struct lflow_table *lflow_table,\n                        struct ovsdb_idl_txn *ovnsb_txn,\n@@ -269,41 +289,17 @@ lflow_table_sync_to_sb(struct lflow_table *lflow_table,\n     struct sb_lflow *sb_lflow;\n     HMAP_FOR_EACH (sb_lflow, hmap_node, &sb_lflows->valid) {\n         const struct sbrec_logical_flow *sbflow = sb_lflow->flow;\n-        struct sbrec_logical_dp_group *dp_group = sbflow->logical_dp_group;\n-        struct ovn_datapath *logical_datapath_od = NULL;\n-        size_t i;\n-\n-        /* Find one valid datapath to get the datapath type. */\n-        struct sbrec_datapath_binding *dp = sbflow->logical_datapath;\n-        if (dp) {\n-            logical_datapath_od = ovn_datapath_from_sbrec(\n-                &ls_datapaths->datapaths, &lr_datapaths->datapaths, dp);\n-            if (logical_datapath_od\n-                && ovn_datapath_is_stale(logical_datapath_od)) {\n-                logical_datapath_od = NULL;\n-            }\n-        }\n-        for (i = 0; dp_group && i < dp_group->n_datapaths; i++) {\n-            logical_datapath_od = ovn_datapath_from_sbrec(\n-                &ls_datapaths->datapaths, &lr_datapaths->datapaths,\n-                dp_group->datapaths[i]);\n-            if (logical_datapath_od\n-                && !ovn_datapath_is_stale(logical_datapath_od)) {\n-                break;\n-            }\n-            logical_datapath_od = NULL;\n-        }\n-\n-        if (!logical_datapath_od) {\n-            /* This lflow has no valid logical datapaths. */\n-            continue;\n-        }\n \n         enum ovn_pipeline pipeline\n             = !strcmp(sbflow->pipeline, \"ingress\") ? P_IN : P_OUT;\n \n         enum ovn_datapath_type dp_type\n-            = ovn_datapath_get_type(logical_datapath_od);\n+            = datapath_type_from_sb_lflow(sbflow);\n+\n+        /* Since we should have weeded out sb_lflows with invalid\n+         * datapaths, we should only get valid datapath types here.\n+         */\n+        ovs_assert(dp_type < DP_MAX);\n \n         lflow = ovn_lflow_find(\n             lflows,\n",
    "prefixes": [
        "ovs-dev",
        "07/14"
    ]
}