sctp: Allow to disable SCTP checksums via module parameter
[safe/jmp/linux-2.6] / net / sctp / output.c
index 5e811b9..2d65b7a 100644 (file)
@@ -1,19 +1,19 @@
-/* SCTP kernel reference Implementation
+/* SCTP kernel implementation
  * (C) Copyright IBM Corp. 2001, 2004
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
  *
- * This file is part of the SCTP kernel reference Implementation
+ * This file is part of the SCTP kernel implementation
  *
  * These functions handle output processing.
  *
- * The SCTP reference implementation is free software;
+ * This SCTP implementation is free software;
  * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
  *
- * The SCTP reference implementation is distributed in the hope that it
+ * This SCTP implementation is distributed in the hope that it
  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
  *                 ************************
  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@@ -50,6 +50,7 @@
 #include <linux/init.h>
 #include <net/inet_ecn.h>
 #include <net/icmp.h>
+#include <net/net_namespace.h>
 
 #ifndef TEST_FRAME
 #include <net/tcp.h>
@@ -74,7 +75,7 @@ struct sctp_packet *sctp_packet_config(struct sctp_packet *packet,
 {
        struct sctp_chunk *chunk = NULL;
 
-       SCTP_DEBUG_PRINTK("%s: packet:%p vtag:0x%x\n", __FUNCTION__,
+       SCTP_DEBUG_PRINTK("%s: packet:%p vtag:0x%x\n", __func__,
                          packet, vtag);
 
        packet->vtag = vtag;
@@ -106,7 +107,7 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
        struct sctp_association *asoc = transport->asoc;
        size_t overhead;
 
-       SCTP_DEBUG_PRINTK("%s: packet:%p transport:%p\n", __FUNCTION__,
+       SCTP_DEBUG_PRINTK("%s: packet:%p transport:%p\n", __func__,
                          packet, transport);
 
        packet->transport = transport;
@@ -138,7 +139,7 @@ void sctp_packet_free(struct sctp_packet *packet)
 {
        struct sctp_chunk *chunk, *tmp;
 
-       SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet);
+       SCTP_DEBUG_PRINTK("%s: packet:%p\n", __func__, packet);
 
        list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
                list_del_init(&chunk->list);
@@ -157,12 +158,13 @@ void sctp_packet_free(struct sctp_packet *packet)
  * packet can be sent only after receiving the COOKIE_ACK.
  */
 sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet,
-                                      struct sctp_chunk *chunk)
+                                      struct sctp_chunk *chunk,
+                                      int one_packet)
 {
        sctp_xmit_t retval;
        int error = 0;
 
-       SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __FUNCTION__,
+       SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __func__,
                          packet, chunk);
 
        switch ((retval = (sctp_packet_append_chunk(packet, chunk)))) {
@@ -175,7 +177,9 @@ sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet,
                        /* If we have an empty packet, then we can NOT ever
                         * return PMTU_FULL.
                         */
-                       retval = sctp_packet_append_chunk(packet, chunk);
+                       if (!one_packet)
+                               retval = sctp_packet_append_chunk(packet,
+                                                                 chunk);
                }
                break;
 
@@ -264,7 +268,7 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
        size_t pmtu;
        int too_big;
 
-       SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __FUNCTION__, packet,
+       SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __func__, packet,
                          chunk);
 
        /* Try to bundle AUTH chunk */
