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 /net/ipv4/tcp_diag.c | |
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 'net/ipv4/tcp_diag.c')
-rw-r--r-- | net/ipv4/tcp_diag.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c index 1a89a03c449b..6f2d6f2276b9 100644 --- a/net/ipv4/tcp_diag.c +++ b/net/ipv4/tcp_diag.c | |||
@@ -81,7 +81,7 @@ static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk, | |||
81 | r->id.tcpdiag_cookie[1] = (u32)(((unsigned long)sk >> 31) >> 1); | 81 | r->id.tcpdiag_cookie[1] = (u32)(((unsigned long)sk >> 31) >> 1); |
82 | 82 | ||
83 | if (r->tcpdiag_state == TCP_TIME_WAIT) { | 83 | if (r->tcpdiag_state == TCP_TIME_WAIT) { |
84 | struct tcp_tw_bucket *tw = (struct tcp_tw_bucket*)sk; | 84 | const struct inet_timewait_sock *tw = inet_twsk(sk); |
85 | long tmo = tw->tw_ttd - jiffies; | 85 | long tmo = tw->tw_ttd - jiffies; |
86 | if (tmo < 0) | 86 | if (tmo < 0) |
87 | tmo = 0; | 87 | tmo = 0; |
@@ -99,10 +99,12 @@ static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk, | |||
99 | r->tcpdiag_inode = 0; | 99 | r->tcpdiag_inode = 0; |
100 | #ifdef CONFIG_IP_TCPDIAG_IPV6 | 100 | #ifdef CONFIG_IP_TCPDIAG_IPV6 |
101 | if (r->tcpdiag_family == AF_INET6) { | 101 | if (r->tcpdiag_family == AF_INET6) { |
102 | const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk); | ||
103 | |||
102 | ipv6_addr_copy((struct in6_addr *)r->id.tcpdiag_src, | 104 | ipv6_addr_copy((struct in6_addr *)r->id.tcpdiag_src, |
103 | &tw->tw_v6_rcv_saddr); | 105 | &tcp6tw->tw_v6_rcv_saddr); |
104 | ipv6_addr_copy((struct in6_addr *)r->id.tcpdiag_dst, | 106 | ipv6_addr_copy((struct in6_addr *)r->id.tcpdiag_dst, |
105 | &tw->tw_v6_daddr); | 107 | &tcp6tw->tw_v6_daddr); |
106 | } | 108 | } |
107 | #endif | 109 | #endif |
108 | nlh->nlmsg_len = skb->tail - b; | 110 | nlh->nlmsg_len = skb->tail - b; |
@@ -239,7 +241,7 @@ static int tcpdiag_get_exact(struct sk_buff *in_skb, const struct nlmsghdr *nlh) | |||
239 | out: | 241 | out: |
240 | if (sk) { | 242 | if (sk) { |
241 | if (sk->sk_state == TCP_TIME_WAIT) | 243 | if (sk->sk_state == TCP_TIME_WAIT) |
242 | tcp_tw_put((struct tcp_tw_bucket*)sk); | 244 | inet_twsk_put((struct inet_timewait_sock *)sk); |
243 | else | 245 | else |
244 | sock_put(sk); | 246 | sock_put(sk); |
245 | } | 247 | } |