diff options
Diffstat (limited to 'net/sctp/associola.c')
-rw-r--r-- | net/sctp/associola.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 8472b8b349c4..f4b23043b610 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -283,8 +283,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
283 | if (!sctp_ulpq_init(&asoc->ulpq, asoc)) | 283 | if (!sctp_ulpq_init(&asoc->ulpq, asoc)) |
284 | goto fail_init; | 284 | goto fail_init; |
285 | 285 | ||
286 | /* Set up the tsn tracking. */ | 286 | memset(&asoc->peer.tsn_map, 0, sizeof(struct sctp_tsnmap)); |
287 | sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE, 0); | ||
288 | 287 | ||
289 | asoc->need_ecne = 0; | 288 | asoc->need_ecne = 0; |
290 | 289 | ||
@@ -402,6 +401,8 @@ void sctp_association_free(struct sctp_association *asoc) | |||
402 | /* Dispose of any pending chunks on the inqueue. */ | 401 | /* Dispose of any pending chunks on the inqueue. */ |
403 | sctp_inq_free(&asoc->base.inqueue); | 402 | sctp_inq_free(&asoc->base.inqueue); |
404 | 403 | ||
404 | sctp_tsnmap_free(&asoc->peer.tsn_map); | ||
405 | |||
405 | /* Free ssnmap storage. */ | 406 | /* Free ssnmap storage. */ |
406 | sctp_ssnmap_free(asoc->ssnmap); | 407 | sctp_ssnmap_free(asoc->ssnmap); |
407 | 408 | ||
@@ -599,11 +600,12 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, | |||
599 | /* Check to see if this is a duplicate. */ | 600 | /* Check to see if this is a duplicate. */ |
600 | peer = sctp_assoc_lookup_paddr(asoc, addr); | 601 | peer = sctp_assoc_lookup_paddr(asoc, addr); |
601 | if (peer) { | 602 | if (peer) { |
603 | /* An UNKNOWN state is only set on transports added by | ||
604 | * user in sctp_connectx() call. Such transports should be | ||
605 | * considered CONFIRMED per RFC 4960, Section 5.4. | ||
606 | */ | ||
602 | if (peer->state == SCTP_UNKNOWN) { | 607 | if (peer->state == SCTP_UNKNOWN) { |
603 | if (peer_state == SCTP_ACTIVE) | 608 | peer->state = SCTP_ACTIVE; |
604 | peer->state = SCTP_ACTIVE; | ||
605 | if (peer_state == SCTP_UNCONFIRMED) | ||
606 | peer->state = SCTP_UNCONFIRMED; | ||
607 | } | 609 | } |
608 | return peer; | 610 | return peer; |
609 | } | 611 | } |
@@ -1121,8 +1123,8 @@ void sctp_assoc_update(struct sctp_association *asoc, | |||
1121 | asoc->peer.rwnd = new->peer.rwnd; | 1123 | asoc->peer.rwnd = new->peer.rwnd; |
1122 | asoc->peer.sack_needed = new->peer.sack_needed; | 1124 | asoc->peer.sack_needed = new->peer.sack_needed; |
1123 | asoc->peer.i = new->peer.i; | 1125 | asoc->peer.i = new->peer.i; |
1124 | sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE, | 1126 | sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL, |
1125 | asoc->peer.i.initial_tsn); | 1127 | asoc->peer.i.initial_tsn, GFP_ATOMIC); |
1126 | 1128 | ||
1127 | /* Remove any peer addresses not present in the new association. */ | 1129 | /* Remove any peer addresses not present in the new association. */ |
1128 | list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { | 1130 | list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { |