esp_init_state doesn't account for the beet pseudo header in the header_len
calculation, which may result in undersized skbs hitting xfrm4_beet_output,
causing unnecessary reallocations in ip_finish_output2.
The skbs should still always have enough room to avoid causing
skb_under_panic in skb_push since we have at least 16 bytes available
from LL_RESERVED_SPACE in xfrm_state_check_space.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
break;
case XFRM_MODE_BEET:
/* The worst case. */
- mtu -= IPV4_BEET_PHMAXLEN;
mtu += min_t(u32, IPV4_BEET_PHMAXLEN, rem);
break;
}
x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
if (x->props.mode == XFRM_MODE_TUNNEL)
x->props.header_len += sizeof(struct iphdr);
+ else if (x->props.mode == XFRM_MODE_BEET)
+ x->props.header_len += IPV4_BEET_PHMAXLEN;
if (x->encap) {
struct xfrm_encap_tmpl *encap = x->encap;
if (unlikely(optlen))
hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4);
- skb_push(skb, x->props.header_len + hdrlen);
+ skb_push(skb, x->props.header_len - IPV4_BEET_PHMAXLEN + hdrlen);
skb_reset_network_header(skb);
top_iph = ip_hdr(skb);
skb->transport_header += sizeof(*iph) - hdrlen;