tcp_output.c (0b28330e39bbe0ffee4c56b09fc415fcec595ea3) | tcp_output.c (de213e5eedecdfb1b1eea7e6be28bc64cac5c078) |
---|---|
1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * Implementation of the Transmission Control Protocol(TCP). 7 * 8 * Authors: Ross Biro --- 336 unchanged lines hidden (view full) --- 345 } 346} 347 348/* Constructs common control bits of non-data skb. If SYN/FIN is present, 349 * auto increment end seqno. 350 */ 351static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) 352{ | 1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * Implementation of the Transmission Control Protocol(TCP). 7 * 8 * Authors: Ross Biro --- 336 unchanged lines hidden (view full) --- 345 } 346} 347 348/* Constructs common control bits of non-data skb. If SYN/FIN is present, 349 * auto increment end seqno. 350 */ 351static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) 352{ |
353 skb->ip_summed = CHECKSUM_PARTIAL; |
|
353 skb->csum = 0; 354 355 TCP_SKB_CB(skb)->flags = flags; 356 TCP_SKB_CB(skb)->sacked = 0; 357 358 skb_shinfo(skb)->gso_segs = 1; 359 skb_shinfo(skb)->gso_size = 0; 360 skb_shinfo(skb)->gso_type = 0; --- 301 unchanged lines hidden (view full) --- 662 struct tcp_md5sig_key **md5, 663 struct tcp_extend_values *xvp) 664{ 665 struct inet_request_sock *ireq = inet_rsk(req); 666 unsigned remaining = MAX_TCP_OPTION_SPACE; 667 u8 cookie_plus = (xvp != NULL && !xvp->cookie_out_never) ? 668 xvp->cookie_plus : 669 0; | 354 skb->csum = 0; 355 356 TCP_SKB_CB(skb)->flags = flags; 357 TCP_SKB_CB(skb)->sacked = 0; 358 359 skb_shinfo(skb)->gso_segs = 1; 360 skb_shinfo(skb)->gso_size = 0; 361 skb_shinfo(skb)->gso_type = 0; --- 301 unchanged lines hidden (view full) --- 663 struct tcp_md5sig_key **md5, 664 struct tcp_extend_values *xvp) 665{ 666 struct inet_request_sock *ireq = inet_rsk(req); 667 unsigned remaining = MAX_TCP_OPTION_SPACE; 668 u8 cookie_plus = (xvp != NULL && !xvp->cookie_out_never) ? 669 xvp->cookie_plus : 670 0; |
670 bool doing_ts = ireq->tstamp_ok; | |
671 672#ifdef CONFIG_TCP_MD5SIG 673 *md5 = tcp_rsk(req)->af_specific->md5_lookup(sk, req); 674 if (*md5) { 675 opts->options |= OPTION_MD5; 676 remaining -= TCPOLEN_MD5SIG_ALIGNED; 677 678 /* We can't fit any SACK blocks in a packet with MD5 + TS 679 * options. There was discussion about disabling SACK 680 * rather than TS in order to fit in better with old, 681 * buggy kernels, but that was deemed to be unnecessary. 682 */ | 671 672#ifdef CONFIG_TCP_MD5SIG 673 *md5 = tcp_rsk(req)->af_specific->md5_lookup(sk, req); 674 if (*md5) { 675 opts->options |= OPTION_MD5; 676 remaining -= TCPOLEN_MD5SIG_ALIGNED; 677 678 /* We can't fit any SACK blocks in a packet with MD5 + TS 679 * options. There was discussion about disabling SACK 680 * rather than TS in order to fit in better with old, 681 * buggy kernels, but that was deemed to be unnecessary. 682 */ |
683 doing_ts &= !ireq->sack_ok; | 683 ireq->tstamp_ok &= !ireq->sack_ok; |
684 } 685#else 686 *md5 = NULL; 687#endif 688 689 /* We always send an MSS option. */ 690 opts->mss = mss; 691 remaining -= TCPOLEN_MSS_ALIGNED; 692 693 if (likely(ireq->wscale_ok)) { 694 opts->ws = ireq->rcv_wscale; 695 opts->options |= OPTION_WSCALE; 696 remaining -= TCPOLEN_WSCALE_ALIGNED; 697 } | 684 } 685#else 686 *md5 = NULL; 687#endif 688 689 /* We always send an MSS option. */ 690 opts->mss = mss; 691 remaining -= TCPOLEN_MSS_ALIGNED; 692 693 if (likely(ireq->wscale_ok)) { 694 opts->ws = ireq->rcv_wscale; 695 opts->options |= OPTION_WSCALE; 696 remaining -= TCPOLEN_WSCALE_ALIGNED; 697 } |
698 if (likely(doing_ts)) { | 698 if (likely(ireq->tstamp_ok)) { |
699 opts->options |= OPTION_TS; 700 opts->tsval = TCP_SKB_CB(skb)->when; 701 opts->tsecr = req->ts_recent; 702 remaining -= TCPOLEN_TSTAMP_ALIGNED; 703 } 704 if (likely(ireq->sack_ok)) { 705 opts->options |= OPTION_SACK_ADVERTISE; | 699 opts->options |= OPTION_TS; 700 opts->tsval = TCP_SKB_CB(skb)->when; 701 opts->tsecr = req->ts_recent; 702 remaining -= TCPOLEN_TSTAMP_ALIGNED; 703 } 704 if (likely(ireq->sack_ok)) { 705 opts->options |= OPTION_SACK_ADVERTISE; |
706 if (unlikely(!doing_ts)) | 706 if (unlikely(!ireq->tstamp_ok)) |
707 remaining -= TCPOLEN_SACKPERM_ALIGNED; 708 } 709 710 /* Similar rationale to tcp_syn_options() applies here, too. 711 * If the <SYN> options fit, the same options should fit now! 712 */ 713 if (*md5 == NULL && | 707 remaining -= TCPOLEN_SACKPERM_ALIGNED; 708 } 709 710 /* Similar rationale to tcp_syn_options() applies here, too. 711 * If the <SYN> options fit, the same options should fit now! 712 */ 713 if (*md5 == NULL && |
714 doing_ts && | 714 ireq->tstamp_ok && |
715 cookie_plus > TCPOLEN_COOKIE_BASE) { 716 int need = cookie_plus; /* has TCPOLEN_COOKIE_BASE */ 717 718 if (0x2 & need) { 719 /* 32-bit multiple */ 720 need += 2; /* NOPs */ 721 } 722 if (need <= remaining) { --- 132 unchanged lines hidden (view full) --- 855 th->urg_ptr = 0; 856 857 /* The urg_mode check is necessary during a below snd_una win probe */ 858 if (unlikely(tcp_urg_mode(tp) && before(tcb->seq, tp->snd_up))) { 859 if (before(tp->snd_up, tcb->seq + 0x10000)) { 860 th->urg_ptr = htons(tp->snd_up - tcb->seq); 861 th->urg = 1; 862 } else if (after(tcb->seq + 0xFFFF, tp->snd_nxt)) { | 715 cookie_plus > TCPOLEN_COOKIE_BASE) { 716 int need = cookie_plus; /* has TCPOLEN_COOKIE_BASE */ 717 718 if (0x2 & need) { 719 /* 32-bit multiple */ 720 need += 2; /* NOPs */ 721 } 722 if (need <= remaining) { --- 132 unchanged lines hidden (view full) --- 855 th->urg_ptr = 0; 856 857 /* The urg_mode check is necessary during a below snd_una win probe */ 858 if (unlikely(tcp_urg_mode(tp) && before(tcb->seq, tp->snd_up))) { 859 if (before(tp->snd_up, tcb->seq + 0x10000)) { 860 th->urg_ptr = htons(tp->snd_up - tcb->seq); 861 th->urg = 1; 862 } else if (after(tcb->seq + 0xFFFF, tp->snd_nxt)) { |
863 th->urg_ptr = 0xFFFF; | 863 th->urg_ptr = htons(0xFFFF); |
864 th->urg = 1; 865 } 866 } 867 868 tcp_options_write((__be32 *)(th + 1), tp, &opts); 869 if (likely((tcb->flags & TCPCB_FLAG_SYN) == 0)) 870 TCP_ECN_send(sk, skb, tcp_header_size); 871 872#ifdef CONFIG_TCP_MD5SIG 873 /* Calculate the MD5 hash, as we have all we need now */ 874 if (md5) { | 864 th->urg = 1; 865 } 866 } 867 868 tcp_options_write((__be32 *)(th + 1), tp, &opts); 869 if (likely((tcb->flags & TCPCB_FLAG_SYN) == 0)) 870 TCP_ECN_send(sk, skb, tcp_header_size); 871 872#ifdef CONFIG_TCP_MD5SIG 873 /* Calculate the MD5 hash, as we have all we need now */ 874 if (md5) { |
875 sk->sk_route_caps &= ~NETIF_F_GSO_MASK; | 875 sk_nocaps_add(sk, NETIF_F_GSO_MASK); |
876 tp->af_specific->calc_md5_hash(opts.hash_location, 877 md5, sk, NULL, skb); 878 } 879#endif 880 | 876 tp->af_specific->calc_md5_hash(opts.hash_location, 877 md5, sk, NULL, skb); 878 } 879#endif 880 |
881 icsk->icsk_af_ops->send_check(sk, skb->len, skb); | 881 icsk->icsk_af_ops->send_check(sk, skb); |
882 883 if (likely(tcb->flags & TCPCB_FLAG_ACK)) 884 tcp_event_ack_sent(sk, tcp_skb_pcount(skb)); 885 886 if (skb->len != tcp_header_size) 887 tcp_event_data_sent(tp, skb, sk); 888 889 if (after(tcb->end_seq, tp->snd_nxt) || tcb->seq == tcb->end_seq) | 882 883 if (likely(tcb->flags & TCPCB_FLAG_ACK)) 884 tcp_event_ack_sent(sk, tcp_skb_pcount(skb)); 885 886 if (skb->len != tcp_header_size) 887 tcp_event_data_sent(tp, skb, sk); 888 889 if (after(tcb->end_seq, tp->snd_nxt) || tcb->seq == tcb->end_seq) |
890 TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); | 890 TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS, 891 tcp_skb_pcount(skb)); |
891 | 892 |
892 err = icsk->icsk_af_ops->queue_xmit(skb, 0); | 893 err = icsk->icsk_af_ops->queue_xmit(skb); |
893 if (likely(err <= 0)) 894 return err; 895 896 tcp_enter_cwr(sk, 1); 897 898 return net_xmit_eval(err); 899} 900 --- 1578 unchanged lines hidden (view full) --- 2479 * Sequence and Acknowledgment Numbers, Initiator 2480 * Cookie, and others handled by IP variant caller. 2481 */ 2482 *tail-- ^= opts.tsval; 2483 *tail-- ^= tcp_rsk(req)->rcv_isn + 1; 2484 *tail-- ^= TCP_SKB_CB(skb)->seq + 1; 2485 2486 /* recommended */ | 894 if (likely(err <= 0)) 895 return err; 896 897 tcp_enter_cwr(sk, 1); 898 899 return net_xmit_eval(err); 900} 901 --- 1578 unchanged lines hidden (view full) --- 2480 * Sequence and Acknowledgment Numbers, Initiator 2481 * Cookie, and others handled by IP variant caller. 2482 */ 2483 *tail-- ^= opts.tsval; 2484 *tail-- ^= tcp_rsk(req)->rcv_isn + 1; 2485 *tail-- ^= TCP_SKB_CB(skb)->seq + 1; 2486 2487 /* recommended */ |
2487 *tail-- ^= ((th->dest << 16) | th->source); | 2488 *tail-- ^= (((__force u32)th->dest << 16) | (__force u32)th->source); |
2488 *tail-- ^= (u32)(unsigned long)cvp; /* per sockopt */ 2489 2490 sha_transform((__u32 *)&xvp->cookie_bakery[0], 2491 (char *)mess, 2492 &workspace[0]); 2493 opts.hash_location = 2494 (__u8 *)&xvp->cookie_bakery[0]; 2495 } 2496 } 2497 2498 th->seq = htonl(TCP_SKB_CB(skb)->seq); 2499 th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1); 2500 2501 /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ 2502 th->window = htons(min(req->rcv_wnd, 65535U)); 2503 tcp_options_write((__be32 *)(th + 1), tp, &opts); 2504 th->doff = (tcp_header_size >> 2); | 2489 *tail-- ^= (u32)(unsigned long)cvp; /* per sockopt */ 2490 2491 sha_transform((__u32 *)&xvp->cookie_bakery[0], 2492 (char *)mess, 2493 &workspace[0]); 2494 opts.hash_location = 2495 (__u8 *)&xvp->cookie_bakery[0]; 2496 } 2497 } 2498 2499 th->seq = htonl(TCP_SKB_CB(skb)->seq); 2500 th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1); 2501 2502 /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ 2503 th->window = htons(min(req->rcv_wnd, 65535U)); 2504 tcp_options_write((__be32 *)(th + 1), tp, &opts); 2505 th->doff = (tcp_header_size >> 2); |
2505 TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); | 2506 TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS, tcp_skb_pcount(skb)); |
2506 2507#ifdef CONFIG_TCP_MD5SIG 2508 /* Okay, we have all we need - do the md5 hash if needed */ 2509 if (md5) { 2510 tcp_rsk(req)->af_specific->calc_md5_hash(opts.hash_location, 2511 md5, NULL, req, skb); 2512 } 2513#endif --- 316 unchanged lines hidden --- | 2507 2508#ifdef CONFIG_TCP_MD5SIG 2509 /* Okay, we have all we need - do the md5 hash if needed */ 2510 if (md5) { 2511 tcp_rsk(req)->af_specific->calc_md5_hash(opts.hash_location, 2512 md5, NULL, req, skb); 2513 } 2514#endif --- 316 unchanged lines hidden --- |