diff options
author | Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | 2009-04-21 19:26:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-04-23 07:04:32 -0400 |
commit | 9d5c5d8f4105dc56ec10864b195dd1714f282c22 (patch) | |
tree | 075499708835271c15fa60b836a3e0f8723f6ba4 | |
parent | af88b52def76679c8c5bcdbed199fbe62b6a16d4 (diff) |
af_iucv: add sockopt() to enable/disable use of IPRM_DATA msgs
Provide the socket operations getsocktopt() and setsockopt() to enable/disable
sending of data in the parameter list of IUCV messages.
The patch sets respective flag only.
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/socket.h | 1 | ||||
-rw-r--r-- | include/net/iucv/af_iucv.h | 4 | ||||
-rw-r--r-- | net/iucv/af_iucv.c | 79 |
3 files changed, 81 insertions, 3 deletions
diff --git a/include/linux/socket.h b/include/linux/socket.h index 42a0396f2c59..d2310cb45d2f 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h | |||
@@ -303,6 +303,7 @@ struct ucred { | |||
303 | #define SOL_BLUETOOTH 274 | 303 | #define SOL_BLUETOOTH 274 |
304 | #define SOL_PNPIPE 275 | 304 | #define SOL_PNPIPE 275 |
305 | #define SOL_RDS 276 | 305 | #define SOL_RDS 276 |
306 | #define SOL_IUCV 277 | ||
306 | 307 | ||
307 | /* IPX options */ | 308 | /* IPX options */ |
308 | #define IPX_TYPE 1 | 309 | #define IPX_TYPE 1 |
diff --git a/include/net/iucv/af_iucv.h b/include/net/iucv/af_iucv.h index 85f80eadfa35..78a72764aeff 100644 --- a/include/net/iucv/af_iucv.h +++ b/include/net/iucv/af_iucv.h | |||
@@ -73,8 +73,12 @@ struct iucv_sock { | |||
73 | struct sk_buff_head backlog_skb_q; | 73 | struct sk_buff_head backlog_skb_q; |
74 | struct sock_msg_q message_q; | 74 | struct sock_msg_q message_q; |
75 | unsigned int send_tag; | 75 | unsigned int send_tag; |
76 | u8 flags; | ||
76 | }; | 77 | }; |
77 | 78 | ||
79 | /* iucv socket options (SOL_IUCV) */ | ||
80 | #define SO_IPRMDATA_MSG 0x0080 /* send/recv IPRM_DATA msgs */ | ||
81 | |||
78 | struct iucv_sock_list { | 82 | struct iucv_sock_list { |
79 | struct hlist_head head; | 83 | struct hlist_head head; |
80 | rwlock_t lock; | 84 | rwlock_t lock; |
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 6cf02b41ef95..b7c40c979921 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #define CONFIG_IUCV_SOCK_DEBUG 1 | 32 | #define CONFIG_IUCV_SOCK_DEBUG 1 |
33 | 33 | ||
34 | #define IPRMDATA 0x80 | 34 | #define IPRMDATA 0x80 |
35 | #define VERSION "1.0" | 35 | #define VERSION "1.1" |
36 | 36 | ||
37 | static char iucv_userid[80]; | 37 | static char iucv_userid[80]; |
38 | 38 | ||
@@ -226,6 +226,7 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio) | |||
226 | spin_lock_init(&iucv_sk(sk)->message_q.lock); | 226 | spin_lock_init(&iucv_sk(sk)->message_q.lock); |
227 | skb_queue_head_init(&iucv_sk(sk)->backlog_skb_q); | 227 | skb_queue_head_init(&iucv_sk(sk)->backlog_skb_q); |
228 | iucv_sk(sk)->send_tag = 0; | 228 | iucv_sk(sk)->send_tag = 0; |
229 | iucv_sk(sk)->flags = 0; | ||
229 | 230 | ||
230 | sk->sk_destruct = iucv_sock_destruct; | 231 | sk->sk_destruct = iucv_sock_destruct; |
231 | sk->sk_sndtimeo = IUCV_CONN_TIMEOUT; | 232 | sk->sk_sndtimeo = IUCV_CONN_TIMEOUT; |
@@ -1003,6 +1004,78 @@ static int iucv_sock_release(struct socket *sock) | |||
1003 | return err; | 1004 | return err; |
1004 | } | 1005 | } |
1005 | 1006 | ||
1007 | /* getsockopt and setsockopt */ | ||
1008 | static int iucv_sock_setsockopt(struct socket *sock, int level, int optname, | ||
1009 | char __user *optval, int optlen) | ||
1010 | { | ||
1011 | struct sock *sk = sock->sk; | ||
1012 | struct iucv_sock *iucv = iucv_sk(sk); | ||
1013 | int val; | ||
1014 | int rc; | ||
1015 | |||
1016 | if (level != SOL_IUCV) | ||
1017 | return -ENOPROTOOPT; | ||
1018 | |||
1019 | if (optlen < sizeof(int)) | ||
1020 | return -EINVAL; | ||
1021 | |||
1022 | if (get_user(val, (int __user *) optval)) | ||
1023 | return -EFAULT; | ||
1024 | |||
1025 | rc = 0; | ||
1026 | |||
1027 | lock_sock(sk); | ||
1028 | switch (optname) { | ||
1029 | case SO_IPRMDATA_MSG: | ||
1030 | if (val) | ||
1031 | iucv->flags |= IUCV_IPRMDATA; | ||
1032 | else | ||
1033 | iucv->flags &= ~IUCV_IPRMDATA; | ||
1034 | break; | ||
1035 | default: | ||
1036 | rc = -ENOPROTOOPT; | ||
1037 | break; | ||
1038 | } | ||
1039 | release_sock(sk); | ||
1040 | |||
1041 | return rc; | ||
1042 | } | ||
1043 | |||
1044 | static int iucv_sock_getsockopt(struct socket *sock, int level, int optname, | ||
1045 | char __user *optval, int __user *optlen) | ||
1046 | { | ||
1047 | struct sock *sk = sock->sk; | ||
1048 | struct iucv_sock *iucv = iucv_sk(sk); | ||
1049 | int val, len; | ||
1050 | |||
1051 | if (level != SOL_IUCV) | ||
1052 | return -ENOPROTOOPT; | ||
1053 | |||
1054 | if (get_user(len, optlen)) | ||
1055 | return -EFAULT; | ||
1056 | |||
1057 | if (len < 0) | ||
1058 | return -EINVAL; | ||
1059 | |||
1060 | len = min_t(unsigned int, len, sizeof(int)); | ||
1061 | |||
1062 | switch (optname) { | ||
1063 | case SO_IPRMDATA_MSG: | ||
1064 | val = (iucv->flags & IUCV_IPRMDATA) ? 1 : 0; | ||
1065 | break; | ||
1066 | default: | ||
1067 | return -ENOPROTOOPT; | ||
1068 | } | ||
1069 | |||
1070 | if (put_user(len, optlen)) | ||
1071 | return -EFAULT; | ||
1072 | if (copy_to_user(optval, &val, len)) | ||
1073 | return -EFAULT; | ||
1074 | |||
1075 | return 0; | ||
1076 | } | ||
1077 | |||
1078 | |||
1006 | /* Callback wrappers - called from iucv base support */ | 1079 | /* Callback wrappers - called from iucv base support */ |
1007 | static int iucv_callback_connreq(struct iucv_path *path, | 1080 | static int iucv_callback_connreq(struct iucv_path *path, |
1008 | u8 ipvmid[8], u8 ipuser[16]) | 1081 | u8 ipvmid[8], u8 ipuser[16]) |
@@ -1229,8 +1302,8 @@ static struct proto_ops iucv_sock_ops = { | |||
1229 | .mmap = sock_no_mmap, | 1302 | .mmap = sock_no_mmap, |
1230 | .socketpair = sock_no_socketpair, | 1303 | .socketpair = sock_no_socketpair, |
1231 | .shutdown = iucv_sock_shutdown, | 1304 | .shutdown = iucv_sock_shutdown, |
1232 | .setsockopt = sock_no_setsockopt, | 1305 | .setsockopt = iucv_sock_setsockopt, |
1233 | .getsockopt = sock_no_getsockopt | 1306 | .getsockopt = iucv_sock_getsockopt, |
1234 | }; | 1307 | }; |
1235 | 1308 | ||
1236 | static struct net_proto_family iucv_sock_family_ops = { | 1309 | static struct net_proto_family iucv_sock_family_ops = { |