aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/protocol.c
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2009-02-13 03:33:44 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-16 03:03:11 -0500
commit914e1c8b6980c516667375d3e55f0b6e674c8c58 (patch)
treed61194143a112ace85f6e6dfc22bc01d7173f62e /net/sctp/protocol.c
parentfaee47cdbfe8d74a1573c2f81ea6dbb08d735be6 (diff)
sctp: Inherit all socket options from parent correctly.
During peeloff/accept() sctp needs to save the parent socket state into the new socket so that any options set on the parent are inherited by the child socket. This was found when the parent/listener socket issues SO_BINDTODEVICE, but the data was misrouted after a route cache flush. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/protocol.c')
-rw-r--r--net/sctp/protocol.c29
1 files changed, 2 insertions, 27 deletions
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