From: Jakub Sitnicki <jakub@cloudflare.com>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: bpf <bpf@vger.kernel.org>, Networking <netdev@vger.kernel.org>,
kernel-team <kernel-team@cloudflare.com>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
"David S. Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>,
Marek Majkowski <marek@cloudflare.com>
Subject: Re: [PATCH bpf-next v3 02/16] bpf: Introduce SK_LOOKUP program type with a dedicated attach point
Date: Fri, 10 Jul 2020 10:55:53 +0200 [thread overview]
Message-ID: <87blknagva.fsf@cloudflare.com> (raw)
In-Reply-To: <CAEf4Bza7URA60jnLJsPV__PwmhV8G8+cCihdqqsKDSdQ1CYr_w@mail.gmail.com>
On Fri, Jul 10, 2020 at 01:09 AM CEST, Andrii Nakryiko wrote:
> On Thu, Jul 9, 2020 at 6:25 AM Jakub Sitnicki <jakub@cloudflare.com> wrote:
>>
>> On Thu, Jul 09, 2020 at 06:08 AM CEST, Andrii Nakryiko wrote:
>> > On Thu, Jul 2, 2020 at 2:25 AM Jakub Sitnicki <jakub@cloudflare.com> wrote:
>> >>
>> >> Add a new program type BPF_PROG_TYPE_SK_LOOKUP with a dedicated attach type
>> >> BPF_SK_LOOKUP. The new program kind is to be invoked by the transport layer
>> >> when looking up a listening socket for a new connection request for
>> >> connection oriented protocols, or when looking up an unconnected socket for
>> >> a packet for connection-less protocols.
>> >>
>> >> When called, SK_LOOKUP BPF program can select a socket that will receive
>> >> the packet. This serves as a mechanism to overcome the limits of what
>> >> bind() API allows to express. Two use-cases driving this work are:
>> >>
>> >> (1) steer packets destined to an IP range, on fixed port to a socket
>> >>
>> >> 192.0.2.0/24, port 80 -> NGINX socket
>> >>
>> >> (2) steer packets destined to an IP address, on any port to a socket
>> >>
>> >> 198.51.100.1, any port -> L7 proxy socket
>> >>
>> >> In its run-time context program receives information about the packet that
>> >> triggered the socket lookup. Namely IP version, L4 protocol identifier, and
>> >> address 4-tuple. Context can be further extended to include ingress
>> >> interface identifier.
>> >>
>> >> To select a socket BPF program fetches it from a map holding socket
>> >> references, like SOCKMAP or SOCKHASH, and calls bpf_sk_assign(ctx, sk, ...)
>> >> helper to record the selection. Transport layer then uses the selected
>> >> socket as a result of socket lookup.
>> >>
>> >> This patch only enables the user to attach an SK_LOOKUP program to a
>> >> network namespace. Subsequent patches hook it up to run on local delivery
>> >> path in ipv4 and ipv6 stacks.
>> >>
>> >> Suggested-by: Marek Majkowski <marek@cloudflare.com>
>> >> Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
>> >> ---
>> >>
>> >> Notes:
>> >> v3:
>> >> - Allow bpf_sk_assign helper to replace previously selected socket only
>> >> when BPF_SK_LOOKUP_F_REPLACE flag is set, as a precaution for multiple
>> >> programs running in series to accidentally override each other's verdict.
>> >> - Let BPF program decide that load-balancing within a reuseport socket group
>> >> should be skipped for the socket selected with bpf_sk_assign() by passing
>> >> BPF_SK_LOOKUP_F_NO_REUSEPORT flag. (Martin)
>> >> - Extend struct bpf_sk_lookup program context with an 'sk' field containing
>> >> the selected socket with an intention for multiple attached program
>> >> running in series to see each other's choices. However, currently the
>> >> verifier doesn't allow checking if pointer is set.
>> >> - Use bpf-netns infra for link-based multi-program attachment. (Alexei)
>> >> - Get rid of macros in convert_ctx_access to make it easier to read.
>> >> - Disallow 1-,2-byte access to context fields containing IP addresses.
>> >>
>> >> v2:
>> >> - Make bpf_sk_assign reject sockets that don't use RCU freeing.
>> >> Update bpf_sk_assign docs accordingly. (Martin)
>> >> - Change bpf_sk_assign proto to take PTR_TO_SOCKET as argument. (Martin)
>> >> - Fix broken build when CONFIG_INET is not selected. (Martin)
>> >> - Rename bpf_sk_lookup{} src_/dst_* fields remote_/local_*. (Martin)
>> >> - Enforce BPF_SK_LOOKUP attach point on load & attach. (Martin)
>> >>
>> >> include/linux/bpf-netns.h | 3 +
>> >> include/linux/bpf_types.h | 2 +
>> >> include/linux/filter.h | 19 ++++
>> >> include/uapi/linux/bpf.h | 74 +++++++++++++++
>> >> kernel/bpf/net_namespace.c | 5 +
>> >> kernel/bpf/syscall.c | 9 ++
>> >> net/core/filter.c | 186 +++++++++++++++++++++++++++++++++++++
>> >> scripts/bpf_helpers_doc.py | 9 +-
>> >> 8 files changed, 306 insertions(+), 1 deletion(-)
>> >>
>>
>> [...]
>>
>> >> +
>> >> +static u32 sk_lookup_convert_ctx_access(enum bpf_access_type type,
>> >> + const struct bpf_insn *si,
>> >> + struct bpf_insn *insn_buf,
>> >> + struct bpf_prog *prog,
>> >> + u32 *target_size)
>> >
>> > Would it be too extreme to rely on BTF and direct memory access
>> > (similar to tp_raw, fentry/fexit, etc) for accessing context fields,
>> > instead of all this assembly rewrites? So instead of having
>> > bpf_sk_lookup and bpf_sk_lookup_kern, it will always be a full variant
>> > (bpf_sk_lookup_kern, or however we'd want to name it then) and
>> > verifier will just ensure that direct memory reads go to the right
>> > field boundaries?
>>
>> Sounds like a decision related to long-term vision. I'd appreciate input
>> from maintainers if this is the direction we want to go in.
>>
>> From implementation PoV - hard for me to say what would be needed to get
>> it working, I'm not familiar how BPF_TRACE_* attach types provide access
>> to context, so I'd need to look around and prototype it
>> first. (Actually, I'm not sure if you're asking if it is doable or you
>> already know?)
>
> I'm pretty sure it's doable with what we have in verifier, but I'm not
> sure about all the details and amount of work. So consider this an
> initiation of a medium-term discussion. I was also curious to hear an
> opinion from Alexei and Daniel whether that's would be the right way
> to do this moving forward (not necessarily with your changes, though).
From my side I can vouch that getting convert_ctx_access is not easy to
get right (at least for me) when backing structure is non-trivial,
e.g. has pointers or unions.
v4 will contain two fixes exactly in this area. I also have a patch for
how verifier handles narrow loads when load size <= target field size <
ctx field size.
That is to say, any alternative approach that "automates" this would be
very welcome.
I've accumulated quite a few changes already since v3, so I was planning
to roll out v4 to keep things moving while we continue the discussion.
>
>>
>> Off the top of my head, I have one concern, I'm exposing the selected
>> socket in the context. This is for the benefit of one program being
>> aware of other program's selection, if multiple programs are attached.
>>
>> I understand that any piece of data reachable from struct sock *, would
>> be readable by SK_LOOKUP prog (writes can be blocked in
>> is_valid_access). And that this is a desired property for tracing. Not
>> sure how to limit it for a network program that doesn't need all that
>> info.
>>
>> >
>> >> +{
>> >> + struct bpf_insn *insn = insn_buf;
>> >> +#if IS_ENABLED(CONFIG_IPV6)
>> >> + int off;
>> >> +#endif
>> >> +
>> >
>> > [...]
next prev parent reply other threads:[~2020-07-10 8:55 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-02 9:24 [PATCH bpf-next v3 00/16] Run a BPF program on socket lookup Jakub Sitnicki
2020-07-02 9:24 ` [PATCH bpf-next v3 01/16] bpf, netns: Handle multiple link attachments Jakub Sitnicki
2020-07-09 3:44 ` Andrii Nakryiko
2020-07-09 12:49 ` Jakub Sitnicki
2020-07-09 22:02 ` Andrii Nakryiko
2020-07-10 19:23 ` Jakub Sitnicki
2020-07-02 9:24 ` [PATCH bpf-next v3 02/16] bpf: Introduce SK_LOOKUP program type with a dedicated attach point Jakub Sitnicki
2020-07-04 18:42 ` Yonghong Song
2020-07-06 11:44 ` Jakub Sitnicki
2020-07-05 9:20 ` kernel test robot
2020-07-05 9:20 ` [RFC PATCH] bpf: sk_lookup_prog_ops can be static kernel test robot
2020-07-07 9:21 ` [PATCH bpf-next v3 02/16] bpf: Introduce SK_LOOKUP program type with a dedicated attach point Jakub Sitnicki
2020-07-09 4:08 ` Andrii Nakryiko
2020-07-09 13:25 ` Jakub Sitnicki
2020-07-09 23:09 ` Andrii Nakryiko
2020-07-10 8:55 ` Jakub Sitnicki [this message]
2020-07-02 9:24 ` [PATCH bpf-next v3 03/16] inet: Extract helper for selecting socket from reuseport group Jakub Sitnicki
2020-07-02 9:24 ` [PATCH bpf-next v3 04/16] inet: Run SK_LOOKUP BPF program on socket lookup Jakub Sitnicki
2020-07-02 10:27 ` Lorenz Bauer
2020-07-02 12:46 ` Jakub Sitnicki
2020-07-02 13:19 ` Lorenz Bauer
2020-07-06 11:24 ` Jakub Sitnicki
2020-07-06 12:06 ` Jakub Sitnicki
2020-07-02 9:24 ` [PATCH bpf-next v3 05/16] inet6: Extract helper for selecting socket from reuseport group Jakub Sitnicki
2020-07-02 9:24 ` [PATCH bpf-next v3 06/16] inet6: Run SK_LOOKUP BPF program on socket lookup Jakub Sitnicki
2020-07-02 9:24 ` [PATCH bpf-next v3 07/16] udp: Extract helper for selecting socket from reuseport group Jakub Sitnicki
2020-07-02 9:24 ` [PATCH bpf-next v3 08/16] udp: Run SK_LOOKUP BPF program on socket lookup Jakub Sitnicki
2020-07-02 9:24 ` [PATCH bpf-next v3 09/16] udp6: Extract helper for selecting socket from reuseport group Jakub Sitnicki
2020-07-02 9:24 ` [PATCH bpf-next v3 10/16] udp6: Run SK_LOOKUP BPF program on socket lookup Jakub Sitnicki
2020-07-02 14:51 ` kernel test robot
2020-07-03 13:04 ` Jakub Sitnicki
2020-07-02 9:24 ` [PATCH bpf-next v3 11/16] bpf: Sync linux/bpf.h to tools/ Jakub Sitnicki
2020-07-02 9:24 ` [PATCH bpf-next v3 12/16] libbpf: Add support for SK_LOOKUP program type Jakub Sitnicki
2020-07-09 4:23 ` Andrii Nakryiko
2020-07-09 15:51 ` Jakub Sitnicki
2020-07-09 23:13 ` Andrii Nakryiko
2020-07-10 8:37 ` Jakub Sitnicki
2020-07-10 18:55 ` Andrii Nakryiko
2020-07-10 19:24 ` Jakub Sitnicki
2020-07-02 9:24 ` [PATCH bpf-next v3 13/16] tools/bpftool: Add name mappings for SK_LOOKUP prog and attach type Jakub Sitnicki
2020-07-02 9:24 ` [PATCH bpf-next v3 14/16] selftests/bpf: Add verifier tests for bpf_sk_lookup context access Jakub Sitnicki
2020-07-02 9:24 ` [PATCH bpf-next v3 15/16] selftests/bpf: Rename test_sk_lookup_kern.c to test_ref_track_kern.c Jakub Sitnicki
2020-07-02 9:24 ` [PATCH bpf-next v3 16/16] selftests/bpf: Tests for BPF_SK_LOOKUP attach point Jakub Sitnicki
2020-07-02 11:01 ` Lorenz Bauer
2020-07-02 12:59 ` Jakub Sitnicki
2020-07-09 4:28 ` Andrii Nakryiko
2020-07-09 15:54 ` Jakub Sitnicki
2020-07-02 11:05 ` [PATCH bpf-next v3 00/16] Run a BPF program on socket lookup Lorenz Bauer
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=87blknagva.fsf@cloudflare.com \
--to=jakub@cloudflare.com \
--cc=andrii.nakryiko@gmail.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=kernel-team@cloudflare.com \
--cc=kuba@kernel.org \
--cc=marek@cloudflare.com \
--cc=netdev@vger.kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).