|
@@ -1411,6 +1411,15 @@ static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr,
|
|
|
TCP_SKB_CB(skb)->sacked = 0;
|
|
|
}
|
|
|
|
|
|
+static void tcp_v6_restore_cb(struct sk_buff *skb)
|
|
|
+{
|
|
|
+ /* We need to move header back to the beginning if xfrm6_policy_check()
|
|
|
+ * and tcp_v6_fill_cb() are going to be called again.
|
|
|
+ */
|
|
|
+ memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6,
|
|
|
+ sizeof(struct inet6_skb_parm));
|
|
|
+}
|
|
|
+
|
|
|
static int tcp_v6_rcv(struct sk_buff *skb)
|
|
|
{
|
|
|
const struct tcphdr *th;
|
|
@@ -1543,6 +1552,7 @@ do_time_wait:
|
|
|
inet_twsk_deschedule(tw, &tcp_death_row);
|
|
|
inet_twsk_put(tw);
|
|
|
sk = sk2;
|
|
|
+ tcp_v6_restore_cb(skb);
|
|
|
goto process;
|
|
|
}
|
|
|
/* Fall through to ACK */
|
|
@@ -1551,6 +1561,7 @@ do_time_wait:
|
|
|
tcp_v6_timewait_ack(sk, skb);
|
|
|
break;
|
|
|
case TCP_TW_RST:
|
|
|
+ tcp_v6_restore_cb(skb);
|
|
|
goto no_tcp_socket;
|
|
|
case TCP_TW_SUCCESS:
|
|
|
;
|