Commit ef3b682a authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'selftests-mptcp-counter-cache-stats-before-timeout'

Matthieu Baerts says:

====================
selftests: mptcp: counter cache & stats before timeout

Here are a bunch of small improvements to the MPTCP selftests:

- Patch 1: move code to mptcp_lib.sh to prepare the new features.

- Patch 2: simplify mptcp_lib_pr_err_stats helper use.

- Patch 3: remove unused last column from nstat output.

- Patch 4: improve stats dump in mptcp_join.sh.

- Patch 5: get counters from nstat history and simplify mptcp_connect.sh.

- Patch 6: avoid taking the same packet trace twice.

- Patch 7: wait for an event instead of a fix time.

- Patch 8: instead of using 'timeout' and print the stats after, another
  internal timeout is used: if it fires, it will print stats, then stop
  everything. This avoids confusions around stats in case of timeout.
====================

Link: https://patch.msgid.link/20251114-net-next-mptcp-sft-count-cache-stats-timeout-v1-0-863cb04e1b7b@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents ca412f25 eea2f448
Loading
Loading
Loading
Loading
+69 −77
Original line number Diff line number Diff line
@@ -375,38 +375,24 @@ do_transfer()
		local capfile="${rndh}-${connector_ns:0:3}-${listener_ns:0:3}-${cl_proto}-${srv_proto}-${connect_addr}-${port}"
		local capopt="-i any -s 65535 -B 32768 ${capuser}"

		ip netns exec ${listener_ns}  tcpdump ${capopt} -w "${capfile}-listener.pcap"  >> "${capout}" 2>&1 &
		ip netns exec ${listener_ns} tcpdump ${capopt} \
			-w "${capfile}-listener.pcap" >> "${capout}" 2>&1 &
		local cappid_listener=$!

		ip netns exec ${connector_ns} tcpdump ${capopt} -w "${capfile}-connector.pcap" >> "${capout}" 2>&1 &
		if [ ${listener_ns} != ${connector_ns} ]; then
			ip netns exec ${connector_ns} tcpdump ${capopt} \
				-w "${capfile}-connector.pcap" >> "${capout}" 2>&1 &
			local cappid_connector=$!
		fi

		sleep 1
	fi

	NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
		nstat -n
	mptcp_lib_nstat_init "${listener_ns}"
	if [ ${listener_ns} != ${connector_ns} ]; then
		NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
			nstat -n
	fi

	local stat_synrx_last_l
	local stat_ackrx_last_l
	local stat_cookietx_last
	local stat_cookierx_last
	local stat_csum_err_s
	local stat_csum_err_c
	local stat_tcpfb_last_l
	stat_synrx_last_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableSYNRX")
	stat_ackrx_last_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableACKRX")
	stat_cookietx_last=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesSent")
	stat_cookierx_last=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesRecv")
	stat_csum_err_s=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtDataCsumErr")
	stat_csum_err_c=$(mptcp_lib_get_counter "${connector_ns}" "MPTcpExtDataCsumErr")
	stat_tcpfb_last_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableFallbackACK")

	timeout ${timeout_test} \
		mptcp_lib_nstat_init "${connector_ns}"
	fi

	ip netns exec ${listener_ns} \
		./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
			$extra_args $local_addr < "$sin" > "$sout" &
