浏览代码

ipsec: Interfamily IPSec BEET

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>
Joakim Koskela 16 年之前
父节点
当前提交
eb49e63093
共有 2 个文件被更改,包括 5 次插入3 次删除
  1. 1 1
      net/ipv4/esp4.c
  2. 4 2
      net/ipv4/xfrm4_mode_beet.c

+ 1 - 1
net/ipv4/esp4.c

@@ -575,7 +575,7 @@ static int esp_init_state(struct xfrm_state *x)
 			      crypto_aead_ivsize(aead);
 			      crypto_aead_ivsize(aead);
 	if (x->props.mode == XFRM_MODE_TUNNEL)
 	if (x->props.mode == XFRM_MODE_TUNNEL)
 		x->props.header_len += sizeof(struct iphdr);
 		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;
 		x->props.header_len += IPV4_BEET_PHMAXLEN;
 	if (x->encap) {
 	if (x->encap) {
 		struct xfrm_encap_tmpl *encap = x->encap;
 		struct xfrm_encap_tmpl *encap = x->encap;

+ 4 - 2
net/ipv4/xfrm4_mode_beet.c

@@ -47,8 +47,10 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 	if (unlikely(optlen))
 	if (unlikely(optlen))
 		hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4);
 		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 +
 	skb->mac_header = skb->network_header +
 			  offsetof(struct iphdr, protocol);
 			  offsetof(struct iphdr, protocol);
 	skb->transport_header = skb->network_header + sizeof(*top_iph);
 	skb->transport_header = skb->network_header + sizeof(*top_iph);