ovn-ic typically interconnects zones by attaching LRPs to a transit switch. On that switch, remote LRPs appear as LSPs of type "remote", so OVN treats them as regular L2 ports and 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.
Add Logical_Switch_Port options:is_router so the CMS can mark a type=remote port as representing a logical router port. lsp_is_router() now returns true for such ports, so they are handled like type=router ports; in particular they are omitted from _MC_flood_l2. The option is ignored for any other port type. Assisted-by: Claude Opus 5, Cursor Signed-off-by: Han Zhou <[email protected]> --- Notes: v2: - Extend lsp_is_router() for type=remote + options:is_router instead of adding a multicast-specific helper (Dumitru). - Add missing OVN_CLEANUP_NORTHD in the new test. Documentation/ref/ovn-logical-flows.7.rst | 10 ++- NEWS | 4 ++ lib/mcast-group-index.h | 4 +- northd/northd.h | 6 +- ovn-nb.xml | 14 +++++ tests/ovn-northd.at | 74 +++++++++++++++++++++++ 6 files changed, 107 insertions(+), 5 deletions(-) diff --git a/Documentation/ref/ovn-logical-flows.7.rst b/Documentation/ref/ovn-logical-flows.7.rst index 1a9168ac8686..97305ea06fef 100644 --- a/Documentation/ref/ovn-logical-flows.7.rst +++ b/Documentation/ref/ovn-logical-flows.7.rst @@ -1470,7 +1470,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 ``remote`` 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 @@ -1485,7 +1486,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 ``remote`` 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 @@ -1513,7 +1515,9 @@ 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 ``remote`` 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 40a1b9867be5..81fbdf1e9d31 100644 --- a/NEWS +++ b/NEWS @@ -120,6 +120,10 @@ OVN v26.09.0 - xxx xx xxxx filter the routes learned through the port by route tag. This supersedes "ic-route-filter-tag", which is now deprecated and is ignored when "ic-route-learn-tag-rules" is set. + - Add Logical_Switch_Port option "is_router" for type=remote ports that + represent a logical router port (e.g. ovn-ic transit switch LSPs). + Such ports are treated like type=router, including omission 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..ae88b4900eb0 100644 --- a/lib/mcast-group-index.h +++ b/lib/mcast-group-index.h @@ -43,7 +43,9 @@ enum ovn_mcast_tunnel_keys { */ OVN_MCAST_FLOOD_L2_TUNNEL_KEY, /* Logical switch broadcast domain * excluding ports towards logical - * routers. + * routers (type=router, or + * type=remote with + * options:is_router=true). */ OVN_MIN_IP_MULTICAST, OVN_MAX_IP_MULTICAST = OVN_MAX_MULTICAST, diff --git a/northd/northd.h b/northd/northd.h index 2e3a9e00dad7..9a74a4abce3c 100644 --- a/northd/northd.h +++ b/northd/northd.h @@ -1143,7 +1143,11 @@ lsp_is_enabled(const struct nbrec_logical_switch_port *lsp) static inline bool lsp_is_router(const struct nbrec_logical_switch_port *nbsp) { - return !strcmp(nbsp->type, "router"); + /* type=router, or a type=remote LSP that CMS marked as representing a + * remote LRP (e.g. ovn-ic transit switch ports). */ + return !strcmp(nbsp->type, "router") + || (!strcmp(nbsp->type, "remote") + && smap_get_bool( ->options, "is_router", false)); } static inline bool diff --git a/ovn-nb.xml b/ovn-nb.xml index c741a3b3279c..57b81d4b44b8 100644 --- a/ovn-nb.xml +++ b/ovn-nb.xml @@ -1777,6 +1777,20 @@ </column> </group> + <group title="Options for remote ports representing routers"> + <column name="options" key="is_router" + type='{"type": "boolean"}'> + If set to <code>true</code> on a port whose <ref column="type"/> is + <code>remote</code>, treat the port as a router port (equivalent to + <code>type=router</code>). CMS may set this on + <code>remote</code> LSPs that back LRPs in another OVN + interconnection zone. Such ports are omitted from the + <code>_MC_flood_l2</code> multicast group so IP multicast is not + flooded toward them. Ignored unless <ref column="type"/> is + <code>remote</code>. Default: <code>false</code>. + </column> + </group> + </group> <group title="Containers"> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index d19978a62a1d..74c75a190298 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -8792,6 +8792,80 @@ OVN_CLEANUP_NORTHD AT_CLEANUP ]) +OVN_FOR_EACH_NORTHD_NO_HV([ +AT_SETUP([LSP type=remote 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 +]) + +dnl The option is ignored unless type is remote. +check ovn-nbctl lsp-set-type remote1 "" +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"], [0], [dnl +1 +]) + +OVN_CLEANUP_NORTHD +AT_CLEANUP +]) + OVN_FOR_EACH_NORTHD_NO_HV_PARALLELIZATION([ AT_SETUP([ACLs after lb]) AT_KEYWORDS([acl]) -- 2.38.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