@@ -416,40 +402,48 @@ do_transfer()

	local start
	start=$(date +%s%3N)
	timeout ${timeout_test} \
	ip netns exec ${connector_ns} \
		./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
			$extra_args $connect_addr < "$cin" > "$cout" &
	local cpid=$!

	mptcp_lib_wait_timeout "${timeout_test}" "${listener_ns}" \
		"${connector_ns}" "${port}" "${cpid}" "${spid}" &
	local timeout_pid=$!

	wait $cpid
	local retc=$?
	wait $spid
	local rets=$?

	if kill -0 $timeout_pid; then
		# Finished before the timeout: kill the background job
		mptcp_lib_kill_group_wait $timeout_pid
		timeout_pid=0
	fi

	local stop
	stop=$(date +%s%3N)

	if $capture; then
		sleep 1
		kill ${cappid_listener}
		if [ ${listener_ns} != ${connector_ns} ]; then
			kill ${cappid_connector}
		fi
	fi

	NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
		nstat | grep Tcp > /tmp/${listener_ns}.out
	mptcp_lib_nstat_get "${listener_ns}"
	if [ ${listener_ns} != ${connector_ns} ]; then
		NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
			nstat | grep Tcp > /tmp/${connector_ns}.out
		mptcp_lib_nstat_get "${connector_ns}"
	fi

	local duration
	duration=$((stop-start))
	printf "(duration %05sms) " "${duration}"
	if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
	if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ] || [ ${timeout_pid} -ne 0 ]; then
		mptcp_lib_pr_fail "client exit code $retc, server $rets"
		mptcp_lib_pr_err_stats "${listener_ns}" "${connector_ns}" "${port}" \
			"/tmp/${listener_ns}.out" "/tmp/${connector_ns}.out"
		mptcp_lib_pr_err_stats "${listener_ns}" "${connector_ns}" "${port}"

		echo
		cat "$capout"
