[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <05d060dc1169649d84c37ad51b0f8fe54a2a3185.1516147540.git.sowmini.varadhan@oracle.com>
Date: Wed, 17 Jan 2018 04:19:59 -0800
From: Sowmini Varadhan <sowmini.varadhan@...cle.com>
To: netdev@...r.kernel.org, willemdebruijn.kernel@...il.com
Cc: davem@...emloft.net, rds-devel@....oracle.com,
sowmini.varadhan@...cle.com, santosh.shilimkar@...cle.com
Subject: [PATCH RFC net-next 1/6] sock: MSG_PEEK support for sk_error_queue
Allow the application the ability to use MSG_PEEK with sk_error_queue
so that it can peek and re-read message in cases where MSG_TRUNC
may be encountered.
Signed-off-by: Sowmini Varadhan <sowmini.varadhan@...cle.com>
---
drivers/net/tun.c | 2 +-
include/net/sock.h | 2 +-
net/core/sock.c | 7 +++++--
net/packet/af_packet.c | 3 ++-
4 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 2fba3be..cfd0e0f 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -2313,7 +2313,7 @@ static int tun_recvmsg(struct socket *sock, struct msghdr *m, size_t total_len,
}
if (flags & MSG_ERRQUEUE) {
ret = sock_recv_errqueue(sock->sk, m, total_len,
- SOL_PACKET, TUN_TX_TIMESTAMP);
+ SOL_PACKET, TUN_TX_TIMESTAMP, flags);
goto out;
}
ret = tun_do_read(tun, tfile, &m->msg_iter, flags & MSG_DONTWAIT, ptr);
diff --git a/include/net/sock.h b/include/net/sock.h
index 73b7830..f0b6990 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2343,7 +2343,7 @@ static inline bool sk_listener(const struct sock *sk)
int sock_get_timestamp(struct sock *, struct timeval __user *);
int sock_get_timestampns(struct sock *, struct timespec __user *);
int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len, int level,
- int type);
+ int type, int flags);
bool sk_ns_capable(const struct sock *sk,
struct user_namespace *user_ns, int cap);
diff --git a/net/core/sock.c b/net/core/sock.c
index 72d14b2..4f52677 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2887,7 +2887,7 @@ void sock_enable_timestamp(struct sock *sk, int flag)
}
int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len,
- int level, int type)
+ int level, int type, int flags)
{
struct sock_exterr_skb *serr;
struct sk_buff *skb;
@@ -2916,7 +2916,10 @@ int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len,
err = copied;
out_free_skb:
- kfree_skb(skb);
+ if (likely(!(flags & MSG_PEEK)))
+ kfree_skb(skb);
+ else
+ skb_queue_head(&sk->sk_error_queue, skb);
out:
return err;
}
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index ee7aa0b..4314f31 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -3294,7 +3294,8 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
if (flags & MSG_ERRQUEUE) {
err = sock_recv_errqueue(sk, msg, len,
- SOL_PACKET, PACKET_TX_TIMESTAMP);
+ SOL_PACKET, PACKET_TX_TIMESTAMP,
+ flags);
goto out;
}
--
1.7.1
Powered by blists - more mailing lists