aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/output.c')
-rw-r--r--net/sctp/output.c135
1 files changed, 108 insertions, 27 deletions
diff --git a/net/sctp/output.c b/net/sctp/output.c
index d85543def754..847639d542c0 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -79,7 +79,10 @@ struct sctp_packet *sctp_packet_config(struct sctp_packet *packet,
79 packet->vtag = vtag; 79 packet->vtag = vtag;
80 packet->has_cookie_echo = 0; 80 packet->has_cookie_echo = 0;
81 packet->has_sack = 0; 81 packet->has_sack = 0;
82 packet->has_auth = 0;
83 packet->has_data = 0;
82 packet->ipfragok = 0; 84 packet->ipfragok = 0;
85 packet->auth = NULL;
83 86
84 if (ecn_capable && sctp_packet_empty(packet)) { 87 if (ecn_capable && sctp_packet_empty(packet)) {
85 chunk = sctp_get_ecne_prepend(packet->transport->asoc); 88 chunk = sctp_get_ecne_prepend(packet->transport->asoc);
@@ -121,8 +124,11 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
121 packet->vtag = 0; 124 packet->vtag = 0;
122 packet->has_cookie_echo = 0; 125 packet->has_cookie_echo = 0;
123 packet->has_sack = 0; 126 packet->has_sack = 0;
127 packet->has_auth = 0;
128 packet->has_data = 0;
124 packet->ipfragok = 0; 129 packet->ipfragok = 0;
125 packet->malloced = 0; 130 packet->malloced = 0;
131 packet->auth = NULL;
126 return packet; 132 return packet;
127} 133}
128 134
@@ -181,6 +187,39 @@ sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet,
181 return retval; 187 return retval;
182} 188}
183 189
190/* Try to bundle an auth chunk into the packet. */
191static sctp_xmit_t sctp_packet_bundle_auth(struct sctp_packet *pkt,
192 struct sctp_chunk *chunk)
193{
194 struct sctp_association *asoc = pkt->transport->asoc;
195 struct sctp_chunk *auth;
196 sctp_xmit_t retval = SCTP_XMIT_OK;
197
198 /* if we don't have an association, we can't do authentication */
199 if (!asoc)
200 return retval;
201
202 /* See if this is an auth chunk we are bundling or if
203 * auth is already bundled.
204 */
205 if (chunk->chunk_hdr->type == SCTP_CID_AUTH || pkt->auth)
206 return retval;
207
208 /* if the peer did not request this chunk to be authenticated,
209 * don't do it
210 */
211 if (!chunk->auth)
212 return retval;
213
214 auth = sctp_make_auth(asoc);
215 if (!auth)
216 return retval;
217
218 retval = sctp_packet_append_chunk(pkt, auth);
219
220 return retval;
221}
222
184/* Try to bundle a SACK with the packet. */ 223/* Try to bundle a SACK with the packet. */
185static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt, 224static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt,
186 struct sctp_chunk *chunk) 225 struct sctp_chunk *chunk)
@@ -227,12 +266,17 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
227 SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __FUNCTION__, packet, 266 SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __FUNCTION__, packet,
228 chunk); 267 chunk);
229 268
230 retval = sctp_packet_bundle_sack(packet, chunk); 269 /* Try to bundle AUTH chunk */
231 psize = packet->size; 270 retval = sctp_packet_bundle_auth(packet, chunk);
271 if (retval != SCTP_XMIT_OK)
272 goto finish;
232 273
274 /* Try to bundle SACK chunk */
275 retval = sctp_packet_bundle_sack(packet, chunk);
233 if (retval != SCTP_XMIT_OK) 276 if (retval != SCTP_XMIT_OK)
234 goto finish; 277 goto finish;
235 278
279 psize = packet->size;
236 pmtu = ((packet->transport->asoc) ? 280 pmtu = ((packet->transport->asoc) ?
237 (packet->transport->asoc->pathmtu) : 281 (packet->transport->asoc->pathmtu) :
238 (packet->transport->pathmtu)); 282 (packet->transport->pathmtu));
@@ -241,10 +285,16 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
241 285
242 /* Decide if we need to fragment or resubmit later. */ 286 /* Decide if we need to fragment or resubmit later. */
243 if (too_big) { 287 if (too_big) {
244 /* Both control chunks and data chunks with TSNs are 288 /* It's OK to fragmet at IP level if any one of the following
245 * non-fragmentable. 289 * is true:
290 * 1. The packet is empty (meaning this chunk is greater
291 * the MTU)
292 * 2. The chunk we are adding is a control chunk
293 * 3. The packet doesn't have any data in it yet and data
294 * requires authentication.
246 */ 295 */
247 if (sctp_packet_empty(packet) || !sctp_chunk_is_data(chunk)) { 296 if (sctp_packet_empty(packet) || !sctp_chunk_is_data(chunk) ||
297 (!packet->has_data && chunk->auth)) {
248 /* We no longer do re-fragmentation. 298 /* We no longer do re-fragmentation.
249 * Just fragment at the IP layer, if we 299 * Just fragment at the IP layer, if we
250 * actually hit this condition 300 * actually hit this condition
@@ -266,16 +316,31 @@ append:
266 /* DATA is a special case since we must examine both rwnd and cwnd 316 /* DATA is a special case since we must examine both rwnd and cwnd
267 * before we send DATA. 317 * before we send DATA.
268 */ 318 */
269 if (sctp_chunk_is_data(chunk)) { 319 switch (chunk->chunk_hdr->type) {
320 case SCTP_CID_DATA:
270 retval = sctp_packet_append_data(packet, chunk); 321 retval = sctp_packet_append_data(packet, chunk);
271 /* Disallow SACK bundling after DATA. */ 322 /* Disallow SACK bundling after DATA. */
272 packet->has_sack = 1; 323 packet->has_sack = 1;
324 /* Disallow AUTH bundling after DATA */
325 packet->has_auth = 1;
326 /* Let it be knows that packet has DATA in it */
327 packet->has_data = 1;
273 if (SCTP_XMIT_OK != retval) 328 if (SCTP_XMIT_OK != retval)
274 goto finish; 329 goto finish;
275 } else if (SCTP_CID_COOKIE_ECHO == chunk->chunk_hdr->type) 330 break;
331 case SCTP_CID_COOKIE_ECHO:
276 packet->has_cookie_echo = 1; 332 packet->has_cookie_echo = 1;
277 else if (SCTP_CID_SACK == chunk->chunk_hdr->type) 333 break;
334
335 case SCTP_CID_SACK:
278 packet->has_sack = 1; 336 packet->has_sack = 1;
337 break;
338
339 case SCTP_CID_AUTH:
340 packet->has_auth = 1;
341 packet->auth = chunk;
342 break;
343 }
279 344
280 /* It is OK to send this chunk. */ 345 /* It is OK to send this chunk. */
281 list_add_tail(&chunk->list, &packet->chunk_list); 346 list_add_tail(&chunk->list, &packet->chunk_list);
@@ -303,6 +368,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
303 int padding; /* How much padding do we need? */ 368 int padding; /* How much padding do we need? */
304 __u8 has_data = 0; 369 __u8 has_data = 0;
305 struct dst_entry *dst = tp->dst; 370 struct dst_entry *dst = tp->dst;
371 unsigned char *auth = NULL; /* pointer to auth in skb data */
372 __u32 cksum_buf_len = sizeof(struct sctphdr);
306 373
307 SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet); 374 SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet);
308 375
@@ -356,16 +423,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
356 sh->vtag = htonl(packet->vtag); 423 sh->vtag = htonl(packet->vtag);
357 sh->checksum = 0; 424 sh->checksum = 0;
358 425
359 /* 2) Calculate the Adler-32 checksum of the whole packet,
360 * including the SCTP common header and all the
361 * chunks.
362 *
363 * Note: Adler-32 is no longer applicable, as has been replaced
364 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
365 */
366 if (!(dst->dev->features & NETIF_F_NO_CSUM))
367 crc32 = sctp_start_cksum((__u8 *)sh, sizeof(struct sctphdr));
368
369 /** 426 /**
370 * 6.10 Bundling 427 * 6.10 Bundling
371 * 428 *
@@ -416,14 +473,16 @@ int sctp_packet_transmit(struct sctp_packet *packet)
416 if (padding) 473 if (padding)
417 memset(skb_put(chunk->skb, padding), 0, padding); 474 memset(skb_put(chunk->skb, padding), 0, padding);
418 475
419 if (dst->dev->features & NETIF_F_NO_CSUM) 476 /* if this is the auth chunk that we are adding,
420 memcpy(skb_put(nskb, chunk->skb->len), 477 * store pointer where it will be added and put
478 * the auth into the packet.
479 */
480 if (chunk == packet->auth)
481 auth = skb_tail_pointer(nskb);
482
483 cksum_buf_len += chunk->skb->len;
484 memcpy(skb_put(nskb, chunk->skb->len),
421 chunk->skb->data, chunk->skb->len); 485 chunk->skb->data, chunk->skb->len);
422 else
423 crc32 = sctp_update_copy_cksum(skb_put(nskb,
424 chunk->skb->len),
425 chunk->skb->data,
426 chunk->skb->len, crc32);
427 486
428 SCTP_DEBUG_PRINTK("%s %p[%s] %s 0x%x, %s %d, %s %d, %s %d\n", 487 SCTP_DEBUG_PRINTK("%s %p[%s] %s 0x%x, %s %d, %s %d, %s %d\n",
429 "*** Chunk", chunk, 488 "*** Chunk", chunk,
@@ -445,9 +504,31 @@ int sctp_packet_transmit(struct sctp_packet *packet)
445 sctp_chunk_free(chunk); 504 sctp_chunk_free(chunk);
446 } 505 }
447 506
448 /* Perform final transformation on checksum. */ 507 /* SCTP-AUTH, Section 6.2
449 if (!(dst->dev->features & NETIF_F_NO_CSUM)) 508 * The sender MUST calculate the MAC as described in RFC2104 [2]
509 * using the hash function H as described by the MAC Identifier and
510 * the shared association key K based on the endpoint pair shared key
511 * described by the shared key identifier. The 'data' used for the
512 * computation of the AUTH-chunk is given by the AUTH chunk with its
513 * HMAC field set to zero (as shown in Figure 6) followed by all
514 * chunks that are placed after the AUTH chunk in the SCTP packet.
515 */
516 if (auth)
517 sctp_auth_calculate_hmac(asoc, nskb,
518 (struct sctp_auth_chunk *)auth,
519 GFP_ATOMIC);
520
521 /* 2) Calculate the Adler-32 checksum of the whole packet,
522 * including the SCTP common header and all the
523 * chunks.
524 *
525 * Note: Adler-32 is no longer applicable, as has been replaced
526 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
527 */
528 if (!(dst->dev->features & NETIF_F_NO_CSUM)) {
529 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
450 crc32 = sctp_end_cksum(crc32); 530 crc32 = sctp_end_cksum(crc32);
531 }
451 532
452 /* 3) Put the resultant value into the checksum field in the 533 /* 3) Put the resultant value into the checksum field in the
453 * common header, and leave the rest of the bits unchanged. 534 * common header, and leave the rest of the bits unchanged.