@@ -463,38 +457,38 @@ do_transfer()
	rets=$?

	local extra=""
	local stat_synrx_now_l
	local stat_ackrx_now_l
	local stat_cookietx_now
	local stat_cookierx_now
	local stat_ooo_now
	local stat_tcpfb_now_l
	stat_synrx_now_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableSYNRX")
	stat_ackrx_now_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableACKRX")
	stat_cookietx_now=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesSent")
	stat_cookierx_now=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesRecv")
	stat_ooo_now=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtTCPOFOQueue")
	stat_tcpfb_now_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableFallbackACK")

	expect_synrx=$((stat_synrx_last_l))
	expect_ackrx=$((stat_ackrx_last_l))
	local stat_synrx
	local stat_ackrx
	local stat_cookietx
	local stat_cookierx
	local stat_ooo
	local stat_tcpfb
	stat_synrx=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableSYNRX")
	stat_ackrx=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableACKRX")
	stat_cookietx=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesSent")
	stat_cookierx=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesRecv")
	stat_ooo=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtTCPOFOQueue")
	stat_tcpfb=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableFallbackACK")

	expect_synrx=0
	expect_ackrx=0

	cookies=$(ip netns exec ${listener_ns} sysctl net.ipv4.tcp_syncookies)
	cookies=${cookies##*=}

	if [ ${cl_proto} = "MPTCP" ] && [ ${srv_proto} = "MPTCP" ]; then
		expect_synrx=$((stat_synrx_last_l+connect_per_transfer))
		expect_ackrx=$((stat_ackrx_last_l+connect_per_transfer))
		expect_synrx=${connect_per_transfer}
		expect_ackrx=${connect_per_transfer}
	fi

	if [ ${stat_synrx_now_l} -lt ${expect_synrx} ]; then
		mptcp_lib_pr_fail "lower MPC SYN rx (${stat_synrx_now_l})" \
	if [ ${stat_synrx} -lt ${expect_synrx} ]; then
		mptcp_lib_pr_fail "lower MPC SYN rx (${stat_synrx})" \
				  "than expected (${expect_synrx})"
		retc=1
	fi
	if [ ${stat_ackrx_now_l} -lt ${expect_ackrx} ]; then
		if [ ${stat_ooo_now} -eq 0 ]; then
			mptcp_lib_pr_fail "lower MPC ACK rx (${stat_ackrx_now_l})" \
	if [ ${stat_ackrx} -lt ${expect_ackrx} ]; then
		if [ ${stat_ooo} -eq 0 ]; then
			mptcp_lib_pr_fail "lower MPC ACK rx (${stat_ackrx})" \
					  "than expected (${expect_ackrx})"
			rets=1
		else
@@ -508,47 +502,45 @@ do_transfer()
		csum_err_s=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtDataCsumErr")
		csum_err_c=$(mptcp_lib_get_counter "${connector_ns}" "MPTcpExtDataCsumErr")

		local csum_err_s_nr=$((csum_err_s - stat_csum_err_s))
		if [ $csum_err_s_nr -gt 0 ]; then
			mptcp_lib_pr_fail "server got ${csum_err_s_nr} data checksum error[s]"
		if [ $csum_err_s -gt 0 ]; then
			mptcp_lib_pr_fail "server got ${csum_err_s} data checksum error[s]"
			rets=1
		fi

		local csum_err_c_nr=$((csum_err_c - stat_csum_err_c))
		if [ $csum_err_c_nr -gt 0 ]; then
			mptcp_lib_pr_fail "client got ${csum_err_c_nr} data checksum error[s]"
		if [ $csum_err_c -gt 0 ]; then
			mptcp_lib_pr_fail "client got ${csum_err_c} data checksum error[s]"
			retc=1
		fi
	fi

	if [ ${stat_ooo_now} -eq 0 ] && [ ${stat_tcpfb_last_l} -ne ${stat_tcpfb_now_l} ]; then
	if [ ${stat_ooo} -eq 0 ] && [ ${stat_tcpfb} -gt 0 ]; then
		mptcp_lib_pr_fail "unexpected fallback to TCP"
		rets=1
	fi

	if [ $cookies -eq 2 ];then
		if [ $stat_cookietx_last -ge $stat_cookietx_now ] ;then
		if [ $stat_cookietx -eq 0 ] ;then
			extra+=" WARN: CookieSent: did not advance"
		fi
		if [ $stat_cookierx_last -ge $stat_cookierx_now ] ;then
		if [ $stat_cookierx -eq 0 ] ;then
			extra+=" WARN: CookieRecv: did not advance"
		fi
	else
		if [ $stat_cookietx_last -ne $stat_cookietx_now ] ;then
		if [ $stat_cookietx -gt 0 ] ;then
			extra+=" WARN: CookieSent: changed"
		fi
		if [ $stat_cookierx_last -ne $stat_cookierx_now ] ;then
		if [ $stat_cookierx -gt 0 ] ;then
			extra+=" WARN: CookieRecv: changed"
		fi
	fi

	if [ ${stat_synrx_now_l} -gt ${expect_synrx} ]; then
	if [ ${stat_synrx} -gt ${expect_synrx} ]; then
		extra+=" WARN: SYNRX: expect ${expect_synrx},"
		extra+=" got ${stat_synrx_now_l} (probably retransmissions)"
		extra+=" got ${stat_synrx} (probably retransmissions)"
	fi
	if [ ${stat_ackrx_now_l} -gt ${expect_ackrx} ]; then
	if [ ${stat_ackrx} -gt ${expect_ackrx} ]; then
		extra+=" WARN: ACKRX: expect ${expect_ackrx},"
		extra+=" got ${stat_ackrx_now_l} (probably retransmissions)"
		extra+=" got ${stat_ackrx} (probably retransmissions)"
	fi

	if [ $retc -eq 0 ] && [ $rets -eq 0 ]; then
+37 −28
Original line number Diff line number Diff line
@@ -983,10 +983,8 @@ do_transfer()

	cond_start_capture ${listener_ns}

	NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
		nstat -n
	NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
		nstat -n
	mptcp_lib_nstat_init "${listener_ns}"
	mptcp_lib_nstat_init "${connector_ns}"

	local extra_args
	if [ $speed = "fast" ]; then
@@ -1026,7 +1024,6 @@ do_transfer()
	if [ "$test_linkfail" -gt 1 ];then
		listener_in="${sinfail}"
	fi
	timeout ${timeout_test} \
	ip netns exec ${listener_ns} \
		./mptcp_connect -t ${timeout_poll} -l -p ${port} -s ${srv_proto} \
			${extra_srv_args} "${bind_addr}" < "${listener_in}" > "${sout}" &
@@ -1036,7 +1033,6 @@ do_transfer()

	extra_cl_args="$extra_args $extra_cl_args"
	if [ "$test_linkfail" -eq 0 ];then
		timeout ${timeout_test} \
		ip netns exec ${connector_ns} \
			./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
				$extra_cl_args $connect_addr < "$cin" > "$cout" &
@@ -1044,20 +1040,22 @@ do_transfer()
		connector_in="${cinsent}"
		( cat "$cinfail" ; sleep 2; link_failure $listener_ns ; cat "$cinfail" ) | \
			tee "$cinsent" | \
			timeout ${timeout_test} \
				ip netns exec ${connector_ns} \
					./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
						$extra_cl_args $connect_addr > "$cout" &
	else
		connector_in="${cinsent}"
		tee "$cinsent" < "$cinfail" | \
			timeout ${timeout_test} \
			ip netns exec ${connector_ns} \
				./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
					$extra_cl_args $connect_addr > "$cout" &
	fi
	local cpid=$!

	mptcp_lib_wait_timeout "${timeout_test}" "${listener_ns}" \
		"${connector_ns}" "${port}" "${cpid}" "${spid}" &
	local timeout_pid=$!

	pm_nl_set_endpoint $listener_ns $connector_ns $connect_addr
	check_cestab $listener_ns $connector_ns

@@ -1066,17 +1064,20 @@ do_transfer()
	wait $spid
	local rets=$?

	if kill -0 $timeout_pid; then
		# Finished before the timeout: kill the background job
		mptcp_lib_kill_group_wait $timeout_pid
		timeout_pid=0
	fi

	cond_stop_capture

	NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
		nstat | grep Tcp > /tmp/${listener_ns}.out
	NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
		nstat | grep Tcp > /tmp/${connector_ns}.out
	mptcp_lib_nstat_get "${listener_ns}"
	mptcp_lib_nstat_get "${connector_ns}"

	if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
	if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ] || [ ${timeout_pid} -ne 0 ]; then
		fail_test "client exit code $retc, server $rets"
		mptcp_lib_pr_err_stats "${listener_ns}" "${connector_ns}" "${port}" \
			"/tmp/${listener_ns}.out" "/tmp/${connector_ns}.out"
		mptcp_lib_pr_err_stats "${listener_ns}" "${connector_ns}" "${port}"
		return 1
	fi

