From: Patrick McHardy Date: Mon, 9 Apr 2007 18:47:58 +0000 (-0700) Subject: [XFRM]: beet: fix worst case header_len calculation X-Git-Tag: v2.6.22-rc1~1128^2~134 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ac758e3c55c529714354fc268892ca4d23ca1e99;p=linux-2.6 [XFRM]: beet: fix worst case header_len calculation 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 Signed-off-by: David S. Miller --- diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index a315d5d227..47c95e8ef0 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -294,7 +294,6 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu) break; case XFRM_MODE_BEET: /* The worst case. */ - mtu -= IPV4_BEET_PHMAXLEN; mtu += min_t(u32, IPV4_BEET_PHMAXLEN, rem); break; } @@ -409,6 +408,8 @@ static int esp_init_state(struct xfrm_state *x) 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; diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c index 0f7c3e30e4..a73e710740 100644 --- a/net/ipv4/xfrm4_mode_beet.c +++ b/net/ipv4/xfrm4_mode_beet.c @@ -40,7 +40,7 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) 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;