On Sun, Nov 20, 2005 at 04:31:34PM +0000, Patrick McHardy wrote:
>
> diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
> index ae0779d..b93e7cd 100644
> --- a/net/ipv4/netfilter.c
> +++ b/net/ipv4/netfilter.c
> @@ -78,6 +79,34 @@ int ip_route_me_harder(struct sk_buff **
>  }
>  EXPORT_SYMBOL(ip_route_me_harder);
>  
> +#ifdef CONFIG_XFRM
> +static inline int __ip_dst_output(struct sk_buff *skb)

I'd like to suggest an alternative way of doing this that

1) Keeps this XFRM stuff in xfrm*.c.
2) Removes the need for ip_dst_output.

Please see the attached patch.

> +     do {
> +             err = skb->dst->output(skb);
> +
> +             if (likely(err == 0))
> +                     return err;
> +             if (unlikely(err != NET_XMIT_BYPASS))
> +                     return err;
> +     } while (skb->dst->xfrm && !skb->dst->xfrm->props.mode);
> +
> +     return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, skb->dst->dev,
> +                    ip_dst_output);

The idea is simply to put this stuff in xfrm[46]_output directly.
So for your patch you would simply need to add the two NF_HOOK
calls at the beginning and end of xfrm[46]_output once they've
been modified in the way I outline below.

> diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
> index 66620a9..c135746 100644
> --- a/net/ipv4/xfrm4_output.c
> +++ b/net/ipv4/xfrm4_output.c
> @@ -133,6 +133,7 @@ int xfrm4_output(struct sk_buff *skb)
>               err = -EHOSTUNREACH;
>               goto error_nolock;
>       }
> +     nf_reset(skb);
>       err = NET_XMIT_BYPASS;

Shouldn't this sit after POST_ROUTING, i.e., once the connection
has been confirmed?

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[EMAIL PROTECTED]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/include/net/ip.h b/include/net/ip.h
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -113,26 +113,31 @@ int xfrm4_output(struct sk_buff *skb)
                        goto error_nolock;
        }
 
-       spin_lock_bh(&x->lock);
-       err = xfrm_state_check(x, skb);
-       if (err)
-               goto error;
-
-       xfrm4_encap(skb);
-
-       err = x->type->output(x, skb);
-       if (err)
-               goto error;
+       do {
+               spin_lock_bh(&x->lock);
+               err = xfrm_state_check(x, skb);
+               if (err)
+                       goto error;
+
+               xfrm4_encap(skb);
+
+               err = x->type->output(x, skb);
+               if (err)
+                       goto error;
 
-       x->curlft.bytes += skb->len;
-       x->curlft.packets++;
+               x->curlft.bytes += skb->len;
+               x->curlft.packets++;
 
-       spin_unlock_bh(&x->lock);
+               spin_unlock_bh(&x->lock);
        
-       if (!(skb->dst = dst_pop(dst))) {
-               err = -EHOSTUNREACH;
-               goto error_nolock;
-       }
+               if (!(skb->dst = dst_pop(dst))) {
+                       err = -EHOSTUNREACH;
+                       goto error_nolock;
+               }
+               dst = skb->dst;
+               x = dst->xfrm;
+       } while (x && !x->props.mode);
+
        err = NET_XMIT_BYPASS;
 
 out_exit:
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -110,28 +110,33 @@ int xfrm6_output(struct sk_buff *skb)
                        goto error_nolock;
        }
 
-       spin_lock_bh(&x->lock);
-       err = xfrm_state_check(x, skb);
-       if (err)
-               goto error;
-
-       xfrm6_encap(skb);
-
-       err = x->type->output(x, skb);
-       if (err)
-               goto error;
-
-       x->curlft.bytes += skb->len;
-       x->curlft.packets++;
-
-       spin_unlock_bh(&x->lock);
+       do {
+               spin_lock_bh(&x->lock);
+               err = xfrm_state_check(x, skb);
+               if (err)
+                       goto error;
+
+               xfrm6_encap(skb);
+
+               err = x->type->output(x, skb);
+               if (err)
+                       goto error;
+
+               x->curlft.bytes += skb->len;
+               x->curlft.packets++;
+
+               spin_unlock_bh(&x->lock);
+
+               skb->nh.raw = skb->data;
+               
+               if (!(skb->dst = dst_pop(dst))) {
+                       err = -EHOSTUNREACH;
+                       goto error_nolock;
+               }
+               dst = skb->dst;
+               x = dst->xfrm;
+       } while (x && !x->props.mode);
 
-       skb->nh.raw = skb->data;
-       
-       if (!(skb->dst = dst_pop(dst))) {
-               err = -EHOSTUNREACH;
-               goto error_nolock;
-       }
        err = NET_XMIT_BYPASS;
 
 out_exit:
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to