diff --git a/include/net/mptcp.h b/include/net/mptcp.h index cde6c6d340323..0cfa9896c9eab 100644 --- a/include/net/mptcp.h +++ b/include/net/mptcp.h @@ -480,6 +480,7 @@ void mptcp_fallback(struct sock *master_sk); void mptcp_clean_rtx_infinite(struct sk_buff *skb, struct sock *sk); void mptcp_fin(struct multipath_pcb *mpcb); void mptcp_retransmit_timer(struct sock *meta_sk); +void mptcp_mark_reinjected(struct sock *sk, struct sk_buff *skb); static inline int mptcp_skb_cloned(const struct sk_buff *skb, const struct tcp_sock *tp) @@ -964,6 +965,7 @@ static inline void mptcp_clean_rtx_queue(struct sock *meta_sk) {} static inline void mptcp_clean_rtx_infinite(struct sk_buff *skb, struct sock *sk) {} static inline void mptcp_retransmit_timer(struct sock *meta_sk) {} +static inline void mptcp_mark_reinjected(struct sock *sk, struct sk_buff *skb) {} static inline void mptcp_set_rto(struct sock *sk) {} static inline void mptcp_reset_xmit_timer(struct sock *meta_sk) {} static inline void mptcp_send_fin(struct sock *meta_sk) {} diff --git a/net/ipv4/mptcp.c b/net/ipv4/mptcp.c index 7ded85c6e035a..6384d13b57218 100644 --- a/net/ipv4/mptcp.c +++ b/net/ipv4/mptcp.c @@ -789,6 +789,26 @@ void mptcp_retransmit_timer(struct sock *meta_sk) meta_icsk->icsk_rto, TCP_RTO_MAX * 2); } +void mptcp_mark_reinjected(struct sock *sk, struct sk_buff *skb) { + struct sock *meta_sk; + struct tcp_sock *tp = tcp_sk(sk); + struct sk_buff *skb_it; + + if (!tp->mpc) + return; + + meta_sk = mptcp_meta_sk(sk); + skb_it = tcp_write_queue_head(meta_sk); + + while (skb_it && skb_it != tcp_send_head(meta_sk)) { + if (TCP_SKB_CB(skb_it)->data_seq == TCP_SKB_CB(skb)->data_seq) { + skb_it->path_mask |= PI_TO_FLAG(tp->path_index); + break; + } + skb_it = tcp_write_queue_next(meta_sk, skb_it); + } +} + int mptcp_alloc_mpcb(struct sock *master_sk, struct request_sock *req, gfp_t flags) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index fca5207f7b419..df7b26ce416f5 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2493,6 +2493,9 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, BUG_ON(tcp_send_head(sk) != skb); tcp_event_new_data_sent(sk, skb); } + if (sk!= subsk && reinject) { + mptcp_mark_reinjected(subsk, skb); + } if (sk != subsk && (TCP_SKB_CB(skb)->flags & TCPHDR_FIN)) { struct sock *sk_it, *sk_tmp;