@@ -24,6 +24,7 @@ struct ovpn_cb {
struct aead_request *req;
struct scatterlist *sg;
unsigned int payload_offset;
+ bool nosignal;
};
static inline struct ovpn_cb *ovpn_skb_cb(struct sk_buff *skb)
@@ -222,6 +222,7 @@ void ovpn_tcp_socket_detach(struct socket *sock)
static void ovpn_tcp_send_sock(struct ovpn_peer *peer)
{
struct sk_buff *skb = peer->tcp.out_msg.skb;
+ int ret, flags;
if (!skb)
return;
@@ -232,9 +233,11 @@ static void ovpn_tcp_send_sock(struct ovpn_peer *peer)
peer->tcp.tx_in_progress = true;
do {
- int ret = skb_send_sock_locked(peer->sock->sock->sk, skb,
- peer->tcp.out_msg.offset,
- peer->tcp.out_msg.len);
+ flags = ovpn_skb_cb(skb)->nosignal ? MSG_NOSIGNAL : 0;
+ ret = skb_send_sock_locked_with_flags(peer->sock->sock->sk, skb,
+ peer->tcp.out_msg.offset,
+ peer->tcp.out_msg.len,
+ flags);
if (unlikely(ret < 0)) {
if (ret == -EAGAIN)
goto out;
@@ -371,7 +374,7 @@ static int ovpn_tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
lock_sock(peer->sock->sock->sk);
- if (msg->msg_flags & ~MSG_DONTWAIT) {
+ if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_NOSIGNAL)) {
ret = -EOPNOTSUPP;
goto peer_free;
}
@@ -404,6 +407,7 @@ static int ovpn_tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
goto peer_free;
}
+ ovpn_skb_cb(skb)->nosignal = msg->msg_flags & MSG_NOSIGNAL;
ovpn_tcp_send_sock_skb(sock->peer, skb);
ret = size;
peer_free:
Userspace may want to pass the MSG_NOSIGNAL flag to tcp_sendmsg() in order to avoid generating a SIGPIPE. To pass this flag down the TCP stack a new skb sending API accepting a flags argument is introduced. Cc: Eric Dumazet <edumazet@google.com> Cc: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Antonio Quartulli <antonio@openvpn.net> --- drivers/net/ovpn/skb.h | 1 + drivers/net/ovpn/tcp.c | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-)