mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
[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 <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
parent
c750360938
commit
3fdadf7d27
29 changed files with 928 additions and 139 deletions
|
|
@ -470,6 +470,10 @@ const struct proto_ops inet6_stream_ops = {
|
|||
.shutdown = inet_shutdown, /* ok */
|
||||
.setsockopt = sock_common_setsockopt, /* ok */
|
||||
.getsockopt = sock_common_getsockopt, /* ok */
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_setsockopt = compat_sock_common_setsockopt,
|
||||
.compat_getsockopt = compat_sock_common_getsockopt,
|
||||
#endif
|
||||
.sendmsg = inet_sendmsg, /* ok */
|
||||
.recvmsg = sock_common_recvmsg, /* ok */
|
||||
.mmap = sock_no_mmap,
|
||||
|
|
@ -491,6 +495,10 @@ const struct proto_ops inet6_dgram_ops = {
|
|||
.shutdown = inet_shutdown, /* ok */
|
||||
.setsockopt = sock_common_setsockopt, /* ok */
|
||||
.getsockopt = sock_common_getsockopt, /* ok */
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_setsockopt = compat_sock_common_setsockopt,
|
||||
.compat_getsockopt = compat_sock_common_getsockopt,
|
||||
#endif
|
||||
.sendmsg = inet_sendmsg, /* ok */
|
||||
.recvmsg = sock_common_recvmsg, /* ok */
|
||||
.mmap = sock_no_mmap,
|
||||
|
|
@ -519,6 +527,10 @@ static const struct proto_ops inet6_sockraw_ops = {
|
|||
.shutdown = inet_shutdown, /* ok */
|
||||
.setsockopt = sock_common_setsockopt, /* ok */
|
||||
.getsockopt = sock_common_getsockopt, /* ok */
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_setsockopt = compat_sock_common_setsockopt,
|
||||
.compat_getsockopt = compat_sock_common_getsockopt,
|
||||
#endif
|
||||
.sendmsg = inet_sendmsg, /* ok */
|
||||
.recvmsg = sock_common_recvmsg, /* ok */
|
||||
.mmap = sock_no_mmap,
|
||||
|
|
|
|||
|
|
@ -109,19 +109,13 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *))
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int optlen)
|
||||
{
|
||||
struct ipv6_pinfo *np = inet6_sk(sk);
|
||||
int val, valbool;
|
||||
int retv = -ENOPROTOOPT;
|
||||
|
||||
if (level == SOL_IP && sk->sk_type != SOCK_RAW)
|
||||
return udp_prot.setsockopt(sk, level, optname, optval, optlen);
|
||||
|
||||
if(level!=SOL_IPV6)
|
||||
goto out;
|
||||
|
||||
if (optval == NULL)
|
||||
val=0;
|
||||
else if (get_user(val, (int __user *) optval))
|
||||
|
|
@ -613,17 +607,9 @@ done:
|
|||
retv = xfrm_user_policy(sk, optname, optval, optlen);
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_NETFILTER
|
||||
default:
|
||||
retv = nf_setsockopt(sk, PF_INET6, optname, optval,
|
||||
optlen);
|
||||
break;
|
||||
#endif
|
||||
|
||||
}
|
||||
release_sock(sk);
|
||||
|
||||
out:
|
||||
return retv;
|
||||
|
||||
e_inval:
|
||||
|
|
@ -631,6 +617,65 @@ e_inval:
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
int ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int optlen)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (level == SOL_IP && sk->sk_type != SOCK_RAW)
|
||||
return udp_prot.setsockopt(sk, level, optname, optval, optlen);
|
||||
|
||||
if (level != SOL_IPV6)
|
||||
return -ENOPROTOOPT;
|
||||
|
||||
err = do_ipv6_setsockopt(sk, level, optname, optval, optlen);
|
||||
#ifdef CONFIG_NETFILTER
|
||||
/* we need to exclude all possible ENOPROTOOPTs except default case */
|
||||
if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY &&
|
||||
optname != IPV6_XFRM_POLICY) {
|
||||
lock_sock(sk);
|
||||
err = nf_setsockopt(sk, PF_INET6, optname, optval,
|
||||
optlen);
|
||||
release_sock(sk);
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
int compat_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int optlen)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (level == SOL_IP && sk->sk_type != SOCK_RAW) {
|
||||
if (udp_prot.compat_setsockopt)
|
||||
return udp_prot.compat_setsockopt(sk, level,
|
||||
optname, optval, optlen);
|
||||
else
|
||||
return udp_prot.setsockopt(sk, level,
|
||||
optname, optval, optlen);
|
||||
}
|
||||
|
||||
if (level != SOL_IPV6)
|
||||
return -ENOPROTOOPT;
|
||||
|
||||
err = do_ipv6_setsockopt(sk, level, optname, optval, optlen);
|
||||
#ifdef CONFIG_NETFILTER
|
||||
/* we need to exclude all possible ENOPROTOOPTs except default case */
|
||||
if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY &&
|
||||
optname != IPV6_XFRM_POLICY) {
|
||||
lock_sock(sk);
|
||||
err = compat_nf_setsockopt(sk, PF_INET6, optname, optval,
|
||||
optlen);
|
||||
release_sock(sk);
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr,
|
||||
char __user *optval, int len)
|
||||
{
|
||||
|
|
@ -642,17 +687,13 @@ static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr,
|
|||
return len;
|
||||
}
|
||||
|
||||
int ipv6_getsockopt(struct sock *sk, int level, int optname,
|
||||
static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int __user *optlen)
|
||||
{
|
||||
struct ipv6_pinfo *np = inet6_sk(sk);
|
||||
int len;
|
||||
int val;
|
||||
|
||||
if (level == SOL_IP && sk->sk_type != SOCK_RAW)
|
||||
return udp_prot.getsockopt(sk, level, optname, optval, optlen);
|
||||
if(level!=SOL_IPV6)
|
||||
return -ENOPROTOOPT;
|
||||
if (get_user(len, optlen))
|
||||
return -EFAULT;
|
||||
switch (optname) {
|
||||
|
|
@ -842,17 +883,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
|
|||
break;
|
||||
|
||||
default:
|
||||
#ifdef CONFIG_NETFILTER
|
||||
lock_sock(sk);
|
||||
val = nf_getsockopt(sk, PF_INET6, optname, optval,
|
||||
&len);
|
||||
release_sock(sk);
|
||||
if (val >= 0)
|
||||
val = put_user(len, optlen);
|
||||
return val;
|
||||
#else
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
len = min_t(unsigned int, sizeof(int), len);
|
||||
if(put_user(len, optlen))
|
||||
|
|
@ -862,6 +893,78 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ipv6_getsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int __user *optlen)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (level == SOL_IP && sk->sk_type != SOCK_RAW)
|
||||
return udp_prot.getsockopt(sk, level, optname, optval, optlen);
|
||||
|
||||
if(level != SOL_IPV6)
|
||||
return -ENOPROTOOPT;
|
||||
|
||||
err = do_ipv6_getsockopt(sk, level, optname, optval, optlen);
|
||||
#ifdef CONFIG_NETFILTER
|
||||
/* we need to exclude all possible EINVALs except default case */
|
||||
if (err == -ENOPROTOOPT && optname != IPV6_ADDRFORM &&
|
||||
optname != MCAST_MSFILTER) {
|
||||
int len;
|
||||
|
||||
if (get_user(len, optlen))
|
||||
return -EFAULT;
|
||||
|
||||
lock_sock(sk);
|
||||
err = nf_getsockopt(sk, PF_INET6, optname, optval,
|
||||
&len);
|
||||
release_sock(sk);
|
||||
if (err >= 0)
|
||||
err = put_user(len, optlen);
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int __user *optlen)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (level == SOL_IP && sk->sk_type != SOCK_RAW) {
|
||||
if (udp_prot.compat_getsockopt)
|
||||
return udp_prot.compat_getsockopt(sk, level,
|
||||
optname, optval, optlen);
|
||||
else
|
||||
return udp_prot.getsockopt(sk, level,
|
||||
optname, optval, optlen);
|
||||
}
|
||||
|
||||
if(level != SOL_IPV6)
|
||||
return -ENOPROTOOPT;
|
||||
|
||||
err = do_ipv6_getsockopt(sk, level, optname, optval, optlen);
|
||||
#ifdef CONFIG_NETFILTER
|
||||
/* we need to exclude all possible EINVALs except default case */
|
||||
if (err == -ENOPROTOOPT && optname != IPV6_ADDRFORM &&
|
||||
optname != MCAST_MSFILTER) {
|
||||
int len;
|
||||
|
||||
if (get_user(len, optlen))
|
||||
return -EFAULT;
|
||||
|
||||
lock_sock(sk);
|
||||
err = compat_nf_getsockopt(sk, PF_INET6, optname, optval,
|
||||
&len);
|
||||
release_sock(sk);
|
||||
if (err >= 0)
|
||||
err = put_user(len, optlen);
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
void __init ipv6_packet_init(void)
|
||||
{
|
||||
dev_add_pack(&ipv6_packet_type);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@ EXPORT_SYMBOL(ip6_route_output);
|
|||
EXPORT_SYMBOL(addrconf_lock);
|
||||
EXPORT_SYMBOL(ipv6_setsockopt);
|
||||
EXPORT_SYMBOL(ipv6_getsockopt);
|
||||
#ifdef CONFIG_COMPAT
|
||||
EXPORT_SYMBOL(compat_ipv6_setsockopt);
|
||||
EXPORT_SYMBOL(compat_ipv6_getsockopt);
|
||||
#endif
|
||||
EXPORT_SYMBOL(inet6_register_protosw);
|
||||
EXPORT_SYMBOL(inet6_unregister_protosw);
|
||||
EXPORT_SYMBOL(inet6_add_protocol);
|
||||
|
|
|
|||
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,
|
||||
|
|
|
|||
|
|
@ -1308,6 +1308,10 @@ static struct inet_connection_sock_af_ops ipv6_specific = {
|
|||
|
||||
.setsockopt = ipv6_setsockopt,
|
||||
.getsockopt = ipv6_getsockopt,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_setsockopt = compat_ipv6_setsockopt,
|
||||
.compat_getsockopt = compat_ipv6_getsockopt,
|
||||
#endif
|
||||
.addr2sockaddr = inet6_csk_addr2sockaddr,
|
||||
.sockaddr_len = sizeof(struct sockaddr_in6)
|
||||
};
|
||||
|
|
@ -1327,6 +1331,10 @@ static struct inet_connection_sock_af_ops ipv6_mapped = {
|
|||
|
||||
.setsockopt = ipv6_setsockopt,
|
||||
.getsockopt = ipv6_getsockopt,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_setsockopt = compat_ipv6_setsockopt,
|
||||
.compat_getsockopt = compat_ipv6_getsockopt,
|
||||
#endif
|
||||
.addr2sockaddr = inet6_csk_addr2sockaddr,
|
||||
.sockaddr_len = sizeof(struct sockaddr_in6)
|
||||
};
|
||||
|
|
@ -1566,6 +1574,10 @@ struct proto tcpv6_prot = {
|
|||
.shutdown = tcp_shutdown,
|
||||
.setsockopt = tcp_setsockopt,
|
||||
.getsockopt = tcp_getsockopt,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_setsockopt = compat_tcp_setsockopt,
|
||||
.compat_getsockopt = compat_tcp_getsockopt,
|
||||
#endif
|
||||
.sendmsg = tcp_sendmsg,
|
||||
.recvmsg = tcp_recvmsg,
|
||||
.backlog_rcv = tcp_v6_do_rcv,
|
||||
|
|
|
|||
|
|
@ -880,16 +880,13 @@ static int udpv6_destroy_sock(struct sock *sk)
|
|||
/*
|
||||
* Socket option code for UDP
|
||||
*/
|
||||
static int udpv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
static int do_udpv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int optlen)
|
||||
{
|
||||
struct udp_sock *up = udp_sk(sk);
|
||||
int val;
|
||||
int err = 0;
|
||||
|
||||
if (level != SOL_UDP)
|
||||
return ipv6_setsockopt(sk, level, optname, optval, optlen);
|
||||
|
||||
if(optlen<sizeof(int))
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -927,15 +924,31 @@ static int udpv6_setsockopt(struct sock *sk, int level, int optname,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int udpv6_getsockopt(struct sock *sk, int level, int optname,
|
||||
static int udpv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int optlen)
|
||||
{
|
||||
if (level != SOL_UDP)
|
||||
return ipv6_setsockopt(sk, level, optname, optval, optlen);
|
||||
return do_udpv6_setsockopt(sk, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static int compat_udpv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int optlen)
|
||||
{
|
||||
if (level != SOL_UDP)
|
||||
return compat_ipv6_setsockopt(sk, level,
|
||||
optname, optval, optlen);
|
||||
return do_udpv6_setsockopt(sk, level, optname, optval, optlen);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int do_udpv6_getsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int __user *optlen)
|
||||
{
|
||||
struct udp_sock *up = udp_sk(sk);
|
||||
int val, len;
|
||||
|
||||
if (level != SOL_UDP)
|
||||
return ipv6_getsockopt(sk, level, optname, optval, optlen);
|
||||
|
||||
if(get_user(len,optlen))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
@ -964,6 +977,25 @@ static int udpv6_getsockopt(struct sock *sk, int level, int optname,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int udpv6_getsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int __user *optlen)
|
||||
{
|
||||
if (level != SOL_UDP)
|
||||
return ipv6_getsockopt(sk, level, optname, optval, optlen);
|
||||
return do_udpv6_getsockopt(sk, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int __user *optlen)
|
||||
{
|
||||
if (level != SOL_UDP)
|
||||
return compat_ipv6_getsockopt(sk, level,
|
||||
optname, optval, optlen);
|
||||
return do_udpv6_getsockopt(sk, level, optname, optval, optlen);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct inet6_protocol udpv6_protocol = {
|
||||
.handler = udpv6_rcv,
|
||||
.err_handler = udpv6_err,
|
||||
|
|
@ -1046,6 +1078,10 @@ struct proto udpv6_prot = {
|
|||
.destroy = udpv6_destroy_sock,
|
||||
.setsockopt = udpv6_setsockopt,
|
||||
.getsockopt = udpv6_getsockopt,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_setsockopt = compat_udpv6_setsockopt,
|
||||
.compat_getsockopt = compat_udpv6_getsockopt,
|
||||
#endif
|
||||
.sendmsg = udpv6_sendmsg,
|
||||
.recvmsg = udpv6_recvmsg,
|
||||
.backlog_rcv = udpv6_queue_rcv_skb,
|
||||
|
|
|
|||
Loading…
Reference in a new issue