diff options
author | Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 2005-08-09 23:09:30 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-08-29 18:42:13 -0400 |
commit | 8feaf0c0a5488b3d898a9c207eb6678f44ba3f26 (patch) | |
tree | ddd004afe2f7c8295f6fdb94d34f78a42b5961cb /include/linux | |
parent | 33b62231908c58ae04185e4f1063d1e35a7c8576 (diff) |
[INET]: Generalise tcp_tw_bucket, aka TIME_WAIT sockets
This paves the way to generalise the rest of the sock ID lookup
routines and saves some bytes in TCPv4 TIME_WAIT sockets on distro
kernels (where IPv6 is always built as a module):
[root@qemu ~]# grep tw_sock /proc/slabinfo
tw_sock_TCPv6 0 0 128 31 1
tw_sock_TCP 0 0 96 41 1
[root@qemu ~]#
Now if a protocol wants to use the TIME_WAIT generic infrastructure it
only has to set the sk_prot->twsk_obj_size field with the size of its
inet_timewait_sock derived sock and proto_register will create
sk_prot->twsk_slab, for now its only for INET sockets, but we can
introduce timewait_sock later if some non INET transport protocolo
wants to use this stuff.
Next changesets will take advantage of this new infrastructure to
generalise even more TCP code.
[acme@toy net-2.6.14]$ grep built-in /tmp/before.size /tmp/after.size
/tmp/before.size: 188646 11764 5068 205478 322a6 net/ipv4/built-in.o
/tmp/after.size: 188144 11764 5068 204976 320b0 net/ipv4/built-in.o
[acme@toy net-2.6.14]$
Tested with both IPv4 & IPv6 (::1 (localhost) & ::ffff:172.20.0.1
(qemu host)).
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/ipv6.h | 52 | ||||
-rw-r--r-- | include/linux/tcp.h | 15 |
2 files changed, 64 insertions, 3 deletions
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 6fcd6a0ade24..98fa32316e40 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h | |||
@@ -308,6 +308,41 @@ static inline void inet_sk_copy_descendant(struct sock *sk_to, | |||
308 | 308 | ||
309 | #define __ipv6_only_sock(sk) (inet6_sk(sk)->ipv6only) | 309 | #define __ipv6_only_sock(sk) (inet6_sk(sk)->ipv6only) |
310 | #define ipv6_only_sock(sk) ((sk)->sk_family == PF_INET6 && __ipv6_only_sock(sk)) | 310 | #define ipv6_only_sock(sk) ((sk)->sk_family == PF_INET6 && __ipv6_only_sock(sk)) |
311 | |||
312 | #include <linux/tcp.h> | ||
313 | |||
314 | struct tcp6_timewait_sock { | ||
315 | struct tcp_timewait_sock tw_v6_sk; | ||
316 | struct in6_addr tw_v6_daddr; | ||
317 | struct in6_addr tw_v6_rcv_saddr; | ||
318 | }; | ||
319 | |||
320 | static inline struct tcp6_timewait_sock *tcp6_twsk(const struct sock *sk) | ||
321 | { | ||
322 | return (struct tcp6_timewait_sock *)sk; | ||
323 | } | ||
324 | |||
325 | static inline struct in6_addr *__tcp_v6_rcv_saddr(const struct sock *sk) | ||
326 | { | ||
327 | return likely(sk->sk_state != TCP_TIME_WAIT) ? | ||
328 | &inet6_sk(sk)->rcv_saddr : &tcp6_twsk(sk)->tw_v6_rcv_saddr; | ||
329 | } | ||
330 | |||
331 | static inline struct in6_addr *tcp_v6_rcv_saddr(const struct sock *sk) | ||
332 | { | ||
333 | return sk->sk_family == AF_INET6 ? __tcp_v6_rcv_saddr(sk) : NULL; | ||
334 | } | ||
335 | |||
336 | static inline int tcp_twsk_ipv6only(const struct sock *sk) | ||
337 | { | ||
338 | return inet_twsk(sk)->tw_ipv6only; | ||
339 | } | ||
340 | |||
341 | static inline int tcp_v6_ipv6only(const struct sock *sk) | ||
342 | { | ||
343 | return likely(sk->sk_state != TCP_TIME_WAIT) ? | ||
344 | ipv6_only_sock(sk) : tcp_twsk_ipv6only(sk); | ||
345 | } | ||
311 | #else | 346 | #else |
312 | #define __ipv6_only_sock(sk) 0 | 347 | #define __ipv6_only_sock(sk) 0 |
313 | #define ipv6_only_sock(sk) 0 | 348 | #define ipv6_only_sock(sk) 0 |
@@ -322,8 +357,19 @@ static inline struct raw6_sock *raw6_sk(const struct sock *sk) | |||
322 | return NULL; | 357 | return NULL; |
323 | } | 358 | } |
324 | 359 | ||
325 | #endif | 360 | #define __tcp_v6_rcv_saddr(__sk) NULL |
361 | #define tcp_v6_rcv_saddr(__sk) NULL | ||
362 | #define tcp_twsk_ipv6only(__sk) 0 | ||
363 | #define tcp_v6_ipv6only(__sk) 0 | ||
364 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ | ||
326 | 365 | ||
327 | #endif | 366 | #define INET6_MATCH(__sk, __saddr, __daddr, __ports, __dif) \ |
367 | (((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports)) && \ | ||
368 | ((__sk)->sk_family == AF_INET6) && \ | ||
369 | ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr)) && \ | ||
370 | ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr)) && \ | ||
371 | (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) | ||
328 | 372 | ||
329 | #endif | 373 | #endif /* __KERNEL__ */ |
374 | |||
375 | #endif /* _IPV6_H */ | ||
diff --git a/include/linux/tcp.h b/include/linux/tcp.h index b88fe05fdcbf..5d295b1b3de7 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h | |||
@@ -179,6 +179,7 @@ struct tcp_info | |||
179 | #include <linux/skbuff.h> | 179 | #include <linux/skbuff.h> |
180 | #include <linux/ip.h> | 180 | #include <linux/ip.h> |
181 | #include <net/sock.h> | 181 | #include <net/sock.h> |
182 | #include <net/inet_timewait_sock.h> | ||
182 | 183 | ||
183 | /* This defines a selective acknowledgement block. */ | 184 | /* This defines a selective acknowledgement block. */ |
184 | struct tcp_sack_block { | 185 | struct tcp_sack_block { |
@@ -387,6 +388,20 @@ static inline struct tcp_sock *tcp_sk(const struct sock *sk) | |||
387 | return (struct tcp_sock *)sk; | 388 | return (struct tcp_sock *)sk; |
388 | } | 389 | } |
389 | 390 | ||
391 | struct tcp_timewait_sock { | ||
392 | struct inet_timewait_sock tw_sk; | ||
393 | __u32 tw_rcv_nxt; | ||
394 | __u32 tw_snd_nxt; | ||
395 | __u32 tw_rcv_wnd; | ||
396 | __u32 tw_ts_recent; | ||
397 | long tw_ts_recent_stamp; | ||
398 | }; | ||
399 | |||
400 | static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) | ||
401 | { | ||
402 | return (struct tcp_timewait_sock *)sk; | ||
403 | } | ||
404 | |||
390 | static inline void *tcp_ca(const struct tcp_sock *tp) | 405 | static inline void *tcp_ca(const struct tcp_sock *tp) |
391 | { | 406 | { |
392 | return (void *) tp->ca_priv; | 407 | return (void *) tp->ca_priv; |