On Mon, Jan 26, 2026 at 10:47 AM Alexandra Rukomoinikova
<[email protected]> wrote:
>
> 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]>
Thanks for fixing the issue and for adding a system test.
I applied this patch to main after adding a simple test in
ovn-northd.at to cover this scenario.
I thought it would be better to have a test in ovn-northd.at too.
-------------------
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 98f108db0e..0bcb5e90b3 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -19123,6 +19123,76 @@ OVN_CLEANUP_NORTHD
AT_CLEANUP
])
+OVN_FOR_EACH_NORTHD_NO_HV([
+AT_SETUP([Logical Switch ARP filtering - only distributed NATs])
+ovn_start
+
+check ovn-sbctl chassis-add ch1 geneve 127.0.0.1
+
+check ovn-nbctl ls-add sw0
+check ovn-nbctl lsp-add sw0 sw0-port1
+check ovn-nbctl lsp-set-addresses sw0-port1 "50:54:00:00:00:03 10.0.0.3"
+check ovn-nbctl lsp-add sw0 sw0-port2
+check ovn-nbctl lsp-set-addresses sw0-port2 "50:54:00:00:00:04 10.0.0.4"
+
+# Create a logical router and attach both logical switches
+check ovn-nbctl lr-add lr0
+check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24 1000::a/64
+check ovn-nbctl lsp-add-router-port sw0 sw0-lr0 lr0-sw0
+
+
+check ovn-nbctl ls-add public
+check ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24
+check ovn-nbctl lsp-add public public-lr0 -- set Logical_Switch_Port
public-lr0 \
+ type=router options:router-port=lr0-public \
+ -- lsp-set-addresses public-lr0 router
+
+check ovn-nbctl lrp-set-gateway-chassis lr0-public hv1
+
+# localnet port
+check ovn-nbctl lsp-add-localnet-port public ln-public public
+
+check ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.168.0.50 10.0.0.3
sw0-port1 f0:00:00:00:00:03
+
+check ovn-nbctl --wait=sb sync
+
+AT_CHECK([ovn-sbctl lflow-list public | grep ls_in_apply_port_sec |
ovn_strip_lflows], [0], [dnl
+ table=??(ls_in_apply_port_sec), priority=0 , match=(1), action=(next;)
+ table=??(ls_in_apply_port_sec), priority=50 , match=(reg0[[15]]
== 1), action=(drop;)
+ table=??(ls_in_apply_port_sec), priority=70 , match=(reg0[[22]]
== 1), action=(drop;)
+ table=??(ls_in_apply_port_sec), priority=75 , match=(reg0[[22]]
== 1 && is_chassis_resident("cr-lr0-public")), action=(next;)
+ table=??(ls_in_apply_port_sec), priority=75 , match=(reg0[[22]]
== 1 && is_chassis_resident("sw0-port1")), action=(next;)
+])
+
+ovn-nbctl show
+ovn-sbctl show
+
+check ovn-nbctl clear logical_router_port lr0-public gateway_chassis
+check ovn-nbctl --wait=sb sync
+
+AT_CHECK([ovn-sbctl lflow-list public | grep ls_in_apply_port_sec |
ovn_strip_lflows], [0], [dnl
+ table=??(ls_in_apply_port_sec), priority=0 , match=(1), action=(next;)
+ table=??(ls_in_apply_port_sec), priority=50 , match=(reg0[[15]]
== 1), action=(drop;)
+])
+
+check ovn-nbctl --wait=sb ha-chassis-group-add hagrp1
+check ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 ch1 30
+hagrp1_uuid=$(fetch_column nb:ha_chassis_group _uuid name=hagrp1)
+check ovn-nbctl --wait=sb set logical_router_port lr0-public
ha_chassis_group=$hagrp1_uuid
+check ovn-nbctl --wait=sb sync
+
+AT_CHECK([ovn-sbctl lflow-list public | grep ls_in_apply_port_sec |
ovn_strip_lflows], [0], [dnl
+ table=??(ls_in_apply_port_sec), priority=0 , match=(1), action=(next;)
+ table=??(ls_in_apply_port_sec), priority=50 , match=(reg0[[15]]
== 1), action=(drop;)
+ table=??(ls_in_apply_port_sec), priority=70 , match=(reg0[[22]]
== 1), action=(drop;)
+ table=??(ls_in_apply_port_sec), priority=75 , match=(reg0[[22]]
== 1 && is_chassis_resident("cr-lr0-public")), action=(next;)
+ table=??(ls_in_apply_port_sec), priority=75 , match=(reg0[[22]]
== 1 && is_chassis_resident("sw0-port1")), action=(next;)
+])
+
+OVN_CLEANUP_NORTHD
+AT_CLEANUP
+])
+
---------------------------
Thanks
Numan
> ---
> v1 --> v2: fixed tests
> ---
> northd/en-ls-arp.c | 10 ++++----
> tests/system-ovn.at | 62 +++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 67 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..67f03e3be 100644
> --- a/tests/system-ovn.at
> +++ b/tests/system-ovn.at
> @@ -20531,3 +20531,65 @@ 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
> +
> +ADD_NAMESPACES(sw01-x)
> +ADD_VETH(sw01-x, sw01-x, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
> + "192.168.1.1")
> +check ovn-nbctl lsp-add sw0 sw01-x \
> + -- lsp-set-addresses sw01-x "f0:00:00:01:02:03 192.168.1.2"
> +
> +ADD_NAMESPACES(ext-foo)
> +ADD_VETH(ext-foo, ext-foo, br-ext, "172.16.1.100/24", "00:10:10:01:02:13", \
> + "172.16.1.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
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev