All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [RFC PATCH resend]: Fix output for BEET ipsec
  2008-03-26  9:15 [RFC PATCH resend]: Fix output for BEET ipsec Joakim Koskela
@ 2008-03-26  9:14 ` Patrick McHardy
  2008-03-26 10:47   ` Joakim Koskela
  2008-03-26 13:31 ` Herbert Xu
  1 sibling, 1 reply; 9+ messages in thread
From: Patrick McHardy @ 2008-03-26  9:14 UTC (permalink / raw)
  To: Joakim Koskela; +Cc: netdev, Herbert Xu, Komu Miika

Joakim Koskela wrote:
> diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
> index 091e670..20d214f 100644
> --- a/net/ipv4/esp4.c
> +++ b/net/ipv4/esp4.c
> @@ -404,7 +404,8 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
>  		break;
>  	case XFRM_MODE_BEET:
>  		/* The worst case. */
> -		mtu += min_t(u32, IPV4_BEET_PHMAXLEN, rem);
> +		/* This will be seen to in the esp header_len */
> +		/* mtu += min_t(u32, IPV4_BEET_PHMAXLEN, rem); */
>  		break;
>  	}


Why are you disabling this?

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [RFC PATCH resend]: Fix output for BEET ipsec
@ 2008-03-26  9:15 Joakim Koskela
  2008-03-26  9:14 ` Patrick McHardy
  2008-03-26 13:31 ` Herbert Xu
  0 siblings, 2 replies; 9+ messages in thread
From: Joakim Koskela @ 2008-03-26  9:15 UTC (permalink / raw)
  To: netdev; +Cc: Herbert Xu, Komu Miika

Hi,

Any comments on this? Would be great to get beet working soon!

br, j

== original post:

This patch fixes the ipsec BEET (Bound End-to-End Tunnel) mode
interfamily handling of the net-2.6 (25-rc3) kernel, as specified by
the ietf draft found at:

http://www.ietf.org/internet-drafts/draft-nikander-esp-beet-mode-08.txt

It is sent as a RFC as it doesn't fit that neatly into the newly
cleaned-up xfrm model - I suspect that there could be a better way to
solve this.

Signed-off-by: Joakim Koskela <jookos@gmail.com>
---
 net/ipv4/esp4.c            |   10 +++-
 net/ipv4/xfrm4_mode_beet.c |  104 +++++++++++++++++++++++++++++---------------
 net/ipv6/esp6.c            |    6 +++
 net/ipv6/xfrm6_mode_beet.c |   83 ++++++++++++++++++++++++++++++-----
 4 files changed, 153 insertions(+), 50 deletions(-)

diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 091e670..20d214f 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -404,7 +404,8 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
 		break;
 	case XFRM_MODE_BEET:
 		/* The worst case. */
-		mtu += min_t(u32, IPV4_BEET_PHMAXLEN, rem);
+		/* This will be seen to in the esp header_len */
+		/* mtu += min_t(u32, IPV4_BEET_PHMAXLEN, rem); */
 		break;
 	}
 
@@ -575,8 +576,11 @@ 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)
-		x->props.header_len += IPV4_BEET_PHMAXLEN;
+	else if (x->props.mode == XFRM_MODE_BEET) {
+		if (x->sel.family == AF_INET) {
+			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 b47030b..83db9b2 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -6,6 +6,7 @@
  *                    Herbert Xu     <herbert@gondor.apana.org.au>
  *                    Abhinav Pathak <abhinav.pathak@hiit.fi>
  *                    Jeff Ahrenholz <ahrenholz@gmail.com>
+ *                    Joakim Koskela <jookos@gmail.com>
  */
 
 #include <linux/init.h>
@@ -38,45 +39,78 @@ static void xfrm4_beet_make_header(struct sk_buff *skb)
  */
 static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 {
-	struct ip_beet_phdr *ph;
 	struct iphdr *iph, *top_iph;
-	int hdrlen, optlen;
 
 	iph = ip_hdr(skb);
-
-	hdrlen = 0;
-	optlen = iph->ihl * 4 - sizeof(*iph);
-	if (unlikely(optlen))
-		hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4);
-
-	skb_set_network_header(skb, IPV4_BEET_PHMAXLEN - x->props.header_len -
-				    hdrlen);
-	skb->mac_header = skb->network_header +
-			  offsetof(struct iphdr, protocol);
-	skb->transport_header = skb->network_header + sizeof(*iph);
-
-	xfrm4_beet_make_header(skb);
-
-	ph = (struct ip_beet_phdr *)__skb_pull(skb, sizeof(*iph) - hdrlen);
-
-	top_iph = ip_hdr(skb);
-
-	if (unlikely(optlen)) {
-		BUG_ON(optlen < 0);
-
-		ph->padlen = 4 - (optlen & 4);
-		ph->hdrlen = optlen / 8;
-		ph->nexthdr = top_iph->protocol;
-		if (ph->padlen)
-			memset(ph + 1, IPOPT_NOP, ph->padlen);
-
-		top_iph->protocol = IPPROTO_BEETPH;
-		top_iph->ihl = sizeof(struct iphdr) / 4;
+	if (iph->version == 4) {
+		struct ip_beet_phdr *ph;
+		int hdrlen, optlen;
+
+		hdrlen = 0;
+		optlen = iph->ihl * 4 - sizeof(*iph);
+		if (unlikely(optlen))
+			hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4);
+
+		skb_set_network_header(skb, IPV4_BEET_PHMAXLEN - x->props.header_len -
+				       hdrlen);
+		skb->mac_header = skb->network_header +
+			offsetof(struct iphdr, protocol);
+		skb->transport_header = skb->network_header + sizeof(*iph);
+
+		xfrm4_beet_make_header(skb);
+
+		ph = (struct ip_beet_phdr *)__skb_pull(skb, sizeof(*iph) - hdrlen);
+
+		top_iph = ip_hdr(skb);
+
+		if (unlikely(optlen)) {
+			BUG_ON(optlen < 0);
+
+			ph->padlen = 4 - (optlen & 4);
+			ph->hdrlen = optlen / 8;
+			ph->nexthdr = top_iph->protocol;
+			if (ph->padlen)
+				memset(ph + 1, IPOPT_NOP, ph->padlen);
+
+			top_iph->protocol = IPPROTO_BEETPH;
+			top_iph->ihl = sizeof(struct iphdr) / 4;
+		}
+
+		top_iph->saddr = x->props.saddr.a4;
+		top_iph->daddr = x->id.daddr.a4;
+
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+	} else if (iph->version == 6) {
+		struct dst_entry *dst = skb->dst;
+
+		int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr);
+		u8 protocol = ipv6_hdr(skb)->nexthdr;
+
+		/* Inner = 6, Outer = 4 : changing the external IP hdr
+		 * to the outer addresses
+		 */
+		skb_set_network_header(skb, delta - x->props.header_len);
+		skb->transport_header = skb->network_header + sizeof(*iph);
+		skb->mac_header = skb->network_header +
+			offsetof(struct iphdr, protocol);
+		skb_pull(skb, sizeof(struct ipv6hdr));
+
+		top_iph = ip_hdr(skb);
+		top_iph->ihl = 5;
+		top_iph->version = 4;
+		top_iph->id = 0;
+		top_iph->frag_off = htons(IP_DF);
+		top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT);
+		top_iph->protocol = protocol;
+
+		top_iph->saddr = x->props.saddr.a4;
+		top_iph->daddr = x->id.daddr.a4;
+		IPCB(skb)->flags = 0;
+
+		skb->protocol = htons(ETH_P_IP);
+		memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+#endif
 	}
-
-	top_iph->saddr = x->props.saddr.a4;
-	top_iph->daddr = x->id.daddr.a4;
-
 	return 0;
 }
 
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 0ec1402..984a03e 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -344,6 +344,7 @@ static u32 esp6_get_mtu(struct xfrm_state *x, int mtu)
 	rem = mtu & (align - 1);
 	mtu &= ~(align - 1);
 
+	/* hm, is this right? maybe we shouldn't do this for beet either? */
 	if (x->props.mode != XFRM_MODE_TUNNEL) {
 		u32 padsize = ((blksize - 1) & 7) + 1;
 		mtu -= blksize - padsize;
@@ -521,6 +522,11 @@ 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_INET) {
+			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/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
index 0527d11..2547c51 100644
--- a/net/ipv6/xfrm6_mode_beet.c
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -6,6 +6,7 @@
  *                    Herbert Xu     <herbert@gondor.apana.org.au>
  *                    Abhinav Pathak <abhinav.pathak@hiit.fi>
  *                    Jeff Ahrenholz <ahrenholz@gmail.com>
+ *                    Joakim Koskela <jookos@gmail.com>
  */
 
 #include <linux/init.h>
@@ -40,18 +41,76 @@ 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);
-	skb->mac_header = skb->network_header +
-			  offsetof(struct ipv6hdr, nexthdr);
-	skb->transport_header = skb->network_header + sizeof(*top_iph);
-
-	xfrm6_beet_make_header(skb);
-
-	top_iph = ipv6_hdr(skb);
-
-	ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
-	ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
+	int hdr_len;
+
+	if (ip_hdr(skb)->version == 6) {
+		u8 *prevhdr;
+
+		hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
+		skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);
+		skb_set_network_header(skb, -x->props.header_len);
+		skb->transport_header = skb->network_header + hdr_len;
+		__skb_pull(skb, hdr_len);
+
+		xfrm6_beet_make_header(skb);
+
+		top_iph = ipv6_hdr(skb);
+
+		ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
+		ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
+	} else {
+		struct dst_entry *dst = skb->dst;
+		struct iphdr *iphv4;
+		int flags, optlen, dsfield;
+		struct ip_beet_phdr *ph;
+		u8 protocol;
+
+		iphv4 = ip_hdr(skb);
+		hdr_len = 0;
+		optlen = iphv4->ihl * 4 - sizeof(*iphv4);
+		if (unlikely(optlen))
+			hdr_len += IPV4_BEET_PHMAXLEN - (optlen & 4);
+
+		skb_set_network_header(skb, IPV4_BEET_PHMAXLEN - x->props.header_len -
+				       hdr_len);
+		skb->mac_header = skb->network_header + offsetof(struct ipv6hdr, nexthdr);
+		skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
+
+		ph = (struct ip_beet_phdr *)__skb_pull(skb, sizeof(*iphv4) - hdr_len);
+		if (unlikely(optlen)) {
+
+			BUG_ON(optlen < 0);
+
+			ph->padlen = 4 - (optlen & 4);
+			ph->hdrlen = optlen / 8;
+			ph->nexthdr = iphv4->protocol;
+			if (ph->padlen)
+				memset(ph + 1, IPOPT_NOP, ph->padlen);
+
+			protocol = IPPROTO_BEETPH;
+		} else
+			protocol = iphv4->protocol;
+
+		top_iph = ipv6_hdr(skb);
+
+		/* DS disclosed */
+		top_iph->version = 6;
+		top_iph->priority = 0;
+		top_iph->flow_lbl[0] = 0;
+		top_iph->flow_lbl[1] = 0;
+		top_iph->flow_lbl[2] = 0;
+		dsfield = ipv6_get_dsfield(top_iph);
+		dsfield = INET_ECN_encapsulate(dsfield, dsfield);
+		flags = x->props.flags;
+		if (flags & XFRM_STATE_NOECN)
+			dsfield &= ~INET_ECN_MASK;
+		ipv6_change_dsfield(top_iph, 0, dsfield);
+
+		top_iph->nexthdr = protocol;
+		top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT);
+		ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
+		ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
+	}
 	return 0;
 }


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH resend]: Fix output for BEET ipsec
  2008-03-26  9:14 ` Patrick McHardy
