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