aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/socket.h1
-rw-r--r--include/net/iucv/af_iucv.h4
-rw-r--r--net/iucv/af_iucv.c79
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
78struct iucv_sock_list { 82struct 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
37static char iucv_userid[80]; 37static 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 */
1008static 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
1044static 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 */
1007static int iucv_callback_connreq(struct iucv_path *path, 1080static 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
1236static struct net_proto_family iucv_sock_family_ops = { 1309static struct net_proto_family iucv_sock_family_ops = {