@ 2008-03-26 10:47   ` Joakim Koskela
  0 siblings, 0 replies; 9+ messages in thread
From: Joakim Koskela @ 2008-03-26 10:47 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netdev, Herbert Xu, Komu Miika

On Wednesday 26 March 2008 11:14, Patrick McHardy wrote:
> Joakim Koskela wrote:
> > diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
> > index 091e670..20d214f 100644
> > --- a/net/ipv4/esp4.c
> > +++ b/net/ipv4/esp4.c
> > @@ -404,7 +404,8 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int
> > mtu) break;
> >  	case XFRM_MODE_BEET:
> >  		/* The worst case. */
> > -		mtu += min_t(u32, IPV4_BEET_PHMAXLEN, rem);
> > +		/* This will be seen to in the esp header_len */
> > +		/* mtu += min_t(u32, IPV4_BEET_PHMAXLEN, rem); */
> >  		break;
> >  	}
>
> Why are you disabling this?

Thanks - can't remember and doesn't seem necessary. I'll reverse that.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH resend]: Fix output for BEET ipsec
  2008-03-26  9:15 [RFC PATCH resend]: Fix output for BEET ipsec Joakim Koskela
  2008-03-26  9:14 ` Patrick McHardy
@ 2008-03-26 13:31 ` Herbert Xu
  2008-04-22 12:12   ` Joakim Koskela
  1 sibling, 1 reply; 9+ messages in thread
