aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_sideeffect.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/sm_sideeffect.c')
-rw-r--r--net/sctp/sm_sideeffect.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index b083312c725a..9732c797e8ed 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -664,7 +664,7 @@ static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds,
664 struct sctp_association *asoc, 664 struct sctp_association *asoc,
665 struct sctp_sackhdr *sackh) 665 struct sctp_sackhdr *sackh)
666{ 666{
667 int err; 667 int err = 0;
668 668
669 if (sctp_outq_sack(&asoc->outqueue, sackh)) { 669 if (sctp_outq_sack(&asoc->outqueue, sackh)) {
670 /* There are no more TSNs awaiting SACK. */ 670 /* There are no more TSNs awaiting SACK. */
@@ -672,11 +672,6 @@ static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds,
672 SCTP_ST_OTHER(SCTP_EVENT_NO_PENDING_TSN), 672 SCTP_ST_OTHER(SCTP_EVENT_NO_PENDING_TSN),
673 asoc->state, asoc->ep, asoc, NULL, 673 asoc->state, asoc->ep, asoc, NULL,
674 GFP_ATOMIC); 674 GFP_ATOMIC);
675 } else {
676 /* Windows may have opened, so we need
677 * to check if we have DATA to transmit
678 */
679 err = sctp_outq_flush(&asoc->outqueue, 0);
680 } 675 }
681 676
682 return err; 677 return err;
@@ -1481,8 +1476,15 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1481 break; 1476 break;
1482 1477
1483 case SCTP_CMD_DISCARD_PACKET: 1478 case SCTP_CMD_DISCARD_PACKET:
1484 /* We need to discard the whole packet. */ 1479 /* We need to discard the whole packet.
1480 * Uncork the queue since there might be
1481 * responses pending
1482 */
1485 chunk->pdiscard = 1; 1483 chunk->pdiscard = 1;
1484 if (asoc) {
1485 sctp_outq_uncork(&asoc->outqueue);
1486 local_cork = 0;
1487 }
1486 break; 1488 break;
1487 1489
1488 case SCTP_CMD_RTO_PENDING: 1490 case SCTP_CMD_RTO_PENDING:
@@ -1553,8 +1555,15 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1553 } 1555 }
1554 1556
1555out: 1557out:
1556 if (local_cork) 1558 /* If this is in response to a received chunk, wait until
1557 sctp_outq_uncork(&asoc->outqueue); 1559 * we are done with the packet to open the queue so that we don't
1560 * send multiple packets in response to a single request.
1561 */
1562 if (asoc && SCTP_EVENT_T_CHUNK == event_type && chunk) {
1563 if (chunk->end_of_packet || chunk->singleton)
1564 sctp_outq_uncork(&asoc->outqueue);
1565 } else if (local_cork)
1566 sctp_outq_uncork(&asoc->outqueue);
1558 return error; 1567 return error;
1559nomem: 1568nomem:
1560 error = -ENOMEM; 1569 error = -ENOMEM;