diff options
Diffstat (limited to 'net/sctp')
| -rw-r--r-- | net/sctp/diag.c | 1 | ||||
| -rw-r--r-- | net/sctp/ipv6.c | 8 | ||||
| -rw-r--r-- | net/sctp/offload.c | 1 | ||||
| -rw-r--r-- | net/sctp/protocol.c | 7 | ||||
| -rw-r--r-- | net/sctp/sm_make_chunk.c | 11 | ||||
| -rw-r--r-- | net/sctp/socket.c | 4 | ||||
| -rw-r--r-- | net/sctp/stream.c | 82 | ||||
| -rw-r--r-- | net/sctp/transport.c | 3 |
8 files changed, 68 insertions, 49 deletions
diff --git a/net/sctp/diag.c b/net/sctp/diag.c index 078f01a8d582..435847d98b51 100644 --- a/net/sctp/diag.c +++ b/net/sctp/diag.c | |||
| @@ -256,6 +256,7 @@ static size_t inet_assoc_attr_size(struct sctp_association *asoc) | |||
| 256 | + nla_total_size(1) /* INET_DIAG_TOS */ | 256 | + nla_total_size(1) /* INET_DIAG_TOS */ |
| 257 | + nla_total_size(1) /* INET_DIAG_TCLASS */ | 257 | + nla_total_size(1) /* INET_DIAG_TCLASS */ |
| 258 | + nla_total_size(4) /* INET_DIAG_MARK */ | 258 | + nla_total_size(4) /* INET_DIAG_MARK */ |
| 259 | + nla_total_size(4) /* INET_DIAG_CLASS_ID */ | ||
| 259 | + nla_total_size(addrlen * asoc->peer.transport_count) | 260 | + nla_total_size(addrlen * asoc->peer.transport_count) |
| 260 | + nla_total_size(addrlen * addrcnt) | 261 | + nla_total_size(addrlen * addrcnt) |
| 261 | + nla_total_size(sizeof(struct inet_diag_meminfo)) | 262 | + nla_total_size(sizeof(struct inet_diag_meminfo)) |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index b9ed271b7ef7..6200cd2b4b99 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
| @@ -97,11 +97,9 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev, | |||
| 97 | 97 | ||
| 98 | switch (ev) { | 98 | switch (ev) { |
| 99 | case NETDEV_UP: | 99 | case NETDEV_UP: |
| 100 | addr = kmalloc(sizeof(struct sctp_sockaddr_entry), GFP_ATOMIC); | 100 | addr = kzalloc(sizeof(*addr), GFP_ATOMIC); |
| 101 | if (addr) { | 101 | if (addr) { |
| 102 | addr->a.v6.sin6_family = AF_INET6; | 102 | addr->a.v6.sin6_family = AF_INET6; |
| 103 | addr->a.v6.sin6_port = 0; | ||
| 104 | addr->a.v6.sin6_flowinfo = 0; | ||
| 105 | addr->a.v6.sin6_addr = ifa->addr; | 103 | addr->a.v6.sin6_addr = ifa->addr; |
| 106 | addr->a.v6.sin6_scope_id = ifa->idev->dev->ifindex; | 104 | addr->a.v6.sin6_scope_id = ifa->idev->dev->ifindex; |
| 107 | addr->valid = 1; | 105 | addr->valid = 1; |
| @@ -282,7 +280,8 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, | |||
| 282 | 280 | ||
| 283 | if (saddr) { | 281 | if (saddr) { |
| 284 | fl6->saddr = saddr->v6.sin6_addr; | 282 | fl6->saddr = saddr->v6.sin6_addr; |
| 285 | fl6->fl6_sport = saddr->v6.sin6_port; | 283 | if (!fl6->fl6_sport) |
| 284 | fl6->fl6_sport = saddr->v6.sin6_port; | ||
| 286 | 285 | ||
| 287 | pr_debug("src=%pI6 - ", &fl6->saddr); | 286 | pr_debug("src=%pI6 - ", &fl6->saddr); |
| 288 | } | 287 | } |
| @@ -434,7 +433,6 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist, | |||
| 434 | addr = kzalloc(sizeof(*addr), GFP_ATOMIC); | 433 | addr = kzalloc(sizeof(*addr), GFP_ATOMIC); |
| 435 | if (addr) { | 434 | if (addr) { |
| 436 | addr->a.v6.sin6_family = AF_INET6; | 435 | addr->a.v6.sin6_family = AF_INET6; |
| 437 | addr->a.v6.sin6_port = 0; | ||
| 438 | addr->a.v6.sin6_addr = ifp->addr; | 436 | addr->a.v6.sin6_addr = ifp->addr; |
| 439 | addr->a.v6.sin6_scope_id = dev->ifindex; | 437 | addr->a.v6.sin6_scope_id = dev->ifindex; |
| 440 | addr->valid = 1; | 438 | addr->valid = 1; |
diff --git a/net/sctp/offload.c b/net/sctp/offload.c index 123e9f2dc226..edfcf16e704c 100644 --- a/net/sctp/offload.c +++ b/net/sctp/offload.c | |||
| @@ -36,6 +36,7 @@ static __le32 sctp_gso_make_checksum(struct sk_buff *skb) | |||
| 36 | { | 36 | { |
| 37 | skb->ip_summed = CHECKSUM_NONE; | 37 | skb->ip_summed = CHECKSUM_NONE; |
| 38 | skb->csum_not_inet = 0; | 38 | skb->csum_not_inet = 0; |
| 39 | gso_reset_checksum(skb, ~0); | ||
| 39 | return sctp_compute_cksum(skb, skb_transport_offset(skb)); | 40 | return sctp_compute_cksum(skb, skb_transport_offset(skb)); |
| 40 | } | 41 | } |
| 41 | 42 | ||
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index d5878ae55840..6abc8b274270 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
| @@ -101,7 +101,6 @@ static void sctp_v4_copy_addrlist(struct list_head *addrlist, | |||
| 101 | addr = kzalloc(sizeof(*addr), GFP_ATOMIC); | 101 | addr = kzalloc(sizeof(*addr), GFP_ATOMIC); |
| 102 | if (addr) { | 102 | if (addr) { |
| 103 | addr->a.v4.sin_family = AF_INET; | 103 | addr->a.v4.sin_family = AF_INET; |
| 104 | addr->a.v4.sin_port = 0; | ||
| 105 | addr->a.v4.sin_addr.s_addr = ifa->ifa_local; | 104 | addr->a.v4.sin_addr.s_addr = ifa->ifa_local; |
| 106 | addr->valid = 1; | 105 | addr->valid = 1; |
| 107 | INIT_LIST_HEAD(&addr->list); | 106 | INIT_LIST_HEAD(&addr->list); |
| @@ -441,7 +440,8 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr, | |||
| 441 | } | 440 | } |
| 442 | if (saddr) { | 441 | if (saddr) { |
| 443 | fl4->saddr = saddr->v4.sin_addr.s_addr; | 442 | fl4->saddr = saddr->v4.sin_addr.s_addr; |
| 444 | fl4->fl4_sport = saddr->v4.sin_port; | 443 | if (!fl4->fl4_sport) |
| 444 | fl4->fl4_sport = saddr->v4.sin_port; | ||
| 445 | } | 445 | } |
| 446 | 446 | ||
| 447 | pr_debug("%s: dst:%pI4, src:%pI4 - ", __func__, &fl4->daddr, | 447 | pr_debug("%s: dst:%pI4, src:%pI4 - ", __func__, &fl4->daddr, |
| @@ -776,10 +776,9 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev, | |||
| 776 | 776 | ||
| 777 | switch (ev) { | 777 | switch (ev) { |
| 778 | case NETDEV_UP: | 778 | case NETDEV_UP: |
| 779 | addr = kmalloc(sizeof(struct sctp_sockaddr_entry), GFP_ATOMIC); | 779 | addr = kzalloc(sizeof(*addr), GFP_ATOMIC); |
| 780 | if (addr) { | 780 | if (addr) { |
| 781 | addr->a.v4.sin_family = AF_INET; | 781 | addr->a.v4.sin_family = AF_INET; |
| 782 | addr->a.v4.sin_port = 0; | ||
| 783 | addr->a.v4.sin_addr.s_addr = ifa->ifa_local; | 782 | addr->a.v4.sin_addr.s_addr = ifa->ifa_local; |
| 784 | addr->valid = 1; | 783 | addr->valid = 1; |
| 785 | spin_lock_bh(&net->sctp.local_addr_lock); | 784 | spin_lock_bh(&net->sctp.local_addr_lock); |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index f4ac6c592e13..d05c57664e36 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
| @@ -495,7 +495,10 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, | |||
| 495 | * | 495 | * |
| 496 | * [INIT ACK back to where the INIT came from.] | 496 | * [INIT ACK back to where the INIT came from.] |
| 497 | */ | 497 | */ |
| 498 | retval->transport = chunk->transport; | 498 | if (chunk->transport) |
| 499 | retval->transport = | ||
| 500 | sctp_assoc_lookup_paddr(asoc, | ||
| 501 | &chunk->transport->ipaddr); | ||
| 499 | 502 | ||
| 500 | retval->subh.init_hdr = | 503 | retval->subh.init_hdr = |
| 501 | sctp_addto_chunk(retval, sizeof(initack), &initack); | 504 | sctp_addto_chunk(retval, sizeof(initack), &initack); |
| @@ -642,8 +645,10 @@ struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *asoc, | |||
| 642 | * | 645 | * |
| 643 | * [COOKIE ACK back to where the COOKIE ECHO came from.] | 646 | * [COOKIE ACK back to where the COOKIE ECHO came from.] |
| 644 | */ | 647 | */ |
| 645 | if (retval && chunk) | 648 | if (retval && chunk && chunk->transport) |
| 646 | retval->transport = chunk->transport; | 649 | retval->transport = |
| 650 | sctp_assoc_lookup_paddr(asoc, | ||
| 651 | &chunk->transport->ipaddr); | ||
| 647 | 652 | ||
| 648 | return retval; | 653 | return retval; |
| 649 | } | 654 | } |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index f93c3cf9e567..65d6d04546ae 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -2027,7 +2027,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len) | |||
| 2027 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; | 2027 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
| 2028 | struct sctp_transport *transport = NULL; | 2028 | struct sctp_transport *transport = NULL; |
| 2029 | struct sctp_sndrcvinfo _sinfo, *sinfo; | 2029 | struct sctp_sndrcvinfo _sinfo, *sinfo; |
| 2030 | struct sctp_association *asoc; | 2030 | struct sctp_association *asoc, *tmp; |
| 2031 | struct sctp_cmsgs cmsgs; | 2031 | struct sctp_cmsgs cmsgs; |
| 2032 | union sctp_addr *daddr; | 2032 | union sctp_addr *daddr; |
| 2033 | bool new = false; | 2033 | bool new = false; |
| @@ -2053,7 +2053,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len) | |||
| 2053 | 2053 | ||
| 2054 | /* SCTP_SENDALL process */ | 2054 | /* SCTP_SENDALL process */ |
| 2055 | if ((sflags & SCTP_SENDALL) && sctp_style(sk, UDP)) { | 2055 | if ((sflags & SCTP_SENDALL) && sctp_style(sk, UDP)) { |
| 2056 | list_for_each_entry(asoc, &ep->asocs, asocs) { | 2056 | list_for_each_entry_safe(asoc, tmp, &ep->asocs, asocs) { |
| 2057 | err = sctp_sendmsg_check_sflags(asoc, sflags, msg, | 2057 | err = sctp_sendmsg_check_sflags(asoc, sflags, msg, |
| 2058 | msg_len); | 2058 | msg_len); |
| 2059 | if (err == 0) | 2059 | if (err == 0) |
diff --git a/net/sctp/stream.c b/net/sctp/stream.c index 3892e7630f3a..2936ed17bf9e 100644 --- a/net/sctp/stream.c +++ b/net/sctp/stream.c | |||
| @@ -84,6 +84,19 @@ static void fa_zero(struct flex_array *fa, size_t index, size_t count) | |||
| 84 | } | 84 | } |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | static size_t fa_index(struct flex_array *fa, void *elem, size_t count) | ||
| 88 | { | ||
| 89 | size_t index = 0; | ||
| 90 | |||
| 91 | while (count--) { | ||
| 92 | if (elem == flex_array_get(fa, index)) | ||
| 93 | break; | ||
| 94 | index++; | ||
| 95 | } | ||
| 96 | |||
| 97 | return index; | ||
| 98 | } | ||
| 99 | |||
| 87 | /* Migrates chunks from stream queues to new stream queues if needed, | 100 | /* Migrates chunks from stream queues to new stream queues if needed, |
| 88 | * but not across associations. Also, removes those chunks to streams | 101 | * but not across associations. Also, removes those chunks to streams |
| 89 | * higher than the new max. | 102 | * higher than the new max. |
| @@ -131,8 +144,10 @@ static void sctp_stream_outq_migrate(struct sctp_stream *stream, | |||
| 131 | } | 144 | } |
| 132 | } | 145 | } |
| 133 | 146 | ||
| 134 | for (i = outcnt; i < stream->outcnt; i++) | 147 | for (i = outcnt; i < stream->outcnt; i++) { |
| 135 | kfree(SCTP_SO(stream, i)->ext); | 148 | kfree(SCTP_SO(stream, i)->ext); |
| 149 | SCTP_SO(stream, i)->ext = NULL; | ||
| 150 | } | ||
| 136 | } | 151 | } |
| 137 | 152 | ||
| 138 | static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt, | 153 | static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt, |
| @@ -147,6 +162,13 @@ static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt, | |||
| 147 | 162 | ||
| 148 | if (stream->out) { | 163 | if (stream->out) { |
| 149 | fa_copy(out, stream->out, 0, min(outcnt, stream->outcnt)); | 164 | fa_copy(out, stream->out, 0, min(outcnt, stream->outcnt)); |
| 165 | if (stream->out_curr) { | ||
| 166 | size_t index = fa_index(stream->out, stream->out_curr, | ||
| 167 | stream->outcnt); | ||
| 168 | |||
| 169 | BUG_ON(index == stream->outcnt); | ||
| 170 | stream->out_curr = flex_array_get(out, index); | ||
| 171 | } | ||
| 150 | fa_free(stream->out); | 172 | fa_free(stream->out); |
| 151 | } | 173 | } |
| 152 | 174 | ||
| @@ -585,9 +607,9 @@ struct sctp_chunk *sctp_process_strreset_outreq( | |||
| 585 | struct sctp_strreset_outreq *outreq = param.v; | 607 | struct sctp_strreset_outreq *outreq = param.v; |
| 586 | struct sctp_stream *stream = &asoc->stream; | 608 | struct sctp_stream *stream = &asoc->stream; |
| 587 | __u32 result = SCTP_STRRESET_DENIED; | 609 | __u32 result = SCTP_STRRESET_DENIED; |
| 588 | __u16 i, nums, flags = 0; | ||
| 589 | __be16 *str_p = NULL; | 610 | __be16 *str_p = NULL; |
| 590 | __u32 request_seq; | 611 | __u32 request_seq; |
| 612 | __u16 i, nums; | ||
| 591 | 613 | ||
| 592 | request_seq = ntohl(outreq->request_seq); | 614 | request_seq = ntohl(outreq->request_seq); |
| 593 | 615 | ||
| @@ -615,6 +637,15 @@ struct sctp_chunk *sctp_process_strreset_outreq( | |||
| 615 | if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_STREAM_REQ)) | 637 | if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_STREAM_REQ)) |
| 616 | goto out; | 638 | goto out; |
| 617 | 639 | ||
| 640 | nums = (ntohs(param.p->length) - sizeof(*outreq)) / sizeof(__u16); | ||
| 641 | str_p = outreq->list_of_streams; | ||
| 642 | for (i = 0; i < nums; i++) { | ||
| 643 | if (ntohs(str_p[i]) >= stream->incnt) { | ||
| 644 | result = SCTP_STRRESET_ERR_WRONG_SSN; | ||
| 645 | goto out; | ||
| 646 | } | ||
| 647 | } | ||
| 648 | |||
| 618 | if (asoc->strreset_chunk) { | 649 | if (asoc->strreset_chunk) { |
| 619 | if (!sctp_chunk_lookup_strreset_param( | 650 | if (!sctp_chunk_lookup_strreset_param( |
| 620 | asoc, outreq->response_seq, | 651 | asoc, outreq->response_seq, |
| @@ -637,32 +668,19 @@ struct sctp_chunk *sctp_process_strreset_outreq( | |||
| 637 | sctp_chunk_put(asoc->strreset_chunk); | 668 | sctp_chunk_put(asoc->strreset_chunk); |
| 638 | asoc->strreset_chunk = NULL; | 669 | asoc->strreset_chunk = NULL; |
| 639 | } | 670 | } |
| 640 | |||
| 641 | flags = SCTP_STREAM_RESET_INCOMING_SSN; | ||
| 642 | } | 671 | } |
| 643 | 672 | ||
| 644 | nums = (ntohs(param.p->length) - sizeof(*outreq)) / sizeof(__u16); | 673 | if (nums) |
| 645 | if (nums) { | ||
| 646 | str_p = outreq->list_of_streams; | ||
| 647 | for (i = 0; i < nums; i++) { | ||
| 648 | if (ntohs(str_p[i]) >= stream->incnt) { | ||
| 649 | result = SCTP_STRRESET_ERR_WRONG_SSN; | ||
| 650 | goto out; | ||
| 651 | } | ||
| 652 | } | ||
| 653 | |||
| 654 | for (i = 0; i < nums; i++) | 674 | for (i = 0; i < nums; i++) |
| 655 | SCTP_SI(stream, ntohs(str_p[i]))->mid = 0; | 675 | SCTP_SI(stream, ntohs(str_p[i]))->mid = 0; |
| 656 | } else { | 676 | else |
| 657 | for (i = 0; i < stream->incnt; i++) | 677 | for (i = 0; i < stream->incnt; i++) |
| 658 | SCTP_SI(stream, i)->mid = 0; | 678 | SCTP_SI(stream, i)->mid = 0; |
| 659 | } | ||
| 660 | 679 | ||
| 661 | result = SCTP_STRRESET_PERFORMED; | 680 | result = SCTP_STRRESET_PERFORMED; |
| 662 | 681 | ||
| 663 | *evp = sctp_ulpevent_make_stream_reset_event(asoc, | 682 | *evp = sctp_ulpevent_make_stream_reset_event(asoc, |
| 664 | flags | SCTP_STREAM_RESET_OUTGOING_SSN, nums, str_p, | 683 | SCTP_STREAM_RESET_INCOMING_SSN, nums, str_p, GFP_ATOMIC); |
| 665 | GFP_ATOMIC); | ||
| 666 | 684 | ||
| 667 | out: | 685 | out: |
| 668 | sctp_update_strreset_result(asoc, result); | 686 | sctp_update_strreset_result(asoc, result); |
| @@ -738,9 +756,6 @@ struct sctp_chunk *sctp_process_strreset_inreq( | |||
| 738 | 756 | ||
| 739 | result = SCTP_STRRESET_PERFORMED; | 757 | result = SCTP_STRRESET_PERFORMED; |
| 740 | 758 | ||
| 741 | *evp = sctp_ulpevent_make_stream_reset_event(asoc, | ||
| 742 | SCTP_STREAM_RESET_INCOMING_SSN, nums, str_p, GFP_ATOMIC); | ||
| 743 | |||
| 744 | out: | 759 | out: |
| 745 | sctp_update_strreset_result(asoc, result); | 760 | sctp_update_strreset_result(asoc, result); |
| 746 | err: | 761 | err: |
| @@ -873,6 +888,14 @@ struct sctp_chunk *sctp_process_strreset_addstrm_out( | |||
| 873 | if (!(asoc->strreset_enable & SCTP_ENABLE_CHANGE_ASSOC_REQ)) | 888 | if (!(asoc->strreset_enable & SCTP_ENABLE_CHANGE_ASSOC_REQ)) |
| 874 | goto out; | 889 | goto out; |
| 875 | 890 | ||
| 891 | in = ntohs(addstrm->number_of_streams); | ||
| 892 | incnt = stream->incnt + in; | ||
| 893 | if (!in || incnt > SCTP_MAX_STREAM) | ||
| 894 | goto out; | ||
| 895 | |||
| 896 | if (sctp_stream_alloc_in(stream, incnt, GFP_ATOMIC)) | ||
| 897 | goto out; | ||
| 898 | |||
| 876 | if (asoc->strreset_chunk) { | 899 | if (asoc->strreset_chunk) { |
| 877 | if (!sctp_chunk_lookup_strreset_param( | 900 | if (!sctp_chunk_lookup_strreset_param( |
| 878 | asoc, 0, SCTP_PARAM_RESET_ADD_IN_STREAMS)) { | 901 | asoc, 0, SCTP_PARAM_RESET_ADD_IN_STREAMS)) { |
| @@ -896,14 +919,6 @@ struct sctp_chunk *sctp_process_strreset_addstrm_out( | |||
| 896 | } | 919 | } |
| 897 | } | 920 | } |
| 898 | 921 | ||
| 899 | in = ntohs(addstrm->number_of_streams); | ||
| 900 | incnt = stream->incnt + in; | ||
| 901 | if (!in || incnt > SCTP_MAX_STREAM) | ||
| 902 | goto out; | ||
| 903 | |||
| 904 | if (sctp_stream_alloc_in(stream, incnt, GFP_ATOMIC)) | ||
| 905 | goto out; | ||
| 906 | |||
| 907 | stream->incnt = incnt; | 922 | stream->incnt = incnt; |
| 908 | 923 | ||
| 909 | result = SCTP_STRRESET_PERFORMED; | 924 | result = SCTP_STRRESET_PERFORMED; |
| @@ -973,9 +988,6 @@ struct sctp_chunk *sctp_process_strreset_addstrm_in( | |||
| 973 | 988 | ||
| 974 | result = SCTP_STRRESET_PERFORMED; | 989 | result = SCTP_STRRESET_PERFORMED; |
| 975 | 990 | ||
| 976 | *evp = sctp_ulpevent_make_stream_change_event(asoc, | ||
| 977 | 0, 0, ntohs(addstrm->number_of_streams), GFP_ATOMIC); | ||
| 978 | |||
| 979 | out: | 991 | out: |
| 980 | sctp_update_strreset_result(asoc, result); | 992 | sctp_update_strreset_result(asoc, result); |
| 981 | err: | 993 | err: |
| @@ -1036,10 +1048,10 @@ struct sctp_chunk *sctp_process_strreset_resp( | |||
| 1036 | sout->mid_uo = 0; | 1048 | sout->mid_uo = 0; |
| 1037 | } | 1049 | } |
| 1038 | } | 1050 | } |
| 1039 | |||
| 1040 | flags = SCTP_STREAM_RESET_OUTGOING_SSN; | ||
| 1041 | } | 1051 | } |
| 1042 | 1052 | ||
| 1053 | flags |= SCTP_STREAM_RESET_OUTGOING_SSN; | ||
| 1054 | |||
| 1043 | for (i = 0; i < stream->outcnt; i++) | 1055 | for (i = 0; i < stream->outcnt; i++) |
| 1044 | SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN; | 1056 | SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN; |
| 1045 | 1057 | ||
| @@ -1058,6 +1070,8 @@ struct sctp_chunk *sctp_process_strreset_resp( | |||
| 1058 | nums = (ntohs(inreq->param_hdr.length) - sizeof(*inreq)) / | 1070 | nums = (ntohs(inreq->param_hdr.length) - sizeof(*inreq)) / |
| 1059 | sizeof(__u16); | 1071 | sizeof(__u16); |
| 1060 | 1072 | ||
| 1073 | flags |= SCTP_STREAM_RESET_INCOMING_SSN; | ||
| 1074 | |||
| 1061 | *evp = sctp_ulpevent_make_stream_reset_event(asoc, flags, | 1075 | *evp = sctp_ulpevent_make_stream_reset_event(asoc, flags, |
| 1062 | nums, str_p, GFP_ATOMIC); | 1076 | nums, str_p, GFP_ATOMIC); |
| 1063 | } else if (req->type == SCTP_PARAM_RESET_TSN_REQUEST) { | 1077 | } else if (req->type == SCTP_PARAM_RESET_TSN_REQUEST) { |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 033696e6f74f..ad158d311ffa 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
| @@ -207,7 +207,8 @@ void sctp_transport_reset_hb_timer(struct sctp_transport *transport) | |||
| 207 | 207 | ||
| 208 | /* When a data chunk is sent, reset the heartbeat interval. */ | 208 | /* When a data chunk is sent, reset the heartbeat interval. */ |
| 209 | expires = jiffies + sctp_transport_timeout(transport); | 209 | expires = jiffies + sctp_transport_timeout(transport); |
| 210 | if (time_before(transport->hb_timer.expires, expires) && | 210 | if ((time_before(transport->hb_timer.expires, expires) || |
| 211 | !timer_pending(&transport->hb_timer)) && | ||
| 211 | !mod_timer(&transport->hb_timer, | 212 | !mod_timer(&transport->hb_timer, |
| 212 | expires + prandom_u32_max(transport->rto))) | 213 | expires + prandom_u32_max(transport->rto))) |
| 213 | sctp_transport_hold(transport); | 214 | sctp_transport_hold(transport); |
