vserver 1.9.3
[linux-2.6.git] / net / ipv6 / udp.c
index 7133801..ff00dc4 100644 (file)
@@ -627,7 +627,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
        struct inet_opt *inet = inet_sk(sk);
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) msg->msg_name;
-       struct in6_addr *daddr;
+       struct in6_addr *daddr, *final_p = NULL, final;
        struct ipv6_txoptions *opt = NULL;
        struct ip6_flowlabel *flowlabel = NULL;
        struct flowi *fl = &inet->cork.fl;
@@ -783,7 +783,9 @@ do_udp_sendmsg:
        /* merge ip6_build_xmit from ip6_output */
        if (opt && opt->srcrt) {
                struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
+               ipv6_addr_copy(&final, &fl->fl6_dst);
                ipv6_addr_copy(&fl->fl6_dst, rt0->addr);
+               final_p = &final;
        }
 
        if (!fl->oif && ipv6_addr_is_multicast(&fl->fl6_dst))
@@ -792,6 +794,13 @@ do_udp_sendmsg:
        err = ip6_dst_lookup(sk, &dst, fl);
        if (err)
                goto out;
+       if (final_p)
+               ipv6_addr_copy(&fl->fl6_dst, final_p);
+
+       if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0) {
+               dst_release(dst);
+               goto out;
+       }
 
        if (hlimit < 0) {
                if (ipv6_addr_is_multicast(&fl->fl6_dst))
@@ -1037,6 +1046,7 @@ struct proto udpv6_prot = {
        .hash =         udp_v6_hash,
        .unhash =       udp_v6_unhash,
        .get_port =     udp_v6_get_port,
+       .slab_obj_size = sizeof(struct udp6_sock),
 };
 
 extern struct proto_ops inet6_dgram_ops;