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