aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/sctp/sctp.h2
-rw-r--r--net/sctp/ipv6.c33
-rw-r--r--net/sctp/protocol.c29
-rw-r--r--net/sctp/socket.c55
4 files changed, 53 insertions, 66 deletions
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index bbb7742195b0..9e226be3be69 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -138,6 +138,8 @@ void sctp_write_space(struct sock *sk);
138unsigned int sctp_poll(struct file *file, struct socket *sock, 138unsigned int sctp_poll(struct file *file, struct socket *sock,
139 poll_table *wait); 139 poll_table *wait);
140void sctp_sock_rfree(struct sk_buff *skb); 140void sctp_sock_rfree(struct sk_buff *skb);
141void sctp_copy_sock(struct sock *newsk, struct sock *sk,
142 struct sctp_association *asoc);
141extern struct percpu_counter sctp_sockets_allocated; 143extern struct percpu_counter sctp_sockets_allocated;
142 144
143/* 145/*
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 786227566696..a63de3f7f185 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -627,9 +627,7 @@ static sctp_scope_t sctp_v6_scope(union sctp_addr *addr)
627static struct sock *sctp_v6_create_accept_sk(struct sock *sk, 627static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
628 struct sctp_association *asoc) 628 struct sctp_association *asoc)
629{ 629{
630 struct inet_sock *inet = inet_sk(sk);
631 struct sock *newsk; 630 struct sock *newsk;
632 struct inet_sock *newinet;
633 struct ipv6_pinfo *newnp, *np = inet6_sk(sk); 631 struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
634 struct sctp6_sock *newsctp6sk; 632 struct sctp6_sock *newsctp6sk;
635 633
@@ -639,17 +637,7 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
639 637
640 sock_init_data(NULL, newsk); 638 sock_init_data(NULL, newsk);
641 639
642 newsk->sk_type = SOCK_STREAM; 640 sctp_copy_sock(newsk, sk, asoc);
643
644 newsk->sk_prot = sk->sk_prot;
645 newsk->sk_no_check = sk->sk_no_check;
646 newsk->sk_reuse = sk->sk_reuse;
647
648 newsk->sk_destruct = inet_sock_destruct;
649 newsk->sk_family = PF_INET6;
650 newsk->sk_protocol = IPPROTO_SCTP;
651 newsk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
652 newsk->sk_shutdown = sk->sk_shutdown;
653 sock_reset_flag(sk, SOCK_ZAPPED); 641 sock_reset_flag(sk, SOCK_ZAPPED);
654 642
655 newsctp6sk = (struct sctp6_sock *)newsk; 643 newsctp6sk = (struct sctp6_sock *)newsk;
@@ -657,7 +645,6 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
657 645
658 sctp_sk(newsk)->v4mapped = sctp_sk(sk)->v4mapped; 646 sctp_sk(newsk)->v4mapped = sctp_sk(sk)->v4mapped;
659 647
660 newinet = inet_sk(newsk);
661 newnp = inet6_sk(newsk); 648 newnp = inet6_sk(newsk);
662 649
663 memcpy(newnp, np, sizeof(struct ipv6_pinfo)); 650 memcpy(newnp, np, sizeof(struct ipv6_pinfo));
@@ -665,26 +652,8 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
665 /* Initialize sk's sport, dport, rcv_saddr and daddr for getsockname() 652 /* Initialize sk's sport, dport, rcv_saddr and daddr for getsockname()
666 * and getpeername(). 653 * and getpeername().
667 */ 654 */
668 newinet->sport = inet->sport;
669 newnp->saddr = np->saddr;
670 newnp->rcv_saddr = np->rcv_saddr;
671 newinet->dport = htons(asoc->peer.port);
672 sctp_v6_to_sk_daddr(&asoc->peer.primary_addr, newsk); 655 sctp_v6_to_sk_daddr(&asoc->peer.primary_addr, newsk);
673 656
674 /* Init the ipv4 part of the socket since we can have sockets
675 * using v6 API for ipv4.
676 */
677 newinet->uc_ttl = -1;
678 newinet->mc_loop = 1;
679 newinet->mc_ttl = 1;
680 newinet->mc_index = 0;
681 newinet->mc_list = NULL;
682
683 if (ipv4_config.no_pmtu_disc)
684 newinet->pmtudisc = IP_PMTUDISC_DONT;
685 else
686 newinet->pmtudisc = IP_PMTUDISC_WANT;
687
688 sk_refcnt_debug_inc(newsk); 657 sk_refcnt_debug_inc(newsk);
689 658
690 if (newsk->sk_prot->init(newsk)) { 659 if (newsk->sk_prot->init(newsk)) {
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index cc0b592698f9..c1e316ee7155 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -589,46 +589,21 @@ static int sctp_v4_is_ce(const struct sk_buff *skb)
589static struct sock *sctp_v4_create_accept_sk(struct sock *sk, 589static struct sock *sctp_v4_create_accept_sk(struct sock *sk,
590 struct sctp_association *asoc) 590 struct sctp_association *asoc)
591{ 591{
592 struct inet_sock *inet = inet_sk(sk);
593 struct inet_sock *newinet;
594 struct sock *newsk = sk_alloc(sock_net(sk), PF_INET, GFP_KERNEL, 592 struct sock *newsk = sk_alloc(sock_net(sk), PF_INET, GFP_KERNEL,
595 sk->sk_prot); 593 sk->sk_prot);
594 struct inet_sock *newinet;
596 595
597 if (!newsk) 596 if (!newsk)
598 goto out; 597 goto out;
599 598
600 sock_init_data(NULL, newsk); 599 sock_init_data(NULL, newsk);
601 600
602 newsk->sk_type = SOCK_STREAM; 601 sctp_copy_sock(newsk, sk, asoc);
603
604 newsk->sk_no_check = sk->sk_no_check;
605 newsk->sk_reuse = sk->sk_reuse;
606 newsk->sk_shutdown = sk->sk_shutdown;
607
608 newsk->sk_destruct = inet_sock_destruct;
609 newsk->sk_family = PF_INET;
610 newsk->sk_protocol = IPPROTO_SCTP;
611 newsk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
612 sock_reset_flag(newsk, SOCK_ZAPPED); 602 sock_reset_flag(newsk, SOCK_ZAPPED);
613 603
614 newinet = inet_sk(newsk); 604 newinet = inet_sk(newsk);
615 605
616 /* Initialize sk's sport, dport, rcv_saddr and daddr for
617 * getsockname() and getpeername()
618 */
619 newinet->sport = inet->sport;
620 newinet->saddr = inet->saddr;
621 newinet->rcv_saddr = inet->rcv_saddr;
622 newinet->dport = htons(asoc->peer.port);
623 newinet->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr; 606 newinet->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr;
624 newinet->pmtudisc = inet->pmtudisc;
625 newinet->id = asoc->next_tsn ^ jiffies;
626
627 newinet->uc_ttl = -1;
628 newinet->mc_loop = 1;
629 newinet->mc_ttl = 1;
630 newinet->mc_index = 0;
631 newinet->mc_list = NULL;
632 607
633 sk_refcnt_debug_inc(newsk); 608 sk_refcnt_debug_inc(newsk);
634 609
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index ff0a8f88de04..dea864f5de54 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3939,7 +3939,6 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc,
3939{ 3939{
3940 struct sock *sk = asoc->base.sk; 3940 struct sock *sk = asoc->base.sk;
3941 struct socket *sock; 3941 struct socket *sock;
3942 struct inet_sock *inetsk;
3943 struct sctp_af *af; 3942 struct sctp_af *af;
3944 int err = 0; 3943 int err = 0;
3945 3944
@@ -3954,18 +3953,18 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc,
3954 if (err < 0) 3953 if (err < 0)
3955 return err; 3954 return err;
3956 3955
3957 /* Populate the fields of the newsk from the oldsk and migrate the 3956 sctp_copy_sock(sock->sk, sk, asoc);
3958 * asoc to the newsk.
3959 */
3960 sctp_sock_migrate(sk, sock->sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH);
3961 3957
3962 /* Make peeled-off sockets more like 1-1 accepted sockets. 3958 /* Make peeled-off sockets more like 1-1 accepted sockets.
3963 * Set the daddr and initialize id to something more random 3959 * Set the daddr and initialize id to something more random
3964 */ 3960 */
3965 af = sctp_get_af_specific(asoc->peer.primary_addr.sa.sa_family); 3961 af = sctp_get_af_specific(asoc->peer.primary_addr.sa.sa_family);
3966 af->to_sk_daddr(&asoc->peer.primary_addr, sk); 3962 af->to_sk_daddr(&asoc->peer.primary_addr, sk);
3967 inetsk = inet_sk(sock->sk); 3963
3968 inetsk->id = asoc->next_tsn ^ jiffies; 3964 /* Populate the fields of the newsk from the oldsk and migrate the
3965 * asoc to the newsk.
3966 */
3967 sctp_sock_migrate(sk, sock->sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH);
3969 3968
3970 *sockp = sock; 3969 *sockp = sock;
3971 3970
@@ -6700,6 +6699,48 @@ done:
6700 sctp_skb_set_owner_r(skb, sk); 6699 sctp_skb_set_owner_r(skb, sk);
6701} 6700}
6702 6701
6702void sctp_copy_sock(struct sock *newsk, struct sock *sk,
6703 struct sctp_association *asoc)
6704{
6705 struct inet_sock *inet = inet_sk(sk);
6706 struct inet_sock *newinet = inet_sk(newsk);
6707
6708 newsk->sk_type = sk->sk_type;
6709 newsk->sk_bound_dev_if = sk->sk_bound_dev_if;
6710 newsk->sk_flags = sk->sk_flags;
6711 newsk->sk_no_check = sk->sk_no_check;
6712 newsk->sk_reuse = sk->sk_reuse;
6713
6714 newsk->sk_shutdown = sk->sk_shutdown;
6715 newsk->sk_destruct = inet_sock_destruct;
6716 newsk->sk_family = sk->sk_family;
6717 newsk->sk_protocol = IPPROTO_SCTP;
6718 newsk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
6719 newsk->sk_sndbuf = sk->sk_sndbuf;
6720 newsk->sk_rcvbuf = sk->sk_rcvbuf;
6721 newsk->sk_lingertime = sk->sk_lingertime;
6722 newsk->sk_rcvtimeo = sk->sk_rcvtimeo;
6723 newsk->sk_sndtimeo = sk->sk_sndtimeo;
6724
6725 newinet = inet_sk(newsk);
6726
6727 /* Initialize sk's sport, dport, rcv_saddr and daddr for
6728 * getsockname() and getpeername()
6729 */
6730 newinet->sport = inet->sport;
6731 newinet->saddr = inet->saddr;
6732 newinet->rcv_saddr = inet->rcv_saddr;
6733 newinet->dport = htons(asoc->peer.port);
6734 newinet->pmtudisc = inet->pmtudisc;
6735 newinet->id = asoc->next_tsn ^ jiffies;
6736
6737 newinet->uc_ttl = inet->uc_ttl;
6738 newinet->mc_loop = 1;
6739 newinet->mc_ttl = 1;
6740 newinet->mc_index = 0;
6741 newinet->mc_list = NULL;
6742}
6743
6703/* Populate the fields of the newsk from the oldsk and migrate the assoc 6744/* Populate the fields of the newsk from the oldsk and migrate the assoc
6704 * and its messages to the newsk. 6745 * and its messages to the newsk.
6705 */ 6746 */