[PATCH v21 13/24] ovpn: add support for MSG_NOSIGNAL in tcp_sendmsg

From: Antonio Quartulli
Date: Mon Mar 03 2025 - 19:38:40 EST


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@xxxxxxxxxx>
Cc: Paolo Abeni <pabeni@xxxxxxxxxx>
Signed-off-by: Antonio Quartulli <antonio@xxxxxxxxxxx>
---
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 bd3cbcfc770d2c28d234fcdd081b4d02e6496ea0..64430880f1dae33a41f698d713cf151be5b38577 100644
--- a/drivers/net/ovpn/skb.h
+++ b/drivers/net/ovpn/skb.h
@@ -25,6 +25,7 @@ struct ovpn_cb {
struct scatterlist *sg;
u8 *iv;
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 a5bfd06bc9499b6886b42e039095bb8ce93994fb..e05c9ba0e0f5f74bd99fc0ed918fb93cd1f3d494 100644
--- a/drivers/net/ovpn/tcp.c
+++ b/drivers/net/ovpn/tcp.c
@@ -220,6 +220,7 @@ void ovpn_tcp_socket_wait_finish(struct ovpn_socket *sock)
static void ovpn_tcp_send_sock(struct ovpn_peer *peer, struct sock *sk)
{
struct sk_buff *skb = peer->tcp.out_msg.skb;
+ int ret, flags;

if (!skb)
return;
@@ -230,9 +231,11 @@ static void ovpn_tcp_send_sock(struct ovpn_peer *peer, struct sock *sk)
peer->tcp.tx_in_progress = true;

do {
- int ret = skb_send_sock_locked(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(sk, skb,
+ peer->tcp.out_msg.offset,
+ peer->tcp.out_msg.len,
+ flags);
if (unlikely(ret < 0)) {
if (ret == -EAGAIN)
goto out;
@@ -380,7 +383,7 @@ static int ovpn_tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
rcu_read_unlock();
peer = sock->peer;

- if (msg->msg_flags & ~MSG_DONTWAIT) {
+ if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_NOSIGNAL)) {
ret = -EOPNOTSUPP;
goto peer_free;
}
@@ -413,6 +416,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(peer, sk, skb);
ret = size;
peer_free:

--
2.45.3