From: Herbert Xu @ 2008-03-26 13:31 UTC (permalink / raw)
  To: Joakim Koskela; +Cc: netdev, Komu Miika

On Wed, Mar 26, 2008 at 11:15:26AM +0200, Joakim Koskela wrote:
> Hi,
> 
> Any comments on this? Would be great to get beet working soon!
> 
> br, j
> 
> == original post:
> 
> This patch fixes the ipsec BEET (Bound End-to-End Tunnel) mode
> interfamily handling of the net-2.6 (25-rc3) kernel, as specified by
> the ietf draft found at:
> 
> http://www.ietf.org/internet-drafts/draft-nikander-esp-beet-mode-08.txt
> 
> It is sent as a RFC as it doesn't fit that neatly into the newly
> cleaned-up xfrm model - I suspect that there could be a better way to
> solve this.
> 
> Signed-off-by: Joakim Koskela <jookos@gmail.com>

Thanks for the patch!

In light of the patch I just posted I believe we can drop everything
but the props_header_len adjustments.  Please let me know if it still
doesn't work with my earlier patch.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH resend]: Fix output for BEET ipsec
  2008-03-26 13:31 ` Herbert Xu
@ 2008-04-22 12:12   ` Joakim Koskela
  2008-04-22 13:13     ` Herbert Xu
  0 siblings, 1 reply; 9+ messages in thread
From: Joakim Koskela @ 2008-04-22 12:12 UTC (permalink / raw)
  To: Herbert Xu; +Cc: netdev

On Wednesday 26 March 2008 15:31, Herbert Xu wrote:
> In light of the patch I just posted I believe we can drop everything
> but the props_header_len adjustments.  Please let me know if it still
> doesn't work with my earlier patch.
>
> Cheers,

Thanks, but I'm still having problems with 6-6 and the interfamilies.

Here's what I'm using right now to get net-2.6 beet working (testing with older
versions and another implementation). It's basically the same as I sent before, 
slightly updated (to use the protocol-independent accessors).

br, j

Signed-off-by: Joakim Koskela <jookos@gmail.com>
--
 net/ipv4/esp4.c            |    2 +-
 net/ipv4/xfrm4_mode_beet.c |  101 ++++++++++++++++++++++++++++---------------
 net/ipv6/esp6.c            |    5 ++
 net/ipv6/xfrm6_mode_beet.c |   65 ++++++++++++++++++++++++----
 4 files changed, 128 insertions(+), 45 deletions(-)

diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 4e73e57..135094e 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -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_INET)
 		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 9c798ab..7f218cc 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -6,6 +6,7 @@
  *                    Herbert Xu     <herbert@gondor.apana.org.au>
  *                    Abhinav Pathak <abhinav.pathak@hiit.fi>
  *                    Jeff Ahrenholz <ahrenholz@gmail.com>
+ *                    Joakim Koskela <jookos@gmail.com>
  */
 
 #include <linux/init.h>
@@ -38,44 +39,74 @@ static void xfrm4_beet_make_header(struct sk_buff *skb)
  */
 static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 {
-	struct ip_beet_phdr *ph;
-	struct iphdr *top_iph;
-	int hdrlen, optlen;
+	struct iphdr *iph, *top_iph;
 
-	hdrlen = 0;
-	optlen = XFRM_MODE_SKB_CB(skb)->optlen;
-	if (unlikely(optlen))
-		hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4);
-
-	skb_set_network_header(skb, IPV4_BEET_PHMAXLEN - x->props.header_len -
-				    hdrlen);
-	skb->mac_header = skb->network_header +
-			  offsetof(struct iphdr, protocol);
-	skb->transport_header = skb->network_header + sizeof(*top_iph);
-
-	xfrm4_beet_make_header(skb);
-
-	ph = (struct ip_beet_phdr *)
-		__skb_pull(skb, XFRM_MODE_SKB_CB(skb)->ihl - hdrlen);
-
-	top_iph = ip_hdr(skb);
-
-	if (unlikely(optlen)) {
-		BUG_ON(optlen < 0);
-
-		ph->padlen = 4 - (optlen & 4);
-		ph->hdrlen = optlen / 8;
-		ph->nexthdr = top_iph->protocol;
-		if (ph->padlen)
-			memset(ph + 1, IPOPT_NOP, ph->padlen);
-
-		top_iph->protocol = IPPROTO_BEETPH;
-		top_iph->ihl = sizeof(struct iphdr) / 4;
+	iph = ip_hdr(skb);
+	if (iph->version == 4) {
+		struct ip_beet_phdr *ph;
+		int hdrlen, optlen;
+
+		hdrlen = 0;
+		optlen = XFRM_MODE_SKB_CB(skb)->optlen;
+		if (unlikely(optlen))
+			hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4);
+
+		skb_set_network_header(skb, IPV4_BEET_PHMAXLEN - x->props.header_len -
+				       hdrlen);
+		skb->mac_header = skb->network_header +
+			offsetof(struct iphdr, protocol);
+		skb->transport_header = skb->network_header + sizeof(*top_iph);
+
+		xfrm4_beet_make_header(skb);
+
+		ph = (struct ip_beet_phdr *)
+			__skb_pull(skb, XFRM_MODE_SKB_CB(skb)->ihl - hdrlen);
+
+		top_iph = ip_hdr(skb);
+
+		if (unlikely(optlen)) {
+			BUG_ON(optlen < 0);
+
+			ph->padlen = 4 - (optlen & 4);
+			ph->hdrlen = optlen / 8;
+			ph->nexthdr = top_iph->protocol;
+			if (ph->padlen)
+				memset(ph + 1, IPOPT_NOP, ph->padlen);
+
+			top_iph->protocol = IPPROTO_BEETPH;
+			top_iph->ihl = sizeof(struct iphdr) / 4;
+		}
+
+		top_iph->saddr = x->props.saddr.a4;
+		top_iph->daddr = x->id.daddr.a4;
+
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+	} else if (iph->version == 6) {
+		int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr);
+		u8 protocol = ipv6_hdr(skb)->nexthdr;
+
+		/* Inner = 6, Outer = 4 : changing the external IP hdr
+		 * to the outer addresses
+		 */
+		skb_set_network_header(skb, delta - x->props.header_len);
+		skb->transport_header = skb->network_header + sizeof(*iph);
+		skb->mac_header = skb->network_header +
+			offsetof(struct iphdr, protocol);
+		skb_pull(skb, sizeof(struct ipv6hdr));
+
+		xfrm4_beet_make_header(skb);
+
+		top_iph = ip_hdr(skb);
+		top_iph->protocol = protocol;
+		top_iph->saddr = x->props.saddr.a4;
+		top_iph->daddr = x->id.daddr.a4;
+		IPCB(skb)->flags = 0;
+
+		skb->protocol = htons(ETH_P_IP);
+		memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+#endif
 	}
 
-	top_iph->saddr = x->props.saddr.a4;
-	top_iph->daddr = x->id.daddr.a4;
-
 	return 0;
 }
 
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index c6bb4c6..8356c11 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -521,6 +521,11 @@ 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_INET) {
+			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/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
index d6ce400..a11af00 100644
--- a/net/ipv6/xfrm6_mode_beet.c
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -40,19 +40,66 @@ 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;
+	int hdr_len;
 
-	skb_set_network_header(skb, -x->props.header_len);
-	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);
+	if (ip_hdr(skb)->version == 6) {
+		u8 *prevhdr;
 
-	xfrm6_beet_make_header(skb);
+		hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
+		skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);
+		skb_set_network_header(skb, -x->props.header_len);
+		skb->transport_header = skb->network_header + hdr_len;
+		__skb_pull(skb, hdr_len);
+
+		xfrm6_beet_make_header(skb);
+
+		top_iph = ipv6_hdr(skb);
+
+		ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
+		ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
+	} else {
+		struct iphdr *iphv4;
+		int optlen;
+		struct ip_beet_phdr *ph;
+		u8 protocol;
+
+		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, IPV4_BEET_PHMAXLEN - x->props.header_len -
+				       hdr_len);
+		skb->mac_header = skb->network_header +
+			offsetof(struct ipv6hdr, nexthdr);
+		skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
+
+		ph = (struct ip_beet_phdr *)
+			__skb_pull(skb, XFRM_MODE_SKB_CB(skb)->ihl - hdr_len);
+		if (unlikely(optlen)) {
+
+			BUG_ON(optlen < 0);
+
+			ph->padlen = 4 - (optlen & 4);
+			ph->hdrlen = optlen / 8;
+			ph->nexthdr = iphv4->protocol;
+			if (ph->padlen)
+				memset(ph + 1, IPOPT_NOP, ph->padlen);
+
+			protocol = IPPROTO_BEETPH;
+		} else
+			protocol = iphv4->protocol;
+
+		xfrm6_beet_make_header(skb);
+
+		top_iph = ipv6_hdr(skb);
 
-	top_iph = ipv6_hdr(skb);
+		top_iph->nexthdr = protocol;
+		ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
+		ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
+	}
 
-	ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
-	ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
 	return 0;
 }

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH resend]: Fix output for BEET ipsec
  2008-04-22 12:12   ` Joakim Koskela
