All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maxim Mikityanskiy <maximmi@nvidia.com>
To: <bpf@vger.kernel.org>, Alexei Starovoitov <ast@kernel.org>,
	"Daniel Borkmann" <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>, <netdev@vger.kernel.org>
Cc: "Tariq Toukan" <tariqt@nvidia.com>,
	"Martin KaFai Lau" <kafai@fb.com>,
	"Song Liu" <songliubraving@fb.com>, "Yonghong Song" <yhs@fb.com>,
	"John Fastabend" <john.fastabend@gmail.com>,
	"KP Singh" <kpsingh@kernel.org>,
	"David S. Miller" <davem@davemloft.net>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Petar Penkov" <ppenkov@google.com>,
	"Lorenz Bauer" <lmb@cloudflare.com>,
	"Eric Dumazet" <edumazet@google.com>,
	"Hideaki YOSHIFUJI" <yoshfuji@linux-ipv6.org>,
	"David Ahern" <dsahern@kernel.org>,
	"Shuah Khan" <shuah@kernel.org>,
	"Jesper Dangaard Brouer" <hawk@kernel.org>,
	"Nathan Chancellor" <nathan@kernel.org>,
	"Nick Desaulniers" <ndesaulniers@google.com>,
	"Joe Stringer" <joe@cilium.io>,
	"Florent Revest" <revest@chromium.org>,
	linux-kselftest@vger.kernel.org,
	"Toke Høiland-Jørgensen" <toke@toke.dk>,
	"Kumar Kartikeya Dwivedi" <memxor@gmail.com>,
	"Florian Westphal" <fw@strlen.de>,
	"Maxim Mikityanskiy" <maximmi@nvidia.com>
Subject: [PATCH bpf-next v2 1/3] bpf: Make errors of bpf_tcp_check_syncookie distinguishable
Date: Mon, 24 Jan 2022 17:13:38 +0200	[thread overview]
Message-ID: <20220124151340.376807-2-maximmi@nvidia.com> (raw)
In-Reply-To: <20220124151340.376807-1-maximmi@nvidia.com>

bpf_tcp_check_syncookie returns ambiguous error codes in some cases. The
list below shows various error conditions and matching error codes:

1. NULL socket: -EINVAL.

2. Invalid packet: -EINVAL, -ENOENT.

3. Bad cookie: -ENOENT.

4. Cookies are not in use: -EINVAL, -ENOENT.

5. Good cookie: 0.

As we see, the same error code may correspond to multiple error
conditions, making them undistinguishable, and at the same time one
error condition may return different codes, although it's typically
handled in the same way.

This patch reassigns error codes of bpf_tcp_check_syncookie and
documents them:

1. Invalid packet or NULL socket: -EINVAL;

2. Bad cookie: -EACCES.

3. Cookies are not in use: -ENOENT.

4. Good cookie: 0.

This change allows XDP programs to make smarter decisions based on error
code, because different error conditions are now easily distinguishable.

Backward compatibility shouldn't suffer because of these reasons:

1. The specific error codes weren't documented. The behavior that used
   to be documented (0 is good cookie, negative values are errors) still
   holds. Anyone who relied on implementation details should have
   understood the risks.

2. Two known usecases (classification of ACKs with cookies that initial
   new connections, SYN flood protection) take decisions which don't
   depend on specific error codes:

     Traffic classification:
       ACK packet is new, error == 0: classify as NEW.
       ACK packet is new, error < 0: classify as INVALID.

     SYN flood protection:
       ACK packet is new, error == 0: good cookie, XDP_PASS.
       ACK packet is new, error < 0: bad cookie, XDP_DROP.

   As Lorenz Bauer confirms, their implementation of traffic classifier
   won't break, as well as the kernel selftests.

3. It's hard to imagine that old error codes could be used for any
   useful decisions.

