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(-)
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 9658513cf021681d20de2f4a581ca032d9d3dfdc..f1be4cd94e16953b39901046ede4381018e8a615 100644 --- a/drivers/net/ovpn/tcp.c +++ b/drivers/net/ovpn/tcp.c @@ -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: