Commit 17240749 authored by Antonio Quartulli's avatar Antonio Quartulli Committed by Paolo Abeni
Browse files

skb: implement skb_send_sock_locked_with_flags()



When sending an skb over a socket using skb_send_sock_locked(),
it is currently not possible to specify any flag to be set in
msghdr->msg_flags.

However, we may want to pass flags the user may have specified,
like MSG_NOSIGNAL.

Extend __skb_send_sock() with a new argument 'flags' and add a
new interface named skb_send_sock_locked_with_flags().

Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>
Signed-off-by: default avatarAntonio Quartulli <antonio@openvpn.net>
Link: https://patch.msgid.link/20250415-b4-ovpn-v26-12-577f6097b964@openvpn.net


Reviewed-by: default avatarSabrina Dubroca <sd@queasysnail.net>
Tested-by: default avatarOleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 11851cbd
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -4145,6 +4145,8 @@ int skb_splice_bits(struct sk_buff *skb, struct sock *sk, unsigned int offset,
		    unsigned int flags);
int skb_send_sock_locked(struct sock *sk, struct sk_buff *skb, int offset,
			 int len);
int skb_send_sock_locked_with_flags(struct sock *sk, struct sk_buff *skb,
				    int offset, int len, int flags);
int skb_send_sock(struct sock *sk, struct sk_buff *skb, int offset, int len);
void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to);
unsigned int skb_zerocopy_headlen(const struct sk_buff *from);
+13 −5
Original line number Diff line number Diff line
@@ -3227,7 +3227,7 @@ static int sendmsg_unlocked(struct sock *sk, struct msghdr *msg)

typedef int (*sendmsg_func)(struct sock *sk, struct msghdr *msg);
static int __skb_send_sock(struct sock *sk, struct sk_buff *skb, int offset,
			   int len, sendmsg_func sendmsg)
			   int len, sendmsg_func sendmsg, int flags)
{
	unsigned int orig_len = len;
	struct sk_buff *head = skb;
@@ -3245,7 +3245,7 @@ static int __skb_send_sock(struct sock *sk, struct sk_buff *skb, int offset,
		kv.iov_base = skb->data + offset;
		kv.iov_len = slen;
		memset(&msg, 0, sizeof(msg));
		msg.msg_flags = MSG_DONTWAIT;
		msg.msg_flags = MSG_DONTWAIT | flags;

		iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, &kv, 1, slen);
		ret = INDIRECT_CALL_2(sendmsg, sendmsg_locked,
@@ -3282,7 +3282,8 @@ static int __skb_send_sock(struct sock *sk, struct sk_buff *skb, int offset,
		while (slen) {
			struct bio_vec bvec;
			struct msghdr msg = {
				.msg_flags = MSG_SPLICE_PAGES | MSG_DONTWAIT,
				.msg_flags = MSG_SPLICE_PAGES | MSG_DONTWAIT |
					     flags,
			};

			bvec_set_page(&bvec, skb_frag_page(frag), slen,
@@ -3328,14 +3329,21 @@ static int __skb_send_sock(struct sock *sk, struct sk_buff *skb, int offset,
int skb_send_sock_locked(struct sock *sk, struct sk_buff *skb, int offset,
			 int len)
{
	return __skb_send_sock(sk, skb, offset, len, sendmsg_locked);
	return __skb_send_sock(sk, skb, offset, len, sendmsg_locked, 0);
}
EXPORT_SYMBOL_GPL(skb_send_sock_locked);

int skb_send_sock_locked_with_flags(struct sock *sk, struct sk_buff *skb,
				    int offset, int len, int flags)
{
	return __skb_send_sock(sk, skb, offset, len, sendmsg_locked, flags);
}
EXPORT_SYMBOL_GPL(skb_send_sock_locked_with_flags);

/* Send skb data on a socket. Socket must be unlocked. */
int skb_send_sock(struct sock *sk, struct sk_buff *skb, int offset, int len)
{
	return __skb_send_sock(sk, skb, offset, len, sendmsg_unlocked);
	return __skb_send_sock(sk, skb, offset, len, sendmsg_unlocked, 0);
}

/**