* If this grows please adjust skbuff.h:skbuff->cb[xxx] size appropriately.
  */
 struct tcp_skb_cb {
-       union {
-               struct inet_skb_parm    h4;
-#if IS_ENABLED(CONFIG_IPV6)
-               struct inet6_skb_parm   h6;
-#endif
-       } header;       /* For incoming frames          */
        __u32           seq;            /* Starting sequence number     */
        __u32           end_seq;        /* SEQ + FIN + SYN + datalen    */
        __u32           tcp_tw_isn;     /* isn chosen by tcp_timewait_state_process() */
        __u8            ip_dsfield;     /* IPv4 tos or IPv6 dsfield     */
        /* 1 byte hole */
        __u32           ack_seq;        /* Sequence number ACK'd        */
+       union {
+               struct inet_skb_parm    h4;
+#if IS_ENABLED(CONFIG_IPV6)
+               struct inet6_skb_parm   h6;
+#endif
+       } header;       /* For incoming frames          */
 };
 
 #define TCP_SKB_CB(__skb)      ((struct tcp_skb_cb *)&((__skb)->cb[0]))
 
  */
 static struct ip_options_rcu *tcp_v4_save_options(struct sk_buff *skb)
 {
-       const struct ip_options *opt = &(IPCB(skb)->opt);
+       const struct ip_options *opt = &TCP_SKB_CB(skb)->header.h4.opt;
        struct ip_options_rcu *dopt = NULL;
 
        if (opt && opt->optlen) {
                int opt_size = sizeof(*dopt) + opt->optlen;
 
                dopt = kmalloc(opt_size, GFP_ATOMIC);
-               if (dopt) {
-                       if (ip_options_echo(&dopt->opt, skb)) {
-                               kfree(dopt);
-                               dopt = NULL;
-                       }
+               if (dopt && __ip_options_echo(&dopt->opt, skb, opt)) {
+                       kfree(dopt);
+                       dopt = NULL;
                }
        }
        return dopt;
 
 #ifdef CONFIG_SYN_COOKIES
        if (!th->syn)
-               sk = cookie_v4_check(sk, skb, &(IPCB(skb)->opt));
+               sk = cookie_v4_check(sk, skb, &TCP_SKB_CB(skb)->header.h4.opt);
 #endif
        return sk;
 }
 
        th = tcp_hdr(skb);
        iph = ip_hdr(skb);
+       /* This is tricky : We move IPCB at its correct location into TCP_SKB_CB()
+        * barrier() makes sure compiler wont play fool^Waliasing games.
+        */
+       memmove(&TCP_SKB_CB(skb)->header.h4, IPCB(skb),
+               sizeof(struct inet_skb_parm));
+       barrier();
+
        TCP_SKB_CB(skb)->seq = ntohl(th->seq);
        TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
                                    skb->len - th->doff * 4);
 
 
        /* Our usage of tstamp should remain private */
        skb->tstamp.tv64 = 0;
+
+       /* Cleanup our debris for IP stacks */
+       memset(skb->cb, 0, max(sizeof(struct inet_skb_parm),
+                              sizeof(struct inet6_skb_parm)));
+
        err = icsk->icsk_af_ops->queue_xmit(sk, skb, &inet->cork.fl);
 
        if (likely(err <= 0))
 
 
        th = tcp_hdr(skb);
        hdr = ipv6_hdr(skb);
+       /* This is tricky : We move IPCB at its correct location into TCP_SKB_CB()
+        * barrier() makes sure compiler wont play fool^Waliasing games.
+        */
+       memmove(&TCP_SKB_CB(skb)->header.h6, IP6CB(skb),
+               sizeof(struct inet6_skb_parm));
+       barrier();
+
        TCP_SKB_CB(skb)->seq = ntohl(th->seq);
        TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
                                    skb->len - th->doff*4);