af_iucv.c (b8942e3b6c4b35dda5e8ca75aec5e2f027fe39a9) | af_iucv.c (44b1e6b5f9a93cc2ba024e09cf137d5f1b5f8426) |
---|---|
1/* 2 * linux/net/iucv/af_iucv.c 3 * 4 * IUCV protocol stack for Linux on zSeries 5 * 6 * Copyright 2006 IBM Corporation 7 * 8 * Author(s): Jennifer Hunt <jenhunt@us.ibm.com> --- 31 unchanged lines hidden (view full) --- 40 .owner = THIS_MODULE, 41 .obj_size = sizeof(struct iucv_sock), 42}; 43 44/* special AF_IUCV IPRM messages */ 45static const u8 iprm_shutdown[8] = 46 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; 47 | 1/* 2 * linux/net/iucv/af_iucv.c 3 * 4 * IUCV protocol stack for Linux on zSeries 5 * 6 * Copyright 2006 IBM Corporation 7 * 8 * Author(s): Jennifer Hunt <jenhunt@us.ibm.com> --- 31 unchanged lines hidden (view full) --- 40 .owner = THIS_MODULE, 41 .obj_size = sizeof(struct iucv_sock), 42}; 43 44/* special AF_IUCV IPRM messages */ 45static const u8 iprm_shutdown[8] = 46 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; 47 |
48#define TRGCLS_SIZE (sizeof(((struct iucv_message *)0)->class)) 49 50/* macros to set/get socket control buffer at correct offset */ 51#define CB_TAG(skb) ((skb)->cb) /* iucv message tag */ 52#define CB_TAG_LEN (sizeof(((struct iucv_message *) 0)->tag)) 53#define CB_TRGCLS(skb) ((skb)->cb + CB_TAG_LEN) /* iucv msg target class */ 54#define CB_TRGCLS_LEN (TRGCLS_SIZE) 55 56 |
|
48static void iucv_sock_kill(struct sock *sk); 49static void iucv_sock_close(struct sock *sk); 50 51/* Call Back functions */ 52static void iucv_callback_rx(struct iucv_path *, struct iucv_message *); 53static void iucv_callback_txdone(struct iucv_path *, struct iucv_message *); 54static void iucv_callback_connack(struct iucv_path *, u8 ipuser[16]); 55static int iucv_callback_connreq(struct iucv_path *, u8 ipvmid[8], --- 637 unchanged lines hidden (view full) --- 693 694static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, 695 struct msghdr *msg, size_t len) 696{ 697 struct sock *sk = sock->sk; 698 struct iucv_sock *iucv = iucv_sk(sk); 699 struct sk_buff *skb; 700 struct iucv_message txmsg; | 57static void iucv_sock_kill(struct sock *sk); 58static void iucv_sock_close(struct sock *sk); 59 60/* Call Back functions */ 61static void iucv_callback_rx(struct iucv_path *, struct iucv_message *); 62static void iucv_callback_txdone(struct iucv_path *, struct iucv_message *); 63static void iucv_callback_connack(struct iucv_path *, u8 ipuser[16]); 64static int iucv_callback_connreq(struct iucv_path *, u8 ipvmid[8], --- 637 unchanged lines hidden (view full) --- 702 703static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, 704 struct msghdr *msg, size_t len) 705{ 706 struct sock *sk = sock->sk; 707 struct iucv_sock *iucv = iucv_sk(sk); 708 struct sk_buff *skb; 709 struct iucv_message txmsg; |
710 struct cmsghdr *cmsg; 711 int cmsg_done; |
|
701 char user_id[9]; 702 char appl_id[9]; 703 int err; 704 705 err = sock_error(sk); 706 if (err) 707 return err; 708 709 if (msg->msg_flags & MSG_OOB) 710 return -EOPNOTSUPP; 711 712 lock_sock(sk); 713 714 if (sk->sk_shutdown & SEND_SHUTDOWN) { 715 err = -EPIPE; 716 goto out; 717 } 718 719 if (sk->sk_state == IUCV_CONNECTED) { | 712 char user_id[9]; 713 char appl_id[9]; 714 int err; 715 716 err = sock_error(sk); 717 if (err) 718 return err; 719 720 if (msg->msg_flags & MSG_OOB) 721 return -EOPNOTSUPP; 722 723 lock_sock(sk); 724 725 if (sk->sk_shutdown & SEND_SHUTDOWN) { 726 err = -EPIPE; 727 goto out; 728 } 729 730 if (sk->sk_state == IUCV_CONNECTED) { |
731 /* initialize defaults */ 732 cmsg_done = 0; /* check for duplicate headers */ 733 txmsg.class = 0; 734 735 /* iterate over control messages */ 736 for (cmsg = CMSG_FIRSTHDR(msg); cmsg; 737 cmsg = CMSG_NXTHDR(msg, cmsg)) { 738 739 if (!CMSG_OK(msg, cmsg)) { 740 err = -EINVAL; 741 goto out; 742 } 743 744 if (cmsg->cmsg_level != SOL_IUCV) 745 continue; 746 747 if (cmsg->cmsg_type & cmsg_done) { 748 err = -EINVAL; 749 goto out; 750 } 751 cmsg_done |= cmsg->cmsg_type; 752 753 switch (cmsg->cmsg_type) { 754 case SCM_IUCV_TRGCLS: 755 if (cmsg->cmsg_len != CMSG_LEN(TRGCLS_SIZE)) { 756 err = -EINVAL; 757 goto out; 758 } 759 760 /* set iucv message target class */ 761 memcpy(&txmsg.class, 762 (void *) CMSG_DATA(cmsg), TRGCLS_SIZE); 763 764 break; 765 766 default: 767 err = -EINVAL; 768 goto out; 769 break; 770 } 771 } 772 |
|
720 if (!(skb = sock_alloc_send_skb(sk, len, 721 msg->msg_flags & MSG_DONTWAIT, 722 &err))) 723 goto out; 724 725 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { 726 err = -EFAULT; 727 goto fail; 728 } 729 | 773 if (!(skb = sock_alloc_send_skb(sk, len, 774 msg->msg_flags & MSG_DONTWAIT, 775 &err))) 776 goto out; 777 778 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { 779 err = -EFAULT; 780 goto fail; 781 } 782 |
730 txmsg.class = 0; 731 memcpy(&txmsg.class, skb->data, skb->len >= 4 ? 4 : skb->len); | 783 /* increment and save iucv message tag for msg_completion cbk */ |
732 txmsg.tag = iucv->send_tag++; | 784 txmsg.tag = iucv->send_tag++; |
733 memcpy(skb->cb, &txmsg.tag, 4); | 785 memcpy(CB_TAG(skb), &txmsg.tag, CB_TAG_LEN); |
734 skb_queue_tail(&iucv->send_skb_q, skb); 735 736 if (((iucv->path->flags & IUCV_IPRMDATA) & iucv->flags) 737 && skb->len <= 7) { 738 err = iucv_send_iprm(iucv->path, &txmsg, skb); 739 740 /* on success: there is no message_complete callback 741 * for an IPRMDATA msg; remove skb from send queue */ --- 54 unchanged lines hidden (view full) --- 796 size = sk->sk_rcvbuf / 4; 797 else 798 size = dataleft; 799 800 nskb = alloc_skb(size, GFP_ATOMIC | GFP_DMA); 801 if (!nskb) 802 return -ENOMEM; 803 | 786 skb_queue_tail(&iucv->send_skb_q, skb); 787 788 if (((iucv->path->flags & IUCV_IPRMDATA) & iucv->flags) 789 && skb->len <= 7) { 790 err = iucv_send_iprm(iucv->path, &txmsg, skb); 791 792 /* on success: there is no message_complete callback 793 * for an IPRMDATA msg; remove skb from send queue */ --- 54 unchanged lines hidden (view full) --- 848 size = sk->sk_rcvbuf / 4; 849 else 850 size = dataleft; 851 852 nskb = alloc_skb(size, GFP_ATOMIC | GFP_DMA); 853 if (!nskb) 854 return -ENOMEM; 855 |
856 /* copy target class to control buffer of new skb */ 857 memcpy(CB_TRGCLS(nskb), CB_TRGCLS(skb), CB_TRGCLS_LEN); 858 859 /* copy data fragment */ |
|
804 memcpy(nskb->data, skb->data + copied, size); 805 copied += size; 806 dataleft -= size; 807 808 skb_reset_transport_header(nskb); 809 skb_reset_network_header(nskb); 810 nskb->len = size; 811 --- 7 unchanged lines hidden (view full) --- 819 struct iucv_path *path, 820 struct iucv_message *msg) 821{ 822 int rc; 823 unsigned int len; 824 825 len = iucv_msg_length(msg); 826 | 860 memcpy(nskb->data, skb->data + copied, size); 861 copied += size; 862 dataleft -= size; 863 864 skb_reset_transport_header(nskb); 865 skb_reset_network_header(nskb); 866 nskb->len = size; 867 --- 7 unchanged lines hidden (view full) --- 875 struct iucv_path *path, 876 struct iucv_message *msg) 877{ 878 int rc; 879 unsigned int len; 880 881 len = iucv_msg_length(msg); 882 |
883 /* store msg target class in the second 4 bytes of skb ctrl buffer */ 884 /* Note: the first 4 bytes are reserved for msg tag */ 885 memcpy(CB_TRGCLS(skb), &msg->class, CB_TRGCLS_LEN); 886 |
|
827 /* check for special IPRM messages (e.g. iucv_sock_shutdown) */ 828 if ((msg->flags & IUCV_IPRMDATA) && len > 7) { 829 if (memcmp(msg->rmmsg, iprm_shutdown, 8) == 0) { 830 skb->data = NULL; 831 skb->len = 0; 832 } 833 } else { 834 rc = iucv_message_receive(path, msg, msg->flags & IUCV_IPRMDATA, --- 75 unchanged lines hidden (view full) --- 910 skb_queue_head(&sk->sk_receive_queue, skb); 911 if (copied == 0) 912 return -EFAULT; 913 goto done; 914 } 915 916 len -= copied; 917 | 887 /* check for special IPRM messages (e.g. iucv_sock_shutdown) */ 888 if ((msg->flags & IUCV_IPRMDATA) && len > 7) { 889 if (memcmp(msg->rmmsg, iprm_shutdown, 8) == 0) { 890 skb->data = NULL; 891 skb->len = 0; 892 } 893 } else { 894 rc = iucv_message_receive(path, msg, msg->flags & IUCV_IPRMDATA, --- 75 unchanged lines hidden (view full) --- 970 skb_queue_head(&sk->sk_receive_queue, skb); 971 if (copied == 0) 972 return -EFAULT; 973 goto done; 974 } 975 976 len -= copied; 977 |
978 /* create control message to store iucv msg target class: 979 * get the trgcls from the control buffer of the skb due to 980 * fragmentation of original iucv message. */ 981 err = put_cmsg(msg, SOL_IUCV, SCM_IUCV_TRGCLS, 982 CB_TRGCLS_LEN, CB_TRGCLS(skb)); 983 if (err) { 984 if (!(flags & MSG_PEEK)) 985 skb_queue_head(&sk->sk_receive_queue, skb); 986 return err; 987 } 988 |
|
918 /* Mark read part of skb as used */ 919 if (!(flags & MSG_PEEK)) { 920 skb_pull(skb, copied); 921 922 if (skb->len) { 923 skb_queue_head(&sk->sk_receive_queue, skb); 924 goto done; 925 } --- 385 unchanged lines hidden (view full) --- 1311 struct sk_buff_head *list = &iucv_sk(sk)->send_skb_q; 1312 struct sk_buff *list_skb = list->next; 1313 unsigned long flags; 1314 1315 if (!skb_queue_empty(list)) { 1316 spin_lock_irqsave(&list->lock, flags); 1317 1318 while (list_skb != (struct sk_buff *)list) { | 989 /* Mark read part of skb as used */ 990 if (!(flags & MSG_PEEK)) { 991 skb_pull(skb, copied); 992 993 if (skb->len) { 994 skb_queue_head(&sk->sk_receive_queue, skb); 995 goto done; 996 } --- 385 unchanged lines hidden (view full) --- 1382 struct sk_buff_head *list = &iucv_sk(sk)->send_skb_q; 1383 struct sk_buff *list_skb = list->next; 1384 unsigned long flags; 1385 1386 if (!skb_queue_empty(list)) { 1387 spin_lock_irqsave(&list->lock, flags); 1388 1389 while (list_skb != (struct sk_buff *)list) { |
1319 if (!memcmp(&msg->tag, list_skb->cb, 4)) { | 1390 if (!memcmp(&msg->tag, CB_TAG(list_skb), CB_TAG_LEN)) { |
1320 this = list_skb; 1321 break; 1322 } 1323 list_skb = list_skb->next; 1324 } 1325 if (this) 1326 __skb_unlink(this, list); 1327 --- 119 unchanged lines hidden --- | 1391 this = list_skb; 1392 break; 1393 } 1394 list_skb = list_skb->next; 1395 } 1396 if (this) 1397 __skb_unlink(this, list); 1398 --- 119 unchanged lines hidden --- |