@ 2008-04-22 13:13     ` Herbert Xu
  2008-04-23  7:13       ` Joakim Koskela
  0 siblings, 1 reply; 9+ messages in thread
From: Herbert Xu @ 2008-04-22 13:13 UTC (permalink / raw)
  To: Joakim Koskela; +Cc: netdev

On Tue, Apr 22, 2008 at 03:12:40PM +0300, Joakim Koskela wrote:
> 
> Thanks, but I'm still having problems with 6-6 and the interfamilies.
> 
> Here's what I'm using right now to get net-2.6 beet working (testing with older
> versions and another implementation). It's basically the same as I sent before, 
> slightly updated (to use the protocol-independent accessors).

You know it would really help if you told us what problems you're
having rather than just resending the patch over and over again :)

Thanks,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH resend]: Fix output for BEET ipsec
  2008-04-22 13:13     ` Herbert Xu
@ 2008-04-23  7:13       ` Joakim Koskela
  2008-04-23  7:30         ` Herbert Xu
  0 siblings, 1 reply; 9+ messages in thread
From: Joakim Koskela @ 2008-04-23  7:13 UTC (permalink / raw)
  To: Herbert Xu; +Cc: netdev

On Tuesday 22 April 2008 16:13, Herbert Xu wrote:
> On Tue, Apr 22, 2008 at 03:12:40PM +0300, Joakim Koskela wrote:
> > Thanks, but I'm still having problems with 6-6 and the interfamilies.
> >
> > Here's what I'm using right now to get net-2.6 beet working (testing with
> > older versions and another implementation). It's basically the same as I
> > sent before, slightly updated (to use the protocol-independent
> > accessors).
>
> You know it would really help if you told us what problems you're
> having rather than just resending the patch over and over again :)

Sorry, I know really should. I'll try to get back on this asap with some more 
details. But in a nutshell - I get crashes on 4-6 (inner-outer), and although 
6-4 gets packets on the wire, they're somehow wrong. Hm, don't actually think 
there's anything wrong with 6-6 though, I'll have to recheck that.. 

Cheers, 
j

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH resend]: Fix output for BEET ipsec
  2008-04-23  7:13       ` Joakim Koskela
