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 ---