patch-2.4.27 linux-2.4.27/net/sctp/sm_make_chunk.c
Next file: linux-2.4.27/net/sctp/sm_sideeffect.c
Previous file: linux-2.4.27/net/sctp/protocol.c
Back to the patch index
Back to the overall index
- Lines: 150
- Date:
2004-08-07 16:26:07.099447243 -0700
- Orig file:
linux-2.4.26/net/sctp/sm_make_chunk.c
- Orig date:
2004-04-14 06:05:41.000000000 -0700
diff -urN linux-2.4.26/net/sctp/sm_make_chunk.c linux-2.4.27/net/sctp/sm_make_chunk.c
@@ -6,10 +6,6 @@
*
* This file is part of the SCTP kernel reference Implementation
*
- * This file includes part of the implementation of the add-IP extension,
- * based on <draft-ietf-tsvwg-addip-sctp-02.txt> June 29, 2001,
- * for the SCTP kernel reference Implementation.
- *
* These functions work with the state functions in sctp_sm_statefuns.c
* to implement the state operations. These functions implement the
* steps which require modifying existing data structures.
@@ -89,11 +85,13 @@
* Note 2: The ECN capable field is reserved for future use of
* Explicit Congestion Notification.
*/
-static const sctp_ecn_capable_param_t ecap_param = {
- {
- SCTP_PARAM_ECN_CAPABLE,
- __constant_htons(sizeof(sctp_ecn_capable_param_t)),
- }
+static const struct sctp_paramhdr ecap_param = {
+ SCTP_PARAM_ECN_CAPABLE,
+ __constant_htons(sizeof(struct sctp_paramhdr)),
+};
+static const struct sctp_paramhdr prsctp_param = {
+ SCTP_PARAM_FWD_TSN_SUPPORT,
+ __constant_htons(sizeof(struct sctp_paramhdr)),
};
/* A helper to initialize to initialize an op error inside a
@@ -196,6 +194,8 @@
chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types);
chunksize += sizeof(ecap_param);
+ if (sctp_prsctp_enable)
+ chunksize += sizeof(prsctp_param);
chunksize += vparam_len;
/* RFC 2960 3.3.2 Initiation (INIT) (1)
@@ -232,6 +232,8 @@
sctp_addto_chunk(retval, num_types * sizeof(__u16), &types);
sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param);
+ if (sctp_prsctp_enable)
+ sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param);
nodata:
if (addrs.v)
kfree(addrs.v);
@@ -278,6 +280,10 @@
if (asoc->peer.ecn_capable)
chunksize += sizeof(ecap_param);
+ /* Tell peer that we'll do PR-SCTP only if peer advertised. */
+ if (asoc->peer.prsctp_capable)
+ chunksize += sizeof(prsctp_param);
+
/* Now allocate and fill out the chunk. */
retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize);
if (!retval)
@@ -293,6 +299,8 @@
sctp_addto_chunk(retval, cookie_len, cookie);
if (asoc->peer.ecn_capable)
sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param);
+ if (asoc->peer.prsctp_capable)
+ sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param);
/* We need to remove the const qualifier at this point. */
retval->asoc = (struct sctp_association *) asoc;
@@ -1286,6 +1294,9 @@
/* Save the raw address list length in the cookie. */
cookie->c.raw_addr_list_len = addrs_len;
+ /* Remember PR-SCTP capability. */
+ cookie->c.prsctp_capable = asoc->peer.prsctp_capable;
+
/* Set an expiration time for the cookie. */
do_gettimeofday(&cookie->c.expiration);
TIMEVAL_ADD(asoc->cookie_life, cookie->c.expiration);
@@ -1442,6 +1453,8 @@
retval->next_tsn = retval->c.initial_tsn;
retval->ctsn_ack_point = retval->next_tsn - 1;
retval->addip_serial = retval->c.initial_tsn;
+ retval->adv_peer_ack_point = retval->ctsn_ack_point;
+ retval->peer.prsctp_capable = retval->c.prsctp_capable;
/* The INIT stuff will be done by the side effects. */
return retval;
@@ -1653,6 +1666,10 @@
case SCTP_PARAM_HOST_NAME_ADDRESS:
/* Tell the peer, we won't support this param. */
return sctp_process_hn_param(asoc, param, chunk, err_chunk);
+ case SCTP_PARAM_FWD_TSN_SUPPORT:
+ if (sctp_prsctp_enable)
+ break;
+ /* Fall Through */
default:
SCTP_DEBUG_PRINTK("Unrecognized param: %d for chunk %d.\n",
ntohs(param.p->type), cid);
@@ -1956,6 +1973,12 @@
asoc->peer.ecn_capable = 1;
break;
+ case SCTP_PARAM_FWD_TSN_SUPPORT:
+ if (sctp_prsctp_enable) {
+ asoc->peer.prsctp_capable = 1;
+ break;
+ }
+ /* Fall Through */
default:
/* Any unrecognized parameters should have been caught
* and handled by sctp_verify_param() which should be
@@ -2610,3 +2633,38 @@
return retval;
}
+
+/* Make a FWD TSN chunk. */
+struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
+ __u32 new_cum_tsn, size_t nstreams,
+ struct sctp_fwdtsn_skip *skiplist)
+{
+ struct sctp_chunk *retval = NULL;
+ struct sctp_fwdtsn_chunk *ftsn_chunk;
+ struct sctp_fwdtsn_hdr ftsn_hdr;
+ struct sctp_fwdtsn_skip skip;
+ size_t hint;
+ int i;
+
+ hint = (nstreams + 1) * sizeof(__u32);
+
+ /* Maybe set the T-bit if we have no association. */
+ retval = sctp_make_chunk(asoc, SCTP_CID_FWD_TSN, 0, hint);
+
+ if (!retval)
+ return NULL;
+
+ ftsn_chunk = (struct sctp_fwdtsn_chunk *)retval->subh.fwdtsn_hdr;
+
+ ftsn_hdr.new_cum_tsn = htonl(new_cum_tsn);
+ retval->subh.fwdtsn_hdr =
+ sctp_addto_chunk(retval, sizeof(ftsn_hdr), &ftsn_hdr);
+
+ for (i = 0; i < nstreams; i++) {
+ skip.stream = skiplist[i].stream;
+ skip.ssn = skiplist[i].ssn;
+ sctp_addto_chunk(retval, sizeof(skip), &skip);
+ }
+
+ return retval;
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)