Merge branch 'mptcp-misc-fixes-for-v7-1-rc4'
Matthieu Baerts says: ==================== mptcp: misc fixes for v7.1-rc4 Here are various unrelated fixes: - Patch 1: avoid dropping partial packets. A previous version has been sent a few week ago. A fix for 5.10. - Patches 2-3: stop ADD_ADDR timer when an ADD_ADDR can never been sent due to insufficient option space. A fix for v5.10. - Patch 4: reset rcv_wnd_sent on disconnect, just in case the next connection falls back to TCP. A fix for 5.17. - Patch 5: update window_clamp when SO_RCVBUF is set during the connection. A fix similar to a recent one on TCP side, for v6.6. - Patch 6: avoid wrong time being displayed in the selftests when using uutils 0.8.0 which contains a regression with 'date +%3N'. It doesn't fix an issue in the kernel selftests, but having the fix is helpful for those using uutils 0.8.0. Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> ==================== Link: https://patch.msgid.link/20260515-net-mptcp-misc-fixes-7-1-rc4-v2-0-701e96419f2f@kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>master
commit
edc502717b
|
|
@ -364,7 +364,13 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
|
|||
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
|
||||
if (!mptcp_pm_should_add_signal_addr(msk)) {
|
||||
/* The cancel path (mptcp_pm_del_add_timer()) can race with this
|
||||
* callback. Once cancel updates retrans_times to MAX, suppress further
|
||||
* retransmissions here. If this callback acquires pm.lock first, one
|
||||
* final transmit attempt is still possible.
|
||||
*/
|
||||
if (entry->retrans_times < ADD_ADDR_RETRANS_MAX &&
|
||||
!mptcp_pm_should_add_signal_addr(msk)) {
|
||||
pr_debug("retransmit ADD_ADDR id=%d\n", entry->addr.id);
|
||||
mptcp_pm_announce_addr(msk, &entry->addr, false);
|
||||
mptcp_pm_add_addr_send_ack(msk);
|
||||
|
|
@ -414,8 +420,12 @@ mptcp_pm_del_add_timer(struct mptcp_sock *msk,
|
|||
/* Note: entry might have been removed by another thread.
|
||||
* We hold rcu_read_lock() to ensure it is not freed under us.
|
||||
*/
|
||||
if (stop_timer)
|
||||
sk_stop_timer_sync(sk, &entry->add_timer);
|
||||
if (stop_timer) {
|
||||
if (check_id)
|
||||
sk_stop_timer(sk, &entry->add_timer);
|
||||
else
|
||||
sk_stop_timer_sync(sk, &entry->add_timer);
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
return entry;
|
||||
|
|
@ -882,6 +892,7 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb,
|
|||
struct mptcp_addr_info *addr, bool *echo,
|
||||
bool *drop_other_suboptions)
|
||||
{
|
||||
bool skip_add_addr = false;
|
||||
int ret = false;
|
||||
u8 add_addr;
|
||||
u8 family;
|
||||
|
|
@ -903,24 +914,49 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb,
|
|||
}
|
||||
|
||||
*echo = mptcp_pm_should_add_signal_echo(msk);
|
||||
port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port);
|
||||
|
||||
family = *echo ? msk->pm.remote.family : msk->pm.local.family;
|
||||
if (remaining < mptcp_add_addr_len(family, *echo, port))
|
||||
goto out_unlock;
|
||||
|
||||
if (*echo) {
|
||||
*addr = msk->pm.remote;
|
||||
add_addr = msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_ECHO);
|
||||
port = !!msk->pm.remote.port;
|
||||
family = msk->pm.remote.family;
|
||||
} else {
|
||||
*addr = msk->pm.local;
|
||||
add_addr = msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_SIGNAL);
|
||||
port = !!msk->pm.local.port;
|
||||
family = msk->pm.local.family;
|
||||
}
|
||||
WRITE_ONCE(msk->pm.addr_signal, add_addr);
|
||||
|
||||
if (remaining < mptcp_add_addr_len(family, *echo, port)) {
|
||||
struct net *net = sock_net((struct sock *)msk);
|
||||
|
||||
if (!*drop_other_suboptions)
|
||||
goto out_unlock;
|
||||
|
||||
if (*echo) {
|
||||
MPTCP_INC_STATS(net, MPTCP_MIB_ECHOADDTXDROP);
|
||||
} else {
|
||||
skip_add_addr = true;
|
||||
MPTCP_INC_STATS(net, MPTCP_MIB_ADDADDRTXDROP);
|
||||
}
|
||||
goto drop_signal_mark;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
|
||||
drop_signal_mark:
|
||||
WRITE_ONCE(msk->pm.addr_signal, add_addr);
|
||||
|
||||
out_unlock:
|
||||
spin_unlock_bh(&msk->pm.lock);
|
||||
|
||||
/* On pure-ACK option-space exhaustion, stop retrying this ADD_ADDR:
|
||||
* clear the signal bit, cancel the matching retransmission timer, and
|
||||
* let the PM state machine progress.
|
||||
*/
|
||||
if (skip_add_addr) {
|
||||
mptcp_pm_del_add_timer(msk, addr, true);
|
||||
mptcp_pm_subflow_established(msk);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -397,12 +397,26 @@ static bool __mptcp_move_skb(struct sock *sk, struct sk_buff *skb)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* old data, keep it simple and drop the whole pkt, sender
|
||||
* will retransmit as needed, if needed.
|
||||
/* Completely old data? */
|
||||
if (!after64(MPTCP_SKB_CB(skb)->end_seq, msk->ack_seq)) {
|
||||
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DUPDATA);
|
||||
mptcp_drop(sk, skb);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Partial packet: map_seq < ack_seq < end_seq.
|
||||
* Skip the already-acked bytes and enqueue the new data.
|
||||
*/
|
||||
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DUPDATA);
|
||||
mptcp_drop(sk, skb);
|
||||
return false;
|
||||
copy_len = MPTCP_SKB_CB(skb)->end_seq - msk->ack_seq;
|
||||
MPTCP_SKB_CB(skb)->offset += msk->ack_seq - MPTCP_SKB_CB(skb)->map_seq;
|
||||
MPTCP_SKB_CB(skb)->map_seq += msk->ack_seq -
|
||||
MPTCP_SKB_CB(skb)->map_seq;
|
||||
msk->bytes_received += copy_len;
|
||||
WRITE_ONCE(msk->ack_seq, msk->ack_seq + copy_len);
|
||||
|
||||
skb_set_owner_r(skb, sk);
|
||||
__skb_queue_tail(&sk->sk_receive_queue, skb);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void mptcp_stop_rtx_timer(struct sock *sk)
|
||||
|
|
@ -3473,6 +3487,7 @@ static int mptcp_disconnect(struct sock *sk, int flags)
|
|||
|
||||
/* for fallback's sake */
|
||||
WRITE_ONCE(msk->ack_seq, 0);
|
||||
atomic64_set(&msk->rcv_wnd_sent, 0);
|
||||
|
||||
WRITE_ONCE(sk->sk_shutdown, 0);
|
||||
sk_error_report(sk);
|
||||
|
|
|
|||
|
|
@ -67,6 +67,12 @@ static int mptcp_get_int_option(struct mptcp_sock *msk, sockptr_t optval,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void __mptcp_subflow_set_rcvbuf(struct sock *ssk, int val)
|
||||
{
|
||||
WRITE_ONCE(ssk->sk_rcvbuf, val);
|
||||
tcp_set_rcvbuf(ssk, val);
|
||||
}
|
||||
|
||||
static void mptcp_sol_socket_sync_intval(struct mptcp_sock *msk, int optname, int val)
|
||||
{
|
||||
struct mptcp_subflow_context *subflow;
|
||||
|
|
@ -100,7 +106,7 @@ static void mptcp_sol_socket_sync_intval(struct mptcp_sock *msk, int optname, in
|
|||
case SO_RCVBUF:
|
||||
case SO_RCVBUFFORCE:
|
||||
ssk->sk_userlocks |= SOCK_RCVBUF_LOCK;
|
||||
WRITE_ONCE(ssk->sk_rcvbuf, sk->sk_rcvbuf);
|
||||
__mptcp_subflow_set_rcvbuf(ssk, sk->sk_rcvbuf);
|
||||
break;
|
||||
case SO_MARK:
|
||||
if (READ_ONCE(ssk->sk_mark) != sk->sk_mark) {
|
||||
|
|
@ -1560,7 +1566,7 @@ static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk)
|
|||
mptcp_subflow_ctx(ssk)->cached_sndbuf = sk->sk_sndbuf;
|
||||
}
|
||||
if (sk->sk_userlocks & SOCK_RCVBUF_LOCK)
|
||||
WRITE_ONCE(ssk->sk_rcvbuf, sk->sk_rcvbuf);
|
||||
__mptcp_subflow_set_rcvbuf(ssk, sk->sk_rcvbuf);
|
||||
}
|
||||
|
||||
if (sock_flag(sk, SOCK_LINGER)) {
|
||||
|
|
|
|||
|
|
@ -401,7 +401,7 @@ do_transfer()
|
|||
mptcp_lib_wait_local_port_listen "${listener_ns}" "${port}"
|
||||
|
||||
local start
|
||||
start=$(date +%s%3N)
|
||||
start=$(date +%s%N)
|
||||
ip netns exec ${connector_ns} \
|
||||
./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
|
||||
$extra_args $connect_addr < "$cin" > "$cout" &
|
||||
|
|
@ -423,7 +423,7 @@ do_transfer()
|
|||
fi
|
||||
|
||||
local stop
|
||||
stop=$(date +%s%3N)
|
||||
stop=$(date +%s%N)
|
||||
|
||||
if $capture; then
|
||||
sleep 1
|
||||
|
|
@ -439,7 +439,7 @@ do_transfer()
|
|||
fi
|
||||
|
||||
local duration
|
||||
duration=$((stop-start))
|
||||
duration=$(((stop-start) / 1000000))
|
||||
printf "(duration %05sms) " "${duration}"
|
||||
if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ] || [ ${timeout_pid} -ne 0 ]; then
|
||||
mptcp_lib_pr_fail "client exit code $retc, server $rets"
|
||||
|
|
|
|||
|
|
@ -1828,6 +1828,22 @@ chk_add_tx_nr()
|
|||
fi
|
||||
}
|
||||
|
||||
chk_add_drop_tx_nr()
|
||||
{
|
||||
local drop_tx_nr=$1
|
||||
local count
|
||||
|
||||
print_check "add addr tx drop"
|
||||
count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtAddAddrTxDrop")
|
||||
if [ -z "$count" ]; then
|
||||
print_skip
|
||||
elif [ "$count" != "$drop_tx_nr" ]; then
|
||||
fail_test "got $count ADD_ADDR drop[s] TX, expected $drop_tx_nr"
|
||||
else
|
||||
print_ok
|
||||
fi
|
||||
}
|
||||
|
||||
chk_rm_nr()
|
||||
{
|
||||
local rm_addr_nr=$1
|
||||
|
|
@ -3278,6 +3294,21 @@ add_addr_ports_tests()
|
|||
|
||||
chk_mpc_endp_attempt ${retl} 1
|
||||
fi
|
||||
|
||||
# first signal address drops, second one still progresses
|
||||
if reset "signal addr list progresses after tx drop"; then
|
||||
pm_nl_set_limits $ns1 0 2
|
||||
pm_nl_set_limits $ns2 1 0
|
||||
ip netns exec $ns1 sysctl -q net.ipv4.tcp_timestamps=1
|
||||
ip netns exec $ns2 sysctl -q net.ipv4.tcp_timestamps=1
|
||||
|
||||
pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal port 10100
|
||||
pm_nl_add_endpoint $ns1 dead:beef:3::1 flags signal
|
||||
run_tests $ns1 $ns2 dead:beef:1::1
|
||||
chk_add_drop_tx_nr 1
|
||||
chk_add_tx_nr 1 1
|
||||
chk_add_nr 1 1 0
|
||||
fi
|
||||
}
|
||||
|
||||
bind_tests()
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ declare -rx MPTCP_LIB_AF_INET6=10
|
|||
MPTCP_LIB_SUBTESTS=()
|
||||
MPTCP_LIB_SUBTESTS_DUPLICATED=0
|
||||
MPTCP_LIB_SUBTEST_FLAKY=0
|
||||
MPTCP_LIB_SUBTESTS_LAST_TS_MS=
|
||||
MPTCP_LIB_SUBTESTS_LAST_TS_NS=
|
||||
MPTCP_LIB_TEST_COUNTER=0
|
||||
MPTCP_LIB_TEST_FORMAT="%02u %-50s"
|
||||
MPTCP_LIB_IP_MPTCP=0
|
||||
|
|
@ -236,7 +236,7 @@ mptcp_lib_kversion_ge() {
|
|||
}
|
||||
|
||||
mptcp_lib_subtests_last_ts_reset() {
|
||||
MPTCP_LIB_SUBTESTS_LAST_TS_MS="$(date +%s%3N)"
|
||||
MPTCP_LIB_SUBTESTS_LAST_TS_NS="$(date +%s%N)"
|
||||
}
|
||||
mptcp_lib_subtests_last_ts_reset
|
||||
|
||||
|
|
@ -255,7 +255,7 @@ __mptcp_lib_result_check_duplicated() {
|
|||
__mptcp_lib_result_add() {
|
||||
local result="${1}"
|
||||
local time="time="
|
||||
local ts_prev_ms
|
||||
local ts_prev_ns
|
||||
shift
|
||||
|
||||
local id=$((${#MPTCP_LIB_SUBTESTS[@]} + 1))
|
||||
|
|
@ -265,9 +265,9 @@ __mptcp_lib_result_add() {
|
|||
# not to add two '#'
|
||||
[[ "${*}" != *"#"* ]] && time="# ${time}"
|
||||
|
||||
ts_prev_ms="${MPTCP_LIB_SUBTESTS_LAST_TS_MS}"
|
||||
ts_prev_ns="${MPTCP_LIB_SUBTESTS_LAST_TS_NS}"
|
||||
mptcp_lib_subtests_last_ts_reset
|
||||
time+="$((MPTCP_LIB_SUBTESTS_LAST_TS_MS - ts_prev_ms))ms"
|
||||
time+="$(((MPTCP_LIB_SUBTESTS_LAST_TS_NS - ts_prev_ns) / 1000000))ms"
|
||||
|
||||
MPTCP_LIB_SUBTESTS+=("${result} ${id} - ${KSFT_TEST}: ${*} ${time}")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue