Skip to content

Commit c1e7fd7

Browse files
matttbeintel-lab-lkp
authored andcommitted
selftests: mptcp: join: validate extra bind cases
By design, an MPTCP connection will not accept extra subflows where no MPTCP listening sockets can accept such requests. In other words, it means that if the 'server' listens on a specific address / device, it cannot accept MP_JOIN sent to a different address / device. Except if there is another MPTCP listening socket accepting them. This is what the new tests are validating: - Forcing a bind on the main v4/v6 address, and checking that MP_JOIN to announced addresses are not accepted. - Also forcing a bind on the main v4/v6 address, but before, another listening socket is created to accept additional subflows. Note that 'mptcpize run nc -l' -- or something else only doing: socket(MPTCP), bind(<IP>), listen(0) -- would be enough, but here mptcp_connect is reused not to depend on another tool just for that. - Same as the previous one, but using v6 link-local addresses: this is a bit particular because it is required to specify the outgoing network interface when connecting to a link-local address announced by the other peer. When using the routing rules, this doesn't work (the outgoing interface is not known) ; but it does work with a 'laminar' endpoint having a specified interface. Note that extra small modifications are needed for these tests to work: - mptcp_connect's check_getpeername_connect() check should strip the specified interface when comparing addresses. - With IPv6 link-local addresses, it is required to wait for them to be ready (no longer in 'tentative' mode) before using them, otherwise the bind() will not be allowed. Link: multipath-tcp/mptcp_net-next#591 Signed-off-by: Matthieu Baerts (NGI0) <[email protected]>
1 parent 07105a2 commit c1e7fd7

File tree

2 files changed

+161
-2
lines changed

2 files changed

+161
-2
lines changed

tools/testing/selftests/net/mptcp/mptcp_connect.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,8 @@ static void check_getpeername_connect(int fd)
10641064
socklen_t salen = sizeof(ss);
10651065
char a[INET6_ADDRSTRLEN];
10661066
char b[INET6_ADDRSTRLEN];
1067+
const char *iface;
1068+
size_t len;
10671069

10681070
if (getpeername(fd, (struct sockaddr *)&ss, &salen) < 0) {
10691071
perror("getpeername");
@@ -1073,7 +1075,13 @@ static void check_getpeername_connect(int fd)
10731075
xgetnameinfo((struct sockaddr *)&ss, salen,
10741076
a, sizeof(a), b, sizeof(b));
10751077

1076-
if (strcmp(cfg_host, a) || strcmp(cfg_port, b))
1078+
iface = strchr(cfg_host, '%');
1079+
if (iface)
1080+
len = iface - cfg_host;
1081+
else
1082+
len = strlen(cfg_host) + 1;
1083+
1084+
if (strncmp(cfg_host, a, len) || strcmp(cfg_port, b))
10771085
fprintf(stderr, "%s: %s vs %s, %s vs %s\n", __func__,
10781086
cfg_host, a, cfg_port, b);
10791087
}

tools/testing/selftests/net/mptcp/mptcp_join.sh

Lines changed: 152 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ unset sflags
6262
unset fastclose
6363
unset fullmesh
6464
unset speed
65+
unset bind_addr
6566
unset join_syn_rej
6667
unset join_csum_ns1
6768
unset join_csum_ns2
@@ -645,6 +646,27 @@ wait_mpj()
645646
done
646647
}
647648

649+
wait_ll_ready()
650+
{
651+
local ns="${1}"
652+
653+
local i
654+
for i in $(seq 50); do
655+
ip -n "${ns}" -6 addr show scope link | grep "inet6 fe80" |
656+
grep -qw "tentative" || break
657+
sleep 0.1
658+
done
659+
}
660+
661+
get_ll_addr()
662+
{
663+
local ns="${1}"
664+
local iface="${2}"
665+
666+
ip -n "${ns}" -6 addr show dev "${iface}" scope link |
667+
grep "inet6 fe80" | sed 's#.*\(fe80::.*\)/.*#\1#'
668+
}
669+
648670
kill_events_pids()
649671
{
650672
mptcp_lib_kill_wait $evts_ns1_pid
@@ -952,6 +974,7 @@ do_transfer()
952974
local fastclose=${fastclose:-""}
953975
local speed=${speed:-"fast"}
954976
local in="${sin}"
977+
local bind_addr=${bind_addr:-"::"}
955978
port=$(get_port)
956979

957980
:> "$cout"
@@ -1005,7 +1028,7 @@ do_transfer()
10051028
timeout ${timeout_test} \
10061029
ip netns exec ${listener_ns} \
10071030
./mptcp_connect -t ${timeout_poll} -l -p ${port} -s ${srv_proto} \
1008-
${extra_srv_args} "::" < "${in}" > "${sout}" &
1031+
${extra_srv_args} "${bind_addr}" < "${in}" > "${sout}" &
10091032
local spid=$!
10101033

10111034
mptcp_lib_wait_local_port_listen "${listener_ns}" "${port}"
@@ -3230,6 +3253,133 @@ add_addr_ports_tests()
32303253
fi
32313254
}
32323255

