[{"id":3682724,"web_url":"http://patchwork.ozlabs.org/comment/3682724/","msgid":"<ae9pvKqxiKzzT_fp@lore-desk>","list_archive_url":null,"date":"2026-04-27T13:50:52","subject":"Re: [ovs-dev] [PATCH v2 ovn] northd: Use MC_UNKNOWN for broadcast\n ARP requests.","submitter":{"id":73083,"url":"http://patchwork.ozlabs.org/api/people/73083/","name":"Lorenzo Bianconi","email":"lorenzo.bianconi@redhat.com"},"content":"> In the OVN logical switch pipeline, broadcast ARP requests (and ND_NS)\n> generated by VIFs and by router ports are also flooded into the per switch\n> MC_FLOOD_L2 multicast group which includes all non-router ports of the\n> switch.\n> In deployments with large logical broadcast domains (logical switches with\n> a significantly large number of switch ports, e.g. 200+) this becomes a\n> problem because the MC_FLOOD_L2 multicast group has a lot of ports so the\n> chain of the OpenFlow tables that the packet needs to traverse for full\n> processing becomes really long, going over OVS' 4K resubmit limit and\n> causing the packet to be dropped.\n> The main reason why the ARP packets are currently sent to all non-router\n> ports 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,\n> which might avoid future ARP requests from other workloads; and it's not a\n> requirement, nothing would really break if we didn't forward those packets\n> to all other VIFs.\n> It's probably acceptable to change the behavior and just forward these ARP\n> requests to the ports that have LSP.addresses=\"unknown\" as the workloads\n> behind those ports (or the fabric for the localnet case) might actually own\n> the arp.tpa target IP.\n> \n> Reported-at: https://redhat.atlassian.net/browse/FDP-3439\n> Co-authored-by: Dumitru Ceara <dceara@redhat.com>\n> Signed-off-by: Dumitru Ceara <dceara@redhat.com>\n\n@Dumitru: I kept your SoB here but I was not sure about it. Please let me know\nif you are fine or not with it.\n\nRegards,\nLorenzo\n\n> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>\n> ---\n> Changes 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(-)\n> \n> diff --git a/northd/northd.c b/northd/northd.c\n> index 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>  \n> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml\n> index 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>  \n> diff --git a/ovs b/ovs\n> index bdb95cc19..6aefe1db3 160000\n> --- a/ovs\n> +++ b/ovs\n> @@ -1 +1 @@\n> -Subproject commit bdb95cc1920d4ab66fe062a9470eeb33a51d33e2\n> +Subproject commit 6aefe1db31e3df4e7b64c21f54a7287e4663e1e4\n> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at\n> index 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\n> diff --git a/tests/ovn.at b/tests/ovn.at\n> index 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> -- \n> 2.53.0\n>","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=WwNU7sYN;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=google header.b=EW6v0UbP;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)","smtp3.osuosl.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key)\n header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=WwNU7sYN;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=google header.b=EW6v0UbP","smtp4.osuosl.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com","smtp4.osuosl.org;\n dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com\n header.a=rsa-sha256 header.s=mimecast20190719 header.b=WwNU7sYN;\n dkim=pass (2048-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=google header.b=EW6v0UbP"],"Received":["from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g44jC3yNTz1xvV\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 27 Apr 2026 23:51:11 +1000 (AEST)","from localhost (localhost [127.0.0.1])\n\tby smtp3.osuosl.org (Postfix) with ESMTP id E2BC36F691;\n\tMon, 27 Apr 2026 13:51:09 +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 mkI8SVKoq6xD; Mon, 27 Apr 2026 13:51:07 +0000 (UTC)","from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])\n\tby smtp3.osuosl.org (Postfix) with ESMTPS id D22176071D;\n\tMon, 27 Apr 2026 13:51:06 +0000 (UTC)","from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id C3D11C04FB;\n\tMon, 27 Apr 2026 13:51:06 +0000 (UTC)","from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137])\n by lists.linuxfoundation.org (Postfix) with ESMTP id C3F85C04FA\n for <ovs-dev@openvswitch.org>; Mon, 27 Apr 2026 13:51:05 +0000 (UTC)","from localhost (localhost [127.0.0.1])\n by smtp4.osuosl.org (Postfix) with ESMTP id C22BC44F3E\n for <ovs-dev@openvswitch.org>; Mon, 27 Apr 2026 13:51:05 +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 YXqjoSlTJonI for <ovs-dev@openvswitch.org>;\n Mon, 27 Apr 2026 13:51:03 +0000 (UTC)","from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by smtp4.osuosl.org (Postfix) with ESMTPS id 1C04D44ED2\n for <ovs-dev@openvswitch.org>; Mon, 27 Apr 2026 13:51:02 +0000 (UTC)","from mail-wm1-f72.google.com (mail-wm1-f72.google.com\n [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-110-TL4E84qHN9WmgtAfpJKGNA-1; Mon, 27 Apr 2026 09:50:59 -0400","by mail-wm1-f72.google.com with SMTP id\n 5b1f17b1804b1-488c768a9a9so67770735e9.1\n for <ovs-dev@openvswitch.org>; Mon, 27 Apr 2026 06:50:58 -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-488fc0b4c85sm760530205e9.0.2026.04.27.06.50.53\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Mon, 27 Apr 2026 06:50:53 -0700 (PDT)"],"X-Virus-Scanned":["amavis at osuosl.org","amavis at osuosl.org"],"X-Comment":"SPF check N/A for local connections - client-ip=140.211.9.56;\n helo=lists.linuxfoundation.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN> ","DKIM-Filter":["OpenDKIM Filter v2.11.0 smtp3.osuosl.org D22176071D","OpenDKIM Filter v2.11.0 smtp4.osuosl.org 1C04D44ED2"],"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 smtp4.osuosl.org 1C04D44ED2","DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1777297861;\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 in-reply-to:in-reply-to:references:references;\n bh=ML0t7r96f6/d1OD9Hzm5YXyuU+UODnVJFszj1ADf7OY=;\n b=WwNU7sYNXPufeD4uxWIawnL91Ugmkqe7RJ4W0OsEZK262nMCCCBZ6YGf61xaD4qYgMH91X\n 8ev48/MCUsdccoA9EOlqwRGuHwZx8Zw/pEuklhkAk1C4KY4IHDBvZ+M7ClniIXgAr2MbM/\n GxWCFXr7ia1FoP/KzYu+8/yeJZSnqSs=","v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=redhat.com; s=google; t=1777297857; x=1777902657; darn=openvswitch.org;\n h=in-reply-to:content-disposition:mime-version:references:message-id\n :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to;\n bh=ML0t7r96f6/d1OD9Hzm5YXyuU+UODnVJFszj1ADf7OY=;\n b=EW6v0UbPCBfMc+kSC4f1k7yWoXE5DnjPbPCWxXfen7ImQY3RhnCsvnoG5OdrvhEs+C\n InSV1S19RolPajyVEapXqk0ZJcXCHOBV7/cczYPH1T6VuGEU8tlS/ia4QNyQ1jqw/jk0\n Qs9KksxxC3AUkRhsaNtB7dICc/am9pGbKQk8wmJckkKa4KTEPY4jerFe3Kt4BmuRSD76\n Wo16c0h2pXJf2iD7jiGTDi9DxWYOoLYFLaYan2Klu1VZcDDCNUZFUZ7aj8053HbLIyac\n TjQDYXDJztRU7iaEH13IvsgtSvMXIpHw/4FdhtXFTzcqYgFcxuGGpr0zgHIR3EOe8s8X\n jK2A=="],"X-MC-Unique":"TL4E84qHN9WmgtAfpJKGNA-1","X-Mimecast-MFC-AGG-ID":"TL4E84qHN9WmgtAfpJKGNA_1777297858","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777297857; x=1777902657;\n h=in-reply-to:content-disposition:mime-version:references:message-id\n :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc\n :subject:date:message-id:reply-to;\n bh=ML0t7r96f6/d1OD9Hzm5YXyuU+UODnVJFszj1ADf7OY=;\n b=IjPYXFY7YqS6zYo73zCnAOpLjKAblZ+htPIiOTbMzGArWBjXapHBUH9u91HRKkBQbo\n B6J1e9R5JBrKbrXQSXFoT0Q1i9jfC56jEe7AHJjHU7y7+bSZaLe92bunPI9PEIJbuMpP\n GvIlQi/IkEWHyGS/ROByXfgy2aGvwIoktNSChTXO5lWX2LEVZgwWPH2iR5hJcIYi6EPw\n 2WcCyml79KMgpWA4tgEJY0Gxvn7t1HL5dEWcnqR3t20gSeL3fsqH3f8G+ERC4fNHXCwi\n ZnsqZv5jKiM7WgNPZ+5J0A3K80E1Ub+BVM81NjOVrPyp9b6YvMzEKkdtGqP3LDvdDIMk\n L61w==","X-Gm-Message-State":"AOJu0Yzf0AJeG4pzO5j7ITS6YnJKa1xzjqBapO9wDxu1twrkvPjV7rxG\n EHQwHYTzVFsMNgqyKNlQQSWLFJADnExe1vNH/TkoIu+CG1cDXqd+OvUZK73B4xomyiF/5qfIi47\n hjR9v5sK6WofcHt1sFoZtqtohjLI5SJQy7o2U2l3MXjMowxZUEKdxaWWrOiMfP0YdIKdD+IfX43\n Fjqi1+NM/rDMviUMYll3hGx1gv6TGhOsBuz9JTGZ8ZojbnQsMNqE3t4Q==","X-Gm-Gg":"AeBDieuGg+puIqGtfXdWJ8Y9U/T7ich8KZ8gNsB3FemPnN5BsOs4tL3/B0crZucuz4h\n PpPbOnA9kicdO9vL9n0bv2XoEEuLwGFAZE6m3h4u1AocrJEG2Zj8jN88nBbxYaFqfUl1W7JgOwS\n D3DhBkhfzyCHicacSOkuhgvzutnFoMMSVWp0KkLmQI1S8FuGDTvK05bI0pl4r+qJpxCrvPOLftD\n FX274VppzPdcmzkN7A7/w0376ejV4fdewFsX1JWfvUJ/thRKgyyoi82RCY/zHX/5b3duCFInsrk\n kRbK8qH7XpCp0Gb9BAnOHNPrwPcfWTqOabweZc4lhdzt6pqyyIfKn67EHbWNXr1DMbwTyDT7VNg\n 6ByF/f0tpzxuCBWO1TsjwtBbedpgRuWtvvOMJCT7Gq88ufsXKemMg3v83131yb5k6wAEf0KuaJg\n dbGB0X","X-Received":["by 2002:a05:600c:a414:b0:48a:53ea:13e6 with SMTP id\n 5b1f17b1804b1-48a53ea14d3mr319149865e9.25.1777297856156;\n Mon, 27 Apr 2026 06:50:56 -0700 (PDT)","by 2002:a05:600c:a414:b0:48a:53ea:13e6 with SMTP id\n 5b1f17b1804b1-48a53ea14d3mr319148965e9.25.1777297854423;\n Mon, 27 Apr 2026 06:50:54 -0700 (PDT)"],"Date":"Mon, 27 Apr 2026 15:50:52 +0200","To":"ovs-dev@openvswitch.org","Message-ID":"<ae9pvKqxiKzzT_fp@lore-desk>","References":"\n <171501687c9645e941e2903c2b52876e21bd3d7c.1777295725.git.lorenzo.bianconi@redhat.com>","MIME-Version":"1.0","In-Reply-To":"\n <171501687c9645e941e2903c2b52876e21bd3d7c.1777295725.git.lorenzo.bianconi@redhat.com>","X-Content-Filtered-By":"Mailman/MimeDel 2.1.30","Subject":"Re: [ovs-dev] [PATCH v2 ovn] northd: Use MC_UNKNOWN for broadcast\n ARP 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":"multipart/mixed; boundary=\"===============6112050144574876685==\"","Errors-To":"ovs-dev-bounces@openvswitch.org","Sender":"\"dev\" <ovs-dev-bounces@openvswitch.org>"}},{"id":3683175,"web_url":"http://patchwork.ozlabs.org/comment/3683175/","msgid":"<8c5fdc70-d172-4441-ac53-abea501b9817@redhat.com>","list_archive_url":null,"date":"2026-04-28T07:17:17","subject":"Re: [ovs-dev] [PATCH v2 ovn] northd: Use MC_UNKNOWN for broadcast\n ARP requests.","submitter":{"id":76591,"url":"http://patchwork.ozlabs.org/api/people/76591/","name":"Dumitru Ceara","email":"dceara@redhat.com"},"content":"On 4/27/26 3:50 PM, Lorenzo Bianconi wrote:\n>> In the OVN logical switch pipeline, broadcast ARP requests (and ND_NS)\n>> generated by VIFs and by router ports are also flooded into the per switch\n>> MC_FLOOD_L2 multicast group which includes all non-router ports of the\n>> switch.\n>> In deployments with large logical broadcast domains (logical switches with\n>> a significantly large number of switch ports, e.g. 200+) this becomes a\n>> problem because the MC_FLOOD_L2 multicast group has a lot of ports so the\n>> chain of the OpenFlow tables that the packet needs to traverse for full\n>> processing becomes really long, going over OVS' 4K resubmit limit and\n>> causing the packet to be dropped.\n>> The main reason why the ARP packets are currently sent to all non-router\n>> ports 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,\n>> which might avoid future ARP requests from other workloads; and it's not a\n>> requirement, nothing would really break if we didn't forward those packets\n>> to all other VIFs.\n>> It's probably acceptable to change the behavior and just forward these ARP\n>> requests to the ports that have LSP.addresses=\"unknown\" as the workloads\n>> behind those ports (or the fabric for the localnet case) might actually own\n>> the arp.tpa target IP.\n>>\n>> Reported-at: https://redhat.atlassian.net/browse/FDP-3439\n>> Co-authored-by: Dumitru Ceara <dceara@redhat.com>\n>> Signed-off-by: Dumitru Ceara <dceara@redhat.com>\n> \n> @Dumitru: I kept your SoB here but I was not sure about it. Please let me know\n> if you are fine or not with it.\n> \n\nHi Lorenzo,\n\nI guess that's fine.  I do have some comments below.\n\n> Regards,\n> Lorenzo\n> \n>> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>\n>> ---\n>> Changes 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(-)\n>>\n>> diff --git a/northd/northd.c b/northd/northd.c\n>> index 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\nWhat about IPv6 gratuitous NS?  Now those go to MC_UNKNOWN while they\nused to go to MC_FLOOD_L2.  Do we need a similar change for IPv6 as you\ndo here for\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>>  \n>> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml\n>> index 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>>  \n>> diff --git a/ovs b/ovs\n>> index bdb95cc19..6aefe1db3 160000\n>> --- a/ovs\n>> +++ b/ovs\n>> @@ -1 +1 @@\n>> -Subproject commit bdb95cc1920d4ab66fe062a9470eeb33a51d33e2\n>> +Subproject commit 6aefe1db31e3df4e7b64c21f54a7287e4663e1e4\n>> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at\n>> index 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\nThis is the IPv6 flow I mentioned above, now we'd only flood gratuitous\nNS from this router port owned IPv6 address to MC_UNKNOWN, not to any\nVIFs we might have in the system.\n\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\n>> diff --git a/tests/ovn.at b/tests/ovn.at\n>> index 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>> -- \n>> 2.53.0\n>>\n\nRegards,\nDumitru","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=JENOj/pD;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)","smtp1.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=JENOj/pD","smtp4.osuosl.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com","smtp4.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=JENOj/pD"],"Received":["from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138])\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 4g4Wwh0LGmz1yHv\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 28 Apr 2026 17:17:39 +1000 (AEST)","from localhost (localhost [127.0.0.1])\n\tby smtp1.osuosl.org (Postfix) with ESMTP id DEE6D82C8F;\n\tTue, 28 Apr 2026 07:17:37 +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 54FA21vf-Kr4; Tue, 28 Apr 2026 07:17:34 +0000 (UTC)","from lists.linuxfoundation.org (lf-lists.osuosl.org\n [IPv6:2605:bc80:3010:104::8cd3:938])\n\tby smtp1.osuosl.org (Postfix) with ESMTPS id C95E282CA5;\n\tTue, 28 Apr 2026 07:17:34 +0000 (UTC)","from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id ACD43C04FB;\n\tTue, 28 Apr 2026 07:17:34 +0000 (UTC)","from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 1A25EC04FA\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 07:17:34 +0000 (UTC)","from localhost (localhost [127.0.0.1])\n by smtp4.osuosl.org (Postfix) with ESMTP id 063544106F\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 07:17:34 +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 uZ85CPd0xRAa for <ovs-dev@openvswitch.org>;\n Tue, 28 Apr 2026 07:17:31 +0000 (UTC)","from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.129.124])\n by smtp4.osuosl.org (Postfix) with ESMTPS id 6DB644106E\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 07:17:30 +0000 (UTC)","from mail-qk1-f199.google.com (mail-qk1-f199.google.com\n [209.85.222.199]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-163-7CeQoJL0OsOHIsXP-vCWqA-1; Tue, 28 Apr 2026 03:17:26 -0400","by mail-qk1-f199.google.com with SMTP id\n af79cd13be357-8cb706313beso1423929085a.3\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 00:17:26 -0700 (PDT)","from ?IPV6:2001:1c05:1417:d800:d1ef:9817:2a26:625d?\n (2001-1c05-1417-d800-d1ef-9817-2a26-625d.cable.dynamic.v6.ziggo.nl.\n [2001:1c05:1417:d800:d1ef:9817:2a26:625d])\n by smtp.gmail.com with ESMTPSA id\n af79cd13be357-8f7c8a94392sm125206085a.46.2026.04.28.00.17.20\n (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n Tue, 28 Apr 2026 00:17:21 -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 smtp1.osuosl.org C95E282CA5","OpenDKIM Filter v2.11.0 smtp4.osuosl.org 6DB644106E"],"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 smtp4.osuosl.org 6DB644106E","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1777360648;\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 in-reply-to:in-reply-to:references:references;\n bh=LqLXmb47LTWaf/KC4RfFe9e3HwBXtMgbbhrPXnNZIXY=;\n b=JENOj/pDIHvZIcNUEtPsd5zJMnOrjp9vM2N25IJDF5wb2g2cvK5G/laVFjS4Aj5x5XLfex\n bttuaJi1R6w7fL4XD1RoCle/Fe95DWiJ9xJyVTvLWo6dKJpJyxshYJ2DRZTrQZZ0Zfwxvz\n JNfwyJTBhn+a9XTOu+lCBmwmSfWt87k=","X-MC-Unique":"7CeQoJL0OsOHIsXP-vCWqA-1","X-Mimecast-MFC-AGG-ID":"7CeQoJL0OsOHIsXP-vCWqA_1777360646","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777360645; x=1777965445;\n h=content-transfer-encoding:in-reply-to:content-language:from\n :references:cc:to:subject:user-agent:mime-version:date:message-id\n :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id\n :reply-to;\n bh=LqLXmb47LTWaf/KC4RfFe9e3HwBXtMgbbhrPXnNZIXY=;\n b=kU+chqC5EyN+PpW9BTELHmP759EZcUU94/1IMpuBpChUJS1Xc/5y7aWqP6W07cMmcx\n FWk+ogvYeVij6kO23KXkJOfRiT8xCBkqUe2sLEjzENRTGknLe5vrZIdismPWo7uOd77P\n NkJiDH9o9vgcWyH7jhB+D9l+D9Tw0VdfBNplF+EuyNc7gsTp3CvNWA6kOPAUIcqDRL/Y\n VJHQFuFNUyLIdxcDwZhxGdalg/Ag8QA9bm6lfShlfOQ4BWQIE6ATI51j3I3s+WxquNLM\n JpFx8pvLmWUMLs05ZlM92fVKYT6yRE7DxXHke4H7CagkpfPtWCApX0x1c99CXHi81Pti\n w8iQ==","X-Forwarded-Encrypted":"i=1;\n AFNElJ/SlXnqvaTZgC/iQe2lyMvx+edlDZX6FbOWoZRqzxrAVY4TSEyd+NsA5Uce6jdw4XGoMjiYG9dr@openvswitch.org","X-Gm-Message-State":"AOJu0Ywh0l2DeFb7On9e2ARjHvOHCIoqPkcISyoivDWzQxc9Tumb50CU\n LHXwM+R4359nm10wiZ+xcIU0BnzK4HA6fMVoHw6nmqMnZP6xxhzOGgRSk7ik3jWg02FRi7LtdCN\n BmyEeGjXxo/UJwMYS6y0Bz3M4EV02uFox+JmbiJnaT4vffYc0Hn5GsN1IrcKRk2BezW4=","X-Gm-Gg":"AeBDietrI+K8Ul7BdMZtFWXgGDZQ3CJ3AXufbQpP4Xp5f5VOYDlnga1L1QMw/Mt8bXU\n mchY6mEGp6hEtrgmqK3WfrGlEGlv8rA9ZJUCznjWMR7UccinOH/bzHXjARlEGsQDt60Fnzu0pjy\n Ce5e7c5PNlOs10U+kIu0Hl1f1ad6pc4Pz0en75wNJw3kKY1N0Z7LbJ7wjmxokhz+nw3Gz9Dtiip\n TQg5iWwaAfQE0BfdsRLcQBMl5EmklIA03ATrMXq7eXeaURjhUynLvRA3cluIDRfmYU8tW7ZzHgB\n gtNpejdmxJx9qdAiCv8HFJpsRHQX9k/KoJYJmeFugz8DGPliEX1AC6oG3u0VVHQpQEw2OeAHwRE\n F5PGK6tZYT2Wf/ntTspfgA9rf926veqhJ12sfO/TnXg+y2EYT54OqjeVeeeOqDlFfu0ly40U0VU\n fbRP+F7lirBegc+eGa8aIhjV1mj+PIWo1m8nZbg4/ft2/WpBi28/rBn7ShFM1U9zR2XSoVauE3h\n MoRtcbFS1s=","X-Received":["by 2002:a05:620a:f06:b0:8cd:b05a:a631 with SMTP id\n af79cd13be357-8f7d734e89dmr244036485a.16.1777360643904;\n Tue, 28 Apr 2026 00:17:23 -0700 (PDT)","by 2002:a05:620a:f06:b0:8cd:b05a:a631 with SMTP id\n af79cd13be357-8f7d734e89dmr244026885a.16.1777360641851;\n Tue, 28 Apr 2026 00:17:21 -0700 (PDT)"],"Message-ID":"<8c5fdc70-d172-4441-ac53-abea501b9817@redhat.com>","Date":"Tue, 28 Apr 2026 09:17:17 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","To":"Lorenzo Bianconi <lorenzo.bianconi@redhat.com>, ovs-dev@openvswitch.org","References":"\n <171501687c9645e941e2903c2b52876e21bd3d7c.1777295725.git.lorenzo.bianconi@redhat.com>\n <ae9pvKqxiKzzT_fp@lore-desk>","In-Reply-To":"<ae9pvKqxiKzzT_fp@lore-desk>","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"v3HOsi0YA6re5twjQ__N1wkMjkQRu_E81p7Njkvgve8_1777360646","X-Mimecast-Originator":"redhat.com","Content-Language":"en-US","Subject":"Re: [ovs-dev] [PATCH v2 ovn] northd: Use MC_UNKNOWN for broadcast\n ARP 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":"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>"}},{"id":3683262,"web_url":"http://patchwork.ozlabs.org/comment/3683262/","msgid":"<afB1LCwHZVkCKeWh@lore-desk>","list_archive_url":null,"date":"2026-04-28T08:51:56","subject":"Re: [ovs-dev] [PATCH v2 ovn] northd: Use MC_UNKNOWN for broadcast\n ARP requests.","submitter":{"id":73083,"url":"http://patchwork.ozlabs.org/api/people/73083/","name":"Lorenzo Bianconi","email":"lorenzo.bianconi@redhat.com"},"content":"> On 4/27/26 3:50 PM, Lorenzo Bianconi wrote:\n> >> In the OVN logical switch pipeline, broadcast ARP requests (and ND_NS)\n> >> generated by VIFs and by router ports are also flooded into the per switch\n> >> MC_FLOOD_L2 multicast group which includes all non-router ports of the\n> >> switch.\n> >> In deployments with large logical broadcast domains (logical switches with\n> >> a significantly large number of switch ports, e.g. 200+) this becomes a\n> >> problem because the MC_FLOOD_L2 multicast group has a lot of ports so the\n> >> chain of the OpenFlow tables that the packet needs to traverse for full\n> >> processing becomes really long, going over OVS' 4K resubmit limit and\n> >> causing the packet to be dropped.\n> >> The main reason why the ARP packets are currently sent to all non-router\n> >> ports 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,\n> >> which might avoid future ARP requests from other workloads; and it's not a\n> >> requirement, nothing would really break if we didn't forward those packets\n> >> to all other VIFs.\n> >> It's probably acceptable to change the behavior and just forward these ARP\n> >> requests to the ports that have LSP.addresses=\"unknown\" as the workloads\n> >> behind those ports (or the fabric for the localnet case) might actually own\n> >> the arp.tpa target IP.\n> >>\n> >> Reported-at: https://redhat.atlassian.net/browse/FDP-3439\n> >> Co-authored-by: Dumitru Ceara <dceara@redhat.com>\n> >> Signed-off-by: Dumitru Ceara <dceara@redhat.com>\n> > \n> > @Dumitru: I kept your SoB here but I was not sure about it. Please let me know\n> > if you are fine or not with it.\n> > \n> \n> Hi Lorenzo,\n> \n> I guess that's fine.  I do have some comments below.\n> \n> > Regards,\n> > Lorenzo\n> > \n> >> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>\n> >> ---\n> >> Changes 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(-)\n> >>\n> >> diff --git a/northd/northd.c b/northd/northd.c\n> >> index 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> \n> What about IPv6 gratuitous NS?  Now those go to MC_UNKNOWN while they\n> used to go to MC_FLOOD_L2.  Do we need a similar change for IPv6 as you\n> do here for\n\nThis is done just for GARP, is there an equivalent for IPv6? let me check.\n\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> >>  \n> >> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml\n> >> index 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> >>  \n> >> diff --git a/ovs b/ovs\n> >> index bdb95cc19..6aefe1db3 160000\n> >> --- a/ovs\n> >> +++ b/ovs\n> >> @@ -1 +1 @@\n> >> -Subproject commit bdb95cc1920d4ab66fe062a9470eeb33a51d33e2\n> >> +Subproject commit 6aefe1db31e3df4e7b64c21f54a7287e4663e1e4\n> >> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at\n> >> index 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> \n> This is the IPv6 flow I mentioned above, now we'd only flood gratuitous\n> NS from this router port owned IPv6 address to MC_UNKNOWN, not to any\n> VIFs we might have in the system.\n\nack, I will fix it.\n\nRegards,\nLorenzo\n\n> \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\n> >> diff --git a/tests/ovn.at b/tests/ovn.at\n> >> index 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> >> -- \n> >> 2.53.0\n> >>\n> \n> Regards,\n> Dumitru\n>","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=IpM13/6u;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=google header.b=TVzFec/5;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=140.211.166.133; helo=smtp2.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)","smtp2.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=IpM13/6u;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=google header.b=TVzFec/5","smtp1.osuosl.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com","smtp1.osuosl.org;\n dkim=pass (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com\n header.a=rsa-sha256 header.s=mimecast20190719 header.b=IpM13/6u;\n dkim=pass (2048-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=google header.b=TVzFec/5"],"Received":["from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133])\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 4g4Z1s3sDFz1yHv\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 28 Apr 2026 18:52:17 +1000 (AEST)","from localhost (localhost [127.0.0.1])\n\tby smtp2.osuosl.org (Postfix) with ESMTP id D001540671;\n\tTue, 28 Apr 2026 08:52:14 +0000 (UTC)","from smtp2.osuosl.org ([127.0.0.1])\n by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id mnp2D1UBR6E5; Tue, 28 Apr 2026 08:52:11 +0000 (UTC)","from lists.linuxfoundation.org (lf-lists.osuosl.org\n [IPv6:2605:bc80:3010:104::8cd3:938])\n\tby smtp2.osuosl.org (Postfix) with ESMTPS id 7E43D4048C;\n\tTue, 28 Apr 2026 08:52:11 +0000 (UTC)","from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id 3F71EC04FB;\n\tTue, 28 Apr 2026 08:52:11 +0000 (UTC)","from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 94657C04FA\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 08:52:09 +0000 (UTC)","from localhost (localhost [127.0.0.1])\n by smtp1.osuosl.org (Postfix) with ESMTP id 8373081271\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 08:52:09 +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 E1dBPeTT-AJA for <ovs-dev@openvswitch.org>;\n Tue, 28 Apr 2026 08:52:07 +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 B462E81258\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 08:52:05 +0000 (UTC)","from mail-wr1-f71.google.com (mail-wr1-f71.google.com\n [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-286-HLAVTC9-M6GAnensAyi5Dg-1; Tue, 28 Apr 2026 04:52:02 -0400","by mail-wr1-f71.google.com with SMTP id\n ffacd0b85a97d-43fe791a398so8612825f8f.0\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 01:52:01 -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 ffacd0b85a97d-4463f994a3fsm4698195f8f.25.2026.04.28.01.51.56\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 28 Apr 2026 01:51:57 -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 smtp2.osuosl.org 7E43D4048C","OpenDKIM Filter v2.11.0 smtp1.osuosl.org B462E81258"],"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 B462E81258","DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1777366324;\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 in-reply-to:in-reply-to:references:references;\n bh=g6vkRqdMyklhRtuy3rr/4VJERp0aEYDw3GUln7DrzcA=;\n b=IpM13/6u100MJ8K5tFk6e9aOQJhS7p81FokjARUGsFf/wpxkocSiqmT0q8KqoNNFBArQHV\n mMLqHbCJOfQz639qALodCzi0s4Gcg4YNLHoD5okuCYxbj68HEE17JRBtKfz3pPYJHvP0u1\n qR5ferTgaXBKON6h+jr+3JYehLPhkLI=","v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=redhat.com; s=google; t=1777366320; x=1777971120; darn=openvswitch.org;\n h=in-reply-to:content-disposition:mime-version:references:message-id\n :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to;\n bh=g6vkRqdMyklhRtuy3rr/4VJERp0aEYDw3GUln7DrzcA=;\n b=TVzFec/54NqXi3Pc2V725bvZzpq4CPOKmLksQgC7Z9plet/fASQRYIXVg6gWTQLNMk\n /KbJIzz72tEyCBn6nFWOP/MivMDyEstBAxA45gTqsaq0UgGO1HYlItnL65O9A9ErDHnk\n RoDpop4UP5tfSClLlLVuLOgwVRRE31w6t67sy/o9FT9dpgZWVaKKPkvA9A6S7n8oHwhv\n /Hib6qo90EovMERAQCSUOm9oMSE4OajhIPXVHtRf8x50A4VeE6PKllde6AXPB62OuJmz\n ZzT+F7FeBOuo2b3U8VYSS6gop4DbTmOAjEWUZU5qX1xZfm2kJjsV7GlmCXr9/uw9RVdu\n 6vSQ=="],"X-MC-Unique":"HLAVTC9-M6GAnensAyi5Dg-1","X-Mimecast-MFC-AGG-ID":"HLAVTC9-M6GAnensAyi5Dg_1777366321","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777366320; x=1777971120;\n h=in-reply-to:content-disposition:mime-version:references:message-id\n :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc\n :subject:date:message-id:reply-to;\n bh=g6vkRqdMyklhRtuy3rr/4VJERp0aEYDw3GUln7DrzcA=;\n b=IOb63zrAdRNXabS8GOFTsRsyagaPW6uEnXCuKSzl66FYelMRTUZIeFxBoM63swQNL8\n xwLklOzFolHXxY+hwytEuEtuLhFPF+9sDPJj+DFHll8dcouc97FM1X6ZKhzW6R12s/HW\n XIO1Jeax3OPd0bDfkK6oqoLyWgOWDPnSHt8GR9e3ETDQGRWSJYe50CZK2ckQ+RZtnBgC\n 504Shfgf4VaSxzfnUI9kRsOkkpT/6w1C9bVVdIWr3G6EVSqHnk0rev7r5wcRG0FOpLP9\n TEZ2i6G1xwQ4z51HQ8lDvXr2wM8adWAmpNOhaBlV52O2gfpAxpxA1v46N6noXoyrLVvn\n +2oA==","X-Gm-Message-State":"AOJu0YzDn0VPAy8WPTLC8M1O9O/HxW6OvJCPLRotYOEU27deX+nctHlW\n 8/46y+XeGeCU9qV4ugEH28d8vzxSgV6dPaZ1F+T5isvcxGXPFEXkKNFV0gTKH7InmIEwgsbHB4a\n suLlsAjMOJM/efpFM3ve5RgdMSnhGF3XjkYed+rkg3Cfv9aPhoGPVDZQvGkADrcBycl4=","X-Gm-Gg":"AeBDiet7OQ/50ZUeq/GWAbRC5QkQ3LJowml78neoI+JxySmJJyqjNQRPThwPiM6CzZt\n /QHnMRwGSFQC5r+eOfpKFdBESHCJh7WMKc7O/SBPmvz0JbMPxWkMp2H7f+UTry05u414Vdxnv2E\n 4BNczB90wEWGnSQxNqeptHMn4jgRKj6Ac78AmcTP7VljAIZYAdtq+1u4retHdnHi2O1lNA56i25\n WL5G0HL2af9qefGU2wYbTD8KijRxxRJCKFFh37x4XT+mfa97DR4XnlDd8FUSva0cT/1OTfkFQaq\n ntRptJPyQWHuzb6UsPfgii0tyFPHeecDet5I+8oADRGodc+fsl1kHemBbjkhnXy3jpMcL9lGmIs\n 7AobBLrF4dhKkDJO7E505HcT4s61FVBg7UzOqEbM4+vAIRFO1jIJYj2pGBTKPQMdUai0R6FgndI\n DUYD2U","X-Received":["by 2002:a05:6000:184d:b0:442:d9c0:799c with SMTP id\n ffacd0b85a97d-446448b8703mr3864597f8f.0.1777366319593;\n Tue, 28 Apr 2026 01:51:59 -0700 (PDT)","by 2002:a05:6000:184d:b0:442:d9c0:799c with SMTP id\n ffacd0b85a97d-446448b8703mr3864444f8f.0.1777366317976;\n Tue, 28 Apr 2026 01:51:57 -0700 (PDT)"],"Date":"Tue, 28 Apr 2026 10:51:56 +0200","To":"Dumitru Ceara <dceara@redhat.com>","Message-ID":"<afB1LCwHZVkCKeWh@lore-desk>","References":"\n <171501687c9645e941e2903c2b52876e21bd3d7c.1777295725.git.lorenzo.bianconi@redhat.com>\n <ae9pvKqxiKzzT_fp@lore-desk>\n <8c5fdc70-d172-4441-ac53-abea501b9817@redhat.com>","MIME-Version":"1.0","In-Reply-To":"<8c5fdc70-d172-4441-ac53-abea501b9817@redhat.com>","X-Content-Filtered-By":"Mailman/MimeDel 2.1.30","Subject":"Re: [ovs-dev] [PATCH v2 ovn] northd: Use MC_UNKNOWN for broadcast\n ARP 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":"ovs-dev@openvswitch.org","Content-Type":"multipart/mixed; boundary=\"===============7635138318304311026==\"","Errors-To":"ovs-dev-bounces@openvswitch.org","Sender":"\"dev\" <ovs-dev-bounces@openvswitch.org>"}},{"id":3683536,"web_url":"http://patchwork.ozlabs.org/comment/3683536/","msgid":"<afDPjvW-7wlOoStl@lore-desk>","list_archive_url":null,"date":"2026-04-28T15:17:34","subject":"Re: [ovs-dev] [PATCH v2 ovn] northd: Use MC_UNKNOWN for broadcast\n ARP requests.","submitter":{"id":73083,"url":"http://patchwork.ozlabs.org/api/people/73083/","name":"Lorenzo Bianconi","email":"lorenzo.bianconi@redhat.com"},"content":"On Apr 28, Lorenzo Bianconi wrote:\n> > On 4/27/26 3:50 PM, Lorenzo Bianconi wrote:\n> > >> In the OVN logical switch pipeline, broadcast ARP requests (and ND_NS)\n> > >> generated by VIFs and by router ports are also flooded into the per switch\n> > >> MC_FLOOD_L2 multicast group which includes all non-router ports of the\n> > >> switch.\n> > >> In deployments with large logical broadcast domains (logical switches with\n> > >> a significantly large number of switch ports, e.g. 200+) this becomes a\n> > >> problem because the MC_FLOOD_L2 multicast group has a lot of ports so the\n> > >> chain of the OpenFlow tables that the packet needs to traverse for full\n> > >> processing becomes really long, going over OVS' 4K resubmit limit and\n> > >> causing the packet to be dropped.\n> > >> The main reason why the ARP packets are currently sent to all non-router\n> > >> ports 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,\n> > >> which might avoid future ARP requests from other workloads; and it's not a\n> > >> requirement, nothing would really break if we didn't forward those packets\n> > >> to all other VIFs.\n> > >> It's probably acceptable to change the behavior and just forward these ARP\n> > >> requests to the ports that have LSP.addresses=\"unknown\" as the workloads\n> > >> behind those ports (or the fabric for the localnet case) might actually own\n> > >> the arp.tpa target IP.\n> > >>\n> > >> Reported-at: https://redhat.atlassian.net/browse/FDP-3439\n> > >> Co-authored-by: Dumitru Ceara <dceara@redhat.com>\n> > >> Signed-off-by: Dumitru Ceara <dceara@redhat.com>\n> > > \n> > > @Dumitru: I kept your SoB here but I was not sure about it. Please let me know\n> > > if you are fine or not with it.\n> > > \n> > \n> > Hi Lorenzo,\n> > \n> > I guess that's fine.  I do have some comments below.\n> > \n> > > Regards,\n> > > Lorenzo\n> > > \n> > >> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>\n> > >> ---\n> > >> Changes 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(-)\n> > >>\n> > >> diff --git a/northd/northd.c b/northd/northd.c\n> > >> index 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> > \n> > What about IPv6 gratuitous NS?  Now those go to MC_UNKNOWN while they\n> > used to go to MC_FLOOD_L2.  Do we need a similar change for IPv6 as you\n> > do here for\n> \n> This is done just for GARP, is there an equivalent for IPv6? let me check.\n\nAccording to my understanding the GARP IPv6 equivalent are unsolicited\nNeighbor Advertisement packets. Reviewing the code, OVN logical router does not\nsupport them, so I guess we do not need any extra flows here. What do you think?\n\nRegards,\nLorenzo\n\n> \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> > >>  \n> > >> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml\n> > >> index 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> > >>  \n> > >> diff --git a/ovs b/ovs\n> > >> index bdb95cc19..6aefe1db3 160000\n> > >> --- a/ovs\n> > >> +++ b/ovs\n> > >> @@ -1 +1 @@\n> > >> -Subproject commit bdb95cc1920d4ab66fe062a9470eeb33a51d33e2\n> > >> +Subproject commit 6aefe1db31e3df4e7b64c21f54a7287e4663e1e4\n> > >> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at\n> > >> index 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> > \n> > This is the IPv6 flow I mentioned above, now we'd only flood gratuitous\n> > NS from this router port owned IPv6 address to MC_UNKNOWN, not to any\n> > VIFs we might have in the system.\n> \n> ack, I will fix it.\n> \n> Regards,\n> Lorenzo\n> \n> > \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\n> > >> diff --git a/tests/ovn.at b/tests/ovn.at\n> > >> index 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> > >> -- \n> > >> 2.53.0\n> > >>\n> > \n> > Regards,\n> > Dumitru\n> >","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=OXimXXU4;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=google header.b=Qg7E2mUE;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)","smtp1.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=OXimXXU4;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key)\n header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=google\n header.b=Qg7E2mUE","smtp1.osuosl.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com"],"Received":["from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138])\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 4g4kZr39Wzz1xvV\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 29 Apr 2026 01:17:56 +1000 (AEST)","from localhost (localhost [127.0.0.1])\n\tby smtp1.osuosl.org (Postfix) with ESMTP id 82AE08225B;\n\tTue, 28 Apr 2026 15:17:54 +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 mUQbjxdMRDYz; Tue, 28 Apr 2026 15:17:49 +0000 (UTC)","from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])\n\tby smtp1.osuosl.org (Postfix) with ESMTPS id BAA4082201;\n\tTue, 28 Apr 2026 15:17:49 +0000 (UTC)","from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id 92DCEC04FB;\n\tTue, 28 Apr 2026 15:17:49 +0000 (UTC)","from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 75A9BC04FA\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 15:17:48 +0000 (UTC)","from localhost (localhost [127.0.0.1])\n by smtp1.osuosl.org (Postfix) with ESMTP id 6155582201\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 15:17:48 +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 J_k57GSD0dv9 for <ovs-dev@openvswitch.org>;\n Tue, 28 Apr 2026 15:17:46 +0000 (UTC)","from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.129.124])\n by smtp1.osuosl.org (Postfix) with ESMTPS id BFBC4821D9\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 15:17:45 +0000 (UTC)","from mail-vs1-f71.google.com (mail-vs1-f71.google.com\n [209.85.217.71]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-515-jD9LwM1SMaapCbQHLWK7og-1; Tue, 28 Apr 2026 11:17:40 -0400","by mail-vs1-f71.google.com with SMTP id\n ada2fe7eead31-611af0d600bso4818788137.2\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 08:17:40 -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 6a1803df08f44-8b3e281bd11sm22973626d6.8.2026.04.28.08.17.35\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 28 Apr 2026 08:17:35 -0700 (PDT)"],"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 smtp1.osuosl.org BAA4082201","OpenDKIM Filter v2.11.0 smtp1.osuosl.org BFBC4821D9"],"Received-SPF":"Pass (mailfrom) identity=mailfrom; client-ip=170.10.129.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 BFBC4821D9","DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1777389463;\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 in-reply-to:in-reply-to:references:references;\n bh=JkHod2syEcgW5NfX9q2vPq1oXItPfkn3/O+35H8FTC0=;\n b=OXimXXU4nlOSoEWchKgarcLQ6dFFKpP0qboONtQi0D/JA4ef8pDhIN9BiqaVcIzNnJRltB\n RbJ9iP3bkAIrnpD+9pucwWPl7SpIUsRFORN6kAbmxBn6R752FYE/xmkZTtN6mp/ywIWG3b\n Fq2lJGtscMJEFpxRRiqPJpG59F1GZaE=","v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=redhat.com; s=google; t=1777389460; x=1777994260; darn=openvswitch.org;\n h=in-reply-to:content-disposition:mime-version:references:message-id\n :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to;\n bh=JkHod2syEcgW5NfX9q2vPq1oXItPfkn3/O+35H8FTC0=;\n b=Qg7E2mUErA8IgSAOCehWrMLUvRmjIkh4gwPrbog2B1bXmDUPNSi0bpZyBfjXX0R142\n Qr7mJFpSiNgAlaceoXNaDUYPdMzl0b+kZPoil3Q2N0/DGiNQ6FOrho6ybmx3Db16tg9n\n pof1mukh4PlEsQ0ALEDTIe6dArT7OpS5lmQVmtwR2Iui6KV/OvhTI8tPHGmYBUsrtwZr\n Ju+SVArK502s0+w2U5A2O/HUJBJIb0B4vMKky/DgwImE/eM0dSRJUcG+6ffh0ccRKQg2\n XTKQP28Im0OyYrOFiTmwFKra9J9rNEPEVTI924B0c9/xMn/R+W+1twPrZc1vOJQcjjH3\n AoJQ=="],"X-MC-Unique":"jD9LwM1SMaapCbQHLWK7og-1","X-Mimecast-MFC-AGG-ID":"jD9LwM1SMaapCbQHLWK7og_1777389460","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777389460; x=1777994260;\n h=in-reply-to:content-disposition:mime-version:references:message-id\n :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc\n :subject:date:message-id:reply-to;\n bh=JkHod2syEcgW5NfX9q2vPq1oXItPfkn3/O+35H8FTC0=;\n b=dZjeYdjjjqiwvkqZCIGiiMXjQErtCflhFUA2mvLqxAcwgwsOyOEr6BySkqAwJAFLvP\n AcZygAnP0mEkBYmB4Vcw8Lel0p6wb0ZgsKRnQ30klP4OgbhmHe420RNGPs2aY3hYY4zP\n H37HM81W15kRGMuLzhWU+jiMASYZjNsQuKCEOxYRnmnck4gJiVIy7aDKbqa8LKAFhViZ\n io1AkxzJYqgccqp/Ghb2JUeThtLkRKdvgfNpXdmcWY4SCpItJB4vXwc6MIp4cK5h0aGD\n 9A0rNmiTIp7Rdq/+fNbt6m7ImPRm2tKyu9QDhORMPKF712LMgK377wW+NwZFVIoQn+q7\n utCg==","X-Gm-Message-State":"AOJu0YznZeTiZdaSQoKGAO2Nn4Pw937pfyDygdXZyjmaQuDJNG9AoT1Y\n g3b0vHw/uZMhwKblxYjQWQGWEYkQwTJy2gRQ/ZrNLl0VEd0NB3UYU4a2gwPKORqVUDZJwNnjjTf\n WtfaSSeR1bhhkm65zcvvrI0s8FO7dAaaGNMxrMuBqnr1T0vbNhuJFRd63ELs=","X-Gm-Gg":"AeBDiet1NskPCGOp/WsE/Y0pHifcAejNNoppZga6NfJ2rQy4rJ2fHTgXL8ZFv/ulAQd\n VSvDRhFhX9sXlDy+H+iT39QsOYzGCT1wPxBIVyHirQiKzLh8jVO0lYGGAArehlDHTD849ta0W8F\n Ufjq8QdNtHIuuZm21VbAfoSVhSJp/zadgl2ZxkH9oOitGjK0gVKjewg0KnaS600lDQhOzjX4YdB\n E+SQFnkOu/O5W6l/TFSWRKQhRaNXTQdH/w1rKiqGag4wK8vxvGWdXXVQoSdmnfb2mSUPnp/7RPp\n JvCEDuhqWAUZwuZ1cJa+ODlJzn3EI7HzPr4g8M1cRmOvI5WS/xpKxRrEhROslPr/7fkcOSNK9v4\n zFSVHeacvvd71teiQl377j7ZpHG+kzJHNWsRLcRUJ1+HBUhbqhCLN0uN3xwumlOkFFAagDF6qe+\n 2bz9Lq","X-Received":["by 2002:a05:6102:809e:b0:606:49d:183f with SMTP id\n ada2fe7eead31-6280b1df187mr1674177137.26.1777389458521;\n Tue, 28 Apr 2026 08:17:38 -0700 (PDT)","by 2002:a05:6102:809e:b0:606:49d:183f with SMTP id\n ada2fe7eead31-6280b1df187mr1673983137.26.1777389456844;\n Tue, 28 Apr 2026 08:17:36 -0700 (PDT)"],"Date":"Tue, 28 Apr 2026 17:17:34 +0200","To":"Dumitru Ceara <dceara@redhat.com>","Message-ID":"<afDPjvW-7wlOoStl@lore-desk>","References":"\n <171501687c9645e941e2903c2b52876e21bd3d7c.1777295725.git.lorenzo.bianconi@redhat.com>\n <ae9pvKqxiKzzT_fp@lore-desk>\n <8c5fdc70-d172-4441-ac53-abea501b9817@redhat.com>\n <afB1LCwHZVkCKeWh@lore-desk>","MIME-Version":"1.0","In-Reply-To":"<afB1LCwHZVkCKeWh@lore-desk>","X-Content-Filtered-By":"Mailman/MimeDel 2.1.30","Subject":"Re: [ovs-dev] [PATCH v2 ovn] northd: Use MC_UNKNOWN for broadcast\n ARP 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":"ovs-dev@openvswitch.org","Content-Type":"multipart/mixed; boundary=\"===============6948104891625757894==\"","Errors-To":"ovs-dev-bounces@openvswitch.org","Sender":"\"dev\" <ovs-dev-bounces@openvswitch.org>"}},{"id":3684503,"web_url":"http://patchwork.ozlabs.org/comment/3684503/","msgid":"<afMEDfPKPjBo4PtX@SDGDEU-G5041VBR>","list_archive_url":null,"date":"2026-04-30T07:26:05","subject":"Re: [ovs-dev] [PATCH v2 ovn] northd: Use MC_UNKNOWN for broadcast\n ARP requests.","submitter":{"id":92762,"url":"http://patchwork.ozlabs.org/api/people/92762/","name":"Felix Huettner","email":"felix.huettner@digits.schwarz"},"content":"Am Tue, Apr 28, 2026 at 05:17:34PM +0200 schrieb Lorenzo Bianconi:\n> On Apr 28, Lorenzo Bianconi wrote:\n> > > On 4/27/26 3:50 PM, Lorenzo Bianconi wrote:\n> > > >> In the OVN logical switch pipeline, broadcast ARP requests (and ND_NS)\n> > > >> generated by VIFs and by router ports are also flooded into the per switch\n> > > >> MC_FLOOD_L2 multicast group which includes all non-router ports of the\n> > > >> switch.\n> > > >> In deployments with large logical broadcast domains (logical switches with\n> > > >> a significantly large number of switch ports, e.g. 200+) this becomes a\n> > > >> problem because the MC_FLOOD_L2 multicast group has a lot of ports so the\n> > > >> chain of the OpenFlow tables that the packet needs to traverse for full\n> > > >> processing becomes really long, going over OVS' 4K resubmit limit and\n> > > >> causing the packet to be dropped.\n> > > >> The main reason why the ARP packets are currently sent to all non-router\n> > > >> ports 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,\n> > > >> which might avoid future ARP requests from other workloads; and it's not a\n> > > >> requirement, nothing would really break if we didn't forward those packets\n> > > >> to all other VIFs.\n> > > >> It's probably acceptable to change the behavior and just forward these ARP\n> > > >> requests to the ports that have LSP.addresses=\"unknown\" as the workloads\n> > > >> behind those ports (or the fabric for the localnet case) might actually own\n> > > >> the arp.tpa target IP.\n> > > >>\n> > > >> Reported-at: https://redhat.atlassian.net/browse/FDP-3439\n> > > >> Co-authored-by: Dumitru Ceara <dceara@redhat.com>\n> > > >> Signed-off-by: Dumitru Ceara <dceara@redhat.com>\n> > > > \n> > > > @Dumitru: I kept your SoB here but I was not sure about it. Please let me know\n> > > > if you are fine or not with it.\n> > > > \n> > > \n> > > Hi Lorenzo,\n> > > \n> > > I guess that's fine.  I do have some comments below.\n> > > \n> > > > Regards,\n> > > > Lorenzo\n> > > > \n> > > >> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>\n> > > >> ---\n> > > >> Changes 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(-)\n> > > >>\n> > > >> diff --git a/northd/northd.c b/northd/northd.c\n> > > >> index 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> > > \n> > > What about IPv6 gratuitous NS?  Now those go to MC_UNKNOWN while they\n> > > used to go to MC_FLOOD_L2.  Do we need a similar change for IPv6 as you\n> > > do here for\n> > \n> > This is done just for GARP, is there an equivalent for IPv6? let me check.\n> \n> According to my understanding the GARP IPv6 equivalent are unsolicited\n> Neighbor Advertisement packets. Reviewing the code, OVN logical router does not\n> support them, so I guess we do not need any extra flows here. What do you think?\n\nHi everyone,\n\nthe thing is that endpoints on other VIFs might support handling the\nUNAs, so we would still need to forward the packet there, otherwise we\nhave the same issue as for ipv4 previously.\n\nKeepalived code to send these UNAs https://github.com/acassen/keepalived/blob/master/keepalived/vrrp/vrrp_ndisc.c#L166\nIf i get it right we could filter on the ipv6 src ip being equal to the\nneighbor Advertisement target ip.\nBut not sure if this is generalizable for other implementations.\n\nThanks\nFelix\n\n\n> \n> Regards,\n> Lorenzo\n> \n> > \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> > > >>  \n> > > >> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml\n> > > >> index 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> > > >>  \n> > > >> diff --git a/ovs b/ovs\n> > > >> index bdb95cc19..6aefe1db3 160000\n> > > >> --- a/ovs\n> > > >> +++ b/ovs\n> > > >> @@ -1 +1 @@\n> > > >> -Subproject commit bdb95cc1920d4ab66fe062a9470eeb33a51d33e2\n> > > >> +Subproject commit 6aefe1db31e3df4e7b64c21f54a7287e4663e1e4\n> > > >> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at\n> > > >> index 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> > > \n> > > This is the IPv6 flow I mentioned above, now we'd only flood gratuitous\n> > > NS from this router port owned IPv6 address to MC_UNKNOWN, not to any\n> > > VIFs we might have in the system.\n> > \n> > ack, I will fix it.\n> > \n> > Regards,\n> > Lorenzo\n> > \n> > > \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\n> > > >> diff --git a/tests/ovn.at b/tests/ovn.at\n> > > >> index 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> > > >> -- \n> > > >> 2.53.0\n> > > >>\n> > > \n> > > Regards,\n> > > Dumitru\n> > > \n> \n>","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\" (2048-bit key;\n unprotected) header.d=digits.schwarz header.i=@digits.schwarz\n header.a=rsa-sha256 header.s=google header.b=OFjFlAk3;\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\" (2048-bit key,\n unprotected) header.d=digits.schwarz header.i=@digits.schwarz\n header.a=rsa-sha256 header.s=google header.b=OFjFlAk3","smtp1.osuosl.org; dmarc=pass (p=reject dis=none)\n header.from=digits.schwarz","smtp1.osuosl.org; dkim=pass (2048-bit key,\n unprotected) header.d=digits.schwarz header.i=@digits.schwarz\n header.a=rsa-sha256 header.s=google header.b=OFjFlAk3"],"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 4g5mbQ2FVHz1yGq\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 30 Apr 2026 17:52:00 +1000 (AEST)","from localhost (localhost [127.0.0.1])\n\tby smtp3.osuosl.org (Postfix) with ESMTP id 10E0561BBE;\n\tThu, 30 Apr 2026 07:51:57 +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 fGuEZtOxzZqN; Thu, 30 Apr 2026 07:51:54 +0000 (UTC)","from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])\n\tby smtp3.osuosl.org (Postfix) with ESMTPS id 022A0610D2;\n\tThu, 30 Apr 2026 07:51:54 +0000 (UTC)","from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id CF645C04FB;\n\tThu, 30 Apr 2026 07:51:53 +0000 (UTC)","from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138])\n by lists.linuxfoundation.org (Postfix) with ESMTP id B7856C04FA\n for <ovs-dev@openvswitch.org>; Thu, 30 Apr 2026 07:51:52 +0000 (UTC)","from localhost (localhost [127.0.0.1])\n by smtp1.osuosl.org (Postfix) with ESMTP id 9755484A0F\n for <ovs-dev@openvswitch.org>; Thu, 30 Apr 2026 07:51:52 +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 J4uk5n8duckg for <ovs-dev@openvswitch.org>;\n Thu, 30 Apr 2026 07:51:50 +0000 (UTC)","from mail-lf1-x162.google.com (mail-lf1-x162.google.com\n [IPv6:2a00:1450:4864:20::162])\n by smtp1.osuosl.org (Postfix) with ESMTPS id 46A4D848E3\n for <ovs-dev@openvswitch.org>; Thu, 30 Apr 2026 07:51:47 +0000 (UTC)","by mail-lf1-x162.google.com with SMTP id\n 2adb3069b0e04-5a283c44478so851611e87.3\n for <ovs-dev@openvswitch.org>; Thu, 30 Apr 2026 00:51:47 -0700 (PDT)","from smtpproxy-deployment-76d878d6c6-4p57v.de1.smtp.exclaimer.net\n ([20.170.110.165]) by smtp-relay.gmail.com with ESMTPS id\n 2adb3069b0e04-5a74a73b836sm287506e87.46.2026.04.30.00.51.45\n for <ovs-dev@openvswitch.org>\n (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);\n Thu, 30 Apr 2026 00:51:45 -0700 (PDT)","from mail-ej1-f70.google.com (209.85.218.70) by\n smtpproxy-deployment-76d878d6c6-4p57v.de1.smtp.exclaimer.net\n (20.170.110.160/28) with Exclaimer Signature Manager ESMTP Proxy\n smtpproxy-deployment-76d878d6c6-4p57v.de1.smtp.exclaimer.net\n (tlsversion=TLS12, tlscipher=TLS_DIFFIEHELLMAN_WITH_AES256_NONE); Thu, 30\n Apr 2026 07:51:45 +0000","by mail-ej1-f70.google.com with SMTP id\n a640c23a62f3a-b97ed96ef12so44686366b.3\n for <ovs-dev@openvswitch.org>; Thu, 30 Apr 2026 00:51:44 -0700 (PDT)","from SDGDEU-G5041VBR ([185.124.194.155])\n by smtp.gmail.com with ESMTPSA id\n ffacd0b85a97d-447b7218622sm11003005f8f.21.2026.04.30.00.26.07\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Thu, 30 Apr 2026 00:26:07 -0700 (PDT)"],"X-Virus-Scanned":["amavis at osuosl.org","amavis at osuosl.org"],"X-Comment":"SPF check N/A for local connections - client-ip=140.211.9.56;\n helo=lists.linuxfoundation.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN> ","DKIM-Filter":["OpenDKIM Filter v2.11.0 smtp3.osuosl.org 022A0610D2","OpenDKIM Filter v2.11.0 smtp1.osuosl.org 46A4D848E3"],"Received-SPF":"Pass (mailfrom) identity=mailfrom;\n client-ip=2a00:1450:4864:20::162; helo=mail-lf1-x162.google.com;\n envelope-from=felix.huettner@digits.schwarz; receiver=<UNKNOWN>","DMARC-Filter":"OpenDMARC Filter v1.4.2 smtp1.osuosl.org 46A4D848E3","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777535506; x=1778140306;\n h=in-reply-to:content-disposition:mime-version:references\n :mail-followup-to:message-id:subject:cc:to:from:date:dkim-signature\n :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id\n :reply-to;\n bh=rAoeeYs8PrPzKapY2RdKZrMIlin0BVuNnhgKFs2malw=;\n b=WFVbSoeGRIe86pIHtNgQwEKVn5tLHvVe7G4C1e1d/FaVQULBl25OoK9SfFIlQWVbjd\n wi8znpY3QhjTh165sDaD4xbD4yxj8Cqj6erg27c6cEbxwet8O0uDYFGuwtjK0SkW1HmP\n Kt4NMm39YNKLOj0vEJr5YZrSV5ZG3m4+3tG50OAtzgUZSK1DxB5GbjfyLACySF4jn67a\n QCSbhecotWvlULY+TtrYN4AZiu5d3cAoo60S94FrqerivzLU3G9wD8Kb70/WGF9HjerZ\n /B/rBcyBvOA6aYEBca1i4TMoIoAuQ/8px6hZIKIRXqeE1tW+A5KM/HtsSKrgCgADGd20\n OKDg==","X-Forwarded-Encrypted":["i=1;\n AFNElJ+/D/yKNGQHPj0J4Ix6ZD4fjnH43E00D+XzYb7c8LyMlhdT3kg136GdOWaaSoxHDobaPqJlgs+Q@openvswitch.org","i=1;\n AFNElJ8ptMElElhLKJ4QdrNQuGd+1Xca8n9PXxhd1bmEGpG6P+9FVF8JgyN+1i0BojUwzmfkaeIIYz4G@openvswitch.org"],"X-Gm-Message-State":"AOJu0Yws/3aJtrVyR/ADb302/G6QwSoI6iQlnWUkWP+e7tRFgIY6UtTw\n 5vGB3/EqRREh+0nzt2nXmUSgUGi90N7+erhtGYo3WOmaHimttpV9XRNGrXuaC5Ta2IhM1nYn3A+\n aegMBnlH3IgACrI/y+YW31k5qxj6za4+zgerJ8jLnLSLN7SQAIoRriBUtx6QV3TKCNfKnmu3Fwl\n b9Bbo5chJ6kbw8/s8urhXlN8JFVdw+vZcAwKSZCr8YVFp2tH5lqqrF5QfrEZvkmhtKV/eyWAnGl\n TxgWx6MGb/gH7RHHL0O/XZ1","X-Gm-Gg":"AeBDievRbI2Su1A/LDtmvU2Cx62k6R7V742xCZWFw1lS2d0qxuPZXMgA4rwJnivHJJJ\n omJ9KGD4BocuxAKhl10OJFGO/omC/VL7JZMnayNlaDYxLJgVq5NsNbA7/W6JyM+fW0HAzDxvoJu\n H0pqzVFwTMb8caVHMIG2hZIz64N/32MIrDuG4oXzO/6WQtrWrnpUAiqFa4/uoUkYljvB6ND3QBT\n e85roF9WyBMAMAifUCX0x7su3EYNUV6c4jdhLAx/nxho36Csaw+EedUtk6j1xp9txQQ3QDQEN7I\n eOSVmE9wybkDjoeEIAhNbou9KJmjcm7/yxmoNfk9LTqbdyOa2slhPz/ly2zgYsdbCWWQowWqNa+\n ZUwGywPQ84qsV/j753gKjELeArG/PA2MzMxntiQHd+Ojv8KKrg1xBpn8pUiz/iD/H7E9ok6ny+K\n SmJ0DWgihG2JCFQHna+RBHgxnu7bcjwKaG0Q==","X-Received":["by 2002:a05:6512:1387:b0:5a2:c0ab:b57f with SMTP id\n 2adb3069b0e04-5a8522bc709mr526877e87.14.1777535505367;\n Thu, 30 Apr 2026 00:51:45 -0700 (PDT)","by 2002:a05:600c:4e88:b0:485:7f02:afd5 with SMTP id\n 5b1f17b1804b1-48a84444083mr27033635e9.13.1777533970086;\n Thu, 30 Apr 2026 00:26:10 -0700 (PDT)","by 2002:a05:600c:4e88:b0:485:7f02:afd5 with SMTP id\n 5b1f17b1804b1-48a84444083mr27031885e9.13.1777533968088;\n Thu, 30 Apr 2026 00:26:08 -0700 (PDT)"],"X-Relaying-Domain":"digits.schwarz","X-ExclaimerHostedSignatures-MessageProcessed":"true","X-ExclaimerProxyLatency":"3335573","X-ExclaimerImprintLatency":"0","X-ExclaimerImprintAction":"f47d0720865f46c08c9d74b33bca670e","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=digits.schwarz; s=google; t=1777535504; x=1778140304; darn=openvswitch.org;\n h=in-reply-to:content-disposition:mime-version:references\n :mail-followup-to:message-id:subject:cc:to:from:date:from:to:cc\n :subject:date:message-id:reply-to;\n bh=rAoeeYs8PrPzKapY2RdKZrMIlin0BVuNnhgKFs2malw=;\n b=OFjFlAk35ZP0eZw+xybw63Y6CuhKuH0nQ6gCQwErvyOD4apmYX80ftc3Yf/8Fxcm7t\n Di4vO3n2sZOCS4/nbCeGnw/k6o/YlbHCpLJZutBMGf0Wx4oSCaKHb0CnWnfWPPlK6Mo+\n 0Gfxsxov3CQYyIzaixN95I9AMvIWTaZkJS69C9RPiVKytp/OGqsL+jxdymCQWR5NzMSB\n N2eYubrFXGVmUVjG007VVYmAPfcTxPB/I+ZZGVVc9r288FMxMuWGYg/9swt/ITrHHe8k\n 1lSOJiDBmKqTfcdi6//ttZ10Q0qFf05z8iR5zMbunDZZRWnbYCyWd2iVOWVJpWQK5F35\n PhNw==","Date":"Thu, 30 Apr 2026 09:26:05 +0200","To":"Lorenzo Bianconi <lorenzo.bianconi@redhat.com>","Cc":"Dumitru Ceara <dceara@redhat.com>, ovs-dev@openvswitch.org","Message-ID":"<afMEDfPKPjBo4PtX@SDGDEU-G5041VBR>","Mail-Followup-To":"Lorenzo Bianconi <lorenzo.bianconi@redhat.com>,\n Dumitru Ceara <dceara@redhat.com>, ovs-dev@openvswitch.org","References":"\n <171501687c9645e941e2903c2b52876e21bd3d7c.1777295725.git.lorenzo.bianconi@redhat.com>\n <ae9pvKqxiKzzT_fp@lore-desk>\n <8c5fdc70-d172-4441-ac53-abea501b9817@redhat.com>\n <afB1LCwHZVkCKeWh@lore-desk> <afDPjvW-7wlOoStl@lore-desk>","MIME-Version":"1.0","In-Reply-To":"<afDPjvW-7wlOoStl@lore-desk>","X-please-dont-add-a-signature":"thanks","X-Schwarz-Google-ToExclaimerByDomain":"1","X-Content-Filtered-By":"Mailman/MimeDel 2.1.30","Subject":"Re: [ovs-dev] [PATCH v2 ovn] northd: Use MC_UNKNOWN for broadcast\n ARP 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":"Felix Huettner via dev <ovs-dev@openvswitch.org>","Reply-To":"Felix Huettner <felix.huettner@digits.schwarz>","Content-Type":"multipart/mixed; boundary=\"===============4661078225905497843==\"","Errors-To":"ovs-dev-bounces@openvswitch.org","Sender":"\"dev\" <ovs-dev-bounces@openvswitch.org>"}}]