diff options
Diffstat (limited to 'net/sctp/input.c')
-rw-r--r-- | net/sctp/input.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/net/sctp/input.c b/net/sctp/input.c index 80564fe03024..e64d5210ed13 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -408,10 +408,10 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, | |||
408 | 408 | ||
409 | if (t->param_flags & SPP_PMTUD_ENABLE) { | 409 | if (t->param_flags & SPP_PMTUD_ENABLE) { |
410 | /* Update transports view of the MTU */ | 410 | /* Update transports view of the MTU */ |
411 | sctp_transport_update_pmtu(t, pmtu); | 411 | sctp_transport_update_pmtu(sk, t, pmtu); |
412 | 412 | ||
413 | /* Update association pmtu. */ | 413 | /* Update association pmtu. */ |
414 | sctp_assoc_sync_pmtu(asoc); | 414 | sctp_assoc_sync_pmtu(sk, asoc); |
415 | } | 415 | } |
416 | 416 | ||
417 | /* Retransmit with the new pmtu setting. | 417 | /* Retransmit with the new pmtu setting. |
@@ -423,6 +423,18 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, | |||
423 | sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD); | 423 | sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD); |
424 | } | 424 | } |
425 | 425 | ||
426 | void sctp_icmp_redirect(struct sock *sk, struct sctp_transport *t, | ||
427 | struct sk_buff *skb) | ||
428 | { | ||
429 | struct dst_entry *dst; | ||
430 | |||
431 | if (!t) | ||
432 | return; | ||
433 | dst = sctp_transport_dst_check(t); | ||
434 | if (dst) | ||
435 | dst->ops->redirect(dst, sk, skb); | ||
436 | } | ||
437 | |||
426 | /* | 438 | /* |
427 | * SCTP Implementer's Guide, 2.37 ICMP handling procedures | 439 | * SCTP Implementer's Guide, 2.37 ICMP handling procedures |
428 | * | 440 | * |
@@ -628,6 +640,10 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
628 | 640 | ||
629 | err = EHOSTUNREACH; | 641 | err = EHOSTUNREACH; |
630 | break; | 642 | break; |
643 | case ICMP_REDIRECT: | ||
644 | sctp_icmp_redirect(sk, transport, skb); | ||
645 | err = 0; | ||
646 | break; | ||
631 | default: | 647 | default: |
632 | goto out_unlock; | 648 | goto out_unlock; |
633 | } | 649 | } |
@@ -736,15 +752,12 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep) | |||
736 | 752 | ||
737 | epb = &ep->base; | 753 | epb = &ep->base; |
738 | 754 | ||
739 | if (hlist_unhashed(&epb->node)) | ||
740 | return; | ||
741 | |||
742 | epb->hashent = sctp_ep_hashfn(epb->bind_addr.port); | 755 | epb->hashent = sctp_ep_hashfn(epb->bind_addr.port); |
743 | 756 | ||
744 | head = &sctp_ep_hashtable[epb->hashent]; | 757 | head = &sctp_ep_hashtable[epb->hashent]; |
745 | 758 | ||
746 | sctp_write_lock(&head->lock); | 759 | sctp_write_lock(&head->lock); |
747 | __hlist_del(&epb->node); | 760 | hlist_del_init(&epb->node); |
748 | sctp_write_unlock(&head->lock); | 761 | sctp_write_unlock(&head->lock); |
749 | } | 762 | } |
750 | 763 | ||
@@ -825,7 +838,7 @@ static void __sctp_unhash_established(struct sctp_association *asoc) | |||
825 | head = &sctp_assoc_hashtable[epb->hashent]; | 838 | head = &sctp_assoc_hashtable[epb->hashent]; |
826 | 839 | ||
827 | sctp_write_lock(&head->lock); | 840 | sctp_write_lock(&head->lock); |
828 | __hlist_del(&epb->node); | 841 | hlist_del_init(&epb->node); |
829 | sctp_write_unlock(&head->lock); | 842 | sctp_write_unlock(&head->lock); |
830 | } | 843 | } |
831 | 844 | ||