diff options
Diffstat (limited to 'net/sctp/protocol.c')
-rw-r--r-- | net/sctp/protocol.c | 155 |
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 | ||
628 | void 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 | } | ||
676 | free_next: | ||
677 | list_del(&addrw->list); | ||
678 | kfree(addrw); | ||
679 | } | ||
680 | spin_unlock_bh(&sctp_addr_wq_lock); | ||
681 | } | ||
682 | |||
683 | static 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 | */ | ||
700 | static 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 | |||
720 | void 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); |