aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/raw.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r--net/ipv6/raw.c112
1 files changed, 87 insertions, 25 deletions
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
862static int rawv6_setsockopt(struct sock *sk, int level, int optname, 862static 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
909static int rawv6_getsockopt(struct sock *sk, int level, int optname, 892static 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
915static 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
938static 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
968static 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
991static 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
956static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg) 1014static 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,