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 /net/dccp | |
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 'net/dccp')
-rw-r--r-- | net/dccp/ipv6.c | 24 | ||||
-rw-r--r-- | net/dccp/ipv6.h | 1 | ||||
-rw-r--r-- | net/dccp/minisocks.c | 7 |
3 files changed, 14 insertions, 18 deletions
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 6cf9f7782ad4..7f075b83128a 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -67,7 +67,7 @@ static inline void dccp_v6_send_check(struct sock *sk, struct sk_buff *skb) | |||
67 | struct dccp_hdr *dh = dccp_hdr(skb); | 67 | struct dccp_hdr *dh = dccp_hdr(skb); |
68 | 68 | ||
69 | dccp_csum_outgoing(skb); | 69 | dccp_csum_outgoing(skb); |
70 | dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr); | 70 | dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &sk->sk_v6_daddr); |
71 | } | 71 | } |
72 | 72 | ||
73 | static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb) | 73 | static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb) |
@@ -467,11 +467,11 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
467 | 467 | ||
468 | memcpy(newnp, np, sizeof(struct ipv6_pinfo)); | 468 | memcpy(newnp, np, sizeof(struct ipv6_pinfo)); |
469 | 469 | ||
470 | ipv6_addr_set_v4mapped(newinet->inet_daddr, &newnp->daddr); | 470 | ipv6_addr_set_v4mapped(newinet->inet_daddr, &newsk->sk_v6_daddr); |
471 | 471 | ||
472 | ipv6_addr_set_v4mapped(newinet->inet_saddr, &newnp->saddr); | 472 | ipv6_addr_set_v4mapped(newinet->inet_saddr, &newnp->saddr); |
473 | 473 | ||
474 | newnp->rcv_saddr = newnp->saddr; | 474 | newsk->sk_v6_rcv_saddr = newnp->saddr; |
475 | 475 | ||
476 | inet_csk(newsk)->icsk_af_ops = &dccp_ipv6_mapped; | 476 | inet_csk(newsk)->icsk_af_ops = &dccp_ipv6_mapped; |
477 | newsk->sk_backlog_rcv = dccp_v4_do_rcv; | 477 | newsk->sk_backlog_rcv = dccp_v4_do_rcv; |
@@ -538,9 +538,9 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
538 | 538 | ||
539 | memcpy(newnp, np, sizeof(struct ipv6_pinfo)); | 539 | memcpy(newnp, np, sizeof(struct ipv6_pinfo)); |
540 | 540 | ||
541 | newnp->daddr = ireq6->rmt_addr; | 541 | newsk->sk_v6_daddr = ireq6->rmt_addr; |
542 | newnp->saddr = ireq6->loc_addr; | 542 | newnp->saddr = ireq6->loc_addr; |
543 | newnp->rcv_saddr = ireq6->loc_addr; | 543 | newsk->sk_v6_rcv_saddr = ireq6->loc_addr; |
544 | newsk->sk_bound_dev_if = ireq6->iif; | 544 | newsk->sk_bound_dev_if = ireq6->iif; |
545 | 545 | ||
546 | /* Now IPv6 options... | 546 | /* Now IPv6 options... |
@@ -885,7 +885,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
885 | return -EINVAL; | 885 | return -EINVAL; |
886 | } | 886 | } |
887 | 887 | ||
888 | np->daddr = usin->sin6_addr; | 888 | sk->sk_v6_daddr = usin->sin6_addr; |
889 | np->flow_label = fl6.flowlabel; | 889 | np->flow_label = fl6.flowlabel; |
890 | 890 | ||
891 | /* | 891 | /* |
@@ -915,16 +915,16 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
915 | goto failure; | 915 | goto failure; |
916 | } | 916 | } |
917 | ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); | 917 | ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); |
918 | ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, &np->rcv_saddr); | 918 | ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, &sk->sk_v6_rcv_saddr); |
919 | 919 | ||
920 | return err; | 920 | return err; |
921 | } | 921 | } |
922 | 922 | ||
923 | if (!ipv6_addr_any(&np->rcv_saddr)) | 923 | if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) |
924 | saddr = &np->rcv_saddr; | 924 | saddr = &sk->sk_v6_rcv_saddr; |
925 | 925 | ||
926 | fl6.flowi6_proto = IPPROTO_DCCP; | 926 | fl6.flowi6_proto = IPPROTO_DCCP; |
927 | fl6.daddr = np->daddr; | 927 | fl6.daddr = sk->sk_v6_daddr; |
928 | fl6.saddr = saddr ? *saddr : np->saddr; | 928 | fl6.saddr = saddr ? *saddr : np->saddr; |
929 | fl6.flowi6_oif = sk->sk_bound_dev_if; | 929 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
930 | fl6.fl6_dport = usin->sin6_port; | 930 | fl6.fl6_dport = usin->sin6_port; |
@@ -941,7 +941,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
941 | 941 | ||
942 | if (saddr == NULL) { | 942 | if (saddr == NULL) { |
943 | saddr = &fl6.saddr; | 943 | saddr = &fl6.saddr; |
944 | np->rcv_saddr = *saddr; | 944 | sk->sk_v6_rcv_saddr = *saddr; |
945 | } | 945 | } |
946 | 946 | ||
947 | /* set the source address */ | 947 | /* set the source address */ |
@@ -963,7 +963,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
963 | goto late_failure; | 963 | goto late_failure; |
964 | 964 | ||
965 | dp->dccps_iss = secure_dccpv6_sequence_number(np->saddr.s6_addr32, | 965 | dp->dccps_iss = secure_dccpv6_sequence_number(np->saddr.s6_addr32, |
966 | np->daddr.s6_addr32, | 966 | sk->sk_v6_daddr.s6_addr32, |
967 | inet->inet_sport, | 967 | inet->inet_sport, |
968 | inet->inet_dport); | 968 | inet->inet_dport); |
969 | err = dccp_connect(sk); | 969 | err = dccp_connect(sk); |
diff --git a/net/dccp/ipv6.h b/net/dccp/ipv6.h index 6eef81fdbe56..6604fc3fe953 100644 --- a/net/dccp/ipv6.h +++ b/net/dccp/ipv6.h | |||
@@ -30,7 +30,6 @@ struct dccp6_request_sock { | |||
30 | 30 | ||
31 | struct dccp6_timewait_sock { | 31 | struct dccp6_timewait_sock { |
32 | struct inet_timewait_sock inet; | 32 | struct inet_timewait_sock inet; |
33 | struct inet6_timewait_sock tw6; | ||
34 | }; | 33 | }; |
35 | 34 | ||
36 | #endif /* _DCCP_IPV6_H */ | 35 | #endif /* _DCCP_IPV6_H */ |
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c index 662071b249cc..32e80d96d4c0 100644 --- a/net/dccp/minisocks.c +++ b/net/dccp/minisocks.c | |||
@@ -56,12 +56,9 @@ void dccp_time_wait(struct sock *sk, int state, int timeo) | |||
56 | #if IS_ENABLED(CONFIG_IPV6) | 56 | #if IS_ENABLED(CONFIG_IPV6) |
57 | if (tw->tw_family == PF_INET6) { | 57 | if (tw->tw_family == PF_INET6) { |
58 | const struct ipv6_pinfo *np = inet6_sk(sk); | 58 | const struct ipv6_pinfo *np = inet6_sk(sk); |
59 | struct inet6_timewait_sock *tw6; | ||
60 | 59 | ||
61 | tw->tw_ipv6_offset = inet6_tw_offset(sk->sk_prot); | 60 | tw->tw_v6_daddr = sk->sk_v6_daddr; |
62 | tw6 = inet6_twsk((struct sock *)tw); | 61 | tw->tw_v6_rcv_saddr = sk->sk_v6_rcv_saddr; |
63 | tw6->tw_v6_daddr = np->daddr; | ||
64 | tw6->tw_v6_rcv_saddr = np->rcv_saddr; | ||
65 | tw->tw_ipv6only = np->ipv6only; | 62 | tw->tw_ipv6only = np->ipv6only; |
66 | } | 63 | } |
67 | #endif | 64 | #endif |