A /31 point-to-point link has no broadcast address; both addresses in
the range are usable hosts.  However, ovn-northd computed a traditional
subnet broadcast for the router port and included it in the priority-100
lr_in_ip_input L3 admission control drop flow (ip4.src == {...}).  On a
/31, that "broadcast" address is the peer, so all traffic originating
from the /31 peer was dropped.

Skip the broadcast address in the admission control drop set for /31
networks so that /31 router ports work as expected.

Fixes: 936b640f4934 ("ovn: Implement basic logical L3 routing.")
Assisted-by: Claude Opus 4.8, Cursor
Signed-off-by: Han Zhou <[email protected]>
---
 Documentation/ref/ovn-logical-flows.7.rst |  2 ++
 NEWS                                      |  4 ++++
 northd/northd.c                           |  6 ++++-
 tests/ovn-northd.at                       | 27 +++++++++++++++++++++++
 4 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/Documentation/ref/ovn-logical-flows.7.rst 
b/Documentation/ref/ovn-logical-flows.7.rst
index 6ce1bdfad1ef..e60732a2c283 100644
--- a/Documentation/ref/ovn-logical-flows.7.rst
+++ b/Documentation/ref/ovn-logical-flows.7.rst
@@ -2270,6 +2270,8 @@ contains the following flows to implement very basic IP 
host functionality.
     ``REGBIT_EGRESS_LOOPBACK``.
 
   - ``ip4.src`` is the broadcast address of any IP network known to the router.
+    Point-to-point (``/31``, RFC 3021) networks have no broadcast address and
+    are excluded, so that traffic from a ``/31`` peer is not dropped.
 
 - A priority-100 flow parses DHCPv6 replies from IPv6 prefix delegation routers
   (``udp.src == 547 && udp.dst == 546``). The ``handle_dhcpv6_reply`` is used 
to
diff --git a/NEWS b/NEWS
index 68cca917e570..229f5b2e1eb8 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,9 @@
 Post v26.03.0
 -------------
+   - Logical router ports configured with a /31 (RFC 3021 point-to-point)
+     network are now supported.  A /31 has no broadcast address, so the L3
+     admission control no longer drops traffic from the /31 peer as a
+     broadcast source.
    - Added Transit Switch port support with new ovn-ic-nbctl 'tsp-add',
      'tsp-del' and 'tsp-set-addr' commands.
    - Added ability to set any "ipsec_*" NB_Global option to configure the
diff --git a/northd/northd.c b/northd/northd.c
index aecfb2ec6281..f0c70092b041 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -13140,7 +13140,11 @@ op_put_v4_networks(struct ds *ds, const struct 
ovn_port *op, bool add_bcast)
     ds_put_cstr(ds, "{");
     for (int i = 0; i < op->lrp_networks.n_ipv4_addrs; i++) {
         ds_put_format(ds, "%s, ", op->lrp_networks.ipv4_addrs[i].addr_s);
-        if (add_bcast) {
+        /* A /31 point-to-point link (RFC 3021) has no broadcast address:
+         * both addresses in the range are usable hosts.  Including the
+         * computed "broadcast" here would drop legitimate traffic from the
+         * /31 peer, so skip it for /31 networks. */
+        if (add_bcast && op->lrp_networks.ipv4_addrs[i].plen != 31) {
             ds_put_format(ds, "%s, ", op->lrp_networks.ipv4_addrs[i].bcast_s);
         }
     }
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 2973d1561ebf..01ddc38316cb 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -2409,6 +2409,33 @@ OVN_CLEANUP_NORTHD
 AT_CLEANUP
 ])
 
+OVN_FOR_EACH_NORTHD_NO_HV([
+AT_SETUP([router LRP /31 L3 admission control])
+ovn_start
+
+# A /31 point-to-point link (RFC 3021) has no broadcast address; both
+# addresses of the /31 are usable hosts.  The L3 admission control flow must
+# therefore not drop the computed "broadcast" address, otherwise traffic from
+# the /31 peer is dropped.
+check ovn-nbctl lr-add lr
+check ovn-nbctl lrp-add lr lrp31 00:00:00:00:00:01 10.0.0.0/31
+check ovn-nbctl lrp-add lr lrp24 00:00:00:00:00:03 10.0.2.1/24
+
+check ovn-nbctl --wait=sb sync
+ovn-sbctl dump-flows lr > lrflows
+AT_CAPTURE_FILE([lrflows])
+
+# The /31 peer (10.0.0.1) must not appear as a dropped broadcast source;
+# only the wider /24 network keeps its broadcast address.
+AT_CHECK([grep "lr_in_ip_input" lrflows | grep "priority=100" | grep "reg9" | 
ovn_strip_lflows], [0], [dnl
+  table=??(lr_in_ip_input     ), priority=100  , match=(ip4.src == {10.0.0.0} 
&& reg9[[0]] == 0), action=(drop;)
+  table=??(lr_in_ip_input     ), priority=100  , match=(ip4.src == {10.0.2.1, 
10.0.2.255} && reg9[[0]] == 0), action=(drop;)
+])
+
+OVN_CLEANUP_NORTHD
+AT_CLEANUP
+])
+
 # This test case tests that when a logical switch has load balancers associated
 # (with VIPs configured), the below logical flow is added by ovn-northd.
 # table=ls_out_pre_lb, priority=100, match=(ip), action=(reg0[[0]] = 1; next;)
-- 
2.38.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to