aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/iucv/af_iucv.c163
1 files changed, 81 insertions, 82 deletions
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index a9b3a6f9ea95..42b7198a6883 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -747,108 +747,107 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
747 goto out; 747 goto out;
748 } 748 }
749 749
750 if (sk->sk_state == IUCV_CONNECTED) { 750 /* Return if the socket is not in connected state */
751 /* initialize defaults */ 751 if (sk->sk_state != IUCV_CONNECTED) {
752 cmsg_done = 0; /* check for duplicate headers */ 752 err = -ENOTCONN;
753 txmsg.class = 0; 753 goto out;
754 754 }
755 /* iterate over control messages */
756 for (cmsg = CMSG_FIRSTHDR(msg); cmsg;
757 cmsg = CMSG_NXTHDR(msg, cmsg)) {
758
759 if (!CMSG_OK(msg, cmsg)) {
760 err = -EINVAL;
761 goto out;
762 }
763 755
764 if (cmsg->cmsg_level != SOL_IUCV) 756 /* initialize defaults */
765 continue; 757 cmsg_done = 0; /* check for duplicate headers */
758 txmsg.class = 0;
766 759
767 if (cmsg->cmsg_type & cmsg_done) { 760 /* iterate over control messages */
768 err = -EINVAL; 761 for (cmsg = CMSG_FIRSTHDR(msg); cmsg;
769 goto out; 762 cmsg = CMSG_NXTHDR(msg, cmsg)) {
770 }
771 cmsg_done |= cmsg->cmsg_type;
772 763
773 switch (cmsg->cmsg_type) { 764 if (!CMSG_OK(msg, cmsg)) {
774 case SCM_IUCV_TRGCLS: 765 err = -EINVAL;
775 if (cmsg->cmsg_len != CMSG_LEN(TRGCLS_SIZE)) { 766 goto out;
776 err = -EINVAL; 767 }
777 goto out;
778 }
779 768
780 /* set iucv message target class */ 769 if (cmsg->cmsg_level != SOL_IUCV)
781 memcpy(&txmsg.class, 770 continue;
782 (void *) CMSG_DATA(cmsg), TRGCLS_SIZE);
783 771
784 break; 772 if (cmsg->cmsg_type & cmsg_done) {
773 err = -EINVAL;
774 goto out;
775 }
776 cmsg_done |= cmsg->cmsg_type;
785 777
786 default: 778 switch (cmsg->cmsg_type) {
779 case SCM_IUCV_TRGCLS:
780 if (cmsg->cmsg_len != CMSG_LEN(TRGCLS_SIZE)) {
787 err = -EINVAL; 781 err = -EINVAL;
788 goto out; 782 goto out;
789 break;
790 } 783 }
791 }
792 784
793 /* allocate one skb for each iucv message: 785 /* set iucv message target class */
794 * this is fine for SOCK_SEQPACKET (unless we want to support 786 memcpy(&txmsg.class,
795 * segmented records using the MSG_EOR flag), but 787 (void *) CMSG_DATA(cmsg), TRGCLS_SIZE);
796 * for SOCK_STREAM we might want to improve it in future */
797 if (!(skb = sock_alloc_send_skb(sk, len,
798 msg->msg_flags & MSG_DONTWAIT,
799 &err)))
800 goto out;
801 788
802 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { 789 break;
803 err = -EFAULT; 790
804 goto fail; 791 default:
792 err = -EINVAL;
793 goto out;
794 break;
805 } 795 }
796 }
806 797
807 /* increment and save iucv message tag for msg_completion cbk */ 798 /* allocate one skb for each iucv message:
808 txmsg.tag = iucv->send_tag++; 799 * this is fine for SOCK_SEQPACKET (unless we want to support
809 memcpy(CB_TAG(skb), &txmsg.tag, CB_TAG_LEN); 800 * segmented records using the MSG_EOR flag), but
810 skb_queue_tail(&iucv->send_skb_q, skb); 801 * for SOCK_STREAM we might want to improve it in future */
802 skb = sock_alloc_send_skb(sk, len, msg->msg_flags & MSG_DONTWAIT,
803 &err);
804 if (!skb)
805 goto out;
806 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
807 err = -EFAULT;
808 goto fail;
809 }
811 810
812 if (((iucv->path->flags & IUCV_IPRMDATA) & iucv->flags) 811 /* increment and save iucv message tag for msg_completion cbk */
813 && skb->len <= 7) { 812 txmsg.tag = iucv->send_tag++;
814 err = iucv_send_iprm(iucv->path, &txmsg, skb); 813 memcpy(CB_TAG(skb), &txmsg.tag, CB_TAG_LEN);
814 skb_queue_tail(&iucv->send_skb_q, skb);
815 815
816 /* on success: there is no message_complete callback 816 if (((iucv->path->flags & IUCV_IPRMDATA) & iucv->flags)
817 * for an IPRMDATA msg; remove skb from send queue */ 817 && skb->len <= 7) {
818 if (err == 0) { 818 err = iucv_send_iprm(iucv->path, &txmsg, skb);
819 skb_unlink(skb, &iucv->send_skb_q);
820 kfree_skb(skb);
821 }
822 819
823 /* this error should never happen since the 820 /* on success: there is no message_complete callback
824 * IUCV_IPRMDATA path flag is set... sever path */ 821 * for an IPRMDATA msg; remove skb from send queue */
825 if (err == 0x15) { 822 if (err == 0) {
826 iucv_path_sever(iucv->path, NULL); 823 skb_unlink(skb, &iucv->send_skb_q);
827 skb_unlink(skb, &iucv->send_skb_q); 824 kfree_skb(skb);
828 err = -EPIPE; 825 }
829 goto fail; 826
830 } 827 /* this error should never happen since the
831 } else 828 * IUCV_IPRMDATA path flag is set... sever path */
832 err = iucv_message_send(iucv->path, &txmsg, 0, 0, 829 if (err == 0x15) {
833 (void *) skb->data, skb->len); 830 iucv_path_sever(iucv->path, NULL);
834 if (err) {
835 if (err == 3) {
836 user_id[8] = 0;
837 memcpy(user_id, iucv->dst_user_id, 8);
838 appl_id[8] = 0;
839 memcpy(appl_id, iucv->dst_name, 8);
840 pr_err("Application %s on z/VM guest %s"
841 " exceeds message limit\n",
842 user_id, appl_id);
843 }
844 skb_unlink(skb, &iucv->send_skb_q); 831 skb_unlink(skb, &iucv->send_skb_q);
845 err = -EPIPE; 832 err = -EPIPE;
846 goto fail; 833 goto fail;
847 } 834 }
848 835 } else
849 } else { 836 err = iucv_message_send(iucv->path, &txmsg, 0, 0,
850 err = -ENOTCONN; 837 (void *) skb->data, skb->len);
851 goto out; 838 if (err) {
839 if (err == 3) {
840 user_id[8] = 0;
841 memcpy(user_id, iucv->dst_user_id, 8);
842 appl_id[8] = 0;
843 memcpy(appl_id, iucv->dst_name, 8);
844 pr_err("Application %s on z/VM guest %s"
845 " exceeds message limit\n",
846 appl_id, user_id);
847 }
848 skb_unlink(skb, &iucv->send_skb_q);
849 err = -EPIPE;
850 goto fail;
852 } 851 }
853 852
854 release_sock(sk); 853 release_sock(sk);