[NET] Generalise TCP's struct open_request minisock infrastructure

Kept this first changeset minimal, without changing existing names to
ease peer review.

Basicaly tcp_openreq_alloc now receives the or_calltable, that in turn
has two new members:

->slab, that replaces tcp_openreq_cachep
->obj_size, to inform the size of the openreq descendant for
  a specific protocol

The protocol specific fields in struct open_request were moved to a
class hierarchy, with the things that are common to all connection
oriented PF_INET protocols in struct inet_request_sock, the TCP ones
in tcp_request_sock, that is an inet_request_sock, that is an
open_request.

I.e. this uses the same approach used for the struct sock class
hierarchy, with sk_prot indicating if the protocol wants to use the
open_request infrastructure by filling in sk_prot->rsk_prot with an
or_calltable.

Results? Performance is improved and TCP v4 now uses only 64 bytes per
open request minisock, down from 96 without this patch :-)

Next changeset will rename some of the structs, fields and functions
mentioned above, struct or_calltable is way unclear, better name it
struct request_sock_ops, s/struct open_request/struct request_sock/g,
etc.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index e923d2f..dd47e6d 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -190,6 +190,8 @@
 struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
 			     struct ip_options *opt)
 {
+	struct inet_request_sock *ireq;
+	struct tcp_request_sock *treq;
 	struct tcp_sock *tp = tcp_sk(sk);
 	__u32 cookie = ntohl(skb->h.th->ack_seq) - 1; 
 	struct sock *ret = sk;
@@ -209,19 +211,20 @@
 
 	NET_INC_STATS_BH(LINUX_MIB_SYNCOOKIESRECV);
 
-	req = tcp_openreq_alloc();
 	ret = NULL;
+	req = tcp_openreq_alloc(&or_ipv4); /* for safety */
 	if (!req)
 		goto out;
 
-	req->rcv_isn		= htonl(skb->h.th->seq) - 1;
-	req->snt_isn		= cookie; 
+	ireq = inet_rsk(req);
+	treq = tcp_rsk(req);
+	treq->rcv_isn		= htonl(skb->h.th->seq) - 1;
+	treq->snt_isn		= cookie; 
 	req->mss		= mss;
- 	req->rmt_port		= skb->h.th->source;
-	req->af.v4_req.loc_addr = skb->nh.iph->daddr;
-	req->af.v4_req.rmt_addr = skb->nh.iph->saddr;
-	req->class		= &or_ipv4; /* for savety */
-	req->af.v4_req.opt	= NULL;
+ 	ireq->rmt_port		= skb->h.th->source;
+	ireq->loc_addr		= skb->nh.iph->daddr;
+	ireq->rmt_addr		= skb->nh.iph->saddr;
+	ireq->opt		= NULL;
 
 	/* We throwed the options of the initial SYN away, so we hope
 	 * the ACK carries the same options again (see RFC1122 4.2.3.8)
@@ -229,17 +232,15 @@
 	if (opt && opt->optlen) {
 		int opt_size = sizeof(struct ip_options) + opt->optlen;
 
-		req->af.v4_req.opt = kmalloc(opt_size, GFP_ATOMIC);
-		if (req->af.v4_req.opt) {
-			if (ip_options_echo(req->af.v4_req.opt, skb)) {
-				kfree(req->af.v4_req.opt);
-				req->af.v4_req.opt = NULL;
-			}
+		ireq->opt = kmalloc(opt_size, GFP_ATOMIC);
+		if (ireq->opt != NULL && ip_options_echo(ireq->opt, skb)) {
+			kfree(ireq->opt);
+			ireq->opt = NULL;
 		}
 	}
 
-	req->snd_wscale = req->rcv_wscale = req->tstamp_ok = 0;
-	req->wscale_ok	= req->sack_ok = 0; 
+	ireq->snd_wscale = ireq->rcv_wscale = ireq->tstamp_ok = 0;
+	ireq->wscale_ok	 = ireq->sack_ok = 0; 
 	req->expires	= 0UL; 
 	req->retrans	= 0; 
 	
@@ -253,8 +254,8 @@
 		struct flowi fl = { .nl_u = { .ip4_u =
 					      { .daddr = ((opt && opt->srr) ?
 							  opt->faddr :
-							  req->af.v4_req.rmt_addr),
-						.saddr = req->af.v4_req.loc_addr,
+							  ireq->rmt_addr),
+						.saddr = ireq->loc_addr,
 						.tos = RT_CONN_FLAGS(sk) } },
 				    .proto = IPPROTO_TCP,
 				    .uli_u = { .ports =
@@ -272,7 +273,7 @@
 				  &req->rcv_wnd, &req->window_clamp, 
 				  0, &rcv_wscale);
 	/* BTW win scale with syncookies is 0 by definition */
-	req->rcv_wscale	  = rcv_wscale; 
+	ireq->rcv_wscale  = rcv_wscale; 
 
 	ret = get_cookie_sock(sk, skb, req, &rt->u.dst);
 out:	return ret;