diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 5d46832c6f72..1f5e62229aaa 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -1411,6 +1411,15 @@ static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr, | |||
| 1411 | TCP_SKB_CB(skb)->sacked = 0; | 1411 | TCP_SKB_CB(skb)->sacked = 0; |
| 1412 | } | 1412 | } |
| 1413 | 1413 | ||
| 1414 | static void tcp_v6_restore_cb(struct sk_buff *skb) | ||
| 1415 | { | ||
| 1416 | /* We need to move header back to the beginning if xfrm6_policy_check() | ||
| 1417 | * and tcp_v6_fill_cb() are going to be called again. | ||
| 1418 | */ | ||
| 1419 | memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6, | ||
| 1420 | sizeof(struct inet6_skb_parm)); | ||
| 1421 | } | ||
| 1422 | |||
| 1414 | static int tcp_v6_rcv(struct sk_buff *skb) | 1423 | static int tcp_v6_rcv(struct sk_buff *skb) |
| 1415 | { | 1424 | { |
| 1416 | const struct tcphdr *th; | 1425 | const struct tcphdr *th; |
| @@ -1543,6 +1552,7 @@ do_time_wait: | |||
| 1543 | inet_twsk_deschedule(tw, &tcp_death_row); | 1552 | inet_twsk_deschedule(tw, &tcp_death_row); |
| 1544 | inet_twsk_put(tw); | 1553 | inet_twsk_put(tw); |
| 1545 | sk = sk2; | 1554 | sk = sk2; |
| 1555 | tcp_v6_restore_cb(skb); | ||
| 1546 | goto process; | 1556 | goto process; |
| 1547 | } | 1557 | } |
| 1548 | /* Fall through to ACK */ | 1558 | /* Fall through to ACK */ |
| @@ -1551,6 +1561,7 @@ do_time_wait: | |||
| 1551 | tcp_v6_timewait_ack(sk, skb); | 1561 | tcp_v6_timewait_ack(sk, skb); |
| 1552 | break; | 1562 | break; |
| 1553 | case TCP_TW_RST: | 1563 | case TCP_TW_RST: |
| 1564 | tcp_v6_restore_cb(skb); | ||
| 1554 | goto no_tcp_socket; | 1565 | goto no_tcp_socket; |
| 1555 | case TCP_TW_SUCCESS: | 1566 | case TCP_TW_SUCCESS: |
| 1556 | ; | 1567 | ; |
| @@ -1585,7 +1596,7 @@ static void tcp_v6_early_demux(struct sk_buff *skb) | |||
| 1585 | skb->sk = sk; | 1596 | skb->sk = sk; |
| 1586 | skb->destructor = sock_edemux; | 1597 | skb->destructor = sock_edemux; |
| 1587 | if (sk->sk_state != TCP_TIME_WAIT) { | 1598 | if (sk->sk_state != TCP_TIME_WAIT) { |
| 1588 | struct dst_entry *dst = sk->sk_rx_dst; | 1599 | struct dst_entry *dst = READ_ONCE(sk->sk_rx_dst); |
| 1589 | 1600 | ||
| 1590 | if (dst) | 1601 | if (dst) |
| 1591 | dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie); | 1602 | dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie); |
