On Mon, 21 Jun 2021, Jianguo Wu wrote: > Hi Mat, > > On 2021/6/19 8:19, Mat Martineau wrote: >> On Wed, 16 Jun 2021, wujianguo106@163.com wrote: >> >>> From: Jianguo Wu >>> >>> If check_fully_established() causes a subflow reset, it should not >>> continue to process the packet in tcp_data_queue(). >>> >>> setting: >>>     TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq; >>> >>> so that the following check will drop the pkt in >>> tcp_data_queue(): >>>  if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) { >>>     __kfree_skb(skb); >>>     return; >>>  } >>> >>> Fixes: d582484726c4 ("mptcp: fix fallback for MP_JOIN subflows") >>> Signed-off-by: Jianguo Wu >>> --- >>> net/mptcp/options.c | 6 ++++++ >>> 1 file changed, 6 insertions(+) >>> >>> diff --git a/net/mptcp/options.c b/net/mptcp/options.c >>> index 1aec01686c1a..be435c5421cd 100644 >>> --- a/net/mptcp/options.c >>> +++ b/net/mptcp/options.c >>> @@ -926,6 +926,12 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk, >>>     return true; >>> >>> reset: >>> +    /* If a subflow is reset, the packet should not continue to be >>> +     * processed in tcp_data_queue(), so setting: end_seq = seq, >>> +     * then tcp_data_queue() will drop the packet. >>> +     */ >>> +    TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq; >>> + >> >> This does have the desired effect when mptcp_incoming_options() is >> called from tcp_data_queue(), but mptcp_incoming_options() is also >> called from tcp_reset() and tcp_rcv_state_process(). The other callers >> appear to tolerate the sequence number modification. >> >> I think it would be clearer to either add a return value or output >> parameter to mptcp_incoming_options() to explicitly tell the caller >> that a reset has been sent and tcp_done() called. Then it would be >> clearer in tcp_data_queue() that the packet is being discarded due to >> mptcp header content. >> > > If a reset has been sent and tcp_done() called in > check_fully_established(), the sk_state will be TCP_CLOSE, how about > just do (sk_state == TCP_CLOSE) check in tcp_data_queue() as it did in > the V1 of this patch? Oh, I see now that Paolo suggested the the end_seq assignment in order to only modify MPTCP code. I still think it's better to make it clear that we're discarding a packet due to the mptcp headers - using the existing sequence check (intended to detect acks) in tcp_data_queue() seems sneaky to me. Something like if (sk_is_mptcp(sk) && !mptcp_incoming_options(sk, skb)) { __kfree_skb(skb); return; } seems both compact and clear. Does that seem ok Paolo? The optimizer would probably share instructions with the following "end_seq == seq" condition for the kfree+return path anyway. > >> (It also looks like it unexpected behavior may be possible if we get a >> strange TCP_RST + MP_JOIN packet when not fully established, but that's >> unrelated to this patch. Maybe I'll try to create a packetdrill test to >> see what happens) >> >>>     mptcp_subflow_reset(ssk); >>>     return false; >>> } -- Mat Martineau Intel