On Tue, Aug 11, 2026 at 4:47 AM Dumitru Ceara <[email protected]> wrote:
>
> On 8/5/26 1:20 AM, Han Zhou wrote:
> > ovn-ic typically interconnects zones by attaching LRPs to a transit
> > switch. On that switch, remote LRPs appear as remote LSPs, so OVN floods
> > IP multicast to them via _MC_flood_l2. Multicast to real LSPs on the
> > transit switch is still desired, but flooding toward remote LRPs is
> > useless (they drop it) and scales poorly.
>
> Hi Han,
>
> Thanks for the patch!
>

Hi Dumitru,

Thanks for the review.

> >
> > Add LSP options:is_router so CMS can mark those remote LRP-backed ports.
>
> Would it make sense to call this "remote_router" or something like that?

I'd keep the option name is_router because type is already remote.

>
> > Omit them from _MC_flood_l2 like type=router.
>
> This makes sense, but please see below for some concerns.
>
> >
> > Assisted-by: Claude Opus 5, Cursor
> > Signed-off-by: Han Zhou <[email protected]>
> > ---
> >  Documentation/ref/ovn-logical-flows.7.rst |  9 ++--
> >  NEWS                                      |  3 ++
> >  lib/mcast-group-index.h                   |  3 +-
> >  northd/en-multicast.c                     |  5 +-
> >  northd/northd.h                           | 11 ++++
> >  ovn-nb.xml                                | 14 +++++
> >  tests/ovn-northd.at                       | 65 +++++++++++++++++++++++
> >  7 files changed, 105 insertions(+), 5 deletions(-)
> >
> > diff --git a/Documentation/ref/ovn-logical-flows.7.rst
b/Documentation/ref/ovn-logical-flows.7.rst
> > index 0ec69e39ee71..735e26ffd6f8 100644
> > --- a/Documentation/ref/ovn-logical-flows.7.rst
> > +++ b/Documentation/ref/ovn-logical-flows.7.rst
> > @@ -1460,7 +1460,8 @@ This table implements switching behavior.  It
contains these logical flows:
> >  - Priority-90 flows for each IPv4 address/VIP/NAT address owned by a
router
> >    port connected to the switch. These flows match GARP packets for the
specific
> >    IP addresses. Matched packets are forwarded to the ``MC_FLOOD_L2``
multicast
> > -  group which contains all non-router logical ports.
> > +  group which contains all non-router logical ports (excluding ports
of type
> > +  ``router`` and ports with ``options:is_router=true``).
> >
> >  - Priority-90 flows for transit switches that forward registered IP
multicast
> >    traffic to their corresponding multicast group , which
``ovn-northd`` creates
> > @@ -1475,7 +1476,8 @@ This table implements switching behavior.  It
contains these logical flows:
> >
> >  - A priority-85 flow that forwards all IP multicast traffic destined to
> >    224.0.0.X to the ``MC_FLOOD_L2`` multicast group, which
``ovn-northd``
> > -  populates with all non-router logical ports.
> > +  populates with all non-router logical ports (excluding ports of type
> > +  ``router`` and ports with ``options:is_router=true``).
> >
> >  - A priority-85 flow that forwards all IP multicast traffic destined
to reserved
> >    multicast IPv6 addresses (RFC 4291, 2.7.1, e.g., Solicited-Node
multicast) to
> > @@ -1503,7 +1505,8 @@ This table implements switching behavior.  It
contains these logical flows:
> >
> >  - Priority-75 flows for each port connected to a logical router
matching self
> >    originated ARP request/RARP request/ND packets.  These packets are
flooded to
> > -  the ``MC_FLOOD_L2`` which contains all non-router logical ports.
> > +  the ``MC_FLOOD_L2`` which contains all non-router logical ports
(excluding
> > +  ports of type ``router`` and ports with ``options:is_router=true``).
> >
> >  - A priority-72 flow that outputs all ND NA (Neighbor Advertisement),
ND RS
> >    (Router Solicitation) and ND RA (Router Advertisement) packets with
an
> > diff --git a/NEWS b/NEWS
> > index 44f117807af5..4d466251b397 100644
> > --- a/NEWS
> > +++ b/NEWS
> > @@ -94,6 +94,9 @@ Post v26.03.0
> >     - Added a new "ovn-debug lflow-pipeline-oftable-start-list" command
that
> >       prints the starting OpenFlow table number of the logical ingress
and
> >       egress pipelines.
> > +   - northd: Add Logical_Switch_Port option "is_router" to mark an LSP
as
> > +     representing a logical router port when type is not "router"
(e.g. IC
> > +     remote LSPs).  Currently used to omit such ports from
_MC_flood_l2.
> >
> >  OVN v26.03.0 - xxx xx xxxx
> >  --------------------------
> > diff --git a/lib/mcast-group-index.h b/lib/mcast-group-index.h
> > index 9664a94dd675..122ab65a5902 100644
> > --- a/lib/mcast-group-index.h
> > +++ b/lib/mcast-group-index.h
> > @@ -43,7 +43,8 @@ enum ovn_mcast_tunnel_keys {
> >                                            */
> >      OVN_MCAST_FLOOD_L2_TUNNEL_KEY,       /* Logical switch broadcast
domain
> >                                            * excluding ports towards
logical
> > -                                          * routers.
> > +                                          * routers (type=router or
> > +                                          * options:is_router=true).
> >                                            */
> >      OVN_MIN_IP_MULTICAST,
> >      OVN_MAX_IP_MULTICAST = OVN_MAX_MULTICAST,
> > diff --git a/northd/en-multicast.c b/northd/en-multicast.c
> > index 5148d88408ae..049afb3fcc38 100644
> > --- a/northd/en-multicast.c
> > +++ b/northd/en-multicast.c
> > @@ -233,7 +233,10 @@ build_mcast_groups(struct multicast_igmp_data
*data,
> >          if (lsp_is_enabled(op->nbsp) &&
lsp_can_receive_multicast(op->nbsp)) {
> >              ovn_multicast_add(&data->mcast_groups, &mc_flood, op);
> >
> > -            if (!lsp_is_router(op->nbsp)) {
> > +            /* Omit type=router ports and ports with
options:is_router=true
> > +             * from MC_FLOOD_L2 (same treatment as real router ports).
> > +             */
> > +            if (!lsp_is_router_for_mcast(op->nbsp)) {
> >                  ovn_multicast_add(&data->mcast_groups, &mc_flood_l2,
op);
> >              }
> >
> > diff --git a/northd/northd.h b/northd/northd.h
> > index d27f519d6e33..9385015f7a13 100644
> > --- a/northd/northd.h
> > +++ b/northd/northd.h
> > @@ -1155,6 +1155,17 @@ lsp_can_learn_mac(const struct
nbrec_logical_switch_port *nbsp)
> >      return smap_get_bool(&nbsp->options, "lsp_learn_fdb", true);
> >  }
> >
> > +/* True for type=router ports, and for ports marked
options:is_router=true
> > + * (LSP represents an LRP even if type is not "router").  Currently
used to
> > + * omit such ports from MC_FLOOD_L2.
> > + */
> > +static inline bool
> > +lsp_is_router_for_mcast(const struct nbrec_logical_switch_port *nbsp)
> > +{
> > +    return lsp_is_router(nbsp)
> > +           || smap_get_bool(&nbsp->options, "is_router", false);
> > +}
>
> To be honest, this seems a bit short sighted to me.  As you mentioned in
> the commit log the "remote" transit switch port is actually a port
> connecting to a remote router.  So logically there's no real difference
> between these ports and the ones lsp_is_router() returns true for, right?
>
> Instead of this very specific helper, shouldn't we just update
> lsp_is_router() to also check the nbsp option if nbsp->type == "remote"?
>

Thanks. In v2 I dropped lsp_is_router_for_mcast() and extended
lsp_is_router() to return true for type=remote + options:is_router=true.

> > +
> >  const char *lrp_find_member_ip(const struct ovn_port *op, const char
*ip_s);
> >
> >  /* This function returns true if 'op' is a gateway router port.
> > diff --git a/ovn-nb.xml b/ovn-nb.xml
> > index 8a9d19fa9214..43568ea7c911 100644
> > --- a/ovn-nb.xml
> > +++ b/ovn-nb.xml
> > @@ -1795,6 +1795,20 @@
> >          </column>
> >        </group>
> >
> > +      <group title="Options for ports representing routers">
> > +        <column name="options" key="is_router"
> > +                type='{"type": "boolean"}'>
> > +          If set to <code>true</code>, indicate that this logical
switch port
> > +          represents a logical router port, even when
> > +          <ref column="type"/> is not <code>router</code>.  CMS may
set this
> > +          on ports such as <code>remote</code> LSPs that back LRPs in
another
> > +          OVN interconnection zone.  OVN may use this hint wherever
router
> > +          ports are handled specially; for example, such ports are
omitted
> > +          from the <code>_MC_flood_l2</code> multicast group so IP
multicast
> > +          is not flooded toward them.  Default: <code>false</code>.
> > +        </column>
> > +      </group>
> > +
> >      </group>
> >
> >      <group title="Containers">
> > diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> > index d3d9de3b3ce5..54c0eeae1990 100644
> > --- a/tests/ovn-northd.at
> > +++ b/tests/ovn-northd.at
> > @@ -8745,6 +8745,71 @@ OVN_CLEANUP_NORTHD
> >  AT_CLEANUP
> >  ])
> >
> > +OVN_FOR_EACH_NORTHD_NO_HV([
> > +AT_SETUP([LSP options:is_router excludes from MC_FLOOD_L2])
> > +ovn_start
> > +
> > +check ovn-nbctl ls-add ls1
> > +check ovn-nbctl lsp-add ls1 vif1
> > +check ovn-nbctl lsp-set-addresses vif1 "00:00:00:00:00:01 10.0.0.1"
> > +check ovn-nbctl lsp-add ls1 remote1
> > +check ovn-nbctl lsp-set-type remote1 remote
> > +check ovn-nbctl lsp-set-addresses remote1 "00:00:00:00:00:02"
> > +check ovn-nbctl lr-add lr1
> > +check ovn-nbctl lrp-add lr1 lr1-ls1 00:00:00:00:00:03 10.0.0.254/24
> > +check ovn-nbctl lsp-add ls1 ls1-lr1
> > +check ovn-nbctl lsp-set-type ls1-lr1 router
> > +check ovn-nbctl lsp-set-addresses ls1-lr1 router
> > +check ovn-nbctl lsp-set-options ls1-lr1 router-port=lr1-ls1
> > +check ovn-nbctl --wait=sb sync
> > +
> > +vif1_uuid=$(fetch_column Port_Binding _uuid logical_port=vif1)
> > +remote1_uuid=$(fetch_column Port_Binding _uuid logical_port=remote1)
> > +lr1_uuid=$(fetch_column Port_Binding _uuid logical_port=ls1-lr1)
> > +
> > +dnl type=router is never in _MC_flood_l2.
> > +AT_CHECK([ovn-sbctl --bare --columns=ports find Multicast_Group \
> > +          name=_MC_flood_l2 | grep -c "$lr1_uuid"], [1], [dnl
> > +0
> > +])
> > +
> > +dnl remote LSP is in _MC_flood_l2 by default (looks like a normal L2
port).
> > +AT_CHECK([ovn-sbctl --bare --columns=ports find Multicast_Group \
> > +          name=_MC_flood_l2 | grep -c "$remote1_uuid"], [0], [dnl
> > +1
> > +])
> > +AT_CHECK([ovn-sbctl --bare --columns=ports find Multicast_Group \
> > +          name=_MC_flood_l2 | grep -c "$vif1_uuid"], [0], [dnl
> > +1
> > +])
> > +
> > +dnl Mark remote LSP as router-facing: omit from _MC_flood_l2.
> > +check ovn-nbctl --wait=sb set Logical_Switch_Port remote1
options:is_router=true
> > +AT_CHECK([ovn-sbctl --bare --columns=ports find Multicast_Group \
> > +          name=_MC_flood_l2 | grep -c "$remote1_uuid"], [1], [dnl
> > +0
> > +])
> > +AT_CHECK([ovn-sbctl --bare --columns=ports find Multicast_Group \
> > +          name=_MC_flood_l2 | grep -c "$vif1_uuid"], [0], [dnl
> > +1
> > +])
> > +
> > +dnl Still a member of _MC_flood (ARP/ND flood domain).
> > +AT_CHECK([ovn-sbctl --bare --columns=ports find Multicast_Group \
> > +          name=_MC_flood | grep -c "$remote1_uuid"], [0], [dnl
> > +1
> > +])
> > +
> > +dnl Clearing the option restores _MC_flood_l2 membership.
> > +check ovn-nbctl --wait=sb remove Logical_Switch_Port remote1 options
is_router
> > +AT_CHECK([ovn-sbctl --bare --columns=ports find Multicast_Group \
> > +          name=_MC_flood_l2 | grep -c "$remote1_uuid"], [0], [dnl
> > +1
> > +])
> > +
>
> Missing OVN_CLEANUP_NORTHD.

Oops. Fixed in v2.

Please take a look at v2:
https://patchwork.ozlabs.org/project/ovn/patch/[email protected]/

Best,
Han

>
> > +AT_CLEANUP
> > +])
> > +
> >  OVN_FOR_EACH_NORTHD_NO_HV_PARALLELIZATION([
> >  AT_SETUP([ACLs after lb])
> >  AT_KEYWORDS([acl])
>
> Regards,
> Dumitru
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to