get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 1306578,
    "url": "http://patchwork.ozlabs.org/api/patches/1306578/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/openvswitch/patch/20200610061835.1981621-1-numans@ovn.org/",
    "project": {
        "id": 47,
        "url": "http://patchwork.ozlabs.org/api/projects/47/?format=api",
        "name": "Open vSwitch",
        "link_name": "openvswitch",
        "list_id": "ovs-dev.openvswitch.org",
        "list_email": "ovs-dev@openvswitch.org",
        "web_url": "http://openvswitch.org/",
        "scm_url": "git@github.com:openvswitch/ovs.git",
        "webscm_url": "https://github.com/openvswitch/ovs",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20200610061835.1981621-1-numans@ovn.org>",
    "list_archive_url": null,
    "date": "2020-06-10T06:18:35",
    "name": "[ovs-dev,ovn,v11,4/6] ovn-controller: Use the tracked runtime data changes for flow calculation.",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "4ad0369203fc44276417e4db215bb3d44404474d",
    "submitter": {
        "id": 77669,
        "url": "http://patchwork.ozlabs.org/api/people/77669/?format=api",
        "name": "Numan Siddique",
        "email": "numans@ovn.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/openvswitch/patch/20200610061835.1981621-1-numans@ovn.org/mbox/",
    "series": [
        {
            "id": 182423,
            "url": "http://patchwork.ozlabs.org/api/series/182423/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/openvswitch/list/?series=182423",
            "date": "2020-06-10T06:17:26",
            "name": "Incremental processing improvements.",
            "version": 11,
            "mbox": "http://patchwork.ozlabs.org/series/182423/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/1306578/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/1306578/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@bilbo.ozlabs.org",
            "ovs-dev@lists.linuxfoundation.org"
        ],
        "Authentication-Results": [
            "ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=140.211.166.133; helo=hemlock.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN>)",
            "ozlabs.org;\n dmarc=none (p=none dis=none) header.from=ovn.org"
        ],
        "Received": [
            "from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 49hcJV2QYNz9sRh\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 10 Jun 2020 16:19:06 +1000 (AEST)",
            "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id D1C3688A74;\n\tWed, 10 Jun 2020 06:19:04 +0000 (UTC)",
            "from hemlock.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id 88XbUr8mpVIo; Wed, 10 Jun 2020 06:19:02 +0000 (UTC)",
            "from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id 27654889E8;\n\tWed, 10 Jun 2020 06:19:02 +0000 (UTC)",
            "from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id EAB28C016F;\n\tWed, 10 Jun 2020 06:19:01 +0000 (UTC)",
            "from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 05BFBC088C\n for <dev@openvswitch.org>; Wed, 10 Jun 2020 06:19:00 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n by silver.osuosl.org (Postfix) with ESMTP id E935E24C5E\n for <dev@openvswitch.org>; Wed, 10 Jun 2020 06:18:59 +0000 (UTC)",
            "from silver.osuosl.org ([127.0.0.1])\n by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n with ESMTP id SwHF9sc+5Sdn for <dev@openvswitch.org>;\n Wed, 10 Jun 2020 06:18:50 +0000 (UTC)",
            "from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net\n [217.70.183.195])\n by silver.osuosl.org (Postfix) with ESMTPS id 40E8524F13\n for <dev@openvswitch.org>; Wed, 10 Jun 2020 06:18:46 +0000 (UTC)",
            "from nusiddiq.home.org.com (unknown [115.99.171.40])\n (Authenticated sender: numans@ovn.org)\n by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id C07476000B;\n Wed, 10 Jun 2020 06:18:41 +0000 (UTC)"
        ],
        "X-Virus-Scanned": [
            "amavisd-new at osuosl.org",
            "amavisd-new at osuosl.org"
        ],
        "X-Greylist": "domain auto-whitelisted by SQLgrey-1.7.6",
        "X-Originating-IP": "115.99.171.40",
        "From": "numans@ovn.org",
        "To": "dev@openvswitch.org",
        "Date": "Wed, 10 Jun 2020 11:48:35 +0530",
        "Message-Id": "<20200610061835.1981621-1-numans@ovn.org>",
        "X-Mailer": "git-send-email 2.26.2",
        "In-Reply-To": "<20200610061726.1937231-1-numans@ovn.org>",
        "References": "<20200610061726.1937231-1-numans@ovn.org>",
        "MIME-Version": "1.0",
        "Cc": "Venkata Anil <anilvenkata@redhat.com>",
        "Subject": "[ovs-dev] [PATCH ovn v11 4/6] ovn-controller: Use the tracked\n\truntime data changes for flow calculation.",
        "X-BeenThere": "ovs-dev@openvswitch.org",
        "X-Mailman-Version": "2.1.15",
        "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>",
        "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": "From: Venkata Anil <anilvenkata@redhat.com>\n\nThis patch processes the logical flows of tracked datapaths\nand tracked logical ports. To handle the tracked logical port\nchanges, reference of logical flows to port bindings is maintained.\n\nCo-Authored-by: Numan Siddique <numans@ovn.org>\nSigned-off-by: Venkata Anil <anilvenkata@redhat.com>\nSigned-off-by: Numan Siddique <numans@ovn.org>\n---\n controller/lflow.c          |  86 +++++++++++++++++++++++++++++\n controller/lflow.h          |  12 +++-\n controller/ovn-controller.c | 107 ++++++++++++++++++------------------\n tests/ovn-performance.at    |  12 ++--\n 4 files changed, 156 insertions(+), 61 deletions(-)",
    "diff": "diff --git a/controller/lflow.c b/controller/lflow.c\nindex 01214a3a6..eb6be0100 100644\n--- a/controller/lflow.c\n+++ b/controller/lflow.c\n@@ -59,6 +59,10 @@ struct condition_aux {\n     struct ovsdb_idl_index *sbrec_port_binding_by_name;\n     const struct sbrec_chassis *chassis;\n     const struct sset *active_tunnels;\n+    const struct sbrec_logical_flow *lflow;\n+    /* Resource reference to store the port name referenced\n+     * in is_chassis_resident() to lhe logicl flow. */\n+    struct lflow_resource_ref *lfrr;\n };\n \n static bool\n@@ -68,6 +72,8 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow,\n                       struct controller_event_options *controller_event_opts,\n                       struct lflow_ctx_in *l_ctx_in,\n                       struct lflow_ctx_out *l_ctx_out);\n+static void lflow_resource_add(struct lflow_resource_ref *, enum ref_type,\n+                               const char *ref_name, const struct uuid *);\n \n static bool\n lookup_port_cb(const void *aux_, const char *port_name, unsigned int *portp)\n@@ -120,6 +126,14 @@ is_chassis_resident_cb(const void *c_aux_, const char *port_name)\n     if (!pb) {\n         return false;\n     }\n+\n+    /* Store the port_name to lflow reference. */\n+    int64_t dp_id = pb->datapath->tunnel_key;\n+    char buf[16];\n+    snprintf(buf, sizeof(buf), \"%\"PRId64\"_%\"PRId64, dp_id, pb->tunnel_key);\n+    lflow_resource_add(c_aux->lfrr, REF_TYPE_PORTBINDING, buf,\n+                       &c_aux->lflow->header_.uuid);\n+\n     if (strcmp(pb->type, \"chassisredirect\")) {\n         /* for non-chassisredirect ports */\n         return pb->chassis && pb->chassis == c_aux->chassis;\n@@ -594,6 +608,8 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow,\n         .sbrec_port_binding_by_name = l_ctx_in->sbrec_port_binding_by_name,\n         .chassis = l_ctx_in->chassis,\n         .active_tunnels = l_ctx_in->active_tunnels,\n+        .lflow = lflow,\n+        .lfrr = l_ctx_out->lfrr\n     };\n     expr = expr_simplify(expr, is_chassis_resident_cb, &cond_aux);\n     expr = expr_normalize(expr);\n@@ -649,6 +665,8 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow,\n                 int64_t dp_id = lflow->logical_datapath->tunnel_key;\n                 char buf[16];\n                 snprintf(buf, sizeof(buf), \"%\"PRId64\"_%\"PRId64, dp_id, port_id);\n+                lflow_resource_add(l_ctx_out->lfrr, REF_TYPE_PORTBINDING, buf,\n+                                   &lflow->header_.uuid);\n                 if (!sset_contains(l_ctx_in->local_lport_ids, buf)) {\n                     VLOG_DBG(\"lflow \"UUID_FMT\n                              \" port %s in match is not local, skip\",\n@@ -847,3 +865,71 @@ lflow_destroy(void)\n     expr_symtab_destroy(&symtab);\n     shash_destroy(&symtab);\n }\n+\n+bool\n+lflow_add_flows_for_datapath(const struct sbrec_datapath_binding *dp,\n+                             struct lflow_ctx_in *l_ctx_in,\n+                             struct lflow_ctx_out *l_ctx_out)\n+{\n+    bool handled = true;\n+    struct hmap dhcp_opts = HMAP_INITIALIZER(&dhcp_opts);\n+    struct hmap dhcpv6_opts = HMAP_INITIALIZER(&dhcpv6_opts);\n+    const struct sbrec_dhcp_options *dhcp_opt_row;\n+    SBREC_DHCP_OPTIONS_TABLE_FOR_EACH (dhcp_opt_row,\n+                                       l_ctx_in->dhcp_options_table) {\n+        dhcp_opt_add(&dhcp_opts, dhcp_opt_row->name, dhcp_opt_row->code,\n+                     dhcp_opt_row->type);\n+    }\n+\n+\n+    const struct sbrec_dhcpv6_options *dhcpv6_opt_row;\n+    SBREC_DHCPV6_OPTIONS_TABLE_FOR_EACH (dhcpv6_opt_row,\n+                                         l_ctx_in->dhcpv6_options_table) {\n+       dhcp_opt_add(&dhcpv6_opts, dhcpv6_opt_row->name, dhcpv6_opt_row->code,\n+                    dhcpv6_opt_row->type);\n+    }\n+\n+    struct hmap nd_ra_opts = HMAP_INITIALIZER(&nd_ra_opts);\n+    nd_ra_opts_init(&nd_ra_opts);\n+\n+    struct controller_event_options controller_event_opts;\n+    controller_event_opts_init(&controller_event_opts);\n+\n+    struct sbrec_logical_flow *lf_row = sbrec_logical_flow_index_init_row(\n+        l_ctx_in->sbrec_logical_flow_by_logical_datapath);\n+    sbrec_logical_flow_index_set_logical_datapath(lf_row, dp);\n+\n+    const struct sbrec_logical_flow *lflow;\n+    SBREC_LOGICAL_FLOW_FOR_EACH_EQUAL (\n+        lflow, lf_row, l_ctx_in->sbrec_logical_flow_by_logical_datapath) {\n+        /* Remove the lflow from flow_table if present before processing it. */\n+        ofctrl_remove_flows(l_ctx_out->flow_table, &lflow->header_.uuid);\n+\n+        if (!consider_logical_flow(lflow, &dhcp_opts, &dhcpv6_opts,\n+                                   &nd_ra_opts, &controller_event_opts,\n+                                   l_ctx_in, l_ctx_out)) {\n+            handled = false;\n+            break;\n+        }\n+    }\n+\n+    dhcp_opts_destroy(&dhcp_opts);\n+    dhcp_opts_destroy(&dhcpv6_opts);\n+    nd_ra_opts_destroy(&nd_ra_opts);\n+    controller_event_opts_destroy(&controller_event_opts);\n+    return handled;\n+}\n+\n+bool\n+lflow_handle_flows_for_lport(const struct sbrec_port_binding *pb,\n+                             struct lflow_ctx_in *l_ctx_in,\n+                             struct lflow_ctx_out *l_ctx_out)\n+{\n+    int64_t dp_id = pb->datapath->tunnel_key;\n+    char pb_ref_name[16];\n+    snprintf(pb_ref_name, sizeof(pb_ref_name), \"%\"PRId64\"_%\"PRId64,\n+             dp_id, pb->tunnel_key);\n+    bool changed = true;\n+    return lflow_handle_changed_ref(REF_TYPE_PORTBINDING, pb_ref_name,\n+                                    l_ctx_in, l_ctx_out, &changed);\n+}\ndiff --git a/controller/lflow.h b/controller/lflow.h\nindex f02f709d7..ae02eaf5e 100644\n--- a/controller/lflow.h\n+++ b/controller/lflow.h\n@@ -48,6 +48,8 @@ struct sbrec_dhcp_options_table;\n struct sbrec_dhcpv6_options_table;\n struct sbrec_logical_flow_table;\n struct sbrec_mac_binding_table;\n+struct sbrec_datapath_binding;\n+struct sbrec_port_binding;\n struct simap;\n struct sset;\n struct uuid;\n@@ -72,7 +74,8 @@ struct uuid;\n \n enum ref_type {\n     REF_TYPE_ADDRSET,\n-    REF_TYPE_PORTGROUP\n+    REF_TYPE_PORTGROUP,\n+    REF_TYPE_PORTBINDING\n };\n \n /* Maintains the relationship for a pair of named resource and\n@@ -117,6 +120,7 @@ void lflow_resource_clear(struct lflow_resource_ref *);\n \n struct lflow_ctx_in {\n     struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath;\n+    struct ovsdb_idl_index *sbrec_logical_flow_by_logical_datapath;\n     struct ovsdb_idl_index *sbrec_port_binding_by_name;\n     const struct sbrec_dhcp_options_table *dhcp_options_table;\n     const struct sbrec_dhcpv6_options_table *dhcpv6_options_table;\n@@ -157,4 +161,10 @@ void lflow_destroy(void);\n \n void lflow_expr_destroy(struct hmap *lflow_expr_cache);\n \n+bool lflow_add_flows_for_datapath(const struct sbrec_datapath_binding *,\n+                                  struct lflow_ctx_in *,\n+                                  struct lflow_ctx_out *);\n+bool lflow_handle_flows_for_lport(const struct sbrec_port_binding *,\n+                                  struct lflow_ctx_in *,\n+                                  struct lflow_ctx_out *);\n #endif /* controller/lflow.h */\ndiff --git a/controller/ovn-controller.c b/controller/ovn-controller.c\nindex 9987ee601..7f0c80877 100644\n--- a/controller/ovn-controller.c\n+++ b/controller/ovn-controller.c\n@@ -1505,6 +1505,11 @@ static void init_lflow_ctx(struct engine_node *node,\n                 engine_get_input(\"SB_port_binding\", node),\n                 \"name\");\n \n+    struct ovsdb_idl_index *sbrec_logical_flow_by_dp =\n+        engine_ovsdb_node_get_index(\n+                engine_get_input(\"SB_logical_flow\", node),\n+                \"logical_datapath\");\n+\n     struct ovsdb_idl_index *sbrec_mc_group_by_name_dp =\n         engine_ovsdb_node_get_index(\n                 engine_get_input(\"SB_multicast_group\", node),\n@@ -1552,6 +1557,8 @@ static void init_lflow_ctx(struct engine_node *node,\n \n     l_ctx_in->sbrec_multicast_group_by_name_datapath =\n         sbrec_mc_group_by_name_dp;\n+    l_ctx_in->sbrec_logical_flow_by_logical_datapath =\n+        sbrec_logical_flow_by_dp;\n     l_ctx_in->sbrec_port_binding_by_name = sbrec_port_binding_by_name;\n     l_ctx_in->dhcp_options_table  = dhcp_table;\n     l_ctx_in->dhcpv6_options_table = dhcpv6_table;\n@@ -1706,7 +1713,8 @@ flow_output_sb_mac_binding_handler(struct engine_node *node, void *data)\n }\n \n static bool\n-flow_output_sb_port_binding_handler(struct engine_node *node, void *data)\n+flow_output_sb_port_binding_handler(struct engine_node *node,\n+                                    void *data)\n {\n     struct ed_type_runtime_data *rt_data =\n         engine_get_input_data(\"runtime_data\", node);\n@@ -1714,56 +1722,13 @@ flow_output_sb_port_binding_handler(struct engine_node *node, void *data)\n     struct ed_type_flow_output *fo = data;\n     struct ovn_desired_flow_table *flow_table = &fo->flow_table;\n \n-    /* XXX: now we handle port-binding changes for physical flow processing\n-     * only, but port-binding change can have impact to logical flow\n-     * processing, too, in below circumstances:\n-     *\n-     *  - When a port-binding for a lport is inserted/deleted but the lflow\n-     *    using that lport doesn't change.\n-     *\n-     *    This can happen only when the lport name is used by ACL match\n-     *    condition, which is specified by user. Even in that case, if the port\n-     *    is actually bound on the current chassis it will trigger recompute on\n-     *    that chassis since ovs interface would be updated. So the only\n-     *    situation this would have real impact is when user defines an ACL\n-     *    that includes lport that is not on current chassis, and there is a\n-     *    port-binding creation/deletion related to that lport.e.g.: an ACL is\n-     *    defined:\n-     *\n-     *    to-lport 1000 'outport==\"A\" && inport==\"B\"' allow-related\n-     *\n-     *    If \"A\" is on current chassis, but \"B\" is lport that hasn't been\n-     *    created yet. When a lport \"B\" is created and bound on another\n-     *    chassis, the ACL will not take effect on the current chassis until a\n-     *    recompute is triggered later. This case doesn't seem to be a problem\n-     *    for real world use cases because usually lport is created before\n-     *    being referenced by name in ACLs.\n-     *\n-     *  - When is_chassis_resident(<lport>) is used in lflow. In this case the\n-     *    port binding is not a regular VIF. It can be either \"patch\" or\n-     *    \"external\", with ha-chassis-group assigned.  In current\n-     *    \"runtime_data\" handling, port-binding changes for these types always\n-     *    trigger recomputing. So it is fine even if we do not handle it here.\n-     *    (due to the ovsdb tracking support for referenced table changes,\n-     *    ha-chassis-group changes will appear as port-binding change).\n-     *\n-     *  - When a mac-binding doesn't change but the port-binding related to\n-     *    that mac-binding is deleted. In this case the neighbor flow generated\n-     *    for the mac-binding should be deleted. This would not cause any real\n-     *    issue for now, since the port-binding related to mac-binding is\n-     *    always logical router port, and any change to logical router port\n-     *    would just trigger recompute.\n-     *\n-     * Although there is no correctness issue so far (except the unusual ACL\n-     * use case, which doesn't seem to be a real problem), it might be better\n-     * to handle this more gracefully, without the need to consider these\n-     * tricky scenarios.  One approach is to maintain a mapping between lport\n-     * names and the lflows that uses them, and reprocess the related lflows\n-     * when related port-bindings change.\n-     */\n     struct physical_ctx p_ctx;\n     init_physical_ctx(node, rt_data, &p_ctx);\n \n+    /* We handle port-binding changes for physical flow processing\n+     * only. flow_output runtime data handler takes care of processing\n+     * logical flows for any port binding changes.\n+     */\n     physical_handle_port_binding_changes(&p_ctx, flow_table);\n \n     engine_set_node_state(node, EN_UPDATED);\n@@ -1851,6 +1816,9 @@ _flow_output_resource_ref_handler(struct engine_node *node, void *data,\n             updated = &pg_data->updated;\n             deleted = &pg_data->deleted;\n             break;\n+\n+        /* This ref type is handled in the flow_output_runtime_data_handler. */\n+        case REF_TYPE_PORTBINDING:\n         default:\n             OVS_NOT_REACHED();\n     }\n@@ -1912,16 +1880,42 @@ flow_output_runtime_data_handler(struct engine_node *node,\n         return false;\n     }\n \n-    if (!hmap_is_empty(&rt_data->tracked_dp_bindings)) {\n-        /* We are not yet handling the tracked datapath binding\n-         * changes. Return false to trigger full recompute. */\n-        return false;\n+    struct hmap *tracked_dp_bindings = &rt_data->tracked_dp_bindings;\n+    if (hmap_is_empty(tracked_dp_bindings)) {\n+        if (rt_data->local_lports_changed) {\n+            engine_set_node_state(node, EN_UPDATED);\n+        }\n+        return true;\n     }\n \n-    if (rt_data->local_lports_changed) {\n-        engine_set_node_state(node, EN_UPDATED);\n+    struct lflow_ctx_in l_ctx_in;\n+    struct lflow_ctx_out l_ctx_out;\n+    struct ed_type_flow_output *fo = data;\n+    init_lflow_ctx(node, rt_data, fo, &l_ctx_in, &l_ctx_out);\n+\n+    struct physical_ctx p_ctx;\n+    init_physical_ctx(node, rt_data, &p_ctx);\n+\n+    struct tracked_binding_datapath *tdp;\n+    HMAP_FOR_EACH (tdp, node, tracked_dp_bindings) {\n+        if (tdp->is_new) {\n+            if (!lflow_add_flows_for_datapath(tdp->dp, &l_ctx_in,\n+                                              &l_ctx_out)) {\n+                return false;\n+            }\n+        } else {\n+            struct shash_node *shash_node;\n+            SHASH_FOR_EACH (shash_node, &tdp->lports) {\n+                struct tracked_binding_lport *lport = shash_node->data;\n+                if (!lflow_handle_flows_for_lport(lport->pb, &l_ctx_in,\n+                                                  &l_ctx_out)) {\n+                    return false;\n+                }\n+            }\n+        }\n     }\n \n+    engine_set_node_state(node, EN_UPDATED);\n     return true;\n }\n \n@@ -2092,6 +2086,9 @@ main(int argc, char *argv[])\n         = chassis_index_create(ovnsb_idl_loop.idl);\n     struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath\n         = mcast_group_index_create(ovnsb_idl_loop.idl);\n+    struct ovsdb_idl_index *sbrec_logical_flow_by_logical_datapath\n+        = ovsdb_idl_index_create1(ovnsb_idl_loop.idl,\n+                                  &sbrec_logical_flow_col_logical_datapath);\n     struct ovsdb_idl_index *sbrec_port_binding_by_name\n         = ovsdb_idl_index_create1(ovnsb_idl_loop.idl,\n                                   &sbrec_port_binding_col_logical_port);\n@@ -2252,6 +2249,8 @@ main(int argc, char *argv[])\n     engine_ovsdb_node_add_index(&en_sb_chassis, \"name\", sbrec_chassis_by_name);\n     engine_ovsdb_node_add_index(&en_sb_multicast_group, \"name_datapath\",\n                                 sbrec_multicast_group_by_name_datapath);\n+    engine_ovsdb_node_add_index(&en_sb_logical_flow, \"logical_datapath\",\n+                                sbrec_logical_flow_by_logical_datapath);\n     engine_ovsdb_node_add_index(&en_sb_port_binding, \"name\",\n                                 sbrec_port_binding_by_name);\n     engine_ovsdb_node_add_index(&en_sb_port_binding, \"key\",\ndiff --git a/tests/ovn-performance.at b/tests/ovn-performance.at\nindex 08acd3bae..a12757e18 100644\n--- a/tests/ovn-performance.at\n+++ b/tests/ovn-performance.at\n@@ -274,7 +274,7 @@ for i in 1 2; do\n     )\n \n     # Add router port to $ls\n-    OVN_CONTROLLER_EXPECT_HIT(\n+    OVN_CONTROLLER_EXPECT_NO_HIT(\n         [hv1 hv2], [lflow_run],\n         [ovn-nbctl --wait=hv lrp-add lr1 $lrp 02:00:00:00:0$i:01 10.0.$i.1/24]\n     )\n@@ -282,7 +282,7 @@ for i in 1 2; do\n         [hv1 hv2], [lflow_run],\n         [ovn-nbctl --wait=hv lsp-add $ls $lsp]\n     )\n-    OVN_CONTROLLER_EXPECT_HIT(\n+    OVN_CONTROLLER_EXPECT_NO_HIT(\n         [hv1 hv2], [lflow_run],\n         [ovn-nbctl --wait=hv lsp-set-type $lsp router]\n     )\n@@ -353,8 +353,8 @@ for i in 1 2; do\n     )\n \n     # Bind port $lp and wait for it to come up\n-    OVN_CONTROLLER_EXPECT_HIT_COND(\n-        [hv$i hv$j], [lflow_run], [>0 =0],\n+    OVN_CONTROLLER_EXPECT_NO_HIT(\n+        [hv$i hv$j], [lflow_run],\n         [as hv$i ovs-vsctl add-port br-int $vif -- set Interface $vif external-ids:iface-id=$lp &&\n          ovn-nbctl wait-until Logical_Switch_Port $lp 'up=true' &&\n          ovn-nbctl --wait=hv sync]\n@@ -404,8 +404,8 @@ for i in 1 2; do\n     lp=lp$i\n \n     # Delete port $lp\n-    OVN_CONTROLLER_EXPECT_HIT_COND(\n-        [hv$i hv$j], [lflow_run], [>0 =0],\n+    OVN_CONTROLLER_EXPECT_NO_HIT(\n+        [hv$i hv$j], [lflow_run],\n         [ovn-nbctl --wait=hv lsp-del $lp]\n     )\n done\n",
    "prefixes": [
        "ovs-dev",
        "ovn",
        "v11",
        "4/6"
    ]
}