summaryrefslogtreecommitdiffstats
path: root/include/linux/ipv6.h
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2013-10-03 18:42:29 -0400
committerDavid S. Miller <davem@davemloft.net>2013-10-09 00:01:25 -0400
commitefe4208f47f907b86f528788da711e8ab9dea44d (patch)
tree8246b487be087877ba26d166f629d8c53d553ec1 /include/linux/ipv6.h
parent05dbc7b59481ca891bbcfe6799a562d48159fbf7 (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.h46
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 */
142struct ipv6_pinfo { 142struct 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
257extern int inet6_sk_rebuild_header(struct sock *sk); 255extern int inet6_sk_rebuild_header(struct sock *sk);
258 256
259struct inet6_timewait_sock {
260 struct in6_addr tw_v6_daddr;
261 struct in6_addr tw_v6_rcv_saddr;
262};
263
264struct tcp6_timewait_sock { 257struct 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
269static 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)
276static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk) 262static 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
324static inline u16 inet6_tw_offset(const struct proto *prot) 310static 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
330static 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
336static 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
341static inline int inet_v6_ipv6only(const struct sock *sk) 317static 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 */