diff options
| author | Xin Long <lucien.xin@gmail.com> | 2016-10-31 12:49:41 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2016-11-02 15:03:13 -0400 |
| commit | e4ff952a7e11e51789949ed738c3c9455e5fd6c0 (patch) | |
| tree | 89b6b808602a3c6942321a814d6292947a2ddae1 /net/sctp/output.c | |
| parent | 92901827538f87bd7e1ec41a7a1c3ebe22bb78f5 (diff) | |
sctp: clean up sctp_packet_transmit
After adding sctp gso, sctp_packet_transmit is a quite big function now.
This patch is to extract the codes for packing packet to sctp_packet_pack
from sctp_packet_transmit, and add some comments, simplify the err path by
freeing auth chunk when freeing packet chunk_list in out path and freeing
head skb early if it fails to pack packet.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/output.c')
| -rw-r--r-- | net/sctp/output.c | 435 |
1 files changed, 158 insertions, 277 deletions
diff --git a/net/sctp/output.c b/net/sctp/output.c index 7b50e4307485..f5320a87341e 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
| @@ -399,187 +399,72 @@ static void sctp_packet_set_owner_w(struct sk_buff *skb, struct sock *sk) | |||
| 399 | atomic_inc(&sk->sk_wmem_alloc); | 399 | atomic_inc(&sk->sk_wmem_alloc); |
| 400 | } | 400 | } |
| 401 | 401 | ||
| 402 | /* All packets are sent to the network through this function from | 402 | static int sctp_packet_pack(struct sctp_packet *packet, |
| 403 | * sctp_outq_tail(). | 403 | struct sk_buff *head, int gso, gfp_t gfp) |
| 404 | * | ||
| 405 | * The return value is a normal kernel error return value. | ||
| 406 | */ | ||
| 407 | int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp) | ||
| 408 | { | 404 | { |
| 409 | struct sctp_transport *tp = packet->transport; | 405 | struct sctp_transport *tp = packet->transport; |
| 410 | struct sctp_association *asoc = tp->asoc; | 406 | struct sctp_auth_chunk *auth = NULL; |
| 411 | struct sctphdr *sh; | ||
| 412 | struct sk_buff *nskb = NULL, *head = NULL; | ||
| 413 | struct sctp_chunk *chunk, *tmp; | 407 | struct sctp_chunk *chunk, *tmp; |
| 414 | struct sock *sk; | 408 | int pkt_count = 0, pkt_size; |
| 415 | int err = 0; | 409 | struct sock *sk = head->sk; |
| 416 | int padding; /* How much padding do we need? */ | 410 | struct sk_buff *nskb; |
| 417 | int pkt_size; | ||
| 418 | __u8 has_data = 0; | ||
| 419 | int gso = 0; | ||
| 420 | int pktcount = 0; | ||
| 421 | int auth_len = 0; | 411 | int auth_len = 0; |
| 422 | struct dst_entry *dst; | ||
| 423 | unsigned char *auth = NULL; /* pointer to auth in skb data */ | ||
| 424 | |||
| 425 | pr_debug("%s: packet:%p\n", __func__, packet); | ||
| 426 | 412 | ||
| 427 | /* Do NOT generate a chunkless packet. */ | ||
| 428 | if (list_empty(&packet->chunk_list)) | ||
| 429 | return err; | ||
| 430 | |||
| 431 | /* Set up convenience variables... */ | ||
| 432 | chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list); | ||
| 433 | sk = chunk->skb->sk; | ||
| 434 | |||
| 435 | /* Allocate the head skb, or main one if not in GSO */ | ||
| 436 | if (packet->size > tp->pathmtu && !packet->ipfragok) { | ||
| 437 | if (sk_can_gso(sk)) { | ||
| 438 | gso = 1; | ||
| 439 | pkt_size = packet->overhead; | ||
| 440 | } else { | ||
| 441 | /* If this happens, we trash this packet and try | ||
| 442 | * to build a new one, hopefully correct this | ||
| 443 | * time. Application may notice this error. | ||
| 444 | */ | ||
| 445 | pr_err_once("Trying to GSO but underlying device doesn't support it."); | ||
| 446 | goto err; | ||
| 447 | } | ||
| 448 | } else { | ||
| 449 | pkt_size = packet->size; | ||
| 450 | } | ||
| 451 | head = alloc_skb(pkt_size + MAX_HEADER, gfp); | ||
| 452 | if (!head) | ||
| 453 | goto err; | ||
| 454 | if (gso) { | 413 | if (gso) { |
| 455 | NAPI_GRO_CB(head)->last = head; | ||
| 456 | skb_shinfo(head)->gso_type = sk->sk_gso_type; | 414 | skb_shinfo(head)->gso_type = sk->sk_gso_type; |
| 415 | NAPI_GRO_CB(head)->last = head; | ||
| 416 | } else { | ||
| 417 | nskb = head; | ||
| 418 | pkt_size = packet->size; | ||
| 419 | goto merge; | ||
| 457 | } | 420 | } |
| 458 | 421 | ||
| 459 | /* Make sure the outbound skb has enough header room reserved. */ | ||
| 460 | skb_reserve(head, packet->overhead + MAX_HEADER); | ||
| 461 | |||
| 462 | /* Set the owning socket so that we know where to get the | ||
| 463 | * destination IP address. | ||
| 464 | */ | ||
| 465 | sctp_packet_set_owner_w(head, sk); | ||
| 466 | |||
| 467 | if (!sctp_transport_dst_check(tp)) { | ||
| 468 | sctp_transport_route(tp, NULL, sctp_sk(sk)); | ||
| 469 | if (asoc && (asoc->param_flags & SPP_PMTUD_ENABLE)) { | ||
| 470 | sctp_assoc_sync_pmtu(sk, asoc); | ||
| 471 | } | ||
| 472 | } | ||
| 473 | dst = dst_clone(tp->dst); | ||
| 474 | if (!dst) { | ||
| 475 | if (asoc) | ||
| 476 | IP_INC_STATS(sock_net(asoc->base.sk), | ||
| 477 | IPSTATS_MIB_OUTNOROUTES); | ||
| 478 | goto nodst; | ||
| 479 | } | ||
| 480 | skb_dst_set(head, dst); | ||
| 481 | |||
| 482 | /* Build the SCTP header. */ | ||
| 483 | sh = (struct sctphdr *)skb_push(head, sizeof(struct sctphdr)); | ||
| 484 | skb_reset_transport_header(head); | ||
| 485 | sh->source = htons(packet->source_port); | ||
| 486 | sh->dest = htons(packet->destination_port); | ||
| 487 | |||
| 488 | /* From 6.8 Adler-32 Checksum Calculation: | ||
| 489 | * After the packet is constructed (containing the SCTP common | ||
| 490 | * header and one or more control or DATA chunks), the | ||
| 491 | * transmitter shall: | ||
| 492 | * | ||
| 493 | * 1) Fill in the proper Verification Tag in the SCTP common | ||
| 494 | * header and initialize the checksum field to 0's. | ||
| 495 | */ | ||
| 496 | sh->vtag = htonl(packet->vtag); | ||
| 497 | sh->checksum = 0; | ||
| 498 | |||
| 499 | pr_debug("***sctp_transmit_packet***\n"); | ||
| 500 | |||
| 501 | do { | 422 | do { |
| 502 | /* Set up convenience variables... */ | 423 | /* calculate the pkt_size and alloc nskb */ |
| 503 | chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list); | 424 | pkt_size = packet->overhead; |
| 504 | pktcount++; | 425 | list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, |
| 505 | 426 | list) { | |
| 506 | /* Calculate packet size, so it fits in PMTU. Leave | 427 | int padded = SCTP_PAD4(chunk->skb->len); |
| 507 | * other chunks for the next packets. | ||
| 508 | */ | ||
| 509 | if (gso) { | ||
| 510 | pkt_size = packet->overhead; | ||
| 511 | list_for_each_entry(chunk, &packet->chunk_list, list) { | ||
| 512 | int padded = SCTP_PAD4(chunk->skb->len); | ||
| 513 | |||
| 514 | if (chunk == packet->auth) | ||
| 515 | auth_len = padded; | ||
| 516 | else if (auth_len + padded + packet->overhead > | ||
| 517 | tp->pathmtu) | ||
| 518 | goto nomem; | ||
| 519 | else if (pkt_size + padded > tp->pathmtu) | ||
| 520 | break; | ||
| 521 | pkt_size += padded; | ||
| 522 | } | ||
| 523 | |||
| 524 | /* Allocate a new skb. */ | ||
| 525 | nskb = alloc_skb(pkt_size + MAX_HEADER, gfp); | ||
| 526 | if (!nskb) | ||
| 527 | goto nomem; | ||
| 528 | 428 | ||
| 529 | /* Make sure the outbound skb has enough header | 429 | if (chunk == packet->auth) |
| 530 | * room reserved. | 430 | auth_len = padded; |
| 531 | */ | 431 | else if (auth_len + padded + packet->overhead > |
| 532 | skb_reserve(nskb, packet->overhead + MAX_HEADER); | 432 | tp->pathmtu) |
| 533 | } else { | 433 | return 0; |
| 534 | nskb = head; | 434 | else if (pkt_size + padded > tp->pathmtu) |
| 435 | break; | ||
| 436 | pkt_size += padded; | ||
| 535 | } | 437 | } |
| 438 | nskb = alloc_skb(pkt_size + MAX_HEADER, gfp); | ||
| 439 | if (!nskb) | ||
| 440 | return 0; | ||
| 441 | skb_reserve(nskb, packet->overhead + MAX_HEADER); | ||
| 536 | 442 | ||
| 537 | /** | 443 | merge: |
| 538 | * 3.2 Chunk Field Descriptions | 444 | /* merge chunks into nskb and append nskb into head list */ |
| 539 | * | ||
| 540 | * The total length of a chunk (including Type, Length and | ||
| 541 | * Value fields) MUST be a multiple of 4 bytes. If the length | ||
| 542 | * of the chunk is not a multiple of 4 bytes, the sender MUST | ||
| 543 | * pad the chunk with all zero bytes and this padding is not | ||
| 544 | * included in the chunk length field. The sender should | ||
| 545 | * never pad with more than 3 bytes. | ||
| 546 | * | ||
| 547 | * [This whole comment explains SCTP_PAD4() below.] | ||
| 548 | */ | ||
| 549 | |||
| 550 | pkt_size -= packet->overhead; | 445 | pkt_size -= packet->overhead; |
| 551 | list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { | 446 | list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { |
| 447 | int padding; | ||
| 448 | |||
| 552 | list_del_init(&chunk->list); | 449 | list_del_init(&chunk->list); |
| 553 | if (sctp_chunk_is_data(chunk)) { | 450 | if (sctp_chunk_is_data(chunk)) { |
| 554 | /* 6.3.1 C4) When data is in flight and when allowed | ||
| 555 | * by rule C5, a new RTT measurement MUST be made each | ||
| 556 | * round trip. Furthermore, new RTT measurements | ||
| 557 | * SHOULD be made no more than once per round-trip | ||
| 558 | * for a given destination transport address. | ||
| 559 | */ | ||
| 560 | |||
| 561 | if (!sctp_chunk_retransmitted(chunk) && | 451 | if (!sctp_chunk_retransmitted(chunk) && |
| 562 | !tp->rto_pending) { | 452 | !tp->rto_pending) { |
| 563 | chunk->rtt_in_progress = 1; | 453 | chunk->rtt_in_progress = 1; |
| 564 | tp->rto_pending = 1; | 454 | tp->rto_pending = 1; |
| 565 | } | 455 | } |
| 566 | |||
| 567 | has_data = 1; | ||
| 568 | } | 456 | } |
| 569 | 457 | ||
| 570 | padding = SCTP_PAD4(chunk->skb->len) - chunk->skb->len; | 458 | padding = SCTP_PAD4(chunk->skb->len) - chunk->skb->len; |
| 571 | if (padding) | 459 | if (padding) |
| 572 | memset(skb_put(chunk->skb, padding), 0, padding); | 460 | memset(skb_put(chunk->skb, padding), 0, padding); |
| 573 | 461 | ||
| 574 | /* if this is the auth chunk that we are adding, | ||
| 575 | * store pointer where it will be added and put | ||
| 576 | * the auth into the packet. | ||
| 577 | */ | ||
| 578 | if (chunk == packet->auth) | 462 | if (chunk == packet->auth) |
| 579 | auth = skb_tail_pointer(nskb); | 463 | auth = (struct sctp_auth_chunk *) |
| 464 | skb_tail_pointer(nskb); | ||
| 580 | 465 | ||
| 581 | memcpy(skb_put(nskb, chunk->skb->len), | 466 | memcpy(skb_put(nskb, chunk->skb->len), chunk->skb->data, |
| 582 | chunk->skb->data, chunk->skb->len); | 467 | chunk->skb->len); |
| 583 | 468 | ||
| 584 | pr_debug("*** Chunk:%p[%s] %s 0x%x, length:%d, chunk->skb->len:%d, rtt_in_progress:%d\n", | 469 | pr_debug("*** Chunk:%p[%s] %s 0x%x, length:%d, chunk->skb->len:%d, rtt_in_progress:%d\n", |
| 585 | chunk, | 470 | chunk, |
| @@ -589,11 +474,6 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp) | |||
| 589 | ntohs(chunk->chunk_hdr->length), chunk->skb->len, | 474 | ntohs(chunk->chunk_hdr->length), chunk->skb->len, |
| 590 | chunk->rtt_in_progress); | 475 | chunk->rtt_in_progress); |
| 591 | 476 | ||
| 592 | /* If this is a control chunk, this is our last | ||
| 593 | * reference. Free data chunks after they've been | ||
| 594 | * acknowledged or have failed. | ||
| 595 | * Re-queue auth chunks if needed. | ||
| 596 | */ | ||
| 597 | pkt_size -= SCTP_PAD4(chunk->skb->len); | 477 | pkt_size -= SCTP_PAD4(chunk->skb->len); |
| 598 | 478 | ||
| 599 | if (!sctp_chunk_is_data(chunk) && chunk != packet->auth) | 479 | if (!sctp_chunk_is_data(chunk) && chunk != packet->auth) |
| @@ -603,160 +483,161 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp) | |||
| 603 | break; | 483 | break; |
| 604 | } | 484 | } |
| 605 | 485 | ||
| 606 | /* SCTP-AUTH, Section 6.2 | 486 | if (auth) { |
| 607 | * The sender MUST calculate the MAC as described in RFC2104 [2] | 487 | sctp_auth_calculate_hmac(tp->asoc, nskb, auth, gfp); |
| 608 | * using the hash function H as described by the MAC Identifier and | 488 | /* free auth if no more chunks, or add it back */ |
| 609 | * the shared association key K based on the endpoint pair shared key | 489 | if (list_empty(&packet->chunk_list)) |
| 610 | * described by the shared key identifier. The 'data' used for the | 490 | sctp_chunk_free(packet->auth); |
| 611 | * computation of the AUTH-chunk is given by the AUTH chunk with its | 491 | else |
| 612 | * HMAC field set to zero (as shown in Figure 6) followed by all | ||
| 613 | * chunks that are placed after the AUTH chunk in the SCTP packet. | ||
| 614 | */ | ||
| 615 | if (auth) | ||
| 616 | sctp_auth_calculate_hmac(asoc, nskb, | ||
| 617 | (struct sctp_auth_chunk *)auth, | ||
| 618 | gfp); | ||
| 619 | |||
| 620 | if (packet->auth) { | ||
| 621 | if (!list_empty(&packet->chunk_list)) { | ||
| 622 | /* We will generate more packets, so re-queue | ||
| 623 | * auth chunk. | ||
| 624 | */ | ||
| 625 | list_add(&packet->auth->list, | 492 | list_add(&packet->auth->list, |
| 626 | &packet->chunk_list); | 493 | &packet->chunk_list); |
| 627 | } else { | ||
| 628 | sctp_chunk_free(packet->auth); | ||
| 629 | packet->auth = NULL; | ||
| 630 | } | ||
| 631 | } | 494 | } |
| 632 | 495 | ||
| 633 | if (!gso) | 496 | if (gso) { |
| 634 | break; | 497 | if (skb_gro_receive(&head, nskb)) { |
| 635 | 498 | kfree_skb(nskb); | |
| 636 | if (skb_gro_receive(&head, nskb)) { | 499 | return 0; |
| 637 | kfree_skb(nskb); | 500 | } |
| 638 | goto nomem; | 501 | if (WARN_ON_ONCE(skb_shinfo(head)->gso_segs >= |
| 502 | sk->sk_gso_max_segs)) | ||
| 503 | return 0; | ||
| 639 | } | 504 | } |
| 640 | nskb = NULL; | 505 | |
| 641 | if (WARN_ON_ONCE(skb_shinfo(head)->gso_segs >= | 506 | pkt_count++; |
| 642 | sk->sk_gso_max_segs)) | ||
| 643 | goto nomem; | ||
| 644 | } while (!list_empty(&packet->chunk_list)); | 507 | } while (!list_empty(&packet->chunk_list)); |
| 645 | 508 | ||
| 646 | /* 2) Calculate the Adler-32 checksum of the whole packet, | 509 | if (gso) { |
| 647 | * including the SCTP common header and all the | 510 | memset(head->cb, 0, max(sizeof(struct inet_skb_parm), |
| 648 | * chunks. | 511 | sizeof(struct inet6_skb_parm))); |
| 649 | * | 512 | skb_shinfo(head)->gso_segs = pkt_count; |
| 650 | * Note: Adler-32 is no longer applicable, as has been replaced | 513 | skb_shinfo(head)->gso_size = GSO_BY_FRAGS; |
| 651 | * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. | 514 | rcu_read_lock(); |
| 652 | * | 515 | if (skb_dst(head) != tp->dst) { |
| 653 | * If it's a GSO packet, it's postponed to sctp_skb_segment. | 516 | dst_hold(tp->dst); |
| 654 | */ | 517 | sk_setup_caps(sk, tp->dst); |
| 655 | if (!sctp_checksum_disable || gso) { | ||
| 656 | if (!gso && (!(dst->dev->features & NETIF_F_SCTP_CRC) || | ||
| 657 | dst_xfrm(dst) || packet->ipfragok)) { | ||
| 658 | sh->checksum = sctp_compute_cksum(head, 0); | ||
| 659 | } else { | ||
| 660 | /* no need to seed pseudo checksum for SCTP */ | ||
| 661 | head->ip_summed = CHECKSUM_PARTIAL; | ||
| 662 | head->csum_start = skb_transport_header(head) - head->head; | ||
| 663 | head->csum_offset = offsetof(struct sctphdr, checksum); | ||
| 664 | } | 518 | } |
| 519 | rcu_read_unlock(); | ||
| 520 | goto chksum; | ||
| 665 | } | 521 | } |
| 666 | 522 | ||
| 667 | /* IP layer ECN support | 523 | if (sctp_checksum_disable) |
| 668 | * From RFC 2481 | 524 | return 1; |
| 669 | * "The ECN-Capable Transport (ECT) bit would be set by the | ||
| 670 | * data sender to indicate that the end-points of the | ||
| 671 | * transport protocol are ECN-capable." | ||
| 672 | * | ||
| 673 | * Now setting the ECT bit all the time, as it should not cause | ||
| 674 | * any problems protocol-wise even if our peer ignores it. | ||
| 675 | * | ||
| 676 | * Note: The works for IPv6 layer checks this bit too later | ||
| 677 | * in transmission. See IP6_ECN_flow_xmit(). | ||
| 678 | */ | ||
| 679 | tp->af_specific->ecn_capable(sk); | ||
| 680 | 525 | ||
| 681 | /* Set up the IP options. */ | 526 | if (!(skb_dst(head)->dev->features & NETIF_F_SCTP_CRC) || |
| 682 | /* BUG: not implemented | 527 | dst_xfrm(skb_dst(head)) || packet->ipfragok) { |
| 683 | * For v4 this all lives somewhere in sk->sk_opt... | 528 | struct sctphdr *sh = |
| 684 | */ | 529 | (struct sctphdr *)skb_transport_header(head); |
| 685 | 530 | ||
| 686 | /* Dump that on IP! */ | 531 | sh->checksum = sctp_compute_cksum(head, 0); |
| 687 | if (asoc) { | 532 | } else { |
| 688 | asoc->stats.opackets += pktcount; | 533 | chksum: |
| 689 | if (asoc->peer.last_sent_to != tp) | 534 | head->ip_summed = CHECKSUM_PARTIAL; |
| 690 | /* Considering the multiple CPU scenario, this is a | 535 | head->csum_start = skb_transport_header(head) - head->head; |
| 691 | * "correcter" place for last_sent_to. --xguo | 536 | head->csum_offset = offsetof(struct sctphdr, checksum); |
| 692 | */ | ||
| 693 | asoc->peer.last_sent_to = tp; | ||
| 694 | } | 537 | } |
| 695 | 538 | ||
| 696 | if (has_data) { | 539 | return pkt_count; |
| 697 | struct timer_list *timer; | 540 | } |
| 698 | unsigned long timeout; | 541 | |
| 542 | /* All packets are sent to the network through this function from | ||
| 543 | * sctp_outq_tail(). | ||
| 544 | * | ||
| 545 | * The return value is always 0 for now. | ||
| 546 | */ | ||
| 547 | int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp) | ||
| 548 | { | ||
| 549 | struct sctp_transport *tp = packet->transport; | ||
| 550 | struct sctp_association *asoc = tp->asoc; | ||
| 551 | struct sctp_chunk *chunk, *tmp; | ||
| 552 | int pkt_count, gso = 0; | ||
| 553 | struct dst_entry *dst; | ||
| 554 | struct sk_buff *head; | ||
| 555 | struct sctphdr *sh; | ||
| 556 | struct sock *sk; | ||
| 699 | 557 | ||
| 700 | /* Restart the AUTOCLOSE timer when sending data. */ | 558 | pr_debug("%s: packet:%p\n", __func__, packet); |
| 701 | if (sctp_state(asoc, ESTABLISHED) && | 559 | if (list_empty(&packet->chunk_list)) |
| 702 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) { | 560 | return 0; |
| 703 | timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; | 561 | chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list); |
| 704 | timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; | 562 | sk = chunk->skb->sk; |
| 705 | 563 | ||
| 706 | if (!mod_timer(timer, jiffies + timeout)) | 564 | /* check gso */ |
| 707 | sctp_association_hold(asoc); | 565 | if (packet->size > tp->pathmtu && !packet->ipfragok) { |
| 566 | if (!sk_can_gso(sk)) { | ||
| 567 | pr_err_once("Trying to GSO but underlying device doesn't support it."); | ||
| 568 | goto out; | ||
| 708 | } | 569 | } |
| 570 | gso = 1; | ||
| 571 | } | ||
| 572 | |||
| 573 | /* alloc head skb */ | ||
| 574 | head = alloc_skb((gso ? packet->overhead : packet->size) + | ||
| 575 | MAX_HEADER, gfp); | ||
| 576 | if (!head) | ||
| 577 | goto out; | ||
| 578 | skb_reserve(head, packet->overhead + MAX_HEADER); | ||
| 579 | sctp_packet_set_owner_w(head, sk); | ||
| 580 | |||
| 581 | /* set sctp header */ | ||
| 582 | sh = (struct sctphdr *)skb_push(head, sizeof(struct sctphdr)); | ||
| 583 | skb_reset_transport_header(head); | ||
| 584 | sh->source = htons(packet->source_port); | ||
| 585 | sh->dest = htons(packet->destination_port); | ||
| 586 | sh->vtag = htonl(packet->vtag); | ||
| 587 | sh->checksum = 0; | ||
| 588 | |||
| 589 | /* update dst if in need */ | ||
| 590 | if (!sctp_transport_dst_check(tp)) { | ||
| 591 | sctp_transport_route(tp, NULL, sctp_sk(sk)); | ||
| 592 | if (asoc && asoc->param_flags & SPP_PMTUD_ENABLE) | ||
| 593 | sctp_assoc_sync_pmtu(sk, asoc); | ||
| 709 | } | 594 | } |
| 595 | dst = dst_clone(tp->dst); | ||
| 596 | if (!dst) { | ||
| 597 | IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); | ||
| 598 | kfree_skb(head); | ||
| 599 | goto out; | ||
| 600 | } | ||
| 601 | skb_dst_set(head, dst); | ||
| 710 | 602 | ||
| 603 | /* pack up chunks */ | ||
| 604 | pkt_count = sctp_packet_pack(packet, head, gso, gfp); | ||
| 605 | if (!pkt_count) { | ||
| 606 | kfree_skb(head); | ||
| 607 | goto out; | ||
| 608 | } | ||
| 711 | pr_debug("***sctp_transmit_packet*** skb->len:%d\n", head->len); | 609 | pr_debug("***sctp_transmit_packet*** skb->len:%d\n", head->len); |
| 712 | 610 | ||
| 713 | if (gso) { | 611 | /* start autoclose timer */ |
| 714 | /* Cleanup our debris for IP stacks */ | 612 | if (packet->has_data && sctp_state(asoc, ESTABLISHED) && |
| 715 | memset(head->cb, 0, max(sizeof(struct inet_skb_parm), | 613 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) { |
| 716 | sizeof(struct inet6_skb_parm))); | 614 | struct timer_list *timer = |
| 615 | &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; | ||
| 616 | unsigned long timeout = | ||
| 617 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; | ||
| 717 | 618 | ||
| 718 | skb_shinfo(head)->gso_segs = pktcount; | 619 | if (!mod_timer(timer, jiffies + timeout)) |
| 719 | skb_shinfo(head)->gso_size = GSO_BY_FRAGS; | 620 | sctp_association_hold(asoc); |
| 621 | } | ||
| 720 | 622 | ||
| 721 | /* We have to refresh this in case we are xmiting to | 623 | /* sctp xmit */ |
| 722 | * more than one transport at a time | 624 | tp->af_specific->ecn_capable(sk); |
| 723 | */ | 625 | if (asoc) { |
| 724 | rcu_read_lock(); | 626 | asoc->stats.opackets += pkt_count; |
| 725 | if (__sk_dst_get(sk) != tp->dst) { | 627 | if (asoc->peer.last_sent_to != tp) |
| 726 | dst_hold(tp->dst); | 628 | asoc->peer.last_sent_to = tp; |
| 727 | sk_setup_caps(sk, tp->dst); | ||
| 728 | } | ||
| 729 | rcu_read_unlock(); | ||
| 730 | } | 629 | } |
| 731 | head->ignore_df = packet->ipfragok; | 630 | head->ignore_df = packet->ipfragok; |
| 732 | tp->af_specific->sctp_xmit(head, tp); | 631 | tp->af_specific->sctp_xmit(head, tp); |
| 733 | goto out; | ||
| 734 | |||
| 735 | nomem: | ||
| 736 | if (packet->auth && list_empty(&packet->auth->list)) | ||
| 737 | sctp_chunk_free(packet->auth); | ||
| 738 | |||
| 739 | nodst: | ||
| 740 | /* FIXME: Returning the 'err' will effect all the associations | ||
| 741 | * associated with a socket, although only one of the paths of the | ||
| 742 | * association is unreachable. | ||
| 743 | * The real failure of a transport or association can be passed on | ||
| 744 | * to the user via notifications. So setting this error may not be | ||
| 745 | * required. | ||
| 746 | */ | ||
| 747 | /* err = -EHOSTUNREACH; */ | ||
| 748 | kfree_skb(head); | ||
| 749 | 632 | ||
| 750 | err: | 633 | out: |
| 751 | list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { | 634 | list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { |
| 752 | list_del_init(&chunk->list); | 635 | list_del_init(&chunk->list); |
| 753 | if (!sctp_chunk_is_data(chunk)) | 636 | if (!sctp_chunk_is_data(chunk)) |
| 754 | sctp_chunk_free(chunk); | 637 | sctp_chunk_free(chunk); |
| 755 | } | 638 | } |
| 756 | |||
| 757 | out: | ||
| 758 | sctp_packet_reset(packet); | 639 | sctp_packet_reset(packet); |
| 759 | return err; | 640 | return 0; |
| 760 | } | 641 | } |
| 761 | 642 | ||
| 762 | /******************************************************************** | 643 | /******************************************************************** |
