aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/protocol.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/protocol.c')
-rw-r--r--net/sctp/protocol.c155
1 files changed, 154 insertions, 1 deletions
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);