aboutsummaryrefslogtreecommitdiffstats
path: root/net/caif/caif_socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/caif/caif_socket.c')
-rw-r--r--net/caif/caif_socket.c152
1 files changed, 72 insertions, 80 deletions
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index c3a70c5c893a..8ce904786116 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -28,8 +28,8 @@
28MODULE_LICENSE("GPL"); 28MODULE_LICENSE("GPL");
29MODULE_ALIAS_NETPROTO(AF_CAIF); 29MODULE_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.
@@ -60,7 +60,7 @@ struct debug_fs_counter {
60 atomic_t num_rx_flow_off; 60 atomic_t num_rx_flow_off;
61 atomic_t num_rx_flow_on; 61 atomic_t num_rx_flow_on;
62}; 62};
63struct debug_fs_counter cnt; 63static struct debug_fs_counter cnt;
64#define dbfs_atomic_inc(v) atomic_inc(v) 64#define dbfs_atomic_inc(v) atomic_inc(v)
65#define dbfs_atomic_dec(v) atomic_dec(v) 65#define dbfs_atomic_dec(v) atomic_dec(v)
66#else 66#else
@@ -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
81static int rx_flow_is_on(struct caifsock *cf_sk) 82static int rx_flow_is_on(struct caifsock *cf_sk)
@@ -128,17 +129,17 @@ static void caif_read_unlock(struct sock *sk)
128 mutex_unlock(&cf_sk->readlock); 129 mutex_unlock(&cf_sk->readlock);
129} 130}
130 131
131int sk_rcvbuf_lowwater(struct caifsock *cf_sk) 132static int sk_rcvbuf_lowwater(struct caifsock *cf_sk)
132{ 133{
133 /* A quarter of full buffer is used a low water mark */ 134 /* A quarter of full buffer is used a low water mark */
134 return cf_sk->sk.sk_rcvbuf / 4; 135 return cf_sk->sk.sk_rcvbuf / 4;
135} 136}
136 137
137void caif_flow_ctrl(struct sock *sk, int mode) 138static void caif_flow_ctrl(struct sock *sk, int mode)
138{ 139{
139 struct caifsock *cf_sk; 140 struct caifsock *cf_sk;
140 cf_sk = container_of(sk, struct caifsock, sk); 141 cf_sk = container_of(sk, struct caifsock, sk);
141 if (cf_sk->layer.dn) 142 if (cf_sk->layer.dn && cf_sk->layer.dn->modemcmd)
142 cf_sk->layer.dn->modemcmd(cf_sk->layer.dn, mode); 143 cf_sk->layer.dn->modemcmd(cf_sk->layer.dn, mode);
143} 144}
144 145
@@ -146,7 +147,7 @@ void caif_flow_ctrl(struct sock *sk, int mode)
146 * Copied from sock.c:sock_queue_rcv_skb(), but changed so packets are 147 * Copied from sock.c:sock_queue_rcv_skb(), but changed so packets are
147 * not dropped, but CAIF is sending flow off instead. 148 * not dropped, but CAIF is sending flow off instead.
148 */ 149 */
149int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) 150static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
150{ 151{
151 int err; 152 int err;
152 int skb_len; 153 int skb_len;
@@ -162,9 +163,8 @@ int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
162 atomic_read(&cf_sk->sk.sk_rmem_alloc), 163 atomic_read(&cf_sk->sk.sk_rmem_alloc),
163 sk_rcvbuf_lowwater(cf_sk)); 164 sk_rcvbuf_lowwater(cf_sk));
164 set_rx_flow_off(cf_sk); 165 set_rx_flow_off(cf_sk);
165 if (cf_sk->layer.dn) 166 dbfs_atomic_inc(&cnt.num_rx_flow_off);
166 cf_sk->layer.dn->modemcmd(cf_sk->layer.dn, 167 caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ);
167 CAIF_MODEMCMD_FLOW_OFF_REQ);
168 } 168 }
169 169
170 err = sk_filter(sk, skb); 170 err = sk_filter(sk, skb);
@@ -175,9 +175,8 @@ int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
175 trace_printk("CAIF: %s():" 175 trace_printk("CAIF: %s():"
176 " sending flow OFF due to rmem_schedule\n", 176 " sending flow OFF due to rmem_schedule\n",
177 __func__); 177 __func__);
178 if (cf_sk->layer.dn) 178 dbfs_atomic_inc(&cnt.num_rx_flow_off);
179 cf_sk->layer.dn->modemcmd(cf_sk->layer.dn, 179 caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ);
180 CAIF_MODEMCMD_FLOW_OFF_REQ);
181 } 180 }
182 skb->dev = NULL; 181 skb->dev = NULL;
183 skb_set_owner_r(skb, sk); 182 skb_set_owner_r(skb, sk);
@@ -285,65 +284,51 @@ static void caif_check_flow_release(struct sock *sk)
285{ 284{
286 struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); 285 struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
287 286
288 if (cf_sk->layer.dn == NULL || cf_sk->layer.dn->modemcmd == NULL)
289 return;
290 if (rx_flow_is_on(cf_sk)) 287 if (rx_flow_is_on(cf_sk))
291 return; 288 return;
292 289
293 if (atomic_read(&sk->sk_rmem_alloc) <= sk_rcvbuf_lowwater(cf_sk)) { 290 if (atomic_read(&sk->sk_rmem_alloc) <= sk_rcvbuf_lowwater(cf_sk)) {
294 dbfs_atomic_inc(&cnt.num_rx_flow_on); 291 dbfs_atomic_inc(&cnt.num_rx_flow_on);
295 set_rx_flow_on(cf_sk); 292 set_rx_flow_on(cf_sk);
296 cf_sk->layer.dn->modemcmd(cf_sk->layer.dn, 293 caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_ON_REQ);
297 CAIF_MODEMCMD_FLOW_ON_REQ);
298 } 294 }
299} 295}
296
300/* 297/*
301 * Copied from sock.c:sock_queue_rcv_skb(), and added check that user buffer 298 * Copied from unix_dgram_recvmsg, but removed credit checks,
302 * has sufficient size. 299 * changed locking, address handling and added MSG_TRUNC.
303 */ 300 */
304
305static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock, 301static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock,
306 struct msghdr *m, size_t buf_len, int flags) 302 struct msghdr *m, size_t len, int flags)
307 303
308{ 304{
309 struct sock *sk = sock->sk; 305 struct sock *sk = sock->sk;
310 struct sk_buff *skb; 306 struct sk_buff *skb;
311 int ret = 0; 307 int ret;
312 int len; 308 int copylen;
313 309
314 if (unlikely(!buf_len)) 310 ret = -EOPNOTSUPP;
315 return -EINVAL; 311 if (m->msg_flags&MSG_OOB)
312 goto read_error;
316 313
317 skb = skb_recv_datagram(sk, flags, 0 , &ret); 314 skb = skb_recv_datagram(sk, flags, 0 , &ret);
318 if (!skb) 315 if (!skb)
319 goto read_error; 316 goto read_error;
320 317 copylen = skb->len;
321 len = skb->len; 318 if (len < copylen) {
322 319 m->msg_flags |= MSG_TRUNC;
323 if (skb && skb->len > buf_len && !(flags & MSG_PEEK)) { 320 copylen = len;
324 len = buf_len;
325 /*
326 * Push skb back on receive queue if buffer too small.
327 * This has a built-in race where multi-threaded receive
328 * may get packet in wrong order, but multiple read does
329 * not really guarantee ordered delivery anyway.
330 * Let's optimize for speed without taking locks.
331 */
332
333 skb_queue_head(&sk->sk_receive_queue, skb);
334 ret = -EMSGSIZE;
335 goto read_error;
336 } 321 }
337 322
338 ret = skb_copy_datagram_iovec(skb, 0, m->msg_iov, len); 323 ret = skb_copy_datagram_iovec(skb, 0, m->msg_iov, copylen);
339 if (ret) 324 if (ret)
340 goto read_error; 325 goto out_free;
341 326
327 ret = (flags & MSG_TRUNC) ? skb->len : copylen;
328out_free:
342 skb_free_datagram(sk, skb); 329 skb_free_datagram(sk, skb);
343
344 caif_check_flow_release(sk); 330 caif_check_flow_release(sk);
345 331 return ret;
346 return len;
347 332
348read_error: 333read_error:
349 return ret; 334 return ret;
@@ -610,27 +595,32 @@ static int caif_seqpkt_sendmsg(struct kiocb *kiocb, struct socket *sock,
610 goto err; 595 goto err;
611 noblock = msg->msg_flags & MSG_DONTWAIT; 596 noblock = msg->msg_flags & MSG_DONTWAIT;
612 597
613 buffer_size = len + CAIF_NEEDED_HEADROOM + CAIF_NEEDED_TAILROOM;
614
615 ret = -EMSGSIZE;
616 if (buffer_size > CAIF_MAX_PAYLOAD_SIZE)
617 goto err;
618
619 timeo = sock_sndtimeo(sk, noblock); 598 timeo = sock_sndtimeo(sk, noblock);
620 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),
621 1, timeo, &ret); 600 1, timeo, &ret);
622 601
602 if (ret)
603 goto err;
623 ret = -EPIPE; 604 ret = -EPIPE;
624 if (cf_sk->sk.sk_state != CAIF_CONNECTED || 605 if (cf_sk->sk.sk_state != CAIF_CONNECTED ||
625 sock_flag(sk, SOCK_DEAD) || 606 sock_flag(sk, SOCK_DEAD) ||
626 (sk->sk_shutdown & RCV_SHUTDOWN)) 607 (sk->sk_shutdown & RCV_SHUTDOWN))
627 goto err; 608 goto err;
628 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
629 ret = -ENOMEM; 617 ret = -ENOMEM;
630 skb = sock_alloc_send_skb(sk, buffer_size, noblock, &ret); 618 skb = sock_alloc_send_skb(sk, buffer_size, noblock, &ret);
631 if (!skb) 619
620 if (!skb || skb_tailroom(skb) < buffer_size)
632 goto err; 621 goto err;
633 skb_reserve(skb, CAIF_NEEDED_HEADROOM); 622
623 skb_reserve(skb, cf_sk->headroom);
634 624
635 ret = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); 625 ret = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
636 626
@@ -661,7 +651,6 @@ static int caif_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
661 long timeo; 651 long timeo;
662 652
663 err = -EOPNOTSUPP; 653 err = -EOPNOTSUPP;
664
665 if (unlikely(msg->msg_flags&MSG_OOB)) 654 if (unlikely(msg->msg_flags&MSG_OOB))
666 goto out_err; 655 goto out_err;
667 656
@@ -678,8 +667,8 @@ static int caif_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
678 667
679 size = len-sent; 668 size = len-sent;
680 669
681 if (size > CAIF_MAX_PAYLOAD_SIZE) 670 if (size > cf_sk->maxframe)
682 size = CAIF_MAX_PAYLOAD_SIZE; 671 size = cf_sk->maxframe;
683 672
684 /* If size is more than half of sndbuf, chop up message */ 673 /* If size is more than half of sndbuf, chop up message */
685 if (size > ((sk->sk_sndbuf >> 1) - 64)) 674 if (size > ((sk->sk_sndbuf >> 1) - 64))
@@ -689,14 +678,14 @@ static int caif_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
689 size = SKB_MAX_ALLOC; 678 size = SKB_MAX_ALLOC;
690 679
691 skb = sock_alloc_send_skb(sk, 680 skb = sock_alloc_send_skb(sk,
692 size + CAIF_NEEDED_HEADROOM 681 size + cf_sk->headroom +
693 + CAIF_NEEDED_TAILROOM, 682 cf_sk->tailroom,
694 msg->msg_flags&MSG_DONTWAIT, 683 msg->msg_flags&MSG_DONTWAIT,
695 &err); 684 &err);
696 if (skb == NULL) 685 if (skb == NULL)
697 goto out_err; 686 goto out_err;
698 687
699 skb_reserve(skb, CAIF_NEEDED_HEADROOM); 688 skb_reserve(skb, cf_sk->headroom);
700 /* 689 /*
701 * If you pass two values to the sock_alloc_send_skb 690 * If you pass two values to the sock_alloc_send_skb
702 * it tries to grab the large buffer with GFP_NOFS 691 * it tries to grab the large buffer with GFP_NOFS
@@ -837,17 +826,15 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
837 struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); 826 struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
838 long timeo; 827 long timeo;
839 int err; 828 int err;
829 int ifindex, headroom, tailroom;
830 struct net_device *dev;
831
840 lock_sock(sk); 832 lock_sock(sk);
841 833
842 err = -EAFNOSUPPORT; 834 err = -EAFNOSUPPORT;
843 if (uaddr->sa_family != AF_CAIF) 835 if (uaddr->sa_family != AF_CAIF)
844 goto out; 836 goto out;
845 837
846 err = -ESOCKTNOSUPPORT;
847 if (unlikely(!(sk->sk_type == SOCK_STREAM &&
848 cf_sk->sk.sk_protocol == CAIFPROTO_AT) &&
849 sk->sk_type != SOCK_SEQPACKET))
850 goto out;
851 switch (sock->state) { 838 switch (sock->state) {
852 case SS_UNCONNECTED: 839 case SS_UNCONNECTED:
853 /* Normal case, a fresh connect */ 840 /* Normal case, a fresh connect */
@@ -890,8 +877,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
890 sk_stream_kill_queues(&cf_sk->sk); 877 sk_stream_kill_queues(&cf_sk->sk);
891 878
892 err = -EINVAL; 879 err = -EINVAL;
893 if (addr_len != sizeof(struct sockaddr_caif) || 880 if (addr_len != sizeof(struct sockaddr_caif))
894 !uaddr)
895 goto out; 881 goto out;
896 882
897 memcpy(&cf_sk->conn_req.sockaddr, uaddr, 883 memcpy(&cf_sk->conn_req.sockaddr, uaddr,
@@ -904,12 +890,23 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
904 dbfs_atomic_inc(&cnt.num_connect_req); 890 dbfs_atomic_inc(&cnt.num_connect_req);
905 cf_sk->layer.receive = caif_sktrecv_cb; 891 cf_sk->layer.receive = caif_sktrecv_cb;
906 err = caif_connect_client(&cf_sk->conn_req, 892 err = caif_connect_client(&cf_sk->conn_req,
907 &cf_sk->layer); 893 &cf_sk->layer, &ifindex, &headroom, &tailroom);
908 if (err < 0) { 894 if (err < 0) {
909 cf_sk->sk.sk_socket->state = SS_UNCONNECTED; 895 cf_sk->sk.sk_socket->state = SS_UNCONNECTED;
910 cf_sk->sk.sk_state = CAIF_DISCONNECTED; 896 cf_sk->sk.sk_state = CAIF_DISCONNECTED;
911 goto out; 897 goto out;
912 } 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 }
913 910
914 err = -EINPROGRESS; 911 err = -EINPROGRESS;
915wait_connect: 912wait_connect:
@@ -920,17 +917,17 @@ wait_connect:
920 timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); 917 timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
921 918
922 release_sock(sk); 919 release_sock(sk);
923 err = wait_event_interruptible_timeout(*sk_sleep(sk), 920 err = -ERESTARTSYS;
921 timeo = wait_event_interruptible_timeout(*sk_sleep(sk),
924 sk->sk_state != CAIF_CONNECTING, 922 sk->sk_state != CAIF_CONNECTING,
925 timeo); 923 timeo);
926 lock_sock(sk); 924 lock_sock(sk);
927 if (err < 0) 925 if (timeo < 0)
928 goto out; /* -ERESTARTSYS */ 926 goto out; /* -ERESTARTSYS */
929 if (err == 0 && sk->sk_state != CAIF_CONNECTED) {
930 err = -ETIMEDOUT;
931 goto out;
932 }
933 927
928 err = -ETIMEDOUT;
929 if (timeo == 0 && sk->sk_state != CAIF_CONNECTED)
930 goto out;
934 if (sk->sk_state != CAIF_CONNECTED) { 931 if (sk->sk_state != CAIF_CONNECTED) {
935 sock->state = SS_UNCONNECTED; 932 sock->state = SS_UNCONNECTED;
936 err = sock_error(sk); 933 err = sock_error(sk);
@@ -945,7 +942,6 @@ out:
945 return err; 942 return err;
946} 943}
947 944
948
949/* 945/*
950 * caif_release() - Disconnect a CAIF Socket 946 * caif_release() - Disconnect a CAIF Socket
951 * Copied and modified af_irda.c:irda_release(). 947 * Copied and modified af_irda.c:irda_release().
@@ -1019,10 +1015,6 @@ static unsigned int caif_poll(struct file *file,
1019 (sk->sk_shutdown & RCV_SHUTDOWN)) 1015 (sk->sk_shutdown & RCV_SHUTDOWN))
1020 mask |= POLLIN | POLLRDNORM; 1016 mask |= POLLIN | POLLRDNORM;
1021 1017
1022 /* Connection-based need to check for termination and startup */
1023 if (sk->sk_state == CAIF_DISCONNECTED)
1024 mask |= POLLHUP;
1025
1026 /* 1018 /*
1027 * we set writable also when the other side has shut down the 1019 * we set writable also when the other side has shut down the
1028 * connection. This prevents stuck sockets. 1020 * connection. This prevents stuck sockets.
@@ -1194,7 +1186,7 @@ static struct net_proto_family caif_family_ops = {
1194 .owner = THIS_MODULE, 1186 .owner = THIS_MODULE,
1195}; 1187};
1196 1188
1197int af_caif_init(void) 1189static int af_caif_init(void)
1198{ 1190{
1199 int err = sock_register(&caif_family_ops); 1191 int err = sock_register(&caif_family_ops);
1200 if (!err) 1192 if (!err)