Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2220894/?format=api
{ "id": 2220894, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2220894/?format=api", "web_url": "http://patchwork.ozlabs.org/project/ovn/patch/20260408115243.2125880-1-dceara@redhat.com/", "project": { "id": 68, "url": "http://patchwork.ozlabs.org/api/1.1/projects/68/?format=api", "name": "Open Virtual Network development", "link_name": "ovn", "list_id": "ovs-dev.openvswitch.org", "list_email": "ovs-dev@openvswitch.org", "web_url": "http://openvswitch.org/", "scm_url": "", "webscm_url": "" }, "msgid": "<20260408115243.2125880-1-dceara@redhat.com>", "date": "2026-04-08T11:52:43", "name": "[ovs-dev] northd: Don't forward IP multicast to routers without IGMP relay.", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "c1c0fab05372e6d2f5faca1e1b97d744a5939c5c", "submitter": { "id": 76591, "url": "http://patchwork.ozlabs.org/api/1.1/people/76591/?format=api", "name": "Dumitru Ceara", "email": "dceara@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/ovn/patch/20260408115243.2125880-1-dceara@redhat.com/mbox/", "series": [ { "id": 499125, "url": "http://patchwork.ozlabs.org/api/1.1/series/499125/?format=api", "web_url": "http://patchwork.ozlabs.org/project/ovn/list/?series=499125", "date": "2026-04-08T11:52:43", "name": "[ovs-dev] northd: Don't forward IP multicast to routers without IGMP relay.", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/499125/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2220894/comments/", "check": "fail", "checks": "http://patchwork.ozlabs.org/api/patches/2220894/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=DNwVvOti;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)", "smtp4.osuosl.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key)\n header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=DNwVvOti", "smtp3.osuosl.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com", "smtp3.osuosl.org;\n dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com\n header.a=rsa-sha256 header.s=mimecast20190719 header.b=DNwVvOti" ], "Received": [ "from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4frLzc5Q8dz1xy1\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 08 Apr 2026 21:53:00 +1000 (AEST)", "from localhost (localhost [127.0.0.1])\n\tby smtp4.osuosl.org (Postfix) with ESMTP id 0C4D04078C;\n\tWed, 8 Apr 2026 11:52:59 +0000 (UTC)", "from smtp4.osuosl.org ([127.0.0.1])\n by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id j2OVbaHOGWaQ; Wed, 8 Apr 2026 11:52:55 +0000 (UTC)", "from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])\n\tby smtp4.osuosl.org (Postfix) with ESMTPS id 53E1440750;\n\tWed, 8 Apr 2026 11:52:55 +0000 (UTC)", "from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id 38B74C054A;\n\tWed, 8 Apr 2026 11:52:55 +0000 (UTC)", "from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 45288C0549\n for <ovs-dev@openvswitch.org>; Wed, 8 Apr 2026 11:52:54 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n by smtp3.osuosl.org (Postfix) with ESMTP id 308466084A\n for <ovs-dev@openvswitch.org>; Wed, 8 Apr 2026 11:52:54 +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 yQZjejWxN3dd for <ovs-dev@openvswitch.org>;\n Wed, 8 Apr 2026 11:52:52 +0000 (UTC)", "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.129.124])\n by smtp3.osuosl.org (Postfix) with ESMTPS id 1EEC960847\n for <ovs-dev@openvswitch.org>; Wed, 8 Apr 2026 11:52:51 +0000 (UTC)", "from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-683-QoPQR41KPVSwCiFa9cTQpw-1; Wed,\n 08 Apr 2026 07:52:48 -0400", "from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 18B4D18002D1\n for <ovs-dev@openvswitch.org>; Wed, 8 Apr 2026 11:52:47 +0000 (UTC)", "from cecil-rh.redhat.com (unknown [10.44.33.24])\n by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id 7BA2F1955D84; Wed, 8 Apr 2026 11:52:45 +0000 (UTC)" ], "X-Virus-Scanned": [ "amavis at osuosl.org", "amavis at osuosl.org" ], "X-Comment": "SPF check N/A for local connections - client-ip=140.211.9.56;\n helo=lists.linuxfoundation.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN> ", "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 smtp4.osuosl.org 53E1440750", "OpenDKIM Filter v2.11.0 smtp3.osuosl.org 1EEC960847" ], "Received-SPF": "Pass (mailfrom) identity=mailfrom; client-ip=170.10.129.124;\n helo=us-smtp-delivery-124.mimecast.com; envelope-from=dceara@redhat.com;\n receiver=<UNKNOWN>", "DMARC-Filter": "OpenDMARC Filter v1.4.2 smtp3.osuosl.org 1EEC960847", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1775649169;\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=GdlkUI2fGPVAcGiiUX2ZgB0xUzGR3lpBkoRxH1icgXk=;\n b=DNwVvOtipUUbVzi2INaGFE+3rqJNw8USOL75m8frGLmmIXT3ggVBfJo2ksJ+GS6i3gOuj5\n DYzcZNoR8ENZ5+kgDMbuygghAdS8ZTltutlXhNn2GqZb0ltsQSWEa2gNqpxOUVk+EJXYkt\n RDfelwg0XeiOBwZqNP8iDpWUfduW0ac=", "X-MC-Unique": "QoPQR41KPVSwCiFa9cTQpw-1", "X-Mimecast-MFC-AGG-ID": "QoPQR41KPVSwCiFa9cTQpw_1775649167", "To": "ovs-dev@openvswitch.org", "Date": "Wed, 8 Apr 2026 13:52:43 +0200", "Message-ID": "<20260408115243.2125880-1-dceara@redhat.com>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.17", "X-Mimecast-Spam-Score": "0", "X-Mimecast-MFC-PROC-ID": "I1b_3xto0-NTBZ4_qOUqysK2puSSJl8LsW5nlrOtxPk_1775649167", "X-Mimecast-Originator": "redhat.com", "Subject": "[ovs-dev] [PATCH ovn] northd: Don't forward IP multicast to routers\n without IGMP relay.", "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": "Dumitru Ceara via dev <ovs-dev@openvswitch.org>", "Reply-To": "Dumitru Ceara <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": "Logical switches should not forward IP multicast packets towards\nconnected OVN logical routers if the router is not configured to relay\nIP multicast traffic (LR.options:mcast_relay=false).\n\nPreviously, a single priority 71 flow matched \"eth.mcast && (arp || ip)\"\nand sent all such traffic to _MC_flood, which includes all ports\n(including router ports). This caused IP multicast packets to be\nforwarded to routers that would always drop them in lr_in_ip_input,\nwasting CPU cycles. In topologies with hundreds of routers connected\nto logical switches, this can lead to the max resubmit limit (4K) being\nhit by such packets, unnecessarily overloading ovs-vswitchd.\n\nFix this by splitting the flow into three:\n - Priority 72: \"eth.mcast && (nd_na || nd_rs || nd_ra)\" -> _MC_flood\n ND NA, Router Solicitation and Router Advertisement must still reach\n routers: ND NA for neighbor learning, ND RS so routers can respond\n with Router Advertisements, ND RA for proper IPv6 network operation.\n - Priority 71: \"eth.mcast && arp\" -> _MC_flood\n ARP (including gratuitous ARP) still reaches all ports.\n - Priority 71: \"eth.mcast && ip\" -> _MC_flood_l2\n IP multicast is only sent to non-router L2 ports, plus\n _MC_mrouter_flood (if any connected router has relay enabled)\n and _MC_static (if any port has mcast_flood=true).\n\nReported-at: https://redhat.atlassian.net/browse/FDP-2262\nAssisted-by: Claude, with model: claude-opus-4-6\nSigned-off-by: Dumitru Ceara <dceara@redhat.com>\n---\n northd/northd.c | 37 +++++++-\n northd/ovn-northd.8.xml | 33 +++++--\n tests/ovn-northd.at | 191 ++++++++++++++++++++++++++++++++++++----\n 3 files changed, 237 insertions(+), 24 deletions(-)", "diff": "diff --git a/northd/northd.c b/northd/northd.c\nindex b7239f4e20..92c1707817 100644\n--- a/northd/northd.c\n+++ b/northd/northd.c\n@@ -11020,10 +11020,45 @@ build_lswitch_destination_lookup_bmcast(struct ovn_datapath *od,\n lflow_ref);\n }\n \n+ /* ND NA, Router Solicitation and Router Advertisement should be\n+ * flooded to all ports including routers. ND NA is needed for\n+ * neighbor learning; ND RS must reach routers so they can respond\n+ * with Router Advertisements; ND RA must reach routers for proper\n+ * IPv6 network operation.\n+ */\n+ ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, 72,\n+ \"eth.mcast && (nd_na || nd_rs || nd_ra)\",\n+ \"outport = \\\"\"MC_FLOOD\"\\\"; output;\", lflow_ref);\n+\n+ /* ARP multicast should be flooded to all ports including routers. */\n ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, 71,\n- \"eth.mcast && (arp || ip)\",\n+ \"eth.mcast && arp\",\n \"outport = \\\"\"MC_FLOOD\"\\\"; output;\", lflow_ref);\n \n+ /* IP multicast should not be forwarded to routers that don't have\n+ * IGMP relay enabled (mcast_relay=true). Such routers will always\n+ * drop IP multicast in lr_in_ip_input anyway.\n+ */\n+ ds_clear(actions);\n+ if (mcast_sw_info->flood_relay) {\n+ ds_put_cstr(actions,\n+ \"clone { \"\n+ \"outport = \\\"\"MC_MROUTER_FLOOD\"\\\"; \"\n+ \"output; \"\n+ \"}; \");\n+ }\n+ if (mcast_sw_info->flood_static) {\n+ ds_put_cstr(actions,\n+ \"clone { \"\n+ \"outport = \\\"\"MC_STATIC\"\\\"; \"\n+ \"output; \"\n+ \"}; \");\n+ }\n+ ds_put_cstr(actions, \"outport = \\\"\"MC_FLOOD_L2\"\\\"; output;\");\n+ ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, 71,\n+ \"eth.mcast && ip\",\n+ ds_cstr(actions), lflow_ref);\n+\n /* Non-{arp,ip} L2 multicast traffic should not be sent to router\n * ports since these packets will be discarded in the router pipeline.\n */\ndiff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml\nindex 9f2d118dd4..4d6370da6b 100644\n--- a/northd/ovn-northd.8.xml\n+++ b/northd/ovn-northd.8.xml\n@@ -2414,18 +2414,41 @@ output;\n </li>\n \n <li>\n- A priority-72 flow that outputs all ARP requests and ND packets with\n- an Ethernet broadcast or multicast <code>eth.dst</code> to the\n- <code>MC_FLOOD_L2</code> multicast group if\n- <code>other_config:broadcast-arps-to-all-routers=true</code>.\n+ A priority-72 flow that outputs all ND NA (Neighbor Advertisement),\n+ ND RS (Router Solicitation) and ND RA (Router Advertisement) packets\n+ with an Ethernet broadcast or multicast <code>eth.dst</code> to the\n+ <code>MC_FLOOD</code> multicast group, which includes all ports.\n+ ND NA must reach routers for neighbor learning; ND RS must reach\n+ routers so they can respond with Router Advertisements; ND RA must\n+ reach routers for proper IPv6 network operation.\n </li>\n \n <li>\n- A priority-71 flow that outputs all ARP or IP packets with an Ethernet\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+ if <code>other_config:broadcast-arps-to-all-routers=false</code>.\n+ </li>\n+\n+ <li>\n+ A priority-71 flow that outputs all ARP packets with an Ethernet\n broadcast or multicast <code>eth.dst</code> to the\n <code>MC_FLOOD</code> multicast group.\n </li>\n \n+ <li>\n+ A priority-71 flow that outputs all IP packets with an Ethernet\n+ broadcast or multicast <code>eth.dst</code> to the\n+ <code>MC_FLOOD_L2</code> multicast group, which contains only\n+ non-router logical ports. If any connected router has\n+ <code>options:mcast_relay=true</code>, the packet is also cloned to\n+ the <code>MC_MROUTER_FLOOD</code> multicast group (which contains\n+ only the router ports with relay enabled). If any port has\n+ <code>options:mcast_flood=true</code>, it is also cloned to the\n+ <code>MC_STATIC</code> multicast group. This prevents IP multicast\n+ from being unnecessarily forwarded to routers that would drop it.\n+ </li>\n+\n <li>\n A priority-70 flow that outputs all packets with an Ethernet broadcast\n or multicast <code>eth.dst</code> to the <code>MC_FLOOD_L2</code>\ndiff --git a/tests/ovn-northd.at b/tests/ovn-northd.at\nindex 6230fd039a..7c2f53da69 100644\n--- a/tests/ovn-northd.at\n+++ b/tests/ovn-northd.at\n@@ -5863,7 +5863,9 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls1_lflows | ovn_strip_lflows], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:01), action=(outport = \"ls1-ro1\"; output;)\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:02), action=(outport = \"vm1\"; output;)\n table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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@@ -5877,7 +5879,9 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls2_lflows | ovn_strip_lflows], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:02:01), action=(outport = \"ls2-ro2\"; output;)\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:02:02), action=(outport = \"vm2\"; output;)\n table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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@@ -5899,7 +5903,9 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls1_lflows | ovn_strip_lflows], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:01), action=(outport = \"ls1-ro1\"; output;)\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:02), action=(outport = \"vm1\"; output;)\n table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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@@ -5915,7 +5921,9 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls2_lflows | ovn_strip_lflows], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:02:01), action=(outport = \"ls2-ro2\"; output;)\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:02:02), action=(outport = \"vm2\"; output;)\n table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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@@ -5939,7 +5947,9 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls1_lflows | ovn_strip_lflows], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:01), action=(outport = \"ls1-ro1\"; output;)\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:02), action=(outport = \"vm1\"; output;)\n table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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@@ -5957,7 +5967,9 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls2_lflows | ovn_strip_lflows], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:02:01), action=(outport = \"ls2-ro2\"; output;)\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:02:02), action=(outport = \"vm2\"; output;)\n table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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@@ -5980,7 +5992,9 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls1_lflows | ovn_strip_lflows], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:01), action=(outport = \"ls1-ro1\"; output;)\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:02), action=(outport = \"vm1\"; output;)\n table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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@@ -6002,7 +6016,9 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls1_lflows | ovn_strip_lflows], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:01), action=(outport = \"ls1-ro1\"; output;)\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:02), action=(outport = \"vm1\"; output;)\n table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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@@ -6031,7 +6047,9 @@ AT_CHECK([grep \"ls_in_l2_lkup\" ls1_lflows | ovn_strip_lflows], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:01 && is_chassis_resident(\"cr-ro1-ls1\")), action=(outport = \"ls1-ro1\"; output;)\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:02), action=(outport = \"vm1\"; output;)\n table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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@@ -8365,6 +8383,127 @@ OVN_CLEANUP_NORTHD\n AT_CLEANUP\n ])\n \n+OVN_FOR_EACH_NORTHD_NO_HV([\n+AT_SETUP([IP multicast flood without IGMP relay])\n+AT_KEYWORDS([mcast_relay])\n+ovn_start\n+\n+check ovn-nbctl lr-add lr0\n+check ovn-nbctl ls-add ls0\n+\n+check ovn-nbctl lrp-add lr0 lrp0 00:00:00:00:00:01 10.0.0.1/24 fe80::1/64\n+check ovn-nbctl lsp-add-router-port ls0 lsp0-router lrp0\n+\n+check ovn-nbctl lsp-add ls0 lsp0 -- \\\n+ lsp-set-addresses lsp0 \"00:00:00:00:00:02 10.0.0.2\"\n+\n+dnl IP multicast packet from lsp0.\n+mcast_pkt='inport == \"lsp0\" && eth.src == 00:00:00:00:00:02 && eth.dst == 01:00:5e:00:01:2a && ip4.src == 10.0.0.2 && ip4.dst == 239.0.1.42 && ip.ttl == 64 && udp.src == 42 && udp.dst == 43'\n+\n+dnl ARP broadcast from lsp0.\n+arp_pkt='inport == \"lsp0\" && eth.src == 00:00:00:00:00:02 && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.sha == 00:00:00:00:00:02 && arp.spa == 10.0.0.2 && arp.tha == 00:00:00:00:00:00 && arp.tpa == 10.0.0.3'\n+\n+dnl Gratuitous ND NA multicast from lsp0.\n+nd_na_pkt='inport == \"lsp0\" && eth.src == 00:00:00:00:00:02 && eth.dst == 33:33:00:00:00:01 && ip6.src == fe80::200:ff:fe00:2 && ip6.dst == ff02::1 && icmp6.type == 136 && nd.target == fe80::200:ff:fe00:2'\n+\n+dnl Router solicitation multicast from lsp0.\n+nd_rs_pkt='inport == \"lsp0\" && eth.src == 00:00:00:00:00:02 && eth.dst == 33:33:00:00:00:02 && ip6.src == fe80::200:ff:fe00:2 && ip6.dst == ff02::2 && icmp6.type == 133 && ip.ttl == 255'\n+\n+dnl Router advertisement multicast from lsp0.\n+nd_ra_pkt='inport == \"lsp0\" && eth.src == 00:00:00:00:00:02 && eth.dst == 33:33:00:00:00:01 && ip6.src == fe80::200:ff:fe00:2 && ip6.dst == ff02::1 && icmp6.type == 134 && ip.ttl == 255'\n+\n+dnl Scenario 1: default, no relay, no snooping.\n+dnl The eth.mcast && ip flow should use _MC_flood_l2 not _MC_flood.\n+check ovn-nbctl --wait=sb sync\n+\n+ovn-sbctl dump-flows ls0 > lsflows\n+AT_CAPTURE_FILE([lsflows])\n+AT_CHECK([grep -e 'ls_in_l2_lkup' lsflows | grep -e 'priority=71' -e 'priority=72' | ovn_strip_lflows], [0], [dnl\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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+])\n+\n+dnl Verify packet forwarding: IP multicast should not reach the router\n+dnl port, while ARP, ND NA, ND RS and ND RA should.\n+AT_CHECK([ovn_trace ls0 \"$mcast_pkt\" | grep 'outport=\"lsp0-router\"'], [1])\n+AT_CHECK([ovn_trace ls0 \"$arp_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+AT_CHECK([ovn_trace ls0 \"$nd_na_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+AT_CHECK([ovn_trace ls0 \"$nd_rs_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+AT_CHECK([ovn_trace ls0 \"$nd_ra_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+\n+dnl Scenario 2: relay enabled on the router but snooping not enabled on the switch.\n+dnl No priority 80 flow is installed because build_mcast_flood_lswitch returns\n+dnl early when snooping is disabled, so the priority 71 flow is the only path\n+dnl for IP multicast to reach relay-enabled routers via _MC_mrouter_flood.\n+check ovn-nbctl set logical_router lr0 options:mcast_relay=\"true\"\n+check ovn-nbctl --wait=sb sync\n+\n+ovn-sbctl dump-flows ls0 > lsflows2\n+AT_CAPTURE_FILE([lsflows2])\n+AT_CHECK([grep -e 'ls_in_l2_lkup' lsflows2 | grep -e 'priority=71' -e 'priority=72' | ovn_strip_lflows], [0], [dnl\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && ip), action=(clone { outport = \"_MC_mrouter_flood\"; output; }; 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+])\n+\n+dnl Verify packet forwarding: all packet types should reach the router port.\n+AT_CHECK([ovn_trace ls0 \"$mcast_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+AT_CHECK([ovn_trace ls0 \"$arp_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+AT_CHECK([ovn_trace ls0 \"$nd_na_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+AT_CHECK([ovn_trace ls0 \"$nd_rs_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+AT_CHECK([ovn_trace ls0 \"$nd_ra_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+\n+dnl Scenario 3: relay enabled on the router and snooping enabled on the switch.\n+dnl The eth.mcast && ip flow should include _MC_mrouter_flood for relay-enabled\n+dnl router ports plus _MC_flood_l2 for regular ports.\n+check ovn-nbctl set logical_switch ls0 other_config:mcast_snoop=\"true\"\n+check ovn-nbctl --wait=sb sync\n+\n+ovn-sbctl dump-flows ls0 > lsflows3\n+AT_CAPTURE_FILE([lsflows3])\n+AT_CHECK([grep -e 'ls_in_l2_lkup' lsflows3 | grep -e 'priority=71' -e 'priority=72' | ovn_strip_lflows], [0], [dnl\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && ip), action=(clone { outport = \"_MC_mrouter_flood\"; output; }; 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+])\n+\n+dnl Verify packet forwarding: all packet types should reach the router port.\n+AT_CHECK([ovn_trace ls0 \"$mcast_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+AT_CHECK([ovn_trace ls0 \"$arp_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+AT_CHECK([ovn_trace ls0 \"$nd_na_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+AT_CHECK([ovn_trace ls0 \"$nd_rs_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+AT_CHECK([ovn_trace ls0 \"$nd_ra_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+\n+dnl Scenario 4: also enable flood_unregistered on the switch.\n+dnl The priority 71 flow should still have _MC_mrouter_flood and _MC_flood_l2.\n+dnl There should be no priority 80 flow for ip4.mcast || ip6.mcast because\n+dnl flood_unregistered causes build_mcast_flood_lswitch to return early.\n+check ovn-nbctl set logical_switch ls0 other_config:mcast_flood_unregistered=\"true\"\n+check ovn-nbctl --wait=sb sync\n+\n+ovn-sbctl dump-flows ls0 > lsflows4\n+AT_CAPTURE_FILE([lsflows4])\n+AT_CHECK([grep -e 'ls_in_l2_lkup' lsflows4 | grep -e 'priority=71' -e 'priority=72' | ovn_strip_lflows], [0], [dnl\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && ip), action=(clone { outport = \"_MC_mrouter_flood\"; output; }; 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+])\n+\n+dnl Verify there is no priority 80 flow for ip4.mcast || ip6.mcast when flood_unregistered is set.\n+AT_CHECK([grep -e 'ls_in_l2_lkup' lsflows4 | grep -e 'priority=80' | grep -F 'ip4.mcast || ip6.mcast'], [1])\n+\n+dnl Verify packet forwarding: all packet types should reach the router port.\n+AT_CHECK([ovn_trace ls0 \"$mcast_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+AT_CHECK([ovn_trace ls0 \"$arp_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+AT_CHECK([ovn_trace ls0 \"$nd_na_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+AT_CHECK([ovn_trace ls0 \"$nd_rs_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+AT_CHECK([ovn_trace ls0 \"$nd_ra_pkt\" | grep -q 'outport=\"lsp0-router\"'])\n+\n+OVN_CLEANUP_NORTHD\n+AT_CLEANUP\n+])\n+\n OVN_FOR_EACH_NORTHD_NO_HV_PARALLELIZATION([\n AT_SETUP([ACLs after lb])\n AT_KEYWORDS([acl])\n@@ -9678,7 +9817,9 @@ ovn_strip_lflows ], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=100 , match=(reg8[[23]] == 1), action=(output;)\n table=??(ls_in_l2_lkup ), priority=110 , match=(eth.dst == $svc_monitor_mac && (tcp || icmp || icmp6)), action=(handle_svc_check(inport);)\n table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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_unknown ), priority=0 , match=(1), action=(output;)\n table=??(ls_in_l2_unknown ), priority=50 , match=(outport == \"none\"), action=(drop;)\n table=??(ls_out_apply_port_sec), priority=0 , match=(1), action=(output;)\n@@ -9714,7 +9855,9 @@ ovn_strip_lflows ], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:01), action=(outport = \"sw0p1\"; output;)\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:02:02), action=(outport = \"sw0p2\"; output;)\n table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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_unknown ), priority=0 , match=(1), action=(output;)\n table=??(ls_in_l2_unknown ), priority=50 , match=(outport == \"none\"), action=(drop;)\n table=??(ls_out_apply_port_sec), priority=0 , match=(1), action=(output;)\n@@ -9749,7 +9892,9 @@ ovn_strip_lflows ], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:01), action=(outport = \"sw0p1\"; output;)\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:02:02), action=(outport = \"sw0p2\"; output;)\n table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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_unknown ), priority=0 , match=(1), action=(output;)\n table=??(ls_in_l2_unknown ), priority=50 , match=(outport == \"none\"), action=(drop;)\n table=??(ls_out_apply_port_sec), priority=0 , match=(1), action=(output;)\n@@ -9785,7 +9930,9 @@ ovn_strip_lflows ], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:01), action=(drop;)\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:02:02), action=(outport = \"sw0p2\"; output;)\n table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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_unknown ), priority=0 , match=(1), action=(output;)\n table=??(ls_in_l2_unknown ), priority=50 , match=(outport == \"none\"), action=(drop;)\n table=??(ls_in_l2_unknown ), priority=50 , match=(outport == \"sw0p1\"), action=(drop;)\n@@ -9821,7 +9968,9 @@ ovn_strip_lflows ], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:01), action=(drop;)\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:02:02), action=(outport = \"sw0p2\"; output;)\n table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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_unknown ), priority=0 , match=(1), action=(output;)\n table=??(ls_in_l2_unknown ), priority=50 , match=(outport == \"none\"), action=(drop;)\n table=??(ls_in_l2_unknown ), priority=50 , match=(outport == \"sw0p1\"), action=(drop;)\n@@ -9861,7 +10010,9 @@ ovn_strip_lflows ], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:01:01), action=(outport = \"sw0p1\"; output;)\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:02:02), action=(outport = \"sw0p2\"; output;)\n table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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_unknown ), priority=0 , match=(1), action=(output;)\n table=??(ls_in_l2_unknown ), priority=50 , match=(outport == \"none\"), action=(drop;)\n table=??(ls_out_apply_port_sec), priority=0 , match=(1), action=(output;)\n@@ -14201,7 +14352,9 @@ AT_CHECK([grep \"ls_in_l2_lkup\" publicflows | ovn_strip_lflows], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:ff:02 && is_chassis_resident(\"cr-lr0-public\")), action=(outport = \"public-lr0\"; output;)\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=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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@@ -14379,7 +14532,9 @@ AT_CHECK([grep \"ls_in_l2_lkup\" publicflows | ovn_strip_lflows], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == 00:00:00:00:ff:02 && is_chassis_resident(\"cr-public-lr0\")), action=(outport = \"public-lr0\"; output;)\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=70 , match=(eth.mcast), action=(outport = \"_MC_flood_l2\"; output;)\n- table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && (arp || ip)), action=(outport = \"_MC_flood\"; output;)\n+ table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && arp), action=(outport = \"_MC_flood\"; output;)\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@@ -14541,7 +14696,7 @@ AT_CHECK([ovn-sbctl dump-flows ls | grep ls_in_l2_lkup | grep -E \"tcp.dst == 179\n AT_CHECK([ovn-sbctl dump-flows ls | grep ls_in_l2_lkup | grep \"arp.op == 2 && arp.tpa == 172.16.1.1\" | ovn_strip_lflows], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=100 , match=(arp.op == 2 && arp.tpa == 172.16.1.1), action=(clone { outport = \"lsp-bgp\"; output; }; outport = \"ls-lr\"; output;)\n ])\n-AT_CHECK([ovn-sbctl dump-flows ls | grep ls_in_l2_lkup | grep \"&& nd_na\" | ovn_strip_lflows], [0], [dnl\n+AT_CHECK([ovn-sbctl dump-flows ls | grep ls_in_l2_lkup | grep \"ip6.dst == .* && nd_na\" | ovn_strip_lflows], [0], [dnl\n table=??(ls_in_l2_lkup ), priority=100 , match=(ip6.dst == fe80::ac:10ff:fe01:1 && nd_na), action=(clone { outport = \"lsp-bgp\"; output; }; outport = \"ls-lr\"; output;)\n ])\n \n", "prefixes": [ "ovs-dev" ] }