mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 17:25:38 +00:00
Merge branch 'mptcp-more-fixes-for-the-in-kernel-pm'
Matthieu Baerts says:
====================
mptcp: more fixes for the in-kernel PM
Here is a new batch of fixes for the MPTCP in-kernel path-manager:
Patch 1 ensures the address ID is set to 0 when the path-manager sends
an ADD_ADDR for the address of the initial subflow. The same fix is
applied when a new subflow is created re-using this special address. A
fix for v6.0.
Patch 2 is similar, but for the case where an endpoint is removed: if
this endpoint was used for the initial address, it is important to send
a RM_ADDR with this ID set to 0, and look for existing subflows with the
ID set to 0. A fix for v6.0 as well.
Patch 3 validates the two previous patches.
Patch 4 makes the PM selecting an "active" path to send an address
notification in an ACK, instead of taking the first path in the list. A
fix for v5.11.
Patch 5 fixes skipping the establishment of a new subflow if a previous
subflow using the same pair of addresses is being closed. A fix for
v5.13.
Patch 6 resets the ID linked to the initial subflow when the linked
endpoint is re-added, possibly with a different ID. A fix for v6.0.
Patch 7 validates the three previous patches.
Patch 8 is a small fix for the MPTCP Join selftest, when being used with
older subflows not supporting all MIB counters. A fix for a commit
introduced in v6.4, but backported up to v5.10.
Patch 9 avoids the PM to try to close the initial subflow multiple
times, and increment counters while nothing happened. A fix for v5.10.
Patch 10 stops incrementing local_addr_used and add_addr_accepted
counters when dealing with the address ID 0, because these counters are
not taking into account the initial subflow, and are then not
decremented when the linked addresses are removed. A fix for v6.0.
Patch 11 validates the previous patch.
Patch 12 avoids the PM to send multiple SUB_CLOSED events for the
initial subflow. A fix for v5.12.
Patch 13 validates the previous patch.
Patch 14 stops treating the ADD_ADDR 0 as a new address, and accepts it
in order to re-create the initial subflow if it has been closed, even if
the limit for *new* addresses -- not taking into account the address of
the initial subflow -- has been reached. A fix for v5.10.
Patch 15 validates the previous patch.
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
Matthieu Baerts (NGI0) (15):
mptcp: pm: reuse ID 0 after delete and re-add
mptcp: pm: fix RM_ADDR ID for the initial subflow
selftests: mptcp: join: check removing ID 0 endpoint
mptcp: pm: send ACK on an active subflow
mptcp: pm: skip connecting to already established sf
mptcp: pm: reset MPC endp ID when re-added
selftests: mptcp: join: check re-adding init endp with != id
selftests: mptcp: join: no extra msg if no counter
mptcp: pm: do not remove already closed subflows
mptcp: pm: fix ID 0 endp usage after multiple re-creations
selftests: mptcp: join: check re-re-adding ID 0 endp
mptcp: avoid duplicated SUB_CLOSED events
selftests: mptcp: join: validate event numbers
mptcp: pm: ADD_ADDR 0 is not a new address
selftests: mptcp: join: check re-re-adding ID 0 signal
net/mptcp/pm.c | 4 +-
net/mptcp/pm_netlink.c | 87 ++++++++++----
net/mptcp/protocol.c | 6 +
net/mptcp/protocol.h | 5 +-
tools/testing/selftests/net/mptcp/mptcp_join.sh | 153 ++++++++++++++++++++----
tools/testing/selftests/net/mptcp/mptcp_lib.sh | 4 +
6 files changed, 209 insertions(+), 50 deletions(-)
---
base-commit: 3a0504d54b
change-id: 20240826-net-mptcp-more-pm-fix-ffa61a36f817
Best regards,
====================
Link: https://patch.msgid.link/20240828-net-mptcp-more-pm-fix-v2-0-7f11b283fff7@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
commit
b666a651d0
@ -226,7 +226,9 @@ void mptcp_pm_add_addr_received(const struct sock *ssk,
|
||||
} else {
|
||||
__MPTCP_INC_STATS(sock_net((struct sock *)msk), MPTCP_MIB_ADDADDRDROP);
|
||||
}
|
||||
} else if (!READ_ONCE(pm->accept_addr)) {
|
||||
/* id0 should not have a different address */
|
||||
} else if ((addr->id == 0 && !mptcp_pm_nl_is_init_remote_addr(msk, addr)) ||
|
||||
(addr->id > 0 && !READ_ONCE(pm->accept_addr))) {
|
||||
mptcp_pm_announce_addr(msk, addr, true);
|
||||
mptcp_pm_add_addr_send_ack(msk);
|
||||
} else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) {
|
||||
|
@ -130,12 +130,15 @@ static bool lookup_subflow_by_daddr(const struct list_head *list,
|
||||
{
|
||||
struct mptcp_subflow_context *subflow;
|
||||
struct mptcp_addr_info cur;
|
||||
struct sock_common *skc;
|
||||
|
||||
list_for_each_entry(subflow, list, node) {
|
||||
skc = (struct sock_common *)mptcp_subflow_tcp_sock(subflow);
|
||||
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
|
||||
|
||||
remote_address(skc, &cur);
|
||||
if (!((1 << inet_sk_state_load(ssk)) &
|
||||
(TCPF_ESTABLISHED | TCPF_SYN_SENT | TCPF_SYN_RECV)))
|
||||
continue;
|
||||
|
||||
remote_address((struct sock_common *)ssk, &cur);
|
||||
if (mptcp_addresses_equal(&cur, daddr, daddr->port))
|
||||
return true;
|
||||
}
|
||||
@ -585,6 +588,11 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
|
||||
|
||||
__clear_bit(local.addr.id, msk->pm.id_avail_bitmap);
|
||||
msk->pm.add_addr_signaled++;
|
||||
|
||||
/* Special case for ID0: set the correct ID */
|
||||
if (local.addr.id == msk->mpc_endpoint_id)
|
||||
local.addr.id = 0;
|
||||
|
||||
mptcp_pm_announce_addr(msk, &local.addr, false);
|
||||
mptcp_pm_nl_addr_send_ack(msk);
|
||||
|
||||
@ -607,8 +615,14 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
|
||||
|
||||
fullmesh = !!(local.flags & MPTCP_PM_ADDR_FLAG_FULLMESH);
|
||||
|
||||
msk->pm.local_addr_used++;
|
||||
__clear_bit(local.addr.id, msk->pm.id_avail_bitmap);
|
||||
|
||||
/* Special case for ID0: set the correct ID */
|
||||
if (local.addr.id == msk->mpc_endpoint_id)
|
||||
local.addr.id = 0;
|
||||
else /* local_addr_used is not decr for ID 0 */
|
||||
msk->pm.local_addr_used++;
|
||||
|
||||
nr = fill_remote_addresses_vec(msk, &local.addr, fullmesh, addrs);
|
||||
if (nr == 0)
|
||||
continue;
|
||||
@ -737,13 +751,24 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
|
||||
if (sf_created) {
|
||||
msk->pm.add_addr_accepted++;
|
||||
/* add_addr_accepted is not decr for ID 0 */
|
||||
if (remote.id)
|
||||
msk->pm.add_addr_accepted++;
|
||||
if (msk->pm.add_addr_accepted >= add_addr_accept_max ||
|
||||
msk->pm.subflows >= subflows_max)
|
||||
WRITE_ONCE(msk->pm.accept_addr, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool mptcp_pm_nl_is_init_remote_addr(struct mptcp_sock *msk,
|
||||
const struct mptcp_addr_info *remote)
|
||||
{
|
||||
struct mptcp_addr_info mpc_remote;
|
||||
|
||||
remote_address((struct sock_common *)msk, &mpc_remote);
|
||||
return mptcp_addresses_equal(&mpc_remote, remote, remote->port);
|
||||
}
|
||||
|
||||
void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
|
||||
{
|
||||
struct mptcp_subflow_context *subflow;
|
||||
@ -755,9 +780,12 @@ void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
|
||||
!mptcp_pm_should_rm_signal(msk))
|
||||
return;
|
||||
|
||||
subflow = list_first_entry_or_null(&msk->conn_list, typeof(*subflow), node);
|
||||
if (subflow)
|
||||
mptcp_pm_send_ack(msk, subflow, false, false);
|
||||
mptcp_for_each_subflow(msk, subflow) {
|
||||
if (__mptcp_subflow_active(subflow)) {
|
||||
mptcp_pm_send_ack(msk, subflow, false, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
|
||||
@ -790,11 +818,6 @@ int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static bool mptcp_local_id_match(const struct mptcp_sock *msk, u8 local_id, u8 id)
|
||||
{
|
||||
return local_id == id || (!local_id && msk->mpc_endpoint_id == id);
|
||||
}
|
||||
|
||||
static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
|
||||
const struct mptcp_rm_list *rm_list,
|
||||
enum linux_mptcp_mib_field rm_type)
|
||||
@ -827,9 +850,11 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
|
||||
int how = RCV_SHUTDOWN | SEND_SHUTDOWN;
|
||||
u8 id = subflow_get_local_id(subflow);
|
||||
|
||||
if (inet_sk_state_load(ssk) == TCP_CLOSE)
|
||||
continue;
|
||||
if (rm_type == MPTCP_MIB_RMADDR && remote_id != rm_id)
|
||||
continue;
|
||||
if (rm_type == MPTCP_MIB_RMSUBFLOW && !mptcp_local_id_match(msk, id, rm_id))
|
||||
if (rm_type == MPTCP_MIB_RMSUBFLOW && id != rm_id)
|
||||
continue;
|
||||
|
||||
pr_debug(" -> %s rm_list_ids[%d]=%u local_id=%u remote_id=%u mpc_id=%u\n",
|
||||
@ -1307,20 +1332,27 @@ static struct pm_nl_pernet *genl_info_pm_nl(struct genl_info *info)
|
||||
return pm_nl_get_pernet(genl_info_net(info));
|
||||
}
|
||||
|
||||
static int mptcp_nl_add_subflow_or_signal_addr(struct net *net)
|
||||
static int mptcp_nl_add_subflow_or_signal_addr(struct net *net,
|
||||
struct mptcp_addr_info *addr)
|
||||
{
|
||||
struct mptcp_sock *msk;
|
||||
long s_slot = 0, s_num = 0;
|
||||
|
||||
while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
|
||||
struct sock *sk = (struct sock *)msk;
|
||||
struct mptcp_addr_info mpc_addr;
|
||||
|
||||
if (!READ_ONCE(msk->fully_established) ||
|
||||
mptcp_pm_is_userspace(msk))
|
||||
goto next;
|
||||
|
||||
/* if the endp linked to the init sf is re-added with a != ID */
|
||||
mptcp_local_address((struct sock_common *)msk, &mpc_addr);
|
||||
|
||||
lock_sock(sk);
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
if (mptcp_addresses_equal(addr, &mpc_addr, addr->port))
|
||||
msk->mpc_endpoint_id = addr->id;
|
||||
mptcp_pm_create_subflow_or_signal_addr(msk);
|
||||
spin_unlock_bh(&msk->pm.lock);
|
||||
release_sock(sk);
|
||||
@ -1393,7 +1425,7 @@ int mptcp_pm_nl_add_addr_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
mptcp_nl_add_subflow_or_signal_addr(sock_net(skb->sk));
|
||||
mptcp_nl_add_subflow_or_signal_addr(sock_net(skb->sk), &entry->addr);
|
||||
return 0;
|
||||
|
||||
out_free:
|
||||
@ -1438,6 +1470,12 @@ static bool remove_anno_list_by_saddr(struct mptcp_sock *msk,
|
||||
return false;
|
||||
}
|
||||
|
||||
static u8 mptcp_endp_get_local_id(struct mptcp_sock *msk,
|
||||
const struct mptcp_addr_info *addr)
|
||||
{
|
||||
return msk->mpc_endpoint_id == addr->id ? 0 : addr->id;
|
||||
}
|
||||
|
||||
static bool mptcp_pm_remove_anno_addr(struct mptcp_sock *msk,
|
||||
const struct mptcp_addr_info *addr,
|
||||
bool force)
|
||||
@ -1445,7 +1483,7 @@ static bool mptcp_pm_remove_anno_addr(struct mptcp_sock *msk,
|
||||
struct mptcp_rm_list list = { .nr = 0 };
|
||||
bool ret;
|
||||
|
||||
list.ids[list.nr++] = addr->id;
|
||||
list.ids[list.nr++] = mptcp_endp_get_local_id(msk, addr);
|
||||
|
||||
ret = remove_anno_list_by_saddr(msk, addr);
|
||||
if (ret || force) {
|
||||
@ -1472,14 +1510,12 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
|
||||
const struct mptcp_pm_addr_entry *entry)
|
||||
{
|
||||
const struct mptcp_addr_info *addr = &entry->addr;
|
||||
struct mptcp_rm_list list = { .nr = 0 };
|
||||
struct mptcp_rm_list list = { .nr = 1 };
|
||||
long s_slot = 0, s_num = 0;
|
||||
struct mptcp_sock *msk;
|
||||
|
||||
pr_debug("remove_id=%d\n", addr->id);
|
||||
|
||||
list.ids[list.nr++] = addr->id;
|
||||
|
||||
while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
|
||||
struct sock *sk = (struct sock *)msk;
|
||||
bool remove_subflow;
|
||||
@ -1497,6 +1533,7 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
|
||||
mptcp_pm_remove_anno_addr(msk, addr, remove_subflow &&
|
||||
!(entry->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT));
|
||||
|
||||
list.ids[0] = mptcp_endp_get_local_id(msk, addr);
|
||||
if (remove_subflow) {
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
mptcp_pm_nl_rm_subflow_received(msk, &list);
|
||||
@ -1509,6 +1546,8 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
|
||||
spin_unlock_bh(&msk->pm.lock);
|
||||
}
|
||||
|
||||
if (msk->mpc_endpoint_id == entry->addr.id)
|
||||
msk->mpc_endpoint_id = 0;
|
||||
release_sock(sk);
|
||||
|
||||
next:
|
||||
@ -1603,6 +1642,7 @@ int mptcp_pm_nl_del_addr_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Called from the userspace PM only */
|
||||
void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list)
|
||||
{
|
||||
struct mptcp_rm_list alist = { .nr = 0 };
|
||||
@ -1631,6 +1671,7 @@ void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list)
|
||||
}
|
||||
}
|
||||
|
||||
/* Called from the in-kernel PM only */
|
||||
static void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
|
||||
struct list_head *rm_list)
|
||||
{
|
||||
@ -1640,11 +1681,11 @@ static void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
|
||||
list_for_each_entry(entry, rm_list, list) {
|
||||
if (slist.nr < MPTCP_RM_IDS_MAX &&
|
||||
lookup_subflow_by_saddr(&msk->conn_list, &entry->addr))
|
||||
slist.ids[slist.nr++] = entry->addr.id;
|
||||
slist.ids[slist.nr++] = mptcp_endp_get_local_id(msk, &entry->addr);
|
||||
|
||||
if (alist.nr < MPTCP_RM_IDS_MAX &&
|
||||
remove_anno_list_by_saddr(msk, &entry->addr))
|
||||
alist.ids[alist.nr++] = entry->addr.id;
|
||||
alist.ids[alist.nr++] = mptcp_endp_get_local_id(msk, &entry->addr);
|
||||
}
|
||||
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
@ -1941,7 +1982,7 @@ static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk,
|
||||
{
|
||||
struct mptcp_rm_list list = { .nr = 0 };
|
||||
|
||||
list.ids[list.nr++] = addr->id;
|
||||
list.ids[list.nr++] = mptcp_endp_get_local_id(msk, addr);
|
||||
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
mptcp_pm_nl_rm_subflow_received(msk, &list);
|
||||
|
@ -2508,6 +2508,12 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
|
||||
void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
|
||||
struct mptcp_subflow_context *subflow)
|
||||
{
|
||||
/* The first subflow can already be closed and still in the list */
|
||||
if (subflow->close_event_done)
|
||||
return;
|
||||
|
||||
subflow->close_event_done = true;
|
||||
|
||||
if (sk->sk_state == TCP_ESTABLISHED)
|
||||
mptcp_event(MPTCP_EVENT_SUB_CLOSED, mptcp_sk(sk), ssk, GFP_KERNEL);
|
||||
|
||||
|
@ -524,7 +524,8 @@ struct mptcp_subflow_context {
|
||||
stale : 1, /* unable to snd/rcv data, do not use for xmit */
|
||||
valid_csum_seen : 1, /* at least one csum validated */
|
||||
is_mptfo : 1, /* subflow is doing TFO */
|
||||
__unused : 10;
|
||||
close_event_done : 1, /* has done the post-closed part */
|
||||
__unused : 9;
|
||||
bool data_avail;
|
||||
bool scheduled;
|
||||
u32 remote_nonce;
|
||||
@ -992,6 +993,8 @@ void mptcp_pm_add_addr_received(const struct sock *ssk,
|
||||
void mptcp_pm_add_addr_echoed(struct mptcp_sock *msk,
|
||||
const struct mptcp_addr_info *addr);
|
||||
void mptcp_pm_add_addr_send_ack(struct mptcp_sock *msk);
|
||||
bool mptcp_pm_nl_is_init_remote_addr(struct mptcp_sock *msk,
|
||||
const struct mptcp_addr_info *remote);
|
||||
void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk);
|
||||
void mptcp_pm_rm_addr_received(struct mptcp_sock *msk,
|
||||
const struct mptcp_rm_list *rm_list);
|
||||
|
@ -420,12 +420,17 @@ reset_with_fail()
|
||||
fi
|
||||
}
|
||||
|
||||
start_events()
|
||||
{
|
||||
mptcp_lib_events "${ns1}" "${evts_ns1}" evts_ns1_pid
|
||||
mptcp_lib_events "${ns2}" "${evts_ns2}" evts_ns2_pid
|
||||
}
|
||||
|
||||
reset_with_events()
|
||||
{
|
||||
reset "${1}" || return 1
|
||||
|
||||
mptcp_lib_events "${ns1}" "${evts_ns1}" evts_ns1_pid
|
||||
mptcp_lib_events "${ns2}" "${evts_ns2}" evts_ns2_pid
|
||||
start_events
|
||||
}
|
||||
|
||||
reset_with_tcp_filter()
|
||||
@ -1112,26 +1117,26 @@ chk_csum_nr()
|
||||
|
||||
print_check "sum"
|
||||
count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtDataCsumErr")
|
||||
if [ "$count" != "$csum_ns1" ]; then
|
||||
if [ -n "$count" ] && [ "$count" != "$csum_ns1" ]; then
|
||||
extra_msg+=" ns1=$count"
|
||||
fi
|
||||
if [ -z "$count" ]; then
|
||||
print_skip
|
||||
elif { [ "$count" != $csum_ns1 ] && [ $allow_multi_errors_ns1 -eq 0 ]; } ||
|
||||
{ [ "$count" -lt $csum_ns1 ] && [ $allow_multi_errors_ns1 -eq 1 ]; }; then
|
||||
{ [ "$count" -lt $csum_ns1 ] && [ $allow_multi_errors_ns1 -eq 1 ]; }; then
|
||||
fail_test "got $count data checksum error[s] expected $csum_ns1"
|
||||
else
|
||||
print_ok
|
||||
fi
|
||||
print_check "csum"
|
||||
count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtDataCsumErr")
|
||||
if [ "$count" != "$csum_ns2" ]; then
|
||||
if [ -n "$count" ] && [ "$count" != "$csum_ns2" ]; then
|
||||
extra_msg+=" ns2=$count"
|
||||
fi
|
||||
if [ -z "$count" ]; then
|
||||
print_skip
|
||||
elif { [ "$count" != $csum_ns2 ] && [ $allow_multi_errors_ns2 -eq 0 ]; } ||
|
||||
{ [ "$count" -lt $csum_ns2 ] && [ $allow_multi_errors_ns2 -eq 1 ]; }; then
|
||||
{ [ "$count" -lt $csum_ns2 ] && [ $allow_multi_errors_ns2 -eq 1 ]; }; then
|
||||
fail_test "got $count data checksum error[s] expected $csum_ns2"
|
||||
else
|
||||
print_ok
|
||||
@ -1169,13 +1174,13 @@ chk_fail_nr()
|
||||
|
||||
print_check "ftx"
|
||||
count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPFailTx")
|
||||
if [ "$count" != "$fail_tx" ]; then
|
||||
if [ -n "$count" ] && [ "$count" != "$fail_tx" ]; then
|
||||
extra_msg+=",tx=$count"
|
||||
fi
|
||||
if [ -z "$count" ]; then
|
||||
print_skip
|
||||
elif { [ "$count" != "$fail_tx" ] && [ $allow_tx_lost -eq 0 ]; } ||
|
||||
{ [ "$count" -gt "$fail_tx" ] && [ $allow_tx_lost -eq 1 ]; }; then
|
||||
{ [ "$count" -gt "$fail_tx" ] && [ $allow_tx_lost -eq 1 ]; }; then
|
||||
fail_test "got $count MP_FAIL[s] TX expected $fail_tx"
|
||||
else
|
||||
print_ok
|
||||
@ -1183,13 +1188,13 @@ chk_fail_nr()
|
||||
|
||||
print_check "failrx"
|
||||
count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtMPFailRx")
|
||||
if [ "$count" != "$fail_rx" ]; then
|
||||
if [ -n "$count" ] && [ "$count" != "$fail_rx" ]; then
|
||||
extra_msg+=",rx=$count"
|
||||
fi
|
||||
if [ -z "$count" ]; then
|
||||
print_skip
|
||||
elif { [ "$count" != "$fail_rx" ] && [ $allow_rx_lost -eq 0 ]; } ||
|
||||
{ [ "$count" -gt "$fail_rx" ] && [ $allow_rx_lost -eq 1 ]; }; then
|
||||
{ [ "$count" -gt "$fail_rx" ] && [ $allow_rx_lost -eq 1 ]; }; then
|
||||
fail_test "got $count MP_FAIL[s] RX expected $fail_rx"
|
||||
else
|
||||
print_ok
|
||||
@ -3333,6 +3338,36 @@ userspace_pm_chk_get_addr()
|
||||
fi
|
||||
}
|
||||
|
||||
# $1: ns ; $2: event type ; $3: count
|
||||
chk_evt_nr()
|
||||
{
|
||||
local ns=${1}
|
||||
local evt_name="${2}"
|
||||
local exp="${3}"
|
||||
|
||||
local evts="${evts_ns1}"
|
||||
local evt="${!evt_name}"
|
||||
local count
|
||||
|
||||
evt_name="${evt_name:16}" # without MPTCP_LIB_EVENT_
|
||||
[ "${ns}" == "ns2" ] && evts="${evts_ns2}"
|
||||
|
||||
print_check "event ${ns} ${evt_name} (${exp})"
|
||||
|
||||
if [[ "${evt_name}" = "LISTENER_"* ]] &&
|
||||
! mptcp_lib_kallsyms_has "mptcp_event_pm_listener$"; then
|
||||
print_skip "event not supported"
|
||||
return
|
||||
fi
|
||||
|
||||
count=$(grep -cw "type:${evt}" "${evts}")
|
||||
if [ "${count}" != "${exp}" ]; then
|
||||
fail_test "got ${count} events, expected ${exp}"
|
||||
else
|
||||
print_ok
|
||||
fi
|
||||
}
|
||||
|
||||
userspace_tests()
|
||||
{
|
||||
# userspace pm type prevents add_addr
|
||||
@ -3572,27 +3607,29 @@ endpoint_tests()
|
||||
|
||||
if reset_with_tcp_filter "delete and re-add" ns2 10.0.3.2 REJECT OUTPUT &&
|
||||
mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
|
||||
pm_nl_set_limits $ns1 0 2
|
||||
pm_nl_set_limits $ns2 0 2
|
||||
start_events
|
||||
pm_nl_set_limits $ns1 0 3
|
||||
pm_nl_set_limits $ns2 0 3
|
||||
pm_nl_add_endpoint $ns2 10.0.1.2 id 1 dev ns2eth1 flags subflow
|
||||
pm_nl_add_endpoint $ns2 10.0.2.2 id 2 dev ns2eth2 flags subflow
|
||||
test_linkfail=4 speed=20 \
|
||||
test_linkfail=4 speed=5 \
|
||||
run_tests $ns1 $ns2 10.0.1.1 &
|
||||
local tests_pid=$!
|
||||
|
||||
wait_mpj $ns2
|
||||
pm_nl_check_endpoint "creation" \
|
||||
$ns2 10.0.2.2 id 2 flags subflow dev ns2eth2
|
||||
chk_subflow_nr "before delete" 2
|
||||
chk_subflow_nr "before delete id 2" 2
|
||||
chk_mptcp_info subflows 1 subflows 1
|
||||
|
||||
pm_nl_del_endpoint $ns2 2 10.0.2.2
|
||||
sleep 0.5
|
||||
chk_subflow_nr "after delete" 1
|
||||
chk_subflow_nr "after delete id 2" 1
|
||||
chk_mptcp_info subflows 0 subflows 0
|
||||
|
||||
pm_nl_add_endpoint $ns2 10.0.2.2 id 2 dev ns2eth2 flags subflow
|
||||
wait_mpj $ns2
|
||||
chk_subflow_nr "after re-add" 2
|
||||
chk_subflow_nr "after re-add id 2" 2
|
||||
chk_mptcp_info subflows 1 subflows 1
|
||||
|
||||
pm_nl_add_endpoint $ns2 10.0.3.2 id 3 flags subflow
|
||||
@ -3607,21 +3644,51 @@ endpoint_tests()
|
||||
chk_subflow_nr "after no reject" 3
|
||||
chk_mptcp_info subflows 2 subflows 2
|
||||
|
||||
local i
|
||||
for i in $(seq 3); do
|
||||
pm_nl_del_endpoint $ns2 1 10.0.1.2
|
||||
sleep 0.5
|
||||
chk_subflow_nr "after delete id 0 ($i)" 2
|
||||
chk_mptcp_info subflows 2 subflows 2 # only decr for additional sf
|
||||
|
||||
pm_nl_add_endpoint $ns2 10.0.1.2 id 1 dev ns2eth1 flags subflow
|
||||
wait_mpj $ns2
|
||||
chk_subflow_nr "after re-add id 0 ($i)" 3
|
||||
chk_mptcp_info subflows 3 subflows 3
|
||||
done
|
||||
|
||||
mptcp_lib_kill_wait $tests_pid
|
||||
|
||||
chk_join_nr 3 3 3
|
||||
chk_rm_nr 1 1
|
||||
kill_events_pids
|
||||
chk_evt_nr ns1 MPTCP_LIB_EVENT_LISTENER_CREATED 1
|
||||
chk_evt_nr ns1 MPTCP_LIB_EVENT_CREATED 1
|
||||
chk_evt_nr ns1 MPTCP_LIB_EVENT_ESTABLISHED 1
|
||||
chk_evt_nr ns1 MPTCP_LIB_EVENT_ANNOUNCED 0
|
||||
chk_evt_nr ns1 MPTCP_LIB_EVENT_REMOVED 4
|
||||
chk_evt_nr ns1 MPTCP_LIB_EVENT_SUB_ESTABLISHED 6
|
||||
chk_evt_nr ns1 MPTCP_LIB_EVENT_SUB_CLOSED 4
|
||||
|
||||
chk_evt_nr ns2 MPTCP_LIB_EVENT_CREATED 1
|
||||
chk_evt_nr ns2 MPTCP_LIB_EVENT_ESTABLISHED 1
|
||||
chk_evt_nr ns2 MPTCP_LIB_EVENT_ANNOUNCED 0
|
||||
chk_evt_nr ns2 MPTCP_LIB_EVENT_REMOVED 0
|
||||
chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_ESTABLISHED 6
|
||||
chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 5 # one has been closed before estab
|
||||
|
||||
chk_join_nr 6 6 6
|
||||
chk_rm_nr 4 4
|
||||
fi
|
||||
|
||||
# remove and re-add
|
||||
if reset "delete re-add signal" &&
|
||||
if reset_with_events "delete re-add signal" &&
|
||||
mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
|
||||
pm_nl_set_limits $ns1 0 2
|
||||
pm_nl_set_limits $ns2 2 2
|
||||
pm_nl_set_limits $ns1 0 3
|
||||
pm_nl_set_limits $ns2 3 3
|
||||
pm_nl_add_endpoint $ns1 10.0.2.1 id 1 flags signal
|
||||
# broadcast IP: no packet for this address will be received on ns1
|
||||
pm_nl_add_endpoint $ns1 224.0.0.1 id 2 flags signal
|
||||
test_linkfail=4 speed=20 \
|
||||
pm_nl_add_endpoint $ns1 10.0.1.1 id 42 flags signal
|
||||
test_linkfail=4 speed=5 \
|
||||
run_tests $ns1 $ns2 10.0.1.1 &
|
||||
local tests_pid=$!
|
||||
|
||||
@ -3642,11 +3709,47 @@ endpoint_tests()
|
||||
wait_mpj $ns2
|
||||
chk_subflow_nr "after re-add" 3
|
||||
chk_mptcp_info subflows 2 subflows 2
|
||||
|
||||
pm_nl_del_endpoint $ns1 42 10.0.1.1
|
||||
sleep 0.5
|
||||
chk_subflow_nr "after delete ID 0" 2
|
||||
chk_mptcp_info subflows 2 subflows 2
|
||||
|
||||
pm_nl_add_endpoint $ns1 10.0.1.1 id 99 flags signal
|
||||
wait_mpj $ns2
|
||||
chk_subflow_nr "after re-add ID 0" 3
|
||||
chk_mptcp_info subflows 3 subflows 3
|
||||
|
||||
pm_nl_del_endpoint $ns1 99 10.0.1.1
|
||||
sleep 0.5
|
||||
chk_subflow_nr "after re-delete ID 0" 2
|
||||
chk_mptcp_info subflows 2 subflows 2
|
||||
|
||||
pm_nl_add_endpoint $ns1 10.0.1.1 id 88 flags signal
|
||||
wait_mpj $ns2
|
||||
chk_subflow_nr "after re-re-add ID 0" 3
|
||||
chk_mptcp_info subflows 3 subflows 3
|
||||
mptcp_lib_kill_wait $tests_pid
|
||||
|
||||
chk_join_nr 3 3 3
|
||||
chk_add_nr 4 4
|
||||
chk_rm_nr 2 1 invert
|
||||
kill_events_pids
|
||||
chk_evt_nr ns1 MPTCP_LIB_EVENT_LISTENER_CREATED 1
|
||||
chk_evt_nr ns1 MPTCP_LIB_EVENT_CREATED 1
|
||||
chk_evt_nr ns1 MPTCP_LIB_EVENT_ESTABLISHED 1
|
||||
chk_evt_nr ns1 MPTCP_LIB_EVENT_ANNOUNCED 0
|
||||
chk_evt_nr ns1 MPTCP_LIB_EVENT_REMOVED 0
|
||||
chk_evt_nr ns1 MPTCP_LIB_EVENT_SUB_ESTABLISHED 5
|
||||
chk_evt_nr ns1 MPTCP_LIB_EVENT_SUB_CLOSED 3
|
||||
|
||||
chk_evt_nr ns2 MPTCP_LIB_EVENT_CREATED 1
|
||||
chk_evt_nr ns2 MPTCP_LIB_EVENT_ESTABLISHED 1
|
||||
chk_evt_nr ns2 MPTCP_LIB_EVENT_ANNOUNCED 6
|
||||
chk_evt_nr ns2 MPTCP_LIB_EVENT_REMOVED 4
|
||||
chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_ESTABLISHED 5
|
||||
chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 3
|
||||
|
||||
chk_join_nr 5 5 5
|
||||
chk_add_nr 6 6
|
||||
chk_rm_nr 4 3 invert
|
||||
fi
|
||||
|
||||
# flush and re-add
|
||||
|
@ -12,10 +12,14 @@ readonly KSFT_SKIP=4
|
||||
readonly KSFT_TEST="${MPTCP_LIB_KSFT_TEST:-$(basename "${0}" .sh)}"
|
||||
|
||||
# These variables are used in some selftests, read-only
|
||||
declare -rx MPTCP_LIB_EVENT_CREATED=1 # MPTCP_EVENT_CREATED
|
||||
declare -rx MPTCP_LIB_EVENT_ESTABLISHED=2 # MPTCP_EVENT_ESTABLISHED
|
||||
declare -rx MPTCP_LIB_EVENT_CLOSED=3 # MPTCP_EVENT_CLOSED
|
||||
declare -rx MPTCP_LIB_EVENT_ANNOUNCED=6 # MPTCP_EVENT_ANNOUNCED
|
||||
declare -rx MPTCP_LIB_EVENT_REMOVED=7 # MPTCP_EVENT_REMOVED
|
||||
declare -rx MPTCP_LIB_EVENT_SUB_ESTABLISHED=10 # MPTCP_EVENT_SUB_ESTABLISHED
|
||||
declare -rx MPTCP_LIB_EVENT_SUB_CLOSED=11 # MPTCP_EVENT_SUB_CLOSED
|
||||
declare -rx MPTCP_LIB_EVENT_SUB_PRIORITY=13 # MPTCP_EVENT_SUB_PRIORITY
|
||||
declare -rx MPTCP_LIB_EVENT_LISTENER_CREATED=15 # MPTCP_EVENT_LISTENER_CREATED
|
||||
declare -rx MPTCP_LIB_EVENT_LISTENER_CLOSED=16 # MPTCP_EVENT_LISTENER_CLOSED
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user