Matthieu Baerts says: ==================== mptcp: misc fixes for v7.3-rc1 Here are various unrelated fixes: - Patch 1: Do not reschedule the RTX timer for sockets that fell back to TCP. A fix for v5.7. - Patch 2: Avoid copying thmac which will not be used and could be uninitialised. A fix for v5.7. - Patch 3: Re-set the request backup flag when SYN cookies are used. A fix for v5.9. - Patch 4: Drop pending ADD_ADDR when removing ID0, and avoid a WARN. A fix for v5.13. - Patch 5: Handle invalid suboptions where the checksum is requested in the MP_CAPABLE 4th ACK with data, but not added in the option. A fix for v5.14. - Patch 6: Prevent a race between mptcp_disconnect() and the retransmit timer. A fix for v5.17. - Patch 7: Fix a use-after-free in the selftests that could lead to false positive. A fix for v5.17. - Patch 8: Limit new addresses with the userspace PM to avoid an address ID overflow. A fix for v5.19. - Patch 9: Reset the ADD_ADDR retransmission counter when the timer is reused. A fix for v5.19. - Patch 10: Remove unneeded and confusing READ_ONCE() annotations. A fix for v6.13. - Patches 11-12: Get nstat counters for the current test, not since the creation of the netns. A fix for v6.19. - Patch 13: Fix an uninit-value in mptcp_write_data_fin for a corner case now that only a part of the tcp_out_options struct is reset. A fix for v7.1. - Patches 14-15: Two follow-up patches addressing minor comments discovered after the human review. A fix for v7.3-rc1. ====================
Unified · Split
| @@ -93,7 +93,8 @@ static void mptcp_parse_option(const struct sk_buff *skb, · 92 unmodified lines | |||
| 93 | * In other words, the only way for checksums not to be used | 93 | * In other words, the only way for checksums not to be used |
| 94 | * is if both hosts in their SYNs set A=0." | 94 | * is if both hosts in their SYNs set A=0." |
| 95 | */ | 95 | */ |
| 96 | if (flags & MPTCP_CAP_CHECKSUM_REQD) | 96 | if ((flags & MPTCP_CAP_CHECKSUM_REQD) && |
| 97 | opsize < TCPOLEN_MPTCP_MPC_ACK_DATA) | ||
| 97 | mp_opt->suboptions |= OPTION_MPTCP_CSUMREQD; | 98 | mp_opt->suboptions |= OPTION_MPTCP_CSUMREQD; |
| 98 | 99 | ||
| 99 | mp_opt->deny_join_id0 = !!(flags & MPTCP_CAP_DENY_JOIN_ID0); | 100 | mp_opt->deny_join_id0 = !!(flags & MPTCP_CAP_DENY_JOIN_ID0); |
| @@ -529,7 +530,7 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb, · 429 unmodified lines | |||
| 529 | return false; | 530 | return false; |
| 530 | 531 | ||
| 531 | /* MPC/MPJ needed only on 3rd ack packet, DATA_FIN and TCP shutdown take precedence */ | 532 | /* MPC/MPJ needed only on 3rd ack packet, DATA_FIN and TCP shutdown take precedence */ |
| 532 | if (READ_ONCE(subflow->fully_established) || snd_data_fin_enable || | 533 | if (subflow->fully_established || snd_data_fin_enable || |
| 533 | subflow->snd_isn != TCP_SKB_CB(skb)->seq || | 534 | subflow->snd_isn != TCP_SKB_CB(skb)->seq || |
| 534 | sk->sk_state != TCP_ESTABLISHED) | 535 | sk->sk_state != TCP_ESTABLISHED) |
| 535 | return false; | 536 | return false; |
| @@ -611,6 +612,7 @@ static void mptcp_write_data_fin(struct mptcp_subflow_context *subflow, · 75 unmodified lines | |||
| 611 | ext->data_seq = data_fin_tx_seq; | 612 | ext->data_seq = data_fin_tx_seq; |
| 612 | ext->subflow_seq = 0; | 613 | ext->subflow_seq = 0; |
| 613 | ext->data_len = 1; | 614 | ext->data_len = 1; |
| 615 | ext->csum = 0; | ||
| 614 | } else if (ext->data_seq + ext->data_len == data_fin_tx_seq) { | 616 | } else if (ext->data_seq + ext->data_len == data_fin_tx_seq) { |
| 615 | /* If there's an existing DSS mapping and it is the | 617 | /* If there's an existing DSS mapping and it is the |
| 616 | * final mapping, DATA_FIN consumes 1 additional byte of | 618 | * final mapping, DATA_FIN consumes 1 additional byte of |
| @@ -980,7 +982,7 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk, · 363 unmodified lines | |||
| 980 | /* here we can process OoO, in-window pkts, only in-sequence 4th ack | 982 | /* here we can process OoO, in-window pkts, only in-sequence 4th ack |
| 981 | * will make the subflow fully established | 983 | * will make the subflow fully established |
| 982 | */ | 984 | */ |
| 983 | if (likely(READ_ONCE(subflow->fully_established))) { | 985 | if (likely(subflow->fully_established)) { |
| 984 | /* on passive sockets, check for 3rd ack retransmission | 986 | /* on passive sockets, check for 3rd ack retransmission |
| 985 | * note that msk is always set by subflow_syn_recv_sock() | 987 | * note that msk is always set by subflow_syn_recv_sock() |
| 986 | * for mp_join subflows | 988 | * for mp_join subflows |
| @@ -462,10 +462,10 @@ bool mptcp_pm_announced_alloc(struct mptcp_sock *msk, · 461 unmodified lines | |||
| 462 | 462 | ||
| 463 | add_entry->addr = *addr; | 463 | add_entry->addr = *addr; |
| 464 | add_entry->sock = msk; | 464 | add_entry->sock = msk; |
| 465 | add_entry->retrans_times = 0; | ||
| 466 | 465 | ||
| 467 | timer_setup(&add_entry->timer, mptcp_pm_add_addr_timer, 0); | 466 | timer_setup(&add_entry->timer, mptcp_pm_add_addr_timer, 0); |
| 468 | reset_timer: | 467 | reset_timer: |
| 468 | add_entry->retrans_times = 0; | ||
| 469 | add_entry->timer_done = false; | 469 | add_entry->timer_done = false; |
| 470 | timeout = mptcp_adjust_add_addr_timeout(msk); | 470 | timeout = mptcp_adjust_add_addr_timeout(msk); |
| 471 | if (timeout) | 471 | if (timeout) |
| @@ -1137,6 +1137,8 @@ static int mptcp_nl_remove_id_zero_address(struct net *net, · 1136 unmodified lines | |||
| 1137 | while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) { | 1137 | while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) { |
| 1138 | struct sock *sk = (struct sock *)msk; | 1138 | struct sock *sk = (struct sock *)msk; |
| 1139 | struct mptcp_addr_info msk_local; | 1139 | struct mptcp_addr_info msk_local; |
| 1140 | struct mptcp_addr_info anno_addr; | ||
| 1141 | bool announced; | ||
| 1140 | 1142 | ||
| 1141 | if (list_empty(&msk->conn_list) || mptcp_pm_is_userspace(msk)) | 1143 | if (list_empty(&msk->conn_list) || mptcp_pm_is_userspace(msk)) |
| 1142 | goto next; | 1144 | goto next; |
| @@ -1146,7 +1148,13 @@ static int mptcp_nl_remove_id_zero_address(struct net *net, · 3 unmodified lines | |||
| 1146 | goto next; | 1148 | goto next; |
| 1147 | 1149 | ||
| 1148 | lock_sock(sk); | 1150 | lock_sock(sk); |
| 1151 | /* Drop a possibly pending ADD_ADDR for this address. */ | ||
| 1152 | anno_addr = msk_local; | ||
| 1153 | anno_addr.port = 0; | ||
| 1154 | announced = mptcp_pm_announced_remove(msk, &anno_addr); | ||
| 1149 | spin_lock_bh(&msk->pm.lock); | 1155 | spin_lock_bh(&msk->pm.lock); |
| 1156 | if (announced) | ||
| 1157 | msk->pm.add_addr_signaled--; | ||
| 1150 | mptcp_pm_remove_addr(msk, &list); | 1158 | mptcp_pm_remove_addr(msk, &list); |
| 1151 | mptcp_pm_rm_subflow(msk, &list); | 1159 | mptcp_pm_rm_subflow(msk, &list); |
| 1152 | __mark_subflow_endp_available(msk, 0); | 1160 | __mark_subflow_endp_available(msk, 0); |
| @@ -69,6 +69,19 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, · 68 unmodified lines | |||
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | if (!addr_match && !id_match) { | 71 | if (!addr_match && !id_match) { |
| 72 | unsigned int id; | ||
| 73 | |||
| 74 | if (!entry->addr.id && needs_id) { | ||
| 75 | id = find_next_zero_bit(id_bitmap, | ||
| 76 | MPTCP_PM_MAX_ADDR_ID + 1, 1); | ||
| 77 | if (id > MPTCP_PM_MAX_ADDR_ID) { | ||
| 78 | ret = -ENOSPC; | ||
| 79 | goto append_err; | ||
| 80 | } | ||
| 81 | } else { | ||
| 82 | id = entry->addr.id; | ||
| 83 | } | ||
| 84 | |||
| 72 | /* Memory for the entry is allocated from the | 85 | /* Memory for the entry is allocated from the |
| 73 | * sock option buffer. | 86 | * sock option buffer. |
| 74 | */ | 87 | */ |
| @@ -78,10 +91,7 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, · 3 unmodified lines | |||
| 78 | goto append_err; | 91 | goto append_err; |
| 79 | } | 92 | } |
| 80 | 93 | ||
| 81 | if (!e->addr.id && needs_id) | 94 | e->addr.id = id; |
| 82 | e->addr.id = find_next_zero_bit(id_bitmap, | ||
| 83 | MPTCP_PM_MAX_ADDR_ID + 1, | ||
| 84 | 1); | ||
| 85 | list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list); | 95 | list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list); |
| 86 | msk->pm.local_addr_used++; | 96 | msk->pm.local_addr_used++; |
| 87 | ret = e->addr.id; | 97 | ret = e->addr.id; |
| @@ -95,6 +95,7 @@ bool __mptcp_try_fallback(struct mptcp_sock *msk, int fb_mib) · 94 unmodified lines | |||
| 95 | 95 | ||
| 96 | msk->allow_subflows = false; | 96 | msk->allow_subflows = false; |
| 97 | set_bit(MPTCP_FALLBACK_DONE, &msk->flags); | 97 | set_bit(MPTCP_FALLBACK_DONE, &msk->flags); |
| 98 | clear_bit(MPTCP_RTX_ENABLED, &msk->flags); | ||
| 98 | __MPTCP_INC_STATS(net, fb_mib); | 99 | __MPTCP_INC_STATS(net, fb_mib); |
| 99 | spin_unlock_bh(&msk->fallback_lock); | 100 | spin_unlock_bh(&msk->fallback_lock); |
| 100 | return true; | 101 | return true; |
| @@ -288,8 +289,8 @@ static void mptcp_prune_ofo_queue(struct sock *sk, · 187 unmodified lines | |||
| 288 | */ | 289 | */ |
| 289 | static bool mptcp_can_ingest(const struct sock *sk) | 290 | static bool mptcp_can_ingest(const struct sock *sk) |
| 290 | { | 291 | { |
| 291 | return unlikely(sk_rmem_alloc_get(sk) <= READ_ONCE(sk->sk_rcvbuf)) || | 292 | return likely(sk_rmem_alloc_get(sk) <= READ_ONCE(sk->sk_rcvbuf)) || |
| 292 | __mptcp_check_fallback(mptcp_sk(sk)); | 293 | __mptcp_check_fallback(mptcp_sk(sk)); |
| 293 | } | 294 | } |
| 294 | 295 | ||
| 295 | static bool mptcp_try_rmem_schedule(struct sock *sk, const struct sk_buff *skb) | 296 | static bool mptcp_try_rmem_schedule(struct sock *sk, const struct sk_buff *skb) |
| @@ -312,12 +313,6 @@ static void mptcp_data_queue_ofo(struct mptcp_sock *msk, struct sk_buff *skb) · 16 unmodified lines | |||
| 312 | u64 seq, end_seq, max_seq; | 313 | u64 seq, end_seq, max_seq; |
| 313 | struct sk_buff *skb1; | 314 | struct sk_buff *skb1; |
| 314 | 315 | ||
| 315 | if (!mptcp_try_rmem_schedule(sk, skb)) { | ||
| 316 | MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RCVPRUNED); | ||
| 317 | mptcp_drop(sk, skb); | ||
| 318 | return; | ||
| 319 | } | ||
| 320 | |||
| 321 | seq = MPTCP_SKB_CB(skb)->map_seq; | 316 | seq = MPTCP_SKB_CB(skb)->map_seq; |
| 322 | end_seq = MPTCP_SKB_CB(skb)->end_seq; | 317 | end_seq = MPTCP_SKB_CB(skb)->end_seq; |
| 323 | max_seq = atomic64_read(&msk->rcv_wnd_sent); | 318 | max_seq = atomic64_read(&msk->rcv_wnd_sent); |
| @@ -334,6 +329,12 @@ static void mptcp_data_queue_ofo(struct mptcp_sock *msk, struct sk_buff *skb) · 10 unmodified lines | |||
| 334 | return; | 329 | return; |
| 335 | } | 330 | } |
| 336 | 331 | ||
| 332 | if (!mptcp_try_rmem_schedule(sk, skb)) { | ||
| 333 | MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RCVPRUNED); | ||
| 334 | mptcp_drop(sk, skb); | ||
| 335 | return; | ||
| 336 | } | ||
| 337 | |||
| 337 | p = &msk->out_of_order_queue.rb_node; | 338 | p = &msk->out_of_order_queue.rb_node; |
| 338 | MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_OFOQUEUE); | 339 | MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_OFOQUEUE); |
| 339 | if (RB_EMPTY_ROOT(&msk->out_of_order_queue)) { | 340 | if (RB_EMPTY_ROOT(&msk->out_of_order_queue)) { |
| @@ -1084,13 +1085,14 @@ static bool mptcp_rtx_timer_pending(struct sock *sk) · 744 unmodified lines | |||
| 1084 | 1085 | ||
| 1085 | static void mptcp_reset_rtx_timer(struct sock *sk) | 1086 | static void mptcp_reset_rtx_timer(struct sock *sk) |
| 1086 | { | 1087 | { |
| 1088 | struct mptcp_sock *msk = mptcp_sk(sk); | ||
| 1087 | unsigned long tout; | 1089 | unsigned long tout; |
| 1088 | 1090 | ||
| 1089 | /* prevent rescheduling on close */ | 1091 | /* Prevent rescheduling on close and in case of fallback. */ |
| 1090 | if (unlikely(inet_sk_state_load(sk) == TCP_CLOSE)) | 1092 | if (!test_bit(MPTCP_RTX_ENABLED, &msk->flags)) |
| 1091 | return; | 1093 | return; |
| 1092 | 1094 | ||
| 1093 | tout = mptcp_sk(sk)->timer_ival; | 1095 | tout = msk->timer_ival; |
| 1094 | sk_reset_timer(sk, &sk->mptcp_retransmit_timer, jiffies + tout); | 1096 | sk_reset_timer(sk, &sk->mptcp_retransmit_timer, jiffies + tout); |
| 1095 | } | 1097 | } |
| 1096 | 1098 | ||
| @@ -3323,6 +3325,9 @@ void mptcp_set_state(struct sock *sk, int state) · 2226 unmodified lines | |||
| 3323 | * transition from TCP_SYN_RECV to TCP_CLOSE_WAIT. | 3325 | * transition from TCP_SYN_RECV to TCP_CLOSE_WAIT. |
| 3324 | */ | 3326 | */ |
| 3325 | break; | 3327 | break; |
| 3328 | case TCP_CLOSE: | ||
| 3329 | clear_bit(MPTCP_RTX_ENABLED, &mptcp_sk(sk)->flags); | ||
| 3330 | fallthrough; | ||
| 3326 | default: | 3331 | default: |
| 3327 | if (oldstate == TCP_ESTABLISHED || oldstate == TCP_CLOSE_WAIT) | 3332 | if (oldstate == TCP_ESTABLISHED || oldstate == TCP_CLOSE_WAIT) |
| 3328 | MPTCP_DEC_STATS(sock_net(sk), MPTCP_MIB_CURRESTAB); | 3333 | MPTCP_DEC_STATS(sock_net(sk), MPTCP_MIB_CURRESTAB); |
| @@ -3583,6 +3588,7 @@ static void mptcp_destroy_common(struct mptcp_sock *msk) · 254 unmodified lines | |||
| 3583 | 3588 | ||
| 3584 | static int mptcp_disconnect(struct sock *sk, int flags) | 3589 | static int mptcp_disconnect(struct sock *sk, int flags) |
| 3585 | { | 3590 | { |
| 3591 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
| 3586 | struct mptcp_sock *msk = mptcp_sk(sk); | 3592 | struct mptcp_sock *msk = mptcp_sk(sk); |
| 3587 | 3593 | ||
| 3588 | /* We are on the fastopen error path. We can't call straight into the | 3594 | /* We are on the fastopen error path. We can't call straight into the |
| @@ -3595,8 +3601,13 @@ static int mptcp_disconnect(struct sock *sk, int flags) · 6 unmodified lines | |||
| 3595 | mptcp_check_listen_stop(sk); | 3601 | mptcp_check_listen_stop(sk); |
| 3596 | mptcp_set_state(sk, TCP_CLOSE); | 3602 | mptcp_set_state(sk, TCP_CLOSE); |
| 3597 | 3603 | ||
| 3598 | mptcp_stop_rtx_timer(sk); | 3604 | /* The later subflow close can not kick again the tout timer, |
| 3599 | mptcp_stop_tout_timer(sk); | 3605 | * as the msk is already in closed status. |
| 3606 | */ | ||
| 3607 | msk->timer_ival = icsk->icsk_rto_min; | ||
| 3608 | sk_stop_timer_sync(sk, &sk->mptcp_retransmit_timer); | ||
| 3609 | icsk->icsk_mtup.probe_timestamp = 0; | ||
| 3610 | sk_stop_timer_sync(sk, &icsk->mptcp_tout_timer); | ||
| 3600 | 3611 | ||
| 3601 | mptcp_pm_connection_closed(msk); | 3612 | mptcp_pm_connection_closed(msk); |
| 3602 | 3613 | ||
| @@ -3875,7 +3886,7 @@ static void schedule_3rdack_retransmission(struct sock *ssk) · 272 unmodified lines | |||
| 3875 | struct tcp_sock *tp = tcp_sk(ssk); | 3886 | struct tcp_sock *tp = tcp_sk(ssk); |
| 3876 | unsigned long timeout; | 3887 | unsigned long timeout; |
| 3877 | 3888 | ||
| 3878 | if (READ_ONCE(mptcp_subflow_ctx(ssk)->fully_established)) | 3889 | if (mptcp_subflow_ctx(ssk)->fully_established) |
| 3879 | return; | 3890 | return; |
| 3880 | 3891 | ||
| 3881 | /* reschedule with a timeout above RTT, as we must look only for drop */ | 3892 | /* reschedule with a timeout above RTT, as we must look only for drop */ |
| @@ -4141,6 +4152,7 @@ static int mptcp_connect(struct sock *sk, struct sockaddr_unsized *uaddr, · 259 unmodified lines | |||
| 4141 | if (IS_ERR(ssk)) | 4152 | if (IS_ERR(ssk)) |
| 4142 | return PTR_ERR(ssk); | 4153 | return PTR_ERR(ssk); |
| 4143 | 4154 | ||
| 4155 | set_bit(MPTCP_RTX_ENABLED, &msk->flags); | ||
| 4144 | mptcp_set_state(sk, TCP_SYN_SENT); | 4156 | mptcp_set_state(sk, TCP_SYN_SENT); |
| 4145 | subflow = mptcp_subflow_ctx(ssk); | 4157 | subflow = mptcp_subflow_ctx(ssk); |
| 4146 | #ifdef CONFIG_TCP_MD5SIG | 4158 | #ifdef CONFIG_TCP_MD5SIG |
| @@ -4288,6 +4300,7 @@ static int mptcp_listen(struct socket *sock, int backlog) · 141 unmodified lines | |||
| 4288 | goto unlock; | 4300 | goto unlock; |
| 4289 | } | 4301 | } |
| 4290 | 4302 | ||
| 4303 | set_bit(MPTCP_RTX_ENABLED, &msk->flags); | ||
| 4291 | mptcp_set_state(sk, TCP_LISTEN); | 4304 | mptcp_set_state(sk, TCP_LISTEN); |
| 4292 | sock_set_flag(sk, SOCK_RCU_FREE); | 4305 | sock_set_flag(sk, SOCK_RCU_FREE); |
| 4293 | 4306 | ||
| @@ -116,6 +116,7 @@ · 115 unmodified lines | |||
| 116 | #define MPTCP_WORK_RTX 1 | 116 | #define MPTCP_WORK_RTX 1 |
| 117 | #define MPTCP_FALLBACK_DONE 2 | 117 | #define MPTCP_FALLBACK_DONE 2 |
| 118 | #define MPTCP_WORK_CLOSE_SUBFLOW 3 | 118 | #define MPTCP_WORK_CLOSE_SUBFLOW 3 |
| 119 | #define MPTCP_RTX_ENABLED 4 | ||
| 119 | 120 | ||
| 120 | /* MPTCP socket release cb flags */ | 121 | /* MPTCP socket release cb flags */ |
| 121 | #define MPTCP_PUSH_PENDING 1 | 122 | #define MPTCP_PUSH_PENDING 1 |
| @@ -2084,7 +2084,6 @@ static void subflow_ulp_clone(const struct request_sock *req, · 2083 unmodified lines | |||
| 2084 | new_ctx->request_bkup = subflow_req->request_bkup; | 2084 | new_ctx->request_bkup = subflow_req->request_bkup; |
| 2085 | WRITE_ONCE(new_ctx->remote_id, subflow_req->remote_id); | 2085 | WRITE_ONCE(new_ctx->remote_id, subflow_req->remote_id); |
| 2086 | new_ctx->token = subflow_req->token; | 2086 | new_ctx->token = subflow_req->token; |
| 2087 | new_ctx->thmac = subflow_req->thmac; | ||
| 2088 | 2087 | ||
| 2089 | /* the subflow req id is valid, fetched via subflow_check_req() | 2088 | /* the subflow req id is valid, fetched via subflow_check_req() |
| 2090 | * and subflow_token_join_request() | 2089 | * and subflow_token_join_request() |
| @@ -26,7 +26,8 @@ struct join_entry { · 25 unmodified lines | |||
| 26 | u32 local_nonce; | 26 | u32 local_nonce; |
| 27 | u8 join_id; | 27 | u8 join_id; |
| 28 | u8 local_id; | 28 | u8 local_id; |
| 29 | u8 backup; | 29 | u8 backup:1, |
| 30 | request_bkup:1; | ||
| 30 | u8 valid; | 31 | u8 valid; |
| 31 | }; | 32 | }; |
| 32 | 33 | ||
| @@ -63,6 +64,7 @@ static void mptcp_join_store_state(struct join_entry *entry, · 30 unmodified lines | |||
| 63 | entry->remote_nonce = subflow_req->remote_nonce; | 64 | entry->remote_nonce = subflow_req->remote_nonce; |
| 64 | entry->local_nonce = subflow_req->local_nonce; | 65 | entry->local_nonce = subflow_req->local_nonce; |
| 65 | entry->backup = subflow_req->backup; | 66 | entry->backup = subflow_req->backup; |
| 67 | entry->request_bkup = subflow_req->request_bkup; | ||
| 66 | entry->join_id = subflow_req->remote_id; | 68 | entry->join_id = subflow_req->remote_id; |
| 67 | entry->local_id = subflow_req->local_id; | 69 | entry->local_id = subflow_req->local_id; |
| 68 | entry->valid = 1; | 70 | entry->valid = 1; |
| @@ -117,6 +119,7 @@ bool mptcp_token_join_cookie_init_state(struct mptcp_subflow_request_sock *subfl · 48 unmodified lines | |||
| 117 | subflow_req->remote_nonce = e->remote_nonce; | 119 | subflow_req->remote_nonce = e->remote_nonce; |
| 118 | subflow_req->local_nonce = e->local_nonce; | 120 | subflow_req->local_nonce = e->local_nonce; |
| 119 | subflow_req->backup = e->backup; | 121 | subflow_req->backup = e->backup; |
| 122 | subflow_req->request_bkup = e->request_bkup; | ||
| 120 | subflow_req->remote_id = e->join_id; | 123 | subflow_req->remote_id = e->join_id; |
| 121 | subflow_req->local_id = e->local_id; | 124 | subflow_req->local_id = e->local_id; |
| 122 | subflow_req->token = e->token; | 125 | subflow_req->token = e->token; |
| @@ -381,6 +381,9 @@ static int sock_connect_mptcp(const char * const remoteaddr, · 380 unmodified lines | |||
| 381 | 381 | ||
| 382 | hints.ai_family = pf; | 382 | hints.ai_family = pf; |
| 383 | 383 | ||
| 384 | /* Keep the resolved address alive for the whole execution: it is | ||
| 385 | * used again when reconnecting, and will be released at exit time. | ||
| 386 | */ | ||
| 384 | xgetaddrinfo(remoteaddr, port, &hints, &addr); | 387 | xgetaddrinfo(remoteaddr, port, &hints, &addr); |
| 385 | for (a = addr; a; a = a->ai_next) { | 388 | for (a = addr; a; a = a->ai_next) { |
| 386 | sock = socket(a->ai_family, a->ai_socktype, proto); | 389 | sock = socket(a->ai_family, a->ai_socktype, proto); |
| @@ -421,7 +424,6 @@ static int sock_connect_mptcp(const char * const remoteaddr, · 34 unmodified lines | |||
| 421 | sock = -1; | 424 | sock = -1; |
| 422 | } | 425 | } |
| 423 | 426 | ||
| 424 | freeaddrinfo(addr); | ||
| 425 | if (sock != -1) | 427 | if (sock != -1) |
| 426 | SOCK_TEST_TCPULP(sock, proto); | 428 | SOCK_TEST_TCPULP(sock, proto); |
| 427 | return sock; | 429 | return sock; |
| @@ -108,12 +108,14 @@ mptcp_lib_pr_info() { · 107 unmodified lines | |||
| 108 | 108 | ||
| 109 | mptcp_lib_pr_nstat() { | 109 | mptcp_lib_pr_nstat() { |
| 110 | local ns="${1}" | 110 | local ns="${1}" |
| 111 | local hist="/tmp/${ns}.out" | 111 | local cache="/tmp/${ns}.out" |
| 112 | local hist="/tmp/${ns}.nstat" | ||
| 112 | 113 | ||
| 113 | if [ -f "${hist}" ]; then | 114 | if [ -f "${cache}" ]; then |
| 114 | awk '$2 != 0 { print " "$0 }' "${hist}" | 115 | awk '$2 != 0 { print " "$0 }' "${cache}" |
| 115 | else | 116 | else |
| 116 | ip netns exec "${ns}" nstat -as | grep Tcp | 117 | NSTAT_HISTORY="${hist}" ip netns exec "${ns}" nstat -s | |
| 118 | grep Tcp | ||
| 117 | fi | 119 | fi |
| 118 | } | 120 | } |
| 119 | 121 | ||
| @@ -414,19 +416,21 @@ mptcp_lib_nstat_get() { · 294 unmodified lines | |||
| 414 | } | 416 | } |
| 415 | 417 | ||
| 416 | # $1: ns, $2: MIB counter | 418 | # $1: ns, $2: MIB counter |
| 417 | # Get the counter from the history (mptcp_lib_nstat_{init,get}()) if available. | 419 | # Get the counter from the cache (mptcp_lib_nstat_{init,get}()) if available. |
| 418 | # If not, get the counter from nstat ignoring any history. | 420 | # If not, get the counter from nstat ignoring any cache, but using the history. |
| 419 | mptcp_lib_get_counter() { | 421 | mptcp_lib_get_counter() { |
| 420 | local ns="${1}" | 422 | local ns="${1}" |
| 421 | local counter="${2}" | 423 | local counter="${2}" |
| 422 | local hist="/tmp/${ns}.out" | 424 | local cache="/tmp/${ns}.out" |
| 425 | local hist="/tmp/${ns}.nstat" | ||
| 423 | local count | 426 | local count |
| 424 | 427 | ||
| 425 | if [[ -s "${hist}" && "${counter}" == *"Tcp"* ]]; then | 428 | if [[ -s "${cache}" && "${counter}" == *"Tcp"* ]]; then |
| 426 | count=$(awk "/^${counter} / {print \$2; exit}" "${hist}") | 429 | count=$(awk "/^${counter} / {print \$2; exit}" "${cache}") |
| 427 | else | 430 | else |
| 428 | count=$(ip netns exec "${ns}" nstat -asz "${counter}" | | 431 | count=$(NSTAT_HISTORY="${hist}" ip netns exec "${ns}" \ |
| 429 | awk 'NR==1 {next} {print $2}') | 432 | nstat -sz "${counter}" | |
| 433 | awk 'NR==1 {next} {print $2}') | ||
| 430 | fi | 434 | fi |
| 431 | if [ -z "${count}" ]; then | 435 | if [ -z "${count}" ]; then |
| 432 | mptcp_lib_fail_if_expected_feature "${counter} counter" | 436 | mptcp_lib_fail_if_expected_feature "${counter} counter" |