Skip to content

Commit ea98b61

Browse files
edumazetkuba-moo
authored andcommitted
tcp: add drop_reason support to tcp_disordered_ack()
Following patch is adding a new drop_reason to tcp_validate_incoming(). Change tcp_disordered_ack() to not return a boolean anymore, but a drop reason. Change its name to tcp_disordered_ack_check() Refactor tcp_validate_incoming() to ease the code review of the following patch, and reduce indentation level. This patch is a refactor, with no functional change. Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Neal Cardwell <ncardwell@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com> Reviewed-by: Jason Xing <kerneljasonxing@gmail.com> Link: https://patch.msgid.link/20250113135558.3180360-2-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 652aac7 commit ea98b61

File tree

1 file changed

+44
-35
lines changed

1 file changed

+44
-35
lines changed

net/ipv4/tcp_input.c

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4450,34 +4450,38 @@ static u32 tcp_tsval_replay(const struct sock *sk)
44504450
return inet_csk(sk)->icsk_rto * 1200 / HZ;
44514451
}
44524452

4453-
static int tcp_disordered_ack(const struct sock *sk, const struct sk_buff *skb)
4453+
static enum skb_drop_reason tcp_disordered_ack_check(const struct sock *sk,
4454+
const struct sk_buff *skb)
44544455
{
44554456
const struct tcp_sock *tp = tcp_sk(sk);
44564457
const struct tcphdr *th = tcp_hdr(skb);
4457-
u32 seq = TCP_SKB_CB(skb)->seq;
4458+
SKB_DR_INIT(reason, TCP_RFC7323_PAWS);
44584459
u32 ack = TCP_SKB_CB(skb)->ack_seq;
4460+
u32 seq = TCP_SKB_CB(skb)->seq;
44594461

4460-
return /* 1. Pure ACK with correct sequence number. */
4461-
(th->ack && seq == TCP_SKB_CB(skb)->end_seq && seq == tp->rcv_nxt) &&
4462+
/* 1. Is this not a pure ACK ? */
4463+
if (!th->ack || seq != TCP_SKB_CB(skb)->end_seq)
4464+
return reason;
44624465

4463-
/* 2. ... and duplicate ACK. */
4464-
ack == tp->snd_una &&
4466+
/* 2. Is its sequence not the expected one ? */
4467+
if (seq != tp->rcv_nxt)
4468+
return reason;
44654469

4466-
/* 3. ... and does not update window. */
4467-
!tcp_may_update_window(tp, ack, seq, ntohs(th->window) << tp->rx_opt.snd_wscale) &&
4470+
/* 3. Is this not a duplicate ACK ? */
4471+
if (ack != tp->snd_una)
4472+
return reason;
44684473

4469-
/* 4. ... and sits in replay window. */
4470-
(s32)(tp->rx_opt.ts_recent - tp->rx_opt.rcv_tsval) <=
4471-
tcp_tsval_replay(sk);
4472-
}
4474+
/* 4. Is this updating the window ? */
4475+
if (tcp_may_update_window(tp, ack, seq, ntohs(th->window) <<
4476+
tp->rx_opt.snd_wscale))
4477+
return reason;
44734478

4474-
static inline bool tcp_paws_discard(const struct sock *sk,
4475-
const struct sk_buff *skb)
4476-
{
4477-
const struct tcp_sock *tp = tcp_sk(sk);
4479+
/* 5. Is this not in the replay window ? */
4480+
if ((s32)(tp->rx_opt.ts_recent - tp->rx_opt.rcv_tsval) >
4481+
tcp_tsval_replay(sk))
4482+
return reason;
44784483

4479-
return !tcp_paws_check(&tp->rx_opt, TCP_PAWS_WINDOW) &&
4480-
!tcp_disordered_ack(sk, skb);
4484+
return 0;
44814485
}
44824486

44834487
/* Check segment sequence number for validity.
@@ -5949,23 +5953,28 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb,
59495953
SKB_DR(reason);
59505954

59515955
/* RFC1323: H1. Apply PAWS check first. */
5952-
if (tcp_fast_parse_options(sock_net(sk), skb, th, tp) &&
5953-
tp->rx_opt.saw_tstamp &&
5954-
tcp_paws_discard(sk, skb)) {
5955-
if (!th->rst) {
5956-
if (unlikely(th->syn))
5957-
goto syn_challenge;
5958-
NET_INC_STATS(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED);
5959-
if (!tcp_oow_rate_limited(sock_net(sk), skb,
5960-
LINUX_MIB_TCPACKSKIPPEDPAWS,
5961-
&tp->last_oow_ack_time))
5962-
tcp_send_dupack(sk, skb);
5963-
SKB_DR_SET(reason, TCP_RFC7323_PAWS);
5964-
goto discard;
5965-
}
5966-
/* Reset is accepted even if it did not pass PAWS. */
5967-
}
5968-
5956+
if (!tcp_fast_parse_options(sock_net(sk), skb, th, tp) ||
5957+
!tp->rx_opt.saw_tstamp ||
5958+
tcp_paws_check(&tp->rx_opt, TCP_PAWS_WINDOW))
5959+
goto step1;
5960+
5961+
reason = tcp_disordered_ack_check(sk, skb);
5962+
if (!reason)
5963+
goto step1;
5964+
/* Reset is accepted even if it did not pass PAWS. */
5965+
if (th->rst)
5966+
goto step1;
5967+
if (unlikely(th->syn))
5968+
goto syn_challenge;
5969+
5970+
NET_INC_STATS(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED);
5971+
if (!tcp_oow_rate_limited(sock_net(sk), skb,
5972+
LINUX_MIB_TCPACKSKIPPEDPAWS,
5973+
&tp->last_oow_ack_time))
5974+
tcp_send_dupack(sk, skb);
5975+
goto discard;
5976+
5977+
step1:
59695978
/* Step 1: check sequence number */
59705979
reason = tcp_sequence(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);
59715980
if (reason) {

0 commit comments

Comments
 (0)