diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/tcp_input.c | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 580f9547ddfe..f79a51607292 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -3442,6 +3442,22 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx, | |||
3442 | } | 3442 | } |
3443 | } | 3443 | } |
3444 | 3444 | ||
3445 | static int tcp_parse_aligned_timestamp(struct tcp_sock *tp, struct tcphdr *th) | ||
3446 | { | ||
3447 | __be32 *ptr = (__be32 *)(th + 1); | ||
3448 | |||
3449 | if (*ptr == htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | ||
3450 | | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) { | ||
3451 | tp->rx_opt.saw_tstamp = 1; | ||
3452 | ++ptr; | ||
3453 | tp->rx_opt.rcv_tsval = ntohl(*ptr); | ||
3454 | ++ptr; | ||
3455 | tp->rx_opt.rcv_tsecr = ntohl(*ptr); | ||
3456 | return 1; | ||
3457 | } | ||
3458 | return 0; | ||
3459 | } | ||
3460 | |||
3445 | /* Fast parse options. This hopes to only see timestamps. | 3461 | /* Fast parse options. This hopes to only see timestamps. |
3446 | * If it is wrong it falls back on tcp_parse_options(). | 3462 | * If it is wrong it falls back on tcp_parse_options(). |
3447 | */ | 3463 | */ |
@@ -3453,16 +3469,8 @@ static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th, | |||
3453 | return 0; | 3469 | return 0; |
3454 | } else if (tp->rx_opt.tstamp_ok && | 3470 | } else if (tp->rx_opt.tstamp_ok && |
3455 | th->doff == (sizeof(struct tcphdr)>>2)+(TCPOLEN_TSTAMP_ALIGNED>>2)) { | 3471 | th->doff == (sizeof(struct tcphdr)>>2)+(TCPOLEN_TSTAMP_ALIGNED>>2)) { |
3456 | __be32 *ptr = (__be32 *)(th + 1); | 3472 | if (tcp_parse_aligned_timestamp(tp, th)) |
3457 | if (*ptr == htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | ||
3458 | | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) { | ||
3459 | tp->rx_opt.saw_tstamp = 1; | ||
3460 | ++ptr; | ||
3461 | tp->rx_opt.rcv_tsval = ntohl(*ptr); | ||
3462 | ++ptr; | ||
3463 | tp->rx_opt.rcv_tsecr = ntohl(*ptr); | ||
3464 | return 1; | 3473 | return 1; |
3465 | } | ||
3466 | } | 3474 | } |
3467 | tcp_parse_options(skb, &tp->rx_opt, 1); | 3475 | tcp_parse_options(skb, &tp->rx_opt, 1); |
3468 | return 1; | 3476 | return 1; |
@@ -4822,19 +4830,10 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
4822 | 4830 | ||
4823 | /* Check timestamp */ | 4831 | /* Check timestamp */ |
4824 | if (tcp_header_len == sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) { | 4832 | if (tcp_header_len == sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) { |
4825 | __be32 *ptr = (__be32 *)(th + 1); | ||
4826 | |||
4827 | /* No? Slow path! */ | 4833 | /* No? Slow path! */ |
4828 | if (*ptr != htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | 4834 | if (!tcp_parse_aligned_timestamp(tp, th)) |
4829 | | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) | ||
4830 | goto slow_path; | 4835 | goto slow_path; |
4831 | 4836 | ||
4832 | tp->rx_opt.saw_tstamp = 1; | ||
4833 | ++ptr; | ||
4834 | tp->rx_opt.rcv_tsval = ntohl(*ptr); | ||
4835 | ++ptr; | ||
4836 | tp->rx_opt.rcv_tsecr = ntohl(*ptr); | ||
4837 | |||
4838 | /* If PAWS failed, check it more carefully in slow path */ | 4837 | /* If PAWS failed, check it more carefully in slow path */ |
4839 | if ((s32)(tp->rx_opt.rcv_tsval - tp->rx_opt.ts_recent) < 0) | 4838 | if ((s32)(tp->rx_opt.rcv_tsval - tp->rx_opt.ts_recent) < 0) |
4840 | goto slow_path; | 4839 | goto slow_path; |