diff options
Diffstat (limited to 'net/ipv4')
| -rw-r--r-- | net/ipv4/route.c | 9 | ||||
| -rw-r--r-- | net/ipv4/tcp.c | 10 | ||||
| -rw-r--r-- | net/ipv4/tcp_input.c | 13 | ||||
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 1 | ||||
| -rw-r--r-- | net/ipv4/tcp_minisocks.c | 1 | ||||
| -rw-r--r-- | net/ipv4/tcp_timer.c | 4 |
6 files changed, 26 insertions, 12 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 432f4bb77238..a8c651216fa6 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -1163,8 +1163,12 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe, | |||
| 1163 | spin_lock_bh(&fnhe_lock); | 1163 | spin_lock_bh(&fnhe_lock); |
| 1164 | 1164 | ||
| 1165 | if (daddr == fnhe->fnhe_daddr) { | 1165 | if (daddr == fnhe->fnhe_daddr) { |
| 1166 | struct rtable *orig; | 1166 | struct rtable *orig = rcu_dereference(fnhe->fnhe_rth); |
| 1167 | 1167 | if (orig && rt_is_expired(orig)) { | |
| 1168 | fnhe->fnhe_gw = 0; | ||
| 1169 | fnhe->fnhe_pmtu = 0; | ||
| 1170 | fnhe->fnhe_expires = 0; | ||
| 1171 | } | ||
| 1168 | if (fnhe->fnhe_pmtu) { | 1172 | if (fnhe->fnhe_pmtu) { |
| 1169 | unsigned long expires = fnhe->fnhe_expires; | 1173 | unsigned long expires = fnhe->fnhe_expires; |
| 1170 | unsigned long diff = expires - jiffies; | 1174 | unsigned long diff = expires - jiffies; |
| @@ -1181,7 +1185,6 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe, | |||
| 1181 | } else if (!rt->rt_gateway) | 1185 | } else if (!rt->rt_gateway) |
| 1182 | rt->rt_gateway = daddr; | 1186 | rt->rt_gateway = daddr; |
| 1183 | 1187 | ||
| 1184 | orig = rcu_dereference(fnhe->fnhe_rth); | ||
| 1185 | rcu_assign_pointer(fnhe->fnhe_rth, rt); | 1188 | rcu_assign_pointer(fnhe->fnhe_rth, rt); |
| 1186 | if (orig) | 1189 | if (orig) |
| 1187 | rt_free(orig); | 1190 | rt_free(orig); |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index f32c02e2a543..197c0008503c 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -549,14 +549,12 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
| 549 | !tp->urg_data || | 549 | !tp->urg_data || |
| 550 | before(tp->urg_seq, tp->copied_seq) || | 550 | before(tp->urg_seq, tp->copied_seq) || |
| 551 | !before(tp->urg_seq, tp->rcv_nxt)) { | 551 | !before(tp->urg_seq, tp->rcv_nxt)) { |
| 552 | struct sk_buff *skb; | ||
| 553 | 552 | ||
| 554 | answ = tp->rcv_nxt - tp->copied_seq; | 553 | answ = tp->rcv_nxt - tp->copied_seq; |
| 555 | 554 | ||
| 556 | /* Subtract 1, if FIN is in queue. */ | 555 | /* Subtract 1, if FIN was received */ |
| 557 | skb = skb_peek_tail(&sk->sk_receive_queue); | 556 | if (answ && sock_flag(sk, SOCK_DONE)) |
| 558 | if (answ && skb) | 557 | answ--; |
| 559 | answ -= tcp_hdr(skb)->fin; | ||
| 560 | } else | 558 | } else |
| 561 | answ = tp->urg_seq - tp->copied_seq; | 559 | answ = tp->urg_seq - tp->copied_seq; |
| 562 | release_sock(sk); | 560 | release_sock(sk); |
| @@ -2766,6 +2764,8 @@ void tcp_get_info(const struct sock *sk, struct tcp_info *info) | |||
| 2766 | info->tcpi_options |= TCPI_OPT_ECN; | 2764 | info->tcpi_options |= TCPI_OPT_ECN; |
| 2767 | if (tp->ecn_flags & TCP_ECN_SEEN) | 2765 | if (tp->ecn_flags & TCP_ECN_SEEN) |
| 2768 | info->tcpi_options |= TCPI_OPT_ECN_SEEN; | 2766 | info->tcpi_options |= TCPI_OPT_ECN_SEEN; |
| 2767 | if (tp->syn_data_acked) | ||
| 2768 | info->tcpi_options |= TCPI_OPT_SYN_DATA; | ||
| 2769 | 2769 | ||
| 2770 | info->tcpi_rto = jiffies_to_usecs(icsk->icsk_rto); | 2770 | info->tcpi_rto = jiffies_to_usecs(icsk->icsk_rto); |
| 2771 | info->tcpi_ato = jiffies_to_usecs(icsk->icsk_ack.ato); | 2771 | info->tcpi_ato = jiffies_to_usecs(icsk->icsk_ack.ato); |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 432c36649db3..1db663983587 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -5646,6 +5646,7 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, | |||
| 5646 | tcp_rearm_rto(sk); | 5646 | tcp_rearm_rto(sk); |
| 5647 | return true; | 5647 | return true; |
| 5648 | } | 5648 | } |
| 5649 | tp->syn_data_acked = tp->syn_data; | ||
| 5649 | return false; | 5650 | return false; |
| 5650 | } | 5651 | } |
| 5651 | 5652 | ||
| @@ -5963,7 +5964,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
| 5963 | 5964 | ||
| 5964 | req = tp->fastopen_rsk; | 5965 | req = tp->fastopen_rsk; |
| 5965 | if (req != NULL) { | 5966 | if (req != NULL) { |
| 5966 | BUG_ON(sk->sk_state != TCP_SYN_RECV && | 5967 | WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV && |
| 5967 | sk->sk_state != TCP_FIN_WAIT1); | 5968 | sk->sk_state != TCP_FIN_WAIT1); |
| 5968 | 5969 | ||
| 5969 | if (tcp_check_req(sk, skb, req, NULL, true) == NULL) | 5970 | if (tcp_check_req(sk, skb, req, NULL, true) == NULL) |
| @@ -6052,7 +6053,15 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
| 6052 | * ACK we have received, this would have acknowledged | 6053 | * ACK we have received, this would have acknowledged |
| 6053 | * our SYNACK so stop the SYNACK timer. | 6054 | * our SYNACK so stop the SYNACK timer. |
| 6054 | */ | 6055 | */ |
| 6055 | if (acceptable && req != NULL) { | 6056 | if (req != NULL) { |
| 6057 | /* Return RST if ack_seq is invalid. | ||
| 6058 | * Note that RFC793 only says to generate a | ||
| 6059 | * DUPACK for it but for TCP Fast Open it seems | ||
| 6060 | * better to treat this case like TCP_SYN_RECV | ||
| 6061 | * above. | ||
| 6062 | */ | ||
| 6063 | if (!acceptable) | ||
| 6064 | return 1; | ||
| 6056 | /* We no longer need the request sock. */ | 6065 | /* We no longer need the request sock. */ |
| 6057 | reqsk_fastopen_remove(sk, req, false); | 6066 | reqsk_fastopen_remove(sk, req, false); |
| 6058 | tcp_rearm_rto(sk); | 6067 | tcp_rearm_rto(sk); |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index ef998b008a57..0c4a64355603 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -1461,6 +1461,7 @@ static int tcp_v4_conn_req_fastopen(struct sock *sk, | |||
| 1461 | skb_set_owner_r(skb, child); | 1461 | skb_set_owner_r(skb, child); |
| 1462 | __skb_queue_tail(&child->sk_receive_queue, skb); | 1462 | __skb_queue_tail(&child->sk_receive_queue, skb); |
| 1463 | tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; | 1463 | tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; |
| 1464 | tp->syn_data_acked = 1; | ||
| 1464 | } | 1465 | } |
| 1465 | sk->sk_data_ready(sk, 0); | 1466 | sk->sk_data_ready(sk, 0); |
| 1466 | bh_unlock_sock(child); | 1467 | bh_unlock_sock(child); |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 27536ba16c9d..a7302d974f32 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
| @@ -510,6 +510,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, | |||
| 510 | newtp->rx_opt.mss_clamp = req->mss; | 510 | newtp->rx_opt.mss_clamp = req->mss; |
| 511 | TCP_ECN_openreq_child(newtp, req); | 511 | TCP_ECN_openreq_child(newtp, req); |
| 512 | newtp->fastopen_rsk = NULL; | 512 | newtp->fastopen_rsk = NULL; |
| 513 | newtp->syn_data_acked = 0; | ||
| 513 | 514 | ||
| 514 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_PASSIVEOPENS); | 515 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_PASSIVEOPENS); |
| 515 | } | 516 | } |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index fc04711e80c8..d47c1b4421a3 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
| @@ -347,8 +347,8 @@ void tcp_retransmit_timer(struct sock *sk) | |||
| 347 | return; | 347 | return; |
| 348 | } | 348 | } |
| 349 | if (tp->fastopen_rsk) { | 349 | if (tp->fastopen_rsk) { |
| 350 | BUG_ON(sk->sk_state != TCP_SYN_RECV && | 350 | WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV && |
| 351 | sk->sk_state != TCP_FIN_WAIT1); | 351 | sk->sk_state != TCP_FIN_WAIT1); |
| 352 | tcp_fastopen_synack_timer(sk); | 352 | tcp_fastopen_synack_timer(sk); |
| 353 | /* Before we receive ACK to our SYN-ACK don't retransmit | 353 | /* Before we receive ACK to our SYN-ACK don't retransmit |
| 354 | * anything else (e.g., data or FIN segments). | 354 | * anything else (e.g., data or FIN segments). |
