tun.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (c) 2018, Linaro Ltd */
  3. #include <linux/miscdevice.h>
  4. #include <linux/module.h>
  5. #include <linux/poll.h>
  6. #include <linux/skbuff.h>
  7. #include <linux/uaccess.h>
  8. #include "qrtr.h"
  9. struct qrtr_tun {
  10. struct qrtr_endpoint ep;
  11. struct sk_buff_head queue;
  12. wait_queue_head_t readq;
  13. };
  14. static int qrtr_tun_send(struct qrtr_endpoint *ep, struct sk_buff *skb)
  15. {
  16. struct qrtr_tun *tun = container_of(ep, struct qrtr_tun, ep);
  17. skb_queue_tail(&tun->queue, skb);
  18. /* wake up any blocking processes, waiting for new data */
  19. wake_up_interruptible(&tun->readq);
  20. return 0;
  21. }
  22. static int qrtr_tun_open(struct inode *inode, struct file *filp)
  23. {
  24. struct qrtr_tun *tun;
  25. int ret;
  26. tun = kzalloc(sizeof(*tun), GFP_KERNEL);
  27. if (!tun)
  28. return -ENOMEM;
  29. skb_queue_head_init(&tun->queue);
  30. init_waitqueue_head(&tun->readq);
  31. tun->ep.xmit = qrtr_tun_send;
  32. filp->private_data = tun;
  33. ret = qrtr_endpoint_register(&tun->ep, QRTR_EP_NET_ID_AUTO, 0);
  34. if (ret)
  35. goto out;
  36. return 0;
  37. out:
  38. filp->private_data = NULL;
  39. kfree(tun);
  40. return ret;
  41. }
  42. static ssize_t qrtr_tun_read_iter(struct kiocb *iocb, struct iov_iter *to)
  43. {
  44. struct file *filp = iocb->ki_filp;
  45. struct qrtr_tun *tun = filp->private_data;
  46. struct sk_buff *skb;
  47. int count;
  48. while (!(skb = skb_dequeue(&tun->queue))) {
  49. if (filp->f_flags & O_NONBLOCK)
  50. return -EAGAIN;
  51. /* Wait until we get data or the endpoint goes away */
  52. if (wait_event_interruptible(tun->readq,
  53. !skb_queue_empty(&tun->queue)))
  54. return -ERESTARTSYS;
  55. }
  56. count = min_t(size_t, iov_iter_count(to), skb->len);
  57. if (copy_to_iter(skb->data, count, to) != count)
  58. count = -EFAULT;
  59. kfree_skb(skb);
  60. return count;
  61. }
  62. static ssize_t qrtr_tun_write_iter(struct kiocb *iocb, struct iov_iter *from)
  63. {
  64. struct file *filp = iocb->ki_filp;
  65. struct qrtr_tun *tun = filp->private_data;
  66. size_t len = iov_iter_count(from);
  67. ssize_t ret;
  68. void *kbuf;
  69. if (!len)
  70. return -EINVAL;
  71. if (len > KMALLOC_MAX_SIZE)
  72. return -ENOMEM;
  73. kbuf = kzalloc(len, GFP_KERNEL);
  74. if (!kbuf)
  75. return -ENOMEM;
  76. if (!copy_from_iter_full(kbuf, len, from)) {
  77. kfree(kbuf);
  78. return -EFAULT;
  79. }
  80. ret = qrtr_endpoint_post(&tun->ep, kbuf, len);
  81. kfree(kbuf);
  82. return ret < 0 ? ret : len;
  83. }
  84. static __poll_t qrtr_tun_poll(struct file *filp, poll_table *wait)
  85. {
  86. struct qrtr_tun *tun = filp->private_data;
  87. __poll_t mask = 0;
  88. poll_wait(filp, &tun->readq, wait);
  89. if (!skb_queue_empty(&tun->queue))
  90. mask |= EPOLLIN | EPOLLRDNORM;
  91. return mask;
  92. }
  93. static int qrtr_tun_release(struct inode *inode, struct file *filp)
  94. {
  95. struct qrtr_tun *tun = filp->private_data;
  96. qrtr_endpoint_unregister(&tun->ep);
  97. /* Discard all SKBs */
  98. skb_queue_purge(&tun->queue);
  99. kfree(tun);
  100. return 0;
  101. }
  102. static const struct file_operations qrtr_tun_ops = {
  103. .owner = THIS_MODULE,
  104. .open = qrtr_tun_open,
  105. .poll = qrtr_tun_poll,
  106. .read_iter = qrtr_tun_read_iter,
  107. .write_iter = qrtr_tun_write_iter,
  108. .release = qrtr_tun_release,
  109. };
  110. static struct miscdevice qrtr_tun_miscdev = {
  111. MISC_DYNAMIC_MINOR,
  112. "qrtr-tun",
  113. &qrtr_tun_ops,
  114. };
  115. static int __init qrtr_tun_init(void)
  116. {
  117. int ret;
  118. ret = misc_register(&qrtr_tun_miscdev);
  119. if (ret)
  120. pr_err("failed to register Qualcomm IPC Router tun device\n");
  121. return ret;
  122. }
  123. static void __exit qrtr_tun_exit(void)
  124. {
  125. misc_deregister(&qrtr_tun_miscdev);
  126. }
  127. module_init(qrtr_tun_init);
  128. module_exit(qrtr_tun_exit);
  129. MODULE_DESCRIPTION("Qualcomm IPC Router TUN device");
  130. MODULE_LICENSE("GPL v2");