diff options
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 45 |
1 files changed, 29 insertions, 16 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 5ff87805258e..9c0b54e87b47 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -1387,6 +1387,28 @@ ipv6_pktoptions: | |||
| 1387 | return 0; | 1387 | return 0; |
| 1388 | } | 1388 | } |
| 1389 | 1389 | ||
| 1390 | static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr, | ||
| 1391 | const struct tcphdr *th) | ||
| 1392 | { | ||
| 1393 | /* This is tricky: we move IP6CB at its correct location into | ||
| 1394 | * TCP_SKB_CB(). It must be done after xfrm6_policy_check(), because | ||
| 1395 | * _decode_session6() uses IP6CB(). | ||
| 1396 | * barrier() makes sure compiler won't play aliasing games. | ||
| 1397 | */ | ||
| 1398 | memmove(&TCP_SKB_CB(skb)->header.h6, IP6CB(skb), | ||
| 1399 | sizeof(struct inet6_skb_parm)); | ||
| 1400 | barrier(); | ||
| 1401 | |||
| 1402 | TCP_SKB_CB(skb)->seq = ntohl(th->seq); | ||
| 1403 | TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + | ||
| 1404 | skb->len - th->doff*4); | ||
| 1405 | TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); | ||
| 1406 | TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); | ||
| 1407 | TCP_SKB_CB(skb)->tcp_tw_isn = 0; | ||
| 1408 | TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); | ||
| 1409 | TCP_SKB_CB(skb)->sacked = 0; | ||
| 1410 | } | ||
| 1411 | |||
| 1390 | static int tcp_v6_rcv(struct sk_buff *skb) | 1412 | static int tcp_v6_rcv(struct sk_buff *skb) |
| 1391 | { | 1413 | { |
| 1392 | const struct tcphdr *th; | 1414 | const struct tcphdr *th; |
| @@ -1418,24 +1440,9 @@ static int tcp_v6_rcv(struct sk_buff *skb) | |||
| 1418 | 1440 | ||
| 1419 | th = tcp_hdr(skb); | 1441 | th = tcp_hdr(skb); |
| 1420 | hdr = ipv6_hdr(skb); | 1442 | 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 | 1443 | ||
| 1437 | sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest, | 1444 | sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest, |
| 1438 | tcp_v6_iif(skb)); | 1445 | inet6_iif(skb)); |
| 1439 | if (!sk) | 1446 | if (!sk) |
| 1440 | goto no_tcp_socket; | 1447 | goto no_tcp_socket; |
| 1441 | 1448 | ||
| @@ -1451,6 +1458,8 @@ process: | |||
| 1451 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) | 1458 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) |
| 1452 | goto discard_and_relse; | 1459 | goto discard_and_relse; |
| 1453 | 1460 | ||
| 1461 | tcp_v6_fill_cb(skb, hdr, th); | ||
| 1462 | |||
| 1454 | #ifdef CONFIG_TCP_MD5SIG | 1463 | #ifdef CONFIG_TCP_MD5SIG |
| 1455 | if (tcp_v6_inbound_md5_hash(sk, skb)) | 1464 | if (tcp_v6_inbound_md5_hash(sk, skb)) |
| 1456 | goto discard_and_relse; | 1465 | goto discard_and_relse; |
| @@ -1482,6 +1491,8 @@ no_tcp_socket: | |||
| 1482 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) | 1491 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) |
| 1483 | goto discard_it; | 1492 | goto discard_it; |
| 1484 | 1493 | ||
| 1494 | tcp_v6_fill_cb(skb, hdr, th); | ||
| 1495 | |||
| 1485 | if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { | 1496 | if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { |
| 1486 | csum_error: | 1497 | csum_error: |
| 1487 | TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS); | 1498 | TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS); |
| @@ -1505,6 +1516,8 @@ do_time_wait: | |||
| 1505 | goto discard_it; | 1516 | goto discard_it; |
| 1506 | } | 1517 | } |
| 1507 | 1518 | ||
| 1519 | tcp_v6_fill_cb(skb, hdr, th); | ||
| 1520 | |||
| 1508 | if (skb->len < (th->doff<<2)) { | 1521 | if (skb->len < (th->doff<<2)) { |
| 1509 | inet_twsk_put(inet_twsk(sk)); | 1522 | inet_twsk_put(inet_twsk(sk)); |
| 1510 | goto bad_packet; | 1523 | goto bad_packet; |
