All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick McHardy <kaber@trash.net>
To: Joakim Koskela <joakim.koskela@hiit.fi>
Cc: netdev@vger.kernel.org, David Miller <davem@davemloft.net>
Subject: Re: [PATCH net-2.6.22-rc7] xfrm beet interfamily support
Date: Mon, 16 Jul 2007 20:47:40 +0200	[thread overview]
Message-ID: <469BBD4C.5040503@trash.net> (raw)
In-Reply-To: <200707161506.47915.joakim.koskela@hiit.fi>

Joakim Koskela wrote:
> diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
> index fa1902d..7a39f4c 100644
> --- a/net/ipv4/xfrm4_input.c
> +++ b/net/ipv4/xfrm4_input.c
> @@ -108,7 +108,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
>  		if (x->mode->input(x, skb))
>  			goto drop;
>  
> -		if (x->props.mode == XFRM_MODE_TUNNEL) {
> +		if (x->props.mode == XFRM_MODE_TUNNEL ||
> +		    x->props.mode == XFRM_MODE_BEET) {
>  			decaps = 1;
>  			break;
>  		}


I was under the impression that one of the main points of BEET is that
it offers tunnel semantics but does only transport mode processing.
Its necessary for inter-family tunnels, but shouldn't this be avoided
for normal use?

> -		ph->padlen = 4 - (optlen & 4);
> -		ph->hdrlen = optlen / 8;
> -		ph->nexthdr = top_iph->protocol;
> -		if (ph->padlen)
> -			memset(ph + 1, IPOPT_NOP, ph->padlen);
> -

> +			ph = (struct ip_beet_phdr *)skb_transport_header(skb);
> +			ph->padlen = 4 - (optlen & 4);
> +			ph->hdrlen = (optlen + ph->padlen + sizeof(*ph)) / 8;


Reintroduces pseudo-header length bug.

> +			ph->nexthdr = iphv4->protocol;
> +			top_iphv4->protocol = IPPROTO_BEETPH;
> +			top_iphv4->ihl = sizeof(struct iphdr) / 4;


Where did padding go?

>  static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
>  {

> -	if (unlikely(iph->protocol == IPPROTO_BEETPH)) {
> -		struct ip_beet_phdr *ph;
> -
> -		if (!pskb_may_pull(skb, sizeof(*ph)))
> -			goto out;
> -		ph = (struct ip_beet_phdr *)(ipip_hdr(skb) + 1);
> -
> -		phlen = sizeof(*ph) + ph->padlen;
> -		optlen = ph->hdrlen * 8 + (IPV4_BEET_PHMAXLEN - phlen);
> -		if (optlen < 0 || optlen & 3 || optlen > 250)
> -			goto out;

> +		if (unlikely(iph->protocol == IPPROTO_BEETPH)) {
> +			struct ip_beet_phdr *ph =
> +				(struct ip_beet_phdr*)(iph + 1);
> +
> +			if (!pskb_may_pull(skb, sizeof(*ph)))
> +				goto out;
> +
> +			phlen = ph->hdrlen * 8;
> +			optlen = phlen - ph->padlen - sizeof(*ph);

Reintroduces header length bug.

> diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
> index 44ef208..8db7910 100644
> --- a/net/ipv4/xfrm4_output.c
> +++ b/net/ipv4/xfrm4_output.c
> @@ -53,7 +53,8 @@ static int xfrm4_output_one(struct sk_buff *skb)
>  			goto error_nolock;
>  	}
>  
> -	if (x->props.mode == XFRM_MODE_TUNNEL) {
> +	if (x->props.mode == XFRM_MODE_TUNNEL ||
> +	    x->props.mode == XFRM_MODE_BEET) {
>  		err = xfrm4_tunnel_check_size(skb);


Its not a real tunnel and all packets are generated locally, why
does it need to send ICMPs?

>  		if (err)
> @@ -81,10 +82,15 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
>  			}
>  		}
>  	};
> +	union {
> +		struct in6_addr *in6;
> +		struct in_addr *in;
> +	} remote, local;
>  	int i;
>  	int err;
>  	int header_len = 0;
>  	int trailer_len = 0;
> +	unsigned short encap_family = 0;
>  
>  	dst = dst_prev = NULL;
>  	dst_hold(&rt->u.dst);
> @@ -113,12 +119,24 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
>  
>  		dst1->next = dst_prev;
>  		dst_prev = dst1;
> -
> +		if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
> +			encap_family = xfrm[i]->props.family;
> +			if (encap_family == AF_INET) {
> +				remote.in = (struct in_addr *)
> +					&xfrm[i]->id.daddr.a4;
> +				local.in  = (struct in_addr *)
> +					&xfrm[i]->props.saddr.a4;
> +			} else if (encap_family == AF_INET6) {
> +				remote.in6 = (struct in6_addr *)
> +					xfrm[i]->id.daddr.a6;
> +				local.in6 = (struct in6_addr *)
> +					xfrm[i]->props.saddr.a6;
> +			}


No ifdefs here?

> +		}
>  		header_len += xfrm[i]->props.header_len;
>  		trailer_len += xfrm[i]->props.trailer_len;
>  
> -		if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL) {
> -			unsigned short encap_family = xfrm[i]->props.family;
> +		if (encap_family) {
>  			switch (encap_family) {
>  			case AF_INET:
>  				fl_tunnel.fl4_dst = xfrm[i]->id.daddr.a4;
> @@ -198,6 +216,12 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
>  	}
>  
>  	xfrm_init_pmtu(dst);
> +	if (encap_family == AF_INET6) {
> +		/* The worst case */
> +		int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr);
> +		u32 mtu = dst_mtu(dst);
> +		xfrm4_update_pmtu(dst, mtu - delta);


This should be known at configuration time, why do you need to call
xfrm4_update_pmtu? Just set header_len correctly.

> diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
> index 5685103..57c2dba 100644
> --- a/net/ipv4/xfrm4_tunnel.c
> +++ b/net/ipv4/xfrm4_tunnel.c
> @@ -27,7 +27,8 @@ static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb)
>  
>  static int ipip_init_state(struct xfrm_state *x)
>  {
> -	if (x->props.mode != XFRM_MODE_TUNNEL)
> +	if (x->props.mode != XFRM_MODE_TUNNEL ||
> +	    x->props.mode != XFRM_MODE_BEET)
>  		return -EINVAL;


Looks like a bug fix that should be seperated.


> @@ -365,6 +366,8 @@ static int esp6_init_state(struct xfrm_state *x)
>  	x->props.header_len = sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen;
>  	if (x->props.mode == XFRM_MODE_TUNNEL)
>  		x->props.header_len += sizeof(struct ipv6hdr);
> +	else if (x->props.mode == XFRM_MODE_BEET)
> +		x->props.header_len += IPV4_BEET_PHMAXLEN;


Seems wrong, you don't do option encapsulation for IPv6. All you do is
subtract this length again. What you probably should do is account for
the IPv4 header *if* it is an interfamiyl tunnel.

> diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
> index c858537..bfb3d7b 100644
> --- a/net/ipv6/xfrm6_input.c
> +++ b/net/ipv6/xfrm6_input.c
> @@ -73,7 +73,8 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
>  		if (x->mode->input(x, skb))
>  			goto drop;
>  
> -		if (x->props.mode == XFRM_MODE_TUNNEL) { /* XXX */
> +		if (x->props.mode == XFRM_MODE_TUNNEL ||
> +		    x->props.mode == XFRM_MODE_BEET) { /* XXX */
>  			decaps = 1;

Same as for IPv4.


I lost interest here, but the reintroduced bugs make me think that
some old version was simply rediffed without even checking the
output and the state initialization also seems to need a bit more work.


  parent reply	other threads:[~2007-07-16 18:47 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-16 12:06 [PATCH net-2.6.22-rc7] xfrm beet interfamily support Joakim Koskela
2007-07-16 12:56 ` Arnaldo Carvalho de Melo
2007-07-18  9:18   ` David Miller
2007-07-16 18:47 ` Patrick McHardy [this message]
2007-07-17 14:30   ` Joakim Koskela
2007-07-17 16:00     ` Patrick McHardy
2007-07-19 14:08       ` Joakim Koskela
2007-07-19 14:46         ` Patrick McHardy
2007-07-19 17:54           ` Joakim Koskela
2007-07-19 19:43             ` Patrick McHardy
2007-07-23 16:19               ` [PATCH net-2.6.22-rc7] xfrm state selection update to use inner addresses Joakim Koskela
2007-07-24 14:31                 ` Patrick McHardy
2007-07-26  7:08                   ` David Miller
2007-07-31 10:39           ` [PATCH net-2.6.22-rc7] xfrm beet interfamily support Joakim Koskela
2007-07-31 10:51             ` Patrick McHardy
2007-07-31 11:08               ` Joakim Koskela
2007-07-31 11:14                 ` Patrick McHardy
2007-07-31 12:13                   ` Joakim Koskela
2007-08-06  6:49     ` Joakim Koskela
2007-08-06 12:08       ` Patrick McHardy
2007-08-06 13:07         ` Joakim Koskela
2007-08-06 13:21           ` Patrick McHardy
  -- strict thread matches above, loose matches on Subject: below --
2007-07-12  9:25 Joakim Koskela
2007-07-15  1:48 ` David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=469BBD4C.5040503@trash.net \
    --to=kaber@trash.net \
    --cc=davem@davemloft.net \
    --cc=joakim.koskela@hiit.fi \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.