Unlike ports on a gateway router that end up with 'l3gateway' port
binding type, the distributed gateway ports have the 'patch' type and
their corresponding cr-* ports get 'chassisredirect'.

This means that while creating RA for DGP ports, the 'preserved' flag
ends up false and the MLF_OVERRIDE_LOCAL_ONLY flag not set as a result.
This leads to DGP RAs to not be sent out on localnet ports.

However, this is not a desired behavior.  The router is supposed to be
able to send RAs to the physical network via localnet on a chassis of
residence regardless of it being a full gateway router or a standard
logical router with a distributed gateway port.

Fix this by also checking for the 'chassis-redirect-port' option in
the port binding, which northd sets on DGP LRPs to reference their
cr-* companion port.

A new test is added to check the DGP path.  Old GR test converted into
a macro to avoid code duplication.  While at it, added the missing
Sb synchronization before the port type check.

Fixes: 744340f701b0 ("Allow LR to send RAs through localnet port.")
Reported-at: https://github.com/ovn-org/ovn/issues/313
Reported-at: 
https://mail.openvswitch.org/pipermail/ovs-discuss/2026-July/053988.html
Reported-by: Meno Abels <[email protected]>
Assisted-by: claude-opus-4.6, OpenCode
Signed-off-by: Ilya Maximets <[email protected]>
---
 controller/pinctrl.c |  3 ++-
 tests/ovn.at         | 41 ++++++++++++++++++++++++++++++++---------
 2 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index 1728aa790..679b20d32 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -4704,7 +4704,8 @@ prepare_ipv6_ras(const struct shash 
*local_active_ports_ras,
         ra->metadata  = peer->datapath->tunnel_key;
         ra->preserved = (!strcmp(pb->type,"l2gateway") ||
                         !strcmp(pb->type,"l3gateway") ||
-                        !strcmp(pb->type,"chassisredirect"));
+                        !strcmp(pb->type,"chassisredirect") ||
+                        smap_get(&pb->options, "chassis-redirect-port"));
         ra->delete_me = false;
 
         /* pinctrl_handler thread will send the IPv6 RAs. */
diff --git a/tests/ovn.at b/tests/ovn.at
index 41d8526ae..b70236c68 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -18038,9 +18038,16 @@ OVN_CLEANUP([hv1],[hv2])
 AT_CLEANUP
 ])
 
-
+dnl OVN_TEST_PERIODIC_RA_LOCALNET([mode])
+dnl
+dnl Tests that periodic IPv6 RAs on a gateway or distributed gateway port
+dnl are forwarded through localnet ports to the provider network.
+dnl
+dnl mode: "l3gateway" - LR with options:chassis (gateway router)
+dnl        "dgp"      - LRP with gateway_chassis (distributed gateway port)
+m4_define([OVN_TEST_PERIODIC_RA_LOCALNET], [dnl
 OVN_FOR_EACH_NORTHD([
-AT_SETUP([IPv6 periodic gateway RA enabled for localnet adjacent switch ports])
+AT_SETUP([IPv6 periodic $1 RA enabled for localnet adjacent switch ports])
 CHECK_SCAPY
 ovn_start
 
@@ -18056,9 +18063,15 @@ check ovs-vsctl add-br br-phys
 check ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 ovn_attach n1 br-phys 192.168.0.3
 
-check ovn-nbctl lr-add ro -- set Logical_Router ro options:chassis="hv1"
+check ovn-nbctl lr-add ro
 check ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01
 
+m4_if([$1], [l3gateway], [
+check ovn-nbctl set Logical_Router ro options:chassis="hv1"
+], [
+check ovn-nbctl lrp-set-gateway-chassis ro-sw hv1
+])
+
 check ovn-nbctl ls-add sw
 check ovn-nbctl lsp-add-localnet-port sw ln phys
 
@@ -18068,7 +18081,14 @@ check ovn-nbctl lsp-set-addresses sw-p1 
"00:00:00:00:00:02 aef0::200:ff:fe00:2"
 check ovn-nbctl lsp-add sw sw-p2
 check ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
 
-AT_CHECK([ovn-sbctl get Port_Binding ro-sw type | tr -d '\n'],[0],[l3gateway])
+check ovn-nbctl --wait=sb sync
+
+m4_if([$1], [l3gateway], [dnl
+AT_CHECK([ovn-sbctl get Port_Binding ro-sw type | tr -d '\n'], [0], 
[l3gateway])
+], [dnl
+AT_CHECK([ovn-sbctl get Port_Binding ro-sw type | tr -d '\n'], [0], [patch])
+AT_CHECK([ovn-sbctl get Port_Binding cr-ro-sw type | tr -d '\n'], [0], 
[chassisredirect])
+])
 
 check ovn-nbctl set Logical_Router_Port ro-sw 
ipv6_ra_configs:send_periodic=true
 check ovn-nbctl set Logical_Router_Port ro-sw 
ipv6_ra_configs:address_mode=slaac
@@ -18087,11 +18107,11 @@ wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
 ra_received() {
-    $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" $1 | sed '/^ffffffffffff/d' | 
wc -l
+    $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" ${1} | sed '/^ffffffffffff/d' 
| wc -l
 }
 
 ra_test() {
-    interface=$1
+    interface=${1}
     shift 1
     local ra_packet=$(fmt_pkt "
         Ether(src='00:00:00:00:00:01', dst='33:33:00:00:00:01') /
@@ -18127,15 +18147,18 @@ ra_test() {
     rm -f expected
 }
 
-# check that RAs are sent
+# Check that RAs are sent to vifs.
 ra_test vif1
 
-# check that RAs are recived on br-phys
+# Check that RAs are received on br-phys.
 ra_test br-phys
 
 OVN_CLEANUP([hv1],[hv2])
 AT_CLEANUP
-])
+])])
+
+OVN_TEST_PERIODIC_RA_LOCALNET([l3gateway])
+OVN_TEST_PERIODIC_RA_LOCALNET([dgp])
 
 OVN_FOR_EACH_NORTHD([
 AT_SETUP([ACL reject rule test])
-- 
2.54.0

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

Reply via email to