tun.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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. tun = kzalloc(sizeof(*tun), GFP_KERNEL);
  26. if (!tun)
  27. return -ENOMEM;
  28. skb_queue_head_init(&tun->queue);
  29. init_waitqueue_head(&tun->readq);
  30. tun->ep.xmit = qrtr_tun_send;
  31. filp->private_data = tun;
  32. return qrtr_endpoint_register(&tun->ep, QRTR_EP_NID_AUTO);
  33. }
  34. static ssize_t qrtr_tun_read_iter(struct kiocb *iocb, struct iov_iter *to)
  35. {
  36. struct file *filp = iocb->ki_filp;
  37. struct qrtr_tun *tun = filp->private_data;
  38. struct sk_buff *skb;
  39. int count;
  40. while (!(skb = skb_dequeue(&tun->queue))) {
  41. if (filp->f_flags & O_NONBLOCK)
  42. return -EAGAIN;
  43. /* Wait until we get data or the endpoint goes away */
  44. if (wait_event_interruptible(tun->readq,
  45. !skb_queue_empty(&tun->queue)))
  46. return -ERESTARTSYS;
  47. }
  48. count = min_t(size_t, iov_iter_count(to), skb->len);
  49. if (copy_to_iter(skb->data, count, to) != count)
  50. count = -EFAULT;
  51. kfree_skb(skb);
  52. return count;
  53. }
  54. static ssize_t qrtr_tun_write_iter(struct kiocb *iocb, struct iov_iter *from)
  55. {
  56. struct file *filp = iocb->ki_filp;
  57. struct qrtr_tun *tun = filp->private_data;
  58. size_t len = iov_iter_count(from);
  59. ssize_t ret;
  60. void *kbuf;
  61. kbuf = kzalloc(len, GFP_KERNEL);
  62. if (!kbuf)
  63. return -ENOMEM;
  64. if (!copy_from_iter_full(kbuf, len, from)) {
  65. kfree(kbuf);
  66. return -EFAULT;
  67. }
  68. ret = qrtr_endpoint_post(&tun->ep, kbuf, len);
  69. kfree(kbuf);
  70. return ret < 0 ? ret : len;
  71. }
  72. static __poll_t qrtr_tun_poll(struct file *filp, poll_table *wait)
  73. {
  74. struct qrtr_tun *tun = filp->private_data;
  75. __poll_t mask = 0;
  76. poll_wait(filp, &tun->readq, wait);
  77. if (!skb_queue_empty(&tun->queue))
  78. mask |= EPOLLIN | EPOLLRDNORM;
  79. return mask;
  80. }
  81. static int qrtr_tun_release(struct inode *inode, struct file *filp)
  82. {
  83. struct qrtr_tun *tun = filp->private_data;
  84. struct sk_buff *skb;
  85. qrtr_endpoint_unregister(&tun->ep);
  86. /* Discard all SKBs */
  87. while (!skb_queue_empty(&tun->queue)) {
  88. skb = skb_dequeue(&tun->queue);
  89. kfree_skb(skb);
  90. }
  91. kfree(tun);
  92. return 0;
  93. }
  94. static const struct file_operations qrtr_tun_ops = {
  95. .owner = THIS_MODULE,
  96. .open = qrtr_tun_open,
  97. .poll = qrtr_tun_poll,
  98. .read_iter = qrtr_tun_read_iter,
  99. .write_iter = qrtr_tun_write_iter,
  100. .release = qrtr_tun_release,
  101. };
  102. static struct miscdevice qrtr_tun_miscdev = {
  103. MISC_DYNAMIC_MINOR,
  104. "qrtr-tun",
  105. &qrtr_tun_ops,
  106. };
  107. static int __init qrtr_tun_init(void)
  108. {
  109. int ret;
  110. ret = misc_register(&qrtr_tun_miscdev);
  111. if (ret)
  112. pr_err("failed to register Qualcomm IPC Router tun device\n");
  113. return ret;
  114. }
  115. static void __exit qrtr_tun_exit(void)
  116. {
  117. misc_deregister(&qrtr_tun_miscdev);
  118. }
  119. module_init(qrtr_tun_init);
  120. module_exit(qrtr_tun_exit);
  121. MODULE_DESCRIPTION("Qualcomm IPC Router TUN device");
  122. MODULE_LICENSE("GPL v2");