[INET_TWSK]: Introduce inet_twsk_alloc

With the parts of tcp_time_wait that are not TCP specific, tcp_time_wait uses
it and so will dccp_time_wait.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index d38d160..ceb577c 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -81,3 +81,31 @@
 
 	write_unlock(&ehead->lock);
 }
+
+struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int state)
+{
+	struct inet_timewait_sock *tw = kmem_cache_alloc(sk->sk_prot_creator->twsk_slab,
+							 SLAB_ATOMIC);
+	if (tw != NULL) {
+		const struct inet_sock *inet = inet_sk(sk);
+
+		/* Give us an identity. */
+		tw->tw_daddr	    = inet->daddr;
+		tw->tw_rcv_saddr    = inet->rcv_saddr;
+		tw->tw_bound_dev_if = sk->sk_bound_dev_if;
+		tw->tw_num	    = inet->num;
+		tw->tw_state	    = TCP_TIME_WAIT;
+		tw->tw_substate	    = state;
+		tw->tw_sport	    = inet->sport;
+		tw->tw_dport	    = inet->dport;
+		tw->tw_family	    = sk->sk_family;
+		tw->tw_reuse	    = sk->sk_reuse;
+		tw->tw_hashent	    = sk->sk_hashent;
+		tw->tw_ipv6only	    = 0;
+		tw->tw_prot	    = sk->sk_prot_creator;
+		atomic_set(&tw->tw_refcnt, 1);
+		inet_twsk_dead_node_init(tw);
+	}
+
+	return tw;
+}
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 4112f7a..66ce179 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -267,37 +267,18 @@
 		recycle_ok = tp->af_specific->remember_stamp(sk);
 
 	if (tcp_tw_count < sysctl_tcp_max_tw_buckets)
-		tw = kmem_cache_alloc(sk->sk_prot_creator->twsk_slab, SLAB_ATOMIC);
+		tw = inet_twsk_alloc(sk, state);
 
 	if (tw != NULL) {
 		struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw);
-		const struct inet_sock *inet = inet_sk(sk);
 		const int rto = (tp->rto << 2) - (tp->rto >> 1);
 
-		/* Remember our protocol */
-		tw->tw_prot		= sk->sk_prot_creator;
-
-		/* Give us an identity. */
-		tw->tw_daddr		= inet->daddr;
-		tw->tw_rcv_saddr	= inet->rcv_saddr;
-		tw->tw_bound_dev_if	= sk->sk_bound_dev_if;
-		tw->tw_num		= inet->num;
-		tw->tw_state		= TCP_TIME_WAIT;
-		tw->tw_substate		= state;
-		tw->tw_sport		= inet->sport;
-		tw->tw_dport		= inet->dport;
-		tw->tw_family		= sk->sk_family;
-		tw->tw_reuse		= sk->sk_reuse;
 		tw->tw_rcv_wscale	= tp->rx_opt.rcv_wscale;
-		atomic_set(&tw->tw_refcnt, 1);
-
-		tw->tw_hashent		= sk->sk_hashent;
 		tcptw->tw_rcv_nxt	= tp->rcv_nxt;
 		tcptw->tw_snd_nxt	= tp->snd_nxt;
 		tcptw->tw_rcv_wnd	= tcp_receive_window(tp);
 		tcptw->tw_ts_recent	= tp->rx_opt.ts_recent;
 		tcptw->tw_ts_recent_stamp = tp->rx_opt.ts_recent_stamp;
-		inet_twsk_dead_node_init(tw);
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 		if (tw->tw_family == PF_INET6) {
@@ -307,8 +288,7 @@
 			ipv6_addr_copy(&tcp6tw->tw_v6_daddr, &np->daddr);
 			ipv6_addr_copy(&tcp6tw->tw_v6_rcv_saddr, &np->rcv_saddr);
 			tw->tw_ipv6only = np->ipv6only;
-		} else
-			tw->tw_ipv6only = 0;
+		}
 #endif
 		/* Linkage updates. */
 		__inet_twsk_hashdance(tw, sk, &tcp_hashinfo);