mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
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: e27cca96cd
("xfrm: add espintcp (RFC 8229)")
Reported-by: Andrew Cagney <cagney@libreswan.org>
Tested-by: Andrew Cagney <cagney@libreswan.org>
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
17175d1a27
commit
ac1321efb1
@ -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,9 +298,10 @@ 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) {
|
||||
err = -ENOBUFS;
|
||||
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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user