| .. | .. |
|---|
| 523 | 523 | newtp->max_window = newtp->snd_wnd; |
|---|
| 524 | 524 | |
|---|
| 525 | 525 | if (newtp->rx_opt.tstamp_ok) { |
|---|
| 526 | | - newtp->rx_opt.ts_recent = req->ts_recent; |
|---|
| 526 | + newtp->rx_opt.ts_recent = READ_ONCE(req->ts_recent); |
|---|
| 527 | 527 | newtp->rx_opt.ts_recent_stamp = ktime_get_seconds(); |
|---|
| 528 | 528 | newtp->tcp_header_len = sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED; |
|---|
| 529 | 529 | } else { |
|---|
| .. | .. |
|---|
| 565 | 565 | * validation and inside tcp_v4_reqsk_send_ack(). Can we do better? |
|---|
| 566 | 566 | * |
|---|
| 567 | 567 | * We don't need to initialize tmp_opt.sack_ok as we don't use the results |
|---|
| 568 | + * |
|---|
| 569 | + * Note: If @fastopen is true, this can be called from process context. |
|---|
| 570 | + * Otherwise, this is from BH context. |
|---|
| 568 | 571 | */ |
|---|
| 569 | 572 | |
|---|
| 570 | 573 | struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, |
|---|
| .. | .. |
|---|
| 583 | 586 | tcp_parse_options(sock_net(sk), skb, &tmp_opt, 0, NULL); |
|---|
| 584 | 587 | |
|---|
| 585 | 588 | if (tmp_opt.saw_tstamp) { |
|---|
| 586 | | - tmp_opt.ts_recent = req->ts_recent; |
|---|
| 589 | + tmp_opt.ts_recent = READ_ONCE(req->ts_recent); |
|---|
| 587 | 590 | if (tmp_opt.rcv_tsecr) |
|---|
| 588 | 591 | tmp_opt.rcv_tsecr -= tcp_rsk(req)->ts_off; |
|---|
| 589 | 592 | /* We do not store true stamp, but it is not required, |
|---|
| .. | .. |
|---|
| 717 | 720 | &tcp_rsk(req)->last_oow_ack_time)) |
|---|
| 718 | 721 | req->rsk_ops->send_ack(sk, skb, req); |
|---|
| 719 | 722 | if (paws_reject) |
|---|
| 720 | | - __NET_INC_STATS(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED); |
|---|
| 723 | + NET_INC_STATS(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED); |
|---|
| 721 | 724 | return NULL; |
|---|
| 722 | 725 | } |
|---|
| 723 | 726 | |
|---|
| 724 | 727 | /* In sequence, PAWS is OK. */ |
|---|
| 725 | 728 | |
|---|
| 729 | + /* TODO: We probably should defer ts_recent change once |
|---|
| 730 | + * we take ownership of @req. |
|---|
| 731 | + */ |
|---|
| 726 | 732 | if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_nxt)) |
|---|
| 727 | | - req->ts_recent = tmp_opt.rcv_tsval; |
|---|
| 733 | + WRITE_ONCE(req->ts_recent, tmp_opt.rcv_tsval); |
|---|
| 728 | 734 | |
|---|
| 729 | 735 | if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn) { |
|---|
| 730 | 736 | /* Truncate SYN, it is out of window starting |
|---|
| .. | .. |
|---|
| 736 | 742 | * "fourth, check the SYN bit" |
|---|
| 737 | 743 | */ |
|---|
| 738 | 744 | if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN)) { |
|---|
| 739 | | - __TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS); |
|---|
| 745 | + TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS); |
|---|
| 740 | 746 | goto embryonic_reset; |
|---|
| 741 | 747 | } |
|---|
| 742 | 748 | |
|---|