aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/associola.c64
-rw-r--r--net/sctp/input.c4
-rw-r--r--net/sctp/ipv6.c2
-rw-r--r--net/sctp/output.c23
-rw-r--r--net/sctp/protocol.c10
-rw-r--r--net/sctp/sm_make_chunk.c16
-rw-r--r--net/sctp/sm_sideeffect.c8
-rw-r--r--net/sctp/sm_statefuns.c14
-rw-r--r--net/sctp/sm_statetable.c2
-rw-r--r--net/sctp/socket.c75
-rw-r--r--net/sctp/sysctl.c6
-rw-r--r--net/sctp/ulpevent.c7
12 files changed, 131 insertions, 100 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index f4b23043b610..525864bf4f07 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -293,7 +293,8 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
293 * told otherwise. 293 * told otherwise.
294 */ 294 */
295 asoc->peer.ipv4_address = 1; 295 asoc->peer.ipv4_address = 1;
296 asoc->peer.ipv6_address = 1; 296 if (asoc->base.sk->sk_family == PF_INET6)
297 asoc->peer.ipv6_address = 1;
297 INIT_LIST_HEAD(&asoc->asocs); 298 INIT_LIST_HEAD(&asoc->asocs);
298 299
299 asoc->autoclose = sp->autoclose; 300 asoc->autoclose = sp->autoclose;
@@ -566,6 +567,21 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,
566 if (asoc->init_last_sent_to == peer) 567 if (asoc->init_last_sent_to == peer)
567 asoc->init_last_sent_to = NULL; 568 asoc->init_last_sent_to = NULL;
568 569
570 /* If we remove the transport an SHUTDOWN was last sent to, set it
571 * to NULL. Combined with the update of the retran path above, this
572 * will cause the next SHUTDOWN to be sent to the next available
573 * transport, maintaining the cycle.
574 */
575 if (asoc->shutdown_last_sent_to == peer)
576 asoc->shutdown_last_sent_to = NULL;
577
578 /* If we remove the transport an ASCONF was last sent to, set it to
579 * NULL.
580 */
581 if (asoc->addip_last_asconf &&
582 asoc->addip_last_asconf->transport == peer)
583 asoc->addip_last_asconf->transport = NULL;
584
569 asoc->peer.transport_count--; 585 asoc->peer.transport_count--;
570 586
571 sctp_transport_free(peer); 587 sctp_transport_free(peer);
@@ -1268,49 +1284,21 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
1268 ntohs(t->ipaddr.v4.sin_port)); 1284 ntohs(t->ipaddr.v4.sin_port));
1269} 1285}
1270 1286
1271/* Choose the transport for sending a INIT packet. */ 1287/* Choose the transport for sending retransmit packet. */
1272struct sctp_transport *sctp_assoc_choose_init_transport( 1288struct sctp_transport *sctp_assoc_choose_alter_transport(
1273 struct sctp_association *asoc) 1289 struct sctp_association *asoc, struct sctp_transport *last_sent_to)
1274{
1275 struct sctp_transport *t;
1276
1277 /* Use the retran path. If the last INIT was sent over the
1278 * retran path, update the retran path and use it.
1279 */
1280 if (!asoc->init_last_sent_to) {
1281 t = asoc->peer.active_path;
1282 } else {
1283 if (asoc->init_last_sent_to == asoc->peer.retran_path)
1284 sctp_assoc_update_retran_path(asoc);
1285 t = asoc->peer.retran_path;
1286 }
1287
1288 SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association"
1289 " %p addr: ",
1290 " port: %d\n",
1291 asoc,
1292 (&t->ipaddr),
1293 ntohs(t->ipaddr.v4.sin_port));
1294
1295 return t;
1296}
1297
1298/* Choose the transport for sending a SHUTDOWN packet. */
1299struct sctp_transport *sctp_assoc_choose_shutdown_transport(
1300 struct sctp_association *asoc)
1301{ 1290{
1302 /* If this is the first time SHUTDOWN is sent, use the active path, 1291 /* If this is the first time packet is sent, use the active path,
1303 * else use the retran path. If the last SHUTDOWN was sent over the 1292 * else use the retran path. If the last packet was sent over the
1304 * retran path, update the retran path and use it. 1293 * retran path, update the retran path and use it.
1305 */ 1294 */
1306 if (!asoc->shutdown_last_sent_to) 1295 if (!last_sent_to)
1307 return asoc->peer.active_path; 1296 return asoc->peer.active_path;
1308 else { 1297 else {
1309 if (asoc->shutdown_last_sent_to == asoc->peer.retran_path) 1298 if (last_sent_to == asoc->peer.retran_path)
1310 sctp_assoc_update_retran_path(asoc); 1299 sctp_assoc_update_retran_path(asoc);
1311 return asoc->peer.retran_path; 1300 return asoc->peer.retran_path;
1312 } 1301 }
1313
1314} 1302}
1315 1303
1316/* Update the association's pmtu and frag_point by going through all the 1304/* Update the association's pmtu and frag_point by going through all the
@@ -1482,6 +1470,10 @@ int sctp_assoc_set_id(struct sctp_association *asoc, gfp_t gfp)
1482{ 1470{
1483 int assoc_id; 1471 int assoc_id;
1484 int error = 0; 1472 int error = 0;
1473
1474 /* If the id is already assigned, keep it. */
1475 if (asoc->assoc_id)
1476 return error;
1485retry: 1477retry:
1486 if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp))) 1478 if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
1487 return -ENOMEM; 1479 return -ENOMEM;
diff --git a/net/sctp/input.c b/net/sctp/input.c
index d2e98803ffe3..c0c973e67add 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -81,13 +81,13 @@ static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb);
81/* Calculate the SCTP checksum of an SCTP packet. */ 81/* Calculate the SCTP checksum of an SCTP packet. */
82static inline int sctp_rcv_checksum(struct sk_buff *skb) 82static inline int sctp_rcv_checksum(struct sk_buff *skb)
83{ 83{
84 struct sk_buff *list = skb_shinfo(skb)->frag_list;
85 struct sctphdr *sh = sctp_hdr(skb); 84 struct sctphdr *sh = sctp_hdr(skb);
86 __le32 cmp = sh->checksum; 85 __le32 cmp = sh->checksum;
86 struct sk_buff *list;
87 __le32 val; 87 __le32 val;
88 __u32 tmp = sctp_start_cksum((__u8 *)sh, skb_headlen(skb)); 88 __u32 tmp = sctp_start_cksum((__u8 *)sh, skb_headlen(skb));
89 89
90 for (; list; list = list->next) 90 skb_walk_frags(skb, list)
91 tmp = sctp_update_cksum((__u8 *)list->data, skb_headlen(list), 91 tmp = sctp_update_cksum((__u8 *)list->data, skb_headlen(list),
92 tmp); 92 tmp);
93 93
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index a63de3f7f185..6a4b19094143 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -133,7 +133,7 @@ static struct notifier_block sctp_inet6addr_notifier = {
133 133
134/* ICMP error handler. */ 134/* ICMP error handler. */
135SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 135SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
136 int type, int code, int offset, __be32 info) 136 u8 type, u8 code, int offset, __be32 info)
137{ 137{
138 struct inet6_dev *idev; 138 struct inet6_dev *idev;
139 struct sock *sk; 139 struct sock *sk;
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 7d08f522ec84..b94c21190566 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -405,13 +405,14 @@ int sctp_packet_transmit(struct sctp_packet *packet)
405 sctp_assoc_sync_pmtu(asoc); 405 sctp_assoc_sync_pmtu(asoc);
406 } 406 }
407 } 407 }
408 nskb->dst = dst_clone(tp->dst); 408 dst = dst_clone(tp->dst);
409 if (!nskb->dst) 409 skb_dst_set(nskb, dst);
410 if (!dst)
410 goto no_route; 411 goto no_route;
411 dst = nskb->dst;
412 412
413 /* Build the SCTP header. */ 413 /* Build the SCTP header. */
414 sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr)); 414 sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr));
415 skb_reset_transport_header(nskb);
415 sh->source = htons(packet->source_port); 416 sh->source = htons(packet->source_port);
416 sh->dest = htons(packet->destination_port); 417 sh->dest = htons(packet->destination_port);
417 418
@@ -527,15 +528,25 @@ int sctp_packet_transmit(struct sctp_packet *packet)
527 * Note: Adler-32 is no longer applicable, as has been replaced 528 * Note: Adler-32 is no longer applicable, as has been replaced
528 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. 529 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
529 */ 530 */
530 if (!sctp_checksum_disable && !(dst->dev->features & NETIF_F_NO_CSUM)) { 531 if (!sctp_checksum_disable &&
532 !(dst->dev->features & (NETIF_F_NO_CSUM | NETIF_F_SCTP_CSUM))) {
531 __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); 533 __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
532 534
533 /* 3) Put the resultant value into the checksum field in the 535 /* 3) Put the resultant value into the checksum field in the
534 * common header, and leave the rest of the bits unchanged. 536 * common header, and leave the rest of the bits unchanged.
535 */ 537 */
536 sh->checksum = sctp_end_cksum(crc32); 538 sh->checksum = sctp_end_cksum(crc32);
537 } else 539 } else {
538 nskb->ip_summed = CHECKSUM_UNNECESSARY; 540 if (dst->dev->features & NETIF_F_SCTP_CSUM) {
541 /* no need to seed psuedo checksum for SCTP */
542 nskb->ip_summed = CHECKSUM_PARTIAL;
543 nskb->csum_start = (skb_transport_header(nskb) -
544 nskb->head);
545 nskb->csum_offset = offsetof(struct sctphdr, checksum);
546 } else {
547 nskb->ip_summed = CHECKSUM_UNNECESSARY;
548 }
549 }
539 550
540 /* IP layer ECN support 551 /* IP layer ECN support
541 * From RFC 2481 552 * From RFC 2481
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 8eb3e61cb701..79cbd47f4df7 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -393,7 +393,7 @@ static int sctp_v4_addr_valid(union sctp_addr *addr,
393 return 0; 393 return 0;
394 394
395 /* Is this a broadcast address? */ 395 /* Is this a broadcast address? */
396 if (skb && skb->rtable->rt_flags & RTCF_BROADCAST) 396 if (skb && skb_rtable(skb)->rt_flags & RTCF_BROADCAST)
397 return 0; 397 return 0;
398 398
399 return 1; 399 return 1;
@@ -572,7 +572,7 @@ static void sctp_v4_get_saddr(struct sctp_sock *sk,
572/* What interface did this skb arrive on? */ 572/* What interface did this skb arrive on? */
573static int sctp_v4_skb_iif(const struct sk_buff *skb) 573static int sctp_v4_skb_iif(const struct sk_buff *skb)
574{ 574{
575 return skb->rtable->rt_iif; 575 return skb_rtable(skb)->rt_iif;
576} 576}
577 577
578/* Was this packet marked by Explicit Congestion Notification? */ 578/* Was this packet marked by Explicit Congestion Notification? */
@@ -848,8 +848,8 @@ static inline int sctp_v4_xmit(struct sk_buff *skb,
848 848
849 SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n", 849 SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n",
850 __func__, skb, skb->len, 850 __func__, skb, skb->len,
851 &skb->rtable->rt_src, 851 &skb_rtable(skb)->rt_src,
852 &skb->rtable->rt_dst); 852 &skb_rtable(skb)->rt_dst);
853 853
854 inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ? 854 inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ?
855 IP_PMTUDISC_DO : IP_PMTUDISC_DONT; 855 IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
@@ -1370,6 +1370,8 @@ SCTP_STATIC __exit void sctp_exit(void)
1370 sctp_proc_exit(); 1370 sctp_proc_exit();
1371 cleanup_sctp_mibs(); 1371 cleanup_sctp_mibs();
1372 1372
1373 rcu_barrier(); /* Wait for completion of call_rcu()'s */
1374
1373 kmem_cache_destroy(sctp_chunk_cachep); 1375 kmem_cache_destroy(sctp_chunk_cachep);
1374 kmem_cache_destroy(sctp_bucket_cachep); 1376 kmem_cache_destroy(sctp_bucket_cachep);
1375} 1377}
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 6851ee94e974..61cc6075b0df 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2864,19 +2864,19 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
2864 switch (addr_param->v4.param_hdr.type) { 2864 switch (addr_param->v4.param_hdr.type) {
2865 case SCTP_PARAM_IPV6_ADDRESS: 2865 case SCTP_PARAM_IPV6_ADDRESS:
2866 if (!asoc->peer.ipv6_address) 2866 if (!asoc->peer.ipv6_address)
2867 return SCTP_ERROR_INV_PARAM; 2867 return SCTP_ERROR_DNS_FAILED;
2868 break; 2868 break;
2869 case SCTP_PARAM_IPV4_ADDRESS: 2869 case SCTP_PARAM_IPV4_ADDRESS:
2870 if (!asoc->peer.ipv4_address) 2870 if (!asoc->peer.ipv4_address)
2871 return SCTP_ERROR_INV_PARAM; 2871 return SCTP_ERROR_DNS_FAILED;
2872 break; 2872 break;
2873 default: 2873 default:
2874 return SCTP_ERROR_INV_PARAM; 2874 return SCTP_ERROR_DNS_FAILED;
2875 } 2875 }
2876 2876
2877 af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type)); 2877 af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type));
2878 if (unlikely(!af)) 2878 if (unlikely(!af))
2879 return SCTP_ERROR_INV_PARAM; 2879 return SCTP_ERROR_DNS_FAILED;
2880 2880
2881 af->from_addr_param(&addr, addr_param, htons(asoc->peer.port), 0); 2881 af->from_addr_param(&addr, addr_param, htons(asoc->peer.port), 0);
2882 2882
@@ -2886,7 +2886,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
2886 * make sure we check for that) 2886 * make sure we check for that)
2887 */ 2887 */
2888 if (!af->is_any(&addr) && !af->addr_valid(&addr, NULL, asconf->skb)) 2888 if (!af->is_any(&addr) && !af->addr_valid(&addr, NULL, asconf->skb))
2889 return SCTP_ERROR_INV_PARAM; 2889 return SCTP_ERROR_DNS_FAILED;
2890 2890
2891 switch (asconf_param->param_hdr.type) { 2891 switch (asconf_param->param_hdr.type) {
2892 case SCTP_PARAM_ADD_IP: 2892 case SCTP_PARAM_ADD_IP:
@@ -2954,12 +2954,12 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
2954 2954
2955 peer = sctp_assoc_lookup_paddr(asoc, &addr); 2955 peer = sctp_assoc_lookup_paddr(asoc, &addr);
2956 if (!peer) 2956 if (!peer)
2957 return SCTP_ERROR_INV_PARAM; 2957 return SCTP_ERROR_DNS_FAILED;
2958 2958
2959 sctp_assoc_set_primary(asoc, peer); 2959 sctp_assoc_set_primary(asoc, peer);
2960 break; 2960 break;
2961 default: 2961 default:
2962 return SCTP_ERROR_INV_PARAM; 2962 return SCTP_ERROR_UNKNOWN_PARAM;
2963 break; 2963 break;
2964 } 2964 }
2965 2965
@@ -3273,7 +3273,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
3273 retval = 1; 3273 retval = 1;
3274 break; 3274 break;
3275 3275
3276 case SCTP_ERROR_INV_PARAM: 3276 case SCTP_ERROR_UNKNOWN_PARAM:
3277 /* Disable sending this type of asconf parameter in 3277 /* Disable sending this type of asconf parameter in
3278 * future. 3278 * future.
3279 */ 3279 */
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index e2020eb2c8ca..86426aac1600 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -686,7 +686,8 @@ static void sctp_cmd_setup_t2(sctp_cmd_seq_t *cmds,
686{ 686{
687 struct sctp_transport *t; 687 struct sctp_transport *t;
688 688
689 t = sctp_assoc_choose_shutdown_transport(asoc); 689 t = sctp_assoc_choose_alter_transport(asoc,
690 asoc->shutdown_last_sent_to);
690 asoc->shutdown_last_sent_to = t; 691 asoc->shutdown_last_sent_to = t;
691 asoc->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = t->rto; 692 asoc->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = t->rto;
692 chunk->transport = t; 693 chunk->transport = t;
@@ -777,7 +778,7 @@ static void sctp_cmd_setup_t4(sctp_cmd_seq_t *cmds,
777{ 778{
778 struct sctp_transport *t; 779 struct sctp_transport *t;
779 780
780 t = asoc->peer.active_path; 781 t = sctp_assoc_choose_alter_transport(asoc, chunk->transport);
781 asoc->timeouts[SCTP_EVENT_TIMEOUT_T4_RTO] = t->rto; 782 asoc->timeouts[SCTP_EVENT_TIMEOUT_T4_RTO] = t->rto;
782 chunk->transport = t; 783 chunk->transport = t;
783} 784}
@@ -1379,7 +1380,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1379 1380
1380 case SCTP_CMD_INIT_CHOOSE_TRANSPORT: 1381 case SCTP_CMD_INIT_CHOOSE_TRANSPORT:
1381 chunk = cmd->obj.ptr; 1382 chunk = cmd->obj.ptr;
1382 t = sctp_assoc_choose_init_transport(asoc); 1383 t = sctp_assoc_choose_alter_transport(asoc,
1384 asoc->init_last_sent_to);
1383 asoc->init_last_sent_to = t; 1385 asoc->init_last_sent_to = t;
1384 chunk->transport = t; 1386 chunk->transport = t;
1385 t->init_sent_count++; 1387 t->init_sent_count++;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 55a61aa69662..7288192f7df5 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -5432,9 +5432,13 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep,
5432 if (!reply) 5432 if (!reply)
5433 goto nomem; 5433 goto nomem;
5434 5434
5435 /* Do some failure management (Section 8.2). */ 5435 /* Do some failure management (Section 8.2).
5436 sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE, 5436 * If we remove the transport an SHUTDOWN was last sent to, don't
5437 SCTP_TRANSPORT(asoc->shutdown_last_sent_to)); 5437 * do failure management.
5438 */
5439 if (asoc->shutdown_last_sent_to)
5440 sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE,
5441 SCTP_TRANSPORT(asoc->shutdown_last_sent_to));
5438 5442
5439 /* Set the transport for the SHUTDOWN/ACK chunk and the timeout for 5443 /* Set the transport for the SHUTDOWN/ACK chunk and the timeout for
5440 * the T2-shutdown timer. 5444 * the T2-shutdown timer.
@@ -5471,7 +5475,9 @@ sctp_disposition_t sctp_sf_t4_timer_expire(
5471 * detection on the appropriate destination address as defined in 5475 * detection on the appropriate destination address as defined in
5472 * RFC2960 [5] section 8.1 and 8.2. 5476 * RFC2960 [5] section 8.1 and 8.2.
5473 */ 5477 */
5474 sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE, SCTP_TRANSPORT(transport)); 5478 if (transport)
5479 sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE,
5480 SCTP_TRANSPORT(transport));
5475 5481
5476 /* Reconfig T4 timer and transport. */ 5482 /* Reconfig T4 timer and transport. */
5477 sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T4, SCTP_CHUNK(chunk)); 5483 sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T4, SCTP_CHUNK(chunk));
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index 5c8186d88c61..6d9b3aafcc5d 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -698,7 +698,7 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
698 TYPE_SCTP_FUNC(sctp_sf_do_prm_asconf), \ 698 TYPE_SCTP_FUNC(sctp_sf_do_prm_asconf), \
699 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 699 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
700 TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \ 700 TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
701} /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */ 701} /* TYPE_SCTP_PRIMITIVE_ASCONF */
702 702
703/* The primary index for this table is the primitive type. 703/* The primary index for this table is the primitive type.
704 * The secondary index for this table is the state. 704 * The secondary index for this table is the state.
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 5fb3a8c9792e..971890dbfea0 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -130,7 +130,7 @@ static inline int sctp_wspace(struct sctp_association *asoc)
130 if (asoc->ep->sndbuf_policy) 130 if (asoc->ep->sndbuf_policy)
131 amt = asoc->sndbuf_used; 131 amt = asoc->sndbuf_used;
132 else 132 else
133 amt = atomic_read(&asoc->base.sk->sk_wmem_alloc); 133 amt = sk_wmem_alloc_get(asoc->base.sk);
134 134
135 if (amt >= asoc->base.sk->sk_sndbuf) { 135 if (amt >= asoc->base.sk->sk_sndbuf) {
136 if (asoc->base.sk->sk_userlocks & SOCK_SNDBUF_LOCK) 136 if (asoc->base.sk->sk_userlocks & SOCK_SNDBUF_LOCK)
@@ -1100,6 +1100,15 @@ static int __sctp_connect(struct sock* sk,
1100 goto out_free; 1100 goto out_free;
1101 } 1101 }
1102 1102
1103 /* In case the user of sctp_connectx() wants an association
1104 * id back, assign one now.
1105 */
1106 if (assoc_id) {
1107 err = sctp_assoc_set_id(asoc, GFP_KERNEL);
1108 if (err < 0)
1109 goto out_free;
1110 }
1111
1103 err = sctp_primitive_ASSOCIATE(asoc, NULL); 1112 err = sctp_primitive_ASSOCIATE(asoc, NULL);
1104 if (err < 0) { 1113 if (err < 0) {
1105 goto out_free; 1114 goto out_free;
@@ -1120,7 +1129,7 @@ static int __sctp_connect(struct sock* sk,
1120 timeo = sock_sndtimeo(sk, f_flags & O_NONBLOCK); 1129 timeo = sock_sndtimeo(sk, f_flags & O_NONBLOCK);
1121 1130
1122 err = sctp_wait_for_connect(asoc, &timeo); 1131 err = sctp_wait_for_connect(asoc, &timeo);
1123 if (!err && assoc_id) 1132 if ((err == 0 || err == -EINPROGRESS) && assoc_id)
1124 *assoc_id = asoc->assoc_id; 1133 *assoc_id = asoc->assoc_id;
1125 1134
1126 /* Don't free association on exit. */ 1135 /* Don't free association on exit. */
@@ -1264,6 +1273,34 @@ SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk,
1264 return assoc_id; 1273 return assoc_id;
1265} 1274}
1266 1275
1276/*
1277 * New (hopefully final) interface for the API. The option buffer is used
1278 * both for the returned association id and the addresses.
1279 */
1280SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len,
1281 char __user *optval,
1282 int __user *optlen)
1283{
1284 sctp_assoc_t assoc_id = 0;
1285 int err = 0;
1286
1287 if (len < sizeof(assoc_id))
1288 return -EINVAL;
1289
1290 err = __sctp_setsockopt_connectx(sk,
1291 (struct sockaddr __user *)(optval + sizeof(assoc_id)),
1292 len - sizeof(assoc_id), &assoc_id);
1293
1294 if (err == 0 || err == -EINPROGRESS) {
1295 if (copy_to_user(optval, &assoc_id, sizeof(assoc_id)))
1296 return -EFAULT;
1297 if (put_user(sizeof(assoc_id), optlen))
1298 return -EFAULT;
1299 }
1300
1301 return err;
1302}
1303
1267/* API 3.1.4 close() - UDP Style Syntax 1304/* API 3.1.4 close() - UDP Style Syntax
1268 * Applications use close() to perform graceful shutdown (as described in 1305 * Applications use close() to perform graceful shutdown (as described in
1269 * Section 10.1 of [SCTP]) on ALL the associations currently represented 1306 * Section 10.1 of [SCTP]) on ALL the associations currently represented
@@ -1844,7 +1881,7 @@ static int sctp_skb_pull(struct sk_buff *skb, int len)
1844 len -= skb_len; 1881 len -= skb_len;
1845 __skb_pull(skb, skb_len); 1882 __skb_pull(skb, skb_len);
1846 1883
1847 for (list = skb_shinfo(skb)->frag_list; list; list = list->next) { 1884 skb_walk_frags(skb, list) {
1848 rlen = sctp_skb_pull(list, len); 1885 rlen = sctp_skb_pull(list, len);
1849 skb->len -= (len-rlen); 1886 skb->len -= (len-rlen);
1850 skb->data_len -= (len-rlen); 1887 skb->data_len -= (len-rlen);
@@ -5578,6 +5615,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
5578 retval = sctp_getsockopt_local_addrs(sk, len, optval, 5615 retval = sctp_getsockopt_local_addrs(sk, len, optval,
5579 optlen); 5616 optlen);
5580 break; 5617 break;
5618 case SCTP_SOCKOPT_CONNECTX3:
5619 retval = sctp_getsockopt_connectx3(sk, len, optval, optlen);
5620 break;
5581 case SCTP_DEFAULT_SEND_PARAM: 5621 case SCTP_DEFAULT_SEND_PARAM:
5582 retval = sctp_getsockopt_default_send_param(sk, len, 5622 retval = sctp_getsockopt_default_send_param(sk, len,
5583 optval, optlen); 5623 optval, optlen);
@@ -6483,7 +6523,7 @@ static int sctp_writeable(struct sock *sk)
6483{ 6523{
6484 int amt = 0; 6524 int amt = 0;
6485 6525
6486 amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); 6526 amt = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
6487 if (amt < 0) 6527 if (amt < 0)
6488 amt = 0; 6528 amt = 0;
6489 return amt; 6529 return amt;
@@ -6612,21 +6652,6 @@ static void sctp_wait_for_close(struct sock *sk, long timeout)
6612 finish_wait(sk->sk_sleep, &wait); 6652 finish_wait(sk->sk_sleep, &wait);
6613} 6653}
6614 6654
6615static void sctp_sock_rfree_frag(struct sk_buff *skb)
6616{
6617 struct sk_buff *frag;
6618
6619 if (!skb->data_len)
6620 goto done;
6621
6622 /* Don't forget the fragments. */
6623 for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next)
6624 sctp_sock_rfree_frag(frag);
6625
6626done:
6627 sctp_sock_rfree(skb);
6628}
6629
6630static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk) 6655static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk)
6631{ 6656{
6632 struct sk_buff *frag; 6657 struct sk_buff *frag;
@@ -6635,7 +6660,7 @@ static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk)
6635 goto done; 6660 goto done;
6636 6661
6637 /* Don't forget the fragments. */ 6662 /* Don't forget the fragments. */
6638 for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) 6663 skb_walk_frags(skb, frag)
6639 sctp_skb_set_owner_r_frag(frag, sk); 6664 sctp_skb_set_owner_r_frag(frag, sk);
6640 6665
6641done: 6666done:
@@ -6736,7 +6761,6 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
6736 sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) { 6761 sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) {
6737 event = sctp_skb2event(skb); 6762 event = sctp_skb2event(skb);
6738 if (event->asoc == assoc) { 6763 if (event->asoc == assoc) {
6739 sctp_sock_rfree_frag(skb);
6740 __skb_unlink(skb, &oldsk->sk_receive_queue); 6764 __skb_unlink(skb, &oldsk->sk_receive_queue);
6741 __skb_queue_tail(&newsk->sk_receive_queue, skb); 6765 __skb_queue_tail(&newsk->sk_receive_queue, skb);
6742 sctp_skb_set_owner_r_frag(skb, newsk); 6766 sctp_skb_set_owner_r_frag(skb, newsk);
@@ -6767,7 +6791,6 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
6767 sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) { 6791 sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) {
6768 event = sctp_skb2event(skb); 6792 event = sctp_skb2event(skb);
6769 if (event->asoc == assoc) { 6793 if (event->asoc == assoc) {
6770 sctp_sock_rfree_frag(skb);
6771 __skb_unlink(skb, &oldsp->pd_lobby); 6794 __skb_unlink(skb, &oldsp->pd_lobby);
6772 __skb_queue_tail(queue, skb); 6795 __skb_queue_tail(queue, skb);
6773 sctp_skb_set_owner_r_frag(skb, newsk); 6796 sctp_skb_set_owner_r_frag(skb, newsk);
@@ -6782,15 +6805,11 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
6782 6805
6783 } 6806 }
6784 6807
6785 sctp_skb_for_each(skb, &assoc->ulpq.reasm, tmp) { 6808 sctp_skb_for_each(skb, &assoc->ulpq.reasm, tmp)
6786 sctp_sock_rfree_frag(skb);
6787 sctp_skb_set_owner_r_frag(skb, newsk); 6809 sctp_skb_set_owner_r_frag(skb, newsk);
6788 }
6789 6810
6790 sctp_skb_for_each(skb, &assoc->ulpq.lobby, tmp) { 6811 sctp_skb_for_each(skb, &assoc->ulpq.lobby, tmp)
6791 sctp_sock_rfree_frag(skb);
6792 sctp_skb_set_owner_r_frag(skb, newsk); 6812 sctp_skb_set_owner_r_frag(skb, newsk);
6793 }
6794 6813
6795 /* Set the type of socket to indicate that it is peeled off from the 6814 /* Set the type of socket to indicate that it is peeled off from the
6796 * original UDP-style socket or created with the accept() call on a 6815 * original UDP-style socket or created with the accept() call on a
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index f58e994e6852..63eabbc71298 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -49,8 +49,8 @@ static int zero = 0;
49static int one = 1; 49static int one = 1;
50static int timer_max = 86400000; /* ms in one day */ 50static int timer_max = 86400000; /* ms in one day */
51static int int_max = INT_MAX; 51static int int_max = INT_MAX;
52static long sack_timer_min = 1; 52static int sack_timer_min = 1;
53static long sack_timer_max = 500; 53static int sack_timer_max = 500;
54 54
55extern int sysctl_sctp_mem[3]; 55extern int sysctl_sctp_mem[3];
56extern int sysctl_sctp_rmem[3]; 56extern int sysctl_sctp_rmem[3];
@@ -223,7 +223,7 @@ static ctl_table sctp_table[] = {
223 .ctl_name = NET_SCTP_SACK_TIMEOUT, 223 .ctl_name = NET_SCTP_SACK_TIMEOUT,
224 .procname = "sack_timeout", 224 .procname = "sack_timeout",
225 .data = &sctp_sack_timeout, 225 .data = &sctp_sack_timeout,
226 .maxlen = sizeof(long), 226 .maxlen = sizeof(int),
227 .mode = 0644, 227 .mode = 0644,
228 .proc_handler = proc_dointvec_minmax, 228 .proc_handler = proc_dointvec_minmax,
229 .strategy = sysctl_intvec, 229 .strategy = sysctl_intvec,
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index 5f186ca550d7..8b3560fd876d 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -976,9 +976,8 @@ static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event,
976 * In general, the skb passed from IP can have only 1 level of 976 * In general, the skb passed from IP can have only 1 level of
977 * fragments. But we allow multiple levels of fragments. 977 * fragments. But we allow multiple levels of fragments.
978 */ 978 */
979 for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { 979 skb_walk_frags(skb, frag)
980 sctp_ulpevent_receive_data(sctp_skb2event(frag), asoc); 980 sctp_ulpevent_receive_data(sctp_skb2event(frag), asoc);
981 }
982} 981}
983 982
984/* Do accounting for bytes just read by user and release the references to 983/* Do accounting for bytes just read by user and release the references to
@@ -1003,7 +1002,7 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event)
1003 goto done; 1002 goto done;
1004 1003
1005 /* Don't forget the fragments. */ 1004 /* Don't forget the fragments. */
1006 for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { 1005 skb_walk_frags(skb, frag) {
1007 /* NOTE: skb_shinfos are recursive. Although IP returns 1006 /* NOTE: skb_shinfos are recursive. Although IP returns
1008 * skb's with only 1 level of fragments, SCTP reassembly can 1007 * skb's with only 1 level of fragments, SCTP reassembly can
1009 * increase the levels. 1008 * increase the levels.
@@ -1026,7 +1025,7 @@ static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event)
1026 goto done; 1025 goto done;
1027 1026
1028 /* Don't forget the fragments. */ 1027 /* Don't forget the fragments. */
1029 for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { 1028 skb_walk_frags(skb, frag) {
1030 /* NOTE: skb_shinfos are recursive. Although IP returns 1029 /* NOTE: skb_shinfos are recursive. Although IP returns
1031 * skb's with only 1 level of fragments, SCTP reassembly can 1030 * skb's with only 1 level of fragments, SCTP reassembly can
1032 * increase the levels. 1031 * increase the levels.