diff options
author | Dmitry Mishin <dim@openvz.org> | 2006-03-21 01:45:21 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-03-21 01:45:21 -0500 |
commit | 3fdadf7d27e3fbcf72930941884387d1f4936f04 (patch) | |
tree | 167072cf1e60b6b307610563614b435ff0caa52d /net/ipv6 | |
parent | c750360938b403e6cc193d293cfbcb099dd6c60e (diff) |
[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>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/af_inet6.c | 12 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 163 | ||||
-rw-r--r-- | net/ipv6/ipv6_syms.c | 4 | ||||
-rw-r--r-- | net/ipv6/raw.c | 112 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 12 | ||||
-rw-r--r-- | net/ipv6/udp.c | 52 |
6 files changed, 292 insertions, 63 deletions
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 6c9711ac1c03..97844c4cd9b1 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -470,6 +470,10 @@ const struct proto_ops inet6_stream_ops = { | |||
470 | .shutdown = inet_shutdown, /* ok */ | 470 | .shutdown = inet_shutdown, /* ok */ |
471 | .setsockopt = sock_common_setsockopt, /* ok */ | 471 | .setsockopt = sock_common_setsockopt, /* ok */ |
472 | .getsockopt = sock_common_getsockopt, /* ok */ | 472 | .getsockopt = sock_common_getsockopt, /* ok */ |
473 | #ifdef CONFIG_COMPAT | ||
474 | .compat_setsockopt = compat_sock_common_setsockopt, | ||
475 | .compat_getsockopt = compat_sock_common_getsockopt, | ||
476 | #endif | ||
473 | .sendmsg = inet_sendmsg, /* ok */ | 477 | .sendmsg = inet_sendmsg, /* ok */ |
474 | .recvmsg = sock_common_recvmsg, /* ok */ | 478 | .recvmsg = sock_common_recvmsg, /* ok */ |
475 | .mmap = sock_no_mmap, | 479 | .mmap = sock_no_mmap, |
@@ -491,6 +495,10 @@ const struct proto_ops inet6_dgram_ops = { | |||
491 | .shutdown = inet_shutdown, /* ok */ | 495 | .shutdown = inet_shutdown, /* ok */ |
492 | .setsockopt = sock_common_setsockopt, /* ok */ | 496 | .setsockopt = sock_common_setsockopt, /* ok */ |
493 | .getsockopt = sock_common_getsockopt, /* ok */ | 497 | .getsockopt = sock_common_getsockopt, /* ok */ |
498 | #ifdef CONFIG_COMPAT | ||
499 | .compat_setsockopt = compat_sock_common_setsockopt, | ||
500 | .compat_getsockopt = compat_sock_common_getsockopt, | ||
501 | #endif | ||
494 | .sendmsg = inet_sendmsg, /* ok */ | 502 | .sendmsg = inet_sendmsg, /* ok */ |
495 | .recvmsg = sock_common_recvmsg, /* ok */ | 503 | .recvmsg = sock_common_recvmsg, /* ok */ |
496 | .mmap = sock_no_mmap, | 504 | .mmap = sock_no_mmap, |
@@ -519,6 +527,10 @@ static const struct proto_ops inet6_sockraw_ops = { | |||
519 | .shutdown = inet_shutdown, /* ok */ | 527 | .shutdown = inet_shutdown, /* ok */ |
520 | .setsockopt = sock_common_setsockopt, /* ok */ | 528 | .setsockopt = sock_common_setsockopt, /* ok */ |
521 | .getsockopt = sock_common_getsockopt, /* ok */ | 529 | .getsockopt = sock_common_getsockopt, /* ok */ |
530 | #ifdef CONFIG_COMPAT | ||
531 | .compat_setsockopt = compat_sock_common_setsockopt, | ||
532 | .compat_getsockopt = compat_sock_common_getsockopt, | ||
533 | #endif | ||
522 | .sendmsg = inet_sendmsg, /* ok */ | 534 | .sendmsg = inet_sendmsg, /* ok */ |
523 | .recvmsg = sock_common_recvmsg, /* ok */ | 535 | .recvmsg = sock_common_recvmsg, /* ok */ |
524 | .mmap = sock_no_mmap, | 536 | .mmap = sock_no_mmap, |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index f7142ba519ab..988eac58e9d1 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -109,19 +109,13 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *)) | |||
109 | return 0; | 109 | return 0; |
110 | } | 110 | } |
111 | 111 | ||
112 | int ipv6_setsockopt(struct sock *sk, int level, int optname, | 112 | static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, |
113 | char __user *optval, int optlen) | 113 | char __user *optval, int optlen) |
114 | { | 114 | { |
115 | struct ipv6_pinfo *np = inet6_sk(sk); | 115 | struct ipv6_pinfo *np = inet6_sk(sk); |
116 | int val, valbool; | 116 | int val, valbool; |
117 | int retv = -ENOPROTOOPT; | 117 | int retv = -ENOPROTOOPT; |
118 | 118 | ||
119 | if (level == SOL_IP && sk->sk_type != SOCK_RAW) | ||
120 | return udp_prot.setsockopt(sk, level, optname, optval, optlen); | ||
121 | |||
122 | if(level!=SOL_IPV6) | ||
123 | goto out; | ||
124 | |||
125 | if (optval == NULL) | 119 | if (optval == NULL) |
126 | val=0; | 120 | val=0; |
127 | else if (get_user(val, (int __user *) optval)) | 121 | else if (get_user(val, (int __user *) optval)) |
@@ -613,17 +607,9 @@ done: | |||
613 | retv = xfrm_user_policy(sk, optname, optval, optlen); | 607 | retv = xfrm_user_policy(sk, optname, optval, optlen); |
614 | break; | 608 | break; |
615 | 609 | ||
616 | #ifdef CONFIG_NETFILTER | ||
617 | default: | ||
618 | retv = nf_setsockopt(sk, PF_INET6, optname, optval, | ||
619 | optlen); | ||
620 | break; | ||
621 | #endif | ||
622 | |||
623 | } | 610 | } |
624 | release_sock(sk); | 611 | release_sock(sk); |
625 | 612 | ||
626 | out: | ||
627 | return retv; | 613 | return retv; |
628 | 614 | ||
629 | e_inval: | 615 | e_inval: |
@@ -631,6 +617,65 @@ e_inval: | |||
631 | return -EINVAL; | 617 | return -EINVAL; |
632 | } | 618 | } |
633 | 619 | ||
620 | int ipv6_setsockopt(struct sock *sk, int level, int optname, | ||
621 | char __user *optval, int optlen) | ||
622 | { | ||
623 | int err; | ||
624 | |||
625 | if (level == SOL_IP && sk->sk_type != SOCK_RAW) | ||
626 | return udp_prot.setsockopt(sk, level, optname, optval, optlen); | ||
627 | |||
628 | if (level != SOL_IPV6) | ||
629 | return -ENOPROTOOPT; | ||
630 | |||
631 | err = do_ipv6_setsockopt(sk, level, optname, optval, optlen); | ||
632 | #ifdef CONFIG_NETFILTER | ||
633 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | ||
634 | if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY && | ||
635 | optname != IPV6_XFRM_POLICY) { | ||
636 | lock_sock(sk); | ||
637 | err = nf_setsockopt(sk, PF_INET6, optname, optval, | ||
638 | optlen); | ||
639 | release_sock(sk); | ||
640 | } | ||
641 | #endif | ||
642 | return err; | ||
643 | } | ||
644 | |||
645 | |||
646 | #ifdef CONFIG_COMPAT | ||
647 | int compat_ipv6_setsockopt(struct sock *sk, int level, int optname, | ||
648 | char __user *optval, int optlen) | ||
649 | { | ||
650 | int err; | ||
651 | |||
652 | if (level == SOL_IP && sk->sk_type != SOCK_RAW) { | ||
653 | if (udp_prot.compat_setsockopt) | ||
654 | return udp_prot.compat_setsockopt(sk, level, | ||
655 | optname, optval, optlen); | ||
656 | else | ||
657 | return udp_prot.setsockopt(sk, level, | ||
658 | optname, optval, optlen); | ||
659 | } | ||
660 | |||
661 | if (level != SOL_IPV6) | ||
662 | return -ENOPROTOOPT; | ||
663 | |||
664 | err = do_ipv6_setsockopt(sk, level, optname, optval, optlen); | ||
665 | #ifdef CONFIG_NETFILTER | ||
666 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | ||
667 | if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY && | ||
668 | optname != IPV6_XFRM_POLICY) { | ||
669 | lock_sock(sk); | ||
670 | err = compat_nf_setsockopt(sk, PF_INET6, optname, optval, | ||
671 | optlen); | ||
672 | release_sock(sk); | ||
673 | } | ||
674 | #endif | ||
675 | return err; | ||
676 | } | ||
677 | #endif | ||
678 | |||
634 | static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr, | 679 | static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr, |
635 | char __user *optval, int len) | 680 | char __user *optval, int len) |
636 | { | 681 | { |
@@ -642,17 +687,13 @@ static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr, | |||
642 | return len; | 687 | return len; |
643 | } | 688 | } |
644 | 689 | ||
645 | int ipv6_getsockopt(struct sock *sk, int level, int optname, | 690 | static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, |
646 | char __user *optval, int __user *optlen) | 691 | char __user *optval, int __user *optlen) |
647 | { | 692 | { |
648 | struct ipv6_pinfo *np = inet6_sk(sk); | 693 | struct ipv6_pinfo *np = inet6_sk(sk); |
649 | int len; | 694 | int len; |
650 | int val; | 695 | int val; |
651 | 696 | ||
652 | if (level == SOL_IP && sk->sk_type != SOCK_RAW) | ||
653 | return udp_prot.getsockopt(sk, level, optname, optval, optlen); | ||
654 | if(level!=SOL_IPV6) | ||
655 | return -ENOPROTOOPT; | ||
656 | if (get_user(len, optlen)) | 697 | if (get_user(len, optlen)) |
657 | return -EFAULT; | 698 | return -EFAULT; |
658 | switch (optname) { | 699 | switch (optname) { |
@@ -842,17 +883,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
842 | break; | 883 | break; |
843 | 884 | ||
844 | default: | 885 | default: |
845 | #ifdef CONFIG_NETFILTER | ||
846 | lock_sock(sk); | ||
847 | val = nf_getsockopt(sk, PF_INET6, optname, optval, | ||
848 | &len); | ||
849 | release_sock(sk); | ||
850 | if (val >= 0) | ||
851 | val = put_user(len, optlen); | ||
852 | return val; | ||
853 | #else | ||
854 | return -EINVAL; | 886 | return -EINVAL; |
855 | #endif | ||
856 | } | 887 | } |
857 | len = min_t(unsigned int, sizeof(int), len); | 888 | len = min_t(unsigned int, sizeof(int), len); |
858 | if(put_user(len, optlen)) | 889 | if(put_user(len, optlen)) |
@@ -862,6 +893,78 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
862 | return 0; | 893 | return 0; |
863 | } | 894 | } |
864 | 895 | ||
896 | int ipv6_getsockopt(struct sock *sk, int level, int optname, | ||
897 | char __user *optval, int __user *optlen) | ||
898 | { | ||
899 | int err; | ||
900 | |||
901 | if (level == SOL_IP && sk->sk_type != SOCK_RAW) | ||
902 | return udp_prot.getsockopt(sk, level, optname, optval, optlen); | ||
903 | |||
904 | if(level != SOL_IPV6) | ||
905 | return -ENOPROTOOPT; | ||
906 | |||
907 | err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); | ||
908 | #ifdef CONFIG_NETFILTER | ||
909 | /* we need to exclude all possible EINVALs except default case */ | ||
910 | if (err == -ENOPROTOOPT && optname != IPV6_ADDRFORM && | ||
911 | optname != MCAST_MSFILTER) { | ||
912 | int len; | ||
913 | |||
914 | if (get_user(len, optlen)) | ||
915 | return -EFAULT; | ||
916 | |||
917 | lock_sock(sk); | ||
918 | err = nf_getsockopt(sk, PF_INET6, optname, optval, | ||
919 | &len); | ||
920 | release_sock(sk); | ||
921 | if (err >= 0) | ||
922 | err = put_user(len, optlen); | ||
923 | } | ||
924 | #endif | ||
925 | return err; | ||
926 | } | ||
927 | |||
928 | #ifdef CONFIG_COMPAT | ||
929 | int compat_ipv6_getsockopt(struct sock *sk, int level, int optname, | ||
930 | char __user *optval, int __user *optlen) | ||
931 | { | ||
932 | int err; | ||
933 | |||
934 | if (level == SOL_IP && sk->sk_type != SOCK_RAW) { | ||
935 | if (udp_prot.compat_getsockopt) | ||
936 | return udp_prot.compat_getsockopt(sk, level, | ||
937 | optname, optval, optlen); | ||
938 | else | ||
939 | return udp_prot.getsockopt(sk, level, | ||
940 | optname, optval, optlen); | ||
941 | } | ||
942 | |||
943 | if(level != SOL_IPV6) | ||
944 | return -ENOPROTOOPT; | ||
945 | |||
946 | err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); | ||
947 | #ifdef CONFIG_NETFILTER | ||
948 | /* we need to exclude all possible EINVALs except default case */ | ||
949 | if (err == -ENOPROTOOPT && optname != IPV6_ADDRFORM && | ||
950 | optname != MCAST_MSFILTER) { | ||
951 | int len; | ||
952 | |||
953 | if (get_user(len, optlen)) | ||
954 | return -EFAULT; | ||
955 | |||
956 | lock_sock(sk); | ||
957 | err = compat_nf_getsockopt(sk, PF_INET6, optname, optval, | ||
958 | &len); | ||
959 | release_sock(sk); | ||
960 | if (err >= 0) | ||
961 | err = put_user(len, optlen); | ||
962 | } | ||
963 | #endif | ||
964 | return err; | ||
965 | } | ||
966 | #endif | ||
967 | |||
865 | void __init ipv6_packet_init(void) | 968 | void __init ipv6_packet_init(void) |
866 | { | 969 | { |
867 | dev_add_pack(&ipv6_packet_type); | 970 | dev_add_pack(&ipv6_packet_type); |
diff --git a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c index 16482785bdfd..61419e11e35d 100644 --- a/net/ipv6/ipv6_syms.c +++ b/net/ipv6/ipv6_syms.c | |||
@@ -18,6 +18,10 @@ EXPORT_SYMBOL(ip6_route_output); | |||
18 | EXPORT_SYMBOL(addrconf_lock); | 18 | EXPORT_SYMBOL(addrconf_lock); |
19 | EXPORT_SYMBOL(ipv6_setsockopt); | 19 | EXPORT_SYMBOL(ipv6_setsockopt); |
20 | EXPORT_SYMBOL(ipv6_getsockopt); | 20 | EXPORT_SYMBOL(ipv6_getsockopt); |
21 | #ifdef CONFIG_COMPAT | ||
22 | EXPORT_SYMBOL(compat_ipv6_setsockopt); | ||
23 | EXPORT_SYMBOL(compat_ipv6_getsockopt); | ||
24 | #endif | ||
21 | EXPORT_SYMBOL(inet6_register_protosw); | 25 | EXPORT_SYMBOL(inet6_register_protosw); |
22 | EXPORT_SYMBOL(inet6_unregister_protosw); | 26 | EXPORT_SYMBOL(inet6_unregister_protosw); |
23 | EXPORT_SYMBOL(inet6_add_protocol); | 27 | EXPORT_SYMBOL(inet6_add_protocol); |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index ae20a0ec9bd8..8de5a8e59149 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -859,29 +859,12 @@ static int rawv6_geticmpfilter(struct sock *sk, int level, int optname, | |||
859 | } | 859 | } |
860 | 860 | ||
861 | 861 | ||
862 | static int rawv6_setsockopt(struct sock *sk, int level, int optname, | 862 | static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, |
863 | char __user *optval, int optlen) | 863 | char __user *optval, int optlen) |
864 | { | 864 | { |
865 | struct raw6_sock *rp = raw6_sk(sk); | 865 | struct raw6_sock *rp = raw6_sk(sk); |
866 | int val; | 866 | int val; |
867 | 867 | ||
868 | switch(level) { | ||
869 | case SOL_RAW: | ||
870 | break; | ||
871 | |||
872 | case SOL_ICMPV6: | ||
873 | if (inet_sk(sk)->num != IPPROTO_ICMPV6) | ||
874 | return -EOPNOTSUPP; | ||
875 | return rawv6_seticmpfilter(sk, level, optname, optval, | ||
876 | optlen); | ||
877 | case SOL_IPV6: | ||
878 | if (optname == IPV6_CHECKSUM) | ||
879 | break; | ||
880 | default: | ||
881 | return ipv6_setsockopt(sk, level, optname, optval, | ||
882 | optlen); | ||
883 | }; | ||
884 | |||
885 | if (get_user(val, (int __user *)optval)) | 868 | if (get_user(val, (int __user *)optval)) |
886 | return -EFAULT; | 869 | return -EFAULT; |
887 | 870 | ||
@@ -906,12 +889,9 @@ static int rawv6_setsockopt(struct sock *sk, int level, int optname, | |||
906 | } | 889 | } |
907 | } | 890 | } |
908 | 891 | ||
909 | static int rawv6_getsockopt(struct sock *sk, int level, int optname, | 892 | static int rawv6_setsockopt(struct sock *sk, int level, int optname, |
910 | char __user *optval, int __user *optlen) | 893 | char __user *optval, int optlen) |
911 | { | 894 | { |
912 | struct raw6_sock *rp = raw6_sk(sk); | ||
913 | int val, len; | ||
914 | |||
915 | switch(level) { | 895 | switch(level) { |
916 | case SOL_RAW: | 896 | case SOL_RAW: |
917 | break; | 897 | break; |
@@ -919,15 +899,47 @@ static int rawv6_getsockopt(struct sock *sk, int level, int optname, | |||
919 | case SOL_ICMPV6: | 899 | case SOL_ICMPV6: |
920 | if (inet_sk(sk)->num != IPPROTO_ICMPV6) | 900 | if (inet_sk(sk)->num != IPPROTO_ICMPV6) |
921 | return -EOPNOTSUPP; | 901 | return -EOPNOTSUPP; |
922 | return rawv6_geticmpfilter(sk, level, optname, optval, | 902 | return rawv6_seticmpfilter(sk, level, optname, optval, |
923 | optlen); | 903 | optlen); |
924 | case SOL_IPV6: | 904 | case SOL_IPV6: |
925 | if (optname == IPV6_CHECKSUM) | 905 | if (optname == IPV6_CHECKSUM) |
926 | break; | 906 | break; |
927 | default: | 907 | default: |
928 | return ipv6_getsockopt(sk, level, optname, optval, | 908 | return ipv6_setsockopt(sk, level, optname, optval, |
929 | optlen); | 909 | optlen); |
930 | }; | 910 | }; |
911 | return do_rawv6_setsockopt(sk, level, optname, optval, optlen); | ||
912 | } | ||
913 | |||
914 | #ifdef CONFIG_COMPAT | ||
915 | static int compat_rawv6_setsockopt(struct sock *sk, int level, int optname, | ||
916 | char __user *optval, int optlen) | ||
917 | { | ||
918 | switch(level) { | ||
919 | case SOL_RAW: | ||
920 | break; | ||
921 | |||
922 | case SOL_ICMPV6: | ||
923 | if (inet_sk(sk)->num != IPPROTO_ICMPV6) | ||
924 | return -EOPNOTSUPP; | ||
925 | return rawv6_seticmpfilter(sk, level, optname, optval, | ||
926 | optlen); | ||
927 | case SOL_IPV6: | ||
928 | if (optname == IPV6_CHECKSUM) | ||
929 | break; | ||
930 | default: | ||
931 | return compat_ipv6_setsockopt(sk, level, | ||
932 | optname, optval, optlen); | ||
933 | }; | ||
934 | return do_rawv6_setsockopt(sk, level, optname, optval, optlen); | ||
935 | } | ||
936 | #endif | ||
937 | |||
938 | static int do_rawv6_getsockopt(struct sock *sk, int level, int optname, | ||
939 | char __user *optval, int __user *optlen) | ||
940 | { | ||
941 | struct raw6_sock *rp = raw6_sk(sk); | ||
942 | int val, len; | ||
931 | 943 | ||
932 | if (get_user(len,optlen)) | 944 | if (get_user(len,optlen)) |
933 | return -EFAULT; | 945 | return -EFAULT; |
@@ -953,6 +965,52 @@ static int rawv6_getsockopt(struct sock *sk, int level, int optname, | |||
953 | return 0; | 965 | return 0; |
954 | } | 966 | } |
955 | 967 | ||
968 | static int rawv6_getsockopt(struct sock *sk, int level, int optname, | ||
969 | char __user *optval, int __user *optlen) | ||
970 | { | ||
971 | switch(level) { | ||
972 | case SOL_RAW: | ||
973 | break; | ||
974 | |||
975 | case SOL_ICMPV6: | ||
976 | if (inet_sk(sk)->num != IPPROTO_ICMPV6) | ||
977 | return -EOPNOTSUPP; | ||
978 | return rawv6_geticmpfilter(sk, level, optname, optval, | ||
979 | optlen); | ||
980 | case SOL_IPV6: | ||
981 | if (optname == IPV6_CHECKSUM) | ||
982 | break; | ||
983 | default: | ||
984 | return ipv6_getsockopt(sk, level, optname, optval, | ||
985 | optlen); | ||
986 | }; | ||
987 | return do_rawv6_getsockopt(sk, level, optname, optval, optlen); | ||
988 | } | ||
989 | |||
990 | #ifdef CONFIG_COMPAT | ||
991 | static int compat_rawv6_getsockopt(struct sock *sk, int level, int optname, | ||
992 | char __user *optval, int __user *optlen) | ||
993 | { | ||
994 | switch(level) { | ||
995 | case SOL_RAW: | ||
996 | break; | ||
997 | |||
998 | case SOL_ICMPV6: | ||
999 | if (inet_sk(sk)->num != IPPROTO_ICMPV6) | ||
1000 | return -EOPNOTSUPP; | ||
1001 | return rawv6_geticmpfilter(sk, level, optname, optval, | ||
1002 | optlen); | ||
1003 | case SOL_IPV6: | ||
1004 | if (optname == IPV6_CHECKSUM) | ||
1005 | break; | ||
1006 | default: | ||
1007 | return compat_ipv6_getsockopt(sk, level, | ||
1008 | optname, optval, optlen); | ||
1009 | }; | ||
1010 | return do_rawv6_getsockopt(sk, level, optname, optval, optlen); | ||
1011 | } | ||
1012 | #endif | ||
1013 | |||
956 | static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg) | 1014 | static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg) |
957 | { | 1015 | { |
958 | switch(cmd) { | 1016 | switch(cmd) { |
@@ -1008,6 +1066,10 @@ struct proto rawv6_prot = { | |||
1008 | .destroy = inet6_destroy_sock, | 1066 | .destroy = inet6_destroy_sock, |
1009 | .setsockopt = rawv6_setsockopt, | 1067 | .setsockopt = rawv6_setsockopt, |
1010 | .getsockopt = rawv6_getsockopt, | 1068 | .getsockopt = rawv6_getsockopt, |
1069 | #ifdef CONFIG_COMPAT | ||
1070 | .compat_setsockopt = compat_rawv6_setsockopt, | ||
1071 | .compat_getsockopt = compat_rawv6_getsockopt, | ||
1072 | #endif | ||
1011 | .sendmsg = rawv6_sendmsg, | 1073 | .sendmsg = rawv6_sendmsg, |
1012 | .recvmsg = rawv6_recvmsg, | 1074 | .recvmsg = rawv6_recvmsg, |
1013 | .bind = rawv6_bind, | 1075 | .bind = rawv6_bind, |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index af6a0c60f903..2f8975e0150a 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -1308,6 +1308,10 @@ static struct inet_connection_sock_af_ops ipv6_specific = { | |||
1308 | 1308 | ||
1309 | .setsockopt = ipv6_setsockopt, | 1309 | .setsockopt = ipv6_setsockopt, |
1310 | .getsockopt = ipv6_getsockopt, | 1310 | .getsockopt = ipv6_getsockopt, |
1311 | #ifdef CONFIG_COMPAT | ||
1312 | .compat_setsockopt = compat_ipv6_setsockopt, | ||
1313 | .compat_getsockopt = compat_ipv6_getsockopt, | ||
1314 | #endif | ||
1311 | .addr2sockaddr = inet6_csk_addr2sockaddr, | 1315 | .addr2sockaddr = inet6_csk_addr2sockaddr, |
1312 | .sockaddr_len = sizeof(struct sockaddr_in6) | 1316 | .sockaddr_len = sizeof(struct sockaddr_in6) |
1313 | }; | 1317 | }; |
@@ -1327,6 +1331,10 @@ static struct inet_connection_sock_af_ops ipv6_mapped = { | |||
1327 | 1331 | ||
1328 | .setsockopt = ipv6_setsockopt, | 1332 | .setsockopt = ipv6_setsockopt, |
1329 | .getsockopt = ipv6_getsockopt, | 1333 | .getsockopt = ipv6_getsockopt, |
1334 | #ifdef CONFIG_COMPAT | ||
1335 | .compat_setsockopt = compat_ipv6_setsockopt, | ||
1336 | .compat_getsockopt = compat_ipv6_getsockopt, | ||
1337 | #endif | ||
1330 | .addr2sockaddr = inet6_csk_addr2sockaddr, | 1338 | .addr2sockaddr = inet6_csk_addr2sockaddr, |
1331 | .sockaddr_len = sizeof(struct sockaddr_in6) | 1339 | .sockaddr_len = sizeof(struct sockaddr_in6) |
1332 | }; | 1340 | }; |
@@ -1566,6 +1574,10 @@ struct proto tcpv6_prot = { | |||
1566 | .shutdown = tcp_shutdown, | 1574 | .shutdown = tcp_shutdown, |
1567 | .setsockopt = tcp_setsockopt, | 1575 | .setsockopt = tcp_setsockopt, |
1568 | .getsockopt = tcp_getsockopt, | 1576 | .getsockopt = tcp_getsockopt, |
1577 | #ifdef CONFIG_COMPAT | ||
1578 | .compat_setsockopt = compat_tcp_setsockopt, | ||
1579 | .compat_getsockopt = compat_tcp_getsockopt, | ||
1580 | #endif | ||
1569 | .sendmsg = tcp_sendmsg, | 1581 | .sendmsg = tcp_sendmsg, |
1570 | .recvmsg = tcp_recvmsg, | 1582 | .recvmsg = tcp_recvmsg, |
1571 | .backlog_rcv = tcp_v6_do_rcv, | 1583 | .backlog_rcv = tcp_v6_do_rcv, |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index c47648892c04..538ada00646a 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -880,16 +880,13 @@ static int udpv6_destroy_sock(struct sock *sk) | |||
880 | /* | 880 | /* |
881 | * Socket option code for UDP | 881 | * Socket option code for UDP |
882 | */ | 882 | */ |
883 | static int udpv6_setsockopt(struct sock *sk, int level, int optname, | 883 | static int do_udpv6_setsockopt(struct sock *sk, int level, int optname, |
884 | char __user *optval, int optlen) | 884 | char __user *optval, int optlen) |
885 | { | 885 | { |
886 | struct udp_sock *up = udp_sk(sk); | 886 | struct udp_sock *up = udp_sk(sk); |
887 | int val; | 887 | int val; |
888 | int err = 0; | 888 | int err = 0; |
889 | 889 | ||
890 | if (level != SOL_UDP) | ||
891 | return ipv6_setsockopt(sk, level, optname, optval, optlen); | ||
892 | |||
893 | if(optlen<sizeof(int)) | 890 | if(optlen<sizeof(int)) |
894 | return -EINVAL; | 891 | return -EINVAL; |
895 | 892 | ||
@@ -927,15 +924,31 @@ static int udpv6_setsockopt(struct sock *sk, int level, int optname, | |||
927 | return err; | 924 | return err; |
928 | } | 925 | } |
929 | 926 | ||
930 | static int udpv6_getsockopt(struct sock *sk, int level, int optname, | 927 | static int udpv6_setsockopt(struct sock *sk, int level, int optname, |
928 | char __user *optval, int optlen) | ||
929 | { | ||
930 | if (level != SOL_UDP) | ||
931 | return ipv6_setsockopt(sk, level, optname, optval, optlen); | ||
932 | return do_udpv6_setsockopt(sk, level, optname, optval, optlen); | ||
933 | } | ||
934 | |||
935 | #ifdef CONFIG_COMPAT | ||
936 | static int compat_udpv6_setsockopt(struct sock *sk, int level, int optname, | ||
937 | char __user *optval, int optlen) | ||
938 | { | ||
939 | if (level != SOL_UDP) | ||
940 | return compat_ipv6_setsockopt(sk, level, | ||
941 | optname, optval, optlen); | ||
942 | return do_udpv6_setsockopt(sk, level, optname, optval, optlen); | ||
943 | } | ||
944 | #endif | ||
945 | |||
946 | static int do_udpv6_getsockopt(struct sock *sk, int level, int optname, | ||
931 | char __user *optval, int __user *optlen) | 947 | char __user *optval, int __user *optlen) |
932 | { | 948 | { |
933 | struct udp_sock *up = udp_sk(sk); | 949 | struct udp_sock *up = udp_sk(sk); |
934 | int val, len; | 950 | int val, len; |
935 | 951 | ||
936 | if (level != SOL_UDP) | ||
937 | return ipv6_getsockopt(sk, level, optname, optval, optlen); | ||
938 | |||
939 | if(get_user(len,optlen)) | 952 | if(get_user(len,optlen)) |
940 | return -EFAULT; | 953 | return -EFAULT; |
941 | 954 | ||
@@ -964,6 +977,25 @@ static int udpv6_getsockopt(struct sock *sk, int level, int optname, | |||
964 | return 0; | 977 | return 0; |
965 | } | 978 | } |
966 | 979 | ||
980 | static int udpv6_getsockopt(struct sock *sk, int level, int optname, | ||
981 | char __user *optval, int __user *optlen) | ||
982 | { | ||
983 | if (level != SOL_UDP) | ||
984 | return ipv6_getsockopt(sk, level, optname, optval, optlen); | ||
985 | return do_udpv6_getsockopt(sk, level, optname, optval, optlen); | ||
986 | } | ||
987 | |||
988 | #ifdef CONFIG_COMPAT | ||
989 | static int compat_udpv6_getsockopt(struct sock *sk, int level, int optname, | ||
990 | char __user *optval, int __user *optlen) | ||
991 | { | ||
992 | if (level != SOL_UDP) | ||
993 | return compat_ipv6_getsockopt(sk, level, | ||
994 | optname, optval, optlen); | ||
995 | return do_udpv6_getsockopt(sk, level, optname, optval, optlen); | ||
996 | } | ||
997 | #endif | ||
998 | |||
967 | static struct inet6_protocol udpv6_protocol = { | 999 | static struct inet6_protocol udpv6_protocol = { |
968 | .handler = udpv6_rcv, | 1000 | .handler = udpv6_rcv, |
969 | .err_handler = udpv6_err, | 1001 | .err_handler = udpv6_err, |
@@ -1046,6 +1078,10 @@ struct proto udpv6_prot = { | |||
1046 | .destroy = udpv6_destroy_sock, | 1078 | .destroy = udpv6_destroy_sock, |
1047 | .setsockopt = udpv6_setsockopt, | 1079 | .setsockopt = udpv6_setsockopt, |
1048 | .getsockopt = udpv6_getsockopt, | 1080 | .getsockopt = udpv6_getsockopt, |
1081 | #ifdef CONFIG_COMPAT | ||
1082 | .compat_setsockopt = compat_udpv6_setsockopt, | ||
1083 | .compat_getsockopt = compat_udpv6_getsockopt, | ||
1084 | #endif | ||
1049 | .sendmsg = udpv6_sendmsg, | 1085 | .sendmsg = udpv6_sendmsg, |
1050 | .recvmsg = udpv6_recvmsg, | 1086 | .recvmsg = udpv6_recvmsg, |
1051 | .backlog_rcv = udpv6_queue_rcv_skb, | 1087 | .backlog_rcv = udpv6_queue_rcv_skb, |