diff options
author | Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 2005-06-19 01:46:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-06-19 01:46:52 -0400 |
commit | 2e6599cb899ba4b133f42cbf9d2b1883d2dc583a (patch) | |
tree | b5d4fcca4d2a515fc3d3d20cefaaeebd8dbf661f | |
parent | 1944972d3bb651474a5021c9da8d0166ae19f1eb (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.h | 21 | ||||
-rw-r--r-- | include/linux/ipv6.h | 13 | ||||
-rw-r--r-- | include/linux/tcp.h | 11 | ||||
-rw-r--r-- | include/net/request_sock.h | 77 | ||||
-rw-r--r-- | include/net/sock.h | 4 | ||||
-rw-r--r-- | include/net/tcp.h | 87 | ||||
-rw-r--r-- | include/net/tcp_ecn.h | 7 | ||||
-rw-r--r-- | net/core/sock.c | 35 | ||||
-rw-r--r-- | net/ipv4/syncookies.c | 39 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 9 | ||||
-rw-r--r-- | net/ipv4/tcp_diag.c | 25 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 72 | ||||
-rw-r--r-- | net/ipv4/tcp_minisocks.c | 48 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 25 | ||||
-rw-r--r-- | net/ipv4/tcp_timer.c | 2 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 96 |
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 | ||
111 | struct 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 | |||
126 | static inline struct inet_request_sock *inet_rsk(const struct open_request *sk) | ||
127 | { | ||
128 | return (struct inet_request_sock *)sk; | ||
129 | } | ||
130 | |||
110 | struct ipv6_pinfo; | 131 | struct ipv6_pinfo; |
111 | 132 | ||
112 | struct inet_sock { | 133 | struct 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 | ||
196 | struct 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 | |||
204 | static 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 | ||
233 | struct tcp_request_sock { | ||
234 | struct inet_request_sock req; | ||
235 | __u32 rcv_isn; | ||
236 | __u32 snt_isn; | ||
237 | }; | ||
238 | |||
239 | static inline struct tcp_request_sock *tcp_rsk(const struct open_request *req) | ||
240 | { | ||
241 | return (struct tcp_request_sock *)req; | ||
242 | } | ||
243 | |||
233 | struct tcp_sock { | 244 | struct 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 | |||
22 | struct open_request; | ||
23 | struct sk_buff; | ||
24 | struct dst_entry; | ||
25 | struct proto; | ||
26 | |||
27 | struct 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 | */ | ||
42 | struct 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 | |||
56 | static 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 | |||
66 | static inline void tcp_openreq_fastfree(struct open_request *req) | ||
67 | { | ||
68 | kmem_cache_free(req->class->slab, req); | ||
69 | } | ||
70 | |||
71 | static 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 | ||
485 | extern int sk_wait_data(struct sock *sk, long *timeo); | 485 | extern int sk_wait_data(struct sock *sk, long *timeo); |
486 | 486 | ||
487 | struct 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; | |||
613 | extern atomic_t tcp_sockets_allocated; | 614 | extern atomic_t tcp_sockets_allocated; |
614 | extern int tcp_memory_pressure; | 615 | extern int tcp_memory_pressure; |
615 | 616 | ||
616 | struct open_request; | ||
617 | |||
618 | struct 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 | |||
626 | struct 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) | ||
633 | struct 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 */ | ||
642 | struct 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. */ | ||
673 | extern 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 | |||
678 | static 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 | ||
1848 | extern void tcp_enter_memory_pressure(void); | 1783 | extern 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, | |||
40 | static __inline__ void | 41 | static __inline__ void |
41 | TCP_ECN_make_synack(struct open_request *req, struct tcphdr *th) | 42 | TCP_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) | |||
113 | static inline void TCP_ECN_openreq_child(struct tcp_sock *tp, | 114 | static 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 | ||
119 | static __inline__ void | 120 | static __inline__ void |
120 | TCP_ECN_create_request(struct open_request *req, struct tcphdr *th) | 121 | TCP_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 | ||
1364 | int proto_register(struct proto *prot, int alloc_slab) | 1365 | int 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; |
1383 | out: | 1404 | out: |
1384 | return rc; | 1405 | return rc; |
1406 | out_free_request_sock_slab_name: | ||
1407 | kfree(request_sock_slab_name); | ||
1408 | out_free_sock_slab: | ||
1409 | kmem_cache_destroy(prot->slab); | ||
1410 | prot->slab = NULL; | ||
1411 | goto out; | ||
1385 | } | 1412 | } |
1386 | 1413 | ||
1387 | EXPORT_SYMBOL(proto_register); | 1414 | EXPORT_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, | |||
190 | struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | 190 | struct 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); |
278 | out: return ret; | 279 | out: 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 | ||
272 | DEFINE_SNMP_STAT(struct tcp_mib, tcp_statistics); | 272 | DEFINE_SNMP_STAT(struct tcp_mib, tcp_statistics); |
273 | 273 | ||
274 | kmem_cache_t *tcp_openreq_cachep; | ||
275 | kmem_cache_t *tcp_bucket_cachep; | 274 | kmem_cache_t *tcp_bucket_cachep; |
276 | kmem_cache_t *tcp_timewait_cachep; | 275 | kmem_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); | |||
2374 | EXPORT_SYMBOL(tcp_disconnect); | 2366 | EXPORT_SYMBOL(tcp_disconnect); |
2375 | EXPORT_SYMBOL(tcp_getsockopt); | 2367 | EXPORT_SYMBOL(tcp_getsockopt); |
2376 | EXPORT_SYMBOL(tcp_ioctl); | 2368 | EXPORT_SYMBOL(tcp_ioctl); |
2377 | EXPORT_SYMBOL(tcp_openreq_cachep); | ||
2378 | EXPORT_SYMBOL(tcp_poll); | 2369 | EXPORT_SYMBOL(tcp_poll); |
2379 | EXPORT_SYMBOL(tcp_read_sock); | 2370 | EXPORT_SYMBOL(tcp_read_sock); |
2380 | EXPORT_SYMBOL(tcp_recvmsg); | 2371 | EXPORT_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 | ||
1257 | static void tcp_v4_or_send_ack(struct sk_buff *skb, struct open_request *req) | 1259 | static 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, | |||
1297 | static int tcp_v4_send_synack(struct sock *sk, struct open_request *req, | 1300 | static 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 | */ |
1333 | static void tcp_v4_or_free(struct open_request *req) | 1337 | static 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 | ||
1339 | static inline void syn_flood_warning(struct sk_buff *skb) | 1343 | static inline void syn_flood_warning(struct sk_buff *skb) |
@@ -1387,6 +1391,7 @@ int sysctl_max_syn_backlog = 256; | |||
1387 | 1391 | ||
1388 | struct or_calltable or_ipv4 = { | 1392 | struct 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 | ||
1396 | int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | 1401 | int 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) | |||
2454 | static void get_openreq4(struct sock *sk, struct open_request *req, | 2462 | static 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) | |||
1358 | struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, | 1358 | struct 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: | |||
960 | static int tcp_v6_send_synack(struct sock *sk, struct open_request *req, | 962 | static 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 | ||
1027 | static void tcp_v6_or_free(struct open_request *req) | 1030 | static 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 | ||
1033 | static struct or_calltable or_ipv6 = { | 1036 | static 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 | ||
1222 | static void tcp_v6_or_send_ack(struct sk_buff *skb, struct open_request *req) | 1226 | static 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 | */ |
1285 | static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | 1289 | static 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 | ||
2244 | static struct inet6_protocol tcpv6_protocol = { | 2250 | static struct inet6_protocol tcpv6_protocol = { |