Signed-off-by: Maxim Mikityanskiy <maximmi@nvidia.com>
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
---
 include/uapi/linux/bpf.h       | 18 ++++++++++++++++--
 net/core/filter.c              |  6 +++---
 tools/include/uapi/linux/bpf.h | 18 ++++++++++++++++--
 3 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 16a7574292a5..4d2d4a09bf25 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -3575,8 +3575,22 @@ union bpf_attr {
  * 		*th* points to the start of the TCP header, while *th_len*
  * 		contains **sizeof**\ (**struct tcphdr**).
  * 	Return
- * 		0 if *iph* and *th* are a valid SYN cookie ACK, or a negative
- * 		error otherwise.
+ *		0 if *iph* and *th* are a valid SYN cookie ACK.
+ *
+ *		On failure, the returned value is one of the following:
+ *
+ *		**-EACCES** if the SYN cookie is not valid.
+ *
+ *		**-EINVAL** if the packet or input arguments are invalid.
+ *
+ *		**-ENOENT** if SYN cookies are not issued (no SYN flood, or SYN
+ *		cookies are disabled in sysctl).
+ *
+ *		**-EOPNOTSUPP** if the kernel configuration does not enable SYN
+ *		cookies (CONFIG_SYN_COOKIES is off).
+ *
+ *		**-EPROTONOSUPPORT** if the IP version is not 4 or 6 (or 6, but
+ *		CONFIG_IPV6 is disabled).
  *
  * long bpf_sysctl_get_name(struct bpf_sysctl *ctx, char *buf, size_t buf_len, u64 flags)
  *	Description
diff --git a/net/core/filter.c b/net/core/filter.c
index a06931c27eeb..18559b5828a3 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -6998,10 +6998,10 @@ BPF_CALL_5(bpf_tcp_check_syncookie, struct sock *, sk, void *, iph, u32, iph_len
 		return -EINVAL;
 
 	if (!sock_net(sk)->ipv4.sysctl_tcp_syncookies)
-		return -EINVAL;
+		return -ENOENT;
 
 	if (!th->ack || th->rst || th->syn)
-		return -ENOENT;
+		return -EINVAL;
 
 	if (tcp_synq_no_recent_overflow(sk))
 		return -ENOENT;
@@ -7032,7 +7032,7 @@ BPF_CALL_5(bpf_tcp_check_syncookie, struct sock *, sk, void *, iph, u32, iph_len
 	if (ret > 0)
 		return 0;
 
-	return -ENOENT;
+	return -EACCES;
 #else
 	return -ENOTSUPP;
 #endif
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 16a7574292a5..4d2d4a09bf25 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -3575,8 +3575,22 @@ union bpf_attr {
  * 		*th* points to the start of the TCP header, while *th_len*
  * 		contains **sizeof**\ (**struct tcphdr**).
  * 	Return
- * 		0 if *iph* and *th* are a valid SYN cookie ACK, or a negative
- * 		error otherwise.
+ *		0 if *iph* and *th* are a valid SYN cookie ACK.
+ *
+ *		On failure, the returned value is one of the following:
+ *
+ *		**-EACCES** if the SYN cookie is not valid.
+ *
+ *		**-EINVAL** if the packet or input arguments are invalid.
+ *
+ *		**-ENOENT** if SYN cookies are not issued (no SYN flood, or SYN
+ *		cookies are disabled in sysctl).
+ *
+ *		**-EOPNOTSUPP** if the kernel configuration does not enable SYN
+ *		cookies (CONFIG_SYN_COOKIES is off).
+ *
+ *		**-EPROTONOSUPPORT** if the IP version is not 4 or 6 (or 6, but
+ *		CONFIG_IPV6 is disabled).
  *
  * long bpf_sysctl_get_name(struct bpf_sysctl *ctx, char *buf, size_t buf_len, u64 flags)
  *	Description
-- 
2.30.2


  reply	other threads:[~2022-01-24 15:14 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-24 15:13 [PATCH bpf-next v2 0/3] New BPF helpers to accelerate synproxy Maxim Mikityanskiy
2022-01-24 15:13 ` Maxim Mikityanskiy [this message]
2022-01-25  7:38   ` [PATCH bpf-next v2 1/3] bpf: Make errors of bpf_tcp_check_syncookie distinguishable John Fastabend
2022-01-31 13:38     ` Maxim Mikityanskiy
2022-01-24 15:13 ` [PATCH bpf-next v2 2/3] bpf: Add helpers to issue and check SYN cookies in XDP Maxim Mikityanskiy
2022-01-25  7:54   ` John Fastabend
2022-01-31 13:38     ` Maxim Mikityanskiy
2022-01-31 21:12       ` John Fastabend
2022-01-31 21:19         ` John Fastabend
2022-02-02 11:09           ` Maxim Mikityanskiy
2022-02-04  2:50             ` John Fastabend
2022-02-04 14:08               ` Toke Høiland-Jørgensen
2022-02-21 14:26                 ` Maxim Mikityanskiy
2022-02-21 15:21                   ` Kumar Kartikeya Dwivedi
2022-02-24 14:29                     ` Maxim Mikityanskiy
2022-02-04  2:29       ` John Fastabend
2022-01-24 15:13 ` [PATCH bpf-next v2 3/3] bpf: Add selftests for raw syncookie helpers Maxim Mikityanskiy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220124151340.376807-2-maximmi@nvidia.com \
    --to=maximmi@nvidia.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@google.com \
    --cc=fw@strlen.de \
    --cc=hawk@kernel.org \
    --cc=joe@cilium.io \
    --cc=john.fastabend@gmail.com \
    --cc=kafai@fb.com \
    --cc=kpsingh@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=lmb@cloudflare.com \
    --cc=memxor@gmail.com \
    --cc=nathan@kernel.org \
    --cc=ndesaulniers@google.com \
    --cc=netdev@vger.kernel.org \
    --cc=ppenkov@google.com \
    --cc=revest@chromium.org \
    --cc=shuah@kernel.org \
    --cc=songliubraving@fb.com \
    --cc=tariqt@nvidia.com \
    --cc=toke@toke.dk \
    --cc=yhs@fb.com \
    --cc=yoshfuji@linux-ipv6.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.