diff options
author | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2006-11-27 12:29:59 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-03 00:30:45 -0500 |
commit | 4c0a6cb0db19de411c4bf7fcdc79d4c7c4ccafb1 (patch) | |
tree | e7f793f8d259df2a37fa975325c25961a5d3e14b /net/ipv6 | |
parent | e3703b3de1f049b38733ba520e5038f23063068e (diff) |
[UDP(-Lite)]: consolidate v4 and v6 get|setsockopt code
This patch consolidates set/getsockopt code between UDP(-Lite) v4 and 6. The
justification is that UDP(-Lite) is a transport-layer protocol and therefore
the socket option code (at least in theory) should be AF-independent.
Furthermore, there is the following code reduplication:
* do_udp{,v6}_getsockopt is 100% identical between v4 and v6
* do_udp{,v6}_setsockopt is identical up to the following differerence
--v4 in contrast to v4 additionally allows the experimental encapsulation
types UDP_ENCAP_ESPINUDP and UDP_ENCAP_ESPINUDP_NON_IKE
--the remainder is identical between v4 and v6
I believe that this difference is of little relevance.
The advantages in not duplicating twice almost completely identical code.
The patch further simplifies the interface of udp{,v6}_push_pending_frames,
since for the second argument (struct udp_sock *up) it always holds that
up = udp_sk(sk); where sk is the first function argument.
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/udp.c | 118 |
1 files changed, 9 insertions, 109 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index b3ea8af50a9b..f52a5c3cc0a3 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -505,10 +505,11 @@ static void udp_v6_flush_pending_frames(struct sock *sk) | |||
505 | * Sending | 505 | * Sending |
506 | */ | 506 | */ |
507 | 507 | ||
508 | static int udp_v6_push_pending_frames(struct sock *sk, struct udp_sock *up) | 508 | static int udp_v6_push_pending_frames(struct sock *sk) |
509 | { | 509 | { |
510 | struct sk_buff *skb; | 510 | struct sk_buff *skb; |
511 | struct udphdr *uh; | 511 | struct udphdr *uh; |
512 | struct udp_sock *up = udp_sk(sk); | ||
512 | struct inet_sock *inet = inet_sk(sk); | 513 | struct inet_sock *inet = inet_sk(sk); |
513 | struct flowi *fl = &inet->cork.fl; | 514 | struct flowi *fl = &inet->cork.fl; |
514 | int err = 0; | 515 | int err = 0; |
@@ -782,7 +783,7 @@ do_append_data: | |||
782 | if (err) | 783 | if (err) |
783 | udp_v6_flush_pending_frames(sk); | 784 | udp_v6_flush_pending_frames(sk); |
784 | else if (!corkreq) | 785 | else if (!corkreq) |
785 | err = udp_v6_push_pending_frames(sk, up); | 786 | err = udp_v6_push_pending_frames(sk); |
786 | else if (unlikely(skb_queue_empty(&sk->sk_write_queue))) | 787 | else if (unlikely(skb_queue_empty(&sk->sk_write_queue))) |
787 | up->pending = 0; | 788 | up->pending = 0; |
788 | 789 | ||
@@ -844,72 +845,12 @@ int udpv6_destroy_sock(struct sock *sk) | |||
844 | /* | 845 | /* |
845 | * Socket option code for UDP | 846 | * Socket option code for UDP |
846 | */ | 847 | */ |
847 | static int do_udpv6_setsockopt(struct sock *sk, int level, int optname, | ||
848 | char __user *optval, int optlen) | ||
849 | { | ||
850 | struct udp_sock *up = udp_sk(sk); | ||
851 | int val; | ||
852 | int err = 0; | ||
853 | |||
854 | if(optlen<sizeof(int)) | ||
855 | return -EINVAL; | ||
856 | |||
857 | if (get_user(val, (int __user *)optval)) | ||
858 | return -EFAULT; | ||
859 | |||
860 | switch(optname) { | ||
861 | case UDP_CORK: | ||
862 | if (val != 0) { | ||
863 | up->corkflag = 1; | ||
864 | } else { | ||
865 | up->corkflag = 0; | ||
866 | lock_sock(sk); | ||
867 | udp_v6_push_pending_frames(sk, up); | ||
868 | release_sock(sk); | ||
869 | } | ||
870 | break; | ||
871 | case UDP_ENCAP: | ||
872 | switch (val) { | ||
873 | case 0: | ||
874 | up->encap_type = val; | ||
875 | break; | ||
876 | default: | ||
877 | err = -ENOPROTOOPT; | ||
878 | break; | ||
879 | } | ||
880 | break; | ||
881 | |||
882 | case UDPLITE_SEND_CSCOV: | ||
883 | if (!up->pcflag) /* Disable the option on UDP sockets */ | ||
884 | return -ENOPROTOOPT; | ||
885 | if (val != 0 && val < 8) /* Illegal coverage: use default (8) */ | ||
886 | val = 8; | ||
887 | up->pcslen = val; | ||
888 | up->pcflag |= UDPLITE_SEND_CC; | ||
889 | break; | ||
890 | |||
891 | case UDPLITE_RECV_CSCOV: | ||
892 | if (!up->pcflag) /* Disable the option on UDP sockets */ | ||
893 | return -ENOPROTOOPT; | ||
894 | if (val != 0 && val < 8) /* Avoid silly minimal values. */ | ||
895 | val = 8; | ||
896 | up->pcrlen = val; | ||
897 | up->pcflag |= UDPLITE_RECV_CC; | ||
898 | break; | ||
899 | |||
900 | default: | ||
901 | err = -ENOPROTOOPT; | ||
902 | break; | ||
903 | }; | ||
904 | |||
905 | return err; | ||
906 | } | ||
907 | |||
908 | int udpv6_setsockopt(struct sock *sk, int level, int optname, | 848 | int udpv6_setsockopt(struct sock *sk, int level, int optname, |
909 | char __user *optval, int optlen) | 849 | char __user *optval, int optlen) |
910 | { | 850 | { |
911 | if (level == SOL_UDP || level == SOL_UDPLITE) | 851 | if (level == SOL_UDP || level == SOL_UDPLITE) |
912 | return do_udpv6_setsockopt(sk, level, optname, optval, optlen); | 852 | return udp_lib_setsockopt(sk, level, optname, optval, optlen, |
853 | udp_v6_push_pending_frames); | ||
913 | return ipv6_setsockopt(sk, level, optname, optval, optlen); | 854 | return ipv6_setsockopt(sk, level, optname, optval, optlen); |
914 | } | 855 | } |
915 | 856 | ||
@@ -918,58 +859,17 @@ int compat_udpv6_setsockopt(struct sock *sk, int level, int optname, | |||
918 | char __user *optval, int optlen) | 859 | char __user *optval, int optlen) |
919 | { | 860 | { |
920 | if (level == SOL_UDP || level == SOL_UDPLITE) | 861 | if (level == SOL_UDP || level == SOL_UDPLITE) |
921 | return do_udpv6_setsockopt(sk, level, optname, optval, optlen); | 862 | return udp_lib_setsockopt(sk, level, optname, optval, optlen, |
863 | udp_v6_push_pending_frames); | ||
922 | return compat_ipv6_setsockopt(sk, level, optname, optval, optlen); | 864 | return compat_ipv6_setsockopt(sk, level, optname, optval, optlen); |
923 | } | 865 | } |
924 | #endif | 866 | #endif |
925 | 867 | ||
926 | static int do_udpv6_getsockopt(struct sock *sk, int level, int optname, | ||
927 | char __user *optval, int __user *optlen) | ||
928 | { | ||
929 | struct udp_sock *up = udp_sk(sk); | ||
930 | int val, len; | ||
931 | |||
932 | if(get_user(len,optlen)) | ||
933 | return -EFAULT; | ||
934 | |||
935 | len = min_t(unsigned int, len, sizeof(int)); | ||
936 | |||
937 | if(len < 0) | ||
938 | return -EINVAL; | ||
939 | |||
940 | switch(optname) { | ||
941 | case UDP_CORK: | ||
942 | val = up->corkflag; | ||
943 | break; | ||
944 | |||
945 | case UDP_ENCAP: | ||
946 | val = up->encap_type; | ||
947 | break; | ||
948 | |||
949 | case UDPLITE_SEND_CSCOV: | ||
950 | val = up->pcslen; | ||
951 | break; | ||
952 | |||
953 | case UDPLITE_RECV_CSCOV: | ||
954 | val = up->pcrlen; | ||
955 | break; | ||
956 | |||
957 | default: | ||
958 | return -ENOPROTOOPT; | ||
959 | }; | ||
960 | |||
961 | if(put_user(len, optlen)) | ||
962 | return -EFAULT; | ||
963 | if(copy_to_user(optval, &val,len)) | ||
964 | return -EFAULT; | ||
965 | return 0; | ||
966 | } | ||
967 | |||
968 | int udpv6_getsockopt(struct sock *sk, int level, int optname, | 868 | int udpv6_getsockopt(struct sock *sk, int level, int optname, |
969 | char __user *optval, int __user *optlen) | 869 | char __user *optval, int __user *optlen) |
970 | { | 870 | { |
971 | if (level == SOL_UDP || level == SOL_UDPLITE) | 871 | if (level == SOL_UDP || level == SOL_UDPLITE) |
972 | return do_udpv6_getsockopt(sk, level, optname, optval, optlen); | 872 | return udp_lib_getsockopt(sk, level, optname, optval, optlen); |
973 | return ipv6_getsockopt(sk, level, optname, optval, optlen); | 873 | return ipv6_getsockopt(sk, level, optname, optval, optlen); |
974 | } | 874 | } |
975 | 875 | ||
@@ -978,7 +878,7 @@ int compat_udpv6_getsockopt(struct sock *sk, int level, int optname, | |||
978 | char __user *optval, int __user *optlen) | 878 | char __user *optval, int __user *optlen) |
979 | { | 879 | { |
980 | if (level == SOL_UDP || level == SOL_UDPLITE) | 880 | if (level == SOL_UDP || level == SOL_UDPLITE) |
981 | return do_udpv6_getsockopt(sk, level, optname, optval, optlen); | 881 | return udp_lib_getsockopt(sk, level, optname, optval, optlen); |
982 | return compat_ipv6_getsockopt(sk, level, optname, optval, optlen); | 882 | return compat_ipv6_getsockopt(sk, level, optname, optval, optlen); |
983 | } | 883 | } |
984 | #endif | 884 | #endif |