]> err.no Git - linux-2.6/commitdiff
[IPSEC]: Use the top IPv4 route's peer instead of the bottom
authorHerbert Xu <herbert@gondor.apana.org.au>
Thu, 18 Oct 2007 04:34:46 +0000 (21:34 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 18 Oct 2007 04:34:46 +0000 (21:34 -0700)
For IPv4 we were using the bottom route's peer instead of the top one.
This is wrong because the peer is only used by TCP to keep track of
information about the TCP destination address which certainly does not
live in the bottom route.

This patch fixes that which allows us to get rid of the family check
since the bottom route could be IPv6 while the top one must always
be IPv4.

I've also changed the other fields which are IPv4-specific to get the
info from the top route instead of potentially bogus data from the
bottom route.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/xfrm4_policy.c

index c65b8e03c0490d83a1aa5862f116c4a9436bd463..1f0ea0e0371bb172feeacd135590e5faf2a1a641 100644 (file)
@@ -169,16 +169,16 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
                dst_prev->neighbour     = neigh_clone(rt->u.dst.neighbour);
                dst_prev->input         = rt->u.dst.input;
                dst_prev->output = dst_prev->xfrm->mode->afinfo->output;
-               if (dst_prev->xfrm->props.family == AF_INET && rt->peer)
-                       atomic_inc(&rt->peer->refcnt);
-               x->u.rt.peer = rt->peer;
+               if (rt0->peer)
+                       atomic_inc(&rt0->peer->refcnt);
+               x->u.rt.peer = rt0->peer;
                /* Sheit... I remember I did this right. Apparently,
                 * it was magically lost, so this code needs audit */
                x->u.rt.rt_flags = rt0->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
-               x->u.rt.rt_type = rt->rt_type;
+               x->u.rt.rt_type = rt0->rt_type;
                x->u.rt.rt_src = rt0->rt_src;
                x->u.rt.rt_dst = rt0->rt_dst;
-               x->u.rt.rt_gateway = rt->rt_gateway;
+               x->u.rt.rt_gateway = rt0->rt_gateway;
                x->u.rt.rt_spec_dst = rt0->rt_spec_dst;
                x->u.rt.idev = rt0->idev;
                in_dev_hold(rt0->idev);
@@ -280,7 +280,7 @@ static void xfrm4_dst_destroy(struct dst_entry *dst)
 
        if (likely(xdst->u.rt.idev))
                in_dev_put(xdst->u.rt.idev);
-       if (dst->xfrm && dst->xfrm->props.family == AF_INET && likely(xdst->u.rt.peer))
+       if (likely(xdst->u.rt.peer))
                inet_putpeer(xdst->u.rt.peer);
        xfrm_dst_destroy(xdst);
 }