diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 69 |
1 files changed, 7 insertions, 62 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 836d74dd0187..19f0149fb6a2 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -3760,8 +3760,8 @@ old_ack: | |||
3760 | * But, this can also be called on packets in the established flow when | 3760 | * But, this can also be called on packets in the established flow when |
3761 | * the fast version below fails. | 3761 | * the fast version below fails. |
3762 | */ | 3762 | */ |
3763 | void tcp_parse_options(const struct sk_buff *skb, struct tcp_options_received *opt_rx, | 3763 | void tcp_parse_options(const struct sk_buff *skb, |
3764 | const u8 **hvpp, int estab, | 3764 | struct tcp_options_received *opt_rx, int estab, |
3765 | struct tcp_fastopen_cookie *foc) | 3765 | struct tcp_fastopen_cookie *foc) |
3766 | { | 3766 | { |
3767 | const unsigned char *ptr; | 3767 | const unsigned char *ptr; |
@@ -3845,31 +3845,6 @@ void tcp_parse_options(const struct sk_buff *skb, struct tcp_options_received *o | |||
3845 | */ | 3845 | */ |
3846 | break; | 3846 | break; |
3847 | #endif | 3847 | #endif |
3848 | case TCPOPT_COOKIE: | ||
3849 | /* This option is variable length. | ||
3850 | */ | ||
3851 | switch (opsize) { | ||
3852 | case TCPOLEN_COOKIE_BASE: | ||
3853 | /* not yet implemented */ | ||
3854 | break; | ||
3855 | case TCPOLEN_COOKIE_PAIR: | ||
3856 | /* not yet implemented */ | ||
3857 | break; | ||
3858 | case TCPOLEN_COOKIE_MIN+0: | ||
3859 | case TCPOLEN_COOKIE_MIN+2: | ||
3860 | case TCPOLEN_COOKIE_MIN+4: | ||
3861 | case TCPOLEN_COOKIE_MIN+6: | ||
3862 | case TCPOLEN_COOKIE_MAX: | ||
3863 | /* 16-bit multiple */ | ||
3864 | opt_rx->cookie_plus = opsize; | ||
3865 | *hvpp = ptr; | ||
3866 | break; | ||
3867 | default: | ||
3868 | /* ignore option */ | ||
3869 | break; | ||
3870 | } | ||
3871 | break; | ||
3872 | |||
3873 | case TCPOPT_EXP: | 3848 | case TCPOPT_EXP: |
3874 | /* Fast Open option shares code 254 using a | 3849 | /* Fast Open option shares code 254 using a |
3875 | * 16 bits magic number. It's valid only in | 3850 | * 16 bits magic number. It's valid only in |
@@ -3915,8 +3890,7 @@ static bool tcp_parse_aligned_timestamp(struct tcp_sock *tp, const struct tcphdr | |||
3915 | * If it is wrong it falls back on tcp_parse_options(). | 3890 | * If it is wrong it falls back on tcp_parse_options(). |
3916 | */ | 3891 | */ |
3917 | static bool tcp_fast_parse_options(const struct sk_buff *skb, | 3892 | static bool tcp_fast_parse_options(const struct sk_buff *skb, |
3918 | const struct tcphdr *th, | 3893 | const struct tcphdr *th, struct tcp_sock *tp) |
3919 | struct tcp_sock *tp, const u8 **hvpp) | ||
3920 | { | 3894 | { |
3921 | /* In the spirit of fast parsing, compare doff directly to constant | 3895 | /* In the spirit of fast parsing, compare doff directly to constant |
3922 | * values. Because equality is used, short doff can be ignored here. | 3896 | * values. Because equality is used, short doff can be ignored here. |
@@ -3930,7 +3904,7 @@ static bool tcp_fast_parse_options(const struct sk_buff *skb, | |||
3930 | return true; | 3904 | return true; |
3931 | } | 3905 | } |
3932 | 3906 | ||
3933 | tcp_parse_options(skb, &tp->rx_opt, hvpp, 1, NULL); | 3907 | tcp_parse_options(skb, &tp->rx_opt, 1, NULL); |
3934 | if (tp->rx_opt.saw_tstamp) | 3908 | if (tp->rx_opt.saw_tstamp) |
3935 | tp->rx_opt.rcv_tsecr -= tp->tsoffset; | 3909 | tp->rx_opt.rcv_tsecr -= tp->tsoffset; |
3936 | 3910 | ||
@@ -5311,12 +5285,10 @@ out: | |||
5311 | static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, | 5285 | static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, |
5312 | const struct tcphdr *th, int syn_inerr) | 5286 | const struct tcphdr *th, int syn_inerr) |
5313 | { | 5287 | { |
5314 | const u8 *hash_location; | ||
5315 | struct tcp_sock *tp = tcp_sk(sk); | 5288 | struct tcp_sock *tp = tcp_sk(sk); |
5316 | 5289 | ||
5317 | /* RFC1323: H1. Apply PAWS check first. */ | 5290 | /* RFC1323: H1. Apply PAWS check first. */ |
5318 | if (tcp_fast_parse_options(skb, th, tp, &hash_location) && | 5291 | if (tcp_fast_parse_options(skb, th, tp) && tp->rx_opt.saw_tstamp && |
5319 | tp->rx_opt.saw_tstamp && | ||
5320 | tcp_paws_discard(sk, skb)) { | 5292 | tcp_paws_discard(sk, skb)) { |
5321 | if (!th->rst) { | 5293 | if (!th->rst) { |
5322 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED); | 5294 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED); |
@@ -5670,12 +5642,11 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, | |||
5670 | 5642 | ||
5671 | if (mss == tp->rx_opt.user_mss) { | 5643 | if (mss == tp->rx_opt.user_mss) { |
5672 | struct tcp_options_received opt; | 5644 | struct tcp_options_received opt; |
5673 | const u8 *hash_location; | ||
5674 | 5645 | ||
5675 | /* Get original SYNACK MSS value if user MSS sets mss_clamp */ | 5646 | /* Get original SYNACK MSS value if user MSS sets mss_clamp */ |
5676 | tcp_clear_options(&opt); | 5647 | tcp_clear_options(&opt); |
5677 | opt.user_mss = opt.mss_clamp = 0; | 5648 | opt.user_mss = opt.mss_clamp = 0; |
5678 | tcp_parse_options(synack, &opt, &hash_location, 0, NULL); | 5649 | tcp_parse_options(synack, &opt, 0, NULL); |
5679 | mss = opt.mss_clamp; | 5650 | mss = opt.mss_clamp; |
5680 | } | 5651 | } |
5681 | 5652 | ||
@@ -5706,14 +5677,12 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, | |||
5706 | static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, | 5677 | static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, |
5707 | const struct tcphdr *th, unsigned int len) | 5678 | const struct tcphdr *th, unsigned int len) |
5708 | { | 5679 | { |
5709 | const u8 *hash_location; | ||
5710 | struct inet_connection_sock *icsk = inet_csk(sk); | 5680 | struct inet_connection_sock *icsk = inet_csk(sk); |
5711 | struct tcp_sock *tp = tcp_sk(sk); | 5681 | struct tcp_sock *tp = tcp_sk(sk); |
5712 | struct tcp_cookie_values *cvp = tp->cookie_values; | ||
5713 | struct tcp_fastopen_cookie foc = { .len = -1 }; | 5682 | struct tcp_fastopen_cookie foc = { .len = -1 }; |
5714 | int saved_clamp = tp->rx_opt.mss_clamp; | 5683 | int saved_clamp = tp->rx_opt.mss_clamp; |
5715 | 5684 | ||
5716 | tcp_parse_options(skb, &tp->rx_opt, &hash_location, 0, &foc); | 5685 | tcp_parse_options(skb, &tp->rx_opt, 0, &foc); |
5717 | if (tp->rx_opt.saw_tstamp) | 5686 | if (tp->rx_opt.saw_tstamp) |
5718 | tp->rx_opt.rcv_tsecr -= tp->tsoffset; | 5687 | tp->rx_opt.rcv_tsecr -= tp->tsoffset; |
5719 | 5688 | ||
@@ -5810,30 +5779,6 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, | |||
5810 | * is initialized. */ | 5779 | * is initialized. */ |
5811 | tp->copied_seq = tp->rcv_nxt; | 5780 | tp->copied_seq = tp->rcv_nxt; |
5812 | 5781 | ||
5813 | if (cvp != NULL && | ||
5814 | cvp->cookie_pair_size > 0 && | ||
5815 | tp->rx_opt.cookie_plus > 0) { | ||
5816 | int cookie_size = tp->rx_opt.cookie_plus | ||
5817 | - TCPOLEN_COOKIE_BASE; | ||
5818 | int cookie_pair_size = cookie_size | ||
5819 | + cvp->cookie_desired; | ||
5820 | |||
5821 | /* A cookie extension option was sent and returned. | ||
5822 | * Note that each incoming SYNACK replaces the | ||
5823 | * Responder cookie. The initial exchange is most | ||
5824 | * fragile, as protection against spoofing relies | ||
5825 | * entirely upon the sequence and timestamp (above). | ||
5826 | * This replacement strategy allows the correct pair to | ||
5827 | * pass through, while any others will be filtered via | ||
5828 | * Responder verification later. | ||
5829 | */ | ||
5830 | if (sizeof(cvp->cookie_pair) >= cookie_pair_size) { | ||
5831 | memcpy(&cvp->cookie_pair[cvp->cookie_desired], | ||
5832 | hash_location, cookie_size); | ||
5833 | cvp->cookie_pair_size = cookie_pair_size; | ||
5834 | } | ||
5835 | } | ||
5836 | |||
5837 | smp_mb(); | 5782 | smp_mb(); |
5838 | 5783 | ||
5839 | tcp_finish_connect(sk, skb); | 5784 | tcp_finish_connect(sk, skb); |