__be16 id;
        __be16 frag_off;
 
+       /* IP header length (excluding options or extension headers). */
+       u8 ihl;
+
        /* TOS for IPv4, class for IPv6. */
        u8 tos;
 
        /* Protocol for IPv4, NH for IPv6. */
        u8 protocol;
 
+       /* Option length for IPv4, zero for IPv6. */
+       u8 optlen;
+
        /* Used by IPv6 only, zero for IPv4. */
        u8 flow_lbl[3];
 };
 
 static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 {
        struct ip_beet_phdr *ph;
-       struct iphdr *iph, *top_iph;
+       struct iphdr *top_iph;
        int hdrlen, optlen;
 
-       iph = ip_hdr(skb);
-
        hdrlen = 0;
-       optlen = iph->ihl * 4 - sizeof(*iph);
+       optlen = XFRM_MODE_SKB_CB(skb)->optlen;
        if (unlikely(optlen))
                hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4);
 
                                    hdrlen);
        skb->mac_header = skb->network_header +
                          offsetof(struct iphdr, protocol);
-       skb->transport_header = skb->network_header + sizeof(*iph);
+       skb->transport_header = skb->network_header + sizeof(*top_iph);
 
        xfrm4_beet_make_header(skb);
 
-       ph = (struct ip_beet_phdr *)__skb_pull(skb, sizeof(*iph) - hdrlen);
+       ph = (struct ip_beet_phdr *)
+               __skb_pull(skb, XFRM_MODE_SKB_CB(skb)->ihl - hdrlen);
 
        top_iph = ip_hdr(skb);
 
 
 {
        struct iphdr *iph = ip_hdr(skb);
 
+       XFRM_MODE_SKB_CB(skb)->ihl = sizeof(*iph);
        XFRM_MODE_SKB_CB(skb)->id = iph->id;
        XFRM_MODE_SKB_CB(skb)->frag_off = iph->frag_off;
        XFRM_MODE_SKB_CB(skb)->tos = iph->tos;
        XFRM_MODE_SKB_CB(skb)->ttl = iph->ttl;
+       XFRM_MODE_SKB_CB(skb)->optlen = iph->ihl * 4 - sizeof(*iph);
        memset(XFRM_MODE_SKB_CB(skb)->flow_lbl, 0,
               sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl));
 
 
        skb->mac_header = skb->network_header +
                          offsetof(struct ipv6hdr, nexthdr);
        skb->transport_header = skb->network_header + sizeof(*top_iph);
+       __skb_pull(skb, XFRM_MODE_SKB_CB(skb)->ihl);
 
        xfrm6_beet_make_header(skb);
 
 
 {
        struct ipv6hdr *iph = ipv6_hdr(skb);
 
+       XFRM_MODE_SKB_CB(skb)->ihl = sizeof(*iph);
        XFRM_MODE_SKB_CB(skb)->id = 0;
        XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF);
        XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph);
        XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit;
+       XFRM_MODE_SKB_CB(skb)->optlen = 0;
        memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl,
               sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl));