diff options
Diffstat (limited to 'net/sctp/output.c')
| -rw-r--r-- | net/sctp/output.c | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/net/sctp/output.c b/net/sctp/output.c index 437cba7260a4..cdc5a3936766 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
| @@ -295,14 +295,14 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
| 295 | struct sctp_transport *tp = packet->transport; | 295 | struct sctp_transport *tp = packet->transport; |
| 296 | struct sctp_association *asoc = tp->asoc; | 296 | struct sctp_association *asoc = tp->asoc; |
| 297 | struct sctphdr *sh; | 297 | struct sctphdr *sh; |
| 298 | __u32 crc32; | 298 | __u32 crc32 = 0; |
| 299 | struct sk_buff *nskb; | 299 | struct sk_buff *nskb; |
| 300 | struct sctp_chunk *chunk, *tmp; | 300 | struct sctp_chunk *chunk, *tmp; |
| 301 | struct sock *sk; | 301 | struct sock *sk; |
| 302 | int err = 0; | 302 | int err = 0; |
| 303 | int padding; /* How much padding do we need? */ | 303 | int padding; /* How much padding do we need? */ |
| 304 | __u8 has_data = 0; | 304 | __u8 has_data = 0; |
| 305 | struct dst_entry *dst; | 305 | struct dst_entry *dst = tp->dst; |
| 306 | 306 | ||
| 307 | SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet); | 307 | SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet); |
| 308 | 308 | ||
| @@ -327,6 +327,19 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
| 327 | */ | 327 | */ |
| 328 | skb_set_owner_w(nskb, sk); | 328 | skb_set_owner_w(nskb, sk); |
| 329 | 329 | ||
| 330 | /* The 'obsolete' field of dst is set to 2 when a dst is freed. */ | ||
| 331 | if (!dst || (dst->obsolete > 1)) { | ||
| 332 | dst_release(dst); | ||
| 333 | sctp_transport_route(tp, NULL, sctp_sk(sk)); | ||
| 334 | if (asoc && (asoc->param_flags & SPP_PMTUD_ENABLE)) { | ||
| 335 | sctp_assoc_sync_pmtu(asoc); | ||
| 336 | } | ||
| 337 | } | ||
| 338 | nskb->dst = dst_clone(tp->dst); | ||
| 339 | if (!nskb->dst) | ||
| 340 | goto no_route; | ||
| 341 | dst = nskb->dst; | ||
| 342 | |||
| 330 | /* Build the SCTP header. */ | 343 | /* Build the SCTP header. */ |
| 331 | sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr)); | 344 | sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr)); |
| 332 | sh->source = htons(packet->source_port); | 345 | sh->source = htons(packet->source_port); |
| @@ -350,7 +363,8 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
| 350 | * Note: Adler-32 is no longer applicable, as has been replaced | 363 | * Note: Adler-32 is no longer applicable, as has been replaced |
| 351 | * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. | 364 | * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. |
| 352 | */ | 365 | */ |
| 353 | crc32 = sctp_start_cksum((__u8 *)sh, sizeof(struct sctphdr)); | 366 | if (!(dst->dev->features & NETIF_F_NO_CSUM)) |
| 367 | crc32 = sctp_start_cksum((__u8 *)sh, sizeof(struct sctphdr)); | ||
| 354 | 368 | ||
| 355 | /** | 369 | /** |
| 356 | * 6.10 Bundling | 370 | * 6.10 Bundling |
| @@ -402,9 +416,14 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
| 402 | if (padding) | 416 | if (padding) |
| 403 | memset(skb_put(chunk->skb, padding), 0, padding); | 417 | memset(skb_put(chunk->skb, padding), 0, padding); |
| 404 | 418 | ||
| 405 | crc32 = sctp_update_copy_cksum(skb_put(nskb, chunk->skb->len), | 419 | if (dst->dev->features & NETIF_F_NO_CSUM) |
| 406 | chunk->skb->data, | 420 | memcpy(skb_put(nskb, chunk->skb->len), |
| 407 | chunk->skb->len, crc32); | 421 | 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); | ||
| 408 | 427 | ||
| 409 | SCTP_DEBUG_PRINTK("%s %p[%s] %s 0x%x, %s %d, %s %d, %s %d\n", | 428 | SCTP_DEBUG_PRINTK("%s %p[%s] %s 0x%x, %s %d, %s %d, %s %d\n", |
| 410 | "*** Chunk", chunk, | 429 | "*** Chunk", chunk, |
| @@ -427,7 +446,8 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
| 427 | } | 446 | } |
| 428 | 447 | ||
| 429 | /* Perform final transformation on checksum. */ | 448 | /* Perform final transformation on checksum. */ |
| 430 | crc32 = sctp_end_cksum(crc32); | 449 | if (!(dst->dev->features & NETIF_F_NO_CSUM)) |
| 450 | crc32 = sctp_end_cksum(crc32); | ||
| 431 | 451 | ||
| 432 | /* 3) Put the resultant value into the checksum field in the | 452 | /* 3) Put the resultant value into the checksum field in the |
| 433 | * common header, and leave the rest of the bits unchanged. | 453 | * common header, and leave the rest of the bits unchanged. |
| @@ -477,20 +497,6 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
| 477 | } | 497 | } |
| 478 | } | 498 | } |
| 479 | 499 | ||
| 480 | dst = tp->dst; | ||
| 481 | /* The 'obsolete' field of dst is set to 2 when a dst is freed. */ | ||
| 482 | if (!dst || (dst->obsolete > 1)) { | ||
| 483 | dst_release(dst); | ||
| 484 | sctp_transport_route(tp, NULL, sctp_sk(sk)); | ||
| 485 | if (asoc->param_flags & SPP_PMTUD_ENABLE) { | ||
| 486 | sctp_assoc_sync_pmtu(asoc); | ||
| 487 | } | ||
| 488 | } | ||
| 489 | |||
| 490 | nskb->dst = dst_clone(tp->dst); | ||
| 491 | if (!nskb->dst) | ||
| 492 | goto no_route; | ||
| 493 | |||
| 494 | SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n", | 500 | SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n", |
| 495 | nskb->len); | 501 | nskb->len); |
| 496 | 502 | ||
