]> err.no Git - linux-2.6/blobdiff - net/ipv6/xfrm6_state.c
Pull acpi_device_handle_cleanup into release branch
[linux-2.6] / net / ipv6 / xfrm6_state.c
index bf0d0abc3871b64cccd967f881febcfd0b298396..b33296b3f6de5ddd25a818ba6ae306444770cfe8 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/pfkeyv2.h>
 #include <linux/ipsec.h>
 #include <net/ipv6.h>
+#include <net/addrconf.h>
 
 static struct xfrm_state_afinfo xfrm6_state_afinfo;
 
@@ -41,6 +42,22 @@ __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl,
        memcpy(&x->props.saddr, &tmpl->saddr, sizeof(x->props.saddr));
        if (ipv6_addr_any((struct in6_addr*)&x->props.saddr))
                memcpy(&x->props.saddr, saddr, sizeof(x->props.saddr));
+       if (tmpl->mode && ipv6_addr_any((struct in6_addr*)&x->props.saddr)) {
+               struct rt6_info *rt;
+               struct flowi fl_tunnel = {
+                       .nl_u = {
+                               .ip6_u = {
+                                       .daddr = *(struct in6_addr *)daddr,
+                               }
+                       }
+               };
+               if (!xfrm_dst_lookup((struct xfrm_dst **)&rt,
+                                    &fl_tunnel, AF_INET6)) {
+                       ipv6_get_saddr(&rt->u.dst, (struct in6_addr *)daddr,
+                                      (struct in6_addr *)&x->props.saddr);
+                       dst_release(&rt->u.dst);
+               }
+       }
        x->props.mode = tmpl->mode;
        x->props.reqid = tmpl->reqid;
        x->props.family = AF_INET6;
@@ -118,7 +135,6 @@ __xfrm6_find_acq(u8 mode, u32 reqid, u8 proto,
 
 static struct xfrm_state_afinfo xfrm6_state_afinfo = {
        .family                 = AF_INET6,
-       .lock                   = RW_LOCK_UNLOCKED,
        .init_tempsel           = __xfrm6_init_tempsel,
        .state_lookup           = __xfrm6_state_lookup,
        .find_acq               = __xfrm6_find_acq,