From 3d73c4c269ff18432a86fa07233b2af346da97d8 Mon Sep 17 00:00:00 2001 From: Joakim Koskela Date: Wed, 6 Aug 2008 02:40:25 -0700 Subject: [PATCH] --- yaml --- r: 107949 b: refs/heads/master c: abf5cdb89d09ca981db10e1a85fd8531440165f2 h: refs/heads/master i: 107947: f4d556b852499f589d05773858d39632da6ad22c v: v3 --- [refs] | 2 +- trunk/net/ipv6/esp6.c | 4 ++++ trunk/net/ipv6/xfrm6_mode_beet.c | 29 ++++++++++++++++++++++++++--- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 65657d0619f1..f187669316fc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: eb49e63093498cd17382018495b8cfb5b4a679bd +refs/heads/master: abf5cdb89d09ca981db10e1a85fd8531440165f2 diff --git a/trunk/net/ipv6/esp6.c b/trunk/net/ipv6/esp6.c index c6bb4c6d24b3..b181b08fb761 100644 --- a/trunk/net/ipv6/esp6.c +++ b/trunk/net/ipv6/esp6.c @@ -521,6 +521,10 @@ static int esp6_init_state(struct xfrm_state *x) crypto_aead_ivsize(aead); switch (x->props.mode) { case XFRM_MODE_BEET: + if (x->sel.family != AF_INET6) + x->props.header_len += IPV4_BEET_PHMAXLEN + + (sizeof(struct ipv6hdr) - sizeof(struct iphdr)); + break; case XFRM_MODE_TRANSPORT: break; case XFRM_MODE_TUNNEL: diff --git a/trunk/net/ipv6/xfrm6_mode_beet.c b/trunk/net/ipv6/xfrm6_mode_beet.c index d6ce400f585f..bbd48b101bae 100644 --- a/trunk/net/ipv6/xfrm6_mode_beet.c +++ b/trunk/net/ipv6/xfrm6_mode_beet.c @@ -40,16 +40,39 @@ static void xfrm6_beet_make_header(struct sk_buff *skb) static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) { struct ipv6hdr *top_iph; - - skb_set_network_header(skb, -x->props.header_len); + struct ip_beet_phdr *ph; + struct iphdr *iphv4; + int optlen, hdr_len; + + iphv4 = ip_hdr(skb); + hdr_len = 0; + optlen = XFRM_MODE_SKB_CB(skb)->optlen; + if (unlikely(optlen)) + hdr_len += IPV4_BEET_PHMAXLEN - (optlen & 4); + + skb_set_network_header(skb, -x->props.header_len - hdr_len); + if (x->sel.family != AF_INET6) + skb->network_header += IPV4_BEET_PHMAXLEN; 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); + ph = (struct ip_beet_phdr *)__skb_pull(skb, XFRM_MODE_SKB_CB(skb)->ihl-hdr_len); xfrm6_beet_make_header(skb); top_iph = ipv6_hdr(skb); + if (unlikely(optlen)) { + + BUG_ON(optlen < 0); + + ph->padlen = 4 - (optlen & 4); + ph->hdrlen = optlen / 8; + ph->nexthdr = top_iph->nexthdr; + if (ph->padlen) + memset(ph + 1, IPOPT_NOP, ph->padlen); + + top_iph->nexthdr = IPPROTO_BEETPH; + } ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);