Commit ac1321ef authored by Sabrina Dubroca's avatar Sabrina Dubroca Committed by Steffen Klassert
Browse files

espintcp: support non-blocking sends



Currently, non-blocking sends from userspace result in EOPNOTSUPP.

To support this, we need to tell espintcp_sendskb_locked() and
espintcp_sendskmsg_locked() that non-blocking operation was requested
from espintcp_sendmsg().

Fixes: e27cca96 ("xfrm: add espintcp (RFC 8229)")
Reported-by: default avatarAndrew Cagney <cagney@libreswan.org>
Tested-by: default avatarAndrew Cagney <cagney@libreswan.org>
Signed-off-by: default avatarSabrina Dubroca <sd@queasysnail.net>
Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
parent 17175d1a
Loading
Loading
Loading
Loading
+13 −13
Original line number Diff line number Diff line
@@ -213,7 +213,7 @@ retry:
	return 0;
}

static int espintcp_push_msgs(struct sock *sk)
static int espintcp_push_msgs(struct sock *sk, int flags)
{
	struct espintcp_ctx *ctx = espintcp_getctx(sk);
	struct espintcp_msg *emsg = &ctx->partial;
@@ -227,12 +227,12 @@ static int espintcp_push_msgs(struct sock *sk)
	ctx->tx_running = 1;

	if (emsg->skb)
		err = espintcp_sendskb_locked(sk, emsg, 0);
		err = espintcp_sendskb_locked(sk, emsg, flags);
	else
		err = espintcp_sendskmsg_locked(sk, emsg, 0);
		err = espintcp_sendskmsg_locked(sk, emsg, flags);
	if (err == -EAGAIN) {
		ctx->tx_running = 0;
		return 0;
		return flags & MSG_DONTWAIT ? -EAGAIN : 0;
	}
	if (!err)
		memset(emsg, 0, sizeof(*emsg));
@@ -257,7 +257,7 @@ int espintcp_push_skb(struct sock *sk, struct sk_buff *skb)
	offset = skb_transport_offset(skb);
	len = skb->len - offset;

	espintcp_push_msgs(sk);
	espintcp_push_msgs(sk, 0);

	if (emsg->len) {
		kfree_skb(skb);
@@ -270,7 +270,7 @@ int espintcp_push_skb(struct sock *sk, struct sk_buff *skb)
	emsg->len = len;
	emsg->skb = skb;

	espintcp_push_msgs(sk);
	espintcp_push_msgs(sk, 0);

	return 0;
}
@@ -287,7 +287,7 @@ static int espintcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
	char buf[2] = {0};
	int err, end;

	if (msg->msg_flags)
	if (msg->msg_flags & ~MSG_DONTWAIT)
		return -EOPNOTSUPP;

	if (size > MAX_ESPINTCP_MSG)
@@ -298,8 +298,9 @@ static int espintcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)

	lock_sock(sk);

	err = espintcp_push_msgs(sk);
	err = espintcp_push_msgs(sk, msg->msg_flags & MSG_DONTWAIT);
	if (err < 0) {
		if (err != -EAGAIN || !(msg->msg_flags & MSG_DONTWAIT))
			err = -ENOBUFS;
		goto unlock;
	}
@@ -337,10 +338,9 @@ static int espintcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)

	tcp_rate_check_app_limited(sk);

	err = espintcp_push_msgs(sk);
	err = espintcp_push_msgs(sk, msg->msg_flags & MSG_DONTWAIT);
	/* this message could be partially sent, keep it */
	if (err < 0)
		goto unlock;

	release_sock(sk);

	return size;
@@ -374,7 +374,7 @@ static void espintcp_tx_work(struct work_struct *work)

	lock_sock(sk);
	if (!ctx->tx_running)
		espintcp_push_msgs(sk);
		espintcp_push_msgs(sk, 0);
	release_sock(sk);
}