]> rtime.felk.cvut.cz Git - can-eth-gw-linux.git/blobdiff - net/ipv4/ipmr.c
ipv4: ipmr: various fixes and cleanups
[can-eth-gw-linux.git] / net / ipv4 / ipmr.c
index adf3d349566f0d12c506104f4bbeed3b9babdc12..0394a8e6d978e55dcf267e804c7d01cd268591d7 100644 (file)
@@ -1207,6 +1207,10 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
        struct net *net = sock_net(sk);
        struct mr_table *mrt;
 
+       if (sk->sk_type != SOCK_RAW ||
+           inet_sk(sk)->inet_num != IPPROTO_IGMP)
+               return -EOPNOTSUPP;
+
        mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT);
        if (mrt == NULL)
                return -ENOENT;
@@ -1219,11 +1223,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
 
        switch (optname) {
        case MRT_INIT:
-               if (sk->sk_type != SOCK_RAW ||
-                   inet_sk(sk)->inet_num != IPPROTO_IGMP)
-                       return -EOPNOTSUPP;
                if (optlen != sizeof(int))
-                       return -ENOPROTOOPT;
+                       return -EINVAL;
 
                rtnl_lock();
                if (rtnl_dereference(mrt->mroute_sk)) {
@@ -1284,9 +1285,11 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
        case MRT_ASSERT:
        {
                int v;
+               if (optlen != sizeof(v))
+                       return -EINVAL;
                if (get_user(v, (int __user *)optval))
                        return -EFAULT;
-               mrt->mroute_do_assert = (v) ? 1 : 0;
+               mrt->mroute_do_assert = !!v;
                return 0;
        }
 #ifdef CONFIG_IP_PIMSM
@@ -1294,9 +1297,11 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
        {
                int v;
 
+               if (optlen != sizeof(v))
+                       return -EINVAL;
                if (get_user(v, (int __user *)optval))
                        return -EFAULT;
-               v = (v) ? 1 : 0;
+               v = !!v;
 
                rtnl_lock();
                ret = 0;
@@ -1325,7 +1330,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
                } else {
                        if (!ipmr_new_table(net, v))
                                ret = -ENOMEM;
-                       raw_sk(sk)->ipmr_table = v;
+                       else
+                               raw_sk(sk)->ipmr_table = v;
                }
                rtnl_unlock();
                return ret;
@@ -1351,6 +1357,10 @@ int ip_mroute_getsockopt(struct sock *sk, int optname, char __user *optval, int
        struct net *net = sock_net(sk);
        struct mr_table *mrt;
 
+       if (sk->sk_type != SOCK_RAW ||
+           inet_sk(sk)->inet_num != IPPROTO_IGMP)
+               return -EOPNOTSUPP;
+
        mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT);
        if (mrt == NULL)
                return -ENOENT;