@ 2008-04-23  7:30         ` Herbert Xu
  2008-04-28  7:51           ` Joakim Koskela
  0 siblings, 1 reply; 9+ messages in thread
From: Herbert Xu @ 2008-04-23  7:30 UTC (permalink / raw)
  To: Joakim Koskela; +Cc: netdev

On Wed, Apr 23, 2008 at 10:13:38AM +0300, Joakim Koskela wrote:
>
> Sorry, I know really should. I'll try to get back on this asap with some more 
> details. But in a nutshell - I get crashes on 4-6 (inner-outer), and although 
> 6-4 gets packets on the wire, they're somehow wrong. Hm, don't actually think 
> there's anything wrong with 6-6 though, I'll have to recheck that.. 

OK I'll try to get my test environment back up to have a look.

Thanks,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC PATCH resend]: Fix output for BEET ipsec
  2008-04-23  7:30         ` Herbert Xu
@ 2008-04-28  7:51           ` Joakim Koskela
  0 siblings, 0 replies; 9+ messages in thread
From: Joakim Koskela @ 2008-04-28  7:51 UTC (permalink / raw)
  To: Herbert Xu; +Cc: netdev

On Wednesday 23 April 2008 10:30, Herbert Xu wrote:
> On Wed, Apr 23, 2008 at 10:13:38AM +0300, Joakim Koskela wrote:
> > Sorry, I know really should. I'll try to get back on this asap with some
> > more details. But in a nutshell - I get crashes on 4-6 (inner-outer), and
> > although 6-4 gets packets on the wire, they're somehow wrong. Hm, don't
> > actually think there's anything wrong with 6-6 though, I'll have to
> > recheck that..
>
> OK I'll try to get my test environment back up to have a look.
>
> Thanks,

