lec: Fix bug introduced by b67bfe0d42cac56c512dd5da4b1b347a23f4b70a
[firefly-linux-kernel-4.4.55.git] / net / sctp / output.c
index 01ab8e0723f04ea845ba81045228786ef07c97ad..42dffd4283898f718630c76cf6dece316492966f 100644 (file)
@@ -178,7 +178,7 @@ sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet,
 
        case SCTP_XMIT_RWND_FULL:
        case SCTP_XMIT_OK:
-       case SCTP_XMIT_NAGLE_DELAY:
+       case SCTP_XMIT_DELAY:
                break;
        }
 
@@ -599,7 +599,7 @@ out:
        return err;
 no_route:
        kfree_skb(nskb);
-       IP_INC_STATS_BH(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES);
+       IP_INC_STATS(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES);
 
        /* FIXME: Returning the 'err' will effect all the associations
         * associated with a socket, although only one of the paths of the
@@ -633,7 +633,6 @@ nomem:
 static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
                                           struct sctp_chunk *chunk)
 {
-       sctp_xmit_t retval = SCTP_XMIT_OK;
        size_t datasize, rwnd, inflight, flight_size;
        struct sctp_transport *transport = packet->transport;
        struct sctp_association *asoc = transport->asoc;
@@ -658,15 +657,11 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
 
        datasize = sctp_data_size(chunk);
 
-       if (datasize > rwnd) {
-               if (inflight > 0) {
-                       /* We have (at least) one data chunk in flight,
-                        * so we can't fall back to rule 6.1 B).
-                        */
-                       retval = SCTP_XMIT_RWND_FULL;
-                       goto finish;
-               }
-       }
+       if (datasize > rwnd && inflight > 0)
+               /* We have (at least) one data chunk in flight,
+                * so we can't fall back to rule 6.1 B).
+                */
+               return SCTP_XMIT_RWND_FULL;
 
        /* RFC 2960 6.1  Transmission of DATA Chunks
         *
@@ -680,36 +675,44 @@ static sctp_xmit_t sctp_packet_can_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 != SCTP_NEED_FRTX)
-               if (flight_size >= transport->cwnd) {
-                       retval = SCTP_XMIT_RWND_FULL;
-                       goto finish;
-               }
+       if (chunk->fast_retransmit != SCTP_NEED_FRTX &&
+           flight_size >= transport->cwnd)
+               return SCTP_XMIT_RWND_FULL;
 
        /* Nagle's algorithm to solve small-packet problem:
         * Inhibit the sending of new chunks when new outgoing data arrives
         * if any previously transmitted data on the connection remains
         * unacknowledged.
         */
-       if (!sctp_sk(asoc->base.sk)->nodelay && sctp_packet_empty(packet) &&
-           inflight && sctp_state(asoc, ESTABLISHED)) {
-               unsigned int max = transport->pathmtu - packet->overhead;
-               unsigned int len = chunk->skb->len + q->out_qlen;
-
-               /* Check whether this chunk and all the rest of pending
-                * data will fit or delay in hopes of bundling a full
-                * sized packet.
-                * Don't delay large message writes that may have been
-                * fragmeneted into small peices.
-                */
-               if ((len < max) && chunk->msg->can_delay) {
-                       retval = SCTP_XMIT_NAGLE_DELAY;
-                       goto finish;
-               }
-       }
 
-finish:
-       return retval;
+       if (sctp_sk(asoc->base.sk)->nodelay)
+               /* Nagle disabled */
+               return SCTP_XMIT_OK;
+
+       if (!sctp_packet_empty(packet))
+               /* Append to packet */
+               return SCTP_XMIT_OK;
+
+       if (inflight == 0)
+               /* Nothing unacked */
+               return SCTP_XMIT_OK;
+
+       if (!sctp_state(asoc, ESTABLISHED))
+               return SCTP_XMIT_OK;
+
+       /* Check whether this chunk and all the rest of pending data will fit
+        * or delay in hopes of bundling a full sized packet.
+        */
+       if (chunk->skb->len + q->out_qlen >= transport->pathmtu - packet->overhead)
+               /* Enough data queued to fill a packet */
+               return SCTP_XMIT_OK;
+
+       /* Don't delay large message writes that may have been fragmented */
+       if (!chunk->msg->can_delay)
+               return SCTP_XMIT_OK;
+
+       /* Defer until all data acked or packet full */
+       return SCTP_XMIT_DELAY;
 }
 
 /* This private function does management things when adding DATA chunk */