3256+
bind_tests()
3257+
{
3258+
# bind to one address should not allow extra subflows to other addresses
3259+
if reset "bind main address v4, no join v4"; then
3260+
pm_nl_set_limits $ns1 0 2
3261+
pm_nl_set_limits $ns2 2 2
3262+
pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3263+
bind_addr="10.0.1.1" \
3264+
run_tests $ns1 $ns2 10.0.1.1
3265+
join_syn_tx=1 \
3266+
chk_join_nr 0 0 0
3267+
chk_add_nr 1 1
3268+
fi
3269+
3270+
# bind to one address should not allow extra subflows to other addresses
3271+
if reset "bind main address v6, no join v6"; then
3272+
pm_nl_set_limits $ns1 0 2
3273+
pm_nl_set_limits $ns2 2 2
3274+
pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
3275+
bind_addr="dead:beef:1::1" \
3276+
run_tests $ns1 $ns2 dead:beef:1::1
3277+
join_syn_tx=1 \
3278+
chk_join_nr 0 0 0
3279+
chk_add_nr 1 1
3280+
fi
3281+
3282+
# multiple binds to allow extra subflows to other addresses
3283+
if reset "multiple bind to allow joins v4"; then
3284+
local extra_bind
3285+
3286+
pm_nl_set_limits $ns1 0 2
3287+
pm_nl_set_limits $ns2 2 2
3288+
pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3289+
3290+
# Launching another app listening on a different address
3291+
# Note: it could be a totally different app, e.g. nc, socat, ...
3292+
ip netns exec ${ns1} ./mptcp_connect -l -p "$(get_port)" \
3293+
-s MPTCP 10.0.2.1 &
3294+
extra_bind=$!
3295+
3296+
bind_addr="10.0.1.1" \
3297+
run_tests $ns1 $ns2 10.0.1.1
3298+
chk_join_nr 1 1 1
3299+
chk_add_nr 1 1
3300+
3301+
kill ${extra_bind}
3302+
fi
3303+
3304+
# multiple binds to allow extra subflows to other addresses
3305+
if reset "multiple bind to allow joins v6"; then
3306+
local extra_bind
3307+
3308+
pm_nl_set_limits $ns1 0 2
3309+
pm_nl_set_limits $ns2 2 2
3310+
pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
3311+
3312+
# Launching another app listening on a different address
3313+
# Note: it could be a totally different app, e.g. nc, socat, ...
3314+
ip netns exec ${ns1} ./mptcp_connect -l -p "$(get_port)" \
3315+
-s MPTCP dead:beef:2::1 &
3316+
extra_bind=$!
3317+
3318+
bind_addr="dead:beef:1::1" \
3319+
run_tests $ns1 $ns2 dead:beef:1::1
3320+
chk_join_nr 1 1 1
3321+
chk_add_nr 1 1
3322+
3323+
kill ${extra_bind}
3324+
fi
3325+
3326+
# multiple binds to allow extra subflows to other addresses: v6 LL case
3327+
if reset "multiple bind to allow joins v6 link-local routing"; then
3328+
local extra_bind ns1ll1 ns1ll2
3329+
3330+
ns1ll1="$(get_ll_addr $ns1 ns1eth1)"
3331+
ns1ll2="$(get_ll_addr $ns1 ns1eth2)"
3332+
3333+
pm_nl_set_limits $ns1 0 2
3334+
pm_nl_set_limits $ns2 2 2
3335+
pm_nl_add_endpoint $ns1 "${ns1ll2}" flags signal
3336+
3337+
wait_ll_ready $ns1 # to be able to bind
3338+
wait_ll_ready $ns2 # also needed to bind on the client side
3339+
ip netns exec ${ns1} ./mptcp_connect -l -p "$(get_port)" \
3340+
-s MPTCP "${ns1ll2}%ns1eth2" &
3341+
extra_bind=$!
3342+
3343+
bind_addr="${ns1ll1}%ns1eth1" \
3344+
run_tests $ns1 $ns2 "${ns1ll1}%ns2eth1"
3345+
# it is not possible to connect to the announced LL addr without
3346+
# specifying the outgoing interface.
3347+
join_connect_err=1 \
3348+
chk_join_nr 0 0 0
3349+
chk_add_nr 1 1
3350+
3351+
kill ${extra_bind}
3352+
fi
3353+
3354+
# multiple binds to allow extra subflows to v6 LL addresses: laminar
3355+
if reset "multiple bind to allow joins v6 link-local laminar" &&
3356+
continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then
3357+
local extra_bind ns1ll1 ns1ll2 ns2ll2
3358+
3359+
ns1ll1="$(get_ll_addr $ns1 ns1eth1)"
3360+
ns1ll2="$(get_ll_addr $ns1 ns1eth2)"
3361+
ns2ll2="$(get_ll_addr $ns2 ns2eth2)"
3362+
3363+
pm_nl_set_limits $ns1 0 2
3364+
pm_nl_set_limits $ns2 2 2
3365+
pm_nl_add_endpoint $ns1 "${ns1ll2}" flags signal
3366+
pm_nl_add_endpoint $ns2 "${ns2ll2}" flags laminar dev ns2eth2
3367+
3368+
wait_ll_ready $ns1 # to be able to bind
3369+
wait_ll_ready $ns2 # also needed to bind on the client side
3370+
ip netns exec ${ns1} ./mptcp_connect -l -p "$(get_port)" \
3371+
-s MPTCP "${ns1ll2}%ns1eth2" &
3372+
extra_bind=$!
3373+
3374+
bind_addr="${ns1ll1}%ns1eth1" \
3375+
run_tests $ns1 $ns2 "${ns1ll1}%ns2eth1"
3376+
chk_join_nr 1 1 1
3377+
chk_add_nr 1 1
3378+
3379+
kill ${extra_bind}
3380+
fi
3381+
}
3382+
32333383
syncookies_tests()
32343384
{
32353385
# single subflow, syncookies
@@ -4184,6 +4334,7 @@ all_tests_sorted=(
41844334
M@mixed_tests
41854335
b@backup_tests
41864336
p@add_addr_ports_tests
4337+
B@bind_tests
41874338
k@syncookies_tests
41884339
S@checksum_tests
41894340
d@deny_join_id0_tests

0 commit comments

Comments
 (0)