Re: [PATCH v2 bpf-next 1/2] selftests/bpf: Fix the flaky tc_redirect_dtime test

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 1/19/24 10:05 PM, Martin KaFai Lau wrote:
From: Martin KaFai Lau <martin.lau@xxxxxxxxxx>

BPF CI has been reporting the tc_redirect_dtime test failing
from time to time:

test_inet_dtime:PASS:setns src 0 nsec
(network_helpers.c:253: errno: No route to host) Failed to connect to server
close_netns:PASS:setns 0 nsec
test_inet_dtime:FAIL:connect_to_fd unexpected connect_to_fd: actual -1 < expected 0
test_tcp_clear_dtime:PASS:tcp ip6 clear dtime ingress_fwdns_p100 0 nsec

The connect_to_fd failure (EHOSTUNREACH) is from the
test_tcp_clear_dtime() test and it is the very first IPv6 traffic
after setting up all the links, addresses, and routes.

The symptom is this first connect() is always slow. In my setup, it
could take ~3s.

After some tracing and tcpdump, the slowness is mostly spent in
the neighbor solicitation in the "ns_fwd" namespace while
the "ns_src" and "ns_dst" are fine.

I forced the kernel to drop the neighbor solicitation messages.
I can then reproduce EHOSTUNREACH. What actually happen could be:
- the neighbor advertisement came back a little slow.
- the "ns_fwd" namespace concluded a neighbor discovery failure
   and triggered the ndisc_error_report() => ip6_link_failure() =>
   icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0)
- the client's connect() reports EHOSTUNREACH after receiving
   the ICMPV6_DEST_UNREACH message.

The neigh table of both "ns_src" and "ns_dst" namespace has already
been manually populated but not the "ns_fwd" namespace. This patch

I tried one experiment which comments out manual population of neigh mac address
like below:

diff --git a/tools/testing/selftests/bpf/prog_tests/tc_redirect.c b/tools/testing/selftests/bpf/prog_tests/tc_redirect.c
index 518f143c5b0f..feb477366393 100644
--- a/tools/testing/selftests/bpf/prog_tests/tc_redirect.c
+++ b/tools/testing/selftests/bpf/prog_tests/tc_redirect.c
@@ -241,14 +241,14 @@ static int netns_setup_links_and_routes(struct netns_setup_result *result)
        SYS(fail, "ip route add " IP4_DST "/32 dev src scope global");
        SYS(fail, "ip route add " IP4_NET "/16 dev src scope global");
        SYS(fail, "ip route add " IP6_DST "/128 dev src scope global");
-
+#if 0
        if (result->dev_mode == MODE_VETH) {
                SYS(fail, "ip neigh add " IP4_DST " dev src lladdr %s",
                    src_fwd_addr);
                SYS(fail, "ip neigh add " IP6_DST " dev src lladdr %s",
                    src_fwd_addr);
        }
-
+#endif
        close_netns(nstoken);
/** setup in 'fwd' namespace */
@@ -284,12 +284,12 @@ static int netns_setup_links_and_routes(struct netns_setup_result *result)
        SYS(fail, "ip route add " IP4_SRC "/32 dev dst scope global");
        SYS(fail, "ip route add " IP4_NET "/16 dev dst scope global");
        SYS(fail, "ip route add " IP6_SRC "/128 dev dst scope global");
-
+#if 0
        if (result->dev_mode == MODE_VETH) {
                SYS(fail, "ip neigh add " IP4_SRC " dev dst lladdr " MAC_DST_FWD);
                SYS(fail, "ip neigh add " IP6_SRC " dev dst lladdr " MAC_DST_FWD);
        }
-
+#endif
        close_netns(nstoken);
return 0;

And I can 100% reliably trigger the following error:

