Skip to content

Commit

Permalink
selftests/mptcp: add diag interface tests
Browse files Browse the repository at this point in the history
basic functional test, triggering the msk diag interface
code. Require appropriate iproute2 support, skip elsewhere.

Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Paolo Abeni authored and davem330 committed Jul 9, 2020
1 parent ac3b45f commit df62f2e
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 5 deletions.
2 changes: 1 addition & 1 deletion tools/testing/selftests/net/mptcp/Makefile
Expand Up @@ -5,7 +5,7 @@ KSFT_KHDR_INSTALL := 1

CFLAGS = -Wall -Wl,--no-as-needed -O2 -g -I$(top_srcdir)/usr/include

TEST_PROGS := mptcp_connect.sh pm_netlink.sh mptcp_join.sh
TEST_PROGS := mptcp_connect.sh pm_netlink.sh mptcp_join.sh diag.sh

TEST_GEN_FILES = mptcp_connect pm_nl_ctl

Expand Down
121 changes: 121 additions & 0 deletions tools/testing/selftests/net/mptcp/diag.sh
@@ -0,0 +1,121 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0

rndh=$(printf %x $sec)-$(mktemp -u XXXXXX)
ns="ns1-$rndh"
ksft_skip=4
test_cnt=1
ret=0
pids=()

flush_pids()
{
# mptcp_connect in join mode will sleep a bit before completing,
# give it some time
sleep 1.1

for pid in ${pids[@]}; do
[ -d /proc/$pid ] && kill -SIGUSR1 $pid >/dev/null 2>&1
done
pids=()
}

cleanup()
{
ip netns del $ns
for pid in ${pids[@]}; do
[ -d /proc/$pid ] && kill -9 $pid >/dev/null 2>&1
done
}

ip -Version > /dev/null 2>&1
if [ $? -ne 0 ];then
echo "SKIP: Could not run test without ip tool"
exit $ksft_skip
fi
ss -h | grep -q MPTCP
if [ $? -ne 0 ];then
echo "SKIP: ss tool does not support MPTCP"
exit $ksft_skip
fi

__chk_nr()
{
local condition="$1"
local expected=$2
local msg nr

shift 2
msg=$*
nr=$(ss -inmHMN $ns | $condition)

printf "%-50s" "$msg"
if [ $nr != $expected ]; then
echo "[ fail ] expected $expected found $nr"
ret=$test_cnt
else
echo "[ ok ]"
fi
test_cnt=$((test_cnt+1))
}

chk_msk_nr()
{
__chk_nr "grep -c token:" $*
}

chk_msk_fallback_nr()
{
__chk_nr "grep -c fallback" $*
}

chk_msk_remote_key_nr()
{
__chk_nr "grep -c remote_key" $*
}


trap cleanup EXIT
ip netns add $ns
ip -n $ns link set dev lo up

echo "a" | ip netns exec $ns ./mptcp_connect -p 10000 -l 0.0.0.0 -t 100 >/dev/null &
sleep 0.1
pids[0]=$!
chk_msk_nr 0 "no msk on netns creation"

echo "b" | ip netns exec $ns ./mptcp_connect -p 10000 127.0.0.1 -j -t 100 >/dev/null &
sleep 0.1
pids[1]=$!
chk_msk_nr 2 "after MPC handshake "
chk_msk_remote_key_nr 2 "....chk remote_key"
chk_msk_fallback_nr 0 "....chk no fallback"
flush_pids


echo "a" | ip netns exec $ns ./mptcp_connect -p 10001 -s TCP -l 0.0.0.0 -t 100 >/dev/null &
pids[0]=$!
sleep 0.1
echo "b" | ip netns exec $ns ./mptcp_connect -p 10001 127.0.0.1 -j -t 100 >/dev/null &
pids[1]=$!
sleep 0.1
chk_msk_fallback_nr 1 "check fallback"
flush_pids

NR_CLIENTS=100
for I in `seq 1 $NR_CLIENTS`; do
echo "a" | ip netns exec $ns ./mptcp_connect -p $((I+10001)) -l 0.0.0.0 -t 100 -w 10 >/dev/null &
pids[$((I*2))]=$!
done
sleep 0.1

for I in `seq 1 $NR_CLIENTS`; do
echo "b" | ip netns exec $ns ./mptcp_connect -p $((I+10001)) 127.0.0.1 -t 100 -w 10 >/dev/null &
pids[$((I*2 + 1))]=$!
done
sleep 1.5

chk_msk_nr $((NR_CLIENTS*2)) "many msk socket present"
flush_pids

exit $ret
22 changes: 18 additions & 4 deletions tools/testing/selftests/net/mptcp/mptcp_connect.c
Expand Up @@ -11,6 +11,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <signal.h>
#include <unistd.h>

#include <sys/poll.h>
Expand All @@ -36,6 +37,7 @@ extern int optind;

static int poll_timeout = 10 * 1000;
static bool listen_mode;
static bool quit;

enum cfg_mode {
CFG_MODE_POLL,
Expand All @@ -52,11 +54,12 @@ static int pf = AF_INET;
static int cfg_sndbuf;
static int cfg_rcvbuf;
static bool cfg_join;
static int cfg_wait;

static void die_usage(void)
{
fprintf(stderr, "Usage: mptcp_connect [-6] [-u] [-s MPTCP|TCP] [-p port] [-m mode]"
"[-l] connect_address\n");
"[-l] [-w sec] connect_address\n");
fprintf(stderr, "\t-6 use ipv6\n");
fprintf(stderr, "\t-t num -- set poll timeout to num\n");
fprintf(stderr, "\t-S num -- set SO_SNDBUF to num\n");
Expand All @@ -65,9 +68,15 @@ static void die_usage(void)
fprintf(stderr, "\t-m [MPTCP|TCP] -- use tcp or mptcp sockets\n");
fprintf(stderr, "\t-s [mmap|poll] -- use poll (default) or mmap\n");
fprintf(stderr, "\t-u -- check mptcp ulp\n");
fprintf(stderr, "\t-w num -- wait num sec before closing the socket\n");
exit(1);
}

static void handle_signal(int nr)
{
quit = true;
}

static const char *getxinfo_strerr(int err)
{
if (err == EAI_SYSTEM)
Expand Down Expand Up @@ -418,8 +427,8 @@ static int copyfd_io_poll(int infd, int peerfd, int outfd)
}

/* leave some time for late join/announce */
if (cfg_join)
usleep(400000);
if (cfg_wait)
usleep(cfg_wait);

close(peerfd);
return 0;
Expand Down Expand Up @@ -812,11 +821,12 @@ static void parse_opts(int argc, char **argv)
{
int c;

while ((c = getopt(argc, argv, "6jlp:s:hut:m:S:R:")) != -1) {
while ((c = getopt(argc, argv, "6jlp:s:hut:m:S:R:w:")) != -1) {
switch (c) {
case 'j':
cfg_join = true;
cfg_mode = CFG_MODE_POLL;
cfg_wait = 400000;
break;
case 'l':
listen_mode = true;
Expand Down Expand Up @@ -850,6 +860,9 @@ static void parse_opts(int argc, char **argv)
case 'R':
cfg_rcvbuf = parse_int(optarg);
break;
case 'w':
cfg_wait = atoi(optarg)*1000000;
break;
}
}

Expand All @@ -865,6 +878,7 @@ int main(int argc, char *argv[])
{
init_rng();

signal(SIGUSR1, handle_signal);
parse_opts(argc, argv);

if (tcpulp_audit)
Expand Down

0 comments on commit df62f2e

Please sign in to comment.