pskb_pull(skb, skb->mac_len + x->props.header_len);
 }
 
+static void __xfrm_mode_beet_prep(struct xfrm_state *x, struct sk_buff *skb,
+                                 unsigned int hsize)
+{
+       struct xfrm_offload *xo = xfrm_offload(skb);
+       int phlen = 0;
+
+       if (xo->flags & XFRM_GSO_SEGMENT)
+               skb->transport_header = skb->network_header + hsize;
+
+       skb_reset_mac_len(skb);
+       if (x->sel.family != AF_INET6) {
+               phlen = IPV4_BEET_PHMAXLEN;
+               if (x->outer_mode.family == AF_INET6)
+                       phlen += sizeof(struct ipv6hdr) - sizeof(struct iphdr);
+       }
+
+       pskb_pull(skb, skb->mac_len + hsize + (x->props.header_len - phlen));
+}
+
 /* Adjust pointers into the packet when IPsec is done at layer2 */
 static void xfrm_outer_mode_prep(struct xfrm_state *x, struct sk_buff *skb)
 {
                        return __xfrm_transport_prep(x, skb,
                                                     sizeof(struct ipv6hdr));
                break;
+       case XFRM_MODE_BEET:
+               if (x->outer_mode.family == AF_INET)
+                       return __xfrm_mode_beet_prep(x, skb,
+                                                    sizeof(struct iphdr));
+               if (x->outer_mode.family == AF_INET6)
+                       return __xfrm_mode_beet_prep(x, skb,
+                                                    sizeof(struct ipv6hdr));
+               break;
        case XFRM_MODE_ROUTEOPTIMIZATION:
        case XFRM_MODE_IN_TRIGGER:
-       case XFRM_MODE_BEET:
                break;
        }
 }