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 --- |