af_iucv.c (d978a6361ad13f1f9694fcb7b5852d253a544d92) af_iucv.c (f9c41a62bba3f3f7ef3541b2a025e3371bcbba97)
1/*
2 * IUCV protocol stack for Linux on zSeries
3 *
4 * Copyright IBM Corp. 2006, 2009
5 *
6 * Author(s): Jennifer Hunt <jenhunt@us.ibm.com>
7 * Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
8 * PM functions:

--- 35 unchanged lines hidden (view full) ---

44static struct iucv_interface *pr_iucv;
45
46/* special AF_IUCV IPRM messages */
47static const u8 iprm_shutdown[8] =
48 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
49
50#define TRGCLS_SIZE (sizeof(((struct iucv_message *)0)->class))
51
1/*
2 * IUCV protocol stack for Linux on zSeries
3 *
4 * Copyright IBM Corp. 2006, 2009
5 *
6 * Author(s): Jennifer Hunt <jenhunt@us.ibm.com>
7 * Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
8 * PM functions:

--- 35 unchanged lines hidden (view full) ---

44static struct iucv_interface *pr_iucv;
45
46/* special AF_IUCV IPRM messages */
47static const u8 iprm_shutdown[8] =
48 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
49
50#define TRGCLS_SIZE (sizeof(((struct iucv_message *)0)->class))
51
52/* macros to set/get socket control buffer at correct offset */
53#define CB_TAG(skb) ((skb)->cb) /* iucv message tag */
54#define CB_TAG_LEN (sizeof(((struct iucv_message *) 0)->tag))
55#define CB_TRGCLS(skb) ((skb)->cb + CB_TAG_LEN) /* iucv msg target class */
56#define CB_TRGCLS_LEN (TRGCLS_SIZE)
57
58#define __iucv_sock_wait(sk, condition, timeo, ret) \
59do { \
60 DEFINE_WAIT(__wait); \
61 long __timeo = timeo; \
62 ret = 0; \
63 prepare_to_wait(sk_sleep(sk), &__wait, TASK_INTERRUPTIBLE); \
64 while (!(condition)) { \
65 if (!__timeo) { \

--- 1070 unchanged lines hidden (view full) ---

1136 /* return -ECONNRESET if the socket is no longer connected */
1137 if (sk->sk_state != IUCV_CONNECTED) {
1138 err = -ECONNRESET;
1139 goto fail;
1140 }
1141
1142 /* increment and save iucv message tag for msg_completion cbk */
1143 txmsg.tag = iucv->send_tag++;
52#define __iucv_sock_wait(sk, condition, timeo, ret) \
53do { \
54 DEFINE_WAIT(__wait); \
55 long __timeo = timeo; \
56 ret = 0; \
57 prepare_to_wait(sk_sleep(sk), &__wait, TASK_INTERRUPTIBLE); \
58 while (!(condition)) { \
59 if (!__timeo) { \

--- 1070 unchanged lines hidden (view full) ---

1130 /* return -ECONNRESET if the socket is no longer connected */
1131 if (sk->sk_state != IUCV_CONNECTED) {
1132 err = -ECONNRESET;
1133 goto fail;
1134 }
1135
1136 /* increment and save iucv message tag for msg_completion cbk */
1137 txmsg.tag = iucv->send_tag++;
1144 memcpy(CB_TAG(skb), &txmsg.tag, CB_TAG_LEN);
1138 IUCV_SKB_CB(skb)->tag = txmsg.tag;
1145
1146 if (iucv->transport == AF_IUCV_TRANS_HIPER) {
1147 atomic_inc(&iucv->msg_sent);
1148 err = afiucv_hs_send(&txmsg, sk, skb, 0);
1149 if (err) {
1150 atomic_dec(&iucv->msg_sent);
1151 goto fail;
1152 }

--- 66 unchanged lines hidden (view full) ---

1219 else
1220 size = dataleft;
1221
1222 nskb = alloc_skb(size, GFP_ATOMIC | GFP_DMA);
1223 if (!nskb)
1224 return -ENOMEM;
1225
1226 /* copy target class to control buffer of new skb */
1139
1140 if (iucv->transport == AF_IUCV_TRANS_HIPER) {
1141 atomic_inc(&iucv->msg_sent);
1142 err = afiucv_hs_send(&txmsg, sk, skb, 0);
1143 if (err) {
1144 atomic_dec(&iucv->msg_sent);
1145 goto fail;
1146 }

--- 66 unchanged lines hidden (view full) ---

1213 else
1214 size = dataleft;
1215
1216 nskb = alloc_skb(size, GFP_ATOMIC | GFP_DMA);
1217 if (!nskb)
1218 return -ENOMEM;
1219
1220 /* copy target class to control buffer of new skb */
1227 memcpy(CB_TRGCLS(nskb), CB_TRGCLS(skb), CB_TRGCLS_LEN);
1221 IUCV_SKB_CB(nskb)->class = IUCV_SKB_CB(skb)->class;
1228
1229 /* copy data fragment */
1230 memcpy(nskb->data, skb->data + copied, size);
1231 copied += size;
1232 dataleft -= size;
1233
1234 skb_reset_transport_header(nskb);
1235 skb_reset_network_header(nskb);

--- 15 unchanged lines hidden (view full) ---

1251{
1252 int rc;
1253 unsigned int len;
1254
1255 len = iucv_msg_length(msg);
1256
1257 /* store msg target class in the second 4 bytes of skb ctrl buffer */
1258 /* Note: the first 4 bytes are reserved for msg tag */
1222
1223 /* copy data fragment */
1224 memcpy(nskb->data, skb->data + copied, size);
1225 copied += size;
1226 dataleft -= size;
1227
1228 skb_reset_transport_header(nskb);
1229 skb_reset_network_header(nskb);

--- 15 unchanged lines hidden (view full) ---

1245{
1246 int rc;
1247 unsigned int len;
1248
1249 len = iucv_msg_length(msg);
1250
1251 /* store msg target class in the second 4 bytes of skb ctrl buffer */
1252 /* Note: the first 4 bytes are reserved for msg tag */
1259 memcpy(CB_TRGCLS(skb), &msg->class, CB_TRGCLS_LEN);
1253 IUCV_SKB_CB(skb)->class = msg->class;
1260
1261 /* check for special IPRM messages (e.g. iucv_sock_shutdown) */
1262 if ((msg->flags & IUCV_IPRMDATA) && len > 7) {
1263 if (memcmp(msg->rmmsg, iprm_shutdown, 8) == 0) {
1264 skb->data = NULL;
1265 skb->len = 0;
1266 }
1267 } else {

--- 19 unchanged lines hidden (view full) ---

1287 skb = skb_dequeue(&iucv_sk(sk)->backlog_skb_q);
1288 } else {
1289 skb_reset_transport_header(skb);
1290 skb_reset_network_header(skb);
1291 skb->len = len;
1292 }
1293 }
1294
1254
1255 /* check for special IPRM messages (e.g. iucv_sock_shutdown) */
1256 if ((msg->flags & IUCV_IPRMDATA) && len > 7) {
1257 if (memcmp(msg->rmmsg, iprm_shutdown, 8) == 0) {
1258 skb->data = NULL;
1259 skb->len = 0;
1260 }
1261 } else {

--- 19 unchanged lines hidden (view full) ---

1281 skb = skb_dequeue(&iucv_sk(sk)->backlog_skb_q);
1282 } else {
1283 skb_reset_transport_header(skb);
1284 skb_reset_network_header(skb);
1285 skb->len = len;
1286 }
1287 }
1288
1289 IUCV_SKB_CB(skb)->offset = 0;
1295 if (sock_queue_rcv_skb(sk, skb))
1296 skb_queue_head(&iucv_sk(sk)->backlog_skb_q, skb);
1297}
1298
1299/* iucv_process_message_q() - Process outstanding IUCV messages
1300 *
1301 * Locking: must be called with message_q.lock held
1302 */

--- 19 unchanged lines hidden (view full) ---

1322 struct msghdr *msg, size_t len, int flags)
1323{
1324 int noblock = flags & MSG_DONTWAIT;
1325 struct sock *sk = sock->sk;
1326 struct iucv_sock *iucv = iucv_sk(sk);
1327 unsigned int copied, rlen;
1328 struct sk_buff *skb, *rskb, *cskb;
1329 int err = 0;
1290 if (sock_queue_rcv_skb(sk, skb))
1291 skb_queue_head(&iucv_sk(sk)->backlog_skb_q, skb);
1292}
1293
1294/* iucv_process_message_q() - Process outstanding IUCV messages
1295 *
1296 * Locking: must be called with message_q.lock held
1297 */

--- 19 unchanged lines hidden (view full) ---

1317 struct msghdr *msg, size_t len, int flags)
1318{
1319 int noblock = flags & MSG_DONTWAIT;
1320 struct sock *sk = sock->sk;
1321 struct iucv_sock *iucv = iucv_sk(sk);
1322 unsigned int copied, rlen;
1323 struct sk_buff *skb, *rskb, *cskb;
1324 int err = 0;
1325 u32 offset;
1330
1331 msg->msg_namelen = 0;
1332
1333 if ((sk->sk_state == IUCV_DISCONN) &&
1334 skb_queue_empty(&iucv->backlog_skb_q) &&
1335 skb_queue_empty(&sk->sk_receive_queue) &&
1336 list_empty(&iucv->message_q.list))
1337 return 0;

--- 5 unchanged lines hidden (view full) ---

1343 * the function understands MSG_PEEK and, thus, does not dequeue skb */
1344 skb = skb_recv_datagram(sk, flags, noblock, &err);
1345 if (!skb) {
1346 if (sk->sk_shutdown & RCV_SHUTDOWN)
1347 return 0;
1348 return err;
1349 }
1350
1326
1327 msg->msg_namelen = 0;
1328
1329 if ((sk->sk_state == IUCV_DISCONN) &&
1330 skb_queue_empty(&iucv->backlog_skb_q) &&
1331 skb_queue_empty(&sk->sk_receive_queue) &&
1332 list_empty(&iucv->message_q.list))
1333 return 0;

--- 5 unchanged lines hidden (view full) ---

1339 * the function understands MSG_PEEK and, thus, does not dequeue skb */
1340 skb = skb_recv_datagram(sk, flags, noblock, &err);
1341 if (!skb) {
1342 if (sk->sk_shutdown & RCV_SHUTDOWN)
1343 return 0;
1344 return err;
1345 }
1346
1351 rlen = skb->len; /* real length of skb */
1347 offset = IUCV_SKB_CB(skb)->offset;
1348 rlen = skb->len - offset; /* real length of skb */
1352 copied = min_t(unsigned int, rlen, len);
1353 if (!rlen)
1354 sk->sk_shutdown = sk->sk_shutdown | RCV_SHUTDOWN;
1355
1356 cskb = skb;
1349 copied = min_t(unsigned int, rlen, len);
1350 if (!rlen)
1351 sk->sk_shutdown = sk->sk_shutdown | RCV_SHUTDOWN;
1352
1353 cskb = skb;
1357 if (skb_copy_datagram_iovec(cskb, 0, msg->msg_iov, copied)) {
1354 if (skb_copy_datagram_iovec(cskb, offset, msg->msg_iov, copied)) {
1358 if (!(flags & MSG_PEEK))
1359 skb_queue_head(&sk->sk_receive_queue, skb);
1360 return -EFAULT;
1361 }
1362
1363 /* SOCK_SEQPACKET: set MSG_TRUNC if recv buf size is too small */
1364 if (sk->sk_type == SOCK_SEQPACKET) {
1365 if (copied < rlen)
1366 msg->msg_flags |= MSG_TRUNC;
1367 /* each iucv message contains a complete record */
1368 msg->msg_flags |= MSG_EOR;
1369 }
1370
1371 /* create control message to store iucv msg target class:
1372 * get the trgcls from the control buffer of the skb due to
1373 * fragmentation of original iucv message. */
1374 err = put_cmsg(msg, SOL_IUCV, SCM_IUCV_TRGCLS,
1355 if (!(flags & MSG_PEEK))
1356 skb_queue_head(&sk->sk_receive_queue, skb);
1357 return -EFAULT;
1358 }
1359
1360 /* SOCK_SEQPACKET: set MSG_TRUNC if recv buf size is too small */
1361 if (sk->sk_type == SOCK_SEQPACKET) {
1362 if (copied < rlen)
1363 msg->msg_flags |= MSG_TRUNC;
1364 /* each iucv message contains a complete record */
1365 msg->msg_flags |= MSG_EOR;
1366 }
1367
1368 /* create control message to store iucv msg target class:
1369 * get the trgcls from the control buffer of the skb due to
1370 * fragmentation of original iucv message. */
1371 err = put_cmsg(msg, SOL_IUCV, SCM_IUCV_TRGCLS,
1375 CB_TRGCLS_LEN, CB_TRGCLS(skb));
1372 sizeof(IUCV_SKB_CB(skb)->class),
1373 (void *)&IUCV_SKB_CB(skb)->class);
1376 if (err) {
1377 if (!(flags & MSG_PEEK))
1378 skb_queue_head(&sk->sk_receive_queue, skb);
1379 return err;
1380 }
1381
1382 /* Mark read part of skb as used */
1383 if (!(flags & MSG_PEEK)) {
1384
1385 /* SOCK_STREAM: re-queue skb if it contains unreceived data */
1386 if (sk->sk_type == SOCK_STREAM) {
1374 if (err) {
1375 if (!(flags & MSG_PEEK))
1376 skb_queue_head(&sk->sk_receive_queue, skb);
1377 return err;
1378 }
1379
1380 /* Mark read part of skb as used */
1381 if (!(flags & MSG_PEEK)) {
1382
1383 /* SOCK_STREAM: re-queue skb if it contains unreceived data */
1384 if (sk->sk_type == SOCK_STREAM) {
1387 skb_pull(skb, copied);
1388 if (skb->len) {
1389 skb_queue_head(&sk->sk_receive_queue, skb);
1385 if (copied < rlen) {
1386 IUCV_SKB_CB(skb)->offset = offset + copied;
1390 goto done;
1391 }
1392 }
1393
1394 kfree_skb(skb);
1395 if (iucv->transport == AF_IUCV_TRANS_HIPER) {
1396 atomic_inc(&iucv->msg_recv);
1397 if (atomic_read(&iucv->msg_recv) > iucv->msglimit) {
1398 WARN_ON(1);
1399 iucv_sock_close(sk);
1400 return -EFAULT;
1401 }
1402 }
1403
1404 /* Queue backlog skbs */
1405 spin_lock_bh(&iucv->message_q.lock);
1406 rskb = skb_dequeue(&iucv->backlog_skb_q);
1407 while (rskb) {
1387 goto done;
1388 }
1389 }
1390
1391 kfree_skb(skb);
1392 if (iucv->transport == AF_IUCV_TRANS_HIPER) {
1393 atomic_inc(&iucv->msg_recv);
1394 if (atomic_read(&iucv->msg_recv) > iucv->msglimit) {
1395 WARN_ON(1);
1396 iucv_sock_close(sk);
1397 return -EFAULT;
1398 }
1399 }
1400
1401 /* Queue backlog skbs */
1402 spin_lock_bh(&iucv->message_q.lock);
1403 rskb = skb_dequeue(&iucv->backlog_skb_q);
1404 while (rskb) {
1405 IUCV_SKB_CB(rskb)->offset = 0;
1408 if (sock_queue_rcv_skb(sk, rskb)) {
1409 skb_queue_head(&iucv->backlog_skb_q,
1410 rskb);
1411 break;
1412 } else {
1413 rskb = skb_dequeue(&iucv->backlog_skb_q);
1414 }
1415 }

--- 42 unchanged lines hidden (view full) ---

1458 unsigned int mask = 0;
1459
1460 sock_poll_wait(file, sk_sleep(sk), wait);
1461
1462 if (sk->sk_state == IUCV_LISTEN)
1463 return iucv_accept_poll(sk);
1464
1465 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
1406 if (sock_queue_rcv_skb(sk, rskb)) {
1407 skb_queue_head(&iucv->backlog_skb_q,
1408 rskb);
1409 break;
1410 } else {
1411 rskb = skb_dequeue(&iucv->backlog_skb_q);
1412 }
1413 }

--- 42 unchanged lines hidden (view full) ---

1456 unsigned int mask = 0;
1457
1458 sock_poll_wait(file, sk_sleep(sk), wait);
1459
1460 if (sk->sk_state == IUCV_LISTEN)
1461 return iucv_accept_poll(sk);
1462
1463 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
1466 mask |= POLLERR |
1467 (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0);
1464 mask |= POLLERR;
1468
1469 if (sk->sk_shutdown & RCV_SHUTDOWN)
1470 mask |= POLLRDHUP;
1471
1472 if (sk->sk_shutdown == SHUTDOWN_MASK)
1473 mask |= POLLHUP;
1474
1475 if (!skb_queue_empty(&sk->sk_receive_queue) ||

--- 352 unchanged lines hidden (view full) ---

1828 struct sk_buff *list_skb = list->next;
1829 unsigned long flags;
1830
1831 bh_lock_sock(sk);
1832 if (!skb_queue_empty(list)) {
1833 spin_lock_irqsave(&list->lock, flags);
1834
1835 while (list_skb != (struct sk_buff *)list) {
1465
1466 if (sk->sk_shutdown & RCV_SHUTDOWN)
1467 mask |= POLLRDHUP;
1468
1469 if (sk->sk_shutdown == SHUTDOWN_MASK)
1470 mask |= POLLHUP;
1471
1472 if (!skb_queue_empty(&sk->sk_receive_queue) ||

--- 352 unchanged lines hidden (view full) ---

1825 struct sk_buff *list_skb = list->next;
1826 unsigned long flags;
1827
1828 bh_lock_sock(sk);
1829 if (!skb_queue_empty(list)) {
1830 spin_lock_irqsave(&list->lock, flags);
1831
1832 while (list_skb != (struct sk_buff *)list) {
1836 if (!memcmp(&msg->tag, CB_TAG(list_skb), CB_TAG_LEN)) {
1833 if (msg->tag != IUCV_SKB_CB(list_skb)->tag) {
1837 this = list_skb;
1838 break;
1839 }
1840 list_skb = list_skb->next;
1841 }
1842 if (this)
1843 __skb_unlink(this, list);
1844

--- 244 unchanged lines hidden (view full) ---

2089 /* write stuff from iucv_msg to skb cb */
2090 if (skb->len < sizeof(struct af_iucv_trans_hdr)) {
2091 kfree_skb(skb);
2092 return NET_RX_SUCCESS;
2093 }
2094 skb_pull(skb, sizeof(struct af_iucv_trans_hdr));
2095 skb_reset_transport_header(skb);
2096 skb_reset_network_header(skb);
1834 this = list_skb;
1835 break;
1836 }
1837 list_skb = list_skb->next;
1838 }
1839 if (this)
1840 __skb_unlink(this, list);
1841

--- 244 unchanged lines hidden (view full) ---

2086 /* write stuff from iucv_msg to skb cb */
2087 if (skb->len < sizeof(struct af_iucv_trans_hdr)) {
2088 kfree_skb(skb);
2089 return NET_RX_SUCCESS;
2090 }
2091 skb_pull(skb, sizeof(struct af_iucv_trans_hdr));
2092 skb_reset_transport_header(skb);
2093 skb_reset_network_header(skb);
2094 IUCV_SKB_CB(skb)->offset = 0;
2097 spin_lock(&iucv->message_q.lock);
2098 if (skb_queue_empty(&iucv->backlog_skb_q)) {
2099 if (sock_queue_rcv_skb(sk, skb)) {
2100 /* handle rcv queue full */
2101 skb_queue_tail(&iucv->backlog_skb_q, skb);
2102 }
2103 } else
2104 skb_queue_tail(&iucv_sk(sk)->backlog_skb_q, skb);

--- 88 unchanged lines hidden (view full) ---

2193 break;
2194 }
2195 /* fall through and receive non-zero length data */
2196 case (AF_IUCV_FLAG_SHT):
2197 /* shutdown request */
2198 /* fall through and receive zero length data */
2199 case 0:
2200 /* plain data frame */
2095 spin_lock(&iucv->message_q.lock);
2096 if (skb_queue_empty(&iucv->backlog_skb_q)) {
2097 if (sock_queue_rcv_skb(sk, skb)) {
2098 /* handle rcv queue full */
2099 skb_queue_tail(&iucv->backlog_skb_q, skb);
2100 }
2101 } else
2102 skb_queue_tail(&iucv_sk(sk)->backlog_skb_q, skb);

--- 88 unchanged lines hidden (view full) ---

2191 break;
2192 }
2193 /* fall through and receive non-zero length data */
2194 case (AF_IUCV_FLAG_SHT):
2195 /* shutdown request */
2196 /* fall through and receive zero length data */
2197 case 0:
2198 /* plain data frame */
2201 memcpy(CB_TRGCLS(skb), &trans_hdr->iucv_hdr.class,
2202 CB_TRGCLS_LEN);
2199 IUCV_SKB_CB(skb)->class = trans_hdr->iucv_hdr.class;
2203 err = afiucv_hs_callback_rx(sk, skb);
2204 break;
2205 default:
2206 ;
2207 }
2208
2209 return err;
2210}

--- 254 unchanged lines hidden ---
2200 err = afiucv_hs_callback_rx(sk, skb);
2201 break;
2202 default:
2203 ;
2204 }
2205
2206 return err;
2207}

--- 254 unchanged lines hidden ---