@@ -1151,12 +1152,20 @@ run_tests()
	do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP ${connect_addr}
}

_dump_stats()
{
	local ns="${1}"
	local side="${2}"

	mptcp_lib_print_err "${side} ns stats (${ns2})"
	mptcp_lib_pr_nstat "${ns}"
	echo
}

dump_stats()
{
	echo Server ns stats
	ip netns exec $ns1 nstat -as | grep Tcp
	echo Client ns stats
	ip netns exec $ns2 nstat -as | grep Tcp
	_dump_stats "${ns1}" "Server"
	_dump_stats "${ns2}" "Client"
}

chk_csum_nr()
+51 −7
Original line number Diff line number Diff line
@@ -106,23 +106,32 @@ mptcp_lib_pr_info() {
	mptcp_lib_print_info "INFO: ${*}"
}

# $1-2: listener/connector ns ; $3 port ; $4-5 listener/connector stat file
mptcp_lib_pr_nstat() {
	local ns="${1}"
	local hist="/tmp/${ns}.out"

	if [ -f "${hist}" ]; then
		awk '$2 != 0 { print "  "$0 }' "${hist}"
	else
		ip netns exec "${ns}" nstat -as | grep Tcp
	fi
}

# $1-2: listener/connector ns ; $3 port
mptcp_lib_pr_err_stats() {
	local lns="${1}"
	local cns="${2}"
	local port="${3}"
	local lstat="${4}"
	local cstat="${5}"

	echo -en "${MPTCP_LIB_COLOR_RED}"
	{
		printf "\nnetns %s (listener) socket stat for %d:\n" "${lns}" "${port}"
		ip netns exec "${lns}" ss -Menitam -o "sport = :${port}"
		cat "${lstat}"
		mptcp_lib_pr_nstat "${lns}"

		printf "\nnetns %s (connector) socket stat for %d:\n" "${cns}" "${port}"
		ip netns exec "${cns}" ss -Menitam -o "dport = :${port}"
		[ "${lstat}" != "${cstat}" ] && cat "${cstat}"
		[ "${lns}" != "${cns}" ] && mptcp_lib_pr_nstat "${cns}"
	} 1>&2
	echo -en "${MPTCP_LIB_COLOR_RESET}"
}
@@ -341,6 +350,19 @@ mptcp_lib_evts_get_info() {
		mptcp_lib_get_info_value "${1}" "^type:${3:-1},"
}

