tcp: Fix MD5 signatures for non-linear skbs
[deliverable/linux.git] / net / ipv4 / tcp_output.c
index ad993ecb4810d88dc49bca51208a96e67c9555bb..958ff486165fdd98b34217af9e10e0b36622106f 100644 (file)
@@ -5,8 +5,6 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp_output.c,v 1.146 2002/02/01 22:01:04 davem Exp $
- *
  * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Mark Evans, <evansmp@uhura.aston.ac.uk>
@@ -542,8 +540,10 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
         * room for it.
         */
        md5 = tp->af_specific->md5_lookup(sk, sk);
-       if (md5)
+       if (md5) {
                tcp_header_size += TCPOLEN_MD5SIG_ALIGNED;
+               sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
+       }
 #endif
 
        skb_push(skb, tcp_header_size);
@@ -604,11 +604,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
        /* Calculate the MD5 hash, as we have all we need now */
        if (md5) {
                tp->af_specific->calc_md5_hash(md5_hash_location,
-                                              md5,
-                                              sk, NULL, NULL,
-                                              tcp_hdr(skb),
-                                              sk->sk_protocol,
-                                              skb->len);
+                                              md5, sk, NULL, skb);
        }
 #endif
 
@@ -621,7 +617,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
                tcp_event_data_sent(tp, skb, sk);
 
        if (after(tcb->end_seq, tp->snd_nxt) || tcb->seq == tcb->end_seq)
-               TCP_INC_STATS(TCP_MIB_OUTSEGS);
+               TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS);
 
        err = icsk->icsk_af_ops->queue_xmit(skb, 0);
        if (likely(err <= 0))
@@ -1913,7 +1909,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
 
        if (err == 0) {
                /* Update global TCP statistics. */
-               TCP_INC_STATS(TCP_MIB_RETRANSSEGS);
+               TCP_INC_STATS(sock_net(sk), TCP_MIB_RETRANSSEGS);
 
                tp->total_retrans++;
 
@@ -1988,14 +1984,17 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
 
                        if (sacked & TCPCB_LOST) {
                                if (!(sacked & (TCPCB_SACKED_ACKED|TCPCB_SACKED_RETRANS))) {
+                                       int mib_idx;
+
                                        if (tcp_retransmit_skb(sk, skb)) {
                                                tp->retransmit_skb_hint = NULL;
                                                return;
                                        }
                                        if (icsk->icsk_ca_state != TCP_CA_Loss)
-                                               NET_INC_STATS_BH(LINUX_MIB_TCPFASTRETRANS);
+                                               mib_idx = LINUX_MIB_TCPFASTRETRANS;
                                        else
-                                               NET_INC_STATS_BH(LINUX_MIB_TCPSLOWSTARTRETRANS);
+                                               mib_idx = LINUX_MIB_TCPSLOWSTARTRETRANS;
+                                       NET_INC_STATS_BH(sock_net(sk), mib_idx);
 
                                        if (skb == tcp_write_queue_head(sk))
                                                inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
@@ -2065,7 +2064,7 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
                                                  inet_csk(sk)->icsk_rto,
                                                  TCP_RTO_MAX);
 
-               NET_INC_STATS_BH(LINUX_MIB_TCPFORWARDRETRANS);
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPFORWARDRETRANS);
        }
 }
 
@@ -2119,7 +2118,7 @@ void tcp_send_active_reset(struct sock *sk, gfp_t priority)
        /* NOTE: No TCP options attached and we never retransmit this. */
        skb = alloc_skb(MAX_TCP_HEADER, priority);
        if (!skb) {
-               NET_INC_STATS(LINUX_MIB_TCPABORTFAILED);
+               NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTFAILED);
                return;
        }
 
@@ -2130,9 +2129,9 @@ void tcp_send_active_reset(struct sock *sk, gfp_t priority)
        /* Send it off. */
        TCP_SKB_CB(skb)->when = tcp_time_stamp;
        if (tcp_transmit_skb(sk, skb, 0, priority))
-               NET_INC_STATS(LINUX_MIB_TCPABORTFAILED);
+               NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTFAILED);
 
-       TCP_INC_STATS(TCP_MIB_OUTRSTS);
+       TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTRSTS);
 }
 
 /* WARNING: This routine must only be called when we have already sent
@@ -2258,16 +2257,13 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
                              );
 
        th->doff = (tcp_header_size >> 2);
-       TCP_INC_STATS(TCP_MIB_OUTSEGS);
+       TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS);
 
 #ifdef CONFIG_TCP_MD5SIG
        /* Okay, we have all we need - do the md5 hash if needed */
        if (md5) {
                tp->af_specific->calc_md5_hash(md5_hash_location,
-                                              md5,
-                                              NULL, dst, req,
-                                              tcp_hdr(skb), sk->sk_protocol,
-                                              skb->len);
+                                              md5, NULL, req, skb);
        }
 #endif
 
@@ -2367,7 +2363,7 @@ int tcp_connect(struct sock *sk)
         */
        tp->snd_nxt = tp->write_seq;
        tp->pushed_seq = tp->write_seq;
-       TCP_INC_STATS(TCP_MIB_ACTIVEOPENS);
+       TCP_INC_STATS(sock_net(sk), TCP_MIB_ACTIVEOPENS);
 
        /* Timer for repeating the SYN until an answer. */
        inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
This page took 0.026733 seconds and 5 git commands to generate.