[ICSK]: Introduce inet_csk_clone

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index 97e0020..a50f4a4b 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -77,6 +77,10 @@
 	return (struct inet_connection_sock *)sk;
 }
 
+extern struct sock *inet_csk_clone(struct sock *sk,
+				   const struct request_sock *req,
+				   const unsigned int __nocast priority);
+
 enum inet_csk_ack_state_t {
 	ICSK_ACK_SCHED	= 1,
 	ICSK_ACK_TIMER  = 2,
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 2712400..136ada0 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -399,3 +399,28 @@
 }
 
 EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_hash_add);
+
+struct sock *inet_csk_clone(struct sock *sk, const struct request_sock *req,
+			    const unsigned int __nocast priority)
+{
+	struct sock *newsk = sk_clone(sk, priority);
+
+	if (newsk != NULL) {
+		struct inet_connection_sock *newicsk = inet_csk(newsk);
+
+		newsk->sk_state = TCP_SYN_RECV;
+		newicsk->icsk_bind_hash = NULL;
+
+		inet_sk(newsk)->dport = inet_rsk(req)->rmt_port;
+		newsk->sk_write_space = sk_stream_write_space;
+
+		newicsk->icsk_retransmits = 0;
+		newicsk->icsk_backoff = 0;
+
+		/* Deinitialize accept_queue to trap illegal accesses. */
+		memset(&newicsk->icsk_accept_queue, 0, sizeof(newicsk->icsk_accept_queue));
+	}
+	return newsk;
+}
+
+EXPORT_SYMBOL_GPL(inet_csk_clone);
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 5682370..4cfbe1d 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -600,22 +600,14 @@
  */
 struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, struct sk_buff *skb)
 {
-	struct sock *newsk = sk_clone(sk, GFP_ATOMIC);
+	struct sock *newsk = inet_csk_clone(sk, req, GFP_ATOMIC);
 
 	if (newsk != NULL) {
-		struct inet_request_sock *ireq = inet_rsk(req);
+		const struct inet_request_sock *ireq = inet_rsk(req);
 		struct tcp_request_sock *treq = tcp_rsk(req);
-		struct inet_sock *newinet = inet_sk(newsk);
-		struct inet_connection_sock *newicsk = inet_csk(newsk);
+		struct inet_connection_sock *newicsk = inet_csk(sk);
 		struct tcp_sock *newtp;
 
-		newsk->sk_state = TCP_SYN_RECV;
-		newicsk->icsk_bind_hash = NULL;
-
-		/* Clone the TCP header template */
-		newinet->dport = ireq->rmt_port;
-		newsk->sk_write_space = sk_stream_write_space;
-
 		/* Now setup tcp_sock */
 		newtp = tcp_sk(newsk);
 		newtp->pred_flags = 0;
@@ -626,8 +618,6 @@
 
 		tcp_init_wl(newtp, treq->snt_isn, treq->rcv_isn);
 
-		newicsk->icsk_retransmits = 0;
-		newicsk->icsk_backoff = 0;
 		newtp->srtt = 0;
 		newtp->mdev = TCP_TIMEOUT_INIT;
 		newicsk->icsk_rto = TCP_TIMEOUT_INIT;
@@ -668,8 +658,6 @@
 		newtp->probes_out = 0;
 		newtp->rx_opt.num_sacks = 0;
 		newtp->urg_data = 0;
-		/* Deinitialize accept_queue to trap illegal accesses. */
-		memset(&newicsk->icsk_accept_queue, 0, sizeof(newicsk->icsk_accept_queue));
 
 		if (sock_flag(newsk, SOCK_KEEPOPEN))
 			inet_csk_reset_keepalive_timer(newsk,