diff options
author | Jason Wang <jasowang@redhat.com> | 2017-05-17 12:14:43 +0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-05-18 10:07:41 -0400 |
commit | ac77cfd4258fb8174766a92d118436da7f9dabf1 (patch) | |
tree | 214a5df92bdd4f822677764a09a682c2ca0d5400 /drivers/net/tun.c | |
parent | 49f96fd0cb3808e5ff96573f28b3dceb16eb6998 (diff) | |
download | op-kernel-dev-ac77cfd4258fb8174766a92d118436da7f9dabf1.zip op-kernel-dev-ac77cfd4258fb8174766a92d118436da7f9dabf1.tar.gz |
tun: support receiving skb through msg_control
This patch makes tun_recvmsg() can receive from skb from its caller
through msg_control. Vhost_net will be the first user.
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r-- | drivers/net/tun.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 3cbfc5c..f8041f9c 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1510,9 +1510,8 @@ out: static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, struct iov_iter *to, - int noblock) + int noblock, struct sk_buff *skb) { - struct sk_buff *skb; ssize_t ret; int err; @@ -1521,10 +1520,12 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, if (!iov_iter_count(to)) return 0; - /* Read frames from ring */ - skb = tun_ring_recv(tfile, noblock, &err); - if (!skb) - return err; + if (!skb) { + /* Read frames from ring */ + skb = tun_ring_recv(tfile, noblock, &err); + if (!skb) + return err; + } ret = tun_put_user(tun, tfile, skb, to); if (unlikely(ret < 0)) @@ -1544,7 +1545,7 @@ static ssize_t tun_chr_read_iter(struct kiocb *iocb, struct iov_iter *to) if (!tun) return -EBADFD; - ret = tun_do_read(tun, tfile, to, file->f_flags & O_NONBLOCK); + ret = tun_do_read(tun, tfile, to, file->f_flags & O_NONBLOCK, NULL); ret = min_t(ssize_t, ret, len); if (ret > 0) iocb->ki_pos = ret; @@ -1646,7 +1647,8 @@ static int tun_recvmsg(struct socket *sock, struct msghdr *m, size_t total_len, SOL_PACKET, TUN_TX_TIMESTAMP); goto out; } - ret = tun_do_read(tun, tfile, &m->msg_iter, flags & MSG_DONTWAIT); + ret = tun_do_read(tun, tfile, &m->msg_iter, flags & MSG_DONTWAIT, + m->msg_control); if (ret > (ssize_t)total_len) { m->msg_flags |= MSG_TRUNC; ret = flags & MSG_TRUNC ? ret : total_len; |