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