On Wed, Apr 8, 2026 at 2:50 PM Lorenzo Bianconi via dev < [email protected]> wrote:
> > Logical switches should not forward IP multicast packets towards > > connected OVN logical routers if the router is not configured to relay > > IP multicast traffic (LR.options:mcast_relay=false). > > > > Previously, a single priority 71 flow matched "eth.mcast && (arp || ip)" > > and sent all such traffic to _MC_flood, which includes all ports > > (including router ports). This caused IP multicast packets to be > > forwarded to routers that would always drop them in lr_in_ip_input, > > wasting CPU cycles. In topologies with hundreds of routers connected > > to logical switches, this can lead to the max resubmit limit (4K) being > > hit by such packets, unnecessarily overloading ovs-vswitchd. > > > > Fix this by splitting the flow into three: > > - Priority 72: "eth.mcast && (nd_na || nd_rs || nd_ra)" -> _MC_flood > > ND NA, Router Solicitation and Router Advertisement must still reach > > routers: ND NA for neighbor learning, ND RS so routers can respond > > with Router Advertisements, ND RA for proper IPv6 network operation. > > - Priority 71: "eth.mcast && arp" -> _MC_flood > > ARP (including gratuitous ARP) still reaches all ports. > > - Priority 71: "eth.mcast && ip" -> _MC_flood_l2 > > IP multicast is only sent to non-router L2 ports, plus > > _MC_mrouter_flood (if any connected router has relay enabled) > > and _MC_static (if any port has mcast_flood=true). > > > > Reported-at: https://redhat.atlassian.net/browse/FDP-2262 > > Assisted-by: Claude, with model: claude-opus-4-6 > > Signed-off-by: Dumitru Ceara <[email protected]> > > Acked-by: Lorenzo Bianconi <[email protected]> > > > --- > > northd/northd.c | 37 +++++++- > > northd/ovn-northd.8.xml | 33 +++++-- > > tests/ovn-northd.at | 191 ++++++++++++++++++++++++++++++++++++---- > > 3 files changed, 237 insertions(+), 24 deletions(-) > > > > diff --git a/northd/northd.c b/northd/northd.c > > index b7239f4e20..92c1707817 100644 > > --- a/northd/northd.c > > +++ b/northd/northd.c > > @@ -11020,10 +11020,45 @@ build_lswitch_destination_lookup_bmcast(struct > ovn_datapath *od, > > lflow_ref); > > } > > > > + /* ND NA, Router Solicitation and Router Advertisement should be > > + * flooded to all ports including routers. ND NA is needed for > > + * neighbor learning; ND RS must reach routers so they can respond > > + * with Router Advertisements; ND RA must reach routers for proper > > + * IPv6 network operation. > > + */ > > + ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, 72, > > + "eth.mcast && (nd_na || nd_rs || nd_ra)", > > + "outport = \""MC_FLOOD"\"; output;", lflow_ref); > > + > > + /* ARP multicast should be flooded to all ports including routers. > */ > > ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, 71, > > - "eth.mcast && (arp || ip)", > > + "eth.mcast && arp", > > "outport = \""MC_FLOOD"\"; output;", lflow_ref); > > > > + /* IP multicast should not be forwarded to routers that don't have > > + * IGMP relay enabled (mcast_relay=true). Such routers will always > > + * drop IP multicast in lr_in_ip_input anyway. > > + */ > > + ds_clear(actions); > > + if (mcast_sw_info->flood_relay) { > > + ds_put_cstr(actions, > > + "clone { " > > + "outport = \""MC_MROUTER_FLOOD"\"; " > > + "output; " > > + "}; "); > > + } > > + if (mcast_sw_info->flood_static) { > > + ds_put_cstr(actions, > > + "clone { " > > + "outport = \""MC_STATIC"\"; " > > + "output; " > > + "}; "); > > + } > > + ds_put_cstr(actions, "outport = \""MC_FLOOD_L2"\"; output;"); > > + ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, 71, > > + "eth.mcast && ip", > > + ds_cstr(actions), lflow_ref); > > + > > /* Non-{arp,ip} L2 multicast traffic should not be sent to router > > * ports since these packets will be discarded in the router > pipeline. > > */ > > diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml > > index 9f2d118dd4..4d6370da6b 100644 > > --- a/northd/ovn-northd.8.xml > > +++ b/northd/ovn-northd.8.xml > > @@ -2414,18 +2414,41 @@ output; > > </li> > > > > <li> > > - A priority-72 flow that outputs all ARP requests and ND packets > with > > - an Ethernet broadcast or multicast <code>eth.dst</code> to the > > - <code>MC_FLOOD_L2</code> multicast group if > > - <code>other_config:broadcast-arps-to-all-routers=true</code>. > > + A priority-72 flow that outputs all ND NA (Neighbor > Advertisement), > > + ND RS (Router Solicitation) and ND RA (Router Advertisement) > packets > > + with an Ethernet broadcast or multicast <code>eth.dst</code> to > the > > + <code>MC_FLOOD</code> multicast group, which includes all ports. > > + ND NA must reach routers for neighbor learning; ND RS must reach > > + routers so they can respond with Router Advertisements; ND RA > must > > + reach routers for proper IPv6 network operation. > > </li> > > > > <li> > > - A priority-71 flow that outputs all ARP or IP packets with an > Ethernet > > + A priority-72 flow that outputs all ARP requests and ND NS > (Neighbor > > + Solicitation) packets with an Ethernet broadcast or multicast > > + <code>eth.dst</code> to the <code>MC_FLOOD_L2</code> multicast > group > > + if > <code>other_config:broadcast-arps-to-all-routers=false</code>. > > + </li> > > + > > + <li> > > + A priority-71 flow that outputs all ARP packets with an Ethernet > > broadcast or multicast <code>eth.dst</code> to the > > <code>MC_FLOOD</code> multicast group. > > </li> > > > > + <li> > > + A priority-71 flow that outputs all IP packets with an Ethernet > > + broadcast or multicast <code>eth.dst</code> to the > > + <code>MC_FLOOD_L2</code> multicast group, which contains only > > + non-router logical ports. If any connected router has > > + <code>options:mcast_relay=true</code>, the packet is also > cloned to > > + the <code>MC_MROUTER_FLOOD</code> multicast group (which > contains > > + only the router ports with relay enabled). If any port has > > + <code>options:mcast_flood=true</code>, it is also cloned to the > > + <code>MC_STATIC</code> multicast group. This prevents IP > multicast > > + from being unnecessarily forwarded to routers that would drop > it. > > + </li> > > + > > <li> > > A priority-70 flow that outputs all packets with an Ethernet > broadcast > > or multicast <code>eth.dst</code> to the > <code>MC_FLOOD_L2</code> > > diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at > > index 6230fd039a..7c2f53da69 100644 > > --- a/tests/ovn-northd.at > > +++ b/tests/ovn-northd.at > > @@ -5863,7 +5863,9 @@ AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | > ovn_strip_lflows], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:01), action=(outport = "ls1-ro1"; output;) > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:02), action=(outport = "vm1"; output;) > > table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_flood_l2"; 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_flood_l2"; output;) > > @@ -5877,7 +5879,9 @@ AT_CHECK([grep "ls_in_l2_lkup" ls2_lflows | > ovn_strip_lflows], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:02:01), action=(outport = "ls2-ro2"; output;) > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:02:02), action=(outport = "vm2"; output;) > > table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_flood_l2"; 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_flood_l2"; output;) > > @@ -5899,7 +5903,9 @@ AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | > ovn_strip_lflows], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:01), action=(outport = "ls1-ro1"; output;) > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:02), action=(outport = "vm1"; output;) > > table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_flood_l2"; 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_flood_l2"; output;) > > @@ -5915,7 +5921,9 @@ AT_CHECK([grep "ls_in_l2_lkup" ls2_lflows | > ovn_strip_lflows], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:02:01), action=(outport = "ls2-ro2"; output;) > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:02:02), action=(outport = "vm2"; output;) > > table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_flood_l2"; 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_flood_l2"; output;) > > @@ -5939,7 +5947,9 @@ AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | > ovn_strip_lflows], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:01), action=(outport = "ls1-ro1"; output;) > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:02), action=(outport = "vm1"; output;) > > table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_flood_l2"; 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_flood_l2"; output;) > > @@ -5957,7 +5967,9 @@ AT_CHECK([grep "ls_in_l2_lkup" ls2_lflows | > ovn_strip_lflows], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:02:01), action=(outport = "ls2-ro2"; output;) > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:02:02), action=(outport = "vm2"; output;) > > table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_flood_l2"; 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_flood_l2"; output;) > > @@ -5980,7 +5992,9 @@ AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | > ovn_strip_lflows], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:01), action=(outport = "ls1-ro1"; output;) > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:02), action=(outport = "vm1"; output;) > > table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_flood_l2"; 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_flood_l2"; output;) > > @@ -6002,7 +6016,9 @@ AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | > ovn_strip_lflows], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:01), action=(outport = "ls1-ro1"; output;) > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:02), action=(outport = "vm1"; output;) > > table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_flood_l2"; 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_flood_l2"; output;) > > @@ -6031,7 +6047,9 @@ AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | > ovn_strip_lflows], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:01 && is_chassis_resident("cr-ro1-ls1")), action=(outport = > "ls1-ro1"; output;) > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:02), action=(outport = "vm1"; output;) > > table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_flood_l2"; 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_flood_l2"; output;) > > @@ -8365,6 +8383,127 @@ OVN_CLEANUP_NORTHD > > AT_CLEANUP > > ]) > > > > +OVN_FOR_EACH_NORTHD_NO_HV([ > > +AT_SETUP([IP multicast flood without IGMP relay]) > > +AT_KEYWORDS([mcast_relay]) > > +ovn_start > > + > > +check ovn-nbctl lr-add lr0 > > +check ovn-nbctl ls-add ls0 > > + > > +check ovn-nbctl lrp-add lr0 lrp0 00:00:00:00:00:01 10.0.0.1/24 > fe80::1/64 > > +check ovn-nbctl lsp-add-router-port ls0 lsp0-router lrp0 > > + > > +check ovn-nbctl lsp-add ls0 lsp0 -- \ > > + lsp-set-addresses lsp0 "00:00:00:00:00:02 10.0.0.2" > > + > > +dnl IP multicast packet from lsp0. > > +mcast_pkt='inport == "lsp0" && eth.src == 00:00:00:00:00:02 && eth.dst > == 01:00:5e:00:01:2a && ip4.src == 10.0.0.2 && ip4.dst == 239.0.1.42 && > ip.ttl == 64 && udp.src == 42 && udp.dst == 43' > > + > > +dnl ARP broadcast from lsp0. > > +arp_pkt='inport == "lsp0" && eth.src == 00:00:00:00:00:02 && eth.dst == > ff:ff:ff:ff:ff:ff && arp.op == 1 && arp.sha == 00:00:00:00:00:02 && arp.spa > == 10.0.0.2 && arp.tha == 00:00:00:00:00:00 && arp.tpa == 10.0.0.3' > > + > > +dnl Gratuitous ND NA multicast from lsp0. > > +nd_na_pkt='inport == "lsp0" && eth.src == 00:00:00:00:00:02 && eth.dst > == 33:33:00:00:00:01 && ip6.src == fe80::200:ff:fe00:2 && ip6.dst == > ff02::1 && icmp6.type == 136 && nd.target == fe80::200:ff:fe00:2' > > + > > +dnl Router solicitation multicast from lsp0. > > +nd_rs_pkt='inport == "lsp0" && eth.src == 00:00:00:00:00:02 && eth.dst > == 33:33:00:00:00:02 && ip6.src == fe80::200:ff:fe00:2 && ip6.dst == > ff02::2 && icmp6.type == 133 && ip.ttl == 255' > > + > > +dnl Router advertisement multicast from lsp0. > > +nd_ra_pkt='inport == "lsp0" && eth.src == 00:00:00:00:00:02 && eth.dst > == 33:33:00:00:00:01 && ip6.src == fe80::200:ff:fe00:2 && ip6.dst == > ff02::1 && icmp6.type == 134 && ip.ttl == 255' > > + > > +dnl Scenario 1: default, no relay, no snooping. > > +dnl The eth.mcast && ip flow should use _MC_flood_l2 not _MC_flood. > > +check ovn-nbctl --wait=sb sync > > + > > +ovn-sbctl dump-flows ls0 > lsflows > > +AT_CAPTURE_FILE([lsflows]) > > +AT_CHECK([grep -e 'ls_in_l2_lkup' lsflows | grep -e 'priority=71' -e > 'priority=72' | ovn_strip_lflows], [0], [dnl > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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;) > > +]) > > + > > +dnl Verify packet forwarding: IP multicast should not reach the router > > +dnl port, while ARP, ND NA, ND RS and ND RA should. > > +AT_CHECK([ovn_trace ls0 "$mcast_pkt" | grep 'outport="lsp0-router"'], > [1]) > > +AT_CHECK([ovn_trace ls0 "$arp_pkt" | grep -q 'outport="lsp0-router"']) > > +AT_CHECK([ovn_trace ls0 "$nd_na_pkt" | grep -q 'outport="lsp0-router"']) > > +AT_CHECK([ovn_trace ls0 "$nd_rs_pkt" | grep -q 'outport="lsp0-router"']) > > +AT_CHECK([ovn_trace ls0 "$nd_ra_pkt" | grep -q 'outport="lsp0-router"']) > > + > > +dnl Scenario 2: relay enabled on the router but snooping not enabled on > the switch. > > +dnl No priority 80 flow is installed because build_mcast_flood_lswitch > returns > > +dnl early when snooping is disabled, so the priority 71 flow is the > only path > > +dnl for IP multicast to reach relay-enabled routers via > _MC_mrouter_flood. > > +check ovn-nbctl set logical_router lr0 options:mcast_relay="true" > > +check ovn-nbctl --wait=sb sync > > + > > +ovn-sbctl dump-flows ls0 > lsflows2 > > +AT_CAPTURE_FILE([lsflows2]) > > +AT_CHECK([grep -e 'ls_in_l2_lkup' lsflows2 | grep -e 'priority=71' -e > 'priority=72' | ovn_strip_lflows], [0], [dnl > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > ip), action=(clone { outport = "_MC_mrouter_flood"; output; }; 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;) > > +]) > > + > > +dnl Verify packet forwarding: all packet types should reach the router > port. > > +AT_CHECK([ovn_trace ls0 "$mcast_pkt" | grep -q 'outport="lsp0-router"']) > > +AT_CHECK([ovn_trace ls0 "$arp_pkt" | grep -q 'outport="lsp0-router"']) > > +AT_CHECK([ovn_trace ls0 "$nd_na_pkt" | grep -q 'outport="lsp0-router"']) > > +AT_CHECK([ovn_trace ls0 "$nd_rs_pkt" | grep -q 'outport="lsp0-router"']) > > +AT_CHECK([ovn_trace ls0 "$nd_ra_pkt" | grep -q 'outport="lsp0-router"']) > > + > > +dnl Scenario 3: relay enabled on the router and snooping enabled on the > switch. > > +dnl The eth.mcast && ip flow should include _MC_mrouter_flood for > relay-enabled > > +dnl router ports plus _MC_flood_l2 for regular ports. > > +check ovn-nbctl set logical_switch ls0 other_config:mcast_snoop="true" > > +check ovn-nbctl --wait=sb sync > > + > > +ovn-sbctl dump-flows ls0 > lsflows3 > > +AT_CAPTURE_FILE([lsflows3]) > > +AT_CHECK([grep -e 'ls_in_l2_lkup' lsflows3 | grep -e 'priority=71' -e > 'priority=72' | ovn_strip_lflows], [0], [dnl > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > ip), action=(clone { outport = "_MC_mrouter_flood"; output; }; 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;) > > +]) > > + > > +dnl Verify packet forwarding: all packet types should reach the router > port. > > +AT_CHECK([ovn_trace ls0 "$mcast_pkt" | grep -q 'outport="lsp0-router"']) > > +AT_CHECK([ovn_trace ls0 "$arp_pkt" | grep -q 'outport="lsp0-router"']) > > +AT_CHECK([ovn_trace ls0 "$nd_na_pkt" | grep -q 'outport="lsp0-router"']) > > +AT_CHECK([ovn_trace ls0 "$nd_rs_pkt" | grep -q 'outport="lsp0-router"']) > > +AT_CHECK([ovn_trace ls0 "$nd_ra_pkt" | grep -q 'outport="lsp0-router"']) > > + > > +dnl Scenario 4: also enable flood_unregistered on the switch. > > +dnl The priority 71 flow should still have _MC_mrouter_flood and > _MC_flood_l2. > > +dnl There should be no priority 80 flow for ip4.mcast || ip6.mcast > because > > +dnl flood_unregistered causes build_mcast_flood_lswitch to return early. > > +check ovn-nbctl set logical_switch ls0 > other_config:mcast_flood_unregistered="true" > > +check ovn-nbctl --wait=sb sync > > + > > +ovn-sbctl dump-flows ls0 > lsflows4 > > +AT_CAPTURE_FILE([lsflows4]) > > +AT_CHECK([grep -e 'ls_in_l2_lkup' lsflows4 | grep -e 'priority=71' -e > 'priority=72' | ovn_strip_lflows], [0], [dnl > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > ip), action=(clone { outport = "_MC_mrouter_flood"; output; }; 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;) > > +]) > > + > > +dnl Verify there is no priority 80 flow for ip4.mcast || ip6.mcast when > flood_unregistered is set. > > +AT_CHECK([grep -e 'ls_in_l2_lkup' lsflows4 | grep -e 'priority=80' | > grep -F 'ip4.mcast || ip6.mcast'], [1]) > > + > > +dnl Verify packet forwarding: all packet types should reach the router > port. > > +AT_CHECK([ovn_trace ls0 "$mcast_pkt" | grep -q 'outport="lsp0-router"']) > > +AT_CHECK([ovn_trace ls0 "$arp_pkt" | grep -q 'outport="lsp0-router"']) > > +AT_CHECK([ovn_trace ls0 "$nd_na_pkt" | grep -q 'outport="lsp0-router"']) > > +AT_CHECK([ovn_trace ls0 "$nd_rs_pkt" | grep -q 'outport="lsp0-router"']) > > +AT_CHECK([ovn_trace ls0 "$nd_ra_pkt" | grep -q 'outport="lsp0-router"']) > > + > > +OVN_CLEANUP_NORTHD > > +AT_CLEANUP > > +]) > > + > > OVN_FOR_EACH_NORTHD_NO_HV_PARALLELIZATION([ > > AT_SETUP([ACLs after lb]) > > AT_KEYWORDS([acl]) > > @@ -9678,7 +9817,9 @@ ovn_strip_lflows ], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=100 , match=(reg8[[23]] == > 1), action=(output;) > > table=??(ls_in_l2_lkup ), priority=110 , match=(eth.dst == > $svc_monitor_mac && (tcp || icmp || icmp6)), > action=(handle_svc_check(inport);) > > table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_unknown ), priority=0 , match=(1), > action=(output;) > > table=??(ls_in_l2_unknown ), priority=50 , match=(outport == > "none"), action=(drop;) > > table=??(ls_out_apply_port_sec), priority=0 , match=(1), > action=(output;) > > @@ -9714,7 +9855,9 @@ ovn_strip_lflows ], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:01), action=(outport = "sw0p1"; output;) > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:02:02), action=(outport = "sw0p2"; output;) > > table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_unknown ), priority=0 , match=(1), > action=(output;) > > table=??(ls_in_l2_unknown ), priority=50 , match=(outport == > "none"), action=(drop;) > > table=??(ls_out_apply_port_sec), priority=0 , match=(1), > action=(output;) > > @@ -9749,7 +9892,9 @@ ovn_strip_lflows ], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:01), action=(outport = "sw0p1"; output;) > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:02:02), action=(outport = "sw0p2"; output;) > > table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_unknown ), priority=0 , match=(1), > action=(output;) > > table=??(ls_in_l2_unknown ), priority=50 , match=(outport == > "none"), action=(drop;) > > table=??(ls_out_apply_port_sec), priority=0 , match=(1), > action=(output;) > > @@ -9785,7 +9930,9 @@ ovn_strip_lflows ], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:01), action=(drop;) > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:02:02), action=(outport = "sw0p2"; output;) > > table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_unknown ), priority=0 , match=(1), > action=(output;) > > table=??(ls_in_l2_unknown ), priority=50 , match=(outport == > "none"), action=(drop;) > > table=??(ls_in_l2_unknown ), priority=50 , match=(outport == > "sw0p1"), action=(drop;) > > @@ -9821,7 +9968,9 @@ ovn_strip_lflows ], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:01), action=(drop;) > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:02:02), action=(outport = "sw0p2"; output;) > > table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_unknown ), priority=0 , match=(1), > action=(output;) > > table=??(ls_in_l2_unknown ), priority=50 , match=(outport == > "none"), action=(drop;) > > table=??(ls_in_l2_unknown ), priority=50 , match=(outport == > "sw0p1"), action=(drop;) > > @@ -9861,7 +10010,9 @@ ovn_strip_lflows ], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:01:01), action=(outport = "sw0p1"; output;) > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:02:02), action=(outport = "sw0p2"; output;) > > table=??(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_unknown ), priority=0 , match=(1), > action=(output;) > > table=??(ls_in_l2_unknown ), priority=50 , match=(outport == > "none"), action=(drop;) > > table=??(ls_out_apply_port_sec), priority=0 , match=(1), > action=(output;) > > @@ -14201,7 +14352,9 @@ AT_CHECK([grep "ls_in_l2_lkup" publicflows | > ovn_strip_lflows], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:ff:02 && is_chassis_resident("cr-lr0-public")), action=(outport > = "public-lr0"; output;) > > 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=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_flood_l2"; 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_flood_l2"; output;) > > @@ -14379,7 +14532,9 @@ AT_CHECK([grep "ls_in_l2_lkup" publicflows | > ovn_strip_lflows], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=50 , match=(eth.dst == > 00:00:00:00:ff:02 && is_chassis_resident("cr-public-lr0")), action=(outport > = "public-lr0"; output;) > > 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=70 , match=(eth.mcast), > action=(outport = "_MC_flood_l2"; output;) > > - table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > (arp || ip)), action=(outport = "_MC_flood"; output;) > > + table=??(ls_in_l2_lkup ), priority=71 , match=(eth.mcast && > arp), action=(outport = "_MC_flood"; output;) > > + 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_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 = > "public-lr0"; output; }; outport = "_MC_flood_l2"; output;) > > @@ -14541,7 +14696,7 @@ AT_CHECK([ovn-sbctl dump-flows ls | grep > ls_in_l2_lkup | grep -E "tcp.dst == 179 > > AT_CHECK([ovn-sbctl dump-flows ls | grep ls_in_l2_lkup | grep "arp.op > == 2 && arp.tpa == 172.16.1.1" | ovn_strip_lflows], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=100 , match=(arp.op == 2 && > arp.tpa == 172.16.1.1), action=(clone { outport = "lsp-bgp"; output; }; > outport = "ls-lr"; output;) > > ]) > > -AT_CHECK([ovn-sbctl dump-flows ls | grep ls_in_l2_lkup | grep "&& > nd_na" | ovn_strip_lflows], [0], [dnl > > +AT_CHECK([ovn-sbctl dump-flows ls | grep ls_in_l2_lkup | grep "ip6.dst > == .* && nd_na" | ovn_strip_lflows], [0], [dnl > > table=??(ls_in_l2_lkup ), priority=100 , match=(ip6.dst == > fe80::ac:10ff:fe01:1 && nd_na), action=(clone { outport = "lsp-bgp"; > output; }; outport = "ls-lr"; output;) > > ]) > > > > -- > > 2.53.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
