aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_ipv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r--net/ipv4/tcp_ipv4.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 42b2a6a73092..00a748d14062 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -417,10 +417,12 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
417 417
418 if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */ 418 if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */
419 tp->mtu_info = info; 419 tp->mtu_info = info;
420 if (!sock_owned_by_user(sk)) 420 if (!sock_owned_by_user(sk)) {
421 tcp_v4_mtu_reduced(sk); 421 tcp_v4_mtu_reduced(sk);
422 else 422 } else {
423 set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags); 423 if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags))
424 sock_hold(sk);
425 }
424 goto out; 426 goto out;
425 } 427 }
426 428
@@ -1462,6 +1464,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1462 goto exit_nonewsk; 1464 goto exit_nonewsk;
1463 1465
1464 newsk->sk_gso_type = SKB_GSO_TCPV4; 1466 newsk->sk_gso_type = SKB_GSO_TCPV4;
1467 inet_sk_rx_dst_set(newsk, skb);
1465 1468
1466 newtp = tcp_sk(newsk); 1469 newtp = tcp_sk(newsk);
1467 newinet = inet_sk(newsk); 1470 newinet = inet_sk(newsk);
@@ -1627,9 +1630,6 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
1627 sk->sk_rx_dst = NULL; 1630 sk->sk_rx_dst = NULL;
1628 } 1631 }
1629 } 1632 }
1630 if (unlikely(sk->sk_rx_dst == NULL))
1631 inet_sk_rx_dst_set(sk, skb);
1632
1633 if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) { 1633 if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) {
1634 rsk = sk; 1634 rsk = sk;
1635 goto reset; 1635 goto reset;
@@ -1872,10 +1872,21 @@ static struct timewait_sock_ops tcp_timewait_sock_ops = {
1872 .twsk_destructor= tcp_twsk_destructor, 1872 .twsk_destructor= tcp_twsk_destructor,
1873}; 1873};
1874 1874
1875void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
1876{
1877 struct dst_entry *dst = skb_dst(skb);
1878
1879 dst_hold(dst);
1880 sk->sk_rx_dst = dst;
1881 inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
1882}
1883EXPORT_SYMBOL(inet_sk_rx_dst_set);
1884
1875const struct inet_connection_sock_af_ops ipv4_specific = { 1885const struct inet_connection_sock_af_ops ipv4_specific = {
1876 .queue_xmit = ip_queue_xmit, 1886 .queue_xmit = ip_queue_xmit,
1877 .send_check = tcp_v4_send_check, 1887 .send_check = tcp_v4_send_check,
1878 .rebuild_header = inet_sk_rebuild_header, 1888 .rebuild_header = inet_sk_rebuild_header,
1889 .sk_rx_dst_set = inet_sk_rx_dst_set,
1879 .conn_request = tcp_v4_conn_request, 1890 .conn_request = tcp_v4_conn_request,
1880 .syn_recv_sock = tcp_v4_syn_recv_sock, 1891 .syn_recv_sock = tcp_v4_syn_recv_sock,
1881 .net_header_len = sizeof(struct iphdr), 1892 .net_header_len = sizeof(struct iphdr),