diff options
author | Eric Dumazet <edumazet@google.com> | 2013-10-03 18:42:29 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-10-09 00:01:25 -0400 |
commit | efe4208f47f907b86f528788da711e8ab9dea44d (patch) | |
tree | 8246b487be087877ba26d166f629d8c53d553ec1 /include/linux/ipv6.h | |
parent | 05dbc7b59481ca891bbcfe6799a562d48159fbf7 (diff) |
ipv6: make lookups simpler and faster
TCP listener refactoring, part 4 :
To speed up inet lookups, we moved IPv4 addresses from inet to struct
sock_common
Now is time to do the same for IPv6, because it permits us to have fast
lookups for all kind of sockets, including upcoming SYN_RECV.
Getting IPv6 addresses in TCP lookups currently requires two extra cache
lines, plus a dereference (and memory stall).
inet6_sk(sk) does the dereference of inet_sk(__sk)->pinet6
This patch is way bigger than its IPv4 counter part, because for IPv4,
we could add aliases (inet_daddr, inet_rcv_saddr), while on IPv6,
it's not doable easily.
inet6_sk(sk)->daddr becomes sk->sk_v6_daddr
inet6_sk(sk)->rcv_saddr becomes sk->sk_v6_rcv_saddr
And timewait socket also have tw->tw_v6_daddr & tw->tw_v6_rcv_saddr
at the same offset.
We get rid of INET6_TW_MATCH() as INET6_MATCH() is now the generic
macro.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/ipv6.h')
-rw-r--r-- | include/linux/ipv6.h | 46 |
1 files changed, 6 insertions, 40 deletions
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index b7f1f3bb346d..35f6c1b562c4 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h | |||
@@ -141,8 +141,6 @@ struct ipv6_fl_socklist; | |||
141 | */ | 141 | */ |
142 | struct ipv6_pinfo { | 142 | struct ipv6_pinfo { |
143 | struct in6_addr saddr; | 143 | struct in6_addr saddr; |
144 | struct in6_addr rcv_saddr; | ||
145 | struct in6_addr daddr; | ||
146 | struct in6_pktinfo sticky_pktinfo; | 144 | struct in6_pktinfo sticky_pktinfo; |
147 | const struct in6_addr *daddr_cache; | 145 | const struct in6_addr *daddr_cache; |
148 | #ifdef CONFIG_IPV6_SUBTREES | 146 | #ifdef CONFIG_IPV6_SUBTREES |
@@ -256,22 +254,10 @@ struct tcp6_sock { | |||
256 | 254 | ||
257 | extern int inet6_sk_rebuild_header(struct sock *sk); | 255 | extern int inet6_sk_rebuild_header(struct sock *sk); |
258 | 256 | ||
259 | struct inet6_timewait_sock { | ||
260 | struct in6_addr tw_v6_daddr; | ||
261 | struct in6_addr tw_v6_rcv_saddr; | ||
262 | }; | ||
263 | |||
264 | struct tcp6_timewait_sock { | 257 | struct tcp6_timewait_sock { |
265 | struct tcp_timewait_sock tcp6tw_tcp; | 258 | struct tcp_timewait_sock tcp6tw_tcp; |
266 | struct inet6_timewait_sock tcp6tw_inet6; | ||
267 | }; | 259 | }; |
268 | 260 | ||
269 | static inline struct inet6_timewait_sock *inet6_twsk(const struct sock *sk) | ||
270 | { | ||
271 | return (struct inet6_timewait_sock *)(((u8 *)sk) + | ||
272 | inet_twsk(sk)->tw_ipv6_offset); | ||
273 | } | ||
274 | |||
275 | #if IS_ENABLED(CONFIG_IPV6) | 261 | #if IS_ENABLED(CONFIG_IPV6) |
276 | static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk) | 262 | static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk) |
277 | { | 263 | { |
@@ -321,21 +307,11 @@ static inline void inet_sk_copy_descendant(struct sock *sk_to, | |||
321 | #define __ipv6_only_sock(sk) (inet6_sk(sk)->ipv6only) | 307 | #define __ipv6_only_sock(sk) (inet6_sk(sk)->ipv6only) |
322 | #define ipv6_only_sock(sk) ((sk)->sk_family == PF_INET6 && __ipv6_only_sock(sk)) | 308 | #define ipv6_only_sock(sk) ((sk)->sk_family == PF_INET6 && __ipv6_only_sock(sk)) |
323 | 309 | ||
324 | static inline u16 inet6_tw_offset(const struct proto *prot) | 310 | static inline const struct in6_addr *inet6_rcv_saddr(const struct sock *sk) |
325 | { | ||
326 | return prot->twsk_prot->twsk_obj_size - | ||
327 | sizeof(struct inet6_timewait_sock); | ||
328 | } | ||
329 | |||
330 | static inline struct in6_addr *__inet6_rcv_saddr(const struct sock *sk) | ||
331 | { | 311 | { |
332 | return likely(sk->sk_state != TCP_TIME_WAIT) ? | 312 | if (sk->sk_family == AF_INET6) |
333 | &inet6_sk(sk)->rcv_saddr : &inet6_twsk(sk)->tw_v6_rcv_saddr; | 313 | return &sk->sk_v6_rcv_saddr; |
334 | } | 314 | return NULL; |
335 | |||
336 | static inline struct in6_addr *inet6_rcv_saddr(const struct sock *sk) | ||
337 | { | ||
338 | return sk->sk_family == AF_INET6 ? __inet6_rcv_saddr(sk) : NULL; | ||
339 | } | 315 | } |
340 | 316 | ||
341 | static inline int inet_v6_ipv6only(const struct sock *sk) | 317 | static inline int inet_v6_ipv6only(const struct sock *sk) |
@@ -363,7 +339,6 @@ static inline struct raw6_sock *raw6_sk(const struct sock *sk) | |||
363 | return NULL; | 339 | return NULL; |
364 | } | 340 | } |
365 | 341 | ||
366 | #define __inet6_rcv_saddr(__sk) NULL | ||
367 | #define inet6_rcv_saddr(__sk) NULL | 342 | #define inet6_rcv_saddr(__sk) NULL |
368 | #define tcp_twsk_ipv6only(__sk) 0 | 343 | #define tcp_twsk_ipv6only(__sk) 0 |
369 | #define inet_v6_ipv6only(__sk) 0 | 344 | #define inet_v6_ipv6only(__sk) 0 |
@@ -372,19 +347,10 @@ static inline struct raw6_sock *raw6_sk(const struct sock *sk) | |||
372 | #define INET6_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif) \ | 347 | #define INET6_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif) \ |
373 | (((__sk)->sk_portpair == (__ports)) && \ | 348 | (((__sk)->sk_portpair == (__ports)) && \ |
374 | ((__sk)->sk_family == AF_INET6) && \ | 349 | ((__sk)->sk_family == AF_INET6) && \ |
375 | ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr)) && \ | 350 | ipv6_addr_equal(&(__sk)->sk_v6_daddr, (__saddr)) && \ |
376 | ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr)) && \ | 351 | ipv6_addr_equal(&(__sk)->sk_v6_rcv_saddr, (__daddr)) && \ |
377 | (!(__sk)->sk_bound_dev_if || \ | 352 | (!(__sk)->sk_bound_dev_if || \ |
378 | ((__sk)->sk_bound_dev_if == (__dif))) && \ | 353 | ((__sk)->sk_bound_dev_if == (__dif))) && \ |
379 | net_eq(sock_net(__sk), (__net))) | 354 | net_eq(sock_net(__sk), (__net))) |
380 | 355 | ||
381 | #define INET6_TW_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif) \ | ||
382 | (((__sk)->sk_portpair == (__ports)) && \ | ||
383 | ((__sk)->sk_family == AF_INET6) && \ | ||
384 | ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_daddr, (__saddr)) && \ | ||
385 | ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_rcv_saddr, (__daddr)) && \ | ||
386 | (!(__sk)->sk_bound_dev_if || \ | ||
387 | ((__sk)->sk_bound_dev_if == (__dif))) && \ | ||
388 | net_eq(sock_net(__sk), (__net))) | ||
389 | |||
390 | #endif /* _IPV6_H */ | 356 | #endif /* _IPV6_H */ |