aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2013-01-29 04:48:30 -0500
committerJiri Kosina <jkosina@suse.cz>2013-01-29 04:48:30 -0500
commit617677295b53a40d0e54aac4cbbc216ffbc755dd (patch)
tree51b9e87213243ed5efff252c8e8d8fec4eebc588 /net/sctp
parent5c8d1b68e01a144813e38795fe6dbe7ebb506131 (diff)
parent6abb7c25775b7fb2225ad0508236d63ca710e65f (diff)
Merge branch 'master' into for-next
Conflicts: drivers/devfreq/exynos4_bus.c Sync with Linus' tree to be able to apply patches that are against newer code (mvneta).
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/Kconfig60
-rw-r--r--net/sctp/associola.c16
-rw-r--r--net/sctp/chunk.c20
-rw-r--r--net/sctp/endpointola.c5
-rw-r--r--net/sctp/inqueue.c2
-rw-r--r--net/sctp/ipv6.c2
-rw-r--r--net/sctp/output.c14
-rw-r--r--net/sctp/outqueue.c24
-rw-r--r--net/sctp/probe.c3
-rw-r--r--net/sctp/proc.c29
-rw-r--r--net/sctp/protocol.c15
-rw-r--r--net/sctp/sm_make_chunk.c24
-rw-r--r--net/sctp/sm_sideeffect.c55
-rw-r--r--net/sctp/sm_statefuns.c24
-rw-r--r--net/sctp/socket.c94
-rw-r--r--net/sctp/sysctl.c63
-rw-r--r--net/sctp/transport.c22
-rw-r--r--net/sctp/tsnmap.c8
-rw-r--r--net/sctp/ulpqueue.c3
19 files changed, 369 insertions, 114 deletions
diff --git a/net/sctp/Kconfig b/net/sctp/Kconfig
index 126b014eb79b..7521d944c0fb 100644
--- a/net/sctp/Kconfig
+++ b/net/sctp/Kconfig
@@ -9,7 +9,6 @@ menuconfig IP_SCTP
9 select CRYPTO 9 select CRYPTO
10 select CRYPTO_HMAC 10 select CRYPTO_HMAC
11 select CRYPTO_SHA1 11 select CRYPTO_SHA1
12 select CRYPTO_MD5 if SCTP_HMAC_MD5
13 select LIBCRC32C 12 select LIBCRC32C
14 ---help--- 13 ---help---
15 Stream Control Transmission Protocol 14 Stream Control Transmission Protocol
@@ -67,34 +66,45 @@ config SCTP_DBG_OBJCNT
67 'cat /proc/net/sctp/sctp_dbg_objcnt' 66 'cat /proc/net/sctp/sctp_dbg_objcnt'
68 67
69 If unsure, say N 68 If unsure, say N
70
71choice 69choice
72 prompt "SCTP: Cookie HMAC Algorithm" 70 prompt "Default SCTP cookie HMAC encoding"
73 default SCTP_HMAC_MD5 71 default SCTP_DEFAULT_COOKIE_HMAC_MD5
72 help
73 This option sets the default sctp cookie hmac algorithm
74 when in doubt select 'md5'
75
76config SCTP_DEFAULT_COOKIE_HMAC_MD5
77 bool "Enable optional MD5 hmac cookie generation"
74 help 78 help
75 HMAC algorithm to be used during association initialization. It 79 Enable optional MD5 hmac based SCTP cookie generation
76 is strongly recommended to use HMAC-SHA1 or HMAC-MD5. See 80 select SCTP_COOKIE_HMAC_MD5
77 configuration for Cryptographic API and enable those algorithms 81
78 to make usable by SCTP. 82config SCTP_DEFAULT_COOKIE_HMAC_SHA1
79 83 bool "Enable optional SHA1 hmac cookie generation"
80config SCTP_HMAC_NONE 84 help
81 bool "None" 85 Enable optional SHA1 hmac based SCTP cookie generation
82 help 86 select SCTP_COOKIE_HMAC_SHA1
83 Choosing this disables the use of an HMAC during association 87
84 establishment. It is advised to use either HMAC-MD5 or HMAC-SHA1. 88config SCTP_DEFAULT_COOKIE_HMAC_NONE
85 89 bool "Use no hmac alg in SCTP cookie generation"
86config SCTP_HMAC_SHA1
87 bool "HMAC-SHA1"
88 help
89 Enable the use of HMAC-SHA1 during association establishment. It
90 is advised to use either HMAC-MD5 or HMAC-SHA1.
91
92config SCTP_HMAC_MD5
93 bool "HMAC-MD5"
94 help 90 help
95 Enable the use of HMAC-MD5 during association establishment. It is 91 Use no hmac algorithm in SCTP cookie generation
96 advised to use either HMAC-MD5 or HMAC-SHA1.
97 92
98endchoice 93endchoice
99 94
95config SCTP_COOKIE_HMAC_MD5
96 bool "Enable optional MD5 hmac cookie generation"
97 help
98 Enable optional MD5 hmac based SCTP cookie generation
99 select CRYPTO_HMAC if SCTP_COOKIE_HMAC_MD5
100 select CRYPTO_MD5 if SCTP_COOKIE_HMAC_MD5
101
102config SCTP_COOKIE_HMAC_SHA1
103 bool "Enable optional SHA1 hmac cookie generation"
104 help
105 Enable optional SHA1 hmac based SCTP cookie generation
106 select CRYPTO_HMAC if SCTP_COOKIE_HMAC_SHA1
107 select CRYPTO_SHA1 if SCTP_COOKIE_HMAC_SHA1
108
109
100endif # IP_SCTP 110endif # IP_SCTP
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index b1ef3bc301a5..b45ed1f96921 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -321,6 +321,9 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
321 asoc->default_timetolive = sp->default_timetolive; 321 asoc->default_timetolive = sp->default_timetolive;
322 asoc->default_rcv_context = sp->default_rcv_context; 322 asoc->default_rcv_context = sp->default_rcv_context;
323 323
324 /* SCTP_GET_ASSOC_STATS COUNTERS */
325 memset(&asoc->stats, 0, sizeof(struct sctp_priv_assoc_stats));
326
324 /* AUTH related initializations */ 327 /* AUTH related initializations */
325 INIT_LIST_HEAD(&asoc->endpoint_shared_keys); 328 INIT_LIST_HEAD(&asoc->endpoint_shared_keys);
326 err = sctp_auth_asoc_copy_shkeys(ep, asoc, gfp); 329 err = sctp_auth_asoc_copy_shkeys(ep, asoc, gfp);
@@ -445,7 +448,7 @@ void sctp_association_free(struct sctp_association *asoc)
445 /* Release the transport structures. */ 448 /* Release the transport structures. */
446 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { 449 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
447 transport = list_entry(pos, struct sctp_transport, transports); 450 transport = list_entry(pos, struct sctp_transport, transports);
448 list_del(pos); 451 list_del_rcu(pos);
449 sctp_transport_free(transport); 452 sctp_transport_free(transport);
450 } 453 }
451 454
@@ -565,7 +568,7 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,
565 sctp_assoc_update_retran_path(asoc); 568 sctp_assoc_update_retran_path(asoc);
566 569
567 /* Remove this peer from the list. */ 570 /* Remove this peer from the list. */
568 list_del(&peer->transports); 571 list_del_rcu(&peer->transports);
569 572
570 /* Get the first transport of asoc. */ 573 /* Get the first transport of asoc. */
571 pos = asoc->peer.transport_addr_list.next; 574 pos = asoc->peer.transport_addr_list.next;
@@ -760,12 +763,13 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
760 763
761 /* Set the transport's RTO.initial value */ 764 /* Set the transport's RTO.initial value */
762 peer->rto = asoc->rto_initial; 765 peer->rto = asoc->rto_initial;
766 sctp_max_rto(asoc, peer);
763 767
764 /* Set the peer's active state. */ 768 /* Set the peer's active state. */
765 peer->state = peer_state; 769 peer->state = peer_state;
766 770
767 /* Attach the remote transport to our asoc. */ 771 /* Attach the remote transport to our asoc. */
768 list_add_tail(&peer->transports, &asoc->peer.transport_addr_list); 772 list_add_tail_rcu(&peer->transports, &asoc->peer.transport_addr_list);
769 asoc->peer.transport_count++; 773 asoc->peer.transport_count++;
770 774
771 /* If we do not yet have a primary path, set one. */ 775 /* If we do not yet have a primary path, set one. */
@@ -1152,8 +1156,12 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
1152 */ 1156 */
1153 if (sctp_chunk_is_data(chunk)) 1157 if (sctp_chunk_is_data(chunk))
1154 asoc->peer.last_data_from = chunk->transport; 1158 asoc->peer.last_data_from = chunk->transport;
1155 else 1159 else {
1156 SCTP_INC_STATS(net, SCTP_MIB_INCTRLCHUNKS); 1160 SCTP_INC_STATS(net, SCTP_MIB_INCTRLCHUNKS);
1161 asoc->stats.ictrlchunks++;
1162 if (chunk->chunk_hdr->type == SCTP_CID_SACK)
1163 asoc->stats.isacks++;
1164 }
1157 1165
1158 if (chunk->transport) 1166 if (chunk->transport)
1159 chunk->transport->last_time_heard = jiffies; 1167 chunk->transport->last_time_heard = jiffies;
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 7c2df9c33df3..69ce21e3716f 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -183,7 +183,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
183 183
184 msg = sctp_datamsg_new(GFP_KERNEL); 184 msg = sctp_datamsg_new(GFP_KERNEL);
185 if (!msg) 185 if (!msg)
186 return NULL; 186 return ERR_PTR(-ENOMEM);
187 187
188 /* Note: Calculate this outside of the loop, so that all fragments 188 /* Note: Calculate this outside of the loop, so that all fragments
189 * have the same expiration. 189 * have the same expiration.
@@ -280,11 +280,14 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
280 280
281 chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0); 281 chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0);
282 282
283 if (!chunk) 283 if (!chunk) {
284 err = -ENOMEM;
284 goto errout; 285 goto errout;
286 }
287
285 err = sctp_user_addto_chunk(chunk, offset, len, msgh->msg_iov); 288 err = sctp_user_addto_chunk(chunk, offset, len, msgh->msg_iov);
286 if (err < 0) 289 if (err < 0)
287 goto errout; 290 goto errout_chunk_free;
288 291
289 offset += len; 292 offset += len;
290 293
@@ -315,8 +318,10 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
315 318
316 chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0); 319 chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0);
317 320
318 if (!chunk) 321 if (!chunk) {
322 err = -ENOMEM;
319 goto errout; 323 goto errout;
324 }
320 325
321 err = sctp_user_addto_chunk(chunk, offset, over,msgh->msg_iov); 326 err = sctp_user_addto_chunk(chunk, offset, over,msgh->msg_iov);
322 327
@@ -324,7 +329,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
324 __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr 329 __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr
325 - (__u8 *)chunk->skb->data); 330 - (__u8 *)chunk->skb->data);
326 if (err < 0) 331 if (err < 0)
327 goto errout; 332 goto errout_chunk_free;
328 333
329 sctp_datamsg_assign(msg, chunk); 334 sctp_datamsg_assign(msg, chunk);
330 list_add_tail(&chunk->frag_list, &msg->chunks); 335 list_add_tail(&chunk->frag_list, &msg->chunks);
@@ -332,6 +337,9 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
332 337
333 return msg; 338 return msg;
334 339
340errout_chunk_free:
341 sctp_chunk_free(chunk);
342
335errout: 343errout:
336 list_for_each_safe(pos, temp, &msg->chunks) { 344 list_for_each_safe(pos, temp, &msg->chunks) {
337 list_del_init(pos); 345 list_del_init(pos);
@@ -339,7 +347,7 @@ errout:
339 sctp_chunk_free(chunk); 347 sctp_chunk_free(chunk);
340 } 348 }
341 sctp_datamsg_put(msg); 349 sctp_datamsg_put(msg);
342 return NULL; 350 return ERR_PTR(err);
343} 351}
344 352
345/* Check whether this message has expired. */ 353/* Check whether this message has expired. */
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index bd7e6a6a815a..17a001bac2cc 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -480,8 +480,11 @@ normal:
480 */ 480 */
481 if (asoc && sctp_chunk_is_data(chunk)) 481 if (asoc && sctp_chunk_is_data(chunk))
482 asoc->peer.last_data_from = chunk->transport; 482 asoc->peer.last_data_from = chunk->transport;
483 else 483 else {
484 SCTP_INC_STATS(sock_net(ep->base.sk), SCTP_MIB_INCTRLCHUNKS); 484 SCTP_INC_STATS(sock_net(ep->base.sk), SCTP_MIB_INCTRLCHUNKS);
485 if (asoc)
486 asoc->stats.ictrlchunks++;
487 }
485 488
486 if (chunk->transport) 489 if (chunk->transport)
487 chunk->transport->last_time_heard = jiffies; 490 chunk->transport->last_time_heard = jiffies;
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c
index 397296fb156f..2d5ad280de38 100644
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -104,6 +104,8 @@ void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *chunk)
104 * on the BH related data structures. 104 * on the BH related data structures.
105 */ 105 */
106 list_add_tail(&chunk->list, &q->in_chunk_list); 106 list_add_tail(&chunk->list, &q->in_chunk_list);
107 if (chunk->asoc)
108 chunk->asoc->stats.ipackets++;
107 q->immediate.func(&q->immediate); 109 q->immediate.func(&q->immediate);
108} 110}
109 111
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index ea14cb445295..f3f0f4dc31dd 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -345,7 +345,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
345 } 345 }
346 346
347out: 347out:
348 if (!IS_ERR(dst)) { 348 if (!IS_ERR_OR_NULL(dst)) {
349 struct rt6_info *rt; 349 struct rt6_info *rt;
350 rt = (struct rt6_info *)dst; 350 rt = (struct rt6_info *)dst;
351 t->dst = dst; 351 t->dst = dst;
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 4e90188bf489..f5200a2ad852 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -311,6 +311,8 @@ static sctp_xmit_t __sctp_packet_append_chunk(struct sctp_packet *packet,
311 311
312 case SCTP_CID_SACK: 312 case SCTP_CID_SACK:
313 packet->has_sack = 1; 313 packet->has_sack = 1;
314 if (chunk->asoc)
315 chunk->asoc->stats.osacks++;
314 break; 316 break;
315 317
316 case SCTP_CID_AUTH: 318 case SCTP_CID_AUTH:
@@ -584,11 +586,13 @@ int sctp_packet_transmit(struct sctp_packet *packet)
584 */ 586 */
585 587
586 /* Dump that on IP! */ 588 /* Dump that on IP! */
587 if (asoc && asoc->peer.last_sent_to != tp) { 589 if (asoc) {
588 /* Considering the multiple CPU scenario, this is a 590 asoc->stats.opackets++;
589 * "correcter" place for last_sent_to. --xguo 591 if (asoc->peer.last_sent_to != tp)
590 */ 592 /* Considering the multiple CPU scenario, this is a
591 asoc->peer.last_sent_to = tp; 593 * "correcter" place for last_sent_to. --xguo
594 */
595 asoc->peer.last_sent_to = tp;
592 } 596 }
593 597
594 if (has_data) { 598 if (has_data) {
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 1b4a7f8ec3fd..9bcdbd02d777 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -224,7 +224,7 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q)
224 224
225/* Free the outqueue structure and any related pending chunks. 225/* Free the outqueue structure and any related pending chunks.
226 */ 226 */
227void sctp_outq_teardown(struct sctp_outq *q) 227static void __sctp_outq_teardown(struct sctp_outq *q)
228{ 228{
229 struct sctp_transport *transport; 229 struct sctp_transport *transport;
230 struct list_head *lchunk, *temp; 230 struct list_head *lchunk, *temp;
@@ -277,8 +277,6 @@ void sctp_outq_teardown(struct sctp_outq *q)
277 sctp_chunk_free(chunk); 277 sctp_chunk_free(chunk);
278 } 278 }
279 279
280 q->error = 0;
281
282 /* Throw away any leftover control chunks. */ 280 /* Throw away any leftover control chunks. */
283 list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) { 281 list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) {
284 list_del_init(&chunk->list); 282 list_del_init(&chunk->list);
@@ -286,11 +284,17 @@ void sctp_outq_teardown(struct sctp_outq *q)
286 } 284 }
287} 285}
288 286
287void sctp_outq_teardown(struct sctp_outq *q)
288{
289 __sctp_outq_teardown(q);
290 sctp_outq_init(q->asoc, q);
291}
292
289/* Free the outqueue structure and any related pending chunks. */ 293/* Free the outqueue structure and any related pending chunks. */
290void sctp_outq_free(struct sctp_outq *q) 294void sctp_outq_free(struct sctp_outq *q)
291{ 295{
292 /* Throw away leftover chunks. */ 296 /* Throw away leftover chunks. */
293 sctp_outq_teardown(q); 297 __sctp_outq_teardown(q);
294 298
295 /* If we were kmalloc()'d, free the memory. */ 299 /* If we were kmalloc()'d, free the memory. */
296 if (q->malloced) 300 if (q->malloced)
@@ -667,6 +671,7 @@ redo:
667 chunk->fast_retransmit = SCTP_DONT_FRTX; 671 chunk->fast_retransmit = SCTP_DONT_FRTX;
668 672
669 q->empty = 0; 673 q->empty = 0;
674 q->asoc->stats.rtxchunks++;
670 break; 675 break;
671 } 676 }
672 677
@@ -876,12 +881,14 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
876 if (status != SCTP_XMIT_OK) { 881 if (status != SCTP_XMIT_OK) {
877 /* put the chunk back */ 882 /* put the chunk back */
878 list_add(&chunk->list, &q->control_chunk_list); 883 list_add(&chunk->list, &q->control_chunk_list);
879 } else if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN) { 884 } else {
885 asoc->stats.octrlchunks++;
880 /* PR-SCTP C5) If a FORWARD TSN is sent, the 886 /* PR-SCTP C5) If a FORWARD TSN is sent, the
881 * sender MUST assure that at least one T3-rtx 887 * sender MUST assure that at least one T3-rtx
882 * timer is running. 888 * timer is running.
883 */ 889 */
884 sctp_transport_reset_timers(transport); 890 if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN)
891 sctp_transport_reset_timers(transport);
885 } 892 }
886 break; 893 break;
887 894
@@ -1055,6 +1062,10 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
1055 */ 1062 */
1056 if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING) 1063 if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING)
1057 chunk->chunk_hdr->flags |= SCTP_DATA_SACK_IMM; 1064 chunk->chunk_hdr->flags |= SCTP_DATA_SACK_IMM;
1065 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
1066 asoc->stats.ouodchunks++;
1067 else
1068 asoc->stats.oodchunks++;
1058 1069
1059 break; 1070 break;
1060 1071
@@ -1162,6 +1173,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
1162 1173
1163 sack_ctsn = ntohl(sack->cum_tsn_ack); 1174 sack_ctsn = ntohl(sack->cum_tsn_ack);
1164 gap_ack_blocks = ntohs(sack->num_gap_ack_blocks); 1175 gap_ack_blocks = ntohs(sack->num_gap_ack_blocks);
1176 asoc->stats.gapcnt += gap_ack_blocks;
1165 /* 1177 /*
1166 * SFR-CACC algorithm: 1178 * SFR-CACC algorithm:
1167 * On receipt of a SACK the sender SHOULD execute the 1179 * On receipt of a SACK the sender SHOULD execute the
diff --git a/net/sctp/probe.c b/net/sctp/probe.c
index bc6cd75cc1dc..5f7518de2fd1 100644
--- a/net/sctp/probe.c
+++ b/net/sctp/probe.c
@@ -122,7 +122,8 @@ static const struct file_operations sctpprobe_fops = {
122 .llseek = noop_llseek, 122 .llseek = noop_llseek,
123}; 123};
124 124
125sctp_disposition_t jsctp_sf_eat_sack(const struct sctp_endpoint *ep, 125sctp_disposition_t jsctp_sf_eat_sack(struct net *net,
126 const struct sctp_endpoint *ep,
126 const struct sctp_association *asoc, 127 const struct sctp_association *asoc,
127 const sctp_subtype_t type, 128 const sctp_subtype_t type,
128 void *arg, 129 void *arg,
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index c3bea269faf4..8c19e97262ca 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -102,7 +102,7 @@ static const struct file_operations sctp_snmp_seq_fops = {
102 .open = sctp_snmp_seq_open, 102 .open = sctp_snmp_seq_open,
103 .read = seq_read, 103 .read = seq_read,
104 .llseek = seq_lseek, 104 .llseek = seq_lseek,
105 .release = single_release, 105 .release = single_release_net,
106}; 106};
107 107
108/* Set up the proc fs entry for 'snmp' object. */ 108/* Set up the proc fs entry for 'snmp' object. */
@@ -139,7 +139,11 @@ static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_commo
139 primary = &peer->saddr; 139 primary = &peer->saddr;
140 } 140 }
141 141
142 list_for_each_entry(laddr, &epb->bind_addr.address_list, list) { 142 rcu_read_lock();
143 list_for_each_entry_rcu(laddr, &epb->bind_addr.address_list, list) {
144 if (!laddr->valid)
145 continue;
146
143 addr = &laddr->a; 147 addr = &laddr->a;
144 af = sctp_get_af_specific(addr->sa.sa_family); 148 af = sctp_get_af_specific(addr->sa.sa_family);
145 if (primary && af->cmp_addr(addr, primary)) { 149 if (primary && af->cmp_addr(addr, primary)) {
@@ -147,6 +151,7 @@ static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_commo
147 } 151 }
148 af->seq_dump_addr(seq, addr); 152 af->seq_dump_addr(seq, addr);
149 } 153 }
154 rcu_read_unlock();
150} 155}
151 156
152/* Dump remote addresses of an association. */ 157/* Dump remote addresses of an association. */
@@ -157,15 +162,20 @@ static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_associa
157 struct sctp_af *af; 162 struct sctp_af *af;
158 163
159 primary = &assoc->peer.primary_addr; 164 primary = &assoc->peer.primary_addr;
160 list_for_each_entry(transport, &assoc->peer.transport_addr_list, 165 rcu_read_lock();
166 list_for_each_entry_rcu(transport, &assoc->peer.transport_addr_list,
161 transports) { 167 transports) {
162 addr = &transport->ipaddr; 168 addr = &transport->ipaddr;
169 if (transport->dead)
170 continue;
171
163 af = sctp_get_af_specific(addr->sa.sa_family); 172 af = sctp_get_af_specific(addr->sa.sa_family);
164 if (af->cmp_addr(addr, primary)) { 173 if (af->cmp_addr(addr, primary)) {
165 seq_printf(seq, "*"); 174 seq_printf(seq, "*");
166 } 175 }
167 af->seq_dump_addr(seq, addr); 176 af->seq_dump_addr(seq, addr);
168 } 177 }
178 rcu_read_unlock();
169} 179}
170 180
171static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos) 181static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos)
@@ -251,7 +261,7 @@ static const struct file_operations sctp_eps_seq_fops = {
251 .open = sctp_eps_seq_open, 261 .open = sctp_eps_seq_open,
252 .read = seq_read, 262 .read = seq_read,
253 .llseek = seq_lseek, 263 .llseek = seq_lseek,
254 .release = seq_release, 264 .release = seq_release_net,
255}; 265};
256 266
257/* Set up the proc fs entry for 'eps' object. */ 267/* Set up the proc fs entry for 'eps' object. */
@@ -372,7 +382,7 @@ static const struct file_operations sctp_assocs_seq_fops = {
372 .open = sctp_assocs_seq_open, 382 .open = sctp_assocs_seq_open,
373 .read = seq_read, 383 .read = seq_read,
374 .llseek = seq_lseek, 384 .llseek = seq_lseek,
375 .release = seq_release, 385 .release = seq_release_net,
376}; 386};
377 387
378/* Set up the proc fs entry for 'assocs' object. */ 388/* Set up the proc fs entry for 'assocs' object. */
@@ -436,12 +446,16 @@ static int sctp_remaddr_seq_show(struct seq_file *seq, void *v)
436 head = &sctp_assoc_hashtable[hash]; 446 head = &sctp_assoc_hashtable[hash];
437 sctp_local_bh_disable(); 447 sctp_local_bh_disable();
438 read_lock(&head->lock); 448 read_lock(&head->lock);
449 rcu_read_lock();
439 sctp_for_each_hentry(epb, node, &head->chain) { 450 sctp_for_each_hentry(epb, node, &head->chain) {
440 if (!net_eq(sock_net(epb->sk), seq_file_net(seq))) 451 if (!net_eq(sock_net(epb->sk), seq_file_net(seq)))
441 continue; 452 continue;
442 assoc = sctp_assoc(epb); 453 assoc = sctp_assoc(epb);
443 list_for_each_entry(tsp, &assoc->peer.transport_addr_list, 454 list_for_each_entry_rcu(tsp, &assoc->peer.transport_addr_list,
444 transports) { 455 transports) {
456 if (tsp->dead)
457 continue;
458
445 /* 459 /*
446 * The remote address (ADDR) 460 * The remote address (ADDR)
447 */ 461 */
@@ -487,6 +501,7 @@ static int sctp_remaddr_seq_show(struct seq_file *seq, void *v)
487 } 501 }
488 } 502 }
489 503
504 rcu_read_unlock();
490 read_unlock(&head->lock); 505 read_unlock(&head->lock);
491 sctp_local_bh_enable(); 506 sctp_local_bh_enable();
492 507
@@ -517,7 +532,7 @@ static const struct file_operations sctp_remaddr_seq_fops = {
517 .open = sctp_remaddr_seq_open, 532 .open = sctp_remaddr_seq_open,
518 .read = seq_read, 533 .read = seq_read,
519 .llseek = seq_lseek, 534 .llseek = seq_lseek,
520 .release = seq_release, 535 .release = seq_release_net,
521}; 536};
522 537
523int __net_init sctp_remaddr_proc_init(struct net *net) 538int __net_init sctp_remaddr_proc_init(struct net *net)
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 2d518425d598..f898b1c58bd2 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -86,7 +86,7 @@ int sysctl_sctp_rmem[3];
86int sysctl_sctp_wmem[3]; 86int sysctl_sctp_wmem[3];
87 87
88/* Set up the proc fs entry for the SCTP protocol. */ 88/* Set up the proc fs entry for the SCTP protocol. */
89static __net_init int sctp_proc_init(struct net *net) 89static int __net_init sctp_proc_init(struct net *net)
90{ 90{
91#ifdef CONFIG_PROC_FS 91#ifdef CONFIG_PROC_FS
92 net->sctp.proc_net_sctp = proc_net_mkdir(net, "sctp", net->proc_net); 92 net->sctp.proc_net_sctp = proc_net_mkdir(net, "sctp", net->proc_net);
@@ -1165,7 +1165,7 @@ static void sctp_v4_del_protocol(void)
1165 unregister_inetaddr_notifier(&sctp_inetaddr_notifier); 1165 unregister_inetaddr_notifier(&sctp_inetaddr_notifier);
1166} 1166}
1167 1167
1168static int sctp_net_init(struct net *net) 1168static int __net_init sctp_net_init(struct net *net)
1169{ 1169{
1170 int status; 1170 int status;
1171 1171
@@ -1190,6 +1190,15 @@ static int sctp_net_init(struct net *net)
1190 /* Whether Cookie Preservative is enabled(1) or not(0) */ 1190 /* Whether Cookie Preservative is enabled(1) or not(0) */
1191 net->sctp.cookie_preserve_enable = 1; 1191 net->sctp.cookie_preserve_enable = 1;
1192 1192
1193 /* Default sctp sockets to use md5 as their hmac alg */
1194#if defined (CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5)
1195 net->sctp.sctp_hmac_alg = "md5";
1196#elif defined (CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1)
1197 net->sctp.sctp_hmac_alg = "sha1";
1198#else
1199 net->sctp.sctp_hmac_alg = NULL;
1200#endif
1201
1193 /* Max.Burst - 4 */ 1202 /* Max.Burst - 4 */
1194 net->sctp.max_burst = SCTP_DEFAULT_MAX_BURST; 1203 net->sctp.max_burst = SCTP_DEFAULT_MAX_BURST;
1195 1204
@@ -1281,7 +1290,7 @@ err_sysctl_register:
1281 return status; 1290 return status;
1282} 1291}
1283 1292
1284static void sctp_net_exit(struct net *net) 1293static void __net_exit sctp_net_exit(struct net *net)
1285{ 1294{
1286 /* Free the local address list */ 1295 /* Free the local address list */
1287 sctp_free_addr_wq(net); 1296 sctp_free_addr_wq(net);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 16a10850ed39..04df5301df04 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -804,10 +804,11 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc)
804 gabs); 804 gabs);
805 805
806 /* Add the duplicate TSN information. */ 806 /* Add the duplicate TSN information. */
807 if (num_dup_tsns) 807 if (num_dup_tsns) {
808 aptr->stats.idupchunks += num_dup_tsns;
808 sctp_addto_chunk(retval, sizeof(__u32) * num_dup_tsns, 809 sctp_addto_chunk(retval, sizeof(__u32) * num_dup_tsns,
809 sctp_tsnmap_get_dups(map)); 810 sctp_tsnmap_get_dups(map));
810 811 }
811 /* Once we have a sack generated, check to see what our sack 812 /* Once we have a sack generated, check to see what our sack
812 * generation is, if its 0, reset the transports to 0, and reset 813 * generation is, if its 0, reset the transports to 0, and reset
813 * the association generation to 1 814 * the association generation to 1
@@ -1090,6 +1091,25 @@ nodata:
1090 return retval; 1091 return retval;
1091} 1092}
1092 1093
1094struct sctp_chunk *sctp_make_violation_max_retrans(
1095 const struct sctp_association *asoc,
1096 const struct sctp_chunk *chunk)
1097{
1098 struct sctp_chunk *retval;
1099 static const char error[] = "Association exceeded its max_retans count";
1100 size_t payload_len = sizeof(error) + sizeof(sctp_errhdr_t);
1101
1102 retval = sctp_make_abort(asoc, chunk, payload_len);
1103 if (!retval)
1104 goto nodata;
1105
1106 sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION, sizeof(error));
1107 sctp_addto_chunk(retval, sizeof(error), error);
1108
1109nodata:
1110 return retval;
1111}
1112
1093/* Make a HEARTBEAT chunk. */ 1113/* Make a HEARTBEAT chunk. */
1094struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc, 1114struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
1095 const struct sctp_transport *transport) 1115 const struct sctp_transport *transport)
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 6773d7803627..c9577754a708 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -542,6 +542,7 @@ static void sctp_do_8_2_transport_strike(sctp_cmd_seq_t *commands,
542 */ 542 */
543 if (!is_hb || transport->hb_sent) { 543 if (!is_hb || transport->hb_sent) {
544 transport->rto = min((transport->rto * 2), transport->asoc->rto_max); 544 transport->rto = min((transport->rto * 2), transport->asoc->rto_max);
545 sctp_max_rto(asoc, transport);
545 } 546 }
546} 547}
547 548
@@ -577,7 +578,7 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands,
577 unsigned int error) 578 unsigned int error)
578{ 579{
579 struct sctp_ulpevent *event; 580 struct sctp_ulpevent *event;
580 581 struct sctp_chunk *abort;
581 /* Cancel any partial delivery in progress. */ 582 /* Cancel any partial delivery in progress. */
582 sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC); 583 sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC);
583 584
@@ -593,6 +594,13 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands,
593 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, 594 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
594 SCTP_ULPEVENT(event)); 595 SCTP_ULPEVENT(event));
595 596
597 if (asoc->overall_error_count >= asoc->max_retrans) {
598 abort = sctp_make_violation_max_retrans(asoc, chunk);
599 if (abort)
600 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
601 SCTP_CHUNK(abort));
602 }
603
596 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, 604 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
597 SCTP_STATE(SCTP_STATE_CLOSED)); 605 SCTP_STATE(SCTP_STATE_CLOSED));
598 606
@@ -1268,14 +1276,14 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1268 sctp_outq_uncork(&asoc->outqueue); 1276 sctp_outq_uncork(&asoc->outqueue);
1269 local_cork = 0; 1277 local_cork = 0;
1270 } 1278 }
1271 asoc = cmd->obj.ptr; 1279 asoc = cmd->obj.asoc;
1272 /* Register with the endpoint. */ 1280 /* Register with the endpoint. */
1273 sctp_endpoint_add_asoc(ep, asoc); 1281 sctp_endpoint_add_asoc(ep, asoc);
1274 sctp_hash_established(asoc); 1282 sctp_hash_established(asoc);
1275 break; 1283 break;
1276 1284
1277 case SCTP_CMD_UPDATE_ASSOC: 1285 case SCTP_CMD_UPDATE_ASSOC:
1278 sctp_assoc_update(asoc, cmd->obj.ptr); 1286 sctp_assoc_update(asoc, cmd->obj.asoc);
1279 break; 1287 break;
1280 1288
1281 case SCTP_CMD_PURGE_OUTQUEUE: 1289 case SCTP_CMD_PURGE_OUTQUEUE:
@@ -1315,7 +1323,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1315 break; 1323 break;
1316 1324
1317 case SCTP_CMD_PROCESS_FWDTSN: 1325 case SCTP_CMD_PROCESS_FWDTSN:
1318 sctp_cmd_process_fwdtsn(&asoc->ulpq, cmd->obj.ptr); 1326 sctp_cmd_process_fwdtsn(&asoc->ulpq, cmd->obj.chunk);
1319 break; 1327 break;
1320 1328
1321 case SCTP_CMD_GEN_SACK: 1329 case SCTP_CMD_GEN_SACK:
@@ -1331,7 +1339,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1331 case SCTP_CMD_PROCESS_SACK: 1339 case SCTP_CMD_PROCESS_SACK:
1332 /* Process an inbound SACK. */ 1340 /* Process an inbound SACK. */
1333 error = sctp_cmd_process_sack(commands, asoc, 1341 error = sctp_cmd_process_sack(commands, asoc,
1334 cmd->obj.ptr); 1342 cmd->obj.chunk);
1335 break; 1343 break;
1336 1344
1337 case SCTP_CMD_GEN_INIT_ACK: 1345 case SCTP_CMD_GEN_INIT_ACK:
@@ -1352,15 +1360,15 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1352 * layer which will bail. 1360 * layer which will bail.
1353 */ 1361 */
1354 error = sctp_cmd_process_init(commands, asoc, chunk, 1362 error = sctp_cmd_process_init(commands, asoc, chunk,
1355 cmd->obj.ptr, gfp); 1363 cmd->obj.init, gfp);
1356 break; 1364 break;
1357 1365
1358 case SCTP_CMD_GEN_COOKIE_ECHO: 1366 case SCTP_CMD_GEN_COOKIE_ECHO:
1359 /* Generate a COOKIE ECHO chunk. */ 1367 /* Generate a COOKIE ECHO chunk. */
1360 new_obj = sctp_make_cookie_echo(asoc, chunk); 1368 new_obj = sctp_make_cookie_echo(asoc, chunk);
1361 if (!new_obj) { 1369 if (!new_obj) {
1362 if (cmd->obj.ptr) 1370 if (cmd->obj.chunk)
1363 sctp_chunk_free(cmd->obj.ptr); 1371 sctp_chunk_free(cmd->obj.chunk);
1364 goto nomem; 1372 goto nomem;
1365 } 1373 }
1366 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, 1374 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
@@ -1369,9 +1377,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1369 /* If there is an ERROR chunk to be sent along with 1377 /* If there is an ERROR chunk to be sent along with
1370 * the COOKIE_ECHO, send it, too. 1378 * the COOKIE_ECHO, send it, too.
1371 */ 1379 */
1372 if (cmd->obj.ptr) 1380 if (cmd->obj.chunk)
1373 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, 1381 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
1374 SCTP_CHUNK(cmd->obj.ptr)); 1382 SCTP_CHUNK(cmd->obj.chunk));
1375 1383
1376 if (new_obj->transport) { 1384 if (new_obj->transport) {
1377 new_obj->transport->init_sent_count++; 1385 new_obj->transport->init_sent_count++;
@@ -1417,18 +1425,18 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1417 case SCTP_CMD_CHUNK_ULP: 1425 case SCTP_CMD_CHUNK_ULP:
1418 /* Send a chunk to the sockets layer. */ 1426 /* Send a chunk to the sockets layer. */
1419 SCTP_DEBUG_PRINTK("sm_sideff: %s %p, %s %p.\n", 1427 SCTP_DEBUG_PRINTK("sm_sideff: %s %p, %s %p.\n",
1420 "chunk_up:", cmd->obj.ptr, 1428 "chunk_up:", cmd->obj.chunk,
1421 "ulpq:", &asoc->ulpq); 1429 "ulpq:", &asoc->ulpq);
1422 sctp_ulpq_tail_data(&asoc->ulpq, cmd->obj.ptr, 1430 sctp_ulpq_tail_data(&asoc->ulpq, cmd->obj.chunk,
1423 GFP_ATOMIC); 1431 GFP_ATOMIC);
1424 break; 1432 break;
1425 1433
1426 case SCTP_CMD_EVENT_ULP: 1434 case SCTP_CMD_EVENT_ULP:
1427 /* Send a notification to the sockets layer. */ 1435 /* Send a notification to the sockets layer. */
1428 SCTP_DEBUG_PRINTK("sm_sideff: %s %p, %s %p.\n", 1436 SCTP_DEBUG_PRINTK("sm_sideff: %s %p, %s %p.\n",
1429 "event_up:",cmd->obj.ptr, 1437 "event_up:",cmd->obj.ulpevent,
1430 "ulpq:",&asoc->ulpq); 1438 "ulpq:",&asoc->ulpq);
1431 sctp_ulpq_tail_event(&asoc->ulpq, cmd->obj.ptr); 1439 sctp_ulpq_tail_event(&asoc->ulpq, cmd->obj.ulpevent);
1432 break; 1440 break;
1433 1441
1434 case SCTP_CMD_REPLY: 1442 case SCTP_CMD_REPLY:
@@ -1438,12 +1446,12 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1438 local_cork = 1; 1446 local_cork = 1;
1439 } 1447 }
1440 /* Send a chunk to our peer. */ 1448 /* Send a chunk to our peer. */
1441 error = sctp_outq_tail(&asoc->outqueue, cmd->obj.ptr); 1449 error = sctp_outq_tail(&asoc->outqueue, cmd->obj.chunk);
1442 break; 1450 break;
1443 1451
1444 case SCTP_CMD_SEND_PKT: 1452 case SCTP_CMD_SEND_PKT:
1445 /* Send a full packet to our peer. */ 1453 /* Send a full packet to our peer. */
1446 packet = cmd->obj.ptr; 1454 packet = cmd->obj.packet;
1447 sctp_packet_transmit(packet); 1455 sctp_packet_transmit(packet);
1448 sctp_ootb_pkt_free(packet); 1456 sctp_ootb_pkt_free(packet);
1449 break; 1457 break;
@@ -1480,7 +1488,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1480 break; 1488 break;
1481 1489
1482 case SCTP_CMD_SETUP_T2: 1490 case SCTP_CMD_SETUP_T2:
1483 sctp_cmd_setup_t2(commands, asoc, cmd->obj.ptr); 1491 sctp_cmd_setup_t2(commands, asoc, cmd->obj.chunk);
1484 break; 1492 break;
1485 1493
1486 case SCTP_CMD_TIMER_START_ONCE: 1494 case SCTP_CMD_TIMER_START_ONCE:
@@ -1514,7 +1522,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1514 break; 1522 break;
1515 1523
1516 case SCTP_CMD_INIT_CHOOSE_TRANSPORT: 1524 case SCTP_CMD_INIT_CHOOSE_TRANSPORT:
1517 chunk = cmd->obj.ptr; 1525 chunk = cmd->obj.chunk;
1518 t = sctp_assoc_choose_alter_transport(asoc, 1526 t = sctp_assoc_choose_alter_transport(asoc,
1519 asoc->init_last_sent_to); 1527 asoc->init_last_sent_to);
1520 asoc->init_last_sent_to = t; 1528 asoc->init_last_sent_to = t;
@@ -1665,17 +1673,16 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1665 break; 1673 break;
1666 1674
1667 case SCTP_CMD_PART_DELIVER: 1675 case SCTP_CMD_PART_DELIVER:
1668 sctp_ulpq_partial_delivery(&asoc->ulpq, cmd->obj.ptr, 1676 sctp_ulpq_partial_delivery(&asoc->ulpq, GFP_ATOMIC);
1669 GFP_ATOMIC);
1670 break; 1677 break;
1671 1678
1672 case SCTP_CMD_RENEGE: 1679 case SCTP_CMD_RENEGE:
1673 sctp_ulpq_renege(&asoc->ulpq, cmd->obj.ptr, 1680 sctp_ulpq_renege(&asoc->ulpq, cmd->obj.chunk,
1674 GFP_ATOMIC); 1681 GFP_ATOMIC);
1675 break; 1682 break;
1676 1683
1677 case SCTP_CMD_SETUP_T4: 1684 case SCTP_CMD_SETUP_T4:
1678 sctp_cmd_setup_t4(commands, asoc, cmd->obj.ptr); 1685 sctp_cmd_setup_t4(commands, asoc, cmd->obj.chunk);
1679 break; 1686 break;
1680 1687
1681 case SCTP_CMD_PROCESS_OPERR: 1688 case SCTP_CMD_PROCESS_OPERR:
@@ -1734,8 +1741,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1734 break; 1741 break;
1735 1742
1736 default: 1743 default:
1737 pr_warn("Impossible command: %u, %p\n", 1744 pr_warn("Impossible command: %u\n",
1738 cmd->verb, cmd->obj.ptr); 1745 cmd->verb);
1739 break; 1746 break;
1740 } 1747 }
1741 1748
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 49493f335861..5131fcfedb03 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -1055,6 +1055,7 @@ sctp_disposition_t sctp_sf_beat_8_3(struct net *net,
1055 void *arg, 1055 void *arg,
1056 sctp_cmd_seq_t *commands) 1056 sctp_cmd_seq_t *commands)
1057{ 1057{
1058 sctp_paramhdr_t *param_hdr;
1058 struct sctp_chunk *chunk = arg; 1059 struct sctp_chunk *chunk = arg;
1059 struct sctp_chunk *reply; 1060 struct sctp_chunk *reply;
1060 size_t paylen = 0; 1061 size_t paylen = 0;
@@ -1072,12 +1073,17 @@ sctp_disposition_t sctp_sf_beat_8_3(struct net *net,
1072 * Information field copied from the received HEARTBEAT chunk. 1073 * Information field copied from the received HEARTBEAT chunk.
1073 */ 1074 */
1074 chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data; 1075 chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data;
1076 param_hdr = (sctp_paramhdr_t *) chunk->subh.hb_hdr;
1075 paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t); 1077 paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t);
1078
1079 if (ntohs(param_hdr->length) > paylen)
1080 return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
1081 param_hdr, commands);
1082
1076 if (!pskb_pull(chunk->skb, paylen)) 1083 if (!pskb_pull(chunk->skb, paylen))
1077 goto nomem; 1084 goto nomem;
1078 1085
1079 reply = sctp_make_heartbeat_ack(asoc, chunk, 1086 reply = sctp_make_heartbeat_ack(asoc, chunk, param_hdr, paylen);
1080 chunk->subh.hb_hdr, paylen);
1081 if (!reply) 1087 if (!reply)
1082 goto nomem; 1088 goto nomem;
1083 1089
@@ -1773,8 +1779,10 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(struct net *net,
1773 1779
1774 /* Update the content of current association. */ 1780 /* Update the content of current association. */
1775 sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc)); 1781 sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
1776 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
1777 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); 1782 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
1783 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
1784 SCTP_STATE(SCTP_STATE_ESTABLISHED));
1785 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
1778 return SCTP_DISPOSITION_CONSUME; 1786 return SCTP_DISPOSITION_CONSUME;
1779 1787
1780nomem_ev: 1788nomem_ev:
@@ -6127,6 +6135,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,
6127 /* The TSN is too high--silently discard the chunk and 6135 /* The TSN is too high--silently discard the chunk and
6128 * count on it getting retransmitted later. 6136 * count on it getting retransmitted later.
6129 */ 6137 */
6138 if (chunk->asoc)
6139 chunk->asoc->stats.outofseqtsns++;
6130 return SCTP_IERROR_HIGH_TSN; 6140 return SCTP_IERROR_HIGH_TSN;
6131 } else if (tmp > 0) { 6141 } else if (tmp > 0) {
6132 /* This is a duplicate. Record it. */ 6142 /* This is a duplicate. Record it. */
@@ -6226,10 +6236,14 @@ static int sctp_eat_data(const struct sctp_association *asoc,
6226 /* Note: Some chunks may get overcounted (if we drop) or overcounted 6236 /* Note: Some chunks may get overcounted (if we drop) or overcounted
6227 * if we renege and the chunk arrives again. 6237 * if we renege and the chunk arrives again.
6228 */ 6238 */
6229 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) 6239 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) {
6230 SCTP_INC_STATS(net, SCTP_MIB_INUNORDERCHUNKS); 6240 SCTP_INC_STATS(net, SCTP_MIB_INUNORDERCHUNKS);
6231 else { 6241 if (chunk->asoc)
6242 chunk->asoc->stats.iuodchunks++;
6243 } else {
6232 SCTP_INC_STATS(net, SCTP_MIB_INORDERCHUNKS); 6244 SCTP_INC_STATS(net, SCTP_MIB_INORDERCHUNKS);
6245 if (chunk->asoc)
6246 chunk->asoc->stats.iodchunks++;
6233 ordered = 1; 6247 ordered = 1;
6234 } 6248 }
6235 6249
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 59d16ea927f0..9e65758cb038 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -110,7 +110,6 @@ static int sctp_do_bind(struct sock *, union sctp_addr *, int);
110static int sctp_autobind(struct sock *sk); 110static int sctp_autobind(struct sock *sk);
111static void sctp_sock_migrate(struct sock *, struct sock *, 111static void sctp_sock_migrate(struct sock *, struct sock *,
112 struct sctp_association *, sctp_socket_type_t); 112 struct sctp_association *, sctp_socket_type_t);
113static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG;
114 113
115extern struct kmem_cache *sctp_bucket_cachep; 114extern struct kmem_cache *sctp_bucket_cachep;
116extern long sysctl_sctp_mem[3]; 115extern long sysctl_sctp_mem[3];
@@ -336,6 +335,7 @@ static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt,
336/* Bind a local address either to an endpoint or to an association. */ 335/* Bind a local address either to an endpoint or to an association. */
337SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) 336SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
338{ 337{
338 struct net *net = sock_net(sk);
339 struct sctp_sock *sp = sctp_sk(sk); 339 struct sctp_sock *sp = sctp_sk(sk);
340 struct sctp_endpoint *ep = sp->ep; 340 struct sctp_endpoint *ep = sp->ep;
341 struct sctp_bind_addr *bp = &ep->base.bind_addr; 341 struct sctp_bind_addr *bp = &ep->base.bind_addr;
@@ -379,7 +379,8 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
379 } 379 }
380 } 380 }
381 381
382 if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) 382 if (snum && snum < PROT_SOCK &&
383 !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
383 return -EACCES; 384 return -EACCES;
384 385
385 /* See if the address matches any of the addresses we may have 386 /* See if the address matches any of the addresses we may have
@@ -610,6 +611,7 @@ static int sctp_send_asconf_add_ip(struct sock *sk,
610 2*asoc->pathmtu, 4380)); 611 2*asoc->pathmtu, 4380));
611 trans->ssthresh = asoc->peer.i.a_rwnd; 612 trans->ssthresh = asoc->peer.i.a_rwnd;
612 trans->rto = asoc->rto_initial; 613 trans->rto = asoc->rto_initial;
614 sctp_max_rto(asoc, trans);
613 trans->rtt = trans->srtt = trans->rttvar = 0; 615 trans->rtt = trans->srtt = trans->rttvar = 0;
614 sctp_transport_route(trans, NULL, 616 sctp_transport_route(trans, NULL,
615 sctp_sk(asoc->base.sk)); 617 sctp_sk(asoc->base.sk));
@@ -974,7 +976,7 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk,
974 void *addr_buf; 976 void *addr_buf;
975 struct sctp_af *af; 977 struct sctp_af *af;
976 978
977 SCTP_DEBUG_PRINTK("sctp_setsocktopt_bindx: sk %p addrs %p" 979 SCTP_DEBUG_PRINTK("sctp_setsockopt_bindx: sk %p addrs %p"
978 " addrs_size %d opt %d\n", sk, addrs, addrs_size, op); 980 " addrs_size %d opt %d\n", sk, addrs, addrs_size, op);
979 981
980 if (unlikely(addrs_size <= 0)) 982 if (unlikely(addrs_size <= 0))
@@ -1162,7 +1164,7 @@ static int __sctp_connect(struct sock* sk,
1162 * be permitted to open new associations. 1164 * be permitted to open new associations.
1163 */ 1165 */
1164 if (ep->base.bind_addr.port < PROT_SOCK && 1166 if (ep->base.bind_addr.port < PROT_SOCK &&
1165 !capable(CAP_NET_BIND_SERVICE)) { 1167 !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) {
1166 err = -EACCES; 1168 err = -EACCES;
1167 goto out_free; 1169 goto out_free;
1168 } 1170 }
@@ -1791,7 +1793,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
1791 * associations. 1793 * associations.
1792 */ 1794 */
1793 if (ep->base.bind_addr.port < PROT_SOCK && 1795 if (ep->base.bind_addr.port < PROT_SOCK &&
1794 !capable(CAP_NET_BIND_SERVICE)) { 1796 !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) {
1795 err = -EACCES; 1797 err = -EACCES;
1796 goto out_unlock; 1798 goto out_unlock;
1797 } 1799 }
@@ -1915,8 +1917,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
1915 1917
1916 /* Break the message into multiple chunks of maximum size. */ 1918 /* Break the message into multiple chunks of maximum size. */
1917 datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len); 1919 datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len);
1918 if (!datamsg) { 1920 if (IS_ERR(datamsg)) {
1919 err = -ENOMEM; 1921 err = PTR_ERR(datamsg);
1920 goto out_free; 1922 goto out_free;
1921 } 1923 }
1922 1924
@@ -3890,6 +3892,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
3890 sp->default_rcv_context = 0; 3892 sp->default_rcv_context = 0;
3891 sp->max_burst = net->sctp.max_burst; 3893 sp->max_burst = net->sctp.max_burst;
3892 3894
3895 sp->sctp_hmac_alg = net->sctp.sctp_hmac_alg;
3896
3893 /* Initialize default setup parameters. These parameters 3897 /* Initialize default setup parameters. These parameters
3894 * can be modified with the SCTP_INITMSG socket option or 3898 * can be modified with the SCTP_INITMSG socket option or
3895 * overridden by the SCTP_INIT CMSG. 3899 * overridden by the SCTP_INIT CMSG.
@@ -5632,6 +5636,71 @@ static int sctp_getsockopt_paddr_thresholds(struct sock *sk,
5632 return 0; 5636 return 0;
5633} 5637}
5634 5638
5639/*
5640 * SCTP_GET_ASSOC_STATS
5641 *
5642 * This option retrieves local per endpoint statistics. It is modeled
5643 * after OpenSolaris' implementation
5644 */
5645static int sctp_getsockopt_assoc_stats(struct sock *sk, int len,
5646 char __user *optval,
5647 int __user *optlen)
5648{
5649 struct sctp_assoc_stats sas;
5650 struct sctp_association *asoc = NULL;
5651
5652 /* User must provide at least the assoc id */
5653 if (len < sizeof(sctp_assoc_t))
5654 return -EINVAL;
5655
5656 if (copy_from_user(&sas, optval, len))
5657 return -EFAULT;
5658
5659 asoc = sctp_id2assoc(sk, sas.sas_assoc_id);
5660 if (!asoc)
5661 return -EINVAL;
5662
5663 sas.sas_rtxchunks = asoc->stats.rtxchunks;
5664 sas.sas_gapcnt = asoc->stats.gapcnt;
5665 sas.sas_outofseqtsns = asoc->stats.outofseqtsns;
5666 sas.sas_osacks = asoc->stats.osacks;
5667 sas.sas_isacks = asoc->stats.isacks;
5668 sas.sas_octrlchunks = asoc->stats.octrlchunks;
5669 sas.sas_ictrlchunks = asoc->stats.ictrlchunks;
5670 sas.sas_oodchunks = asoc->stats.oodchunks;
5671 sas.sas_iodchunks = asoc->stats.iodchunks;
5672 sas.sas_ouodchunks = asoc->stats.ouodchunks;
5673 sas.sas_iuodchunks = asoc->stats.iuodchunks;
5674 sas.sas_idupchunks = asoc->stats.idupchunks;
5675 sas.sas_opackets = asoc->stats.opackets;
5676 sas.sas_ipackets = asoc->stats.ipackets;
5677
5678 /* New high max rto observed, will return 0 if not a single
5679 * RTO update took place. obs_rto_ipaddr will be bogus
5680 * in such a case
5681 */
5682 sas.sas_maxrto = asoc->stats.max_obs_rto;
5683 memcpy(&sas.sas_obs_rto_ipaddr, &asoc->stats.obs_rto_ipaddr,
5684 sizeof(struct sockaddr_storage));
5685
5686 /* Mark beginning of a new observation period */
5687 asoc->stats.max_obs_rto = asoc->rto_min;
5688
5689 /* Allow the struct to grow and fill in as much as possible */
5690 len = min_t(size_t, len, sizeof(sas));
5691
5692 if (put_user(len, optlen))
5693 return -EFAULT;
5694
5695 SCTP_DEBUG_PRINTK("sctp_getsockopt_assoc_stat(%d): %d\n",
5696 len, sas.sas_assoc_id);
5697
5698 if (copy_to_user(optval, &sas, len))
5699 return -EFAULT;
5700
5701 return 0;
5702}
5703
5635SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, 5704SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
5636 char __user *optval, int __user *optlen) 5705 char __user *optval, int __user *optlen)
5637{ 5706{
@@ -5773,6 +5842,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
5773 case SCTP_PEER_ADDR_THLDS: 5842 case SCTP_PEER_ADDR_THLDS:
5774 retval = sctp_getsockopt_paddr_thresholds(sk, optval, len, optlen); 5843 retval = sctp_getsockopt_paddr_thresholds(sk, optval, len, optlen);
5775 break; 5844 break;
5845 case SCTP_GET_ASSOC_STATS:
5846 retval = sctp_getsockopt_assoc_stats(sk, len, optval, optlen);
5847 break;
5776 default: 5848 default:
5777 retval = -ENOPROTOOPT; 5849 retval = -ENOPROTOOPT;
5778 break; 5850 break;
@@ -5981,13 +6053,15 @@ SCTP_STATIC int sctp_listen_start(struct sock *sk, int backlog)
5981 struct sctp_sock *sp = sctp_sk(sk); 6053 struct sctp_sock *sp = sctp_sk(sk);
5982 struct sctp_endpoint *ep = sp->ep; 6054 struct sctp_endpoint *ep = sp->ep;
5983 struct crypto_hash *tfm = NULL; 6055 struct crypto_hash *tfm = NULL;
6056 char alg[32];
5984 6057
5985 /* Allocate HMAC for generating cookie. */ 6058 /* Allocate HMAC for generating cookie. */
5986 if (!sctp_sk(sk)->hmac && sctp_hmac_alg) { 6059 if (!sp->hmac && sp->sctp_hmac_alg) {
5987 tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); 6060 sprintf(alg, "hmac(%s)", sp->sctp_hmac_alg);
6061 tfm = crypto_alloc_hash(alg, 0, CRYPTO_ALG_ASYNC);
5988 if (IS_ERR(tfm)) { 6062 if (IS_ERR(tfm)) {
5989 net_info_ratelimited("failed to load transform for %s: %ld\n", 6063 net_info_ratelimited("failed to load transform for %s: %ld\n",
5990 sctp_hmac_alg, PTR_ERR(tfm)); 6064 sp->sctp_hmac_alg, PTR_ERR(tfm));
5991 return -ENOSYS; 6065 return -ENOSYS;
5992 } 6066 }
5993 sctp_sk(sk)->hmac = tfm; 6067 sctp_sk(sk)->hmac = tfm;
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 70e3ba5cb50b..bf3c6e8fc401 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -62,6 +62,11 @@ extern long sysctl_sctp_mem[3];
62extern int sysctl_sctp_rmem[3]; 62extern int sysctl_sctp_rmem[3];
63extern int sysctl_sctp_wmem[3]; 63extern int sysctl_sctp_wmem[3];
64 64
65static int proc_sctp_do_hmac_alg(ctl_table *ctl,
66 int write,
67 void __user *buffer, size_t *lenp,
68
69 loff_t *ppos);
65static ctl_table sctp_table[] = { 70static ctl_table sctp_table[] = {
66 { 71 {
67 .procname = "sctp_mem", 72 .procname = "sctp_mem",
@@ -147,6 +152,12 @@ static ctl_table sctp_net_table[] = {
147 .proc_handler = proc_dointvec, 152 .proc_handler = proc_dointvec,
148 }, 153 },
149 { 154 {
155 .procname = "cookie_hmac_alg",
156 .maxlen = 8,
157 .mode = 0644,
158 .proc_handler = proc_sctp_do_hmac_alg,
159 },
160 {
150 .procname = "valid_cookie_life", 161 .procname = "valid_cookie_life",
151 .data = &init_net.sctp.valid_cookie_life, 162 .data = &init_net.sctp.valid_cookie_life,
152 .maxlen = sizeof(unsigned int), 163 .maxlen = sizeof(unsigned int),
@@ -289,6 +300,54 @@ static ctl_table sctp_net_table[] = {
289 { /* sentinel */ } 300 { /* sentinel */ }
290}; 301};
291 302
303static int proc_sctp_do_hmac_alg(ctl_table *ctl,
304 int write,
305 void __user *buffer, size_t *lenp,
306 loff_t *ppos)
307{
308 struct net *net = current->nsproxy->net_ns;
309 char tmp[8];
310 ctl_table tbl;
311 int ret;
312 int changed = 0;
313 char *none = "none";
314
315 memset(&tbl, 0, sizeof(struct ctl_table));
316
317 if (write) {
318 tbl.data = tmp;
319 tbl.maxlen = 8;
320 } else {
321 tbl.data = net->sctp.sctp_hmac_alg ? : none;
322 tbl.maxlen = strlen(tbl.data);
323 }
324 ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
325
326 if (write) {
327#ifdef CONFIG_CRYPTO_MD5
328 if (!strncmp(tmp, "md5", 3)) {
329 net->sctp.sctp_hmac_alg = "md5";
330 changed = 1;
331 }
332#endif
333#ifdef CONFIG_CRYPTO_SHA1
334 if (!strncmp(tmp, "sha1", 4)) {
335 net->sctp.sctp_hmac_alg = "sha1";
336 changed = 1;
337 }
338#endif
339 if (!strncmp(tmp, "none", 4)) {
340 net->sctp.sctp_hmac_alg = NULL;
341 changed = 1;
342 }
343
344 if (!changed)
345 ret = -EINVAL;
346 }
347
348 return ret;
349}
350
292int sctp_sysctl_net_register(struct net *net) 351int sctp_sysctl_net_register(struct net *net)
293{ 352{
294 struct ctl_table *table; 353 struct ctl_table *table;
@@ -307,7 +366,11 @@ int sctp_sysctl_net_register(struct net *net)
307 366
308void sctp_sysctl_net_unregister(struct net *net) 367void sctp_sysctl_net_unregister(struct net *net)
309{ 368{
369 struct ctl_table *table;
370
371 table = net->sctp.sysctl_header->ctl_table_arg;
310 unregister_net_sysctl_table(net->sctp.sysctl_header); 372 unregister_net_sysctl_table(net->sctp.sysctl_header);
373 kfree(table);
311} 374}
312 375
313static struct ctl_table_header * sctp_sysctl_header; 376static struct ctl_table_header * sctp_sysctl_header;
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 953c21e4af97..4e45bb68aef0 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -163,13 +163,11 @@ void sctp_transport_free(struct sctp_transport *transport)
163 sctp_transport_put(transport); 163 sctp_transport_put(transport);
164} 164}
165 165
166/* Destroy the transport data structure. 166static void sctp_transport_destroy_rcu(struct rcu_head *head)
167 * Assumes there are no more users of this structure.
168 */
169static void sctp_transport_destroy(struct sctp_transport *transport)
170{ 167{
171 SCTP_ASSERT(transport->dead, "Transport is not dead", return); 168 struct sctp_transport *transport;
172 169
170 transport = container_of(head, struct sctp_transport, rcu);
173 if (transport->asoc) 171 if (transport->asoc)
174 sctp_association_put(transport->asoc); 172 sctp_association_put(transport->asoc);
175 173
@@ -180,6 +178,16 @@ static void sctp_transport_destroy(struct sctp_transport *transport)
180 SCTP_DBG_OBJCNT_DEC(transport); 178 SCTP_DBG_OBJCNT_DEC(transport);
181} 179}
182 180
181/* Destroy the transport data structure.
182 * Assumes there are no more users of this structure.
183 */
184static void sctp_transport_destroy(struct sctp_transport *transport)
185{
186 SCTP_ASSERT(transport->dead, "Transport is not dead", return);
187
188 call_rcu(&transport->rcu, sctp_transport_destroy_rcu);
189}
190
183/* Start T3_rtx timer if it is not already running and update the heartbeat 191/* Start T3_rtx timer if it is not already running and update the heartbeat
184 * timer. This routine is called every time a DATA chunk is sent. 192 * timer. This routine is called every time a DATA chunk is sent.
185 */ 193 */
@@ -331,7 +339,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
331 * 1/8, rto_alpha would be expressed as 3. 339 * 1/8, rto_alpha would be expressed as 3.
332 */ 340 */
333 tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta) 341 tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta)
334 + ((abs(tp->srtt - rtt)) >> net->sctp.rto_beta); 342 + (((__u32)abs64((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta);
335 tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha) 343 tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha)
336 + (rtt >> net->sctp.rto_alpha); 344 + (rtt >> net->sctp.rto_alpha);
337 } else { 345 } else {
@@ -363,6 +371,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
363 if (tp->rto > tp->asoc->rto_max) 371 if (tp->rto > tp->asoc->rto_max)
364 tp->rto = tp->asoc->rto_max; 372 tp->rto = tp->asoc->rto_max;
365 373
374 sctp_max_rto(tp->asoc, tp);
366 tp->rtt = rtt; 375 tp->rtt = rtt;
367 376
368 /* Reset rto_pending so that a new RTT measurement is started when a 377 /* Reset rto_pending so that a new RTT measurement is started when a
@@ -620,6 +629,7 @@ void sctp_transport_reset(struct sctp_transport *t)
620 t->burst_limited = 0; 629 t->burst_limited = 0;
621 t->ssthresh = asoc->peer.i.a_rwnd; 630 t->ssthresh = asoc->peer.i.a_rwnd;
622 t->rto = asoc->rto_initial; 631 t->rto = asoc->rto_initial;
632 sctp_max_rto(asoc, t);
623 t->rtt = 0; 633 t->rtt = 0;
624 t->srtt = 0; 634 t->srtt = 0;
625 t->rttvar = 0; 635 t->rttvar = 0;
diff --git a/net/sctp/tsnmap.c b/net/sctp/tsnmap.c
index b5fb7c409023..5f25e0c92c31 100644
--- a/net/sctp/tsnmap.c
+++ b/net/sctp/tsnmap.c
@@ -272,7 +272,7 @@ __u16 sctp_tsnmap_pending(struct sctp_tsnmap *map)
272 __u32 max_tsn = map->max_tsn_seen; 272 __u32 max_tsn = map->max_tsn_seen;
273 __u32 base_tsn = map->base_tsn; 273 __u32 base_tsn = map->base_tsn;
274 __u16 pending_data; 274 __u16 pending_data;
275 u32 gap, i; 275 u32 gap;
276 276
277 pending_data = max_tsn - cum_tsn; 277 pending_data = max_tsn - cum_tsn;
278 gap = max_tsn - base_tsn; 278 gap = max_tsn - base_tsn;
@@ -280,11 +280,7 @@ __u16 sctp_tsnmap_pending(struct sctp_tsnmap *map)
280 if (gap == 0 || gap >= map->len) 280 if (gap == 0 || gap >= map->len)
281 goto out; 281 goto out;
282 282
283 for (i = 0; i < gap+1; i++) { 283 pending_data -= bitmap_weight(map->tsn_map, gap + 1);
284 if (test_bit(i, map->tsn_map))
285 pending_data--;
286 }
287
288out: 284out:
289 return pending_data; 285 return pending_data;
290} 286}
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index 360d8697b95c..ada17464b65b 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -997,7 +997,6 @@ static __u16 sctp_ulpq_renege_frags(struct sctp_ulpq *ulpq, __u16 needed)
997 997
998/* Partial deliver the first message as there is pressure on rwnd. */ 998/* Partial deliver the first message as there is pressure on rwnd. */
999void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq, 999void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq,
1000 struct sctp_chunk *chunk,
1001 gfp_t gfp) 1000 gfp_t gfp)
1002{ 1001{
1003 struct sctp_ulpevent *event; 1002 struct sctp_ulpevent *event;
@@ -1060,7 +1059,7 @@ void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
1060 sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn, chunk->transport); 1059 sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn, chunk->transport);
1061 sctp_ulpq_tail_data(ulpq, chunk, gfp); 1060 sctp_ulpq_tail_data(ulpq, chunk, gfp);
1062 1061
1063 sctp_ulpq_partial_delivery(ulpq, chunk, gfp); 1062 sctp_ulpq_partial_delivery(ulpq, gfp);
1064 } 1063 }
1065 1064
1066 sk_mem_reclaim(asoc->base.sk); 1065 sk_mem_reclaim(asoc->base.sk);