aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2014-10-17 12:17:20 -0400
committerDavid S. Miller <davem@davemloft.net>2014-10-17 23:48:07 -0400
commit870c3151382c980590d4d609babf3b0243e7db93 (patch)
tree5d472dc0982bfda41f56c08ff98c46d9b0f4afd8 /net
parent70b33fb0ddec827cbbd14cdc664fc27b2ef4a6b6 (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.c3
-rw-r--r--net/ipv6/syncookies.c2
-rw-r--r--net/ipv6/tcp_ipv6.c26
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),