diff options
author | Eric Dumazet <edumazet@google.com> | 2014-10-17 12:17:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-10-17 23:48:07 -0400 |
commit | 870c3151382c980590d4d609babf3b0243e7db93 (patch) | |
tree | 5d472dc0982bfda41f56c08ff98c46d9b0f4afd8 /net | |
parent | 70b33fb0ddec827cbbd14cdc664fc27b2ef4a6b6 (diff) |
ipv6: introduce tcp_v6_iif()
Commit 971f10eca186 ("tcp: better TCP_SKB_CB layout to reduce cache line
misses") added a regression for SO_BINDTODEVICE on IPv6.
This is because we still use inet6_iif() which expects that IP6 control
block is still at the beginning of skb->cb[]
This patch adds tcp_v6_iif() helper and uses it where necessary.
Because __inet6_lookup_skb() is used by TCP and DCCP, we add an iif
parameter to it.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Fixes: 971f10eca186 ("tcp: better TCP_SKB_CB layout to reduce cache line misses")
Acked-by: Cong Wang <cwang@twopensource.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/dccp/ipv6.c | 3 | ||||
-rw-r--r-- | net/ipv6/syncookies.c | 2 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 26 |
3 files changed, 18 insertions, 13 deletions
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index ad2acfe1ca61..6bcaa33cd804 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -757,7 +757,8 @@ static int dccp_v6_rcv(struct sk_buff *skb) | |||
757 | /* Step 2: | 757 | /* Step 2: |
758 | * Look up flow ID in table and get corresponding socket */ | 758 | * Look up flow ID in table and get corresponding socket */ |
759 | sk = __inet6_lookup_skb(&dccp_hashinfo, skb, | 759 | sk = __inet6_lookup_skb(&dccp_hashinfo, skb, |
760 | dh->dccph_sport, dh->dccph_dport); | 760 | dh->dccph_sport, dh->dccph_dport, |
761 | inet6_iif(skb)); | ||
761 | /* | 762 | /* |
762 | * Step 2: | 763 | * Step 2: |
763 | * If no socket ... | 764 | * If no socket ... |
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 9a2838e93cc5..2a86a0f00f2b 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
@@ -214,7 +214,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
214 | /* So that link locals have meaning */ | 214 | /* So that link locals have meaning */ |
215 | if (!sk->sk_bound_dev_if && | 215 | if (!sk->sk_bound_dev_if && |
216 | ipv6_addr_type(&ireq->ir_v6_rmt_addr) & IPV6_ADDR_LINKLOCAL) | 216 | ipv6_addr_type(&ireq->ir_v6_rmt_addr) & IPV6_ADDR_LINKLOCAL) |
217 | ireq->ir_iif = inet6_iif(skb); | 217 | ireq->ir_iif = tcp_v6_iif(skb); |
218 | 218 | ||
219 | ireq->ir_mark = inet_request_mark(sk, skb); | 219 | ireq->ir_mark = inet_request_mark(sk, skb); |
220 | 220 | ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index cf2e45ab2fa4..831495529b82 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -424,6 +424,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
424 | if (sock_owned_by_user(sk)) | 424 | if (sock_owned_by_user(sk)) |
425 | goto out; | 425 | goto out; |
426 | 426 | ||
427 | /* Note : We use inet6_iif() here, not tcp_v6_iif() */ | ||
427 | req = inet6_csk_search_req(sk, &prev, th->dest, &hdr->daddr, | 428 | req = inet6_csk_search_req(sk, &prev, th->dest, &hdr->daddr, |
428 | &hdr->saddr, inet6_iif(skb)); | 429 | &hdr->saddr, inet6_iif(skb)); |
429 | if (!req) | 430 | if (!req) |
@@ -738,7 +739,7 @@ static void tcp_v6_init_req(struct request_sock *req, struct sock *sk, | |||
738 | /* So that link locals have meaning */ | 739 | /* So that link locals have meaning */ |
739 | if (!sk->sk_bound_dev_if && | 740 | if (!sk->sk_bound_dev_if && |
740 | ipv6_addr_type(&ireq->ir_v6_rmt_addr) & IPV6_ADDR_LINKLOCAL) | 741 | ipv6_addr_type(&ireq->ir_v6_rmt_addr) & IPV6_ADDR_LINKLOCAL) |
741 | ireq->ir_iif = inet6_iif(skb); | 742 | ireq->ir_iif = tcp_v6_iif(skb); |
742 | 743 | ||
743 | if (!TCP_SKB_CB(skb)->tcp_tw_isn && | 744 | if (!TCP_SKB_CB(skb)->tcp_tw_isn && |
744 | (ipv6_opt_accepted(sk, skb, &TCP_SKB_CB(skb)->header.h6) || | 745 | (ipv6_opt_accepted(sk, skb, &TCP_SKB_CB(skb)->header.h6) || |
@@ -860,7 +861,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
860 | 861 | ||
861 | fl6.flowi6_proto = IPPROTO_TCP; | 862 | fl6.flowi6_proto = IPPROTO_TCP; |
862 | if (rt6_need_strict(&fl6.daddr) && !oif) | 863 | if (rt6_need_strict(&fl6.daddr) && !oif) |
863 | fl6.flowi6_oif = inet6_iif(skb); | 864 | fl6.flowi6_oif = tcp_v6_iif(skb); |
864 | else | 865 | else |
865 | fl6.flowi6_oif = oif; | 866 | fl6.flowi6_oif = oif; |
866 | fl6.flowi6_mark = IP6_REPLY_MARK(net, skb->mark); | 867 | fl6.flowi6_mark = IP6_REPLY_MARK(net, skb->mark); |
@@ -918,7 +919,7 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb) | |||
918 | sk1 = inet6_lookup_listener(dev_net(skb_dst(skb)->dev), | 919 | sk1 = inet6_lookup_listener(dev_net(skb_dst(skb)->dev), |
919 | &tcp_hashinfo, &ipv6h->saddr, | 920 | &tcp_hashinfo, &ipv6h->saddr, |
920 | th->source, &ipv6h->daddr, | 921 | th->source, &ipv6h->daddr, |
921 | ntohs(th->source), inet6_iif(skb)); | 922 | ntohs(th->source), tcp_v6_iif(skb)); |
922 | if (!sk1) | 923 | if (!sk1) |
923 | return; | 924 | return; |
924 | 925 | ||
@@ -1000,13 +1001,14 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk, struct sk_buff *skb) | |||
1000 | /* Find possible connection requests. */ | 1001 | /* Find possible connection requests. */ |
1001 | req = inet6_csk_search_req(sk, &prev, th->source, | 1002 | req = inet6_csk_search_req(sk, &prev, th->source, |
1002 | &ipv6_hdr(skb)->saddr, | 1003 | &ipv6_hdr(skb)->saddr, |
1003 | &ipv6_hdr(skb)->daddr, inet6_iif(skb)); | 1004 | &ipv6_hdr(skb)->daddr, tcp_v6_iif(skb)); |
1004 | if (req) | 1005 | if (req) |
1005 | return tcp_check_req(sk, skb, req, prev, false); | 1006 | return tcp_check_req(sk, skb, req, prev, false); |
1006 | 1007 | ||
1007 | nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo, | 1008 | nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo, |
1008 | &ipv6_hdr(skb)->saddr, th->source, | 1009 | &ipv6_hdr(skb)->saddr, th->source, |
1009 | &ipv6_hdr(skb)->daddr, ntohs(th->dest), inet6_iif(skb)); | 1010 | &ipv6_hdr(skb)->daddr, ntohs(th->dest), |
1011 | tcp_v6_iif(skb)); | ||
1010 | 1012 | ||
1011 | if (nsk) { | 1013 | if (nsk) { |
1012 | if (nsk->sk_state != TCP_TIME_WAIT) { | 1014 | if (nsk->sk_state != TCP_TIME_WAIT) { |
@@ -1090,7 +1092,7 @@ static struct sock *tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1090 | newnp->ipv6_fl_list = NULL; | 1092 | newnp->ipv6_fl_list = NULL; |
1091 | newnp->pktoptions = NULL; | 1093 | newnp->pktoptions = NULL; |
1092 | newnp->opt = NULL; | 1094 | newnp->opt = NULL; |
1093 | newnp->mcast_oif = inet6_iif(skb); | 1095 | newnp->mcast_oif = tcp_v6_iif(skb); |
1094 | newnp->mcast_hops = ipv6_hdr(skb)->hop_limit; | 1096 | newnp->mcast_hops = ipv6_hdr(skb)->hop_limit; |
1095 | newnp->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(skb)); | 1097 | newnp->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(skb)); |
1096 | if (np->repflow) | 1098 | if (np->repflow) |
@@ -1174,7 +1176,7 @@ static struct sock *tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1174 | skb_set_owner_r(newnp->pktoptions, newsk); | 1176 | skb_set_owner_r(newnp->pktoptions, newsk); |
1175 | } | 1177 | } |
1176 | newnp->opt = NULL; | 1178 | newnp->opt = NULL; |
1177 | newnp->mcast_oif = inet6_iif(skb); | 1179 | newnp->mcast_oif = tcp_v6_iif(skb); |
1178 | newnp->mcast_hops = ipv6_hdr(skb)->hop_limit; | 1180 | newnp->mcast_hops = ipv6_hdr(skb)->hop_limit; |
1179 | newnp->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(skb)); | 1181 | newnp->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(skb)); |
1180 | if (np->repflow) | 1182 | if (np->repflow) |
@@ -1360,7 +1362,7 @@ ipv6_pktoptions: | |||
1360 | if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt && | 1362 | if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt && |
1361 | !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { | 1363 | !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { |
1362 | if (np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo) | 1364 | if (np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo) |
1363 | np->mcast_oif = inet6_iif(opt_skb); | 1365 | np->mcast_oif = tcp_v6_iif(opt_skb); |
1364 | if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) | 1366 | if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) |
1365 | np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit; | 1367 | np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit; |
1366 | if (np->rxopt.bits.rxflow || np->rxopt.bits.rxtclass) | 1368 | if (np->rxopt.bits.rxflow || np->rxopt.bits.rxtclass) |
@@ -1427,7 +1429,8 @@ static int tcp_v6_rcv(struct sk_buff *skb) | |||
1427 | TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); | 1429 | TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); |
1428 | TCP_SKB_CB(skb)->sacked = 0; | 1430 | TCP_SKB_CB(skb)->sacked = 0; |
1429 | 1431 | ||
1430 | sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest); | 1432 | sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest, |
1433 | tcp_v6_iif(skb)); | ||
1431 | if (!sk) | 1434 | if (!sk) |
1432 | goto no_tcp_socket; | 1435 | goto no_tcp_socket; |
1433 | 1436 | ||
@@ -1514,7 +1517,7 @@ do_time_wait: | |||
1514 | sk2 = inet6_lookup_listener(dev_net(skb->dev), &tcp_hashinfo, | 1517 | sk2 = inet6_lookup_listener(dev_net(skb->dev), &tcp_hashinfo, |
1515 | &ipv6_hdr(skb)->saddr, th->source, | 1518 | &ipv6_hdr(skb)->saddr, th->source, |
1516 | &ipv6_hdr(skb)->daddr, | 1519 | &ipv6_hdr(skb)->daddr, |
1517 | ntohs(th->dest), inet6_iif(skb)); | 1520 | ntohs(th->dest), tcp_v6_iif(skb)); |
1518 | if (sk2 != NULL) { | 1521 | if (sk2 != NULL) { |
1519 | struct inet_timewait_sock *tw = inet_twsk(sk); | 1522 | struct inet_timewait_sock *tw = inet_twsk(sk); |
1520 | inet_twsk_deschedule(tw, &tcp_death_row); | 1523 | inet_twsk_deschedule(tw, &tcp_death_row); |
@@ -1553,6 +1556,7 @@ static void tcp_v6_early_demux(struct sk_buff *skb) | |||
1553 | if (th->doff < sizeof(struct tcphdr) / 4) | 1556 | if (th->doff < sizeof(struct tcphdr) / 4) |
1554 | return; | 1557 | return; |
1555 | 1558 | ||
1559 | /* Note : We use inet6_iif() here, not tcp_v6_iif() */ | ||
1556 | sk = __inet6_lookup_established(dev_net(skb->dev), &tcp_hashinfo, | 1560 | sk = __inet6_lookup_established(dev_net(skb->dev), &tcp_hashinfo, |
1557 | &hdr->saddr, th->source, | 1561 | &hdr->saddr, th->source, |
1558 | &hdr->daddr, ntohs(th->dest), | 1562 | &hdr->daddr, ntohs(th->dest), |