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.c55
1 files changed, 48 insertions, 7 deletions
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 */