vserver 1.9.5.x5
[linux-2.6.git] / net / ipv6 / datagram.c
index 8b1cf3e..65b9375 100644 (file)
@@ -36,9 +36,9 @@
 int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
        struct sockaddr_in6     *usin = (struct sockaddr_in6 *) uaddr;
-       struct inet_opt         *inet = inet_sk(sk);
+       struct inet_sock        *inet = inet_sk(sk);
        struct ipv6_pinfo       *np = inet6_sk(sk);
-       struct in6_addr         *daddr;
+       struct in6_addr         *daddr, *final_p = NULL, final;
        struct dst_entry        *dst;
        struct flowi            fl;
        struct ip6_flowlabel    *flowlabel = NULL;
@@ -157,16 +157,27 @@ ipv4_connected:
        if (flowlabel) {
                if (flowlabel->opt && flowlabel->opt->srcrt) {
                        struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt;
+                       ipv6_addr_copy(&final, &fl.fl6_dst);
                        ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+                       final_p = &final;
                }
        } else if (np->opt && np->opt->srcrt) {
                struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
+               ipv6_addr_copy(&final, &fl.fl6_dst);
                ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+               final_p = &final;
        }
 
        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;
+       }
 
        /* source address lookup done in ip6_dst_lookup */
 
@@ -179,7 +190,7 @@ ipv4_connected:
        }
 
        ip6_dst_store(sk, dst,
-                     !ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ?
+                     ipv6_addr_equal(&fl.fl6_dst, &np->daddr) ?
                      &np->daddr : NULL);
 
        sk->sk_state = TCP_ESTABLISHED;
@@ -324,7 +335,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
                        if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
                                sin->sin6_scope_id = IP6CB(skb)->iif;
                } else {
-                       struct inet_opt *inet = inet_sk(sk);
+                       struct inet_sock *inet = inet_sk(sk);
 
                        ipv6_addr_set(&sin->sin6_addr, 0, 0,
                                      htonl(0xffff),
@@ -416,9 +427,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
                int addr_type;
                struct net_device *dev = NULL;
 
-               if (cmsg->cmsg_len < sizeof(struct cmsghdr) ||
-                   (unsigned long)(((char*)cmsg - (char*)msg->msg_control)
-                                   + cmsg->cmsg_len) > msg->msg_controllen) {
+               if (!CMSG_OK(msg, cmsg)) {
                        err = -EINVAL;
                        goto exit_f;
                }