Merge tag 'sound-fix-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[linux-drm-fsl-dcu.git] / net / ipv6 / ipv6_sockglue.c
index d1e2e8ef29c54abd86064728ec145f0478f360af..1c6ce3119ff8ce45f1b406c9b1356a2400f6fc1d 100644 (file)
@@ -174,7 +174,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
                        }
 
                        if (ipv6_only_sock(sk) ||
-                           !ipv6_addr_v4mapped(&np->daddr)) {
+                           !ipv6_addr_v4mapped(&sk->sk_v6_daddr)) {
                                retv = -EADDRNOTAVAIL;
                                break;
                        }
@@ -1011,7 +1011,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
                                struct in6_pktinfo src_info;
                                src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif :
                                        np->sticky_pktinfo.ipi6_ifindex;
-                               src_info.ipi6_addr = np->mcast_oif ? np->daddr : np->sticky_pktinfo.ipi6_addr;
+                               src_info.ipi6_addr = np->mcast_oif ? sk->sk_v6_daddr : np->sticky_pktinfo.ipi6_addr;
                                put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info);
                        }
                        if (np->rxopt.bits.rxhlim) {
@@ -1026,7 +1026,8 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
                                struct in6_pktinfo src_info;
                                src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif :
                                        np->sticky_pktinfo.ipi6_ifindex;
-                               src_info.ipi6_addr = np->mcast_oif ? np->daddr : np->sticky_pktinfo.ipi6_addr;
+                               src_info.ipi6_addr = np->mcast_oif ? sk->sk_v6_daddr :
+                                                                    np->sticky_pktinfo.ipi6_addr;
                                put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
                        }
                        if (np->rxopt.bits.rxohlim) {
@@ -1211,6 +1212,34 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
                val = np->sndflow;
                break;
 
+       case IPV6_FLOWLABEL_MGR:
+       {
+               struct in6_flowlabel_req freq;
+
+               if (len < sizeof(freq))
+                       return -EINVAL;
+
+               if (copy_from_user(&freq, optval, sizeof(freq)))
+                       return -EFAULT;
+
+               if (freq.flr_action != IPV6_FL_A_GET)
+                       return -EINVAL;
+
+               len = sizeof(freq);
+               memset(&freq, 0, sizeof(freq));
+
+               val = ipv6_flowlabel_opt_get(sk, &freq);
+               if (val < 0)
+                       return val;
+
+               if (put_user(len, optlen))
+                       return -EFAULT;
+               if (copy_to_user(optval, &freq, len))
+                       return -EFAULT;
+
+               return 0;
+       }
+
        case IPV6_ADDR_PREFERENCES:
                val = 0;