ipsec: Interfamily IPSec BEET
authorJoakim Koskela <jookos@gmail.com>
Wed, 6 Aug 2008 09:39:30 +0000 (02:39 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 6 Aug 2008 09:39:30 +0000 (02:39 -0700)
Here's a revised version, based on Herbert's comments, of a fix for
the ipv6-inner, ipv4-outer interfamily ipsec beet mode. It fixes the
network header adjustment in interfamily, and doesn't reserve space
for the pseudo header anymore when we have ipv6 as the inner family.

Signed-off-by: Joakim Koskela <jookos@gmail.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/esp4.c
net/ipv4/xfrm4_mode_beet.c

index 4e73e5708e700d276ddb3be80a9452931621a15b..21515d4c49eb5712c22655ba7d8166909bdcf13e 100644 (file)
@@ -575,7 +575,7 @@ static int esp_init_state(struct xfrm_state *x)
                              crypto_aead_ivsize(aead);
        if (x->props.mode == XFRM_MODE_TUNNEL)
                x->props.header_len += sizeof(struct iphdr);
-       else if (x->props.mode == XFRM_MODE_BEET)
+       else if (x->props.mode == XFRM_MODE_BEET && x->sel.family != AF_INET6)
                x->props.header_len += IPV4_BEET_PHMAXLEN;
        if (x->encap) {
                struct xfrm_encap_tmpl *encap = x->encap;
index 9c798abce736c5afdb78aaccb3d26f1ce08ad307..63418185f5249aaba6a8ae55be365536a56397a1 100644 (file)
@@ -47,8 +47,10 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
        if (unlikely(optlen))
                hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4);
 
-       skb_set_network_header(skb, IPV4_BEET_PHMAXLEN - x->props.header_len -
-                                   hdrlen);
+       skb_set_network_header(skb, -x->props.header_len -
+                                   hdrlen + (XFRM_MODE_SKB_CB(skb)->ihl - sizeof(*top_iph)));
+       if (x->sel.family != AF_INET6)
+               skb->network_header += IPV4_BEET_PHMAXLEN;
        skb->mac_header = skb->network_header +
                          offsetof(struct iphdr, protocol);
        skb->transport_header = skb->network_header + sizeof(*top_iph);