diff options
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 125 |
1 files changed, 65 insertions, 60 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index d09203c63264..719652305a29 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -838,7 +838,6 @@ static void tcp_v4_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, | |||
838 | */ | 838 | */ |
839 | static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, | 839 | static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, |
840 | struct request_sock *req, | 840 | struct request_sock *req, |
841 | struct request_values *rvp, | ||
842 | u16 queue_mapping, | 841 | u16 queue_mapping, |
843 | bool nocache) | 842 | bool nocache) |
844 | { | 843 | { |
@@ -851,7 +850,7 @@ static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, | |||
851 | if (!dst && (dst = inet_csk_route_req(sk, &fl4, req)) == NULL) | 850 | if (!dst && (dst = inet_csk_route_req(sk, &fl4, req)) == NULL) |
852 | return -1; | 851 | return -1; |
853 | 852 | ||
854 | skb = tcp_make_synack(sk, dst, req, rvp, NULL); | 853 | skb = tcp_make_synack(sk, dst, req, NULL); |
855 | 854 | ||
856 | if (skb) { | 855 | if (skb) { |
857 | __tcp_v4_send_check(skb, ireq->loc_addr, ireq->rmt_addr); | 856 | __tcp_v4_send_check(skb, ireq->loc_addr, ireq->rmt_addr); |
@@ -868,10 +867,9 @@ static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, | |||
868 | return err; | 867 | return err; |
869 | } | 868 | } |
870 | 869 | ||
871 | static int tcp_v4_rtx_synack(struct sock *sk, struct request_sock *req, | 870 | static int tcp_v4_rtx_synack(struct sock *sk, struct request_sock *req) |
872 | struct request_values *rvp) | ||
873 | { | 871 | { |
874 | int res = tcp_v4_send_synack(sk, NULL, req, rvp, 0, false); | 872 | int res = tcp_v4_send_synack(sk, NULL, req, 0, false); |
875 | 873 | ||
876 | if (!res) | 874 | if (!res) |
877 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); | 875 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); |
@@ -1371,8 +1369,7 @@ static bool tcp_fastopen_check(struct sock *sk, struct sk_buff *skb, | |||
1371 | static int tcp_v4_conn_req_fastopen(struct sock *sk, | 1369 | static int tcp_v4_conn_req_fastopen(struct sock *sk, |
1372 | struct sk_buff *skb, | 1370 | struct sk_buff *skb, |
1373 | struct sk_buff *skb_synack, | 1371 | struct sk_buff *skb_synack, |
1374 | struct request_sock *req, | 1372 | struct request_sock *req) |
1375 | struct request_values *rvp) | ||
1376 | { | 1373 | { |
1377 | struct tcp_sock *tp = tcp_sk(sk); | 1374 | struct tcp_sock *tp = tcp_sk(sk); |
1378 | struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; | 1375 | struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; |
@@ -1467,9 +1464,7 @@ static int tcp_v4_conn_req_fastopen(struct sock *sk, | |||
1467 | 1464 | ||
1468 | int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | 1465 | int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) |
1469 | { | 1466 | { |
1470 | struct tcp_extend_values tmp_ext; | ||
1471 | struct tcp_options_received tmp_opt; | 1467 | struct tcp_options_received tmp_opt; |
1472 | const u8 *hash_location; | ||
1473 | struct request_sock *req; | 1468 | struct request_sock *req; |
1474 | struct inet_request_sock *ireq; | 1469 | struct inet_request_sock *ireq; |
1475 | struct tcp_sock *tp = tcp_sk(sk); | 1470 | struct tcp_sock *tp = tcp_sk(sk); |
@@ -1519,42 +1514,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1519 | tcp_clear_options(&tmp_opt); | 1514 | tcp_clear_options(&tmp_opt); |
1520 | tmp_opt.mss_clamp = TCP_MSS_DEFAULT; | 1515 | tmp_opt.mss_clamp = TCP_MSS_DEFAULT; |
1521 | tmp_opt.user_mss = tp->rx_opt.user_mss; | 1516 | tmp_opt.user_mss = tp->rx_opt.user_mss; |
1522 | tcp_parse_options(skb, &tmp_opt, &hash_location, 0, | 1517 | tcp_parse_options(skb, &tmp_opt, 0, want_cookie ? NULL : &foc); |
1523 | want_cookie ? NULL : &foc); | ||
1524 | |||
1525 | if (tmp_opt.cookie_plus > 0 && | ||
1526 | tmp_opt.saw_tstamp && | ||
1527 | !tp->rx_opt.cookie_out_never && | ||
1528 | (sysctl_tcp_cookie_size > 0 || | ||
1529 | (tp->cookie_values != NULL && | ||
1530 | tp->cookie_values->cookie_desired > 0))) { | ||
1531 | u8 *c; | ||
1532 | u32 *mess = &tmp_ext.cookie_bakery[COOKIE_DIGEST_WORDS]; | ||
1533 | int l = tmp_opt.cookie_plus - TCPOLEN_COOKIE_BASE; | ||
1534 | |||
1535 | if (tcp_cookie_generator(&tmp_ext.cookie_bakery[0]) != 0) | ||
1536 | goto drop_and_release; | ||
1537 | |||
1538 | /* Secret recipe starts with IP addresses */ | ||
1539 | *mess++ ^= (__force u32)daddr; | ||
1540 | *mess++ ^= (__force u32)saddr; | ||
1541 | |||
1542 | /* plus variable length Initiator Cookie */ | ||
1543 | c = (u8 *)mess; | ||
1544 | while (l-- > 0) | ||
1545 | *c++ ^= *hash_location++; | ||
1546 | |||
1547 | want_cookie = false; /* not our kind of cookie */ | ||
1548 | tmp_ext.cookie_out_never = 0; /* false */ | ||
1549 | tmp_ext.cookie_plus = tmp_opt.cookie_plus; | ||
1550 | } else if (!tp->rx_opt.cookie_in_always) { | ||
1551 | /* redundant indications, but ensure initialization. */ | ||
1552 | tmp_ext.cookie_out_never = 1; /* true */ | ||
1553 | tmp_ext.cookie_plus = 0; | ||
1554 | } else { | ||
1555 | goto drop_and_release; | ||
1556 | } | ||
1557 | tmp_ext.cookie_in_always = tp->rx_opt.cookie_in_always; | ||
1558 | 1518 | ||
1559 | if (want_cookie && !tmp_opt.saw_tstamp) | 1519 | if (want_cookie && !tmp_opt.saw_tstamp) |
1560 | tcp_clear_options(&tmp_opt); | 1520 | tcp_clear_options(&tmp_opt); |
@@ -1636,7 +1596,6 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1636 | * of tcp_v4_send_synack()->tcp_select_initial_window(). | 1596 | * of tcp_v4_send_synack()->tcp_select_initial_window(). |
1637 | */ | 1597 | */ |
1638 | skb_synack = tcp_make_synack(sk, dst, req, | 1598 | skb_synack = tcp_make_synack(sk, dst, req, |
1639 | (struct request_values *)&tmp_ext, | ||
1640 | fastopen_cookie_present(&valid_foc) ? &valid_foc : NULL); | 1599 | fastopen_cookie_present(&valid_foc) ? &valid_foc : NULL); |
1641 | 1600 | ||
1642 | if (skb_synack) { | 1601 | if (skb_synack) { |
@@ -1660,8 +1619,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1660 | if (fastopen_cookie_present(&foc) && foc.len != 0) | 1619 | if (fastopen_cookie_present(&foc) && foc.len != 0) |
1661 | NET_INC_STATS_BH(sock_net(sk), | 1620 | NET_INC_STATS_BH(sock_net(sk), |
1662 | LINUX_MIB_TCPFASTOPENPASSIVEFAIL); | 1621 | LINUX_MIB_TCPFASTOPENPASSIVEFAIL); |
1663 | } else if (tcp_v4_conn_req_fastopen(sk, skb, skb_synack, req, | 1622 | } else if (tcp_v4_conn_req_fastopen(sk, skb, skb_synack, req)) |
1664 | (struct request_values *)&tmp_ext)) | ||
1665 | goto drop_and_free; | 1623 | goto drop_and_free; |
1666 | 1624 | ||
1667 | return 0; | 1625 | return 0; |
@@ -1908,6 +1866,7 @@ discard: | |||
1908 | return 0; | 1866 | return 0; |
1909 | 1867 | ||
1910 | csum_err: | 1868 | csum_err: |
1869 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_CSUMERRORS); | ||
1911 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS); | 1870 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS); |
1912 | goto discard; | 1871 | goto discard; |
1913 | } | 1872 | } |
@@ -1950,6 +1909,51 @@ void tcp_v4_early_demux(struct sk_buff *skb) | |||
1950 | } | 1909 | } |
1951 | } | 1910 | } |
1952 | 1911 | ||
1912 | /* Packet is added to VJ-style prequeue for processing in process | ||
1913 | * context, if a reader task is waiting. Apparently, this exciting | ||
1914 | * idea (VJ's mail "Re: query about TCP header on tcp-ip" of 07 Sep 93) | ||
1915 | * failed somewhere. Latency? Burstiness? Well, at least now we will | ||
1916 | * see, why it failed. 8)8) --ANK | ||
1917 | * | ||
1918 | */ | ||
1919 | bool tcp_prequeue(struct sock *sk, struct sk_buff *skb) | ||
1920 | { | ||
1921 | struct tcp_sock *tp = tcp_sk(sk); | ||
1922 | |||
1923 | if (sysctl_tcp_low_latency || !tp->ucopy.task) | ||
1924 | return false; | ||
1925 | |||
1926 | if (skb->len <= tcp_hdrlen(skb) && | ||
1927 | skb_queue_len(&tp->ucopy.prequeue) == 0) | ||
1928 | return false; | ||
1929 | |||
1930 | skb_dst_force(skb); | ||
1931 | __skb_queue_tail(&tp->ucopy.prequeue, skb); | ||
1932 | tp->ucopy.memory += skb->truesize; | ||
1933 | if (tp->ucopy.memory > sk->sk_rcvbuf) { | ||
1934 | struct sk_buff *skb1; | ||
1935 | |||
1936 | BUG_ON(sock_owned_by_user(sk)); | ||
1937 | |||
1938 | while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) { | ||
1939 | sk_backlog_rcv(sk, skb1); | ||
1940 | NET_INC_STATS_BH(sock_net(sk), | ||
1941 | LINUX_MIB_TCPPREQUEUEDROPPED); | ||
1942 | } | ||
1943 | |||
1944 | tp->ucopy.memory = 0; | ||
1945 | } else if (skb_queue_len(&tp->ucopy.prequeue) == 1) { | ||
1946 | wake_up_interruptible_sync_poll(sk_sleep(sk), | ||
1947 | POLLIN | POLLRDNORM | POLLRDBAND); | ||
1948 | if (!inet_csk_ack_scheduled(sk)) | ||
1949 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, | ||
1950 | (3 * tcp_rto_min(sk)) / 4, | ||
1951 | TCP_RTO_MAX); | ||
1952 | } | ||
1953 | return true; | ||
1954 | } | ||
1955 | EXPORT_SYMBOL(tcp_prequeue); | ||
1956 | |||
1953 | /* | 1957 | /* |
1954 | * From tcp_input.c | 1958 | * From tcp_input.c |
1955 | */ | 1959 | */ |
@@ -1983,7 +1987,7 @@ int tcp_v4_rcv(struct sk_buff *skb) | |||
1983 | * provided case of th->doff==0 is eliminated. | 1987 | * provided case of th->doff==0 is eliminated. |
1984 | * So, we defer the checks. */ | 1988 | * So, we defer the checks. */ |
1985 | if (!skb_csum_unnecessary(skb) && tcp_v4_checksum_init(skb)) | 1989 | if (!skb_csum_unnecessary(skb) && tcp_v4_checksum_init(skb)) |
1986 | goto bad_packet; | 1990 | goto csum_error; |
1987 | 1991 | ||
1988 | th = tcp_hdr(skb); | 1992 | th = tcp_hdr(skb); |
1989 | iph = ip_hdr(skb); | 1993 | iph = ip_hdr(skb); |
@@ -2049,6 +2053,8 @@ no_tcp_socket: | |||
2049 | goto discard_it; | 2053 | goto discard_it; |
2050 | 2054 | ||
2051 | if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) { | 2055 | if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) { |
2056 | csum_error: | ||
2057 | TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS); | ||
2052 | bad_packet: | 2058 | bad_packet: |
2053 | TCP_INC_STATS_BH(net, TCP_MIB_INERRS); | 2059 | TCP_INC_STATS_BH(net, TCP_MIB_INERRS); |
2054 | } else { | 2060 | } else { |
@@ -2070,10 +2076,13 @@ do_time_wait: | |||
2070 | goto discard_it; | 2076 | goto discard_it; |
2071 | } | 2077 | } |
2072 | 2078 | ||
2073 | if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) { | 2079 | if (skb->len < (th->doff << 2)) { |
2074 | TCP_INC_STATS_BH(net, TCP_MIB_INERRS); | ||
2075 | inet_twsk_put(inet_twsk(sk)); | 2080 | inet_twsk_put(inet_twsk(sk)); |
2076 | goto discard_it; | 2081 | goto bad_packet; |
2082 | } | ||
2083 | if (tcp_checksum_complete(skb)) { | ||
2084 | inet_twsk_put(inet_twsk(sk)); | ||
2085 | goto csum_error; | ||
2077 | } | 2086 | } |
2078 | switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) { | 2087 | switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) { |
2079 | case TCP_TW_SYN: { | 2088 | case TCP_TW_SYN: { |
@@ -2197,12 +2206,6 @@ void tcp_v4_destroy_sock(struct sock *sk) | |||
2197 | if (inet_csk(sk)->icsk_bind_hash) | 2206 | if (inet_csk(sk)->icsk_bind_hash) |
2198 | inet_put_port(sk); | 2207 | inet_put_port(sk); |
2199 | 2208 | ||
2200 | /* TCP Cookie Transactions */ | ||
2201 | if (tp->cookie_values != NULL) { | ||
2202 | kref_put(&tp->cookie_values->kref, | ||
2203 | tcp_cookie_values_release); | ||
2204 | tp->cookie_values = NULL; | ||
2205 | } | ||
2206 | BUG_ON(tp->fastopen_rsk != NULL); | 2209 | BUG_ON(tp->fastopen_rsk != NULL); |
2207 | 2210 | ||
2208 | /* If socket is aborted during connect operation */ | 2211 | /* If socket is aborted during connect operation */ |
@@ -2580,7 +2583,7 @@ static void tcp_seq_stop(struct seq_file *seq, void *v) | |||
2580 | 2583 | ||
2581 | int tcp_seq_open(struct inode *inode, struct file *file) | 2584 | int tcp_seq_open(struct inode *inode, struct file *file) |
2582 | { | 2585 | { |
2583 | struct tcp_seq_afinfo *afinfo = PDE(inode)->data; | 2586 | struct tcp_seq_afinfo *afinfo = PDE_DATA(inode); |
2584 | struct tcp_iter_state *s; | 2587 | struct tcp_iter_state *s; |
2585 | int err; | 2588 | int err; |
2586 | 2589 | ||
@@ -2659,7 +2662,9 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) | |||
2659 | __u16 srcp = ntohs(inet->inet_sport); | 2662 | __u16 srcp = ntohs(inet->inet_sport); |
2660 | int rx_queue; | 2663 | int rx_queue; |
2661 | 2664 | ||
2662 | if (icsk->icsk_pending == ICSK_TIME_RETRANS) { | 2665 | if (icsk->icsk_pending == ICSK_TIME_RETRANS || |
2666 | icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS || | ||
2667 | icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) { | ||
2663 | timer_active = 1; | 2668 | timer_active = 1; |
2664 | timer_expires = icsk->icsk_timeout; | 2669 | timer_expires = icsk->icsk_timeout; |
2665 | } else if (icsk->icsk_pending == ICSK_TIME_PROBE0) { | 2670 | } else if (icsk->icsk_pending == ICSK_TIME_PROBE0) { |