mptcp_lib_wait_timeout() {
	local timeout_test="${1}"
	local listener_ns="${2}"
	local connector_ns="${3}"
	local port="${4}"
	shift 4 # rest are PIDs

	sleep "${timeout_test}"
	mptcp_lib_print_err "timeout"
	mptcp_lib_pr_err_stats "${listener_ns}" "${connector_ns}" "${port}"
	kill "${@}" 2>/dev/null
}

# $1: PID
mptcp_lib_kill_wait() {
	[ "${1}" -eq 0 ] && return 0
@@ -376,14 +398,36 @@ mptcp_lib_is_v6() {
	[ -z "${1##*:*}" ]
}

mptcp_lib_nstat_init() {
	local ns="${1}"

	rm -f "/tmp/${ns}."{nstat,out}
	NSTAT_HISTORY="/tmp/${ns}.nstat" ip netns exec "${ns}" nstat -n
}

mptcp_lib_nstat_get() {
	local ns="${1}"

	# filter out non-*TCP stats, and the rate (last column)
	NSTAT_HISTORY="/tmp/${ns}.nstat" ip netns exec "${ns}" nstat -sz |
		grep -o ".*Tcp\S\+\s\+[0-9]\+" > "/tmp/${ns}.out"
}

# $1: ns, $2: MIB counter
# Get the counter from the history (mptcp_lib_nstat_{init,get}()) if available.
# If not, get the counter from nstat ignoring any history.
mptcp_lib_get_counter() {
	local ns="${1}"
	local counter="${2}"
	local hist="/tmp/${ns}.out"
	local count

	if [[ -s "${hist}" && "${counter}" == *"Tcp"* ]]; then
		count=$(awk "/^${counter} / {print \$2; exit}" "${hist}")
	else
		count=$(ip netns exec "${ns}" nstat -asz "${counter}" |
			awk 'NR==1 {next} {print $2}')
	fi
	if [ -z "${count}" ]; then
		mptcp_lib_fail_if_expected_feature "${counter} counter"
		return 1
+24 −21
Original line number Diff line number Diff line
@@ -169,41 +169,44 @@ do_transfer()
		cmsg+=",TCPINQ"
	fi

	NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
		nstat -n
	NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
		nstat -n
	mptcp_lib_nstat_init "${listener_ns}"
	mptcp_lib_nstat_init "${connector_ns}"

	timeout ${timeout_test} \
	ip netns exec ${listener_ns} \
		$mptcp_connect -t ${timeout_poll} -l -M 1 -p $port -s ${srv_proto} -c "${cmsg}" \
			${local_addr} < "$sin" > "$sout" &
	local spid=$!

	sleep 1
	mptcp_lib_wait_local_port_listen "${listener_ns}" "${port}"

	timeout ${timeout_test} \
	ip netns exec ${connector_ns} \
		$mptcp_connect -t ${timeout_poll} -M 2 -p $port -s ${cl_proto} -c "${cmsg}" \
			$connect_addr < "$cin" > "$cout" &

	local cpid=$!

	mptcp_lib_wait_timeout "${timeout_test}" "${listener_ns}" \
		"${connector_ns}" "${port}" "${cpid}" "${spid}" &
	local timeout_pid=$!

	wait $cpid
	local retc=$?
	wait $spid
	local rets=$?

	NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
		nstat | grep Tcp > /tmp/${listener_ns}.out
	NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
		nstat | grep Tcp > /tmp/${connector_ns}.out
	if kill -0 $timeout_pid; then
		# Finished before the timeout: kill the background job
		mptcp_lib_kill_group_wait $timeout_pid
		timeout_pid=0
	fi

	mptcp_lib_nstat_get "${listener_ns}"
	mptcp_lib_nstat_get "${connector_ns}"

	print_title "Transfer ${ip:2}"
	if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
	if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ] || [ ${timeout_pid} -ne 0 ]; then
		mptcp_lib_pr_fail "client exit code $retc, server $rets"
		mptcp_lib_pr_err_stats "${listener_ns}" "${connector_ns}" "${port}" \
			"/tmp/${listener_ns}.out" "/tmp/${connector_ns}.out"
		mptcp_lib_pr_err_stats "${listener_ns}" "${connector_ns}" "${port}"

		mptcp_lib_result_fail "transfer ${ip}"

+25 −21
Original line number Diff line number Diff line
@@ -155,12 +155,9 @@ do_transfer()
		sleep 1
	fi

	NSTAT_HISTORY=/tmp/${ns3}.nstat ip netns exec ${ns3} \
		nstat -n
	NSTAT_HISTORY=/tmp/${ns1}.nstat ip netns exec ${ns1} \
		nstat -n
	mptcp_lib_nstat_init "${ns3}"
	mptcp_lib_nstat_init "${ns1}"

	timeout ${timeout_test} \
	ip netns exec ${ns3} \
		./mptcp_connect -jt ${timeout_poll} -l -p $port -T $max_time \
			0.0.0.0 < "$sin" > "$sout" &
@@ -168,35 +165,43 @@ do_transfer()

	mptcp_lib_wait_local_port_listen "${ns3}" "${port}"

	timeout ${timeout_test} \
	ip netns exec ${ns1} \
		./mptcp_connect -jt ${timeout_poll} -p $port -T $max_time \
			10.0.3.3 < "$cin" > "$cout" &
	local cpid=$!

	mptcp_lib_wait_timeout "${timeout_test}" "${ns3}" "${ns1}" "${port}" \
		"${cpid}" "${spid}" &
	local timeout_pid=$!

	wait $cpid
	local retc=$?
	wait $spid
	local rets=$?

	if kill -0 $timeout_pid; then
		# Finished before the timeout: kill the background job
		mptcp_lib_kill_group_wait $timeout_pid
		timeout_pid=0
	fi

	if $capture; then
		sleep 1
		kill ${cappid_listener}
		kill ${cappid_connector}
	fi

	NSTAT_HISTORY=/tmp/${ns3}.nstat ip netns exec ${ns3} \
		nstat | grep Tcp > /tmp/${ns3}.out
	NSTAT_HISTORY=/tmp/${ns1}.nstat ip netns exec ${ns1} \
		nstat | grep Tcp > /tmp/${ns1}.out
	mptcp_lib_nstat_get "${ns3}"
	mptcp_lib_nstat_get "${ns1}"

	cmp $sin $cout > /dev/null 2>&1
	local cmps=$?
	cmp $cin $sout > /dev/null 2>&1
	local cmpc=$?

	if [ $retc -eq 0 ] && [ $rets -eq 0 ] && \
	   [ $cmpc -eq 0 ] && [ $cmps -eq 0 ]; then
	if [ $retc -eq 0 ] && [ $rets -eq 0 ] &&
	   [ $cmpc -eq 0 ] && [ $cmps -eq 0 ] &&
	   [ $timeout_pid -eq 0 ]; then
		printf "%-16s" " max $max_time "
		mptcp_lib_pr_ok
		cat "$capout"
@@ -204,8 +209,7 @@ do_transfer()
	fi

	mptcp_lib_pr_fail "client exit code $retc, server $rets"
	mptcp_lib_pr_err_stats "${ns3}" "${ns1}" "${port}" \
		"/tmp/${ns3}.out" "/tmp/${ns1}.out"
	mptcp_lib_pr_err_stats "${ns3}" "${ns1}" "${port}"
	ls -l $sin $cout
	ls -l $cin $sout

Loading