$ ./test_progs -t tc_redirect
...
All error logs:
test_tc_redirect:PASS:pthread_create 0 nsec
netns_setup_namespaces:PASS:ip netns add ns_src 0 nsec
netns_setup_namespaces:PASS:ip netns add ns_fwd 0 nsec
netns_setup_namespaces:PASS:ip netns add ns_dst 0 nsec
test_tc_redirect_run_tests:PASS:setup namespaces 0 nsec
...
test_tcp:PASS:setns dst 0 nsec
test_tcp:PASS:listen 0 nsec
close_netns:PASS:setns 0 nsec
open_netns:PASS:malloc token 0 nsec
open_netns:PASS:open /proc/self/ns/net 0 nsec
open_netns:PASS:open netns fd 0 nsec
open_netns:PASS:setns 0 nsec
test_tcp:PASS:setns src 0 nsec
(network_helpers.c:253: errno: Operation now in progress) Failed to connect to server
test_tcp:FAIL:connect_to_fd unexpected connect_to_fd: actual -1 < expected 0
close_netns:PASS:setns 0 nsec
test_ping:FAIL:ip netns exec ns_src ping -i 0.2 -c 3 -w 10 -q 172.16.2.100 > /dev/null unexpected error: 256 (errno 115)
...
open_netns:PASS:setns 0 nsec
test_tcp:PASS:setns src 0 nsec
(network_helpers.c:253: errno: Operation now in progress) Failed to connect to server
test_tcp:FAIL:connect_to_fd unexpected connect_to_fd: actual -1 < expected 0
close_netns:PASS:setns 0 nsec
test_ping:FAIL:ip netns exec ns_src ping6 -i 0.2 -c 3 -w 10 -q 0::2:dead:beef:cafe > /dev/null unexpected error: 256 (errno 115)
close_netns:PASS:setns 0 nsec

The error message:
  (network_helpers.c:253: errno: Operation now in progress) Failed to connect to server
not exactly the same but very similar to the failure observed in CI:
  (network_helpers.c:253: errno: No route to host) Failed to connect to server

The above error 'Operation now in progress' may indicate some slowness in the kernel
which caused the test failure, with or without my above hack.

fixes it by manually populating the neigh table also in the "ns_fwd"
namespace.

Although the namespace configuration part had been existed before
the tc_redirect_dtime test, still Fixes-tagging the patch when
the tc_redirect_dtime test was added since it is the only test
hitting it so far.

Fixes: c803475fd8dd ("bpf: selftests: test skb->tstamp in redirect_neigh")
Signed-off-by: Martin KaFai Lau <martin.lau@xxxxxxxxxx>
---
  tools/testing/selftests/bpf/prog_tests/tc_redirect.c | 11 +++++++++++
  1 file changed, 11 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/tc_redirect.c b/tools/testing/selftests/bpf/prog_tests/tc_redirect.c
index 518f143c5b0f..610887157fd8 100644
--- a/tools/testing/selftests/bpf/prog_tests/tc_redirect.c
+++ b/tools/testing/selftests/bpf/prog_tests/tc_redirect.c
@@ -188,6 +188,7 @@ static int netns_setup_links_and_routes(struct netns_setup_result *result)
  {
  	struct nstoken *nstoken = NULL;
  	char src_fwd_addr[IFADDR_STR_LEN+1] = {};
+	char src_addr[IFADDR_STR_LEN + 1] = {};
  	int err;
if (result->dev_mode == MODE_VETH) {
@@ -208,6 +209,9 @@ static int netns_setup_links_and_routes(struct netns_setup_result *result)
  	if (get_ifaddr("src_fwd", src_fwd_addr))
  		goto fail;
+ if (get_ifaddr("src", src_addr))
+		goto fail;
+
  	result->ifindex_src = if_nametoindex("src");
  	if (!ASSERT_GT(result->ifindex_src, 0, "ifindex_src"))
  		goto fail;
@@ -270,6 +274,13 @@ static int netns_setup_links_and_routes(struct netns_setup_result *result)
  	SYS(fail, "ip route add " IP4_DST "/32 dev dst_fwd scope global");
  	SYS(fail, "ip route add " IP6_DST "/128 dev dst_fwd scope global");
+ if (result->dev_mode == MODE_VETH) {
+		SYS(fail, "ip neigh add " IP4_SRC " dev src_fwd lladdr %s", src_addr);
+		SYS(fail, "ip neigh add " IP6_SRC " dev src_fwd lladdr %s", src_addr);
+		SYS(fail, "ip neigh add " IP4_DST " dev dst_fwd lladdr %s", MAC_DST);
+		SYS(fail, "ip neigh add " IP6_DST " dev dst_fwd lladdr %s", MAC_DST);
+	}
+
  	close_netns(nstoken);
/** setup in 'dst' namespace */




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux