aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 5ff87805258e..5d46832c6f72 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1199,6 +1199,8 @@ static struct sock *tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1199 inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + 1199 inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
1200 newnp->opt->opt_flen); 1200 newnp->opt->opt_flen);
1201 1201
1202 tcp_ca_openreq_child(newsk, dst);
1203
1202 tcp_sync_mss(newsk, dst_mtu(dst)); 1204 tcp_sync_mss(newsk, dst_mtu(dst));
1203 newtp->advmss = dst_metric_advmss(dst); 1205 newtp->advmss = dst_metric_advmss(dst);
1204 if (tcp_sk(sk)->rx_opt.user_mss && 1206 if (tcp_sk(sk)->rx_opt.user_mss &&
@@ -1387,6 +1389,28 @@ ipv6_pktoptions:
1387 return 0; 1389 return 0;
1388} 1390}
1389 1391
1392static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr,
1393 const struct tcphdr *th)
1394{
1395 /* This is tricky: we move IP6CB at its correct location into
1396 * TCP_SKB_CB(). It must be done after xfrm6_policy_check(), because
1397 * _decode_session6() uses IP6CB().
1398 * barrier() makes sure compiler won't play aliasing games.
1399 */
1400 memmove(&TCP_SKB_CB(skb)->header.h6, IP6CB(skb),
1401 sizeof(struct inet6_skb_parm));
1402 barrier();
1403
1404 TCP_SKB_CB(skb)->seq = ntohl(th->seq);
1405 TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
1406 skb->len - th->doff*4);
1407 TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
1408 TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th);
1409 TCP_SKB_CB(skb)->tcp_tw_isn = 0;
1410 TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr);
1411 TCP_SKB_CB(skb)->sacked = 0;
1412}
1413
1390static int tcp_v6_rcv(struct sk_buff *skb) 1414static int tcp_v6_rcv(struct sk_buff *skb)
1391{ 1415{
1392 const struct tcphdr *th; 1416 const struct tcphdr *th;
@@ -1418,24 +1442,9 @@ static int tcp_v6_rcv(struct sk_buff *skb)
1418 1442
1419 th = tcp_hdr(skb); 1443 th = tcp_hdr(skb);
1420 hdr = ipv6_hdr(skb); 1444 hdr = ipv6_hdr(skb);
1421 /* This is tricky : We move IPCB at its correct location into TCP_SKB_CB()
1422 * barrier() makes sure compiler wont play fool^Waliasing games.
1423 */
1424 memmove(&TCP_SKB_CB(skb)->header.h6, IP6CB(skb),
1425 sizeof(struct inet6_skb_parm));
1426 barrier();
1427
1428 TCP_SKB_CB(skb)->seq = ntohl(th->seq);
1429 TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
1430 skb->len - th->doff*4);
1431 TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
1432 TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th);
1433 TCP_SKB_CB(skb)->tcp_tw_isn = 0;
1434 TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr);
1435 TCP_SKB_CB(skb)->sacked = 0;
1436 1445
1437 sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest, 1446 sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest,
1438 tcp_v6_iif(skb)); 1447 inet6_iif(skb));
1439 if (!sk) 1448 if (!sk)
1440 goto no_tcp_socket; 1449 goto no_tcp_socket;
1441 1450
@@ -1451,6 +1460,8 @@ process:
1451 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) 1460 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
1452 goto discard_and_relse; 1461 goto discard_and_relse;
1453 1462
1463 tcp_v6_fill_cb(skb, hdr, th);
1464
1454#ifdef CONFIG_TCP_MD5SIG 1465#ifdef CONFIG_TCP_MD5SIG
1455 if (tcp_v6_inbound_md5_hash(sk, skb)) 1466 if (tcp_v6_inbound_md5_hash(sk, skb))
1456 goto discard_and_relse; 1467 goto discard_and_relse;
@@ -1482,6 +1493,8 @@ no_tcp_socket:
1482 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) 1493 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
1483 goto discard_it; 1494 goto discard_it;
1484 1495
1496 tcp_v6_fill_cb(skb, hdr, th);
1497
1485 if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { 1498 if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) {
1486csum_error: 1499csum_error:
1487 TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS); 1500 TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS);
@@ -1505,6 +1518,8 @@ do_time_wait:
1505 goto discard_it; 1518 goto discard_it;
1506 } 1519 }
1507 1520
1521 tcp_v6_fill_cb(skb, hdr, th);
1522
1508 if (skb->len < (th->doff<<2)) { 1523 if (skb->len < (th->doff<<2)) {
1509 inet_twsk_put(inet_twsk(sk)); 1524 inet_twsk_put(inet_twsk(sk));
1510 goto bad_packet; 1525 goto bad_packet;