@@ -320,14 +324,16 @@ append:
        switch (chunk->chunk_hdr->type) {
            case SCTP_CID_DATA:
                retval = sctp_packet_append_data(packet, chunk);
+               if (SCTP_XMIT_OK != retval)
+                       goto finish;
                /* Disallow SACK bundling after DATA. */
                packet->has_sack = 1;
                /* Disallow AUTH bundling after DATA */
                packet->has_auth = 1;
                /* Let it be knows that packet has DATA in it */
                packet->has_data = 1;
-               if (SCTP_XMIT_OK != retval)
-                       goto finish;
+               /* timestamp the chunk for rtx purposes */
+               chunk->sent_at = jiffies;
                break;
            case SCTP_CID_COOKIE_ECHO:
                packet->has_cookie_echo = 1;
@@ -361,7 +367,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
        struct sctp_transport *tp = packet->transport;
        struct sctp_association *asoc = tp->asoc;
        struct sctphdr *sh;
-       __u32 crc32 = 0;
+       __be32 crc32 = cpu_to_be32(0);
        struct sk_buff *nskb;
        struct sctp_chunk *chunk, *tmp;
        struct sock *sk;
@@ -372,7 +378,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
        unsigned char *auth = NULL;     /* pointer to auth in skb data */
        __u32 cksum_buf_len = sizeof(struct sctphdr);
 
-       SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet);
+       SCTP_DEBUG_PRINTK("%s: packet:%p\n", __func__, packet);
 
        /* Do NOT generate a chunkless packet. */
        if (list_empty(&packet->chunk_list))
@@ -466,7 +472,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
                        } else
                                chunk->resent = 1;
 
-                       chunk->sent_at = jiffies;
                        has_data = 1;
                }
 
@@ -526,15 +531,16 @@ int sctp_packet_transmit(struct sctp_packet *packet)
         * Note: Adler-32 is no longer applicable, as has been replaced
         * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
         */
-       if (!(dst->dev->features & NETIF_F_NO_CSUM)) {
+       if (!sctp_checksum_disable && !(dst->dev->features & NETIF_F_NO_CSUM)) {
                crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
                crc32 = sctp_end_cksum(crc32);
-       }
+       } else
+               nskb->ip_summed = CHECKSUM_UNNECESSARY;
 
        /* 3) Put the resultant value into the checksum field in the
         *    common header, and leave the rest of the bits unchanged.
         */
-       sh->checksum = htonl(crc32);
+       sh->checksum = crc32;
 
        /* IP layer ECN support
         * From RFC 2481
@@ -548,7 +554,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
         * Note: The works for IPv6 layer checks this bit too later
         * in transmission.  See IP6_ECN_flow_xmit().
         */
-       INET_ECN_xmit(nskb->sk);
+       (*tp->af_specific->ecn_capable)(nskb->sk);
 
        /* Set up the IP options.  */
        /* BUG: not implemented
@@ -582,17 +588,15 @@ int sctp_packet_transmit(struct sctp_packet *packet)
        SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n",
                          nskb->len);
 
-       if (tp->param_flags & SPP_PMTUD_ENABLE)
-               (*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok);
-       else
-               (*tp->af_specific->sctp_xmit)(nskb, tp, 1);
+       nskb->local_df = packet->ipfragok;
+       (*tp->af_specific->sctp_xmit)(nskb, tp);
 
 out:
        packet->size = packet->overhead;
        return err;
 no_route:
        kfree_skb(nskb);
-       IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES);
+       IP_INC_STATS_BH(&init_net, IPSTATS_MIB_OUTNOROUTES);
 
        /* FIXME: Returning the 'err' will effect all the associations
         * associated with a socket, although only one of the paths of the
@@ -677,7 +681,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
                                  "transport: %p, cwnd: %d, "
                                  "ssthresh: %d, flight_size: %d, "
                                  "pba: %d\n",
-                                 __FUNCTION__, transport,
+                                 __func__, transport,
                                  transport->cwnd,
                                  transport->ssthresh,
                                  transport->flight_size,
@@ -696,7 +700,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
         *    When a Fast Retransmit is being performed the sender SHOULD
         *    ignore the value of cwnd and SHOULD NOT delay retransmission.
         */
-       if (chunk->fast_retransmit <= 0)
+       if (chunk->fast_retransmit != SCTP_NEED_FRTX)
                if (transport->flight_size >= transport->cwnd) {
                        retval = SCTP_XMIT_RWND_FULL;
                        goto finish;