summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWei Yongjun <yjwei@cn.fujitsu.com>2009-11-23 23:53:56 +0300
committerVlad Yasevich <vladislav.yasevich@hp.com>2009-11-23 23:53:56 +0300
commitb93d6471748de2ce02cc24774b774deb306a57a8 (patch)
tree98c69d791297d3805d00f9d8ce2fa04dfbd63c9a
parent6dc7694f9df20f148076d82d00cb3663afb0b000 (diff)
downloadlinux-b93d6471748de2ce02cc24774b774deb306a57a8.tar.xz
sctp: implement the sender side for SACK-IMMEDIATELY extension
This patch implement the sender side for SACK-IMMEDIATELY extension. Section 4.1. Sender Side Considerations Whenever the sender of a DATA chunk can benefit from the corresponding SACK chunk being sent back without delay, the sender MAY set the I-bit in the DATA chunk header. Reasons for setting the I-bit include o The sender is in the SHUTDOWN-PENDING state. o The application requests to set the I-bit of the last DATA chunk of a user message when providing the user message to the SCTP implementation. Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
-rw-r--r--include/net/sctp/user.h1
-rw-r--r--net/sctp/chunk.c15
-rw-r--r--net/sctp/outqueue.c7
3 files changed, 22 insertions, 1 deletions
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index be2334aaf52e..50b2431405f2 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -206,6 +206,7 @@ enum sctp_sinfo_flags {
SCTP_UNORDERED = 1, /* Send/receive message unordered. */
SCTP_ADDR_OVER = 2, /* Override the primary destination. */
SCTP_ABORT=4, /* Send an ABORT message to the peer. */
+ SCTP_SACK_IMMEDIATELY = 8, /* SACK should be sent without delay */
SCTP_EOF=MSG_FIN, /* Initiate graceful shutdown process. */
};
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index acf7c4d128f7..8e4320040f05 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -263,9 +263,18 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
if (0 == i)
frag |= SCTP_DATA_FIRST_FRAG;
- if ((i == (whole - 1)) && !over)
+ if ((i == (whole - 1)) && !over) {
frag |= SCTP_DATA_LAST_FRAG;
+ /* The application requests to set the I-bit of the
+ * last DATA chunk of a user message when providing
+ * the user message to the SCTP implementation.
+ */
+ if ((sinfo->sinfo_flags & SCTP_EOF) ||
+ (sinfo->sinfo_flags & SCTP_SACK_IMMEDIATELY))
+ frag |= SCTP_DATA_SACK_IMM;
+ }
+
chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0);
if (!chunk)
@@ -297,6 +306,10 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
else
frag = SCTP_DATA_LAST_FRAG;
+ if ((sinfo->sinfo_flags & SCTP_EOF) ||
+ (sinfo->sinfo_flags & SCTP_SACK_IMMEDIATELY))
+ frag |= SCTP_DATA_SACK_IMM;
+
chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0);
if (!chunk)
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index c9f20e28521b..5732661c87d3 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -1011,6 +1011,13 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
break;
case SCTP_XMIT_OK:
+ /* The sender is in the SHUTDOWN-PENDING state,
+ * The sender MAY set the I-bit in the DATA
+ * chunk header.
+ */
+ if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING)
+ chunk->chunk_hdr->flags |= SCTP_DATA_SACK_IMM;
+
break;
default: