aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c37
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
3445static 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;