case MCAST_LEAVE_SOURCE_GROUP:
        case MCAST_BLOCK_SOURCE:
        case MCAST_UNBLOCK_SOURCE:
-               return compat_mc_setsockopt(sk, level, optname, optval, optlen,
-                       ip_setsockopt);
+       {
+               struct compat_group_source_req __user *gsr32 = (void __user *)optval;
+               struct group_source_req greqs;
+
+               if (optlen != sizeof(struct compat_group_source_req))
+                       return -EINVAL;
+
+               if (get_user(greqs.gsr_interface, &gsr32->gsr_interface) ||
+                   copy_from_user(&greqs.gsr_group, &gsr32->gsr_group,
+                               sizeof(greqs.gsr_group)) ||
+                   copy_from_user(&greqs.gsr_source, &gsr32->gsr_source,
+                               sizeof(greqs.gsr_source)))
+                       return -EFAULT;
+
+               rtnl_lock();
+               lock_sock(sk);
+               err = do_mcast_group_source(sk, optname, &greqs);
+               release_sock(sk);
+               rtnl_unlock();
+               return err;
+       }
        case MCAST_MSFILTER:
        {
                const int size0 = offsetof(struct compat_group_filter, gf_slist);
 
        case MCAST_LEAVE_SOURCE_GROUP:
        case MCAST_BLOCK_SOURCE:
        case MCAST_UNBLOCK_SOURCE:
-               return compat_mc_setsockopt(sk, level, optname, optval, optlen,
-                       ipv6_setsockopt);
+       {
+               struct compat_group_source_req __user *gsr32 = (void __user *)optval;
+               struct group_source_req greqs;
+
+               if (optlen < sizeof(struct compat_group_source_req))
+                       return -EINVAL;
+
+               if (get_user(greqs.gsr_interface, &gsr32->gsr_interface) ||
+                   copy_from_user(&greqs.gsr_group, &gsr32->gsr_group,
+                               sizeof(greqs.gsr_group)) ||
+                   copy_from_user(&greqs.gsr_source, &gsr32->gsr_source,
+                               sizeof(greqs.gsr_source)))
+                       return -EFAULT;
+
+               rtnl_lock();
+               lock_sock(sk);
+               err = do_ipv6_mcast_group_source(sk, optname, &greqs);
+               release_sock(sk);
+               rtnl_unlock();
+               return err;
+       }
        case MCAST_MSFILTER:
        {
                const int size0 = offsetof(struct compat_group_filter, gf_slist);