{"id":2228897,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2228897/?format=json","web_url":"http://patchwork.ozlabs.org/project/ovn/patch/171501687c9645e941e2903c2b52876e21bd3d7c.1777295725.git.lorenzo.bianconi@redhat.com/","project":{"id":68,"url":"http://patchwork.ozlabs.org/api/1.1/projects/68/?format=json","name":"Open Virtual Network development","link_name":"ovn","list_id":"ovs-dev.openvswitch.org","list_email":"ovs-dev@openvswitch.org","web_url":"http://openvswitch.org/","scm_url":"","webscm_url":""},"msgid":"<171501687c9645e941e2903c2b52876e21bd3d7c.1777295725.git.lorenzo.bianconi@redhat.com>","date":"2026-04-27T13:19:01","name":"[ovs-dev,v2] northd: Use MC_UNKNOWN for broadcast ARP requests.","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"629afe81c79b53fb3176ca528a80fea9dee68d27","submitter":{"id":73083,"url":"http://patchwork.ozlabs.org/api/1.1/people/73083/?format=json","name":"Lorenzo Bianconi","email":"lorenzo.bianconi@redhat.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/ovn/patch/171501687c9645e941e2903c2b52876e21bd3d7c.1777295725.git.lorenzo.bianconi@redhat.com/mbox/","series":[{"id":501647,"url":"http://patchwork.ozlabs.org/api/1.1/series/501647/?format=json","web_url":"http://patchwork.ozlabs.org/project/ovn/list/?series=501647","date":"2026-04-27T13:19:01","name":"[ovs-dev,v2] northd: Use MC_UNKNOWN for broadcast ARP requests.","version":2,"mbox":"http://patchwork.ozlabs.org/series/501647/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2228897/comments/","check":"success","checks":"http://patchwork.ozlabs.org/api/patches/2228897/checks/","tags":{},"headers":{"Return-Path":"<ovs-dev-bounces@openvswitch.org>","X-Original-To":["incoming@patchwork.ozlabs.org","ovs-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=DJBEhXxj;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=140.211.166.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 unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=DJBEhXxj","smtp1.osuosl.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com","smtp1.osuosl.org; dkim=pass (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=DJBEhXxj"],"Received":["from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.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 4g440c2ff7z1yHX\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 27 Apr 2026 23:19:26 +1000 (AEST)","from localhost (localhost [127.0.0.1])\n\tby smtp3.osuosl.org (Postfix) with ESMTP id 0CEE56F6BA;\n\tMon, 27 Apr 2026 13:19:24 +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 z9SrxIhJsiDa; Mon, 27 Apr 2026 13:19:20 +0000 (UTC)","from lists.linuxfoundation.org (lf-lists.osuosl.org\n [IPv6:2605:bc80:3010:104::8cd3:938])\n\tby smtp3.osuosl.org (Postfix) with ESMTPS id C51566F49A;\n\tMon, 27 Apr 2026 13:19:20 +0000 (UTC)","from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id B59F1C04FB;\n\tMon, 27 Apr 2026 13:19:20 +0000 (UTC)","from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 98855C04FA\n for <ovs-dev@openvswitch.org>; Mon, 27 Apr 2026 13:19:19 +0000 (UTC)","from localhost (localhost [127.0.0.1])\n by smtp1.osuosl.org (Postfix) with ESMTP id 8FF7D8565B\n for <ovs-dev@openvswitch.org>; Mon, 27 Apr 2026 13:19:19 +0000 (UTC)","from smtp1.osuosl.org ([127.0.0.1])\n by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id zzaKuHd-GjMn for <ovs-dev@openvswitch.org>;\n Mon, 27 Apr 2026 13:19:17 +0000 (UTC)","from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by smtp1.osuosl.org (Postfix) with ESMTPS id C70298565A\n for <ovs-dev@openvswitch.org>; Mon, 27 Apr 2026 13:19:15 +0000 (UTC)","from mail-wr1-f69.google.com (mail-wr1-f69.google.com\n [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-348-laevWA1WNLqeATDxqOuULQ-1; Mon, 27 Apr 2026 09:19:12 -0400","by mail-wr1-f69.google.com with SMTP id\n ffacd0b85a97d-4411a2c034fso5957115f8f.3\n for <ovs-dev@openvswitch.org>; Mon, 27 Apr 2026 06:19:12 -0700 (PDT)","from localhost (net-37-119-153-93.cust.vodafonedsl.it.\n [37.119.153.93]) by smtp.gmail.com with ESMTPSA id\n 5b1f17b1804b1-48a6124d7e7sm488946155e9.5.2026.04.27.06.19.05\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Mon, 27 Apr 2026 06:19:06 -0700 (PDT)"],"X-Virus-Scanned":["amavis at osuosl.org","amavis at osuosl.org"],"X-Comment":"SPF check N/A for local connections -\n client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN> ","DKIM-Filter":["OpenDKIM Filter v2.11.0 smtp3.osuosl.org C51566F49A","OpenDKIM Filter v2.11.0 smtp1.osuosl.org C70298565A"],"Received-SPF":"Pass (mailfrom) identity=mailfrom; client-ip=170.10.133.124;\n helo=us-smtp-delivery-124.mimecast.com;\n envelope-from=lorenzo.bianconi@redhat.com; receiver=<UNKNOWN>","DMARC-Filter":"OpenDMARC Filter v1.4.2 smtp1.osuosl.org C70298565A","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1777295954;\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 bh=NFAq1nKjHSHPr0LCbgcG77LkuYndqoLbldh36Hu7NgU=;\n b=DJBEhXxjRJ491qfMNgTXRnAKQSDe5DomXG9bX4iI08HFE8GeUFK5jz46KjMdrhjGMlalxt\n KqI4ncfpAkqeMWPHu/B439Ab1Ub5dCeteJwMhLFi1CtvEvnpEdsDBpnPcv111jP6xNRWp1\n EzhIfjo5x+uw+EQOViZh9tmiZHxrO08=","X-MC-Unique":"laevWA1WNLqeATDxqOuULQ-1","X-Mimecast-MFC-AGG-ID":"laevWA1WNLqeATDxqOuULQ_1777295951","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777295951; x=1777900751;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n :message-id:reply-to;\n bh=NFAq1nKjHSHPr0LCbgcG77LkuYndqoLbldh36Hu7NgU=;\n b=jxWy3xZ1yTxlNb+DAQhHKja3+IU0amRoutAURNmpMXFBRz7rPSsMCtiFTb62xgRTw5\n PxNGzoVG66BwoxxYO5kc3S5vgaNTeL1FdWK7m9wAciI24nL9yquUgiBzIQLOMCNtSjOX\n FVC6U+UPJXjkGVpLt8XAMio1nH4H+TXb7eo0m54kBQ69QGGt5Xk5ECPWbelZ66yovD3r\n 2zd3wmWBblIYI8uuyVQ3kJQWY06sPZh3or0k1HVVytL0Bq31Wko9DGfvKLYQObLuSZWP\n jb8c2ntsyTCZZ9CBkrBDssXGiQOtnSbQ8rRB0FSkfs4rS3Qq8lVYM7a7pZSY68gDEY4G\n hwOw==","X-Gm-Message-State":"AOJu0YyayKyamcXtvde0eKC04fPlQRYy0H3eM2VLd8tiI0GQpcMI2xCC\n 80jGW3rCfb+vqowhpEGJWIouHpYhD0ppXXLAZi5yN4G0iC/f7eWfBgAOExJ7ZEUKrQ6/IWK2Dfr\n 5F76PWqxRNCtnZkEUpsqXqO+PX9dzDAbYW8xnOQZhe2Jv82sEyhehMgh5EP3bLj7VgPI4NL6vZw\n o2IEbCrN03C4EGH1L4QFDhc7/KcZro8thDGD52WxPfjG4Amrw8RYDrqw==","X-Gm-Gg":"AeBDieuojCMc1zGdmyFCrFATPJKQMIROqTSBbXIriv/IvhUsk0bv9Dny52FqUBnh6jG\n z5PVR4MwbksQGdEcypGzRD4ze/Ein5uLMgc5boI0EkoUtUb/N9YLztFo2VNPxL7RSnQRgR3jMfo\n DKwxf93vM4iA2kJynjppnZ81eb9rGrJnxAN1bKz2H4psSGMDv13b8zZX/p3URb6F4dAx6QT+jzt\n twXm6COHjORDOLlcn9uP5+7hmlbVK8d/84e4OsAus1v19Unv2faA895PAeZwVaoPqFYtdh1XU+N\n MvKXPb58pRmLkLr9IL9ZtUXpE3lAsDMy/6ozrQs6kuJWPLBNqhpWjwHx32cT0Dj0zowSiwbpwzu\n K04emEsNInWBpxajZjMEa/0kyjr0Q9WHur76DBsEfVlfw5YiME0d3hMYeaGqbrq36QKUFRcINj2\n dpDcmg","X-Received":["by 2002:a05:600c:548c:b0:48a:568f:ae6b with SMTP id\n 5b1f17b1804b1-48a568fafcbmr351788885e9.7.1777295948827;\n Mon, 27 Apr 2026 06:19:08 -0700 (PDT)","by 2002:a05:600c:548c:b0:48a:568f:ae6b with SMTP id\n 5b1f17b1804b1-48a568fafcbmr351786655e9.7.1777295946592;\n Mon, 27 Apr 2026 06:19:06 -0700 (PDT)"],"To":"ovs-dev@openvswitch.org","Date":"Mon, 27 Apr 2026 15:19:01 +0200","Message-ID":"\n <171501687c9645e941e2903c2b52876e21bd3d7c.1777295725.git.lorenzo.bianconi@redhat.com>","X-Mailer":"git-send-email 2.53.0","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"x_b5cN-hBG1oWqqeC9gFRBEn7zaI-1xBSSs-jfbUErY_1777295951","X-Mimecast-Originator":"redhat.com","Subject":"[ovs-dev] [PATCH v2 ovn] northd: Use MC_UNKNOWN for broadcast ARP\n requests.","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":"Lorenzo Bianconi via dev <ovs-dev@openvswitch.org>","Reply-To":"Lorenzo Bianconi <lorenzo.bianconi@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":"In the OVN logical switch pipeline, broadcast ARP requests (and ND_NS)\ngenerated by VIFs and by router ports are also flooded into the per switch\nMC_FLOOD_L2 multicast group which includes all non-router ports of the\nswitch.\nIn deployments with large logical broadcast domains (logical switches with\na significantly large number of switch ports, e.g. 200+) this becomes a\nproblem because the MC_FLOOD_L2 multicast group has a lot of ports so the\nchain of the OpenFlow tables that the packet needs to traverse for full\nprocessing becomes really long, going over OVS' 4K resubmit limit and\ncausing the packet to be dropped.\nThe main reason why the ARP packets are currently sent to all non-router\nports is to allow the workloads to learn the mapping between arp.spa\n(source IP) and arp.sha (source MAC). However, that's just an optimization,\nwhich might avoid future ARP requests from other workloads; and it's not a\nrequirement, nothing would really break if we didn't forward those packets\nto all other VIFs.\nIt's probably acceptable to change the behavior and just forward these ARP\nrequests to the ports that have LSP.addresses=\"unknown\" as the workloads\nbehind those ports (or the fabric for the localnet case) might actually own\nthe arp.tpa target IP.\n\nReported-at: https://redhat.atlassian.net/browse/FDP-3439\nCo-authored-by: Dumitru Ceara <dceara@redhat.com>\nSigned-off-by: Dumitru Ceara <dceara@redhat.com>\nSigned-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>\n---\nChanges since v1:\n- Add dedicated GARP management\n- Do not skip any unit-test\n---\n northd/northd.c         |  25 +++++-\n northd/ovn-northd.8.xml |  14 ++-\n ovs                     |   2 +-\n tests/ovn-northd.at     | 192 +++++++++++++++++++++++++---------------\n tests/ovn.at            |  38 ++++----\n 5 files changed, 173 insertions(+), 98 deletions(-)","diff":"diff --git a/northd/northd.c b/northd/northd.c\nindex 0b52db6cf..e606365c6 100644\n--- a/northd/northd.c\n+++ b/northd/northd.c\n@@ -9583,6 +9583,7 @@ build_lswitch_rport_arp_req_flow(\n {\n     struct ds match   = DS_EMPTY_INITIALIZER;\n     struct ds m       = DS_EMPTY_INITIALIZER;\n+    struct ds m_garp  = DS_EMPTY_INITIALIZER;\n     struct ds actions = DS_EMPTY_INITIALIZER;\n \n     arp_nd_ns_match(ips, addr_family, &m);\n@@ -9604,16 +9605,27 @@ build_lswitch_rport_arp_req_flow(\n                       patch_op->cr_port->json_key);\n     }\n \n+    if (addr_family == AF_INET) {\n+        ds_clone(&m_garp, &match);\n+        ds_put_format(&m_garp, \" && arp.spa == %s\", ips);\n+    }\n+\n     /* Send a the packet to the router pipeline.  If the switch has non-router\n      * ports then flood it there as well.\n      */\n     if (vector_len(&od->router_ports) != od->nbs->n_ports) {\n         ds_put_format(&actions, \"clone {outport = %s; output; }; \"\n-                                \"outport = \\\"\"MC_FLOOD_L2\"\\\"; output;\",\n+                                \"outport = \\\"\"MC_UNKNOWN\"\\\"; output;\",\n                       patch_op->json_key);\n         ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, priority,\n                       ds_cstr(&match), ds_cstr(&actions), lflow_ref,\n                       WITH_HINT(stage_hint));\n+        if (addr_family == AF_INET) {\n+            ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, priority + 10,\n+                          ds_cstr(&m_garp),\n+                          \"outport = \\\"\"MC_FLOOD_L2\"\\\"; output;\",\n+                          lflow_ref, WITH_HINT(stage_hint));\n+        }\n     } else {\n         ds_put_format(&actions, \"outport = %s; output;\", patch_op->json_key);\n         ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, priority,\n@@ -9628,11 +9640,17 @@ build_lswitch_rport_arp_req_flow(\n         ds_clear(&actions);\n         if (vector_len(&od->router_ports) != od->nbs->n_ports) {\n             ds_put_format(&actions, \"clone {outport = %s; output; }; \"\n-                                    \"outport = \\\"\"MC_FLOOD_L2\"\\\"; output;\",\n+                                    \"outport = \\\"\"MC_UNKNOWN\"\\\"; output;\",\n                           patch_op->cr_port->json_key);\n             ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, priority,\n                           ds_cstr(&match), ds_cstr(&actions), lflow_ref,\n                           WITH_HINT(stage_hint));\n+            if (addr_family == AF_INET) {\n+                ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, priority + 10,\n+                              ds_cstr(&m_garp),\n+                              \"outport = \\\"\"MC_FLOOD_L2\"\\\"; output;\",\n+                              lflow_ref, WITH_HINT(stage_hint));\n+            }\n         } else {\n             ds_put_format(&actions, \"outport = %s; output;\",\n                           patch_op->cr_port->json_key);\n@@ -9644,6 +9662,7 @@ build_lswitch_rport_arp_req_flow(\n \n     ds_destroy(&m);\n     ds_destroy(&match);\n+    ds_destroy(&m_garp);\n     ds_destroy(&actions);\n }\n \n@@ -11061,7 +11080,7 @@ build_lswitch_destination_lookup_bmcast(struct ovn_datapath *od,\n                        \"broadcast-arps-to-all-routers\", true)) {\n         ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, 72,\n                       \"eth.mcast && (arp.op == 1 || nd_ns)\",\n-                      \"outport = \\\"\"MC_FLOOD_L2\"\\\"; output;\",\n+                      \"outport = \\\"\"MC_UNKNOWN\"\\\"; output;\",\n                       lflow_ref);\n     }\n \ndiff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml\nindex 4d6370da6..75c17e75d 100644\n--- a/northd/ovn-northd.8.xml\n+++ b/northd/ovn-northd.8.xml\n@@ -2346,6 +2346,14 @@ output;\n         <ref table=\"IGMP_Group\" db=\"OVN_Southbound\"/> entries.\n       </li>\n \n+      <li>\n+        Priority-95 flows for each IP address/VIP/NAT address owned by a\n+        router port connected to the switch. These flows match GARP packets\n+        for the specific IP addresses. Matched packets are forwarded to the\n+        <code>MC_FLOOD_L2</code> multicast group which contains all non-router\n+        logical ports.\n+      </li>\n+\n       <li>\n         Priority-90 flows that forward registered IP multicast traffic to\n         their corresponding multicast group, which <code>ovn-northd</code>\n@@ -2402,8 +2410,8 @@ output;\n         router port connected to the switch. These flows match ARP requests\n         and ND packets for the specific IP addresses.  Matched packets are\n         forwarded only to the router that owns the IP address and to the\n-        <code>MC_FLOOD_L2</code> multicast group which contains all non-router\n-        logical ports.\n+        <code>MC_UNKNOWN</code> multicast group which contains all enabled\n+        logical ports that accept unknown destination packets.\n       </li>\n \n       <li>\n@@ -2426,7 +2434,7 @@ output;\n       <li>\n         A priority-72 flow that outputs all ARP requests and ND NS (Neighbor\n         Solicitation) packets with an Ethernet broadcast or multicast\n-        <code>eth.dst</code> to the <code>MC_FLOOD_L2</code> multicast group\n+        <code>eth.dst</code> to the <code>MC_UNKNOWN</code> multicast group\n         if <code>other_config:broadcast-arps-to-all-routers=false</code>.\n       </li>\n \ndiff --git a/ovs b/ovs\nindex bdb95cc19..6aefe1db3 160000\n--- a/ovs\n+++ b/ovs\n@@ -1 +1 @@\n-Subproject commit bdb95cc1920d4ab66fe062a9470eeb33a51d33e2\n+Subproject commit 6aefe1db31e3df4e7b64c21f54a7287e4663e1e4\ndiff --git a/tests/ovn-northd.at b/tests/ovn-northd.at\nindex 1d7bd6c28..b66f36691 100644\n--- a/tests/ovn-northd.at\n+++ b/tests/ovn-northd.at\n@@ -5867,8 +5867,9 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls1_lflows | ovn_strip_lflows], [0], [dnl\n   table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip), action=(outport = \"_MC_flood_l2\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast && (nd_na || nd_rs || nd_ra)), action=(outport = \"_MC_flood\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=75   , match=(eth.src == {00:00:00:00:01:01} && eth.dst == ff:ff:ff:ff:ff:ff && (arp.op == 1 || rarp.op == 3 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1 && arp.spa == 192.168.1.1), action=(outport = \"_MC_flood_l2\"; output;)\n ])\n \n ovn-sbctl lflow-list ls2 > ls2_lflows\n@@ -5883,8 +5884,9 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls2_lflows | ovn_strip_lflows], [0], [dnl\n   table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip), action=(outport = \"_MC_flood_l2\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast && (nd_na || nd_rs || nd_ra)), action=(outport = \"_MC_flood\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=75   , match=(eth.src == {00:00:00:00:02:01} && eth.dst == ff:ff:ff:ff:ff:ff && (arp.op == 1 || rarp.op == 3 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.2.1), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:201), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.2.1), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:201), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.2.1 && arp.spa == 192.168.2.1), action=(outport = \"_MC_flood_l2\"; output;)\n ])\n \n AS_BOX([Adding some reachable NAT addresses])\n@@ -5907,10 +5909,13 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls1_lflows | ovn_strip_lflows], [0], [dnl\n   table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip), action=(outport = \"_MC_flood_l2\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast && (nd_na || nd_rs || nd_ra)), action=(outport = \"_MC_flood\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=75   , match=(eth.src == {00:00:00:00:01:01} && eth.dst == ff:ff:ff:ff:ff:ff && (arp.op == 1 || rarp.op == 3 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.100 && arp.spa == 10.0.0.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.200 && arp.spa == 10.0.0.200), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1 && arp.spa == 192.168.1.1), action=(outport = \"_MC_flood_l2\"; output;)\n ])\n \n ovn-sbctl lflow-list ls2 > ls2_lflows\n@@ -5925,10 +5930,13 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls2_lflows | ovn_strip_lflows], [0], [dnl\n   table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip), action=(outport = \"_MC_flood_l2\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast && (nd_na || nd_rs || nd_ra)), action=(outport = \"_MC_flood\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=75   , match=(eth.src == {00:00:00:00:02:01} && eth.dst == ff:ff:ff:ff:ff:ff && (arp.op == 1 || rarp.op == 3 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.2.1), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 20.0.0.100), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 20.0.0.200), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:201), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.2.1), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 20.0.0.100), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 20.0.0.200), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:201), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.2.1 && arp.spa == 192.168.2.1), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 20.0.0.100 && arp.spa == 20.0.0.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 20.0.0.200 && arp.spa == 20.0.0.200), action=(outport = \"_MC_flood_l2\"; output;)\n ])\n \n AS_BOX([Adding some unreachable NAT addresses])\n@@ -5951,12 +5959,17 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls1_lflows | ovn_strip_lflows], [0], [dnl\n   table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip), action=(outport = \"_MC_flood_l2\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast && (nd_na || nd_rs || nd_ra)), action=(outport = \"_MC_flood\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=75   , match=(eth.src == {00:00:00:00:01:01} && eth.dst == ff:ff:ff:ff:ff:ff && (arp.op == 1 || rarp.op == 3 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.100 && arp.spa == 10.0.0.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.200 && arp.spa == 10.0.0.200), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1 && arp.spa == 192.168.1.1), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.100 && arp.spa == 30.0.0.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.200 && arp.spa == 30.0.0.200), action=(outport = \"_MC_flood_l2\"; output;)\n ])\n \n ovn-sbctl lflow-list ls2 > ls2_lflows\n@@ -5971,12 +5984,17 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls2_lflows | ovn_strip_lflows], [0], [dnl\n   table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip), action=(outport = \"_MC_flood_l2\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast && (nd_na || nd_rs || nd_ra)), action=(outport = \"_MC_flood\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=75   , match=(eth.src == {00:00:00:00:02:01} && eth.dst == ff:ff:ff:ff:ff:ff && (arp.op == 1 || rarp.op == 3 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.2.1), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 20.0.0.100), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 20.0.0.200), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 40.0.0.100), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 40.0.0.200), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:201), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.2.1), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 20.0.0.100), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 20.0.0.200), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 40.0.0.100), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 40.0.0.200), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:201), action=(clone {outport = \"ls2-ro2\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.2.1 && arp.spa == 192.168.2.1), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 20.0.0.100 && arp.spa == 20.0.0.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 20.0.0.200 && arp.spa == 20.0.0.200), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 40.0.0.100 && arp.spa == 40.0.0.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 40.0.0.200 && arp.spa == 40.0.0.200), action=(outport = \"_MC_flood_l2\"; output;)\n ])\n \n AS_BOX([Adding load balancer reachable VIPs to ro1])\n@@ -5996,13 +6014,19 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls1_lflows | ovn_strip_lflows], [0], [dnl\n   table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip), action=(outport = \"_MC_flood_l2\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast && (nd_na || nd_rs || nd_ra)), action=(outport = \"_MC_flood\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=75   , match=(eth.src == {00:00:00:00:01:01} && eth.dst == ff:ff:ff:ff:ff:ff && (arp.op == 1 || rarp.op == 3 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.100 && arp.spa == 10.0.0.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.200 && arp.spa == 10.0.0.200), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1 && arp.spa == 192.168.1.1), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.100 && arp.spa == 192.168.1.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.100 && arp.spa == 30.0.0.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.200 && arp.spa == 30.0.0.200), action=(outport = \"_MC_flood_l2\"; output;)\n ])\n \n AS_BOX([Adding load balancer unreachable VIPs to ro1])\n@@ -6020,13 +6044,19 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls1_lflows | ovn_strip_lflows], [0], [dnl\n   table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip), action=(outport = \"_MC_flood_l2\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast && (nd_na || nd_rs || nd_ra)), action=(outport = \"_MC_flood\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=75   , match=(eth.src == {00:00:00:00:01:01} && eth.dst == ff:ff:ff:ff:ff:ff && (arp.op == 1 || rarp.op == 3 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.100 && arp.spa == 10.0.0.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.200 && arp.spa == 10.0.0.200), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1 && arp.spa == 192.168.1.1), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.100 && arp.spa == 192.168.1.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.100 && arp.spa == 30.0.0.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.200 && arp.spa == 30.0.0.200), action=(outport = \"_MC_flood_l2\"; output;)\n ])\n \n # Make sure that there is no flow for VIP 192.168.4.100 as ro1-ls1 doesn't\n@@ -6051,13 +6081,19 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls1_lflows | ovn_strip_lflows], [0], [dnl\n   table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip), action=(outport = \"_MC_flood_l2\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast && (nd_na || nd_rs || nd_ra)), action=(outport = \"_MC_flood\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=75   , match=(eth.src == {00:00:00:00:01:01} && eth.dst == ff:ff:ff:ff:ff:ff && (arp.op == 1 || rarp.op == 3 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.100), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.200), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone {outport = \"ls1-ro1\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.100 && arp.spa == 10.0.0.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 10.0.0.200 && arp.spa == 10.0.0.200), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.1 && arp.spa == 192.168.1.1), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.100 && arp.spa == 192.168.1.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.100 && arp.spa == 30.0.0.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.200 && arp.spa == 30.0.0.200), action=(outport = \"_MC_flood_l2\"; output;)\n ])\n \n \n@@ -8066,17 +8102,17 @@ check ovn-nbctl lsp-add S1 S1-VIF\n check ovn-nbctl lsp-set-addresses S1-VIF \"02:ac:10:01:00:02 unknown\"\n check ovn-nbctl --wait=sb sync\n \n-AT_CHECK([ovn-sbctl lflow-list S1 | grep ls_in_l2_lkup | grep -q 'match=(eth.mcast && (arp.op == 1 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)'], [1])\n+AT_CHECK([ovn-sbctl lflow-list S1 | grep ls_in_l2_lkup | grep -q 'match=(eth.mcast && (arp.op == 1 || nd_ns)), action=(outport = \"_MC_unknown\"; output;)'], [1])\n \n check ovn-nbctl --wait=sb set Logical_Switch S1 \\\n     other_config:broadcast-arps-to-all-routers=false\n \n-AT_CHECK([ovn-sbctl lflow-list S1 | grep ls_in_l2_lkup | grep -q 'match=(eth.mcast && (arp.op == 1 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)'], [0], [], [ignore])\n+AT_CHECK([ovn-sbctl lflow-list S1 | grep ls_in_l2_lkup | grep -q 'match=(eth.mcast && (arp.op == 1 || nd_ns)), action=(outport = \"_MC_unknown\"; output;)'], [0], [], [ignore])\n \n check ovn-nbctl --wait=sb set Logical_Switch S1 \\\n     other_config:broadcast-arps-to-all-routers=true\n \n-AT_CHECK([ovn-sbctl lflow-list S1 | grep ls_in_l2_lkup | grep -q 'match=(eth.mcast && (arp.op == 1 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)'], [1])\n+AT_CHECK([ovn-sbctl lflow-list S1 | grep ls_in_l2_lkup | grep -q 'match=(eth.mcast && (arp.op == 1 || nd_ns)), action=(outport = \"_MC_unknown\"; output;)'], [1])\n \n OVN_CLEANUP_NORTHD\n AT_CLEANUP\n@@ -14356,11 +14392,15 @@ AT_CHECK([grep \"ls_in_l2_lkup\" publicflows | ovn_strip_lflows], [0], [dnl\n   table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip), action=(outport = \"_MC_flood_l2\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast && (nd_na || nd_rs || nd_ra)), action=(outport = \"_MC_flood\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=75   , match=(eth.src == {00:00:00:00:ff:02, 30:54:00:00:00:03} && eth.dst == ff:ff:ff:ff:ff:ff && (arp.op == 1 || rarp.op == 3 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.10), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.100), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:ff02), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.10), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.100), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:ff02), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.10 && arp.spa == 172.168.0.10), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.100 && arp.spa == 172.168.0.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110 && arp.spa == 172.168.0.110), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120 && arp.spa == 172.168.0.120), action=(outport = \"_MC_flood_l2\"; output;)\n ])\n \n AT_CHECK([grep -Fe \"172.168.0.110\" -e \"172.168.0.120\" -e \"10.0.0.3\" -e \"20.0.0.3\" -e \"30:54:00:00:00:03\"  -e \"sw0-port1\" lr0flows | ovn_strip_lflows], [0], [dnl\n@@ -14391,8 +14431,10 @@ AT_CHECK([grep -Fe \"172.168.0.110\" -e \"172.168.0.120\" -e \"10.0.0.3\" -e \"20.0.0.3\n AT_CHECK([grep -Fe \"172.168.0.110\" -e \"172.168.0.120\" -e \"10.0.0.3\" -e \"20.0.0.3\" -e \"30:54:00:00:00:03\"  -e \"sw0-port1\" publicflows | ovn_strip_lflows | grep -v \"reg0.*22\"], [0], [dnl\n   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 30:54:00:00:00:03 && is_chassis_resident(\"sw0-port1\")), action=(outport = \"public-lr0\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=75   , match=(eth.src == {00:00:00:00:ff:02, 30:54:00:00:00:03} && eth.dst == ff:ff:ff:ff:ff:ff && (arp.op == 1 || rarp.op == 3 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110 && arp.spa == 172.168.0.110), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120 && arp.spa == 172.168.0.120), action=(outport = \"_MC_flood_l2\"; output;)\n ])\n }\n \n@@ -14536,16 +14578,20 @@ AT_CHECK([grep \"ls_in_l2_lkup\" publicflows | ovn_strip_lflows], [0], [dnl\n   table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip), action=(outport = \"_MC_flood_l2\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast && (nd_na || nd_rs || nd_ra)), action=(outport = \"_MC_flood\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=75   , match=(eth.src == {00:00:00:00:ff:02, 30:54:00:00:00:03} && eth.dst == ff:ff:ff:ff:ff:ff && (arp.op == 1 || rarp.op == 3 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.10 && !is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"cr-public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.10 && is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.100 && !is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"cr-public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.100 && is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110 && !is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"cr-public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110 && is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120 && !is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"cr-public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120 && is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:ff02 && !is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"cr-public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:ff02 && is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.10 && !is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"cr-public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.10 && is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.100 && !is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"cr-public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.100 && is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110 && !is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"cr-public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110 && is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120 && !is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"cr-public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120 && is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:ff02 && !is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"cr-public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:ff02 && is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.10 && is_chassis_resident(\"cr-public-lr0\") && arp.spa == 172.168.0.10), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.100 && is_chassis_resident(\"cr-public-lr0\") && arp.spa == 172.168.0.100), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110 && is_chassis_resident(\"cr-public-lr0\") && arp.spa == 172.168.0.110), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120 && is_chassis_resident(\"cr-public-lr0\") && arp.spa == 172.168.0.120), action=(outport = \"_MC_flood_l2\"; output;)\n ])\n \n AT_CHECK([grep -Fe \"172.168.0.110\" -e \"172.168.0.120\" -e \"10.0.0.3\" -e \"20.0.0.3\" -e \"30:54:00:00:00:03\"  -e \"sw0-port1\" lr0flows | ovn_strip_lflows], [0], [dnl\n@@ -14570,10 +14616,12 @@ AT_CHECK([grep -Fe \"172.168.0.110\" -e \"172.168.0.120\" -e \"10.0.0.3\" -e \"20.0.0.3\n AT_CHECK([grep -Fe \"172.168.0.110\" -e \"172.168.0.120\" -e \"10.0.0.3\" -e \"20.0.0.3\" -e \"30:54:00:00:00:03\"  -e \"sw0-port1\" publicflows | ovn_strip_lflows], [0], [dnl\n   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 30:54:00:00:00:03 && is_chassis_resident(\"sw0-port1\")), action=(outport = \"public-lr0\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=75   , match=(eth.src == {00:00:00:00:ff:02, 30:54:00:00:00:03} && eth.dst == ff:ff:ff:ff:ff:ff && (arp.op == 1 || rarp.op == 3 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110 && !is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"cr-public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110 && is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120 && !is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"cr-public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120 && is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110 && !is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"cr-public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110 && is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120 && !is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"cr-public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120 && is_chassis_resident(\"cr-public-lr0\")), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110 && is_chassis_resident(\"cr-public-lr0\") && arp.spa == 172.168.0.110), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120 && is_chassis_resident(\"cr-public-lr0\") && arp.spa == 172.168.0.120), action=(outport = \"_MC_flood_l2\"; output;)\n ])\n }\n \n@@ -14637,8 +14685,10 @@ AT_CHECK([grep -Fe \"172.168.0.110\" -e \"172.168.0.120\" -e \"10.0.0.3\" -e \"20.0.0.3\n AT_CHECK([grep -Fe \"172.168.0.110\" -e \"172.168.0.120\" -e \"10.0.0.3\" -e \"20.0.0.3\" -e \"30:54:00:00:00:03\"  -e \"sw0-port1\" publicflows | ovn_strip_lflows], [0], [dnl\n   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 30:54:00:00:00:03 && is_chassis_resident(\"sw0-port1\")), action=(outport = \"public-lr0\"; output;)\n   table=??(ls_in_l2_lkup      ), priority=75   , match=(eth.src == {00:00:00:00:ff:02, 30:54:00:00:00:03} && eth.dst == ff:ff:ff:ff:ff:ff && (arp.op == 1 || rarp.op == 3 || nd_ns)), action=(outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n-  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120), action=(clone {outport = \"public-lr0\"; output; }; outport = \"_MC_unknown\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.110 && arp.spa == 172.168.0.110), action=(outport = \"_MC_flood_l2\"; output;)\n+  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 172.168.0.120 && arp.spa == 172.168.0.120), action=(outport = \"_MC_flood_l2\"; output;)\n ])\n \n OVN_CLEANUP_NORTHD\ndiff --git a/tests/ovn.at b/tests/ovn.at\nindex c0ae611bc..e0ab6fa0b 100644\n--- a/tests/ovn.at\n+++ b/tests/ovn.at\n@@ -5192,7 +5192,7 @@ test_ip() {\n # SPA and TPA are each 8 hex digits.\n test_arp() {\n     echo \"$@\"\n-    local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5\n+    local inport=$1 sha=$2 spa=$3 tpa=$4 rip=$5 reply_ha=$6\n     local request=$(fmt_pkt \"Ether(dst='ff:ff:ff:ff:ff:ff', src='${sha}')/ \\\n                              ARP(hwsrc='${sha}', hwdst='ff:ff:ff:ff:ff:ff', psrc='${spa}', pdst='${tpa}')\")\n     hv=hv`vif_to_hv $inport`\n@@ -5206,9 +5206,19 @@ test_arp() {\n         for k in 1 2 3; do\n             # 192.168.33.254 is configured to the switch patch port for lrp33,\n             # so no ARP flooding expected for it.\n-            if test $i$j$k != $inport && test $tpa != 192.168.33.254; then\n-                echo $request >> $i$j$k.expected\n+            if test $i$j$k = $inport; then\n+                continue\n+            fi\n+\n+            if test $tpa = 192.168.33.254; then\n+                continue\n             fi\n+\n+            if test $rip = $tpa && test $j$k != 11; then\n+                continue\n+            fi\n+\n+            echo $request >> $i$j$k.expected\n         done\n     done\n \n@@ -5348,9 +5358,9 @@ for i in 1 2 3; do\n       otherip=192.168.$i$j.55 # Some other IP in subnet\n       externalip=1.2.3.4      # Some other IP not in subnet\n \n-      test_arp $i$j$k $smac $sip        $rip        $rmac      #4\n-      test_arp $i$j$k $smac $otherip    $rip        $rmac      #5\n-      test_arp $i$j$k $smac $sip        $otherip               #6\n+      test_arp $i$j$k $smac $sip        $rip        $rip    $rmac #4\n+      test_arp $i$j$k $smac $otherip    $rip        $rip    $rmac #5\n+      test_arp $i$j$k $smac $sip        $otherip    $rip          #6\n \n       # When rip is 192.168.33.254, ARP request from externalip won't be\n       # filtered, because 192.168.33.254 is configured to switch peer port\n@@ -5359,9 +5369,9 @@ for i in 1 2 3; do\n       if test $i = 3 && test $j = 3; then\n         lrp33_rsp=$rmac\n       fi\n-      test_arp $i$j$k $smac $externalip $rip        $lrp33_rsp #7\n+      test_arp $i$j$k $smac $externalip $rip $rip $lrp33_rsp #7\n \n-      # MAC binding should be learned from ARP request.\n+      ## MAC binding should be learned from ARP request.\n       echo lrp$i$j,$sip,$smac >> mac_bindings.expected\n \n       # mac_binding is learned and overwritten so only the last one remains.\n@@ -27702,18 +27712,6 @@ for var in sw_dp_uuid sw_dp_key sw1_dp_key r1_dp_key r1_tnl_key r2_tnl_key \\\n    echo \"$var=$value\"\n done\n \n-as hv1\n-AT_CAPTURE_FILE([offlows])\n-OVS_WAIT_FOR_OUTPUT([\n-    ovs-ofctl dump-flows br-int > offlows\n-    for match in \"$match_send_rtr1\" \"$match_send_rtr2\"; do\n-        grep -E \"$match_arp_req.*$match\" offlows | grep -c 'n_packets=[[1-9]]'\n-    done\n-    :\n-], [0], [1\n-0\n-])\n-\n # Inject ND_NS for ofirst router owned IP address.\n src_ipv6=00100000000000000000000000000254\n dst_ipv6=00100000000000000000000000000001\n","prefixes":["ovs-dev","v2"]}