diff options
-rw-r--r-- | include/net/sctp/sctp.h | 2 | ||||
-rw-r--r-- | net/sctp/ipv6.c | 33 | ||||
-rw-r--r-- | net/sctp/protocol.c | 29 | ||||
-rw-r--r-- | net/sctp/socket.c | 55 |
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); | |||
138 | unsigned int sctp_poll(struct file *file, struct socket *sock, | 138 | unsigned int sctp_poll(struct file *file, struct socket *sock, |
139 | poll_table *wait); | 139 | poll_table *wait); |
140 | void sctp_sock_rfree(struct sk_buff *skb); | 140 | void sctp_sock_rfree(struct sk_buff *skb); |
141 | void sctp_copy_sock(struct sock *newsk, struct sock *sk, | ||
142 | struct sctp_association *asoc); | ||
141 | extern struct percpu_counter sctp_sockets_allocated; | 143 | extern 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) | |||
627 | static struct sock *sctp_v6_create_accept_sk(struct sock *sk, | 627 | static 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) | |||
589 | static struct sock *sctp_v4_create_accept_sk(struct sock *sk, | 589 | static 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 | ||
6702 | void 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 | */ |