aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/associola.c8
-rw-r--r--net/sctp/bind_addr.c17
-rw-r--r--net/sctp/input.c3
-rw-r--r--net/sctp/ipv6.c2
-rw-r--r--net/sctp/output.c8
-rw-r--r--net/sctp/outqueue.c19
-rw-r--r--net/sctp/protocol.c155
-rw-r--r--net/sctp/sm_make_chunk.c55
-rw-r--r--net/sctp/sm_sideeffect.c7
-rw-r--r--net/sctp/sm_statefuns.c57
-rw-r--r--net/sctp/socket.c202
-rw-r--r--net/sctp/sysctl.c20
12 files changed, 469 insertions, 84 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 4a62888f2e4..49814827f81 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -173,7 +173,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
173 asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; 173 asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
174 asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay; 174 asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay;
175 asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = 175 asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
176 (unsigned long)sp->autoclose * HZ; 176 min_t(unsigned long, sp->autoclose, sctp_max_autoclose) * HZ;
177 177
178 /* Initializes the timers */ 178 /* Initializes the timers */
179 for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) 179 for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i)
@@ -280,6 +280,8 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
280 asoc->peer.asconf_capable = 0; 280 asoc->peer.asconf_capable = 0;
281 if (sctp_addip_noauth) 281 if (sctp_addip_noauth)
282 asoc->peer.asconf_capable = 1; 282 asoc->peer.asconf_capable = 1;
283 asoc->asconf_addr_del_pending = NULL;
284 asoc->src_out_of_asoc_ok = 0;
283 285
284 /* Create an input queue. */ 286 /* Create an input queue. */
285 sctp_inq_init(&asoc->base.inqueue); 287 sctp_inq_init(&asoc->base.inqueue);
@@ -446,6 +448,10 @@ void sctp_association_free(struct sctp_association *asoc)
446 448
447 sctp_asconf_queue_teardown(asoc); 449 sctp_asconf_queue_teardown(asoc);
448 450
451 /* Free pending address space being deleted */
452 if (asoc->asconf_addr_del_pending != NULL)
453 kfree(asoc->asconf_addr_del_pending);
454
449 /* AUTH - Free the endpoint shared keys */ 455 /* AUTH - Free the endpoint shared keys */
450 sctp_auth_destroy_keys(&asoc->endpoint_shared_keys); 456 sctp_auth_destroy_keys(&asoc->endpoint_shared_keys);
451 457
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index 83e3011c19c..4ece451c8d2 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -430,7 +430,7 @@ union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr *bp,
430 list_for_each_entry(laddr, &bp->address_list, list) { 430 list_for_each_entry(laddr, &bp->address_list, list) {
431 addr_buf = (union sctp_addr *)addrs; 431 addr_buf = (union sctp_addr *)addrs;
432 for (i = 0; i < addrcnt; i++) { 432 for (i = 0; i < addrcnt; i++) {
433 addr = (union sctp_addr *)addr_buf; 433 addr = addr_buf;
434 af = sctp_get_af_specific(addr->v4.sin_family); 434 af = sctp_get_af_specific(addr->v4.sin_family);
435 if (!af) 435 if (!af)
436 break; 436 break;
@@ -534,6 +534,21 @@ int sctp_in_scope(const union sctp_addr *addr, sctp_scope_t scope)
534 return 0; 534 return 0;
535} 535}
536 536
537int sctp_is_ep_boundall(struct sock *sk)
538{
539 struct sctp_bind_addr *bp;
540 struct sctp_sockaddr_entry *addr;
541
542 bp = &sctp_sk(sk)->ep->base.bind_addr;
543 if (sctp_list_single_entry(&bp->address_list)) {
544 addr = list_entry(bp->address_list.next,
545 struct sctp_sockaddr_entry, list);
546 if (sctp_is_any(sk, &addr->a))
547 return 1;
548 }
549 return 0;
550}
551
537/******************************************************************** 552/********************************************************************
538 * 3rd Level Abstractions 553 * 3rd Level Abstractions
539 ********************************************************************/ 554 ********************************************************************/
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 741ed164883..b7692aab6e9 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -510,8 +510,7 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
510 * discard the packet. 510 * discard the packet.
511 */ 511 */
512 if (vtag == 0) { 512 if (vtag == 0) {
513 chunkhdr = (struct sctp_init_chunk *)((void *)sctphdr 513 chunkhdr = (void *)sctphdr + sizeof(struct sctphdr);
514 + sizeof(struct sctphdr));
515 if (len < sizeof(struct sctphdr) + sizeof(sctp_chunkhdr_t) 514 if (len < sizeof(struct sctphdr) + sizeof(sctp_chunkhdr_t)
516 + sizeof(__be32) || 515 + sizeof(__be32) ||
517 chunkhdr->chunk_hdr.type != SCTP_CID_INIT || 516 chunkhdr->chunk_hdr.type != SCTP_CID_INIT ||
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 0bb0d7cb9f1..aabaee41dd3 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -112,6 +112,7 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
112 addr->valid = 1; 112 addr->valid = 1;
113 spin_lock_bh(&sctp_local_addr_lock); 113 spin_lock_bh(&sctp_local_addr_lock);
114 list_add_tail_rcu(&addr->list, &sctp_local_addr_list); 114 list_add_tail_rcu(&addr->list, &sctp_local_addr_list);
115 sctp_addr_wq_mgmt(addr, SCTP_ADDR_NEW);
115 spin_unlock_bh(&sctp_local_addr_lock); 116 spin_unlock_bh(&sctp_local_addr_lock);
116 } 117 }
117 break; 118 break;
@@ -122,6 +123,7 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
122 if (addr->a.sa.sa_family == AF_INET6 && 123 if (addr->a.sa.sa_family == AF_INET6 &&
123 ipv6_addr_equal(&addr->a.v6.sin6_addr, 124 ipv6_addr_equal(&addr->a.v6.sin6_addr,
124 &ifa->addr)) { 125 &ifa->addr)) {
126 sctp_addr_wq_mgmt(addr, SCTP_ADDR_DEL);
125 found = 1; 127 found = 1;
126 addr->valid = 0; 128 addr->valid = 0;
127 list_del_rcu(&addr->list); 129 list_del_rcu(&addr->list);
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 08b3cead650..817174eb5f4 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -697,13 +697,7 @@ static void sctp_packet_append_data(struct sctp_packet *packet,
697 /* Keep track of how many bytes are in flight to the receiver. */ 697 /* Keep track of how many bytes are in flight to the receiver. */
698 asoc->outqueue.outstanding_bytes += datasize; 698 asoc->outqueue.outstanding_bytes += datasize;
699 699
700 /* Update our view of the receiver's rwnd. Include sk_buff overhead 700 /* Update our view of the receiver's rwnd. */
701 * while updating peer.rwnd so that it reduces the chances of a
702 * receiver running out of receive buffer space even when receive
703 * window is still open. This can happen when a sender is sending
704 * sending small messages.
705 */
706 datasize += sizeof(struct sk_buff);
707 if (datasize < rwnd) 701 if (datasize < rwnd)
708 rwnd -= datasize; 702 rwnd -= datasize;
709 else 703 else
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index d03682109b7..6edd7deb1ad 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -411,8 +411,7 @@ void sctp_retransmit_mark(struct sctp_outq *q,
411 chunk->transport->flight_size -= 411 chunk->transport->flight_size -=
412 sctp_data_size(chunk); 412 sctp_data_size(chunk);
413 q->outstanding_bytes -= sctp_data_size(chunk); 413 q->outstanding_bytes -= sctp_data_size(chunk);
414 q->asoc->peer.rwnd += (sctp_data_size(chunk) + 414 q->asoc->peer.rwnd += sctp_data_size(chunk);
415 sizeof(struct sk_buff));
416 } 415 }
417 continue; 416 continue;
418 } 417 }
@@ -432,8 +431,7 @@ void sctp_retransmit_mark(struct sctp_outq *q,
432 * (Section 7.2.4)), add the data size of those 431 * (Section 7.2.4)), add the data size of those
433 * chunks to the rwnd. 432 * chunks to the rwnd.
434 */ 433 */
435 q->asoc->peer.rwnd += (sctp_data_size(chunk) + 434 q->asoc->peer.rwnd += sctp_data_size(chunk);
436 sizeof(struct sk_buff));
437 q->outstanding_bytes -= sctp_data_size(chunk); 435 q->outstanding_bytes -= sctp_data_size(chunk);
438 if (chunk->transport) 436 if (chunk->transport)
439 transport->flight_size -= sctp_data_size(chunk); 437 transport->flight_size -= sctp_data_size(chunk);
@@ -754,6 +752,16 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
754 */ 752 */
755 753
756 list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) { 754 list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) {
755 /* RFC 5061, 5.3
756 * F1) This means that until such time as the ASCONF
757 * containing the add is acknowledged, the sender MUST
758 * NOT use the new IP address as a source for ANY SCTP
759 * packet except on carrying an ASCONF Chunk.
760 */
761 if (asoc->src_out_of_asoc_ok &&
762 chunk->chunk_hdr->type != SCTP_CID_ASCONF)
763 continue;
764
757 list_del_init(&chunk->list); 765 list_del_init(&chunk->list);
758 766
759 /* Pick the right transport to use. */ 767 /* Pick the right transport to use. */
@@ -881,6 +889,9 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
881 } 889 }
882 } 890 }
883 891
892 if (q->asoc->src_out_of_asoc_ok)
893 goto sctp_flush_out;
894
884 /* Is it OK to send data chunks? */ 895 /* Is it OK to send data chunks? */
885 switch (asoc->state) { 896 switch (asoc->state) {
886 case SCTP_STATE_COOKIE_ECHOED: 897 case SCTP_STATE_COOKIE_ECHOED:
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 207175b2f40..48cb7b98b11 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -503,7 +503,9 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
503 sctp_v4_dst_saddr(&dst_saddr, fl4, htons(bp->port)); 503 sctp_v4_dst_saddr(&dst_saddr, fl4, htons(bp->port));
504 rcu_read_lock(); 504 rcu_read_lock();
505 list_for_each_entry_rcu(laddr, &bp->address_list, list) { 505 list_for_each_entry_rcu(laddr, &bp->address_list, list) {
506 if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC)) 506 if (!laddr->valid || (laddr->state == SCTP_ADDR_DEL) ||
507 (laddr->state != SCTP_ADDR_SRC &&
508 !asoc->src_out_of_asoc_ok))
507 continue; 509 continue;
508 if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a)) 510 if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a))
509 goto out_unlock; 511 goto out_unlock;
@@ -623,6 +625,143 @@ static void sctp_v4_ecn_capable(struct sock *sk)
623 INET_ECN_xmit(sk); 625 INET_ECN_xmit(sk);
624} 626}
625 627
628void sctp_addr_wq_timeout_handler(unsigned long arg)
629{
630 struct sctp_sockaddr_entry *addrw, *temp;
631 struct sctp_sock *sp;
632
633 spin_lock_bh(&sctp_addr_wq_lock);
634
635 list_for_each_entry_safe(addrw, temp, &sctp_addr_waitq, list) {
636 SCTP_DEBUG_PRINTK_IPADDR("sctp_addrwq_timo_handler: the first ent in wq %p is ",
637 " for cmd %d at entry %p\n", &sctp_addr_waitq, &addrw->a, addrw->state,
638 addrw);
639
640#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
641 /* Now we send an ASCONF for each association */
642 /* Note. we currently don't handle link local IPv6 addressees */
643 if (addrw->a.sa.sa_family == AF_INET6) {
644 struct in6_addr *in6;
645
646 if (ipv6_addr_type(&addrw->a.v6.sin6_addr) &
647 IPV6_ADDR_LINKLOCAL)
648 goto free_next;
649
650 in6 = (struct in6_addr *)&addrw->a.v6.sin6_addr;
651 if (ipv6_chk_addr(&init_net, in6, NULL, 0) == 0 &&
652 addrw->state == SCTP_ADDR_NEW) {
653 unsigned long timeo_val;
654
655 SCTP_DEBUG_PRINTK("sctp_timo_handler: this is on DAD, trying %d sec later\n",
656 SCTP_ADDRESS_TICK_DELAY);
657 timeo_val = jiffies;
658 timeo_val += msecs_to_jiffies(SCTP_ADDRESS_TICK_DELAY);
659 mod_timer(&sctp_addr_wq_timer, timeo_val);
660 break;
661 }
662 }
663#endif
664 list_for_each_entry(sp, &sctp_auto_asconf_splist, auto_asconf_list) {
665 struct sock *sk;
666
667 sk = sctp_opt2sk(sp);
668 /* ignore bound-specific endpoints */
669 if (!sctp_is_ep_boundall(sk))
670 continue;
671 sctp_bh_lock_sock(sk);
672 if (sctp_asconf_mgmt(sp, addrw) < 0)
673 SCTP_DEBUG_PRINTK("sctp_addrwq_timo_handler: sctp_asconf_mgmt failed\n");
674 sctp_bh_unlock_sock(sk);
675 }
676free_next:
677 list_del(&addrw->list);
678 kfree(addrw);
679 }
680 spin_unlock_bh(&sctp_addr_wq_lock);
681}
682
683static void sctp_free_addr_wq(void)
684{
685 struct sctp_sockaddr_entry *addrw;
686 struct sctp_sockaddr_entry *temp;
687
688 spin_lock_bh(&sctp_addr_wq_lock);
689 del_timer(&sctp_addr_wq_timer);
690 list_for_each_entry_safe(addrw, temp, &sctp_addr_waitq, list) {
691 list_del(&addrw->list);
692 kfree(addrw);
693 }
694 spin_unlock_bh(&sctp_addr_wq_lock);
695}
696
697/* lookup the entry for the same address in the addr_waitq
698 * sctp_addr_wq MUST be locked
699 */
700static struct sctp_sockaddr_entry *sctp_addr_wq_lookup(struct sctp_sockaddr_entry *addr)
701{
702 struct sctp_sockaddr_entry *addrw;
703
704 list_for_each_entry(addrw, &sctp_addr_waitq, list) {
705 if (addrw->a.sa.sa_family != addr->a.sa.sa_family)
706 continue;
707 if (addrw->a.sa.sa_family == AF_INET) {
708 if (addrw->a.v4.sin_addr.s_addr ==
709 addr->a.v4.sin_addr.s_addr)
710 return addrw;
711 } else if (addrw->a.sa.sa_family == AF_INET6) {
712 if (ipv6_addr_equal(&addrw->a.v6.sin6_addr,
713 &addr->a.v6.sin6_addr))
714 return addrw;
715 }
716 }
717 return NULL;
718}
719
720void sctp_addr_wq_mgmt(struct sctp_sockaddr_entry *addr, int cmd)
721{
722 struct sctp_sockaddr_entry *addrw;
723 unsigned long timeo_val;
724
725 /* first, we check if an opposite message already exist in the queue.
726 * If we found such message, it is removed.
727 * This operation is a bit stupid, but the DHCP client attaches the
728 * new address after a couple of addition and deletion of that address
729 */
730
731 spin_lock_bh(&sctp_addr_wq_lock);
732 /* Offsets existing events in addr_wq */
733 addrw = sctp_addr_wq_lookup(addr);
734 if (addrw) {
735 if (addrw->state != cmd) {
736 SCTP_DEBUG_PRINTK_IPADDR("sctp_addr_wq_mgmt offsets existing entry for %d ",
737 " in wq %p\n", addrw->state, &addrw->a,
738 &sctp_addr_waitq);
739 list_del(&addrw->list);
740 kfree(addrw);
741 }
742 spin_unlock_bh(&sctp_addr_wq_lock);
743 return;
744 }
745
746 /* OK, we have to add the new address to the wait queue */
747 addrw = kmemdup(addr, sizeof(struct sctp_sockaddr_entry), GFP_ATOMIC);
748 if (addrw == NULL) {
749 spin_unlock_bh(&sctp_addr_wq_lock);
750 return;
751 }
752 addrw->state = cmd;
753 list_add_tail(&addrw->list, &sctp_addr_waitq);
754 SCTP_DEBUG_PRINTK_IPADDR("sctp_addr_wq_mgmt add new entry for cmd:%d ",
755 " in wq %p\n", addrw->state, &addrw->a, &sctp_addr_waitq);
756
757 if (!timer_pending(&sctp_addr_wq_timer)) {
758 timeo_val = jiffies;
759 timeo_val += msecs_to_jiffies(SCTP_ADDRESS_TICK_DELAY);
760 mod_timer(&sctp_addr_wq_timer, timeo_val);
761 }
762 spin_unlock_bh(&sctp_addr_wq_lock);
763}
764
626/* Event handler for inet address addition/deletion events. 765/* Event handler for inet address addition/deletion events.
627 * The sctp_local_addr_list needs to be protocted by a spin lock since 766 * The sctp_local_addr_list needs to be protocted by a spin lock since
628 * multiple notifiers (say IPv4 and IPv6) may be running at the same 767 * multiple notifiers (say IPv4 and IPv6) may be running at the same
@@ -650,6 +789,7 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
650 addr->valid = 1; 789 addr->valid = 1;
651 spin_lock_bh(&sctp_local_addr_lock); 790 spin_lock_bh(&sctp_local_addr_lock);
652 list_add_tail_rcu(&addr->list, &sctp_local_addr_list); 791 list_add_tail_rcu(&addr->list, &sctp_local_addr_list);
792 sctp_addr_wq_mgmt(addr, SCTP_ADDR_NEW);
653 spin_unlock_bh(&sctp_local_addr_lock); 793 spin_unlock_bh(&sctp_local_addr_lock);
654 } 794 }
655 break; 795 break;
@@ -660,6 +800,7 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
660 if (addr->a.sa.sa_family == AF_INET && 800 if (addr->a.sa.sa_family == AF_INET &&
661 addr->a.v4.sin_addr.s_addr == 801 addr->a.v4.sin_addr.s_addr ==
662 ifa->ifa_local) { 802 ifa->ifa_local) {
803 sctp_addr_wq_mgmt(addr, SCTP_ADDR_DEL);
663 found = 1; 804 found = 1;
664 addr->valid = 0; 805 addr->valid = 0;
665 list_del_rcu(&addr->list); 806 list_del_rcu(&addr->list);
@@ -1144,6 +1285,9 @@ SCTP_STATIC __init int sctp_init(void)
1144 sctp_max_instreams = SCTP_DEFAULT_INSTREAMS; 1285 sctp_max_instreams = SCTP_DEFAULT_INSTREAMS;
1145 sctp_max_outstreams = SCTP_DEFAULT_OUTSTREAMS; 1286 sctp_max_outstreams = SCTP_DEFAULT_OUTSTREAMS;
1146 1287
1288 /* Initialize maximum autoclose timeout. */
1289 sctp_max_autoclose = INT_MAX / HZ;
1290
1147 /* Initialize handle used for association ids. */ 1291 /* Initialize handle used for association ids. */
1148 idr_init(&sctp_assocs_id); 1292 idr_init(&sctp_assocs_id);
1149 1293
@@ -1233,6 +1377,7 @@ SCTP_STATIC __init int sctp_init(void)
1233 /* Disable ADDIP by default. */ 1377 /* Disable ADDIP by default. */
1234 sctp_addip_enable = 0; 1378 sctp_addip_enable = 0;
1235 sctp_addip_noauth = 0; 1379 sctp_addip_noauth = 0;
1380 sctp_default_auto_asconf = 0;
1236 1381
1237 /* Enable PR-SCTP by default. */ 1382 /* Enable PR-SCTP by default. */
1238 sctp_prsctp_enable = 1; 1383 sctp_prsctp_enable = 1;
@@ -1257,6 +1402,13 @@ SCTP_STATIC __init int sctp_init(void)
1257 spin_lock_init(&sctp_local_addr_lock); 1402 spin_lock_init(&sctp_local_addr_lock);
1258 sctp_get_local_addr_list(); 1403 sctp_get_local_addr_list();
1259 1404
1405 /* Initialize the address event list */
1406 INIT_LIST_HEAD(&sctp_addr_waitq);
1407 INIT_LIST_HEAD(&sctp_auto_asconf_splist);
1408 spin_lock_init(&sctp_addr_wq_lock);
1409 sctp_addr_wq_timer.expires = 0;
1410 setup_timer(&sctp_addr_wq_timer, sctp_addr_wq_timeout_handler, 0);
1411
1260 status = sctp_v4_protosw_init(); 1412 status = sctp_v4_protosw_init();
1261 1413
1262 if (status) 1414 if (status)
@@ -1328,6 +1480,7 @@ SCTP_STATIC __exit void sctp_exit(void)
1328 /* Unregister with inet6/inet layers. */ 1480 /* Unregister with inet6/inet layers. */
1329 sctp_v6_del_protocol(); 1481 sctp_v6_del_protocol();
1330 sctp_v4_del_protocol(); 1482 sctp_v4_del_protocol();
1483 sctp_free_addr_wq();
1331 1484
1332 /* Free the control endpoint. */ 1485 /* Free the control endpoint. */
1333 inet_ctl_sock_destroy(sctp_ctl_sock); 1486 inet_ctl_sock_destroy(sctp_ctl_sock);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 58eb27fed4b..81db4e38535 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2768,11 +2768,12 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
2768 int addr_param_len = 0; 2768 int addr_param_len = 0;
2769 int totallen = 0; 2769 int totallen = 0;
2770 int i; 2770 int i;
2771 int del_pickup = 0;
2771 2772
2772 /* Get total length of all the address parameters. */ 2773 /* Get total length of all the address parameters. */
2773 addr_buf = addrs; 2774 addr_buf = addrs;
2774 for (i = 0; i < addrcnt; i++) { 2775 for (i = 0; i < addrcnt; i++) {
2775 addr = (union sctp_addr *)addr_buf; 2776 addr = addr_buf;
2776 af = sctp_get_af_specific(addr->v4.sin_family); 2777 af = sctp_get_af_specific(addr->v4.sin_family);
2777 addr_param_len = af->to_addr_param(addr, &addr_param); 2778 addr_param_len = af->to_addr_param(addr, &addr_param);
2778 2779
@@ -2780,6 +2781,13 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
2780 totallen += addr_param_len; 2781 totallen += addr_param_len;
2781 2782
2782 addr_buf += af->sockaddr_len; 2783 addr_buf += af->sockaddr_len;
2784 if (asoc->asconf_addr_del_pending && !del_pickup) {
2785 /* reuse the parameter length from the same scope one */
2786 totallen += paramlen;
2787 totallen += addr_param_len;
2788 del_pickup = 1;
2789 SCTP_DEBUG_PRINTK("mkasconf_update_ip: picked same-scope del_pending addr, totallen for all addresses is %d\n", totallen);
2790 }
2783 } 2791 }
2784 2792
2785 /* Create an asconf chunk with the required length. */ 2793 /* Create an asconf chunk with the required length. */
@@ -2790,7 +2798,7 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
2790 /* Add the address parameters to the asconf chunk. */ 2798 /* Add the address parameters to the asconf chunk. */
2791 addr_buf = addrs; 2799 addr_buf = addrs;
2792 for (i = 0; i < addrcnt; i++) { 2800 for (i = 0; i < addrcnt; i++) {
2793 addr = (union sctp_addr *)addr_buf; 2801 addr = addr_buf;
2794 af = sctp_get_af_specific(addr->v4.sin_family); 2802 af = sctp_get_af_specific(addr->v4.sin_family);
2795 addr_param_len = af->to_addr_param(addr, &addr_param); 2803 addr_param_len = af->to_addr_param(addr, &addr_param);
2796 param.param_hdr.type = flags; 2804 param.param_hdr.type = flags;
@@ -2802,6 +2810,17 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
2802 2810
2803 addr_buf += af->sockaddr_len; 2811 addr_buf += af->sockaddr_len;
2804 } 2812 }
2813 if (flags == SCTP_PARAM_ADD_IP && del_pickup) {
2814 addr = asoc->asconf_addr_del_pending;
2815 af = sctp_get_af_specific(addr->v4.sin_family);
2816 addr_param_len = af->to_addr_param(addr, &addr_param);
2817 param.param_hdr.type = SCTP_PARAM_DEL_IP;
2818 param.param_hdr.length = htons(paramlen + addr_param_len);
2819 param.crr_id = i;
2820
2821 sctp_addto_chunk(retval, paramlen, &param);
2822 sctp_addto_chunk(retval, addr_param_len, &addr_param);
2823 }
2805 return retval; 2824 return retval;
2806} 2825}
2807 2826
@@ -2939,8 +2958,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
2939 union sctp_addr addr; 2958 union sctp_addr addr;
2940 union sctp_addr_param *addr_param; 2959 union sctp_addr_param *addr_param;
2941 2960
2942 addr_param = (union sctp_addr_param *) 2961 addr_param = (void *)asconf_param + sizeof(sctp_addip_param_t);
2943 ((void *)asconf_param + sizeof(sctp_addip_param_t));
2944 2962
2945 if (asconf_param->param_hdr.type != SCTP_PARAM_ADD_IP && 2963 if (asconf_param->param_hdr.type != SCTP_PARAM_ADD_IP &&
2946 asconf_param->param_hdr.type != SCTP_PARAM_DEL_IP && 2964 asconf_param->param_hdr.type != SCTP_PARAM_DEL_IP &&
@@ -3014,7 +3032,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
3014 * an Error Cause TLV set to the new error code 'Request to 3032 * an Error Cause TLV set to the new error code 'Request to
3015 * Delete Source IP Address' 3033 * Delete Source IP Address'
3016 */ 3034 */
3017 if (sctp_cmp_addr_exact(sctp_source(asconf), &addr)) 3035 if (sctp_cmp_addr_exact(&asconf->source, &addr))
3018 return SCTP_ERROR_DEL_SRC_IP; 3036 return SCTP_ERROR_DEL_SRC_IP;
3019 3037
3020 /* Section 4.2.2 3038 /* Section 4.2.2
@@ -3125,7 +3143,7 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
3125 * asconf parameter. 3143 * asconf parameter.
3126 */ 3144 */
3127 length = ntohs(addr_param->p.length); 3145 length = ntohs(addr_param->p.length);
3128 asconf_param = (sctp_addip_param_t *)((void *)addr_param + length); 3146 asconf_param = (void *)addr_param + length;
3129 chunk_len -= length; 3147 chunk_len -= length;
3130 3148
3131 /* create an ASCONF_ACK chunk. 3149 /* create an ASCONF_ACK chunk.
@@ -3166,8 +3184,7 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
3166 3184
3167 /* Move to the next ASCONF param. */ 3185 /* Move to the next ASCONF param. */
3168 length = ntohs(asconf_param->param_hdr.length); 3186 length = ntohs(asconf_param->param_hdr.length);
3169 asconf_param = (sctp_addip_param_t *)((void *)asconf_param + 3187 asconf_param = (void *)asconf_param + length;
3170 length);
3171 chunk_len -= length; 3188 chunk_len -= length;
3172 } 3189 }
3173 3190
@@ -3197,8 +3214,7 @@ static void sctp_asconf_param_success(struct sctp_association *asoc,
3197 struct sctp_transport *transport; 3214 struct sctp_transport *transport;
3198 struct sctp_sockaddr_entry *saddr; 3215 struct sctp_sockaddr_entry *saddr;
3199 3216
3200 addr_param = (union sctp_addr_param *) 3217 addr_param = (void *)asconf_param + sizeof(sctp_addip_param_t);
3201 ((void *)asconf_param + sizeof(sctp_addip_param_t));
3202 3218
3203 /* We have checked the packet before, so we do not check again. */ 3219 /* We have checked the packet before, so we do not check again. */
3204 af = sctp_get_af_specific(param_type2af(addr_param->p.type)); 3220 af = sctp_get_af_specific(param_type2af(addr_param->p.type));
@@ -3224,6 +3240,11 @@ static void sctp_asconf_param_success(struct sctp_association *asoc,
3224 case SCTP_PARAM_DEL_IP: 3240 case SCTP_PARAM_DEL_IP:
3225 local_bh_disable(); 3241 local_bh_disable();
3226 sctp_del_bind_addr(bp, &addr); 3242 sctp_del_bind_addr(bp, &addr);
3243 if (asoc->asconf_addr_del_pending != NULL &&
3244 sctp_cmp_addr_exact(asoc->asconf_addr_del_pending, &addr)) {
3245 kfree(asoc->asconf_addr_del_pending);
3246 asoc->asconf_addr_del_pending = NULL;
3247 }
3227 local_bh_enable(); 3248 local_bh_enable();
3228 list_for_each_entry(transport, &asoc->peer.transport_addr_list, 3249 list_for_each_entry(transport, &asoc->peer.transport_addr_list,
3229 transports) { 3250 transports) {
@@ -3278,8 +3299,7 @@ static __be16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack,
3278 return SCTP_ERROR_NO_ERROR; 3299 return SCTP_ERROR_NO_ERROR;
3279 case SCTP_PARAM_ERR_CAUSE: 3300 case SCTP_PARAM_ERR_CAUSE:
3280 length = sizeof(sctp_addip_param_t); 3301 length = sizeof(sctp_addip_param_t);
3281 err_param = (sctp_errhdr_t *) 3302 err_param = (void *)asconf_ack_param + length;
3282 ((void *)asconf_ack_param + length);
3283 asconf_ack_len -= length; 3303 asconf_ack_len -= length;
3284 if (asconf_ack_len > 0) 3304 if (asconf_ack_len > 0)
3285 return err_param->cause; 3305 return err_param->cause;
@@ -3292,8 +3312,7 @@ static __be16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack,
3292 } 3312 }
3293 3313
3294 length = ntohs(asconf_ack_param->param_hdr.length); 3314 length = ntohs(asconf_ack_param->param_hdr.length);
3295 asconf_ack_param = (sctp_addip_param_t *) 3315 asconf_ack_param = (void *)asconf_ack_param + length;
3296 ((void *)asconf_ack_param + length);
3297 asconf_ack_len -= length; 3316 asconf_ack_len -= length;
3298 } 3317 }
3299 3318
@@ -3325,7 +3344,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
3325 * pointer to the first asconf parameter. 3344 * pointer to the first asconf parameter.
3326 */ 3345 */
3327 length = ntohs(addr_param->p.length); 3346 length = ntohs(addr_param->p.length);
3328 asconf_param = (sctp_addip_param_t *)((void *)addr_param + length); 3347 asconf_param = (void *)addr_param + length;
3329 asconf_len -= length; 3348 asconf_len -= length;
3330 3349
3331 /* ADDIP 4.1 3350 /* ADDIP 4.1
@@ -3376,11 +3395,13 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
3376 * one. 3395 * one.
3377 */ 3396 */
3378 length = ntohs(asconf_param->param_hdr.length); 3397 length = ntohs(asconf_param->param_hdr.length);
3379 asconf_param = (sctp_addip_param_t *)((void *)asconf_param + 3398 asconf_param = (void *)asconf_param + length;
3380 length);
3381 asconf_len -= length; 3399 asconf_len -= length;
3382 } 3400 }
3383 3401
3402 if (no_err && asoc->src_out_of_asoc_ok)
3403 asoc->src_out_of_asoc_ok = 0;
3404
3384 /* Free the cached last sent asconf chunk. */ 3405 /* Free the cached last sent asconf chunk. */
3385 list_del_init(&asconf->transmitted_list); 3406 list_del_init(&asconf->transmitted_list);
3386 sctp_chunk_free(asconf); 3407 sctp_chunk_free(asconf);
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 6e0f88295aa..76388b083f2 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1210,7 +1210,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1210 int local_cork = 0; 1210 int local_cork = 0;
1211 1211
1212 if (SCTP_EVENT_T_TIMEOUT != event_type) 1212 if (SCTP_EVENT_T_TIMEOUT != event_type)
1213 chunk = (struct sctp_chunk *) event_arg; 1213 chunk = event_arg;
1214 1214
1215 /* Note: This whole file is a huge candidate for rework. 1215 /* Note: This whole file is a huge candidate for rework.
1216 * For example, each command could either have its own handler, so 1216 * For example, each command could either have its own handler, so
@@ -1689,6 +1689,11 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1689 case SCTP_CMD_PURGE_ASCONF_QUEUE: 1689 case SCTP_CMD_PURGE_ASCONF_QUEUE:
1690 sctp_asconf_queue_teardown(asoc); 1690 sctp_asconf_queue_teardown(asoc);
1691 break; 1691 break;
1692
1693 case SCTP_CMD_SET_ASOC:
1694 asoc = cmd->obj.asoc;
1695 break;
1696
1692 default: 1697 default:
1693 pr_warn("Impossible command: %u, %p\n", 1698 pr_warn("Impossible command: %u, %p\n",
1694 cmd->verb, cmd->obj.ptr); 1699 cmd->verb, cmd->obj.ptr);
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 246117142b5..a0f31e6c1c6 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -2047,6 +2047,12 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep,
2047 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc)); 2047 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
2048 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); 2048 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
2049 2049
2050 /* Restore association pointer to provide SCTP command interpeter
2051 * with a valid context in case it needs to manipulate
2052 * the queues */
2053 sctp_add_cmd_sf(commands, SCTP_CMD_SET_ASOC,
2054 SCTP_ASOC((struct sctp_association *)asoc));
2055
2050 return retval; 2056 return retval;
2051 2057
2052nomem: 2058nomem:
@@ -4008,31 +4014,32 @@ sctp_disposition_t sctp_sf_eat_auth(const struct sctp_endpoint *ep,
4008 auth_hdr = (struct sctp_authhdr *)chunk->skb->data; 4014 auth_hdr = (struct sctp_authhdr *)chunk->skb->data;
4009 error = sctp_sf_authenticate(ep, asoc, type, chunk); 4015 error = sctp_sf_authenticate(ep, asoc, type, chunk);
4010 switch (error) { 4016 switch (error) {
4011 case SCTP_IERROR_AUTH_BAD_HMAC: 4017 case SCTP_IERROR_AUTH_BAD_HMAC:
4012 /* Generate the ERROR chunk and discard the rest 4018 /* Generate the ERROR chunk and discard the rest
4013 * of the packet 4019 * of the packet
4014 */ 4020 */
4015 err_chunk = sctp_make_op_error(asoc, chunk, 4021 err_chunk = sctp_make_op_error(asoc, chunk,
4016 SCTP_ERROR_UNSUP_HMAC, 4022 SCTP_ERROR_UNSUP_HMAC,
4017 &auth_hdr->hmac_id, 4023 &auth_hdr->hmac_id,
4018 sizeof(__u16), 0); 4024 sizeof(__u16), 0);
4019 if (err_chunk) { 4025 if (err_chunk) {
4020 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, 4026 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
4021 SCTP_CHUNK(err_chunk)); 4027 SCTP_CHUNK(err_chunk));
4022 } 4028 }
4023 /* Fall Through */ 4029 /* Fall Through */
4024 case SCTP_IERROR_AUTH_BAD_KEYID: 4030 case SCTP_IERROR_AUTH_BAD_KEYID:
4025 case SCTP_IERROR_BAD_SIG: 4031 case SCTP_IERROR_BAD_SIG:
4026 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); 4032 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
4027 break; 4033
4028 case SCTP_IERROR_PROTO_VIOLATION: 4034 case SCTP_IERROR_PROTO_VIOLATION:
4029 return sctp_sf_violation_chunklen(ep, asoc, type, arg, 4035 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
4030 commands); 4036 commands);
4031 break; 4037
4032 case SCTP_IERROR_NOMEM: 4038 case SCTP_IERROR_NOMEM:
4033 return SCTP_DISPOSITION_NOMEM; 4039 return SCTP_DISPOSITION_NOMEM;
4034 default: 4040
4035 break; 4041 default: /* Prevent gcc warnings */
4042 break;
4036 } 4043 }
4037 4044
4038 if (asoc->active_key_id != ntohs(auth_hdr->shkey_id)) { 4045 if (asoc->active_key_id != ntohs(auth_hdr->shkey_id)) {
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index d3ccf7973c5..4760f4e65b8 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -476,7 +476,7 @@ static int sctp_bindx_add(struct sock *sk, struct sockaddr *addrs, int addrcnt)
476 /* The list may contain either IPv4 or IPv6 address; 476 /* The list may contain either IPv4 or IPv6 address;
477 * determine the address length for walking thru the list. 477 * determine the address length for walking thru the list.
478 */ 478 */
479 sa_addr = (struct sockaddr *)addr_buf; 479 sa_addr = addr_buf;
480 af = sctp_get_af_specific(sa_addr->sa_family); 480 af = sctp_get_af_specific(sa_addr->sa_family);
481 if (!af) { 481 if (!af) {
482 retval = -EINVAL; 482 retval = -EINVAL;
@@ -555,7 +555,7 @@ static int sctp_send_asconf_add_ip(struct sock *sk,
555 */ 555 */
556 addr_buf = addrs; 556 addr_buf = addrs;
557 for (i = 0; i < addrcnt; i++) { 557 for (i = 0; i < addrcnt; i++) {
558 addr = (union sctp_addr *)addr_buf; 558 addr = addr_buf;
559 af = sctp_get_af_specific(addr->v4.sin_family); 559 af = sctp_get_af_specific(addr->v4.sin_family);
560 if (!af) { 560 if (!af) {
561 retval = -EINVAL; 561 retval = -EINVAL;
@@ -583,22 +583,35 @@ static int sctp_send_asconf_add_ip(struct sock *sk,
583 goto out; 583 goto out;
584 } 584 }
585 585
586 retval = sctp_send_asconf(asoc, chunk);
587 if (retval)
588 goto out;
589
590 /* Add the new addresses to the bind address list with 586 /* Add the new addresses to the bind address list with
591 * use_as_src set to 0. 587 * use_as_src set to 0.
592 */ 588 */
593 addr_buf = addrs; 589 addr_buf = addrs;
594 for (i = 0; i < addrcnt; i++) { 590 for (i = 0; i < addrcnt; i++) {
595 addr = (union sctp_addr *)addr_buf; 591 addr = addr_buf;
596 af = sctp_get_af_specific(addr->v4.sin_family); 592 af = sctp_get_af_specific(addr->v4.sin_family);
597 memcpy(&saveaddr, addr, af->sockaddr_len); 593 memcpy(&saveaddr, addr, af->sockaddr_len);
598 retval = sctp_add_bind_addr(bp, &saveaddr, 594 retval = sctp_add_bind_addr(bp, &saveaddr,
599 SCTP_ADDR_NEW, GFP_ATOMIC); 595 SCTP_ADDR_NEW, GFP_ATOMIC);
600 addr_buf += af->sockaddr_len; 596 addr_buf += af->sockaddr_len;
601 } 597 }
598 if (asoc->src_out_of_asoc_ok) {
599 struct sctp_transport *trans;
600
601 list_for_each_entry(trans,
602 &asoc->peer.transport_addr_list, transports) {
603 /* Clear the source and route cache */
604 dst_release(trans->dst);
605 trans->cwnd = min(4*asoc->pathmtu, max_t(__u32,
606 2*asoc->pathmtu, 4380));
607 trans->ssthresh = asoc->peer.i.a_rwnd;
608 trans->rto = asoc->rto_initial;
609 trans->rtt = trans->srtt = trans->rttvar = 0;
610 sctp_transport_route(trans, NULL,
611 sctp_sk(asoc->base.sk));
612 }
613 }
614 retval = sctp_send_asconf(asoc, chunk);
602 } 615 }
603 616
604out: 617out:
@@ -646,7 +659,7 @@ static int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt)
646 goto err_bindx_rem; 659 goto err_bindx_rem;
647 } 660 }
648 661
649 sa_addr = (union sctp_addr *)addr_buf; 662 sa_addr = addr_buf;
650 af = sctp_get_af_specific(sa_addr->sa.sa_family); 663 af = sctp_get_af_specific(sa_addr->sa.sa_family);
651 if (!af) { 664 if (!af) {
652 retval = -EINVAL; 665 retval = -EINVAL;
@@ -715,7 +728,9 @@ static int sctp_send_asconf_del_ip(struct sock *sk,
715 struct sctp_sockaddr_entry *saddr; 728 struct sctp_sockaddr_entry *saddr;
716 int i; 729 int i;
717 int retval = 0; 730 int retval = 0;
731 int stored = 0;
718 732
733 chunk = NULL;
719 if (!sctp_addip_enable) 734 if (!sctp_addip_enable)
720 return retval; 735 return retval;
721 736
@@ -743,7 +758,7 @@ static int sctp_send_asconf_del_ip(struct sock *sk,
743 */ 758 */
744 addr_buf = addrs; 759 addr_buf = addrs;
745 for (i = 0; i < addrcnt; i++) { 760 for (i = 0; i < addrcnt; i++) {
746 laddr = (union sctp_addr *)addr_buf; 761 laddr = addr_buf;
747 af = sctp_get_af_specific(laddr->v4.sin_family); 762 af = sctp_get_af_specific(laddr->v4.sin_family);
748 if (!af) { 763 if (!af) {
749 retval = -EINVAL; 764 retval = -EINVAL;
@@ -766,8 +781,37 @@ static int sctp_send_asconf_del_ip(struct sock *sk,
766 bp = &asoc->base.bind_addr; 781 bp = &asoc->base.bind_addr;
767 laddr = sctp_find_unmatch_addr(bp, (union sctp_addr *)addrs, 782 laddr = sctp_find_unmatch_addr(bp, (union sctp_addr *)addrs,
768 addrcnt, sp); 783 addrcnt, sp);
769 if (!laddr) 784 if ((laddr == NULL) && (addrcnt == 1)) {
770 continue; 785 if (asoc->asconf_addr_del_pending)
786 continue;
787 asoc->asconf_addr_del_pending =
788 kzalloc(sizeof(union sctp_addr), GFP_ATOMIC);
789 if (asoc->asconf_addr_del_pending == NULL) {
790 retval = -ENOMEM;
791 goto out;
792 }
793 asoc->asconf_addr_del_pending->sa.sa_family =
794 addrs->sa_family;
795 asoc->asconf_addr_del_pending->v4.sin_port =
796 htons(bp->port);
797 if (addrs->sa_family == AF_INET) {
798 struct sockaddr_in *sin;
799
800 sin = (struct sockaddr_in *)addrs;
801 asoc->asconf_addr_del_pending->v4.sin_addr.s_addr = sin->sin_addr.s_addr;
802 } else if (addrs->sa_family == AF_INET6) {
803 struct sockaddr_in6 *sin6;
804
805 sin6 = (struct sockaddr_in6 *)addrs;
806 ipv6_addr_copy(&asoc->asconf_addr_del_pending->v6.sin6_addr, &sin6->sin6_addr);
807 }
808 SCTP_DEBUG_PRINTK_IPADDR("send_asconf_del_ip: keep the last address asoc: %p ",
809 " at %p\n", asoc, asoc->asconf_addr_del_pending,
810 asoc->asconf_addr_del_pending);
811 asoc->src_out_of_asoc_ok = 1;
812 stored = 1;
813 goto skip_mkasconf;
814 }
771 815
772 /* We do not need RCU protection throughout this loop 816 /* We do not need RCU protection throughout this loop
773 * because this is done under a socket lock from the 817 * because this is done under a socket lock from the
@@ -780,12 +824,13 @@ static int sctp_send_asconf_del_ip(struct sock *sk,
780 goto out; 824 goto out;
781 } 825 }
782 826
827skip_mkasconf:
783 /* Reset use_as_src flag for the addresses in the bind address 828 /* Reset use_as_src flag for the addresses in the bind address
784 * list that are to be deleted. 829 * list that are to be deleted.
785 */ 830 */
786 addr_buf = addrs; 831 addr_buf = addrs;
787 for (i = 0; i < addrcnt; i++) { 832 for (i = 0; i < addrcnt; i++) {
788 laddr = (union sctp_addr *)addr_buf; 833 laddr = addr_buf;
789 af = sctp_get_af_specific(laddr->v4.sin_family); 834 af = sctp_get_af_specific(laddr->v4.sin_family);
790 list_for_each_entry(saddr, &bp->address_list, list) { 835 list_for_each_entry(saddr, &bp->address_list, list) {
791 if (sctp_cmp_addr_exact(&saddr->a, laddr)) 836 if (sctp_cmp_addr_exact(&saddr->a, laddr))
@@ -805,12 +850,37 @@ static int sctp_send_asconf_del_ip(struct sock *sk,
805 sctp_sk(asoc->base.sk)); 850 sctp_sk(asoc->base.sk));
806 } 851 }
807 852
853 if (stored)
854 /* We don't need to transmit ASCONF */
855 continue;
808 retval = sctp_send_asconf(asoc, chunk); 856 retval = sctp_send_asconf(asoc, chunk);
809 } 857 }
810out: 858out:
811 return retval; 859 return retval;
812} 860}
813 861
862/* set addr events to assocs in the endpoint. ep and addr_wq must be locked */
863int sctp_asconf_mgmt(struct sctp_sock *sp, struct sctp_sockaddr_entry *addrw)
864{
865 struct sock *sk = sctp_opt2sk(sp);
866 union sctp_addr *addr;
867 struct sctp_af *af;
868
869 /* It is safe to write port space in caller. */
870 addr = &addrw->a;
871 addr->v4.sin_port = htons(sp->ep->base.bind_addr.port);
872 af = sctp_get_af_specific(addr->sa.sa_family);
873 if (!af)
874 return -EINVAL;
875 if (sctp_verify_addr(sk, addr, af->sockaddr_len))
876 return -EINVAL;
877
878 if (addrw->state == SCTP_ADDR_NEW)
879 return sctp_send_asconf_add_ip(sk, (struct sockaddr *)addr, 1);
880 else
881 return sctp_send_asconf_del_ip(sk, (struct sockaddr *)addr, 1);
882}
883
814/* Helper for tunneling sctp_bindx() requests through sctp_setsockopt() 884/* Helper for tunneling sctp_bindx() requests through sctp_setsockopt()
815 * 885 *
816 * API 8.1 886 * API 8.1
@@ -927,7 +997,7 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk,
927 return -EINVAL; 997 return -EINVAL;
928 } 998 }
929 999
930 sa_addr = (struct sockaddr *)addr_buf; 1000 sa_addr = addr_buf;
931 af = sctp_get_af_specific(sa_addr->sa_family); 1001 af = sctp_get_af_specific(sa_addr->sa_family);
932 1002
933 /* If the address family is not supported or if this address 1003 /* If the address family is not supported or if this address
@@ -1018,7 +1088,7 @@ static int __sctp_connect(struct sock* sk,
1018 goto out_free; 1088 goto out_free;
1019 } 1089 }
1020 1090
1021 sa_addr = (union sctp_addr *)addr_buf; 1091 sa_addr = addr_buf;
1022 af = sctp_get_af_specific(sa_addr->sa.sa_family); 1092 af = sctp_get_af_specific(sa_addr->sa.sa_family);
1023 1093
1024 /* If the address family is not supported or if this address 1094 /* If the address family is not supported or if this address
@@ -2129,8 +2199,6 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
2129 return -EINVAL; 2199 return -EINVAL;
2130 if (copy_from_user(&sp->autoclose, optval, optlen)) 2200 if (copy_from_user(&sp->autoclose, optval, optlen))
2131 return -EFAULT; 2201 return -EFAULT;
2132 /* make sure it won't exceed MAX_SCHEDULE_TIMEOUT */
2133 sp->autoclose = min_t(long, sp->autoclose, MAX_SCHEDULE_TIMEOUT / HZ);
2134 2202
2135 return 0; 2203 return 0;
2136} 2204}
@@ -3213,11 +3281,11 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk,
3213 return -EFAULT; 3281 return -EFAULT;
3214 3282
3215 switch (val.sauth_chunk) { 3283 switch (val.sauth_chunk) {
3216 case SCTP_CID_INIT: 3284 case SCTP_CID_INIT:
3217 case SCTP_CID_INIT_ACK: 3285 case SCTP_CID_INIT_ACK:
3218 case SCTP_CID_SHUTDOWN_COMPLETE: 3286 case SCTP_CID_SHUTDOWN_COMPLETE:
3219 case SCTP_CID_AUTH: 3287 case SCTP_CID_AUTH:
3220 return -EINVAL; 3288 return -EINVAL;
3221 } 3289 }
3222 3290
3223 /* add this chunk id to the endpoint */ 3291 /* add this chunk id to the endpoint */
@@ -3360,6 +3428,46 @@ static int sctp_setsockopt_del_key(struct sock *sk,
3360 3428
3361} 3429}
3362 3430
3431/*
3432 * 8.1.23 SCTP_AUTO_ASCONF
3433 *
3434 * This option will enable or disable the use of the automatic generation of
3435 * ASCONF chunks to add and delete addresses to an existing association. Note
3436 * that this option has two caveats namely: a) it only affects sockets that
3437 * are bound to all addresses available to the SCTP stack, and b) the system
3438 * administrator may have an overriding control that turns the ASCONF feature
3439 * off no matter what setting the socket option may have.
3440 * This option expects an integer boolean flag, where a non-zero value turns on
3441 * the option, and a zero value turns off the option.
3442 * Note. In this implementation, socket operation overrides default parameter
3443 * being set by sysctl as well as FreeBSD implementation
3444 */
3445static int sctp_setsockopt_auto_asconf(struct sock *sk, char __user *optval,
3446 unsigned int optlen)
3447{
3448 int val;
3449 struct sctp_sock *sp = sctp_sk(sk);
3450
3451 if (optlen < sizeof(int))
3452 return -EINVAL;
3453 if (get_user(val, (int __user *)optval))
3454 return -EFAULT;
3455 if (!sctp_is_ep_boundall(sk) && val)
3456 return -EINVAL;
3457 if ((val && sp->do_auto_asconf) || (!val && !sp->do_auto_asconf))
3458 return 0;
3459
3460 if (val == 0 && sp->do_auto_asconf) {
3461 list_del(&sp->auto_asconf_list);
3462 sp->do_auto_asconf = 0;
3463 } else if (val && !sp->do_auto_asconf) {
3464 list_add_tail(&sp->auto_asconf_list,
3465 &sctp_auto_asconf_splist);
3466 sp->do_auto_asconf = 1;
3467 }
3468 return 0;
3469}
3470
3363 3471
3364/* API 6.2 setsockopt(), getsockopt() 3472/* API 6.2 setsockopt(), getsockopt()
3365 * 3473 *
@@ -3507,6 +3615,9 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
3507 case SCTP_AUTH_DELETE_KEY: 3615 case SCTP_AUTH_DELETE_KEY:
3508 retval = sctp_setsockopt_del_key(sk, optval, optlen); 3616 retval = sctp_setsockopt_del_key(sk, optval, optlen);
3509 break; 3617 break;
3618 case SCTP_AUTO_ASCONF:
3619 retval = sctp_setsockopt_auto_asconf(sk, optval, optlen);
3620 break;
3510 default: 3621 default:
3511 retval = -ENOPROTOOPT; 3622 retval = -ENOPROTOOPT;
3512 break; 3623 break;
@@ -3789,6 +3900,12 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
3789 local_bh_disable(); 3900 local_bh_disable();
3790 percpu_counter_inc(&sctp_sockets_allocated); 3901 percpu_counter_inc(&sctp_sockets_allocated);
3791 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); 3902 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
3903 if (sctp_default_auto_asconf) {
3904 list_add_tail(&sp->auto_asconf_list,
3905 &sctp_auto_asconf_splist);
3906 sp->do_auto_asconf = 1;
3907 } else
3908 sp->do_auto_asconf = 0;
3792 local_bh_enable(); 3909 local_bh_enable();
3793 3910
3794 return 0; 3911 return 0;
@@ -3797,13 +3914,17 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
3797/* Cleanup any SCTP per socket resources. */ 3914/* Cleanup any SCTP per socket resources. */
3798SCTP_STATIC void sctp_destroy_sock(struct sock *sk) 3915SCTP_STATIC void sctp_destroy_sock(struct sock *sk)
3799{ 3916{
3800 struct sctp_endpoint *ep; 3917 struct sctp_sock *sp;
3801 3918
3802 SCTP_DEBUG_PRINTK("sctp_destroy_sock(sk: %p)\n", sk); 3919 SCTP_DEBUG_PRINTK("sctp_destroy_sock(sk: %p)\n", sk);
3803 3920
3804 /* Release our hold on the endpoint. */ 3921 /* Release our hold on the endpoint. */
3805 ep = sctp_sk(sk)->ep; 3922 sp = sctp_sk(sk);
3806 sctp_endpoint_free(ep); 3923 if (sp->do_auto_asconf) {
3924 sp->do_auto_asconf = 0;
3925 list_del(&sp->auto_asconf_list);
3926 }
3927 sctp_endpoint_free(sp->ep);
3807 local_bh_disable(); 3928 local_bh_disable();
3808 percpu_counter_dec(&sctp_sockets_allocated); 3929 percpu_counter_dec(&sctp_sockets_allocated);
3809 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); 3930 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
@@ -5303,6 +5424,28 @@ static int sctp_getsockopt_assoc_number(struct sock *sk, int len,
5303} 5424}
5304 5425
5305/* 5426/*
5427 * 8.1.23 SCTP_AUTO_ASCONF
5428 * See the corresponding setsockopt entry as description
5429 */
5430static int sctp_getsockopt_auto_asconf(struct sock *sk, int len,
5431 char __user *optval, int __user *optlen)
5432{
5433 int val = 0;
5434
5435 if (len < sizeof(int))
5436 return -EINVAL;
5437
5438 len = sizeof(int);
5439 if (sctp_sk(sk)->do_auto_asconf && sctp_is_ep_boundall(sk))
5440 val = 1;
5441 if (put_user(len, optlen))
5442 return -EFAULT;
5443 if (copy_to_user(optval, &val, len))
5444 return -EFAULT;
5445 return 0;
5446}
5447
5448/*
5306 * 8.2.6. Get the Current Identifiers of Associations 5449 * 8.2.6. Get the Current Identifiers of Associations
5307 * (SCTP_GET_ASSOC_ID_LIST) 5450 * (SCTP_GET_ASSOC_ID_LIST)
5308 * 5451 *
@@ -5486,6 +5629,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
5486 case SCTP_GET_ASSOC_ID_LIST: 5629 case SCTP_GET_ASSOC_ID_LIST:
5487 retval = sctp_getsockopt_assoc_ids(sk, len, optval, optlen); 5630 retval = sctp_getsockopt_assoc_ids(sk, len, optval, optlen);
5488 break; 5631 break;
5632 case SCTP_AUTO_ASCONF:
5633 retval = sctp_getsockopt_auto_asconf(sk, len, optval, optlen);
5634 break;
5489 default: 5635 default:
5490 retval = -ENOPROTOOPT; 5636 retval = -ENOPROTOOPT;
5491 break; 5637 break;
@@ -6538,6 +6684,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
6538 struct sk_buff *skb, *tmp; 6684 struct sk_buff *skb, *tmp;
6539 struct sctp_ulpevent *event; 6685 struct sctp_ulpevent *event;
6540 struct sctp_bind_hashbucket *head; 6686 struct sctp_bind_hashbucket *head;
6687 struct list_head tmplist;
6541 6688
6542 /* Migrate socket buffer sizes and all the socket level options to the 6689 /* Migrate socket buffer sizes and all the socket level options to the
6543 * new socket. 6690 * new socket.
@@ -6545,7 +6692,12 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
6545 newsk->sk_sndbuf = oldsk->sk_sndbuf; 6692 newsk->sk_sndbuf = oldsk->sk_sndbuf;
6546 newsk->sk_rcvbuf = oldsk->sk_rcvbuf; 6693 newsk->sk_rcvbuf = oldsk->sk_rcvbuf;
6547 /* Brute force copy old sctp opt. */ 6694 /* Brute force copy old sctp opt. */
6548 inet_sk_copy_descendant(newsk, oldsk); 6695 if (oldsp->do_auto_asconf) {
6696 memcpy(&tmplist, &newsp->auto_asconf_list, sizeof(tmplist));
6697 inet_sk_copy_descendant(newsk, oldsk);
6698 memcpy(&newsp->auto_asconf_list, &tmplist, sizeof(tmplist));
6699 } else
6700 inet_sk_copy_descendant(newsk, oldsk);
6549 6701
6550 /* Restore the ep value that was overwritten with the above structure 6702 /* Restore the ep value that was overwritten with the above structure
6551 * copy. 6703 * copy.
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 50cb57f0919..60ffbd067ff 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -53,6 +53,10 @@ static int sack_timer_min = 1;
53static int sack_timer_max = 500; 53static int sack_timer_max = 500;
54static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ 54static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */
55static int rwnd_scale_max = 16; 55static int rwnd_scale_max = 16;
56static unsigned long max_autoclose_min = 0;
57static unsigned long max_autoclose_max =
58 (MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX)
59 ? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ;
56 60
57extern long sysctl_sctp_mem[3]; 61extern long sysctl_sctp_mem[3];
58extern int sysctl_sctp_rmem[3]; 62extern int sysctl_sctp_rmem[3];
@@ -183,6 +187,13 @@ static ctl_table sctp_table[] = {
183 .proc_handler = proc_dointvec, 187 .proc_handler = proc_dointvec,
184 }, 188 },
185 { 189 {
190 .procname = "default_auto_asconf",
191 .data = &sctp_default_auto_asconf,
192 .maxlen = sizeof(int),
193 .mode = 0644,
194 .proc_handler = proc_dointvec,
195 },
196 {
186 .procname = "prsctp_enable", 197 .procname = "prsctp_enable",
187 .data = &sctp_prsctp_enable, 198 .data = &sctp_prsctp_enable,
188 .maxlen = sizeof(int), 199 .maxlen = sizeof(int),
@@ -251,6 +262,15 @@ static ctl_table sctp_table[] = {
251 .extra1 = &one, 262 .extra1 = &one,
252 .extra2 = &rwnd_scale_max, 263 .extra2 = &rwnd_scale_max,
253 }, 264 },
265 {
266 .procname = "max_autoclose",
267 .data = &sctp_max_autoclose,
268 .maxlen = sizeof(unsigned long),
269 .mode = 0644,
270 .proc_handler = &proc_doulongvec_minmax,
271 .extra1 = &max_autoclose_min,
272 .extra2 = &max_autoclose_max,
273 },
254 274
255 { /* sentinel */ } 275 { /* sentinel */ }
256}; 276};