diff options
| author | Michal Marek <mmarek@suse.cz> | 2010-08-04 08:05:07 -0400 |
|---|---|---|
| committer | Michal Marek <mmarek@suse.cz> | 2010-08-04 08:05:07 -0400 |
| commit | 7a996d3ab150bb0e1b71fa182f70199a703efdd1 (patch) | |
| tree | 96a36947d90c9b96580899abd38cb3b70cd9d40b /net/ipv4/tcp_output.c | |
| parent | 7cf3d73b4360e91b14326632ab1aeda4cb26308d (diff) | |
| parent | 9fe6206f400646a2322096b56c59891d530e8d51 (diff) | |
Merge commit 'v2.6.35' into kbuild/kconfig
Conflicts:
scripts/kconfig/Makefile
Diffstat (limited to 'net/ipv4/tcp_output.c')
| -rw-r--r-- | net/ipv4/tcp_output.c | 69 |
1 files changed, 39 insertions, 30 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 383ce237640f..7ed9dc1042d1 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #include <net/tcp.h> | 37 | #include <net/tcp.h> |
| 38 | 38 | ||
| 39 | #include <linux/compiler.h> | 39 | #include <linux/compiler.h> |
| 40 | #include <linux/gfp.h> | ||
| 40 | #include <linux/module.h> | 41 | #include <linux/module.h> |
| 41 | 42 | ||
| 42 | /* People can turn this off for buggy TCP's found in printers etc. */ | 43 | /* People can turn this off for buggy TCP's found in printers etc. */ |
| @@ -183,7 +184,8 @@ static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts) | |||
| 183 | */ | 184 | */ |
| 184 | void tcp_select_initial_window(int __space, __u32 mss, | 185 | void tcp_select_initial_window(int __space, __u32 mss, |
| 185 | __u32 *rcv_wnd, __u32 *window_clamp, | 186 | __u32 *rcv_wnd, __u32 *window_clamp, |
| 186 | int wscale_ok, __u8 *rcv_wscale) | 187 | int wscale_ok, __u8 *rcv_wscale, |
| 188 | __u32 init_rcv_wnd) | ||
| 187 | { | 189 | { |
| 188 | unsigned int space = (__space < 0 ? 0 : __space); | 190 | unsigned int space = (__space < 0 ? 0 : __space); |
| 189 | 191 | ||
| @@ -232,7 +234,13 @@ void tcp_select_initial_window(int __space, __u32 mss, | |||
| 232 | init_cwnd = 2; | 234 | init_cwnd = 2; |
| 233 | else if (mss > 1460) | 235 | else if (mss > 1460) |
| 234 | init_cwnd = 3; | 236 | init_cwnd = 3; |
| 235 | if (*rcv_wnd > init_cwnd * mss) | 237 | /* when initializing use the value from init_rcv_wnd |
| 238 | * rather than the default from above | ||
| 239 | */ | ||
| 240 | if (init_rcv_wnd && | ||
| 241 | (*rcv_wnd > init_rcv_wnd * mss)) | ||
| 242 | *rcv_wnd = init_rcv_wnd * mss; | ||
| 243 | else if (*rcv_wnd > init_cwnd * mss) | ||
| 236 | *rcv_wnd = init_cwnd * mss; | 244 | *rcv_wnd = init_cwnd * mss; |
| 237 | } | 245 | } |
| 238 | 246 | ||
| @@ -342,6 +350,7 @@ static inline void TCP_ECN_send(struct sock *sk, struct sk_buff *skb, | |||
| 342 | */ | 350 | */ |
| 343 | static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) | 351 | static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) |
| 344 | { | 352 | { |
| 353 | skb->ip_summed = CHECKSUM_PARTIAL; | ||
| 345 | skb->csum = 0; | 354 | skb->csum = 0; |
| 346 | 355 | ||
| 347 | TCP_SKB_CB(skb)->flags = flags; | 356 | TCP_SKB_CB(skb)->flags = flags; |
| @@ -659,7 +668,6 @@ static unsigned tcp_synack_options(struct sock *sk, | |||
| 659 | u8 cookie_plus = (xvp != NULL && !xvp->cookie_out_never) ? | 668 | u8 cookie_plus = (xvp != NULL && !xvp->cookie_out_never) ? |
| 660 | xvp->cookie_plus : | 669 | xvp->cookie_plus : |
| 661 | 0; | 670 | 0; |
| 662 | bool doing_ts = ireq->tstamp_ok; | ||
| 663 | 671 | ||
| 664 | #ifdef CONFIG_TCP_MD5SIG | 672 | #ifdef CONFIG_TCP_MD5SIG |
| 665 | *md5 = tcp_rsk(req)->af_specific->md5_lookup(sk, req); | 673 | *md5 = tcp_rsk(req)->af_specific->md5_lookup(sk, req); |
| @@ -672,7 +680,7 @@ static unsigned tcp_synack_options(struct sock *sk, | |||
| 672 | * rather than TS in order to fit in better with old, | 680 | * rather than TS in order to fit in better with old, |
| 673 | * buggy kernels, but that was deemed to be unnecessary. | 681 | * buggy kernels, but that was deemed to be unnecessary. |
| 674 | */ | 682 | */ |
| 675 | doing_ts &= !ireq->sack_ok; | 683 | ireq->tstamp_ok &= !ireq->sack_ok; |
| 676 | } | 684 | } |
| 677 | #else | 685 | #else |
| 678 | *md5 = NULL; | 686 | *md5 = NULL; |
| @@ -687,7 +695,7 @@ static unsigned tcp_synack_options(struct sock *sk, | |||
| 687 | opts->options |= OPTION_WSCALE; | 695 | opts->options |= OPTION_WSCALE; |
| 688 | remaining -= TCPOLEN_WSCALE_ALIGNED; | 696 | remaining -= TCPOLEN_WSCALE_ALIGNED; |
| 689 | } | 697 | } |
| 690 | if (likely(doing_ts)) { | 698 | if (likely(ireq->tstamp_ok)) { |
| 691 | opts->options |= OPTION_TS; | 699 | opts->options |= OPTION_TS; |
| 692 | opts->tsval = TCP_SKB_CB(skb)->when; | 700 | opts->tsval = TCP_SKB_CB(skb)->when; |
| 693 | opts->tsecr = req->ts_recent; | 701 | opts->tsecr = req->ts_recent; |
| @@ -695,7 +703,7 @@ static unsigned tcp_synack_options(struct sock *sk, | |||
| 695 | } | 703 | } |
| 696 | if (likely(ireq->sack_ok)) { | 704 | if (likely(ireq->sack_ok)) { |
| 697 | opts->options |= OPTION_SACK_ADVERTISE; | 705 | opts->options |= OPTION_SACK_ADVERTISE; |
| 698 | if (unlikely(!doing_ts)) | 706 | if (unlikely(!ireq->tstamp_ok)) |
| 699 | remaining -= TCPOLEN_SACKPERM_ALIGNED; | 707 | remaining -= TCPOLEN_SACKPERM_ALIGNED; |
| 700 | } | 708 | } |
| 701 | 709 | ||
| @@ -703,7 +711,7 @@ static unsigned tcp_synack_options(struct sock *sk, | |||
| 703 | * If the <SYN> options fit, the same options should fit now! | 711 | * If the <SYN> options fit, the same options should fit now! |
| 704 | */ | 712 | */ |
| 705 | if (*md5 == NULL && | 713 | if (*md5 == NULL && |
| 706 | doing_ts && | 714 | ireq->tstamp_ok && |
| 707 | cookie_plus > TCPOLEN_COOKIE_BASE) { | 715 | cookie_plus > TCPOLEN_COOKIE_BASE) { |
| 708 | int need = cookie_plus; /* has TCPOLEN_COOKIE_BASE */ | 716 | int need = cookie_plus; /* has TCPOLEN_COOKIE_BASE */ |
| 709 | 717 | ||
| @@ -852,7 +860,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
| 852 | th->urg_ptr = htons(tp->snd_up - tcb->seq); | 860 | th->urg_ptr = htons(tp->snd_up - tcb->seq); |
| 853 | th->urg = 1; | 861 | th->urg = 1; |
| 854 | } else if (after(tcb->seq + 0xFFFF, tp->snd_nxt)) { | 862 | } else if (after(tcb->seq + 0xFFFF, tp->snd_nxt)) { |
| 855 | th->urg_ptr = 0xFFFF; | 863 | th->urg_ptr = htons(0xFFFF); |
| 856 | th->urg = 1; | 864 | th->urg = 1; |
| 857 | } | 865 | } |
| 858 | } | 866 | } |
| @@ -864,13 +872,13 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
| 864 | #ifdef CONFIG_TCP_MD5SIG | 872 | #ifdef CONFIG_TCP_MD5SIG |
| 865 | /* Calculate the MD5 hash, as we have all we need now */ | 873 | /* Calculate the MD5 hash, as we have all we need now */ |
| 866 | if (md5) { | 874 | if (md5) { |
| 867 | sk->sk_route_caps &= ~NETIF_F_GSO_MASK; | 875 | sk_nocaps_add(sk, NETIF_F_GSO_MASK); |
| 868 | tp->af_specific->calc_md5_hash(opts.hash_location, | 876 | tp->af_specific->calc_md5_hash(opts.hash_location, |
| 869 | md5, sk, NULL, skb); | 877 | md5, sk, NULL, skb); |
| 870 | } | 878 | } |
| 871 | #endif | 879 | #endif |
| 872 | 880 | ||
| 873 | icsk->icsk_af_ops->send_check(sk, skb->len, skb); | 881 | icsk->icsk_af_ops->send_check(sk, skb); |
| 874 | 882 | ||
| 875 | if (likely(tcb->flags & TCPCB_FLAG_ACK)) | 883 | if (likely(tcb->flags & TCPCB_FLAG_ACK)) |
| 876 | tcp_event_ack_sent(sk, tcp_skb_pcount(skb)); | 884 | tcp_event_ack_sent(sk, tcp_skb_pcount(skb)); |
| @@ -879,9 +887,10 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
| 879 | tcp_event_data_sent(tp, skb, sk); | 887 | tcp_event_data_sent(tp, skb, sk); |
| 880 | 888 | ||
| 881 | if (after(tcb->end_seq, tp->snd_nxt) || tcb->seq == tcb->end_seq) | 889 | if (after(tcb->end_seq, tp->snd_nxt) || tcb->seq == tcb->end_seq) |
| 882 | TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); | 890 | TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS, |
| 891 | tcp_skb_pcount(skb)); | ||
| 883 | 892 | ||
| 884 | err = icsk->icsk_af_ops->queue_xmit(skb, 0); | 893 | err = icsk->icsk_af_ops->queue_xmit(skb); |
| 885 | if (likely(err <= 0)) | 894 | if (likely(err <= 0)) |
| 886 | return err; | 895 | return err; |
| 887 | 896 | ||
| @@ -1794,11 +1803,6 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, | |||
| 1794 | void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss, | 1803 | void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss, |
| 1795 | int nonagle) | 1804 | int nonagle) |
| 1796 | { | 1805 | { |
| 1797 | struct sk_buff *skb = tcp_send_head(sk); | ||
| 1798 | |||
| 1799 | if (!skb) | ||
| 1800 | return; | ||
| 1801 | |||
| 1802 | /* If we are closed, the bytes will have to remain here. | 1806 | /* If we are closed, the bytes will have to remain here. |
| 1803 | * In time closedown will finish, we empty the write queue and | 1807 | * In time closedown will finish, we empty the write queue and |
| 1804 | * all will be happy. | 1808 | * all will be happy. |
| @@ -2204,6 +2208,9 @@ void tcp_xmit_retransmit_queue(struct sock *sk) | |||
| 2204 | int mib_idx; | 2208 | int mib_idx; |
| 2205 | int fwd_rexmitting = 0; | 2209 | int fwd_rexmitting = 0; |
| 2206 | 2210 | ||
| 2211 | if (!tp->packets_out) | ||
| 2212 | return; | ||
| 2213 | |||
| 2207 | if (!tp->lost_out) | 2214 | if (!tp->lost_out) |
| 2208 | tp->retransmit_high = tp->snd_una; | 2215 | tp->retransmit_high = tp->snd_una; |
| 2209 | 2216 | ||
| @@ -2393,13 +2400,17 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
| 2393 | struct tcp_extend_values *xvp = tcp_xv(rvp); | 2400 | struct tcp_extend_values *xvp = tcp_xv(rvp); |
| 2394 | struct inet_request_sock *ireq = inet_rsk(req); | 2401 | struct inet_request_sock *ireq = inet_rsk(req); |
| 2395 | struct tcp_sock *tp = tcp_sk(sk); | 2402 | struct tcp_sock *tp = tcp_sk(sk); |
| 2403 | const struct tcp_cookie_values *cvp = tp->cookie_values; | ||
| 2396 | struct tcphdr *th; | 2404 | struct tcphdr *th; |
| 2397 | struct sk_buff *skb; | 2405 | struct sk_buff *skb; |
| 2398 | struct tcp_md5sig_key *md5; | 2406 | struct tcp_md5sig_key *md5; |
| 2399 | int tcp_header_size; | 2407 | int tcp_header_size; |
| 2400 | int mss; | 2408 | int mss; |
| 2409 | int s_data_desired = 0; | ||
| 2401 | 2410 | ||
| 2402 | skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC); | 2411 | if (cvp != NULL && cvp->s_data_constant && cvp->s_data_desired) |
| 2412 | s_data_desired = cvp->s_data_desired; | ||
| 2413 | skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15 + s_data_desired, 1, GFP_ATOMIC); | ||
| 2403 | if (skb == NULL) | 2414 | if (skb == NULL) |
| 2404 | return NULL; | 2415 | return NULL; |
| 2405 | 2416 | ||
| @@ -2422,7 +2433,8 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
| 2422 | &req->rcv_wnd, | 2433 | &req->rcv_wnd, |
| 2423 | &req->window_clamp, | 2434 | &req->window_clamp, |
| 2424 | ireq->wscale_ok, | 2435 | ireq->wscale_ok, |
| 2425 | &rcv_wscale); | 2436 | &rcv_wscale, |
| 2437 | dst_metric(dst, RTAX_INITRWND)); | ||
| 2426 | ireq->rcv_wscale = rcv_wscale; | 2438 | ireq->rcv_wscale = rcv_wscale; |
| 2427 | } | 2439 | } |
| 2428 | 2440 | ||
| @@ -2454,16 +2466,12 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
| 2454 | TCPCB_FLAG_SYN | TCPCB_FLAG_ACK); | 2466 | TCPCB_FLAG_SYN | TCPCB_FLAG_ACK); |
| 2455 | 2467 | ||
| 2456 | if (OPTION_COOKIE_EXTENSION & opts.options) { | 2468 | if (OPTION_COOKIE_EXTENSION & opts.options) { |
| 2457 | const struct tcp_cookie_values *cvp = tp->cookie_values; | 2469 | if (s_data_desired) { |
| 2458 | 2470 | u8 *buf = skb_put(skb, s_data_desired); | |
| 2459 | if (cvp != NULL && | ||
| 2460 | cvp->s_data_constant && | ||
| 2461 | cvp->s_data_desired > 0) { | ||
| 2462 | u8 *buf = skb_put(skb, cvp->s_data_desired); | ||
| 2463 | 2471 | ||
| 2464 | /* copy data directly from the listening socket. */ | 2472 | /* copy data directly from the listening socket. */ |
| 2465 | memcpy(buf, cvp->s_data_payload, cvp->s_data_desired); | 2473 | memcpy(buf, cvp->s_data_payload, s_data_desired); |
| 2466 | TCP_SKB_CB(skb)->end_seq += cvp->s_data_desired; | 2474 | TCP_SKB_CB(skb)->end_seq += s_data_desired; |
| 2467 | } | 2475 | } |
| 2468 | 2476 | ||
| 2469 | if (opts.hash_size > 0) { | 2477 | if (opts.hash_size > 0) { |
| @@ -2480,7 +2488,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
| 2480 | *tail-- ^= TCP_SKB_CB(skb)->seq + 1; | 2488 | *tail-- ^= TCP_SKB_CB(skb)->seq + 1; |
| 2481 | 2489 | ||
| 2482 | /* recommended */ | 2490 | /* recommended */ |
| 2483 | *tail-- ^= ((th->dest << 16) | th->source); | 2491 | *tail-- ^= (((__force u32)th->dest << 16) | (__force u32)th->source); |
| 2484 | *tail-- ^= (u32)(unsigned long)cvp; /* per sockopt */ | 2492 | *tail-- ^= (u32)(unsigned long)cvp; /* per sockopt */ |
| 2485 | 2493 | ||
| 2486 | sha_transform((__u32 *)&xvp->cookie_bakery[0], | 2494 | sha_transform((__u32 *)&xvp->cookie_bakery[0], |
| @@ -2498,7 +2506,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
| 2498 | th->window = htons(min(req->rcv_wnd, 65535U)); | 2506 | th->window = htons(min(req->rcv_wnd, 65535U)); |
| 2499 | tcp_options_write((__be32 *)(th + 1), tp, &opts); | 2507 | tcp_options_write((__be32 *)(th + 1), tp, &opts); |
| 2500 | th->doff = (tcp_header_size >> 2); | 2508 | th->doff = (tcp_header_size >> 2); |
| 2501 | TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); | 2509 | TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS, tcp_skb_pcount(skb)); |
| 2502 | 2510 | ||
| 2503 | #ifdef CONFIG_TCP_MD5SIG | 2511 | #ifdef CONFIG_TCP_MD5SIG |
| 2504 | /* Okay, we have all we need - do the md5 hash if needed */ | 2512 | /* Okay, we have all we need - do the md5 hash if needed */ |
| @@ -2549,7 +2557,8 @@ static void tcp_connect_init(struct sock *sk) | |||
| 2549 | &tp->rcv_wnd, | 2557 | &tp->rcv_wnd, |
| 2550 | &tp->window_clamp, | 2558 | &tp->window_clamp, |
| 2551 | sysctl_tcp_window_scaling, | 2559 | sysctl_tcp_window_scaling, |
| 2552 | &rcv_wscale); | 2560 | &rcv_wscale, |
| 2561 | dst_metric(dst, RTAX_INITRWND)); | ||
| 2553 | 2562 | ||
| 2554 | tp->rx_opt.rcv_wscale = rcv_wscale; | 2563 | tp->rx_opt.rcv_wscale = rcv_wscale; |
| 2555 | tp->rcv_ssthresh = tp->rcv_wnd; | 2564 | tp->rcv_ssthresh = tp->rcv_wnd; |
