]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/ipv6/datagram.c
Merge branches 'pm-core', 'pm-qos', 'pm-domains' and 'pm-opp'
[linux.git] / net / ipv6 / datagram.c
index ccf40550c475d31bcbc0565daa4a81428e5c9c58..eec27f87efaca15133cf1d5225e37e6a2f6a6f8a 100644 (file)
@@ -33,7 +33,7 @@
 #include <net/dsfield.h>
 
 #include <linux/errqueue.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 static bool ipv6_mapped_addr_any(const struct in6_addr *a)
 {
@@ -54,6 +54,7 @@ static void ip6_datagram_flow_key_init(struct flowi6 *fl6, struct sock *sk)
        fl6->fl6_dport = inet->inet_dport;
        fl6->fl6_sport = inet->inet_sport;
        fl6->flowlabel = np->flow_label;
+       fl6->flowi6_uid = sk->sk_uid;
 
        if (!fl6->flowi6_oif)
                fl6->flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
@@ -166,18 +167,22 @@ int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr,
        if (np->sndflow)
                fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
 
-       addr_type = ipv6_addr_type(&usin->sin6_addr);
-
-       if (addr_type == IPV6_ADDR_ANY) {
+       if (ipv6_addr_any(&usin->sin6_addr)) {
                /*
                 *      connect to self
                 */
-               usin->sin6_addr.s6_addr[15] = 0x01;
+               if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr))
+                       ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK),
+                                              &usin->sin6_addr);
+               else
+                       usin->sin6_addr = in6addr_loopback;
        }
 
+       addr_type = ipv6_addr_type(&usin->sin6_addr);
+
        daddr = &usin->sin6_addr;
 
-       if (addr_type == IPV6_ADDR_MAPPED) {
+       if (addr_type & IPV6_ADDR_MAPPED) {
                struct sockaddr_in sin;
 
                if (__ipv6_only_sock(sk)) {
@@ -700,7 +705,7 @@ void ip6_datagram_recv_specific_ctl(struct sock *sk, struct msghdr *msg,
                struct sockaddr_in6 sin6;
                __be16 *ports = (__be16 *) skb_transport_header(skb);
 
-               if (skb_transport_offset(skb) + 4 <= skb->len) {
+               if (skb_transport_offset(skb) + 4 <= (int)skb->len) {
                        /* All current transport protocols have the port numbers in the
                         * first four bytes of the transport header and this function is
                         * written with this assumption in mind.
@@ -717,6 +722,11 @@ void ip6_datagram_recv_specific_ctl(struct sock *sk, struct msghdr *msg,
                        put_cmsg(msg, SOL_IPV6, IPV6_ORIGDSTADDR, sizeof(sin6), &sin6);
                }
        }
+       if (np->rxopt.bits.recvfragsize && opt->frag_max_size) {
+               int val = opt->frag_max_size;
+
+               put_cmsg(msg, SOL_IPV6, IPV6_RECVFRAGSIZE, sizeof(val), &val);
+       }
 }
 
 void ip6_datagram_recv_ctl(struct sock *sk, struct msghdr *msg,