[NET]: {get|set}sockopt compatibility layer
This patch extends {get|set}sockopt compatibility layer in order to move protocol specific parts to their place and avoid huge universal net/compat.c file in the future. Signed-off-by: Dmitry Mishin <dim@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
c750360938
commit
3fdadf7d27
112
net/ipv6/raw.c
112
net/ipv6/raw.c
@@ -859,29 +859,12 @@ static int rawv6_geticmpfilter(struct sock *sk, int level, int optname,
|
||||
}
|
||||
|
||||
|
||||
static int rawv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int optlen)
|
||||
{
|
||||
struct raw6_sock *rp = raw6_sk(sk);
|
||||
int val;
|
||||
|
||||
switch(level) {
|
||||
case SOL_RAW:
|
||||
break;
|
||||
|
||||
case SOL_ICMPV6:
|
||||
if (inet_sk(sk)->num != IPPROTO_ICMPV6)
|
||||
return -EOPNOTSUPP;
|
||||
return rawv6_seticmpfilter(sk, level, optname, optval,
|
||||
optlen);
|
||||
case SOL_IPV6:
|
||||
if (optname == IPV6_CHECKSUM)
|
||||
break;
|
||||
default:
|
||||
return ipv6_setsockopt(sk, level, optname, optval,
|
||||
optlen);
|
||||
};
|
||||
|
||||
if (get_user(val, (int __user *)optval))
|
||||
return -EFAULT;
|
||||
|
||||
@@ -906,12 +889,9 @@ static int rawv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
}
|
||||
}
|
||||
|
||||
static int rawv6_getsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int __user *optlen)
|
||||
static int rawv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int optlen)
|
||||
{
|
||||
struct raw6_sock *rp = raw6_sk(sk);
|
||||
int val, len;
|
||||
|
||||
switch(level) {
|
||||
case SOL_RAW:
|
||||
break;
|
||||
@@ -919,15 +899,47 @@ static int rawv6_getsockopt(struct sock *sk, int level, int optname,
|
||||
case SOL_ICMPV6:
|
||||
if (inet_sk(sk)->num != IPPROTO_ICMPV6)
|
||||
return -EOPNOTSUPP;
|
||||
return rawv6_geticmpfilter(sk, level, optname, optval,
|
||||
return rawv6_seticmpfilter(sk, level, optname, optval,
|
||||
optlen);
|
||||
case SOL_IPV6:
|
||||
if (optname == IPV6_CHECKSUM)
|
||||
break;
|
||||
default:
|
||||
return ipv6_getsockopt(sk, level, optname, optval,
|
||||
return ipv6_setsockopt(sk, level, optname, optval,
|
||||
optlen);
|
||||
};
|
||||
return do_rawv6_setsockopt(sk, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static int compat_rawv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int optlen)
|
||||
{
|
||||
switch(level) {
|
||||
case SOL_RAW:
|
||||
break;
|
||||
|
||||
case SOL_ICMPV6:
|
||||
if (inet_sk(sk)->num != IPPROTO_ICMPV6)
|
||||
return -EOPNOTSUPP;
|
||||
return rawv6_seticmpfilter(sk, level, optname, optval,
|
||||
optlen);
|
||||
case SOL_IPV6:
|
||||
if (optname == IPV6_CHECKSUM)
|
||||
break;
|
||||
default:
|
||||
return compat_ipv6_setsockopt(sk, level,
|
||||
optname, optval, optlen);
|
||||
};
|
||||
return do_rawv6_setsockopt(sk, level, optname, optval, optlen);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int do_rawv6_getsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int __user *optlen)
|
||||
{
|
||||
struct raw6_sock *rp = raw6_sk(sk);
|
||||
int val, len;
|
||||
|
||||
if (get_user(len,optlen))
|
||||
return -EFAULT;
|
||||
@@ -953,6 +965,52 @@ static int rawv6_getsockopt(struct sock *sk, int level, int optname,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rawv6_getsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int __user *optlen)
|
||||
{
|
||||
switch(level) {
|
||||
case SOL_RAW:
|
||||
break;
|
||||
|
||||
case SOL_ICMPV6:
|
||||
if (inet_sk(sk)->num != IPPROTO_ICMPV6)
|
||||
return -EOPNOTSUPP;
|
||||
return rawv6_geticmpfilter(sk, level, optname, optval,
|
||||
optlen);
|
||||
case SOL_IPV6:
|
||||
if (optname == IPV6_CHECKSUM)
|
||||
break;
|
||||
default:
|
||||
return ipv6_getsockopt(sk, level, optname, optval,
|
||||
optlen);
|
||||
};
|
||||
return do_rawv6_getsockopt(sk, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static int compat_rawv6_getsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int __user *optlen)
|
||||
{
|
||||
switch(level) {
|
||||
case SOL_RAW:
|
||||
break;
|
||||
|
||||
case SOL_ICMPV6:
|
||||
if (inet_sk(sk)->num != IPPROTO_ICMPV6)
|
||||
return -EOPNOTSUPP;
|
||||
return rawv6_geticmpfilter(sk, level, optname, optval,
|
||||
optlen);
|
||||
case SOL_IPV6:
|
||||
if (optname == IPV6_CHECKSUM)
|
||||
break;
|
||||
default:
|
||||
return compat_ipv6_getsockopt(sk, level,
|
||||
optname, optval, optlen);
|
||||
};
|
||||
return do_rawv6_getsockopt(sk, level, optname, optval, optlen);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg)
|
||||
{
|
||||
switch(cmd) {
|
||||
@@ -1008,6 +1066,10 @@ struct proto rawv6_prot = {
|
||||
.destroy = inet6_destroy_sock,
|
||||
.setsockopt = rawv6_setsockopt,
|
||||
.getsockopt = rawv6_getsockopt,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_setsockopt = compat_rawv6_setsockopt,
|
||||
.compat_getsockopt = compat_rawv6_getsockopt,
|
||||
#endif
|
||||
.sendmsg = rawv6_sendmsg,
|
||||
.recvmsg = rawv6_recvmsg,
|
||||
.bind = rawv6_bind,
|
||||
|
Reference in New Issue
Block a user