Here's a calltrace from 4 inner, 6 outer. I do a manual key setup, and try to
ping the other host.

------------[ cut here ]------------
invalid opcode: 0000 [#4] PREEMPT
Process ping (pid: 5516, ti=d9598000 task=d957b140 task.ti=d9598000)
Stack: e086f700 e1b9a5ec 00000000 00000014 d9599c17 dc3fbc40 dfa68a80 dfa68a80
       00000078 00000000 00000001 c069a3a0 deef2000 00000000 dc3fbc40 dfa68aa0
       d9569040 dfa68a80 c03d2c04 00000054 d9569038 c0476b1d 00000054 dc35e600
Call Trace:
 [<c03d2c04>] skb_to_sgvec+0x14/0x30
 [<c0476b1d>] esp6_output+0x1ad/0x270
 [<c0441fa4>] xfrm_output_resume+0x2a4/0x320
 [<c03fad17>] __ip_local_out+0x97/0xa0
 [<c03fad35>] ip_local_out+0x15/0x20
 [<c03faf4a>] ip_push_pending_frames+0x20a/0x350
 [<c03f3ea4>] ip_route_output_flow+0x74/0x290
 [<c041688f>] raw_sendmsg+0x69f/0x750
 [<c041eb27>] inet_sendmsg+0x37/0x70
 [<c03cde7d>] sock_sendmsg+0xcd/0x100
 [<c03fd407>] ip_setsockopt+0x147/0xc40
 [<c0136550>] autoremove_wake_function+0x0/0x50
 [<c011ce9c>] set_next_entity+0x1c/0x50
 [<c04cbfb7>] schedule+0x177/0x310
 [<c03d5afa>] verify_iovec+0x2a/0x90
 [<c03ce011>] sys_sendmsg+0x161/0x270
 [<c0359f6a>] tty_ioctl+0x73a/0xec0
 [<c014e7ae>] find_lock_page+0x2e/0xd0
 [<c0150e2f>] filemap_fault+0x1ef/0x460
 [<c015b291>] __do_fault+0x171/0x3b0
 [<c0150c40>] filemap_fault+0x0/0x460
 [<c015d0c2>] handle_mm_fault+0xf2/0x600
 [<c03cf42f>] sys_socketcall+0x24f/0x280
 [<c013b62d>] do_gettimeofday+0xd/0x30
 [<c0102f3d>] sysenter_past_esp+0x6a/0x91
 =======================
Code: ff ff c7 44 24 0c 74 09 00 00 c7 44 24 08 a9 37 5a c0 c7 44 24 04 bb 37 5a c0 c7 04 24 2c 6e 5a c0 e8 95 1c d5 ff e9 02 ff ff ff <0f> 0b eb fe 0f 0b eb fe 90 8d b4 26 00 00 00 00 53 89 d3 83 ec
EIP: [<c03d2be0>] __skb_to_sgvec+0x280/0x290 SS:ESP 0068:d9599bd0

Modules linked in: radeon drm rfcomm l2cap binfmt_misc ppdev lp cpufreq_userspace cpufreq_conservative cpufreq_powersave cpufreq_ondemand ipt_TTL ipt_ttl ipt_REDIRECT ipt_recent ipt_NETMAP ipt_MASQUERADE ipt_ECN ipt_ecn ipt_addrtype nf_nat_tftp nf_nat_snmp_basic nf_nat_sip nf_nat_pptp nf_nat_proto_gre nf_nat_irc nf_nat_h323 nf_nat_ftp nf_nat_amanda ts_kmp nf_conntrack_amanda nf_conntrack_tftp nf_conntrack_sip nf_conntrack_proto_sctp nf_conntrack_pptp nf_conntrack_proto_gre nf_conntrack_netbios_ns nf_conntrack_irc nf_conntrack_h323 nf_conntrack_ftp xt_tcpmss xt_pkttype xt_mark xt_mac xt_limit xt_length xt_helper xt_hashlimit xt_dccp xt_conntrack xt_CONNMARK xt_connmark xt_state iptable_nat nf_nat nf_conntrack_ipv4 nf_conntrack nls_cp437 loop 8250_pci hci_usb bluetooth snd_intel8x0m snd_inte
 l8x0 snd_ac97_codec irtty_sir ac97_bus sir_dev snd_pcm_oss snd_mixer_oss parport_pc 8250_pnp snd_pcm 8250 irda snd_timer serial_core snd parport crc_ccitt floppy soundcore ide_cd_mod ipw2100 cdro
 i2c_i801 snd_page_alloc ieee80211 ieee80211_crypt e1000 ehci_hcd uhci_hcd video usbcore output evdev

Pid: 5516, comm: ping Tainted: G      D  (2.6.25-02632-g358c129 #3)
EIP: 0060:[<c03d2be0>] EFLAGS: 00010206 CPU: 0
EIP is at __skb_to_sgvec+0x280/0x290
EAX: dc3fbc40 EBX: 00000048 ECX: dfa68a80 EDX: d9569100
ESI: 00000000 EDI: 00000014 EBP: 00000078 ESP: d9599bd0
 DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
---[ end trace ff7f9acec52365a5 ]---




^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2008-04-28  7:48 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-26  9:15 [RFC PATCH resend]: Fix output for BEET ipsec Joakim Koskela
2008-03-26  9:14 ` Patrick McHardy
2008-03-26 10:47   ` Joakim Koskela
2008-03-26 13:31 ` Herbert Xu
2008-04-22 12:12   ` Joakim Koskela
2008-04-22 13:13     ` Herbert Xu
2008-04-23  7:13       ` Joakim Koskela
2008-04-23  7:30         ` Herbert Xu
2008-04-28  7:51           ` Joakim Koskela

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.