NAT records with only distributed dnat_and_snat configured were missing
from logical switch ARP incremental processing node data, which was incorrect 
behavior.

Reported-at: 
https://mail.openvswitch.org/pipermail/ovs-dev/2026-January/429694.html
Fixes: 1b4058b9162c ("northd: Process external arps on ha chassis.")
Signed-off-by: Alexandra Rukomoinikova <[email protected]>
---
 northd/en-ls-arp.c  | 10 ++++-----
 tests/system-ovn.at | 54 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/northd/en-ls-arp.c b/northd/en-ls-arp.c
index d571dc941..a96b67928 100644
--- a/northd/en-ls-arp.c
+++ b/northd/en-ls-arp.c
@@ -71,13 +71,12 @@ ls_arp_table_clear(struct ls_arp_table *table)
 }
 
 static inline bool
-is_centralized_nat_record(const struct ovn_nat *nat_entry)
+is_nat_dgp_connected(const struct ovn_nat *nat_entry)
 {
     return nat_entry->is_valid
            && nat_entry->l3dgw_port
            && nat_entry->l3dgw_port->peer
-           && nat_entry->l3dgw_port->peer->od
-           && !nat_entry->is_distributed;
+           && nat_entry->l3dgw_port->peer->od;
 }
 
 static void
@@ -98,9 +97,10 @@ nat_record_data_create(struct ls_arp_record *ls_arp_record,
         for (size_t i = 0; i < lrnat_rec->n_nat_entries; i++) {
             const struct ovn_nat *nat_entry = &lrnat_rec->nat_entries[i];
 
-            if (is_centralized_nat_record(nat_entry)) {
+            if (is_nat_dgp_connected(nat_entry)) {
                 hmapx_add(&ls_arp_record->nat_records,
                           (struct lrnat_rec *) lrnat_rec);
+                continue;
             }
         }
     }
@@ -283,7 +283,7 @@ nat_odmap_create(struct lr_nat_record *lrnat_rec,
     for (size_t i = 0; i < lrnat_rec->n_nat_entries; i++) {
         const struct ovn_nat *nat_entry = &lrnat_rec->nat_entries[i];
 
-        if (is_centralized_nat_record(nat_entry)) {
+        if (is_nat_dgp_connected(nat_entry)) {
             hmapx_add(odmap, nat_entry->l3dgw_port->peer->od);
         }
     }
diff --git a/tests/system-ovn.at b/tests/system-ovn.at
index 6eaf38a4c..3875bb97a 100644
--- a/tests/system-ovn.at
+++ b/tests/system-ovn.at
@@ -20531,3 +20531,57 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/.*error receiving.*/d
 /.*terminating with signal 15.*/d"])
 AT_CLEANUP
 ])
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([NAT with only dnat_and_snat NAT configured: IPv4])
+AT_KEYWORDS([ovnnat])
+
+ovn_start
+OVS_TRAFFIC_VSWITCHD_START()
+
+ADD_BR([br-int])
+ADD_BR([br-ext])
+
+ovs-ofctl add-flow br-ext action=normal
+# Set external-ids in br-int needed for ovn-controller
+ovs-vsctl \
+        -- set Open_vSwitch . external-ids:system-id=hv1 \
+        -- set Open_vSwitch . 
external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
+        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
+        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
+        -- set Open_vSwitch . external-ids:ovn-bridge-mappings=phynet:br-ext
+        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
+
+# Start ovn-controller
+start_daemon ovn-controller
+
+check ovn-nbctl lr-add lr1
+check ovn-nbctl ls-add sw0
+check ovn-nbctl ls-add public
+
+check ovn-nbctl lrp-add lr1 rp-sw0 00:00:01:01:02:03 192.168.1.1/24
+check ovn-nbctl lrp-add lr1 rp-public 00:00:02:01:02:03 172.16.1.1/24
+
+check ovn-nbctl lsp-add-router-port sw0 sw0-rp rp-sw0
+check ovn-nbctl lsp-add-router-port public public-rp rp-public
+
+check ovn-nbctl lsp-add-localnet-port public localnet phynet
+
+NS_CHECK_CONNECTIVITY([ext-foo], [sw01-x], 172.16.0.1)
+
+# Create distributed nat and set gw chassis to non-exisrting
+# one - to check distributed NAT on non gw-chassis.
+check ovn-nbctl lrp-set-gateway-chassis rp-public hv2
+check ovn-nbctl lr-nat-del lr1
+check ovn-nbctl lr-nat-add lr1 dnat_and_snat 172.16.0.1 192.168.1.2 sw01-x 
00:00:04:00:00:01
+
+NS_EXEC([ext-foo], [ip r add 172.16.0.1/32 dev ext-foo])
+NS_CHECK_CONNECTIVITY([ext-foo], [sw01-x], 172.16.0.1)
+
+OVN_CLEANUP_CONTROLLER([hv1])
+OVN_CLEANUP_NORTHD
+as
+OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
+/connection dropped.*/d"])
+AT_CLEANUP
+])
-- 
2.48.1

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

Reply via email to