diff options
Diffstat (limited to 'net/caif/caif_socket.c')
| -rw-r--r-- | net/caif/caif_socket.c | 61 | 
1 files changed, 37 insertions, 24 deletions
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 3d0e09584fae..8ce904786116 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c  | |||
| @@ -28,8 +28,8 @@ | |||
| 28 | MODULE_LICENSE("GPL"); | 28 | MODULE_LICENSE("GPL"); | 
| 29 | MODULE_ALIAS_NETPROTO(AF_CAIF); | 29 | MODULE_ALIAS_NETPROTO(AF_CAIF); | 
| 30 | 30 | ||
| 31 | #define CAIF_DEF_SNDBUF (CAIF_MAX_PAYLOAD_SIZE*10) | 31 | #define CAIF_DEF_SNDBUF (4096*10) | 
| 32 | #define CAIF_DEF_RCVBUF (CAIF_MAX_PAYLOAD_SIZE*100) | 32 | #define CAIF_DEF_RCVBUF (4096*100) | 
| 33 | 33 | ||
| 34 | /* | 34 | /* | 
| 35 | * CAIF state is re-using the TCP socket states. | 35 | * CAIF state is re-using the TCP socket states. | 
| @@ -76,6 +76,7 @@ struct caifsock { | |||
| 76 | struct caif_connect_request conn_req; | 76 | struct caif_connect_request conn_req; | 
| 77 | struct mutex readlock; | 77 | struct mutex readlock; | 
| 78 | struct dentry *debugfs_socket_dir; | 78 | struct dentry *debugfs_socket_dir; | 
| 79 | int headroom, tailroom, maxframe; | ||
| 79 | }; | 80 | }; | 
| 80 | 81 | ||
| 81 | static int rx_flow_is_on(struct caifsock *cf_sk) | 82 | static int rx_flow_is_on(struct caifsock *cf_sk) | 
| @@ -594,27 +595,32 @@ static int caif_seqpkt_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 594 | goto err; | 595 | goto err; | 
| 595 | noblock = msg->msg_flags & MSG_DONTWAIT; | 596 | noblock = msg->msg_flags & MSG_DONTWAIT; | 
| 596 | 597 | ||
| 597 | buffer_size = len + CAIF_NEEDED_HEADROOM + CAIF_NEEDED_TAILROOM; | ||
| 598 | |||
| 599 | ret = -EMSGSIZE; | ||
| 600 | if (buffer_size > CAIF_MAX_PAYLOAD_SIZE) | ||
| 601 | goto err; | ||
| 602 | |||
| 603 | timeo = sock_sndtimeo(sk, noblock); | 598 | timeo = sock_sndtimeo(sk, noblock); | 
| 604 | timeo = caif_wait_for_flow_on(container_of(sk, struct caifsock, sk), | 599 | timeo = caif_wait_for_flow_on(container_of(sk, struct caifsock, sk), | 
| 605 | 1, timeo, &ret); | 600 | 1, timeo, &ret); | 
| 606 | 601 | ||
| 602 | if (ret) | ||
| 603 | goto err; | ||
| 607 | ret = -EPIPE; | 604 | ret = -EPIPE; | 
| 608 | if (cf_sk->sk.sk_state != CAIF_CONNECTED || | 605 | if (cf_sk->sk.sk_state != CAIF_CONNECTED || | 
| 609 | sock_flag(sk, SOCK_DEAD) || | 606 | sock_flag(sk, SOCK_DEAD) || | 
| 610 | (sk->sk_shutdown & RCV_SHUTDOWN)) | 607 | (sk->sk_shutdown & RCV_SHUTDOWN)) | 
| 611 | goto err; | 608 | goto err; | 
| 612 | 609 | ||
| 610 | /* Error if trying to write more than maximum frame size. */ | ||
| 611 | ret = -EMSGSIZE; | ||
| 612 | if (len > cf_sk->maxframe && cf_sk->sk.sk_protocol != CAIFPROTO_RFM) | ||
| 613 | goto err; | ||
| 614 | |||
| 615 | buffer_size = len + cf_sk->headroom + cf_sk->tailroom; | ||
| 616 | |||
| 613 | ret = -ENOMEM; | 617 | ret = -ENOMEM; | 
| 614 | skb = sock_alloc_send_skb(sk, buffer_size, noblock, &ret); | 618 | skb = sock_alloc_send_skb(sk, buffer_size, noblock, &ret); | 
| 615 | if (!skb) | 619 | |
| 620 | if (!skb || skb_tailroom(skb) < buffer_size) | ||
| 616 | goto err; | 621 | goto err; | 
| 617 | skb_reserve(skb, CAIF_NEEDED_HEADROOM); | 622 | |
| 623 | skb_reserve(skb, cf_sk->headroom); | ||
| 618 | 624 | ||
| 619 | ret = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); | 625 | ret = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); | 
| 620 | 626 | ||
| @@ -645,7 +651,6 @@ static int caif_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 645 | long timeo; | 651 | long timeo; | 
| 646 | 652 | ||
| 647 | err = -EOPNOTSUPP; | 653 | err = -EOPNOTSUPP; | 
| 648 | |||
| 649 | if (unlikely(msg->msg_flags&MSG_OOB)) | 654 | if (unlikely(msg->msg_flags&MSG_OOB)) | 
| 650 | goto out_err; | 655 | goto out_err; | 
| 651 | 656 | ||
| @@ -662,8 +667,8 @@ static int caif_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 662 | 667 | ||
| 663 | size = len-sent; | 668 | size = len-sent; | 
| 664 | 669 | ||
| 665 | if (size > CAIF_MAX_PAYLOAD_SIZE) | 670 | if (size > cf_sk->maxframe) | 
| 666 | size = CAIF_MAX_PAYLOAD_SIZE; | 671 | size = cf_sk->maxframe; | 
| 667 | 672 | ||
| 668 | /* If size is more than half of sndbuf, chop up message */ | 673 | /* If size is more than half of sndbuf, chop up message */ | 
| 669 | if (size > ((sk->sk_sndbuf >> 1) - 64)) | 674 | if (size > ((sk->sk_sndbuf >> 1) - 64)) | 
| @@ -673,14 +678,14 @@ static int caif_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 673 | size = SKB_MAX_ALLOC; | 678 | size = SKB_MAX_ALLOC; | 
| 674 | 679 | ||
| 675 | skb = sock_alloc_send_skb(sk, | 680 | skb = sock_alloc_send_skb(sk, | 
| 676 | size + CAIF_NEEDED_HEADROOM | 681 | size + cf_sk->headroom + | 
| 677 | + CAIF_NEEDED_TAILROOM, | 682 | cf_sk->tailroom, | 
| 678 | msg->msg_flags&MSG_DONTWAIT, | 683 | msg->msg_flags&MSG_DONTWAIT, | 
| 679 | &err); | 684 | &err); | 
| 680 | if (skb == NULL) | 685 | if (skb == NULL) | 
| 681 | goto out_err; | 686 | goto out_err; | 
| 682 | 687 | ||
| 683 | skb_reserve(skb, CAIF_NEEDED_HEADROOM); | 688 | skb_reserve(skb, cf_sk->headroom); | 
| 684 | /* | 689 | /* | 
| 685 | * If you pass two values to the sock_alloc_send_skb | 690 | * If you pass two values to the sock_alloc_send_skb | 
| 686 | * it tries to grab the large buffer with GFP_NOFS | 691 | * it tries to grab the large buffer with GFP_NOFS | 
| @@ -821,17 +826,15 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, | |||
| 821 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | 826 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | 
| 822 | long timeo; | 827 | long timeo; | 
| 823 | int err; | 828 | int err; | 
| 829 | int ifindex, headroom, tailroom; | ||
| 830 | struct net_device *dev; | ||
| 831 | |||
| 824 | lock_sock(sk); | 832 | lock_sock(sk); | 
| 825 | 833 | ||
| 826 | err = -EAFNOSUPPORT; | 834 | err = -EAFNOSUPPORT; | 
| 827 | if (uaddr->sa_family != AF_CAIF) | 835 | if (uaddr->sa_family != AF_CAIF) | 
| 828 | goto out; | 836 | goto out; | 
| 829 | 837 | ||
| 830 | err = -ESOCKTNOSUPPORT; | ||
| 831 | if (unlikely(!(sk->sk_type == SOCK_STREAM && | ||
| 832 | cf_sk->sk.sk_protocol == CAIFPROTO_AT) && | ||
| 833 | sk->sk_type != SOCK_SEQPACKET)) | ||
| 834 | goto out; | ||
| 835 | switch (sock->state) { | 838 | switch (sock->state) { | 
| 836 | case SS_UNCONNECTED: | 839 | case SS_UNCONNECTED: | 
| 837 | /* Normal case, a fresh connect */ | 840 | /* Normal case, a fresh connect */ | 
| @@ -874,8 +877,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, | |||
| 874 | sk_stream_kill_queues(&cf_sk->sk); | 877 | sk_stream_kill_queues(&cf_sk->sk); | 
| 875 | 878 | ||
| 876 | err = -EINVAL; | 879 | err = -EINVAL; | 
| 877 | if (addr_len != sizeof(struct sockaddr_caif) || | 880 | if (addr_len != sizeof(struct sockaddr_caif)) | 
| 878 | !uaddr) | ||
| 879 | goto out; | 881 | goto out; | 
| 880 | 882 | ||
| 881 | memcpy(&cf_sk->conn_req.sockaddr, uaddr, | 883 | memcpy(&cf_sk->conn_req.sockaddr, uaddr, | 
| @@ -888,12 +890,23 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, | |||
| 888 | dbfs_atomic_inc(&cnt.num_connect_req); | 890 | dbfs_atomic_inc(&cnt.num_connect_req); | 
| 889 | cf_sk->layer.receive = caif_sktrecv_cb; | 891 | cf_sk->layer.receive = caif_sktrecv_cb; | 
| 890 | err = caif_connect_client(&cf_sk->conn_req, | 892 | err = caif_connect_client(&cf_sk->conn_req, | 
| 891 | &cf_sk->layer); | 893 | &cf_sk->layer, &ifindex, &headroom, &tailroom); | 
| 892 | if (err < 0) { | 894 | if (err < 0) { | 
| 893 | cf_sk->sk.sk_socket->state = SS_UNCONNECTED; | 895 | cf_sk->sk.sk_socket->state = SS_UNCONNECTED; | 
| 894 | cf_sk->sk.sk_state = CAIF_DISCONNECTED; | 896 | cf_sk->sk.sk_state = CAIF_DISCONNECTED; | 
| 895 | goto out; | 897 | goto out; | 
| 896 | } | 898 | } | 
| 899 | dev = dev_get_by_index(sock_net(sk), ifindex); | ||
| 900 | cf_sk->headroom = LL_RESERVED_SPACE_EXTRA(dev, headroom); | ||
| 901 | cf_sk->tailroom = tailroom; | ||
| 902 | cf_sk->maxframe = dev->mtu - (headroom + tailroom); | ||
| 903 | dev_put(dev); | ||
| 904 | if (cf_sk->maxframe < 1) { | ||
| 905 | pr_warning("CAIF: %s(): CAIF Interface MTU too small (%d)\n", | ||
| 906 | __func__, dev->mtu); | ||
| 907 | err = -ENODEV; | ||
| 908 | goto out; | ||
| 909 | } | ||
| 897 | 910 | ||
| 898 | err = -EINPROGRESS; | 911 | err = -EINPROGRESS; | 
| 899 | wait_connect: | 912 | wait_connect: | 
