On Fri, Jun 26, 2026 at 2:09 PM Dumitru Ceara via dev <
[email protected]> wrote:

> The flows in ls_in_l2_lkup, generated by
> build_lswitch_rport_arp_req_flow(), matched ARP requests and
> ND_NS for router-owned IPs without restricting eth.dst to
> broadcast/multicast.  This caused unicast ARP requests
> (eth.dst == router_MAC) to be intercepted and flooded into the
> L2 domain.
>
> On switches with 200+ ports this flooding can exceed the OVS
> 4096 resubmit limit, dropping the packet.
>
> Fix arp_nd_ns_match() to add "eth.dst == ff:ff:ff:ff:ff:ff"
> for IPv4 ARP and "eth.mcast" for IPv6 ND_NS.  This follows
> the precedent set by commit c05c565548 which added the same
> eth.dst restriction to the priority 75 self-originated ARP
> flood flow in the same pipeline stage.
>
> After this fix, unicast ARP and ND requests for router-owned
> IPs fall through to the L2_LKUP stage flows for direct L2
> delivery.
>
> Reported-at: https://issues.redhat.com/browse/FDP-3885
> Assisted-by: Claude Opus 4.6, Claude Code
> Signed-off-by: Dumitru Ceara <[email protected]>
> ---
> NOTE: this depends on 1872d61e34aa ("northd: Use MC_UNKNOWN for
> broadcast ARP requests.") which is only present on the main branch.
> For backporting this fix to 26.03 we'd have to backport its dependency
> too.
> ---
>  northd/northd.c     |   7 +-
>  tests/ovn-northd.at | 265 ++++++++++++++++++++++++--------------------
>  tests/ovn.at        | 206 ++++++++++++++++++++++++++++++++++
>  3 files changed, 358 insertions(+), 120 deletions(-)
>
> diff --git a/northd/northd.c b/northd/northd.c
> index 70033bda0c..cd613f690e 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -9571,9 +9571,12 @@ arp_nd_ns_match(const char *ips, int addr_family,
> struct ds *match)
>      ds_put_cstr(match, FLAGBIT_NOT_VXLAN " && ");
>
>      if (addr_family == AF_INET) {
> -        ds_put_format(match, "arp.op == 1 && arp.tpa == %s", ips);
> +        ds_put_format(match,
> +                      "eth.dst == ff:ff:ff:ff:ff:ff && "
> +                      "arp.op == 1 && arp.tpa == %s", ips);
>      } else {
> -        ds_put_format(match, "nd_ns && nd.target == %s", ips);
> +        ds_put_format(match,
> +                      "eth.mcast && nd_ns && nd.target == %s", ips);
>      }
>  }
>
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 0c98eb7fb5..0c3d5ecfd8 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -5964,9 +5964,9 @@ AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows |
> ovn_strip_lflows], [0], [dnl
>    table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip),
> action=(outport = "_MC_flood_l2"; output;)
>    table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast &&
> (nd_na || nd_rs || nd_ra)), action=(outport = "_MC_flood"; output;)
>    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;)
> -  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;)
> -  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;)
> -  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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.1.1),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.mcast && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone
> {outport = "ls1-ro1"; output; }; outport = "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.1.1 &&
> arp.spa == 192.168.1.1), action=(outport = "_MC_flood_l2"; output;)
>  ])
>
>  ovn-sbctl lflow-list ls2 > ls2_lflows
> @@ -5981,9 +5981,9 @@ AT_CHECK([grep "ls_in_l2_lkup" ls2_lflows |
> ovn_strip_lflows], [0], [dnl
>    table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip),
> action=(outport = "_MC_flood_l2"; output;)
>    table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast &&
> (nd_na || nd_rs || nd_ra)), action=(outport = "_MC_flood"; output;)
>    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;)
> -  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;)
> -  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;)
> -  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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.2.1),
> action=(clone {outport = "ls2-ro2"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.mcast && nd_ns && nd.target == fe80::200:ff:fe00:201), action=(clone
> {outport = "ls2-ro2"; output; }; outport = "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.2.1 &&
> arp.spa == 192.168.2.1), action=(outport = "_MC_flood_l2"; output;)
>  ])
>
>  AS_BOX([Adding some reachable NAT addresses])
> @@ -6006,13 +6006,13 @@ AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows |
> ovn_strip_lflows], [0], [dnl
>    table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip),
> action=(outport = "_MC_flood_l2"; output;)
>    table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast &&
> (nd_na || nd_rs || nd_ra)), action=(outport = "_MC_flood"; output;)
>    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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.100),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.200),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.1.1),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.mcast && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone
> {outport = "ls1-ro1"; output; }; outport = "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.100 &&
> arp.spa == 10.0.0.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.200 &&
> arp.spa == 10.0.0.200), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.1.1 &&
> arp.spa == 192.168.1.1), action=(outport = "_MC_flood_l2"; output;)
>  ])
>
>  ovn-sbctl lflow-list ls2 > ls2_lflows
> @@ -6027,13 +6027,13 @@ AT_CHECK([grep "ls_in_l2_lkup" ls2_lflows |
> ovn_strip_lflows], [0], [dnl
>    table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip),
> action=(outport = "_MC_flood_l2"; output;)
>    table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast &&
> (nd_na || nd_rs || nd_ra)), action=(outport = "_MC_flood"; output;)
>    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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.2.1),
> action=(clone {outport = "ls2-ro2"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 20.0.0.100),
> action=(clone {outport = "ls2-ro2"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 20.0.0.200),
> action=(clone {outport = "ls2-ro2"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.mcast && nd_ns && nd.target == fe80::200:ff:fe00:201), action=(clone
> {outport = "ls2-ro2"; output; }; outport = "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.2.1 &&
> arp.spa == 192.168.2.1), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 20.0.0.100 &&
> arp.spa == 20.0.0.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 20.0.0.200 &&
> arp.spa == 20.0.0.200), action=(outport = "_MC_flood_l2"; output;)
>  ])
>
>  AS_BOX([Adding some unreachable NAT addresses])
> @@ -6056,17 +6056,17 @@ AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows |
> ovn_strip_lflows], [0], [dnl
>    table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip),
> action=(outport = "_MC_flood_l2"; output;)
>    table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast &&
> (nd_na || nd_rs || nd_ra)), action=(outport = "_MC_flood"; output;)
>    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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.100),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.200),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.1.1),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 30.0.0.100),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 30.0.0.200),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.mcast && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone
> {outport = "ls1-ro1"; output; }; outport = "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.100 &&
> arp.spa == 10.0.0.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.200 &&
> arp.spa == 10.0.0.200), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.1.1 &&
> arp.spa == 192.168.1.1), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 30.0.0.100 &&
> arp.spa == 30.0.0.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 30.0.0.200 &&
> arp.spa == 30.0.0.200), action=(outport = "_MC_flood_l2"; output;)
>  ])
>
>  ovn-sbctl lflow-list ls2 > ls2_lflows
> @@ -6081,17 +6081,17 @@ AT_CHECK([grep "ls_in_l2_lkup" ls2_lflows |
> ovn_strip_lflows], [0], [dnl
>    table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip),
> action=(outport = "_MC_flood_l2"; output;)
>    table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast &&
> (nd_na || nd_rs || nd_ra)), action=(outport = "_MC_flood"; output;)
>    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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.2.1),
> action=(clone {outport = "ls2-ro2"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 20.0.0.100),
> action=(clone {outport = "ls2-ro2"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 20.0.0.200),
> action=(clone {outport = "ls2-ro2"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 40.0.0.100),
> action=(clone {outport = "ls2-ro2"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 40.0.0.200),
> action=(clone {outport = "ls2-ro2"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.mcast && nd_ns && nd.target == fe80::200:ff:fe00:201), action=(clone
> {outport = "ls2-ro2"; output; }; outport = "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.2.1 &&
> arp.spa == 192.168.2.1), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 20.0.0.100 &&
> arp.spa == 20.0.0.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 20.0.0.200 &&
> arp.spa == 20.0.0.200), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 40.0.0.100 &&
> arp.spa == 40.0.0.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 40.0.0.200 &&
> arp.spa == 40.0.0.200), action=(outport = "_MC_flood_l2"; output;)
>  ])
>
>  AS_BOX([Adding load balancer reachable VIPs to ro1])
> @@ -6111,19 +6111,19 @@ AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows |
> ovn_strip_lflows], [0], [dnl
>    table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip),
> action=(outport = "_MC_flood_l2"; output;)
>    table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast &&
> (nd_na || nd_rs || nd_ra)), action=(outport = "_MC_flood"; output;)
>    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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.100),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.200),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.1.1),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa ==
> 192.168.1.100), action=(clone {outport = "ls1-ro1"; output; }; outport =
> "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 30.0.0.100),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 30.0.0.200),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.mcast && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone
> {outport = "ls1-ro1"; output; }; outport = "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.100 &&
> arp.spa == 10.0.0.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.200 &&
> arp.spa == 10.0.0.200), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.1.1 &&
> arp.spa == 192.168.1.1), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.1.100
> && arp.spa == 192.168.1.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 30.0.0.100 &&
> arp.spa == 30.0.0.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 30.0.0.200 &&
> arp.spa == 30.0.0.200), action=(outport = "_MC_flood_l2"; output;)
>  ])
>
>  AS_BOX([Adding load balancer unreachable VIPs to ro1])
> @@ -6141,19 +6141,19 @@ AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows |
> ovn_strip_lflows], [0], [dnl
>    table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip),
> action=(outport = "_MC_flood_l2"; output;)
>    table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast &&
> (nd_na || nd_rs || nd_ra)), action=(outport = "_MC_flood"; output;)
>    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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.100),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.200),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.1.1),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa ==
> 192.168.1.100), action=(clone {outport = "ls1-ro1"; output; }; outport =
> "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 30.0.0.100),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 30.0.0.200),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.mcast && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone
> {outport = "ls1-ro1"; output; }; outport = "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.100 &&
> arp.spa == 10.0.0.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.200 &&
> arp.spa == 10.0.0.200), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.1.1 &&
> arp.spa == 192.168.1.1), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.1.100
> && arp.spa == 192.168.1.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 30.0.0.100 &&
> arp.spa == 30.0.0.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 30.0.0.200 &&
> arp.spa == 30.0.0.200), action=(outport = "_MC_flood_l2"; output;)
>  ])
>
>  # Make sure that there is no flow for VIP 192.168.4.100 as ro1-ls1 doesn't
> @@ -6178,19 +6178,19 @@ AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows |
> ovn_strip_lflows], [0], [dnl
>    table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip),
> action=(outport = "_MC_flood_l2"; output;)
>    table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast &&
> (nd_na || nd_rs || nd_ra)), action=(outport = "_MC_flood"; output;)
>    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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.100),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.200),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.1.1),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa ==
> 192.168.1.100), action=(clone {outport = "ls1-ro1"; output; }; outport =
> "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 30.0.0.100),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 30.0.0.200),
> action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.mcast && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone
> {outport = "ls1-ro1"; output; }; outport = "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.100 &&
> arp.spa == 10.0.0.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 10.0.0.200 &&
> arp.spa == 10.0.0.200), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.1.1 &&
> arp.spa == 192.168.1.1), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 192.168.1.100
> && arp.spa == 192.168.1.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 30.0.0.100 &&
> arp.spa == 30.0.0.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 30.0.0.200 &&
> arp.spa == 30.0.0.200), action=(outport = "_MC_flood_l2"; output;)
>  ])
>
>
> @@ -14631,15 +14631,15 @@ AT_CHECK([grep "ls_in_l2_lkup" publicflows |
> ovn_strip_lflows], [0], [dnl
>    table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip),
> action=(outport = "_MC_flood_l2"; output;)
>    table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast &&
> (nd_na || nd_rs || nd_ra)), action=(outport = "_MC_flood"; output;)
>    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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 172.168.0.10),
> action=(clone {outport = "public-lr0"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa ==
> 172.168.0.100), action=(clone {outport = "public-lr0"; output; }; outport =
> "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa ==
> 172.168.0.110), action=(clone {outport = "public-lr0"; output; }; outport =
> "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa ==
> 172.168.0.120), action=(clone {outport = "public-lr0"; output; }; outport =
> "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.mcast && nd_ns && nd.target == fe80::200:ff:fe00:ff02),
> action=(clone {outport = "public-lr0"; output; }; outport = "_MC_unknown";
> output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 172.168.0.10
> && arp.spa == 172.168.0.10), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 172.168.0.100
> && arp.spa == 172.168.0.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 172.168.0.110
> && arp.spa == 172.168.0.110), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 172.168.0.120
> && arp.spa == 172.168.0.120), action=(outport = "_MC_flood_l2"; output;)
>  ])
>
>  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
> @@ -14666,10 +14666,10 @@ AT_CHECK([grep -Fe "172.168.0.110" -e
> "172.168.0.120" -e "10.0.0.3" -e "20.0.0.3
>  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
>    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;)
>    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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa ==
> 172.168.0.110), action=(clone {outport = "public-lr0"; output; }; outport =
> "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa ==
> 172.168.0.120), action=(clone {outport = "public-lr0"; output; }; outport =
> "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 172.168.0.110
> && arp.spa == 172.168.0.110), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 172.168.0.120
> && arp.spa == 172.168.0.120), action=(outport = "_MC_flood_l2"; output;)
>  ])
>  }
>
> @@ -14813,20 +14813,20 @@ AT_CHECK([grep "ls_in_l2_lkup" publicflows |
> ovn_strip_lflows], [0], [dnl
>    table=??(ls_in_l2_lkup      ), priority=71   , match=(eth.mcast && ip),
> action=(outport = "_MC_flood_l2"; output;)
>    table=??(ls_in_l2_lkup      ), priority=72   , match=(eth.mcast &&
> (nd_na || nd_rs || nd_ra)), action=(outport = "_MC_flood"; output;)
>    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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && 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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && 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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && 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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && 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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && 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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && 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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && 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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && 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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.mcast && 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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.mcast && 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;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 172.168.0.10
> && arp.spa == 172.168.0.10), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 172.168.0.100
> && arp.spa == 172.168.0.100), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 172.168.0.110
> && arp.spa == 172.168.0.110), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 172.168.0.120
> && arp.spa == 172.168.0.120), action=(outport = "_MC_flood_l2"; output;)
>  ])
>
>  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
> @@ -14851,12 +14851,12 @@ AT_CHECK([grep -Fe "172.168.0.110" -e
> "172.168.0.120" -e "10.0.0.3" -e "20.0.0.3
>  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
>    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;)
>    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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && 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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && 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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && 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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && 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;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 172.168.0.110
> && arp.spa == 172.168.0.110), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 172.168.0.120
> && arp.spa == 172.168.0.120), action=(outport = "_MC_flood_l2"; output;)
>  ])
>  }
>
> @@ -14916,10 +14916,10 @@ AT_CHECK([grep -Fe "172.168.0.110" -e
> "172.168.0.120" -e "10.0.0.3" -e "20.0.0.3
>  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
>    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;)
>    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;)
> -  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;)
> -  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;)
> -  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;)
> -  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;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa ==
> 172.168.0.110), action=(clone {outport = "public-lr0"; output; }; outport =
> "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa ==
> 172.168.0.120), action=(clone {outport = "public-lr0"; output; }; outport =
> "_MC_unknown"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 172.168.0.110
> && arp.spa == 172.168.0.110), action=(outport = "_MC_flood_l2"; output;)
> +  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0
> && eth.dst == ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.tpa == 172.168.0.120
> && arp.spa == 172.168.0.120), action=(outport = "_MC_flood_l2"; output;)
>  ])
>
>  OVN_CLEANUP_NORTHD
> @@ -20316,6 +20316,35 @@ OVN_CLEANUP_NORTHD
>  AT_CLEANUP
>  ])
>
> +OVN_FOR_EACH_NORTHD_NO_HV([
> +AT_SETUP([ovn-northd - broadcast restriction on rport ARP/ND req flows in
> l2_lkup])
> +AT_KEYWORDS([ovn])
> +ovn_start
> +
> +check ovn-nbctl lr-add lr0
> +check ovn-nbctl lrp-add lr0 lr0-ls0 00:00:00:00:00:01 10.0.0.1/24
> aef0::1/64
> +
> +check ovn-nbctl ls-add ls0
> +check ovn-nbctl lsp-add-router-port ls0 ls0-lr0 lr0-ls0
> +
> +check ovn-nbctl lsp-add ls0 lsp1 \
> +    -- lsp-set-addresses lsp1 "00:00:00:00:00:02 10.0.0.2 aef0::2"
> +
> +check ovn-nbctl --wait=sb sync
> +
> +dnl Priority 80 IPv4 ARP request flow must restrict to broadcast.
> +AT_CHECK([ovn-sbctl dump-flows ls0 | grep ls_in_l2_lkup | grep
> "priority=80" | grep "arp.tpa == 10.0.0.1" | grep -q "eth.dst ==
> ff:ff:ff:ff:ff:ff"])
> +
> +dnl Priority 90 GARP flow must also restrict to broadcast.
> +AT_CHECK([ovn-sbctl dump-flows ls0 | grep ls_in_l2_lkup | grep
> "priority=90" | grep "arp.spa == 10.0.0.1" | grep -q "eth.dst ==
> ff:ff:ff:ff:ff:ff"])
> +
> +dnl Priority 80 IPv6 ND_NS flow must restrict to multicast.
> +AT_CHECK([ovn-sbctl dump-flows ls0 | grep ls_in_l2_lkup | grep
> "priority=80" | grep "nd.target == aef0::1" | grep -q "eth.mcast"])
> +
> +OVN_CLEANUP_NORTHD
> +AT_CLEANUP
> +])
> +
>  OVN_FOR_EACH_NORTHD_NO_HV([
>  AT_SETUP([LS EVPN Advertised_MAC_Binding sync])
>  ovn_start
> diff --git a/tests/ovn.at b/tests/ovn.at
> index 5dda500449..79cbc9d244 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -44959,6 +44959,212 @@ OVN_CLEANUP([hv1])
>  AT_CLEANUP
>  ])
>
> +OVN_FOR_EACH_NORTHD([
> +AT_SETUP([Unicast ARP for router port not flooded to multicast group])
> +ovn_start
> +
> +check ovn-nbctl ls-add ls1
> +check ovn-nbctl lr-add lr1
> +check ovn-nbctl lrp-add lr1 lr1-ls1 00:00:00:00:00:01 10.0.0.1/16
> +check ovn-nbctl lsp-add-router-port ls1 ls1-lr1 lr1-ls1
> +
> +dnl Create 220 VIF ports in batch to make sure we don't trigger the 4096
> +dnl resubmit limit due to incorrect forwarding to multicast flood groups.
> +nbctl_cmd=""
> +for i in $(seq 1 220); do
> +    idx=$(printf "%04d" $i)
> +    hex_hi=$(printf "%02x" $(($i / 256)))
> +    hex_lo=$(printf "%02x" $(($i % 256)))
> +    mac="f0:00:00:00:${hex_hi}:${hex_lo}"
> +    nbctl_cmd="$nbctl_cmd -- lsp-add ls1 vif-$idx"
> +    nbctl_cmd="$nbctl_cmd -- lsp-set-addresses vif-$idx \"$mac\""
> +done
> +eval check ovn-nbctl $nbctl_cmd
> +
> +net_add n1
> +sim_add hv1
> +as hv1
> +ovs-vsctl add-br br-phys
> +ovn_attach n1 br-phys 192.168.0.1
> +
> +vsctl_cmd=""
> +for i in $(seq 1 220); do
> +    idx=$(printf "%04d" $i)
> +    vsctl_cmd="$vsctl_cmd -- add-port br-int vif-$idx "
> +    vsctl_cmd="$vsctl_cmd -- set Interface vif-$idx
> external-ids:iface-id=vif-$idx"
> +done
> +eval check ovs-vsctl $vsctl_cmd
> +
> +OVN_POPULATE_ARP
> +wait_for_ports_up
> +check ovn-nbctl --wait=hv sync
> +
> +dnl Check that unicast GARP requests incorrectly spoofing the router port
> IP
> +dnl don't cause the 4096 resubmit limit to be hit.
> +ofport=$(as hv1 ovs-vsctl get Interface vif-0001 ofport)
> +AT_CHECK([as hv1 ovs-appctl ofproto/trace br-int \
> +    "in_port=$ofport,dl_src=f0:00:00:00:00:01,dl_dst=00:00:00:00:00:01,\
> +     arp,arp_op=1,arp_spa=10.0.0.1,arp_tpa=10.0.0.1,\
> +     arp_sha=f0:00:00:00:00:01,arp_tha=00:00:00:00:00:01"], [0], [stdout])
> +AT_CHECK([grep "Translation failed" stdout], [1])
> +AT_CHECK([grep "packet is dropped" stdout], [1])
> +
> +dnl Also check valid unicast ARP requests for the router port don't cause
> +dnl the 4096 resubmit limit to be hit.
> +AT_CHECK([as hv1 ovs-appctl ofproto/trace br-int \
> +    "in_port=$ofport,dl_src=f0:00:00:00:00:01,dl_dst=00:00:00:00:00:01,\
> +     arp,arp_op=1,arp_spa=10.0.0.2,arp_tpa=10.0.0.1,\
> +     arp_sha=f0:00:00:00:00:01,arp_tha=00:00:00:00:00:01"], [0], [stdout])
> +AT_CHECK([grep "Translation failed" stdout], [1])
> +AT_CHECK([grep "packet is dropped" stdout], [1])
> +
> +OVN_CLEANUP([hv1])
> +AT_CLEANUP
> +])
> +
> +OVN_FOR_EACH_NORTHD([
> +AT_SETUP([Unicast ARP for router IP with proxy ARP - resubmit overflow])
> +ovn_start
> +
> +dnl Create a logical switch and router, connected via a router port.
> +check ovn-nbctl ls-add ls1
> +check ovn-nbctl lr-add lr1
> +check ovn-nbctl lrp-add lr1 lr1-ls1 00:00:00:00:00:01 10.0.0.1/24
> +check ovn-nbctl lsp-add-router-port ls1 ls1-lr1 lr1-ls1
> +
> +dnl Configure proxy ARP on the router port with a range that includes the
> +dnl router IP (10.0.0.1 is within 10.0.0.0/24).
> +check ovn-nbctl set logical_switch_port ls1-lr1 \
> +    options:arp_proxy="10.0.0.0/24"
> +
> +dnl Add a VIF port that will send the unicast ARP.
> +check ovn-nbctl lsp-add ls1 vm1 -- \
> +      lsp-set-addresses vm1 "00:00:00:00:00:02 10.0.0.2"
> +
> +dnl Add 220 additional VIF ports to make MC_FLOOD_L2 large enough
> +dnl that flooding to it would exceed the OVS 4096 resubmit limit.
> +nbctl_cmd=""
> +for i in $(seq 1 220); do
> +    idx=$(printf "%04d" $i)
> +    hex_hi=$(printf "%02x" $(($i / 256)))
> +    hex_lo=$(printf "%02x" $(($i % 256)))
> +    mac="f0:00:00:00:${hex_hi}:${hex_lo}"
> +    nbctl_cmd="$nbctl_cmd -- lsp-add ls1 vif-$idx"
> +    nbctl_cmd="$nbctl_cmd -- lsp-set-addresses vif-$idx \"$mac\""
> +done
> +eval check ovn-nbctl $nbctl_cmd
> +
> +net_add n1
> +sim_add hv1
> +as hv1
> +ovs-vsctl add-br br-phys
> +ovn_attach n1 br-phys 192.168.0.1
> +
> +dnl Bind the sender VIF port.
> +ovs-vsctl add-port br-int vif-vm1 -- \
> +    set Interface vif-vm1 external-ids:iface-id=vm1 \
> +    options:tx_pcap=hv1/vif-vm1-tx.pcap \
> +    options:rxq_pcap=hv1/vif-vm1-rx.pcap
> +
> +dnl Bind all 220 additional VIF ports so they join MC_FLOOD_L2.
> +vsctl_cmd=""
> +for i in $(seq 1 220); do
> +    idx=$(printf "%04d" $i)
> +    vsctl_cmd="$vsctl_cmd -- add-port br-int vif-$idx"
> +    vsctl_cmd="$vsctl_cmd -- set Interface vif-$idx
> external-ids:iface-id=vif-$idx"
> +done
> +eval check ovs-vsctl $vsctl_cmd
> +
> +OVN_POPULATE_ARP
> +
> +wait_for_ports_up
> +check ovn-nbctl --wait=hv sync
> +
> +dnl Trace a unicast ARP request from vm1 for the router IP,
> +dnl eth.dst is the router MAC (unicast).
> +dnl
> +dnl The router port should answer with an ARP reply, since
> +dnl the packet is unicast.  The proxy ARP is bypassed.
> +dnl
> +dnl Verify via ofproto/trace that the packet is not dropped.
> +packet=""
> +AT_CHECK([as hv1 ovs-appctl ofproto/trace br-int \
> +
> "in_port=vif-vm1,dl_src=00:00:00:00:00:02,dl_dst=00:00:00:00:00:01, \
> +            arp,arp_spa=10.0.0.2,arp_tpa=10.0.0.1,arp_op=1, \
> +            arp_sha=00:00:00:00:00:02,arp_tha=00:00:00:00:00:01"], [0],
> [stdout])
> +AT_CHECK([grep "Translation failed" stdout], [1])
> +AT_CHECK([grep "packet is dropped" stdout], [1])
> +
> +OVN_CLEANUP([hv1])
> +AT_CLEANUP
> +])
> +
> +OVN_FOR_EACH_NORTHD([
> +AT_SETUP([Unicast ND_NS for router IPv6 with proxy ARP - resubmit
> overflow])
> +ovn_start
> +
> +check ovn-nbctl ls-add ls1
> +check ovn-nbctl lr-add lr1
> +check ovn-nbctl lrp-add lr1 lr1-ls1 00:00:00:00:00:01 10.0.0.1/24
> aef0::1/64
> +check ovn-nbctl lsp-add-router-port ls1 ls1-lr1 lr1-ls1
> +
> +dnl Configure proxy ARP/ND on the router port with ranges that include
> +dnl the router IPs (10.0.0.1 is within 10.0.0.0/24, aef0::1 is within
> +dnl aef0::/64).
> +check ovn-nbctl set logical_switch_port ls1-lr1 \
> +    options:arp_proxy="10.0.0.0/24 aef0::/64"
> +
> +check ovn-nbctl lsp-add ls1 vm1 -- \
> +      lsp-set-addresses vm1 "00:00:00:00:00:02 10.0.0.2 aef0::2"
> +
> +dnl Add 220 additional VIF ports to make MC_FLOOD_L2/MC_UNKNOWN large
> enough
> +dnl that flooding to it would exceed the OVS 4096 resubmit limit.
> +nbctl_cmd=""
> +for i in $(seq 1 220); do
> +    idx=$(printf "%04d" $i)
> +    nbctl_cmd="$nbctl_cmd -- lsp-add ls1 vif-$idx"
> +    nbctl_cmd="$nbctl_cmd -- lsp-set-addresses vif-$idx unknown"
> +done
> +eval check ovn-nbctl $nbctl_cmd
> +
> +net_add n1
> +sim_add hv1
> +as hv1
> +ovs-vsctl add-br br-phys
> +ovn_attach n1 br-phys 192.168.0.1
> +
> +ovs-vsctl add-port br-int vif-vm1 -- \
> +    set Interface vif-vm1 external-ids:iface-id=vm1 \
> +    options:tx_pcap=hv1/vif-vm1-tx.pcap \
> +    options:rxq_pcap=hv1/vif-vm1-rx.pcap
> +
> +vsctl_cmd=""
> +for i in $(seq 1 220); do
> +    idx=$(printf "%04d" $i)
> +    vsctl_cmd="$vsctl_cmd -- add-port br-int vif-$idx"
> +    vsctl_cmd="$vsctl_cmd -- set Interface vif-$idx
> external-ids:iface-id=vif-$idx"
> +done
> +eval check ovs-vsctl $vsctl_cmd
> +
> +OVN_POPULATE_ARP
> +
> +wait_for_ports_up
> +check ovn-nbctl --wait=hv sync
> +
> +dnl Trace a unicast ND_NS from vm1 for the router IPv6 address.
> +dnl eth.dst is the router MAC (unicast, NOT solicited-node multicast).
> +AT_CHECK([as hv1 ovs-appctl ofproto/trace br-int \
> +    "in_port=vif-vm1,dl_src=00:00:00:00:00:02,dl_dst=00:00:00:00:00:01, \
> +    icmp6,ipv6_src=aef0::2,ipv6_dst=aef0::1,nw_ttl=255, \
> +    icmpv6_type=135,icmpv6_code=0, \
> +    nd_target=aef0::1,nd_sll=00:00:00:00:00:02"], [0], [stdout])
> +AT_CHECK([grep "Translation failed" stdout], [1])
> +AT_CHECK([grep "packet is dropped" stdout], [1])
> +
> +OVN_CLEANUP([hv1])
> +AT_CLEANUP
> +])
> +
>  OVN_FOR_EACH_NORTHD([
>  AT_SETUP([Port security - VRRPv3 ARP/ND])
>  CHECK_SCAPY
> --
> 2.54.0
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
>
Looks good to me, thanks.

Acked-by: Ales Musil <[email protected]>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to