aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@ghostprotocols.net>2005-06-19 01:46:52 -0400
committerDavid S. Miller <davem@davemloft.net>2005-06-19 01:46:52 -0400
commit2e6599cb899ba4b133f42cbf9d2b1883d2dc583a (patch)
treeb5d4fcca4d2a515fc3d3d20cefaaeebd8dbf661f
parent1944972d3bb651474a5021c9da8d0166ae19f1eb (diff)
[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>
-rw-r--r--include/linux/ip.h21
-rw-r--r--include/linux/ipv6.h13
-rw-r--r--include/linux/tcp.h11
-rw-r--r--include/net/request_sock.h77
-rw-r--r--include/net/sock.h4
-rw-r--r--include/net/tcp.h87
-rw-r--r--include/net/tcp_ecn.h7
-rw-r--r--net/core/sock.c35
-rw-r--r--net/ipv4/syncookies.c39
-rw-r--r--net/ipv4/tcp.c9
-rw-r--r--net/ipv4/tcp_diag.c25
-rw-r--r--net/ipv4/tcp_ipv4.c72
-rw-r--r--net/ipv4/tcp_minisocks.c48
-rw-r--r--net/ipv4/tcp_output.c25
-rw-r--r--net/ipv4/tcp_timer.c2
-rw-r--r--net/ipv6/tcp_ipv6.c96
16 files changed, 341 insertions, 230 deletions
diff --git a/include/linux/ip.h b/include/linux/ip.h
index 8438c68591f9..d5b7c907204e 100644
--- a/include/linux/ip.h
+++ b/include/linux/ip.h
@@ -81,6 +81,7 @@
81#ifdef __KERNEL__ 81#ifdef __KERNEL__
82#include <linux/config.h> 82#include <linux/config.h>
83#include <linux/types.h> 83#include <linux/types.h>
84#include <net/request_sock.h>
84#include <net/sock.h> 85#include <net/sock.h>
85#include <linux/igmp.h> 86#include <linux/igmp.h>
86#include <net/flow.h> 87#include <net/flow.h>
@@ -107,6 +108,26 @@ struct ip_options {
107 108
108#define optlength(opt) (sizeof(struct ip_options) + opt->optlen) 109#define optlength(opt) (sizeof(struct ip_options) + opt->optlen)
109 110
111struct inet_request_sock {
112 struct open_request req;
113 u32 loc_addr;
114 u32 rmt_addr;
115 u16 rmt_port;
116 u16 snd_wscale : 4,
117 rcv_wscale : 4,
118 tstamp_ok : 1,
119 sack_ok : 1,
120 wscale_ok : 1,
121 ecn_ok : 1,
122 acked : 1;
123 struct ip_options *opt;
124};
125
126static inline struct inet_request_sock *inet_rsk(const struct open_request *sk)
127{
128 return (struct inet_request_sock *)sk;
129}
130
110struct ipv6_pinfo; 131struct ipv6_pinfo;
111 132
112struct inet_sock { 133struct inet_sock {
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index ab0d0efbf240..98acdbf3d446 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -193,6 +193,19 @@ struct inet6_skb_parm {
193 193
194#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb)) 194#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb))
195 195
196struct tcp6_request_sock {
197 struct tcp_request_sock req;
198 struct in6_addr loc_addr;
199 struct in6_addr rmt_addr;
200 struct sk_buff *pktopts;
201 int iif;
202};
203
204static inline struct tcp6_request_sock *tcp6_rsk(const struct open_request *sk)
205{
206 return (struct tcp6_request_sock *)sk;
207}
208
196/** 209/**
197 * struct ipv6_pinfo - ipv6 private area 210 * struct ipv6_pinfo - ipv6 private area
198 * 211 *
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 14a55e3e3a50..86771b37b80d 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -230,6 +230,17 @@ struct tcp_options_received {
230 __u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ 230 __u16 mss_clamp; /* Maximal mss, negotiated at connection setup */
231}; 231};
232 232
233struct tcp_request_sock {
234 struct inet_request_sock req;
235 __u32 rcv_isn;
236 __u32 snt_isn;
237};
238
239static inline struct tcp_request_sock *tcp_rsk(const struct open_request *req)
240{
241 return (struct tcp_request_sock *)req;
242}
243
233struct tcp_sock { 244struct tcp_sock {
234 /* inet_sock has to be the first member of tcp_sock */ 245 /* inet_sock has to be the first member of tcp_sock */
235 struct inet_sock inet; 246 struct inet_sock inet;
diff --git a/include/net/request_sock.h b/include/net/request_sock.h
new file mode 100644
index 000000000000..9502f5587931
--- /dev/null
+++ b/include/net/request_sock.h
@@ -0,0 +1,77 @@
1/*
2 * NET Generic infrastructure for Network protocols.
3 *
4 * Definitions for request_sock
5 *
6 * Authors: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
7 *
8 * From code originally in include/net/tcp.h
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15#ifndef _REQUEST_SOCK_H
16#define _REQUEST_SOCK_H
17
18#include <linux/slab.h>
19#include <linux/types.h>
20#include <net/sock.h>
21
22struct open_request;
23struct sk_buff;
24struct dst_entry;
25struct proto;
26
27struct or_calltable {
28 int family;
29 kmem_cache_t *slab;
30 int obj_size;
31 int (*rtx_syn_ack)(struct sock *sk,
32 struct open_request *req,
33 struct dst_entry *dst);
34 void (*send_ack)(struct sk_buff *skb,
35 struct open_request *req);
36 void (*send_reset)(struct sk_buff *skb);
37 void (*destructor)(struct open_request *req);
38};
39
40/* struct open_request - mini sock to represent a connection request
41 */
42struct open_request {
43 struct open_request *dl_next; /* Must be first member! */
44 u16 mss;
45 u8 retrans;
46 u8 __pad;
47 /* The following two fields can be easily recomputed I think -AK */
48 u32 window_clamp; /* window clamp at creation time */
49 u32 rcv_wnd; /* rcv_wnd offered first time */
50 u32 ts_recent;
51 unsigned long expires;
52 struct or_calltable *class;
53 struct sock *sk;
54};
55
56static inline struct open_request *tcp_openreq_alloc(struct or_calltable *class)
57{
58 struct open_request *req = kmem_cache_alloc(class->slab, SLAB_ATOMIC);
59
60 if (req != NULL)
61 req->class = class;
62
63 return req;
64}
65
66static inline void tcp_openreq_fastfree(struct open_request *req)
67{
68 kmem_cache_free(req->class->slab, req);
69}
70
71static inline void tcp_openreq_free(struct open_request *req)
72{
73 req->class->destructor(req);
74 tcp_openreq_fastfree(req);
75}
76
77#endif /* _REQUEST_SOCK_H */
diff --git a/include/net/sock.h b/include/net/sock.h
index a9ef3a6a13f3..6919276af8af 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -484,6 +484,8 @@ extern void sk_stream_kill_queues(struct sock *sk);
484 484
485extern int sk_wait_data(struct sock *sk, long *timeo); 485extern int sk_wait_data(struct sock *sk, long *timeo);
486 486
487struct or_calltable;
488
487/* Networking protocol blocks we attach to sockets. 489/* Networking protocol blocks we attach to sockets.
488 * socket layer -> transport layer interface 490 * socket layer -> transport layer interface
489 * transport -> network interface is defined by struct inet_proto 491 * transport -> network interface is defined by struct inet_proto
@@ -547,6 +549,8 @@ struct proto {
547 kmem_cache_t *slab; 549 kmem_cache_t *slab;
548 unsigned int obj_size; 550 unsigned int obj_size;
549 551
552 struct or_calltable *rsk_prot;
553
550 struct module *owner; 554 struct module *owner;
551 555
552 char name[32]; 556 char name[32];
diff --git a/include/net/tcp.h b/include/net/tcp.h
index e71f8ba3e101..d438ba566b89 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -31,6 +31,7 @@
31#include <linux/cache.h> 31#include <linux/cache.h>
32#include <linux/percpu.h> 32#include <linux/percpu.h>
33#include <net/checksum.h> 33#include <net/checksum.h>
34#include <net/request_sock.h>
34#include <net/sock.h> 35#include <net/sock.h>
35#include <net/snmp.h> 36#include <net/snmp.h>
36#include <net/ip.h> 37#include <net/ip.h>
@@ -613,74 +614,6 @@ extern atomic_t tcp_memory_allocated;
613extern atomic_t tcp_sockets_allocated; 614extern atomic_t tcp_sockets_allocated;
614extern int tcp_memory_pressure; 615extern int tcp_memory_pressure;
615 616
616struct open_request;
617
618struct or_calltable {
619 int family;
620 int (*rtx_syn_ack) (struct sock *sk, struct open_request *req, struct dst_entry*);
621 void (*send_ack) (struct sk_buff *skb, struct open_request *req);
622 void (*destructor) (struct open_request *req);
623 void (*send_reset) (struct sk_buff *skb);
624};
625
626struct tcp_v4_open_req {
627 __u32 loc_addr;
628 __u32 rmt_addr;
629 struct ip_options *opt;
630};
631
632#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
633struct tcp_v6_open_req {
634 struct in6_addr loc_addr;
635 struct in6_addr rmt_addr;
636 struct sk_buff *pktopts;
637 int iif;
638};
639#endif
640
641/* this structure is too big */
642struct open_request {
643 struct open_request *dl_next; /* Must be first member! */
644 __u32 rcv_isn;
645 __u32 snt_isn;
646 __u16 rmt_port;
647 __u16 mss;
648 __u8 retrans;
649 __u8 __pad;
650 __u16 snd_wscale : 4,
651 rcv_wscale : 4,
652 tstamp_ok : 1,
653 sack_ok : 1,
654 wscale_ok : 1,
655 ecn_ok : 1,
656 acked : 1;
657 /* The following two fields can be easily recomputed I think -AK */
658 __u32 window_clamp; /* window clamp at creation time */
659 __u32 rcv_wnd; /* rcv_wnd offered first time */
660 __u32 ts_recent;
661 unsigned long expires;
662 struct or_calltable *class;
663 struct sock *sk;
664 union {
665 struct tcp_v4_open_req v4_req;
666#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
667 struct tcp_v6_open_req v6_req;
668#endif
669 } af;
670};
671
672/* SLAB cache for open requests. */
673extern kmem_cache_t *tcp_openreq_cachep;
674
675#define tcp_openreq_alloc() kmem_cache_alloc(tcp_openreq_cachep, SLAB_ATOMIC)
676#define tcp_openreq_fastfree(req) kmem_cache_free(tcp_openreq_cachep, req)
677
678static inline void tcp_openreq_free(struct open_request *req)
679{
680 req->class->destructor(req);
681 tcp_openreq_fastfree(req);
682}
683
684#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 617#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
685#define TCP_INET_FAMILY(fam) ((fam) == AF_INET) 618#define TCP_INET_FAMILY(fam) ((fam) == AF_INET)
686#else 619#else
@@ -1832,17 +1765,19 @@ static __inline__ void tcp_openreq_init(struct open_request *req,
1832 struct tcp_options_received *rx_opt, 1765 struct tcp_options_received *rx_opt,
1833 struct sk_buff *skb) 1766 struct sk_buff *skb)
1834{ 1767{
1768 struct inet_request_sock *ireq = inet_rsk(req);
1769
1835 req->rcv_wnd = 0; /* So that tcp_send_synack() knows! */ 1770 req->rcv_wnd = 0; /* So that tcp_send_synack() knows! */
1836 req->rcv_isn = TCP_SKB_CB(skb)->seq; 1771 tcp_rsk(req)->rcv_isn = TCP_SKB_CB(skb)->seq;
1837 req->mss = rx_opt->mss_clamp; 1772 req->mss = rx_opt->mss_clamp;
1838 req->ts_recent = rx_opt->saw_tstamp ? rx_opt->rcv_tsval : 0; 1773 req->ts_recent = rx_opt->saw_tstamp ? rx_opt->rcv_tsval : 0;
1839 req->tstamp_ok = rx_opt->tstamp_ok; 1774 ireq->tstamp_ok = rx_opt->tstamp_ok;
1840 req->sack_ok = rx_opt->sack_ok; 1775 ireq->sack_ok = rx_opt->sack_ok;
1841 req->snd_wscale = rx_opt->snd_wscale; 1776 ireq->snd_wscale = rx_opt->snd_wscale;
1842 req->wscale_ok = rx_opt->wscale_ok; 1777 ireq->wscale_ok = rx_opt->wscale_ok;
1843 req->acked = 0; 1778 ireq->acked = 0;
1844 req->ecn_ok = 0; 1779 ireq->ecn_ok = 0;
1845 req->rmt_port = skb->h.th->source; 1780 ireq->rmt_port = skb->h.th->source;
1846} 1781}
1847 1782
1848extern void tcp_enter_memory_pressure(void); 1783extern void tcp_enter_memory_pressure(void);
diff --git a/include/net/tcp_ecn.h b/include/net/tcp_ecn.h
index dc1456389a97..94ad970e844a 100644
--- a/include/net/tcp_ecn.h
+++ b/include/net/tcp_ecn.h
@@ -2,6 +2,7 @@
2#define _NET_TCP_ECN_H_ 1 2#define _NET_TCP_ECN_H_ 1
3 3
4#include <net/inet_ecn.h> 4#include <net/inet_ecn.h>
5#include <net/request_sock.h>
5 6
6#define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH)) 7#define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH))
7 8
@@ -40,7 +41,7 @@ static inline void TCP_ECN_send_syn(struct sock *sk, struct tcp_sock *tp,
40static __inline__ void 41static __inline__ void
41TCP_ECN_make_synack(struct open_request *req, struct tcphdr *th) 42TCP_ECN_make_synack(struct open_request *req, struct tcphdr *th)
42{ 43{
43 if (req->ecn_ok) 44 if (inet_rsk(req)->ecn_ok)
44 th->ece = 1; 45 th->ece = 1;
45} 46}
46 47
@@ -113,14 +114,14 @@ static inline int TCP_ECN_rcv_ecn_echo(struct tcp_sock *tp, struct tcphdr *th)
113static inline void TCP_ECN_openreq_child(struct tcp_sock *tp, 114static inline void TCP_ECN_openreq_child(struct tcp_sock *tp,
114 struct open_request *req) 115 struct open_request *req)
115{ 116{
116 tp->ecn_flags = req->ecn_ok ? TCP_ECN_OK : 0; 117 tp->ecn_flags = inet_rsk(req)->ecn_ok ? TCP_ECN_OK : 0;
117} 118}
118 119
119static __inline__ void 120static __inline__ void
120TCP_ECN_create_request(struct open_request *req, struct tcphdr *th) 121TCP_ECN_create_request(struct open_request *req, struct tcphdr *th)
121{ 122{
122 if (sysctl_tcp_ecn && th->ece && th->cwr) 123 if (sysctl_tcp_ecn && th->ece && th->cwr)
123 req->ecn_ok = 1; 124 inet_rsk(req)->ecn_ok = 1;
124} 125}
125 126
126#endif 127#endif
diff --git a/net/core/sock.c b/net/core/sock.c
index 96e00b08698f..a6ec3ada7f9e 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -118,6 +118,7 @@
118#include <linux/netdevice.h> 118#include <linux/netdevice.h>
119#include <net/protocol.h> 119#include <net/protocol.h>
120#include <linux/skbuff.h> 120#include <linux/skbuff.h>
121#include <net/request_sock.h>
121#include <net/sock.h> 122#include <net/sock.h>
122#include <net/xfrm.h> 123#include <net/xfrm.h>
123#include <linux/ipsec.h> 124#include <linux/ipsec.h>
@@ -1363,6 +1364,7 @@ static LIST_HEAD(proto_list);
1363 1364
1364int proto_register(struct proto *prot, int alloc_slab) 1365int proto_register(struct proto *prot, int alloc_slab)
1365{ 1366{
1367 char *request_sock_slab_name;
1366 int rc = -ENOBUFS; 1368 int rc = -ENOBUFS;
1367 1369
1368 if (alloc_slab) { 1370 if (alloc_slab) {
@@ -1374,6 +1376,25 @@ int proto_register(struct proto *prot, int alloc_slab)
1374 prot->name); 1376 prot->name);
1375 goto out; 1377 goto out;
1376 } 1378 }
1379
1380 if (prot->rsk_prot != NULL) {
1381 static const char mask[] = "request_sock_%s";
1382
1383 request_sock_slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL);
1384 if (request_sock_slab_name == NULL)
1385 goto out_free_sock_slab;
1386
1387 sprintf(request_sock_slab_name, mask, prot->name);
1388 prot->rsk_prot->slab = kmem_cache_create(request_sock_slab_name,
1389 prot->rsk_prot->obj_size, 0,
1390 SLAB_HWCACHE_ALIGN, NULL, NULL);
1391
1392 if (prot->rsk_prot->slab == NULL) {
1393 printk(KERN_CRIT "%s: Can't create request sock SLAB cache!\n",
1394 prot->name);
1395 goto out_free_request_sock_slab_name;
1396 }
1397 }
1377 } 1398 }
1378 1399
1379 write_lock(&proto_list_lock); 1400 write_lock(&proto_list_lock);
@@ -1382,6 +1403,12 @@ int proto_register(struct proto *prot, int alloc_slab)
1382 rc = 0; 1403 rc = 0;
1383out: 1404out:
1384 return rc; 1405 return rc;
1406out_free_request_sock_slab_name:
1407 kfree(request_sock_slab_name);
1408out_free_sock_slab:
1409 kmem_cache_destroy(prot->slab);
1410 prot->slab = NULL;
1411 goto out;
1385} 1412}
1386 1413
1387EXPORT_SYMBOL(proto_register); 1414EXPORT_SYMBOL(proto_register);
@@ -1395,6 +1422,14 @@ void proto_unregister(struct proto *prot)
1395 prot->slab = NULL; 1422 prot->slab = NULL;
1396 } 1423 }
1397 1424
1425 if (prot->rsk_prot != NULL && prot->rsk_prot->slab != NULL) {
1426 const char *name = kmem_cache_name(prot->rsk_prot->slab);
1427
1428 kmem_cache_destroy(prot->rsk_prot->slab);
1429 kfree(name);
1430 prot->rsk_prot->slab = NULL;
1431 }
1432
1398 list_del(&prot->node); 1433 list_del(&prot->node);
1399 write_unlock(&proto_list_lock); 1434 write_unlock(&proto_list_lock);
1400} 1435}
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index e923d2f021aa..dd47e6da6fb3 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -190,6 +190,8 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
190struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, 190struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
191 struct ip_options *opt) 191 struct ip_options *opt)
192{ 192{
193 struct inet_request_sock *ireq;
194 struct tcp_request_sock *treq;
193 struct tcp_sock *tp = tcp_sk(sk); 195 struct tcp_sock *tp = tcp_sk(sk);
194 __u32 cookie = ntohl(skb->h.th->ack_seq) - 1; 196 __u32 cookie = ntohl(skb->h.th->ack_seq) - 1;
195 struct sock *ret = sk; 197 struct sock *ret = sk;
@@ -209,19 +211,20 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
209 211
210 NET_INC_STATS_BH(LINUX_MIB_SYNCOOKIESRECV); 212 NET_INC_STATS_BH(LINUX_MIB_SYNCOOKIESRECV);
211 213
212 req = tcp_openreq_alloc();
213 ret = NULL; 214 ret = NULL;
215 req = tcp_openreq_alloc(&or_ipv4); /* for safety */
214 if (!req) 216 if (!req)
215 goto out; 217 goto out;
216 218
217 req->rcv_isn = htonl(skb->h.th->seq) - 1; 219 ireq = inet_rsk(req);
218 req->snt_isn = cookie; 220 treq = tcp_rsk(req);
221 treq->rcv_isn = htonl(skb->h.th->seq) - 1;
222 treq->snt_isn = cookie;
219 req->mss = mss; 223 req->mss = mss;
220 req->rmt_port = skb->h.th->source; 224 ireq->rmt_port = skb->h.th->source;
221 req->af.v4_req.loc_addr = skb->nh.iph->daddr; 225 ireq->loc_addr = skb->nh.iph->daddr;
222 req->af.v4_req.rmt_addr = skb->nh.iph->saddr; 226 ireq->rmt_addr = skb->nh.iph->saddr;
223 req->class = &or_ipv4; /* for savety */ 227 ireq->opt = NULL;
224 req->af.v4_req.opt = NULL;
225 228
226 /* We throwed the options of the initial SYN away, so we hope 229 /* We throwed the options of the initial SYN away, so we hope
227 * the ACK carries the same options again (see RFC1122 4.2.3.8) 230 * the ACK carries the same options again (see RFC1122 4.2.3.8)
@@ -229,17 +232,15 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
229 if (opt && opt->optlen) { 232 if (opt && opt->optlen) {
230 int opt_size = sizeof(struct ip_options) + opt->optlen; 233 int opt_size = sizeof(struct ip_options) + opt->optlen;
231 234
232 req->af.v4_req.opt = kmalloc(opt_size, GFP_ATOMIC); 235 ireq->opt = kmalloc(opt_size, GFP_ATOMIC);
233 if (req->af.v4_req.opt) { 236 if (ireq->opt != NULL && ip_options_echo(ireq->opt, skb)) {
234 if (ip_options_echo(req->af.v4_req.opt, skb)) { 237 kfree(ireq->opt);
235 kfree(req->af.v4_req.opt); 238 ireq->opt = NULL;
236 req->af.v4_req.opt = NULL;
237 }
238 } 239 }
239 } 240 }
240 241
241 req->snd_wscale = req->rcv_wscale = req->tstamp_ok = 0; 242 ireq->snd_wscale = ireq->rcv_wscale = ireq->tstamp_ok = 0;
242 req->wscale_ok = req->sack_ok = 0; 243 ireq->wscale_ok = ireq->sack_ok = 0;
243 req->expires = 0UL; 244 req->expires = 0UL;
244 req->retrans = 0; 245 req->retrans = 0;
245 246
@@ -253,8 +254,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
253 struct flowi fl = { .nl_u = { .ip4_u = 254 struct flowi fl = { .nl_u = { .ip4_u =
254 { .daddr = ((opt && opt->srr) ? 255 { .daddr = ((opt && opt->srr) ?
255 opt->faddr : 256 opt->faddr :
256 req->af.v4_req.rmt_addr), 257 ireq->rmt_addr),
257 .saddr = req->af.v4_req.loc_addr, 258 .saddr = ireq->loc_addr,
258 .tos = RT_CONN_FLAGS(sk) } }, 259 .tos = RT_CONN_FLAGS(sk) } },
259 .proto = IPPROTO_TCP, 260 .proto = IPPROTO_TCP,
260 .uli_u = { .ports = 261 .uli_u = { .ports =
@@ -272,7 +273,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
272 &req->rcv_wnd, &req->window_clamp, 273 &req->rcv_wnd, &req->window_clamp,
273 0, &rcv_wscale); 274 0, &rcv_wscale);
274 /* BTW win scale with syncookies is 0 by definition */ 275 /* BTW win scale with syncookies is 0 by definition */
275 req->rcv_wscale = rcv_wscale; 276 ireq->rcv_wscale = rcv_wscale;
276 277
277 ret = get_cookie_sock(sk, skb, req, &rt->u.dst); 278 ret = get_cookie_sock(sk, skb, req, &rt->u.dst);
278out: return ret; 279out: return ret;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 0d9a4fd5f1a4..a3cabfa2022a 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -271,7 +271,6 @@ int sysctl_tcp_fin_timeout = TCP_FIN_TIMEOUT;
271 271
272DEFINE_SNMP_STAT(struct tcp_mib, tcp_statistics); 272DEFINE_SNMP_STAT(struct tcp_mib, tcp_statistics);
273 273
274kmem_cache_t *tcp_openreq_cachep;
275kmem_cache_t *tcp_bucket_cachep; 274kmem_cache_t *tcp_bucket_cachep;
276kmem_cache_t *tcp_timewait_cachep; 275kmem_cache_t *tcp_timewait_cachep;
277 276
@@ -2271,13 +2270,6 @@ void __init tcp_init(void)
2271 __skb_cb_too_small_for_tcp(sizeof(struct tcp_skb_cb), 2270 __skb_cb_too_small_for_tcp(sizeof(struct tcp_skb_cb),
2272 sizeof(skb->cb)); 2271 sizeof(skb->cb));
2273 2272
2274 tcp_openreq_cachep = kmem_cache_create("tcp_open_request",
2275 sizeof(struct open_request),
2276 0, SLAB_HWCACHE_ALIGN,
2277 NULL, NULL);
2278 if (!tcp_openreq_cachep)
2279 panic("tcp_init: Cannot alloc open_request cache.");
2280
2281 tcp_bucket_cachep = kmem_cache_create("tcp_bind_bucket", 2273 tcp_bucket_cachep = kmem_cache_create("tcp_bind_bucket",
2282 sizeof(struct tcp_bind_bucket), 2274 sizeof(struct tcp_bind_bucket),
2283 0, SLAB_HWCACHE_ALIGN, 2275 0, SLAB_HWCACHE_ALIGN,
@@ -2374,7 +2366,6 @@ EXPORT_SYMBOL(tcp_destroy_sock);
2374EXPORT_SYMBOL(tcp_disconnect); 2366EXPORT_SYMBOL(tcp_disconnect);
2375EXPORT_SYMBOL(tcp_getsockopt); 2367EXPORT_SYMBOL(tcp_getsockopt);
2376EXPORT_SYMBOL(tcp_ioctl); 2368EXPORT_SYMBOL(tcp_ioctl);
2377EXPORT_SYMBOL(tcp_openreq_cachep);
2378EXPORT_SYMBOL(tcp_poll); 2369EXPORT_SYMBOL(tcp_poll);
2379EXPORT_SYMBOL(tcp_read_sock); 2370EXPORT_SYMBOL(tcp_read_sock);
2380EXPORT_SYMBOL(tcp_recvmsg); 2371EXPORT_SYMBOL(tcp_recvmsg);
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c
index 8faa8948f75c..700ff2413588 100644
--- a/net/ipv4/tcp_diag.c
+++ b/net/ipv4/tcp_diag.c
@@ -458,6 +458,7 @@ static int tcpdiag_fill_req(struct sk_buff *skb, struct sock *sk,
458 struct open_request *req, 458 struct open_request *req,
459 u32 pid, u32 seq) 459 u32 pid, u32 seq)
460{ 460{
461 const struct inet_request_sock *ireq = inet_rsk(req);
461 struct inet_sock *inet = inet_sk(sk); 462 struct inet_sock *inet = inet_sk(sk);
462 unsigned char *b = skb->tail; 463 unsigned char *b = skb->tail;
463 struct tcpdiagmsg *r; 464 struct tcpdiagmsg *r;
@@ -482,9 +483,9 @@ static int tcpdiag_fill_req(struct sk_buff *skb, struct sock *sk,
482 tmo = 0; 483 tmo = 0;
483 484
484 r->id.tcpdiag_sport = inet->sport; 485 r->id.tcpdiag_sport = inet->sport;
485 r->id.tcpdiag_dport = req->rmt_port; 486 r->id.tcpdiag_dport = ireq->rmt_port;
486 r->id.tcpdiag_src[0] = req->af.v4_req.loc_addr; 487 r->id.tcpdiag_src[0] = ireq->loc_addr;
487 r->id.tcpdiag_dst[0] = req->af.v4_req.rmt_addr; 488 r->id.tcpdiag_dst[0] = ireq->rmt_addr;
488 r->tcpdiag_expires = jiffies_to_msecs(tmo), 489 r->tcpdiag_expires = jiffies_to_msecs(tmo),
489 r->tcpdiag_rqueue = 0; 490 r->tcpdiag_rqueue = 0;
490 r->tcpdiag_wqueue = 0; 491 r->tcpdiag_wqueue = 0;
@@ -493,9 +494,9 @@ static int tcpdiag_fill_req(struct sk_buff *skb, struct sock *sk,
493#ifdef CONFIG_IP_TCPDIAG_IPV6 494#ifdef CONFIG_IP_TCPDIAG_IPV6
494 if (r->tcpdiag_family == AF_INET6) { 495 if (r->tcpdiag_family == AF_INET6) {
495 ipv6_addr_copy((struct in6_addr *)r->id.tcpdiag_src, 496 ipv6_addr_copy((struct in6_addr *)r->id.tcpdiag_src,
496 &req->af.v6_req.loc_addr); 497 &tcp6_rsk(req)->loc_addr);
497 ipv6_addr_copy((struct in6_addr *)r->id.tcpdiag_dst, 498 ipv6_addr_copy((struct in6_addr *)r->id.tcpdiag_dst,
498 &req->af.v6_req.rmt_addr); 499 &tcp6_rsk(req)->rmt_addr);
499 } 500 }
500#endif 501#endif
501 nlh->nlmsg_len = skb->tail - b; 502 nlh->nlmsg_len = skb->tail - b;
@@ -545,9 +546,11 @@ static int tcpdiag_dump_reqs(struct sk_buff *skb, struct sock *sk,
545 546
546 reqnum = 0; 547 reqnum = 0;
547 for (req = head; req; reqnum++, req = req->dl_next) { 548 for (req = head; req; reqnum++, req = req->dl_next) {
549 struct inet_request_sock *ireq = inet_rsk(req);
550
548 if (reqnum < s_reqnum) 551 if (reqnum < s_reqnum)
549 continue; 552 continue;
550 if (r->id.tcpdiag_dport != req->rmt_port && 553 if (r->id.tcpdiag_dport != ireq->rmt_port &&
551 r->id.tcpdiag_dport) 554 r->id.tcpdiag_dport)
552 continue; 555 continue;
553 556
@@ -555,16 +558,16 @@ static int tcpdiag_dump_reqs(struct sk_buff *skb, struct sock *sk,
555 entry.saddr = 558 entry.saddr =
556#ifdef CONFIG_IP_TCPDIAG_IPV6 559#ifdef CONFIG_IP_TCPDIAG_IPV6
557 (entry.family == AF_INET6) ? 560 (entry.family == AF_INET6) ?
558 req->af.v6_req.loc_addr.s6_addr32 : 561 tcp6_rsk(req)->loc_addr.s6_addr32 :
559#endif 562#endif
560 &req->af.v4_req.loc_addr; 563 &ireq->loc_addr;
561 entry.daddr = 564 entry.daddr =
562#ifdef CONFIG_IP_TCPDIAG_IPV6 565#ifdef CONFIG_IP_TCPDIAG_IPV6
563 (entry.family == AF_INET6) ? 566 (entry.family == AF_INET6) ?
564 req->af.v6_req.rmt_addr.s6_addr32 : 567 tcp6_rsk(req)->rmt_addr.s6_addr32 :
565#endif 568#endif
566 &req->af.v4_req.rmt_addr; 569 &ireq->rmt_addr;
567 entry.dport = ntohs(req->rmt_port); 570 entry.dport = ntohs(ireq->rmt_port);
568 571
569 if (!tcpdiag_bc_run(RTA_DATA(bc), 572 if (!tcpdiag_bc_run(RTA_DATA(bc),
570 RTA_PAYLOAD(bc), &entry)) 573 RTA_PAYLOAD(bc), &entry))
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index dad98e4a5043..e156be90df14 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -880,9 +880,11 @@ static struct open_request *tcp_v4_search_req(struct tcp_sock *tp,
880 for (prev = &lopt->syn_table[tcp_v4_synq_hash(raddr, rport, lopt->hash_rnd)]; 880 for (prev = &lopt->syn_table[tcp_v4_synq_hash(raddr, rport, lopt->hash_rnd)];
881 (req = *prev) != NULL; 881 (req = *prev) != NULL;
882 prev = &req->dl_next) { 882 prev = &req->dl_next) {
883 if (req->rmt_port == rport && 883 const struct inet_request_sock *ireq = inet_rsk(req);
884 req->af.v4_req.rmt_addr == raddr && 884
885 req->af.v4_req.loc_addr == laddr && 885 if (ireq->rmt_port == rport &&
886 ireq->rmt_addr == raddr &&
887 ireq->loc_addr == laddr &&
886 TCP_INET_FAMILY(req->class->family)) { 888 TCP_INET_FAMILY(req->class->family)) {
887 BUG_TRAP(!req->sk); 889 BUG_TRAP(!req->sk);
888 *prevp = prev; 890 *prevp = prev;
@@ -897,7 +899,7 @@ static void tcp_v4_synq_add(struct sock *sk, struct open_request *req)
897{ 899{
898 struct tcp_sock *tp = tcp_sk(sk); 900 struct tcp_sock *tp = tcp_sk(sk);
899 struct tcp_listen_opt *lopt = tp->listen_opt; 901 struct tcp_listen_opt *lopt = tp->listen_opt;
900 u32 h = tcp_v4_synq_hash(req->af.v4_req.rmt_addr, req->rmt_port, lopt->hash_rnd); 902 u32 h = tcp_v4_synq_hash(inet_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd);
901 903
902 req->expires = jiffies + TCP_TIMEOUT_INIT; 904 req->expires = jiffies + TCP_TIMEOUT_INIT;
903 req->retrans = 0; 905 req->retrans = 0;
@@ -1065,7 +1067,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 info)
1065 */ 1067 */
1066 BUG_TRAP(!req->sk); 1068 BUG_TRAP(!req->sk);
1067 1069
1068 if (seq != req->snt_isn) { 1070 if (seq != tcp_rsk(req)->snt_isn) {
1069 NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS); 1071 NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS);
1070 goto out; 1072 goto out;
1071 } 1073 }
@@ -1256,7 +1258,7 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
1256 1258
1257static void tcp_v4_or_send_ack(struct sk_buff *skb, struct open_request *req) 1259static void tcp_v4_or_send_ack(struct sk_buff *skb, struct open_request *req)
1258{ 1260{
1259 tcp_v4_send_ack(skb, req->snt_isn + 1, req->rcv_isn + 1, req->rcv_wnd, 1261 tcp_v4_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd,
1260 req->ts_recent); 1262 req->ts_recent);
1261} 1263}
1262 1264
@@ -1264,18 +1266,19 @@ static struct dst_entry* tcp_v4_route_req(struct sock *sk,
1264 struct open_request *req) 1266 struct open_request *req)
1265{ 1267{
1266 struct rtable *rt; 1268 struct rtable *rt;
1267 struct ip_options *opt = req->af.v4_req.opt; 1269 const struct inet_request_sock *ireq = inet_rsk(req);
1270 struct ip_options *opt = inet_rsk(req)->opt;
1268 struct flowi fl = { .oif = sk->sk_bound_dev_if, 1271 struct flowi fl = { .oif = sk->sk_bound_dev_if,
1269 .nl_u = { .ip4_u = 1272 .nl_u = { .ip4_u =
1270 { .daddr = ((opt && opt->srr) ? 1273 { .daddr = ((opt && opt->srr) ?
1271 opt->faddr : 1274 opt->faddr :
1272 req->af.v4_req.rmt_addr), 1275 ireq->rmt_addr),
1273 .saddr = req->af.v4_req.loc_addr, 1276 .saddr = ireq->loc_addr,
1274 .tos = RT_CONN_FLAGS(sk) } }, 1277 .tos = RT_CONN_FLAGS(sk) } },
1275 .proto = IPPROTO_TCP, 1278 .proto = IPPROTO_TCP,
1276 .uli_u = { .ports = 1279 .uli_u = { .ports =
1277 { .sport = inet_sk(sk)->sport, 1280 { .sport = inet_sk(sk)->sport,
1278 .dport = req->rmt_port } } }; 1281 .dport = ireq->rmt_port } } };
1279 1282
1280 if (ip_route_output_flow(&rt, &fl, sk, 0)) { 1283 if (ip_route_output_flow(&rt, &fl, sk, 0)) {
1281 IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); 1284 IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES);
@@ -1297,6 +1300,7 @@ static struct dst_entry* tcp_v4_route_req(struct sock *sk,
1297static int tcp_v4_send_synack(struct sock *sk, struct open_request *req, 1300static int tcp_v4_send_synack(struct sock *sk, struct open_request *req,
1298 struct dst_entry *dst) 1301 struct dst_entry *dst)
1299{ 1302{
1303 const struct inet_request_sock *ireq = inet_rsk(req);
1300 int err = -1; 1304 int err = -1;
1301 struct sk_buff * skb; 1305 struct sk_buff * skb;
1302 1306
@@ -1310,14 +1314,14 @@ static int tcp_v4_send_synack(struct sock *sk, struct open_request *req,
1310 struct tcphdr *th = skb->h.th; 1314 struct tcphdr *th = skb->h.th;
1311 1315
1312 th->check = tcp_v4_check(th, skb->len, 1316 th->check = tcp_v4_check(th, skb->len,
1313 req->af.v4_req.loc_addr, 1317 ireq->loc_addr,
1314 req->af.v4_req.rmt_addr, 1318 ireq->rmt_addr,
1315 csum_partial((char *)th, skb->len, 1319 csum_partial((char *)th, skb->len,
1316 skb->csum)); 1320 skb->csum));
1317 1321
1318 err = ip_build_and_send_pkt(skb, sk, req->af.v4_req.loc_addr, 1322 err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr,
1319 req->af.v4_req.rmt_addr, 1323 ireq->rmt_addr,
1320 req->af.v4_req.opt); 1324 ireq->opt);
1321 if (err == NET_XMIT_CN) 1325 if (err == NET_XMIT_CN)
1322 err = 0; 1326 err = 0;
1323 } 1327 }
@@ -1332,8 +1336,8 @@ out:
1332 */ 1336 */
1333static void tcp_v4_or_free(struct open_request *req) 1337static void tcp_v4_or_free(struct open_request *req)
1334{ 1338{
1335 if (req->af.v4_req.opt) 1339 if (inet_rsk(req)->opt)
1336 kfree(req->af.v4_req.opt); 1340 kfree(inet_rsk(req)->opt);
1337} 1341}
1338 1342
1339static inline void syn_flood_warning(struct sk_buff *skb) 1343static inline void syn_flood_warning(struct sk_buff *skb)
@@ -1387,6 +1391,7 @@ int sysctl_max_syn_backlog = 256;
1387 1391
1388struct or_calltable or_ipv4 = { 1392struct or_calltable or_ipv4 = {
1389 .family = PF_INET, 1393 .family = PF_INET,
1394 .obj_size = sizeof(struct tcp_request_sock),
1390 .rtx_syn_ack = tcp_v4_send_synack, 1395 .rtx_syn_ack = tcp_v4_send_synack,
1391 .send_ack = tcp_v4_or_send_ack, 1396 .send_ack = tcp_v4_or_send_ack,
1392 .destructor = tcp_v4_or_free, 1397 .destructor = tcp_v4_or_free,
@@ -1395,6 +1400,7 @@ struct or_calltable or_ipv4 = {
1395 1400
1396int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) 1401int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1397{ 1402{
1403 struct inet_request_sock *ireq;
1398 struct tcp_options_received tmp_opt; 1404 struct tcp_options_received tmp_opt;
1399 struct open_request *req; 1405 struct open_request *req;
1400 __u32 saddr = skb->nh.iph->saddr; 1406 __u32 saddr = skb->nh.iph->saddr;
@@ -1433,7 +1439,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1433 if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1) 1439 if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
1434 goto drop; 1440 goto drop;
1435 1441
1436 req = tcp_openreq_alloc(); 1442 req = tcp_openreq_alloc(&or_ipv4);
1437 if (!req) 1443 if (!req)
1438 goto drop; 1444 goto drop;
1439 1445
@@ -1461,10 +1467,10 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1461 1467
1462 tcp_openreq_init(req, &tmp_opt, skb); 1468 tcp_openreq_init(req, &tmp_opt, skb);
1463 1469
1464 req->af.v4_req.loc_addr = daddr; 1470 ireq = inet_rsk(req);
1465 req->af.v4_req.rmt_addr = saddr; 1471 ireq->loc_addr = daddr;
1466 req->af.v4_req.opt = tcp_v4_save_options(sk, skb); 1472 ireq->rmt_addr = saddr;
1467 req->class = &or_ipv4; 1473 ireq->opt = tcp_v4_save_options(sk, skb);
1468 if (!want_cookie) 1474 if (!want_cookie)
1469 TCP_ECN_create_request(req, skb->h.th); 1475 TCP_ECN_create_request(req, skb->h.th);
1470 1476
@@ -1523,7 +1529,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1523 1529
1524 isn = tcp_v4_init_sequence(sk, skb); 1530 isn = tcp_v4_init_sequence(sk, skb);
1525 } 1531 }
1526 req->snt_isn = isn; 1532 tcp_rsk(req)->snt_isn = isn;
1527 1533
1528 if (tcp_v4_send_synack(sk, req, dst)) 1534 if (tcp_v4_send_synack(sk, req, dst))
1529 goto drop_and_free; 1535 goto drop_and_free;
@@ -1551,6 +1557,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1551 struct open_request *req, 1557 struct open_request *req,
1552 struct dst_entry *dst) 1558 struct dst_entry *dst)
1553{ 1559{
1560 struct inet_request_sock *ireq;
1554 struct inet_sock *newinet; 1561 struct inet_sock *newinet;
1555 struct tcp_sock *newtp; 1562 struct tcp_sock *newtp;
1556 struct sock *newsk; 1563 struct sock *newsk;
@@ -1570,11 +1577,12 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1570 1577
1571 newtp = tcp_sk(newsk); 1578 newtp = tcp_sk(newsk);
1572 newinet = inet_sk(newsk); 1579 newinet = inet_sk(newsk);
1573 newinet->daddr = req->af.v4_req.rmt_addr; 1580 ireq = inet_rsk(req);
1574 newinet->rcv_saddr = req->af.v4_req.loc_addr; 1581 newinet->daddr = ireq->rmt_addr;
1575 newinet->saddr = req->af.v4_req.loc_addr; 1582 newinet->rcv_saddr = ireq->loc_addr;
1576 newinet->opt = req->af.v4_req.opt; 1583 newinet->saddr = ireq->loc_addr;
1577 req->af.v4_req.opt = NULL; 1584 newinet->opt = ireq->opt;
1585 ireq->opt = NULL;
1578 newinet->mc_index = tcp_v4_iif(skb); 1586 newinet->mc_index = tcp_v4_iif(skb);
1579 newinet->mc_ttl = skb->nh.iph->ttl; 1587 newinet->mc_ttl = skb->nh.iph->ttl;
1580 newtp->ext_header_len = 0; 1588 newtp->ext_header_len = 0;
@@ -2454,15 +2462,16 @@ void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo)
2454static void get_openreq4(struct sock *sk, struct open_request *req, 2462static void get_openreq4(struct sock *sk, struct open_request *req,
2455 char *tmpbuf, int i, int uid) 2463 char *tmpbuf, int i, int uid)
2456{ 2464{
2465 const struct inet_request_sock *ireq = inet_rsk(req);
2457 int ttd = req->expires - jiffies; 2466 int ttd = req->expires - jiffies;
2458 2467
2459 sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X" 2468 sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
2460 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p", 2469 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p",
2461 i, 2470 i,
2462 req->af.v4_req.loc_addr, 2471 ireq->loc_addr,
2463 ntohs(inet_sk(sk)->sport), 2472 ntohs(inet_sk(sk)->sport),
2464 req->af.v4_req.rmt_addr, 2473 ireq->rmt_addr,
2465 ntohs(req->rmt_port), 2474 ntohs(ireq->rmt_port),
2466 TCP_SYN_RECV, 2475 TCP_SYN_RECV,
2467 0, 0, /* could print option size, but that is af dependent. */ 2476 0, 0, /* could print option size, but that is af dependent. */
2468 1, /* timers active (only the expire timer) */ 2477 1, /* timers active (only the expire timer) */
@@ -2618,6 +2627,7 @@ struct proto tcp_prot = {
2618 .sysctl_rmem = sysctl_tcp_rmem, 2627 .sysctl_rmem = sysctl_tcp_rmem,
2619 .max_header = MAX_TCP_HEADER, 2628 .max_header = MAX_TCP_HEADER,
2620 .obj_size = sizeof(struct tcp_sock), 2629 .obj_size = sizeof(struct tcp_sock),
2630 .rsk_prot = &or_ipv4,
2621}; 2631};
2622 2632
2623 2633
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index eea1a17a9ac2..1037401c7cc8 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -692,6 +692,8 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
692 struct sock *newsk = sk_alloc(PF_INET, GFP_ATOMIC, sk->sk_prot, 0); 692 struct sock *newsk = sk_alloc(PF_INET, GFP_ATOMIC, sk->sk_prot, 0);
693 693
694 if(newsk != NULL) { 694 if(newsk != NULL) {
695 struct inet_request_sock *ireq = inet_rsk(req);
696 struct tcp_request_sock *treq = tcp_rsk(req);
695 struct tcp_sock *newtp; 697 struct tcp_sock *newtp;
696 struct sk_filter *filter; 698 struct sk_filter *filter;
697 699
@@ -703,7 +705,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
703 tcp_sk(newsk)->bind_hash = NULL; 705 tcp_sk(newsk)->bind_hash = NULL;
704 706
705 /* Clone the TCP header template */ 707 /* Clone the TCP header template */
706 inet_sk(newsk)->dport = req->rmt_port; 708 inet_sk(newsk)->dport = ireq->rmt_port;
707 709
708 sock_lock_init(newsk); 710 sock_lock_init(newsk);
709 bh_lock_sock(newsk); 711 bh_lock_sock(newsk);
@@ -739,14 +741,14 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
739 /* Now setup tcp_sock */ 741 /* Now setup tcp_sock */
740 newtp = tcp_sk(newsk); 742 newtp = tcp_sk(newsk);
741 newtp->pred_flags = 0; 743 newtp->pred_flags = 0;
742 newtp->rcv_nxt = req->rcv_isn + 1; 744 newtp->rcv_nxt = treq->rcv_isn + 1;
743 newtp->snd_nxt = req->snt_isn + 1; 745 newtp->snd_nxt = treq->snt_isn + 1;
744 newtp->snd_una = req->snt_isn + 1; 746 newtp->snd_una = treq->snt_isn + 1;
745 newtp->snd_sml = req->snt_isn + 1; 747 newtp->snd_sml = treq->snt_isn + 1;
746 748
747 tcp_prequeue_init(newtp); 749 tcp_prequeue_init(newtp);
748 750
749 tcp_init_wl(newtp, req->snt_isn, req->rcv_isn); 751 tcp_init_wl(newtp, treq->snt_isn, treq->rcv_isn);
750 752
751 newtp->retransmits = 0; 753 newtp->retransmits = 0;
752 newtp->backoff = 0; 754 newtp->backoff = 0;
@@ -775,10 +777,10 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
775 tcp_set_ca_state(newtp, TCP_CA_Open); 777 tcp_set_ca_state(newtp, TCP_CA_Open);
776 tcp_init_xmit_timers(newsk); 778 tcp_init_xmit_timers(newsk);
777 skb_queue_head_init(&newtp->out_of_order_queue); 779 skb_queue_head_init(&newtp->out_of_order_queue);
778 newtp->rcv_wup = req->rcv_isn + 1; 780 newtp->rcv_wup = treq->rcv_isn + 1;
779 newtp->write_seq = req->snt_isn + 1; 781 newtp->write_seq = treq->snt_isn + 1;
780 newtp->pushed_seq = newtp->write_seq; 782 newtp->pushed_seq = newtp->write_seq;
781 newtp->copied_seq = req->rcv_isn + 1; 783 newtp->copied_seq = treq->rcv_isn + 1;
782 784
783 newtp->rx_opt.saw_tstamp = 0; 785 newtp->rx_opt.saw_tstamp = 0;
784 786
@@ -808,18 +810,18 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
808 newsk->sk_socket = NULL; 810 newsk->sk_socket = NULL;
809 newsk->sk_sleep = NULL; 811 newsk->sk_sleep = NULL;
810 812
811 newtp->rx_opt.tstamp_ok = req->tstamp_ok; 813 newtp->rx_opt.tstamp_ok = ireq->tstamp_ok;
812 if((newtp->rx_opt.sack_ok = req->sack_ok) != 0) { 814 if((newtp->rx_opt.sack_ok = ireq->sack_ok) != 0) {
813 if (sysctl_tcp_fack) 815 if (sysctl_tcp_fack)
814 newtp->rx_opt.sack_ok |= 2; 816 newtp->rx_opt.sack_ok |= 2;
815 } 817 }
816 newtp->window_clamp = req->window_clamp; 818 newtp->window_clamp = req->window_clamp;
817 newtp->rcv_ssthresh = req->rcv_wnd; 819 newtp->rcv_ssthresh = req->rcv_wnd;
818 newtp->rcv_wnd = req->rcv_wnd; 820 newtp->rcv_wnd = req->rcv_wnd;
819 newtp->rx_opt.wscale_ok = req->wscale_ok; 821 newtp->rx_opt.wscale_ok = ireq->wscale_ok;
820 if (newtp->rx_opt.wscale_ok) { 822 if (newtp->rx_opt.wscale_ok) {
821 newtp->rx_opt.snd_wscale = req->snd_wscale; 823 newtp->rx_opt.snd_wscale = ireq->snd_wscale;
822 newtp->rx_opt.rcv_wscale = req->rcv_wscale; 824 newtp->rx_opt.rcv_wscale = ireq->rcv_wscale;
823 } else { 825 } else {
824 newtp->rx_opt.snd_wscale = newtp->rx_opt.rcv_wscale = 0; 826 newtp->rx_opt.snd_wscale = newtp->rx_opt.rcv_wscale = 0;
825 newtp->window_clamp = min(newtp->window_clamp, 65535U); 827 newtp->window_clamp = min(newtp->window_clamp, 65535U);
@@ -881,7 +883,7 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
881 } 883 }
882 884
883 /* Check for pure retransmitted SYN. */ 885 /* Check for pure retransmitted SYN. */
884 if (TCP_SKB_CB(skb)->seq == req->rcv_isn && 886 if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn &&
885 flg == TCP_FLAG_SYN && 887 flg == TCP_FLAG_SYN &&
886 !paws_reject) { 888 !paws_reject) {
887 /* 889 /*
@@ -959,7 +961,7 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
959 * Invalid ACK: reset will be sent by listening socket 961 * Invalid ACK: reset will be sent by listening socket
960 */ 962 */
961 if ((flg & TCP_FLAG_ACK) && 963 if ((flg & TCP_FLAG_ACK) &&
962 (TCP_SKB_CB(skb)->ack_seq != req->snt_isn+1)) 964 (TCP_SKB_CB(skb)->ack_seq != tcp_rsk(req)->snt_isn + 1))
963 return sk; 965 return sk;
964 966
965 /* Also, it would be not so bad idea to check rcv_tsecr, which 967 /* Also, it would be not so bad idea to check rcv_tsecr, which
@@ -970,7 +972,7 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
970 /* RFC793: "first check sequence number". */ 972 /* RFC793: "first check sequence number". */
971 973
972 if (paws_reject || !tcp_in_window(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq, 974 if (paws_reject || !tcp_in_window(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq,
973 req->rcv_isn+1, req->rcv_isn+1+req->rcv_wnd)) { 975 tcp_rsk(req)->rcv_isn + 1, tcp_rsk(req)->rcv_isn + 1 + req->rcv_wnd)) {
974 /* Out of window: send ACK and drop. */ 976 /* Out of window: send ACK and drop. */
975 if (!(flg & TCP_FLAG_RST)) 977 if (!(flg & TCP_FLAG_RST))
976 req->class->send_ack(skb, req); 978 req->class->send_ack(skb, req);
@@ -981,12 +983,12 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
981 983
982 /* In sequence, PAWS is OK. */ 984 /* In sequence, PAWS is OK. */
983 985
984 if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, req->rcv_isn+1)) 986 if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_isn + 1))
985 req->ts_recent = tmp_opt.rcv_tsval; 987 req->ts_recent = tmp_opt.rcv_tsval;
986 988
987 if (TCP_SKB_CB(skb)->seq == req->rcv_isn) { 989 if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn) {
988 /* Truncate SYN, it is out of window starting 990 /* Truncate SYN, it is out of window starting
989 at req->rcv_isn+1. */ 991 at tcp_rsk(req)->rcv_isn + 1. */
990 flg &= ~TCP_FLAG_SYN; 992 flg &= ~TCP_FLAG_SYN;
991 } 993 }
992 994
@@ -1003,8 +1005,8 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
1003 return NULL; 1005 return NULL;
1004 1006
1005 /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */ 1007 /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */
1006 if (tp->defer_accept && TCP_SKB_CB(skb)->end_seq == req->rcv_isn+1) { 1008 if (tp->defer_accept && TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) {
1007 req->acked = 1; 1009 inet_rsk(req)->acked = 1;
1008 return NULL; 1010 return NULL;
1009 } 1011 }
1010 1012
@@ -1026,7 +1028,7 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
1026 1028
1027 listen_overflow: 1029 listen_overflow:
1028 if (!sysctl_tcp_abort_on_overflow) { 1030 if (!sysctl_tcp_abort_on_overflow) {
1029 req->acked = 1; 1031 inet_rsk(req)->acked = 1;
1030 return NULL; 1032 return NULL;
1031 } 1033 }
1032 1034
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index fa24e7ae1f40..f3c8747caf91 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1358,6 +1358,7 @@ int tcp_send_synack(struct sock *sk)
1358struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, 1358struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
1359 struct open_request *req) 1359 struct open_request *req)
1360{ 1360{
1361 struct inet_request_sock *ireq = inet_rsk(req);
1361 struct tcp_sock *tp = tcp_sk(sk); 1362 struct tcp_sock *tp = tcp_sk(sk);
1362 struct tcphdr *th; 1363 struct tcphdr *th;
1363 int tcp_header_size; 1364 int tcp_header_size;
@@ -1373,47 +1374,47 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
1373 skb->dst = dst_clone(dst); 1374 skb->dst = dst_clone(dst);
1374 1375
1375 tcp_header_size = (sizeof(struct tcphdr) + TCPOLEN_MSS + 1376 tcp_header_size = (sizeof(struct tcphdr) + TCPOLEN_MSS +
1376 (req->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0) + 1377 (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0) +
1377 (req->wscale_ok ? TCPOLEN_WSCALE_ALIGNED : 0) + 1378 (ireq->wscale_ok ? TCPOLEN_WSCALE_ALIGNED : 0) +
1378 /* SACK_PERM is in the place of NOP NOP of TS */ 1379 /* SACK_PERM is in the place of NOP NOP of TS */
1379 ((req->sack_ok && !req->tstamp_ok) ? TCPOLEN_SACKPERM_ALIGNED : 0)); 1380 ((ireq->sack_ok && !ireq->tstamp_ok) ? TCPOLEN_SACKPERM_ALIGNED : 0));
1380 skb->h.th = th = (struct tcphdr *) skb_push(skb, tcp_header_size); 1381 skb->h.th = th = (struct tcphdr *) skb_push(skb, tcp_header_size);
1381 1382
1382 memset(th, 0, sizeof(struct tcphdr)); 1383 memset(th, 0, sizeof(struct tcphdr));
1383 th->syn = 1; 1384 th->syn = 1;
1384 th->ack = 1; 1385 th->ack = 1;
1385 if (dst->dev->features&NETIF_F_TSO) 1386 if (dst->dev->features&NETIF_F_TSO)
1386 req->ecn_ok = 0; 1387 ireq->ecn_ok = 0;
1387 TCP_ECN_make_synack(req, th); 1388 TCP_ECN_make_synack(req, th);
1388 th->source = inet_sk(sk)->sport; 1389 th->source = inet_sk(sk)->sport;
1389 th->dest = req->rmt_port; 1390 th->dest = ireq->rmt_port;
1390 TCP_SKB_CB(skb)->seq = req->snt_isn; 1391 TCP_SKB_CB(skb)->seq = tcp_rsk(req)->snt_isn;
1391 TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1; 1392 TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1;
1392 TCP_SKB_CB(skb)->sacked = 0; 1393 TCP_SKB_CB(skb)->sacked = 0;
1393 skb_shinfo(skb)->tso_segs = 1; 1394 skb_shinfo(skb)->tso_segs = 1;
1394 skb_shinfo(skb)->tso_size = 0; 1395 skb_shinfo(skb)->tso_size = 0;
1395 th->seq = htonl(TCP_SKB_CB(skb)->seq); 1396 th->seq = htonl(TCP_SKB_CB(skb)->seq);
1396 th->ack_seq = htonl(req->rcv_isn + 1); 1397 th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1);
1397 if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */ 1398 if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */
1398 __u8 rcv_wscale; 1399 __u8 rcv_wscale;
1399 /* Set this up on the first call only */ 1400 /* Set this up on the first call only */
1400 req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW); 1401 req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW);
1401 /* tcp_full_space because it is guaranteed to be the first packet */ 1402 /* tcp_full_space because it is guaranteed to be the first packet */
1402 tcp_select_initial_window(tcp_full_space(sk), 1403 tcp_select_initial_window(tcp_full_space(sk),
1403 dst_metric(dst, RTAX_ADVMSS) - (req->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), 1404 dst_metric(dst, RTAX_ADVMSS) - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0),
1404 &req->rcv_wnd, 1405 &req->rcv_wnd,
1405 &req->window_clamp, 1406 &req->window_clamp,
1406 req->wscale_ok, 1407 ireq->wscale_ok,
1407 &rcv_wscale); 1408 &rcv_wscale);
1408 req->rcv_wscale = rcv_wscale; 1409 ireq->rcv_wscale = rcv_wscale;
1409 } 1410 }
1410 1411
1411 /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ 1412 /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */
1412 th->window = htons(req->rcv_wnd); 1413 th->window = htons(req->rcv_wnd);
1413 1414
1414 TCP_SKB_CB(skb)->when = tcp_time_stamp; 1415 TCP_SKB_CB(skb)->when = tcp_time_stamp;
1415 tcp_syn_build_options((__u32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), req->tstamp_ok, 1416 tcp_syn_build_options((__u32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), ireq->tstamp_ok,
1416 req->sack_ok, req->wscale_ok, req->rcv_wscale, 1417 ireq->sack_ok, ireq->wscale_ok, ireq->rcv_wscale,
1417 TCP_SKB_CB(skb)->when, 1418 TCP_SKB_CB(skb)->when,
1418 req->ts_recent); 1419 req->ts_recent);
1419 1420
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 799ebe061e2c..ba30ca0aa6a3 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -513,7 +513,7 @@ static void tcp_synack_timer(struct sock *sk)
513 while ((req = *reqp) != NULL) { 513 while ((req = *reqp) != NULL) {
514 if (time_after_eq(now, req->expires)) { 514 if (time_after_eq(now, req->expires)) {
515 if ((req->retrans < thresh || 515 if ((req->retrans < thresh ||
516 (req->acked && req->retrans < max_retries)) 516 (inet_rsk(req)->acked && req->retrans < max_retries))
517 && !req->class->rtx_syn_ack(sk, req, NULL)) { 517 && !req->class->rtx_syn_ack(sk, req, NULL)) {
518 unsigned long timeo; 518 unsigned long timeo;
519 519
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 0f69e800a0ad..9199ad2fde0d 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -407,11 +407,13 @@ static struct open_request *tcp_v6_search_req(struct tcp_sock *tp,
407 for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport, lopt->hash_rnd)]; 407 for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport, lopt->hash_rnd)];
408 (req = *prev) != NULL; 408 (req = *prev) != NULL;
409 prev = &req->dl_next) { 409 prev = &req->dl_next) {
410 if (req->rmt_port == rport && 410 const struct tcp6_request_sock *treq = tcp6_rsk(req);
411
412 if (inet_rsk(req)->rmt_port == rport &&
411 req->class->family == AF_INET6 && 413 req->class->family == AF_INET6 &&
412 ipv6_addr_equal(&req->af.v6_req.rmt_addr, raddr) && 414 ipv6_addr_equal(&treq->rmt_addr, raddr) &&
413 ipv6_addr_equal(&req->af.v6_req.loc_addr, laddr) && 415 ipv6_addr_equal(&treq->loc_addr, laddr) &&
414 (!req->af.v6_req.iif || req->af.v6_req.iif == iif)) { 416 (!treq->iif || treq->iif == iif)) {
415 BUG_TRAP(req->sk == NULL); 417 BUG_TRAP(req->sk == NULL);
416 *prevp = prev; 418 *prevp = prev;
417 return req; 419 return req;
@@ -923,7 +925,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
923 */ 925 */
924 BUG_TRAP(req->sk == NULL); 926 BUG_TRAP(req->sk == NULL);
925 927
926 if (seq != req->snt_isn) { 928 if (seq != tcp_rsk(req)->snt_isn) {
927 NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS); 929 NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS);
928 goto out; 930 goto out;
929 } 931 }
@@ -960,6 +962,7 @@ out:
960static int tcp_v6_send_synack(struct sock *sk, struct open_request *req, 962static int tcp_v6_send_synack(struct sock *sk, struct open_request *req,
961 struct dst_entry *dst) 963 struct dst_entry *dst)
962{ 964{
965 struct tcp6_request_sock *treq = tcp6_rsk(req);
963 struct ipv6_pinfo *np = inet6_sk(sk); 966 struct ipv6_pinfo *np = inet6_sk(sk);
964 struct sk_buff * skb; 967 struct sk_buff * skb;
965 struct ipv6_txoptions *opt = NULL; 968 struct ipv6_txoptions *opt = NULL;
@@ -969,19 +972,19 @@ static int tcp_v6_send_synack(struct sock *sk, struct open_request *req,
969 972
970 memset(&fl, 0, sizeof(fl)); 973 memset(&fl, 0, sizeof(fl));
971 fl.proto = IPPROTO_TCP; 974 fl.proto = IPPROTO_TCP;
972 ipv6_addr_copy(&fl.fl6_dst, &req->af.v6_req.rmt_addr); 975 ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
973 ipv6_addr_copy(&fl.fl6_src, &req->af.v6_req.loc_addr); 976 ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
974 fl.fl6_flowlabel = 0; 977 fl.fl6_flowlabel = 0;
975 fl.oif = req->af.v6_req.iif; 978 fl.oif = treq->iif;
976 fl.fl_ip_dport = req->rmt_port; 979 fl.fl_ip_dport = inet_rsk(req)->rmt_port;
977 fl.fl_ip_sport = inet_sk(sk)->sport; 980 fl.fl_ip_sport = inet_sk(sk)->sport;
978 981
979 if (dst == NULL) { 982 if (dst == NULL) {
980 opt = np->opt; 983 opt = np->opt;
981 if (opt == NULL && 984 if (opt == NULL &&
982 np->rxopt.bits.srcrt == 2 && 985 np->rxopt.bits.srcrt == 2 &&
983 req->af.v6_req.pktopts) { 986 treq->pktopts) {
984 struct sk_buff *pktopts = req->af.v6_req.pktopts; 987 struct sk_buff *pktopts = treq->pktopts;
985 struct inet6_skb_parm *rxopt = IP6CB(pktopts); 988 struct inet6_skb_parm *rxopt = IP6CB(pktopts);
986 if (rxopt->srcrt) 989 if (rxopt->srcrt)
987 opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(pktopts->nh.raw + rxopt->srcrt)); 990 opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(pktopts->nh.raw + rxopt->srcrt));
@@ -1008,10 +1011,10 @@ static int tcp_v6_send_synack(struct sock *sk, struct open_request *req,
1008 struct tcphdr *th = skb->h.th; 1011 struct tcphdr *th = skb->h.th;
1009 1012
1010 th->check = tcp_v6_check(th, skb->len, 1013 th->check = tcp_v6_check(th, skb->len,
1011 &req->af.v6_req.loc_addr, &req->af.v6_req.rmt_addr, 1014 &treq->loc_addr, &treq->rmt_addr,
1012 csum_partial((char *)th, skb->len, skb->csum)); 1015 csum_partial((char *)th, skb->len, skb->csum));
1013 1016
1014 ipv6_addr_copy(&fl.fl6_dst, &req->af.v6_req.rmt_addr); 1017 ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
1015 err = ip6_xmit(sk, skb, &fl, opt, 0); 1018 err = ip6_xmit(sk, skb, &fl, opt, 0);
1016 if (err == NET_XMIT_CN) 1019 if (err == NET_XMIT_CN)
1017 err = 0; 1020 err = 0;
@@ -1026,12 +1029,13 @@ done:
1026 1029
1027static void tcp_v6_or_free(struct open_request *req) 1030static void tcp_v6_or_free(struct open_request *req)
1028{ 1031{
1029 if (req->af.v6_req.pktopts) 1032 if (tcp6_rsk(req)->pktopts)
1030 kfree_skb(req->af.v6_req.pktopts); 1033 kfree_skb(tcp6_rsk(req)->pktopts);
1031} 1034}
1032 1035
1033static struct or_calltable or_ipv6 = { 1036static struct or_calltable or_ipv6 = {
1034 .family = AF_INET6, 1037 .family = AF_INET6,
1038 .obj_size = sizeof(struct tcp6_request_sock),
1035 .rtx_syn_ack = tcp_v6_send_synack, 1039 .rtx_syn_ack = tcp_v6_send_synack,
1036 .send_ack = tcp_v6_or_send_ack, 1040 .send_ack = tcp_v6_or_send_ack,
1037 .destructor = tcp_v6_or_free, 1041 .destructor = tcp_v6_or_free,
@@ -1221,7 +1225,7 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
1221 1225
1222static void tcp_v6_or_send_ack(struct sk_buff *skb, struct open_request *req) 1226static void tcp_v6_or_send_ack(struct sk_buff *skb, struct open_request *req)
1223{ 1227{
1224 tcp_v6_send_ack(skb, req->snt_isn+1, req->rcv_isn+1, req->rcv_wnd, req->ts_recent); 1228 tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent);
1225} 1229}
1226 1230
1227 1231
@@ -1264,7 +1268,7 @@ static void tcp_v6_synq_add(struct sock *sk, struct open_request *req)
1264{ 1268{
1265 struct tcp_sock *tp = tcp_sk(sk); 1269 struct tcp_sock *tp = tcp_sk(sk);
1266 struct tcp_listen_opt *lopt = tp->listen_opt; 1270 struct tcp_listen_opt *lopt = tp->listen_opt;
1267 u32 h = tcp_v6_synq_hash(&req->af.v6_req.rmt_addr, req->rmt_port, lopt->hash_rnd); 1271 u32 h = tcp_v6_synq_hash(&tcp6_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd);
1268 1272
1269 req->sk = NULL; 1273 req->sk = NULL;
1270 req->expires = jiffies + TCP_TIMEOUT_INIT; 1274 req->expires = jiffies + TCP_TIMEOUT_INIT;
@@ -1284,6 +1288,7 @@ static void tcp_v6_synq_add(struct sock *sk, struct open_request *req)
1284 */ 1288 */
1285static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) 1289static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1286{ 1290{
1291 struct tcp6_request_sock *treq;
1287 struct ipv6_pinfo *np = inet6_sk(sk); 1292 struct ipv6_pinfo *np = inet6_sk(sk);
1288 struct tcp_options_received tmp_opt; 1293 struct tcp_options_received tmp_opt;
1289 struct tcp_sock *tp = tcp_sk(sk); 1294 struct tcp_sock *tp = tcp_sk(sk);
@@ -1308,7 +1313,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1308 if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1) 1313 if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
1309 goto drop; 1314 goto drop;
1310 1315
1311 req = tcp_openreq_alloc(); 1316 req = tcp_openreq_alloc(&or_ipv6);
1312 if (req == NULL) 1317 if (req == NULL)
1313 goto drop; 1318 goto drop;
1314 1319
@@ -1321,28 +1326,28 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1321 tmp_opt.tstamp_ok = tmp_opt.saw_tstamp; 1326 tmp_opt.tstamp_ok = tmp_opt.saw_tstamp;
1322 tcp_openreq_init(req, &tmp_opt, skb); 1327 tcp_openreq_init(req, &tmp_opt, skb);
1323 1328
1324 req->class = &or_ipv6; 1329 treq = tcp6_rsk(req);
1325 ipv6_addr_copy(&req->af.v6_req.rmt_addr, &skb->nh.ipv6h->saddr); 1330 ipv6_addr_copy(&treq->rmt_addr, &skb->nh.ipv6h->saddr);
1326 ipv6_addr_copy(&req->af.v6_req.loc_addr, &skb->nh.ipv6h->daddr); 1331 ipv6_addr_copy(&treq->loc_addr, &skb->nh.ipv6h->daddr);
1327 TCP_ECN_create_request(req, skb->h.th); 1332 TCP_ECN_create_request(req, skb->h.th);
1328 req->af.v6_req.pktopts = NULL; 1333 treq->pktopts = NULL;
1329 if (ipv6_opt_accepted(sk, skb) || 1334 if (ipv6_opt_accepted(sk, skb) ||
1330 np->rxopt.bits.rxinfo || 1335 np->rxopt.bits.rxinfo ||
1331 np->rxopt.bits.rxhlim) { 1336 np->rxopt.bits.rxhlim) {
1332 atomic_inc(&skb->users); 1337 atomic_inc(&skb->users);
1333 req->af.v6_req.pktopts = skb; 1338 treq->pktopts = skb;
1334 } 1339 }
1335 req->af.v6_req.iif = sk->sk_bound_dev_if; 1340 treq->iif = sk->sk_bound_dev_if;
1336 1341
1337 /* So that link locals have meaning */ 1342 /* So that link locals have meaning */
1338 if (!sk->sk_bound_dev_if && 1343 if (!sk->sk_bound_dev_if &&
1339 ipv6_addr_type(&req->af.v6_req.rmt_addr) & IPV6_ADDR_LINKLOCAL) 1344 ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL)
1340 req->af.v6_req.iif = tcp_v6_iif(skb); 1345 treq->iif = tcp_v6_iif(skb);
1341 1346
1342 if (isn == 0) 1347 if (isn == 0)
1343 isn = tcp_v6_init_sequence(sk,skb); 1348 isn = tcp_v6_init_sequence(sk,skb);
1344 1349
1345 req->snt_isn = isn; 1350 tcp_rsk(req)->snt_isn = isn;
1346 1351
1347 if (tcp_v6_send_synack(sk, req, NULL)) 1352 if (tcp_v6_send_synack(sk, req, NULL))
1348 goto drop; 1353 goto drop;
@@ -1363,6 +1368,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1363 struct open_request *req, 1368 struct open_request *req,
1364 struct dst_entry *dst) 1369 struct dst_entry *dst)
1365{ 1370{
1371 struct tcp6_request_sock *treq = tcp6_rsk(req);
1366 struct ipv6_pinfo *newnp, *np = inet6_sk(sk); 1372 struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
1367 struct tcp6_sock *newtcp6sk; 1373 struct tcp6_sock *newtcp6sk;
1368 struct inet_sock *newinet; 1374 struct inet_sock *newinet;
@@ -1426,10 +1432,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1426 goto out_overflow; 1432 goto out_overflow;
1427 1433
1428 if (np->rxopt.bits.srcrt == 2 && 1434 if (np->rxopt.bits.srcrt == 2 &&
1429 opt == NULL && req->af.v6_req.pktopts) { 1435 opt == NULL && treq->pktopts) {
1430 struct inet6_skb_parm *rxopt = IP6CB(req->af.v6_req.pktopts); 1436 struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts);
1431 if (rxopt->srcrt) 1437 if (rxopt->srcrt)
1432 opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(req->af.v6_req.pktopts->nh.raw+rxopt->srcrt)); 1438 opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr *)(treq->pktopts->nh.raw + rxopt->srcrt));
1433 } 1439 }
1434 1440
1435 if (dst == NULL) { 1441 if (dst == NULL) {
@@ -1438,16 +1444,16 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1438 1444
1439 memset(&fl, 0, sizeof(fl)); 1445 memset(&fl, 0, sizeof(fl));
1440 fl.proto = IPPROTO_TCP; 1446 fl.proto = IPPROTO_TCP;
1441 ipv6_addr_copy(&fl.fl6_dst, &req->af.v6_req.rmt_addr); 1447 ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
1442 if (opt && opt->srcrt) { 1448 if (opt && opt->srcrt) {
1443 struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; 1449 struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
1444 ipv6_addr_copy(&final, &fl.fl6_dst); 1450 ipv6_addr_copy(&final, &fl.fl6_dst);
1445 ipv6_addr_copy(&fl.fl6_dst, rt0->addr); 1451 ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
1446 final_p = &final; 1452 final_p = &final;
1447 } 1453 }
1448 ipv6_addr_copy(&fl.fl6_src, &req->af.v6_req.loc_addr); 1454 ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
1449 fl.oif = sk->sk_bound_dev_if; 1455 fl.oif = sk->sk_bound_dev_if;
1450 fl.fl_ip_dport = req->rmt_port; 1456 fl.fl_ip_dport = inet_rsk(req)->rmt_port;
1451 fl.fl_ip_sport = inet_sk(sk)->sport; 1457 fl.fl_ip_sport = inet_sk(sk)->sport;
1452 1458
1453 if (ip6_dst_lookup(sk, &dst, &fl)) 1459 if (ip6_dst_lookup(sk, &dst, &fl))
@@ -1482,10 +1488,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1482 1488
1483 memcpy(newnp, np, sizeof(struct ipv6_pinfo)); 1489 memcpy(newnp, np, sizeof(struct ipv6_pinfo));
1484 1490
1485 ipv6_addr_copy(&newnp->daddr, &req->af.v6_req.rmt_addr); 1491 ipv6_addr_copy(&newnp->daddr, &treq->rmt_addr);
1486 ipv6_addr_copy(&newnp->saddr, &req->af.v6_req.loc_addr); 1492 ipv6_addr_copy(&newnp->saddr, &treq->loc_addr);
1487 ipv6_addr_copy(&newnp->rcv_saddr, &req->af.v6_req.loc_addr); 1493 ipv6_addr_copy(&newnp->rcv_saddr, &treq->loc_addr);
1488 newsk->sk_bound_dev_if = req->af.v6_req.iif; 1494 newsk->sk_bound_dev_if = treq->iif;
1489 1495
1490 /* Now IPv6 options... 1496 /* Now IPv6 options...
1491 1497
@@ -1498,11 +1504,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1498 1504
1499 /* Clone pktoptions received with SYN */ 1505 /* Clone pktoptions received with SYN */
1500 newnp->pktoptions = NULL; 1506 newnp->pktoptions = NULL;
1501 if (req->af.v6_req.pktopts) { 1507 if (treq->pktopts != NULL) {
1502 newnp->pktoptions = skb_clone(req->af.v6_req.pktopts, 1508 newnp->pktoptions = skb_clone(treq->pktopts, GFP_ATOMIC);
1503 GFP_ATOMIC); 1509 kfree_skb(treq->pktopts);
1504 kfree_skb(req->af.v6_req.pktopts); 1510 treq->pktopts = NULL;
1505 req->af.v6_req.pktopts = NULL;
1506 if (newnp->pktoptions) 1511 if (newnp->pktoptions)
1507 skb_set_owner_r(newnp->pktoptions, newsk); 1512 skb_set_owner_r(newnp->pktoptions, newsk);
1508 } 1513 }
@@ -2058,8 +2063,8 @@ static void get_openreq6(struct seq_file *seq,
2058 if (ttd < 0) 2063 if (ttd < 0)
2059 ttd = 0; 2064 ttd = 0;
2060 2065
2061 src = &req->af.v6_req.loc_addr; 2066 src = &tcp6_rsk(req)->loc_addr;
2062 dest = &req->af.v6_req.rmt_addr; 2067 dest = &tcp6_rsk(req)->rmt_addr;
2063 seq_printf(seq, 2068 seq_printf(seq,
2064 "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " 2069 "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
2065 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p\n", 2070 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p\n",
@@ -2069,7 +2074,7 @@ static void get_openreq6(struct seq_file *seq,
2069 ntohs(inet_sk(sk)->sport), 2074 ntohs(inet_sk(sk)->sport),
2070 dest->s6_addr32[0], dest->s6_addr32[1], 2075 dest->s6_addr32[0], dest->s6_addr32[1],
2071 dest->s6_addr32[2], dest->s6_addr32[3], 2076 dest->s6_addr32[2], dest->s6_addr32[3],
2072 ntohs(req->rmt_port), 2077 ntohs(inet_rsk(req)->rmt_port),
2073 TCP_SYN_RECV, 2078 TCP_SYN_RECV,
2074 0,0, /* could print option size, but that is af dependent. */ 2079 0,0, /* could print option size, but that is af dependent. */
2075 1, /* timers active (only the expire timer) */ 2080 1, /* timers active (only the expire timer) */
@@ -2239,6 +2244,7 @@ struct proto tcpv6_prot = {
2239 .sysctl_rmem = sysctl_tcp_rmem, 2244 .sysctl_rmem = sysctl_tcp_rmem,
2240 .max_header = MAX_TCP_HEADER, 2245 .max_header = MAX_TCP_HEADER,
2241 .obj_size = sizeof(struct tcp6_sock), 2246 .obj_size = sizeof(struct tcp6_sock),
2247 .rsk_prot = &or_ipv6,
2242}; 2248};
2243 2249
2244static struct inet6_protocol tcpv6_protocol = { 2250static struct inet6_protocol tcpv6_protocol = {