]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - net/ipv6/xfrm6_policy.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6
[karo-tx-linux.git] / net / ipv6 / xfrm6_policy.c
index 98c2fe449b3f1f0fe530668d59b6ab83b90d65e7..73cee2ec07e8ed22fcba162427ce91622e5d7f59 100644 (file)
@@ -34,6 +34,26 @@ static int xfrm6_dst_lookup(struct xfrm_dst **dst, struct flowi *fl)
        return err;
 }
 
+static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
+{
+       struct rt6_info *rt;
+       struct flowi fl_tunnel = {
+               .nl_u = {
+                       .ip6_u = {
+                               .daddr = *(struct in6_addr *)&daddr->a6,
+                       },
+               },
+       };
+
+       if (!xfrm6_dst_lookup((struct xfrm_dst **)&rt, &fl_tunnel)) {
+               ipv6_get_saddr(&rt->u.dst, (struct in6_addr *)&daddr->a6,
+                              (struct in6_addr *)&saddr->a6);
+               dst_release(&rt->u.dst);
+               return 0;
+       }
+       return -EHOSTUNREACH;
+}
+
 static struct dst_entry *
 __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
 {
@@ -53,7 +73,7 @@ __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
                                 xdst->u.rt6.rt6i_src.plen);
                if (ipv6_addr_equal(&xdst->u.rt6.rt6i_dst.addr, &fl_dst_prefix) &&
                    ipv6_addr_equal(&xdst->u.rt6.rt6i_src.addr, &fl_src_prefix) &&
-                   xfrm_bundle_ok(xdst, fl, AF_INET6,
+                   xfrm_bundle_ok(policy, xdst, fl, AF_INET6,
                                   (xdst->u.rt6.rt6i_dst.plen != 128 ||
                                    xdst->u.rt6.rt6i_src.plen != 128))) {
                        dst_clone(dst);
@@ -149,6 +169,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 
                xdst = (struct xfrm_dst *)dst1;
                xdst->route = &rt->u.dst;
+               xdst->genid = xfrm[i]->genid;
                if (rt->rt6i_node)
                        xdst->route_cookie = rt->rt6i_node->fn_sernum;
 
@@ -361,6 +382,7 @@ static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
        .family =               AF_INET6,
        .dst_ops =              &xfrm6_dst_ops,
        .dst_lookup =           xfrm6_dst_lookup,
+       .get_saddr =            xfrm6_get_saddr,
        .find_bundle =          __xfrm6_find_bundle,
        .bundle_create =        __xfrm6_bundle_create,
        .decode_session =       _decode_session6,