The probing tests used fixed delays and absolute probe counts around the
MAC binding aging deadline.  Under load, controller statistics could
cross the deadline before a reply was processed, causing an active
binding to be removed.

Synchronize with stale, used MAC cache flows while the binding still
exists, and compare probe counts relative to their observed values.
Reply to each neighbor as soon as its probe arrives so that serial
waits cannot consume the aging window.

Fixes: 1e4fa9f174f1 ("mac-cache: Do not send probes for inactive MAC Bindings.")
Assisted-by: GPT-5.6-sol, OpenCode
Signed-off-by: Ales Musil <[email protected]>
---
 tests/ovn.at | 47 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 30 insertions(+), 17 deletions(-)

diff --git a/tests/ovn.at b/tests/ovn.at
index 8acfecb7b..448e0818b 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -37738,14 +37738,12 @@ dump_arp 1 00:00:00:00:10:00 00:00:00:00:10:1b 
10.10.10.1 10.10.10.101 00:00:00:
 dump_ns 00:00:00:00:10:1b 00:00:00:00:10:00 fd11::65 fd11::1 fd11::65 > 
ucast_v6_65.pkt
 OVS_WAIT_UNTIL([test $($PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" 
hv1/vif1-tx.pcap | \
                 grep -Fc "$(cat ucast_v4_101.pkt)") -ge 2])
+v4_ts=$(fetch_column Mac_Binding timestamp ip=10.10.10.101)
+send_garp hv1 vif1 2 00:00:00:00:10:1b 00:00:00:00:10:00 10.10.10.101 
10.10.10.1
+
 OVS_WAIT_UNTIL([test $($PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" 
hv1/vif1-tx.pcap | \
                 grep -Fc "$(cat ucast_v6_65.pkt)") -ge 2])
-
-# The neighbours answer, refreshing the rows in place (resetting
-# arp_attempts).  Confirm the timestamps advanced.
-v4_ts=$(fetch_column Mac_Binding timestamp ip=10.10.10.101)
 v6_ts=$(fetch_column Mac_Binding timestamp ip=\"fd11::65\")
-send_garp hv1 vif1 2 00:00:00:00:10:1b 00:00:00:00:10:00 10.10.10.101 
10.10.10.1
 send_na hv1 vif1 00:00:00:00:10:1b 00:00:00:00:10:00 fd11::65 fd11::1
 OVS_WAIT_UNTIL([test $(fetch_column Mac_Binding timestamp ip=10.10.10.101) -gt 
$v4_ts])
 OVS_WAIT_UNTIL([test $(fetch_column Mac_Binding timestamp ip=\"fd11::65\") -gt 
$v6_ts])
@@ -37869,6 +37867,25 @@ dump_icmp() {
     echo $packet
 }
 
+mac_cache_flow_is_stale() {
+    local flow=$1
+    local stats field n_packets idle_age
+
+    stats=$(as hv1 ovs-ofctl dump-flows br-int \
+            "table=OFTABLE_MAC_CACHE_USE,$flow" | grep 'n_packets=')
+    n_packets=
+    idle_age=
+    for field in $stats; do
+        field=${field%,}
+        case $field in
+            n_packets=*) n_packets=${field#n_packets=} ;;
+            idle_age=*) idle_age=${field#idle_age=} ;;
+        esac
+    done
+
+    test "$n_packets" -gt 0 && test "$idle_age" -ge "$aging_th"
+}
+
 aging_th=5
 net_add n1
 sim_add hv1
@@ -37928,17 +37945,15 @@ OVS_WAIT_UNTIL([$(ovs-ofctl dump-flows br-int 
table=OFTABLE_MAC_BINDING | \
 
 send_icmp_echo_req hv1 public 00:00:00:00:10:00 00:00:00:00:10:1a 192.168.20.2 
192.168.10.100
 
-# Wait until ovn-controller sends the ARP request.
-OVS_WAIT_UNTIL([test $(grep -c "Sending ARP/ND.*ip: 192.168.20.2" 
hv1/ovn-controller.log) -eq 1])
-send_icmp_echo_req hv1 public 00:00:00:00:10:00 00:00:00:00:10:1a 192.168.20.2 
192.168.10.100
-
 # Now drop ICMP echo reply in order to force OVN to arp the mac binding entry
 # for the distributed router lr.
 check ovn-nbctl --wait=hv acl-add join from-lport 1000 'inport == "join-lr" && 
icmp' drop
 
-sleep $((aging_th / 2))
+OVS_WAIT_UNTIL([mac_cache_flow_is_stale 'ip,nw_src=192.168.20.2'])
+
+probe_count=$(grep -c "Sending ARP/ND.*ip: 192.168.20.2" 
hv1/ovn-controller.log)
 send_icmp_echo_req hv1 public 00:00:00:00:10:00 00:00:00:00:10:1a 192.168.20.2 
192.168.10.100
-OVS_WAIT_UNTIL([test $(grep -c "Sending ARP/ND.*ip: 192.168.20.2" 
hv1/ovn-controller.log) -eq 2])
+OVS_WAIT_UNTIL([test "$(grep -c "Sending ARP/ND.*ip: 192.168.20.2" 
hv1/ovn-controller.log)" -gt "$probe_count"])
 
 check ovn-nbctl --wait=hv acl-del join
 wait_row_count mac_binding 0 ip="192.168.10.100" logical_port="gw-public"
@@ -37949,17 +37964,15 @@ wait_row_count mac_binding 1 
mac=\"00:00:00:00:30:00\" ip=\"fd12::2\"
 
 send_icmp6_echo_req hv1 public 00:00:00:00:10:00 00:00:00:00:50:01 fd12::2 
fd11::64
 
-# Wait until ovn-controller sends the NS request.
-OVS_WAIT_UNTIL([test $(grep -c "Sending ARP/ND.*ip: fd12::2" 
hv1/ovn-controller.log) -eq 1])
-send_icmp6_echo_req hv1 public 00:00:00:00:10:00 00:00:00:00:50:01 fd12::2 
fd11::64
-
 # Now drop ICMPv6 echo reply in order to force OVN to send NS for the lr mac 
binding entry.
 check ovn-nbctl --wait=hv acl-add join from-lport 1010 'inport == "join-lr" && 
ip6 && icmp6.type == 0x87' allow
 check ovn-nbctl --wait=hv acl-add join from-lport 1000 'inport == "join-lr" && 
icmp' drop
 
-sleep $((aging_th / 2))
+OVS_WAIT_UNTIL([mac_cache_flow_is_stale 'ipv6,ipv6_src=fd12::2'])
+
+probe_count=$(grep -c "Sending ARP/ND.*ip: fd12::2" hv1/ovn-controller.log)
 send_icmp6_echo_req hv1 public 00:00:00:00:10:00 00:00:00:00:50:01 fd12::2 
fd11::64
-OVS_WAIT_UNTIL([test $(grep -c "Sending ARP/ND.*ip: fd12::2" 
hv1/ovn-controller.log) -eq 2])
+OVS_WAIT_UNTIL([test "$(grep -c "Sending ARP/ND.*ip: fd12::2" 
hv1/ovn-controller.log)" -gt "$probe_count"])
 
 wait_row_count mac_binding 0 ip=\"fd12::2\" logical_port="gw-join"
 
-- 
2.55.0

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

Reply via email to