diff options
author | Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 2005-08-09 23:10:12 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-08-29 18:42:36 -0400 |
commit | 87d11ceb9deb7a3f13fdee6e89d9bb6be7d27a71 (patch) | |
tree | 3b5f6f15a76e6d58e5088cad707859390757181a /net/ipv4/tcp_minisocks.c | |
parent | c676270bcd25015b978722ec0352c330dcc87883 (diff) |
[SOCK]: Introduce sk_clone
Out of tcp_create_openreq_child, will be used in
dccp_create_openreq_child, and is a nice sock function anyway.
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_minisocks.c')
-rw-r--r-- | net/ipv4/tcp_minisocks.c | 70 |
1 files changed, 3 insertions, 67 deletions
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 66ce1790a94f..8b6cd8d80662 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -599,67 +599,26 @@ out: | |||
599 | */ | 599 | */ |
600 | struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, struct sk_buff *skb) | 600 | struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, struct sk_buff *skb) |
601 | { | 601 | { |
602 | /* allocate the newsk from the same slab of the master sock, | 602 | struct sock *newsk = sk_clone(sk, GFP_ATOMIC); |
603 | * if not, at sk_free time we'll try to free it from the wrong | ||
604 | * slabcache (i.e. is it TCPv4 or v6?), this is handled thru sk->sk_prot -acme */ | ||
605 | struct sock *newsk = sk_alloc(PF_INET, GFP_ATOMIC, sk->sk_prot, 0); | ||
606 | 603 | ||
607 | if(newsk != NULL) { | 604 | if (newsk != NULL) { |
608 | struct inet_request_sock *ireq = inet_rsk(req); | 605 | struct inet_request_sock *ireq = inet_rsk(req); |
609 | struct tcp_request_sock *treq = tcp_rsk(req); | 606 | struct tcp_request_sock *treq = tcp_rsk(req); |
610 | struct inet_sock *newinet = inet_sk(newsk); | 607 | struct inet_sock *newinet = inet_sk(newsk); |
611 | struct tcp_sock *newtp; | 608 | struct tcp_sock *newtp; |
612 | struct sk_filter *filter; | ||
613 | 609 | ||
614 | memcpy(newsk, sk, sizeof(struct tcp_sock)); | ||
615 | newsk->sk_state = TCP_SYN_RECV; | 610 | newsk->sk_state = TCP_SYN_RECV; |
616 | |||
617 | /* SANITY */ | ||
618 | sk_node_init(&newsk->sk_node); | ||
619 | newinet->bind_hash = NULL; | 611 | newinet->bind_hash = NULL; |
620 | 612 | ||
621 | /* Clone the TCP header template */ | 613 | /* Clone the TCP header template */ |
622 | newinet->dport = ireq->rmt_port; | 614 | newinet->dport = ireq->rmt_port; |
623 | |||
624 | sock_lock_init(newsk); | ||
625 | bh_lock_sock(newsk); | ||
626 | |||
627 | rwlock_init(&newsk->sk_dst_lock); | ||
628 | newsk->sk_dst_cache = NULL; | ||
629 | atomic_set(&newsk->sk_rmem_alloc, 0); | ||
630 | skb_queue_head_init(&newsk->sk_receive_queue); | ||
631 | atomic_set(&newsk->sk_wmem_alloc, 0); | ||
632 | skb_queue_head_init(&newsk->sk_write_queue); | ||
633 | atomic_set(&newsk->sk_omem_alloc, 0); | ||
634 | newsk->sk_wmem_queued = 0; | ||
635 | newsk->sk_forward_alloc = 0; | ||
636 | |||
637 | sock_reset_flag(newsk, SOCK_DONE); | ||
638 | newsk->sk_userlocks = sk->sk_userlocks & ~SOCK_BINDPORT_LOCK; | ||
639 | newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; | ||
640 | newsk->sk_send_head = NULL; | ||
641 | rwlock_init(&newsk->sk_callback_lock); | ||
642 | skb_queue_head_init(&newsk->sk_error_queue); | ||
643 | newsk->sk_write_space = sk_stream_write_space; | 615 | newsk->sk_write_space = sk_stream_write_space; |
644 | 616 | ||
645 | if ((filter = newsk->sk_filter) != NULL) | ||
646 | sk_filter_charge(newsk, filter); | ||
647 | |||
648 | if (unlikely(xfrm_sk_clone_policy(newsk))) { | ||
649 | /* It is still raw copy of parent, so invalidate | ||
650 | * destructor and make plain sk_free() */ | ||
651 | newsk->sk_destruct = NULL; | ||
652 | sk_free(newsk); | ||
653 | return NULL; | ||
654 | } | ||
655 | |||
656 | /* Now setup tcp_sock */ | 617 | /* Now setup tcp_sock */ |
657 | newtp = tcp_sk(newsk); | 618 | newtp = tcp_sk(newsk); |
658 | newtp->pred_flags = 0; | 619 | newtp->pred_flags = 0; |
659 | newtp->rcv_nxt = treq->rcv_isn + 1; | 620 | newtp->rcv_nxt = treq->rcv_isn + 1; |
660 | newtp->snd_nxt = treq->snt_isn + 1; | 621 | newtp->snd_nxt = newtp->snd_una = newtp->snd_sml = treq->snt_isn + 1; |
661 | newtp->snd_una = treq->snt_isn + 1; | ||
662 | newtp->snd_sml = treq->snt_isn + 1; | ||
663 | 622 | ||
664 | tcp_prequeue_init(newtp); | 623 | tcp_prequeue_init(newtp); |
665 | 624 | ||
@@ -710,32 +669,9 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, | |||
710 | /* Deinitialize accept_queue to trap illegal accesses. */ | 669 | /* Deinitialize accept_queue to trap illegal accesses. */ |
711 | memset(&newtp->accept_queue, 0, sizeof(newtp->accept_queue)); | 670 | memset(&newtp->accept_queue, 0, sizeof(newtp->accept_queue)); |
712 | 671 | ||
713 | /* Back to base struct sock members. */ | ||
714 | newsk->sk_err = 0; | ||
715 | newsk->sk_priority = 0; | ||
716 | atomic_set(&newsk->sk_refcnt, 2); | ||
717 | |||
718 | /* | ||
719 | * Increment the counter in the same struct proto as the master | ||
720 | * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that | ||
721 | * is the same as sk->sk_prot->socks, as this field was copied | ||
722 | * with memcpy), same rationale as the first comment in this | ||
723 | * function. | ||
724 | * | ||
725 | * This _changes_ the previous behaviour, where | ||
726 | * tcp_create_openreq_child always was incrementing the | ||
727 | * equivalent to tcp_prot->socks (inet_sock_nr), so this have | ||
728 | * to be taken into account in all callers. -acme | ||
729 | */ | ||
730 | sk_refcnt_debug_inc(newsk); | ||
731 | |||
732 | atomic_inc(&tcp_sockets_allocated); | ||
733 | |||
734 | if (sock_flag(newsk, SOCK_KEEPOPEN)) | 672 | if (sock_flag(newsk, SOCK_KEEPOPEN)) |
735 | tcp_reset_keepalive_timer(newsk, | 673 | tcp_reset_keepalive_timer(newsk, |
736 | keepalive_time_when(newtp)); | 674 | keepalive_time_when(newtp)); |
737 | newsk->sk_socket = NULL; | ||
738 | newsk->sk_sleep = NULL; | ||
739 | 675 | ||
740 | newtp->rx_opt.tstamp_ok = ireq->tstamp_ok; | 676 | newtp->rx_opt.tstamp_ok = ireq->tstamp_ok; |
741 | if((newtp->rx_opt.sack_ok = ireq->sack_ok) != 0) { | 677 | if((newtp->rx_opt.sack_ok = ireq->sack_ok) != 0) { |