diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index b224eb8bce8b..8416f8a68e65 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -5518,6 +5518,18 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
5518 | struct tcp_sock *tp = tcp_sk(sk); | 5518 | struct tcp_sock *tp = tcp_sk(sk); |
5519 | int res; | 5519 | int res; |
5520 | 5520 | ||
5521 | if (sk->sk_rx_dst) { | ||
5522 | struct dst_entry *dst = sk->sk_rx_dst; | ||
5523 | if (unlikely(dst->obsolete)) { | ||
5524 | if (dst->ops->check(dst, 0) == NULL) { | ||
5525 | dst_release(dst); | ||
5526 | sk->sk_rx_dst = NULL; | ||
5527 | } | ||
5528 | } | ||
5529 | } | ||
5530 | if (unlikely(sk->sk_rx_dst == NULL)) | ||
5531 | sk->sk_rx_dst = dst_clone(skb_dst(skb)); | ||
5532 | |||
5521 | /* | 5533 | /* |
5522 | * Header prediction. | 5534 | * Header prediction. |
5523 | * The code loosely follows the one in the famous | 5535 | * The code loosely follows the one in the famous |
@@ -5729,8 +5741,10 @@ void tcp_finish_connect(struct sock *sk, struct sk_buff *skb) | |||
5729 | 5741 | ||
5730 | tcp_set_state(sk, TCP_ESTABLISHED); | 5742 | tcp_set_state(sk, TCP_ESTABLISHED); |
5731 | 5743 | ||
5732 | if (skb != NULL) | 5744 | if (skb != NULL) { |
5745 | sk->sk_rx_dst = dst_clone(skb_dst(skb)); | ||
5733 | security_inet_conn_established(sk, skb); | 5746 | security_inet_conn_established(sk, skb); |
5747 | } | ||
5734 | 5748 | ||
5735 | /* Make sure socket is routed, for correct metrics. */ | 5749 | /* Make sure socket is routed, for correct metrics. */ |
5736 | icsk->icsk_af_ops->rebuild_header(sk); | 5750 | icsk->icsk_af_ops->rebuild_header(sk); |