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 <eduma...@google.com>
Cc: Paolo Abeni <pab...@redhat.com>
Signed-off-by: Antonio Quartulli <anto...@openvpn.net>
---
 drivers/net/ovpn/skb.h |  1 +
 drivers/net/ovpn/tcp.c | 12 ++++++++----
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ovpn/skb.h b/drivers/net/ovpn/skb.h
index 
fd19cc3081227e01c4c1ef25155de614b2dc2795..67c6e1e4a79041198f554d7c534bc2373ca96033
 100644
--- a/drivers/net/ovpn/skb.h
+++ b/drivers/net/ovpn/skb.h
@@ -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)
diff --git a/drivers/net/ovpn/tcp.c b/drivers/net/ovpn/tcp.c
index 
f42b449b24d04ac247576d9de2c0513683e0072c..9776d87acc4742661423cd1824ac12b385889a97
 100644
--- a/drivers/net/ovpn/tcp.c
+++ b/drivers/net/ovpn/tcp.c
@@ -217,6 +217,7 @@ void ovpn_tcp_socket_detach(struct ovpn_socket *ovpn_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;
@@ -227,9 +228,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;
@@ -369,7 +372,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;
        }
@@ -402,6 +405,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:

-- 
2.45.2


Reply via email to