All of lore.kernel.org
 help / color / mirror / Atom feed
From: Martin KaFai Lau <martin.lau@linux.dev>
To: Kuniyuki Iwashima <kuniyu@amazon.com>
Cc: Kuniyuki Iwashima <kuni1840@gmail.com>,
	bpf@vger.kernel.org, netdev@vger.kernel.org,
	Daniel Xu <dxu@dxuuu.xyz>, Eric Dumazet <edumazet@google.com>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>
Subject: Re: [PATCH v5 bpf-next 6/6] selftest: bpf: Test bpf_sk_assign_tcp_reqsk().
Date: Wed, 13 Dec 2023 12:44:42 -0800	[thread overview]
Message-ID: <8fccb066-6d17-4fa8-ba67-287042046ea4@linux.dev> (raw)
In-Reply-To: <20231211073650.90819-7-kuniyu@amazon.com>

On 12/10/23 11:36 PM, Kuniyuki Iwashima wrote:
> This commit adds a sample selftest to demonstrate how we can use
> bpf_sk_assign_tcp_reqsk() as the backend of SYN Proxy.
> 
> The test creates IPv4/IPv6 x TCP/MPTCP connections and transfer
> messages over them on lo with BPF tc prog attached.
> 
> The tc prog will process SYN and returns SYN+ACK with the following
> ISN and TS.  In a real use case, this part will be done by other
> hosts.
> 
>          MSB                                   LSB
>    ISN:  | 31 ... 8 | 7 6 |   5 |    4 | 3 2 1 0 |
>          |   Hash_1 | MSS | ECN | SACK |  WScale |
> 
>    TS:   | 31 ... 8 |          7 ... 0           |
>          |   Random |           Hash_2           |
> 
>    WScale in SYN is reused in SYN+ACK.
> 
> The client returns ACK, and tc prog will recalculate ISN and TS
> from ACK and validate SYN Cookie.
> 
> If it's valid, the prog calls kfunc to allocate a reqsk for skb and
> configure the reqsk based on the argument created from SYN Cookie.
> 
> Later, the reqsk will be processed in cookie_v[46]_check() to create
> a connection.

The patch set looks good.

One thing I just noticed is about writing/reading bits into/from "struct 
tcp_options_received". More on this below.

[ ... ]

> +void test_tcp_custom_syncookie(void)
> +{
> +	struct test_tcp_custom_syncookie *skel;
> +	int i;
> +
> +	if (setup_netns())
> +		return;
> +
> +	skel = test_tcp_custom_syncookie__open_and_load();
> +	if (!ASSERT_OK_PTR(skel, "open_and_load"))
> +		return;
> +
> +	if (setup_tc(skel))
> +		goto destroy_skel;
> +
> +	for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
> +		skel->bss->handled_syn = false;
> +		skel->bss->handled_ack = false;
> +
> +		test__start_subtest(test_cases[i].name);


This should be tested with:

	if (!test__start_subtest(test_cases[i].name))
		continue;

to skip the create_connection(). Probably do it at the beginning of the for loop.

> +		create_connection(&test_cases[i]);
> +
> +		ASSERT_EQ(skel->bss->handled_syn, true, "SYN is not handled at tc.");
> +		ASSERT_EQ(skel->bss->handled_ack, true, "ACK is not handled at tc");
> +	}
> +
> +destroy_skel:
> +	system("tc qdisc del dev lo clsact");
> +
> +	test_tcp_custom_syncookie__destroy(skel);
> +}

[ ... ]

> +static int tcp_parse_option(__u32 index, struct tcp_syncookie *ctx)
> +{
> +	struct tcp_options_received *tcp_opt = &ctx->attr.tcp_opt;
> +	char opcode, opsize;
> +
> +	if (ctx->ptr + 1 > ctx->data_end)
> +		goto stop;
> +
> +	opcode = *ctx->ptr++;
> +
> +	if (opcode == TCPOPT_EOL)
> +		goto stop;
> +
> +	if (opcode == TCPOPT_NOP)
> +		goto next;
> +
> +	if (ctx->ptr + 1 > ctx->data_end)
> +		goto stop;
> +
> +	opsize = *ctx->ptr++;
> +
> +	if (opsize < 2)
> +		goto stop;
> +
> +	switch (opcode) {
> +	case TCPOPT_MSS:
> +		if (opsize == TCPOLEN_MSS && ctx->tcp->syn &&
> +		    ctx->ptr + (TCPOLEN_MSS - 2) < ctx->data_end)
> +			tcp_opt->mss_clamp = get_unaligned_be16(ctx->ptr);
> +		break;
> +	case TCPOPT_WINDOW:
> +		if (opsize == TCPOLEN_WINDOW && ctx->tcp->syn &&
> +		    ctx->ptr + (TCPOLEN_WINDOW - 2) < ctx->data_end) {
> +			tcp_opt->wscale_ok = 1;
> +			tcp_opt->snd_wscale = *ctx->ptr;

When writing to a bitfield of "struct tcp_options_received" which is a kernel 
struct, it needs to use the CO-RE api. The BPF_CORE_WRITE_BITFIELD has not been 
landed yet: 
https://lore.kernel.org/bpf/4d3dd215a4fd57d980733886f9c11a45e1a9adf3.1702325874.git.dxu@dxuuu.xyz/

The same for reading bitfield but BPF_CORE_READ_BITFIELD() has already been 
implemented in bpf_core_read.h

Once the BPF_CORE_WRITE_BITFIELD is landed, this test needs to be changed to use 
the BPF_CORE_{READ,WRITE}_BITFIELD.

> +		}
> +		break;
> +	case TCPOPT_TIMESTAMP:
> +		if (opsize == TCPOLEN_TIMESTAMP &&
> +		    ctx->ptr + (TCPOLEN_TIMESTAMP - 2) < ctx->data_end) {
> +			tcp_opt->saw_tstamp = 1;
> +			tcp_opt->rcv_tsval = get_unaligned_be32(ctx->ptr);
> +			tcp_opt->rcv_tsecr = get_unaligned_be32(ctx->ptr + 4);
> +
> +			if (ctx->tcp->syn && tcp_opt->rcv_tsecr)
> +				tcp_opt->tstamp_ok = 0;
> +			else
> +				tcp_opt->tstamp_ok = 1;
> +		}
> +		break;
> +	case TCPOPT_SACK_PERM:
> +		if (opsize == TCPOLEN_SACK_PERM && ctx->tcp->syn &&
> +		    ctx->ptr + (TCPOLEN_SACK_PERM - 2) < ctx->data_end)
> +			tcp_opt->sack_ok = 1;
> +		break;
> +	}
> +
> +	ctx->ptr += opsize - 2;
> +next:
> +	return 0;
> +stop:
> +	return 1;
> +}



  reply	other threads:[~2023-12-13 20:44 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-11  7:36 [PATCH v5 bpf-next 0/6] bpf: tcp: Support arbitrary SYN Cookie at TC Kuniyuki Iwashima
2023-12-11  7:36 ` [PATCH v5 bpf-next 1/6] tcp: Move tcp_ns_to_ts() to tcp.h Kuniyuki Iwashima
2023-12-11  7:36 ` [PATCH v5 bpf-next 2/6] tcp: Move skb_steal_sock() to request_sock.h Kuniyuki Iwashima
2023-12-11  7:36 ` [PATCH v5 bpf-next 3/6] bpf: tcp: Handle BPF SYN Cookie in skb_steal_sock() Kuniyuki Iwashima
2023-12-11  7:36 ` [PATCH v5 bpf-next 4/6] bpf: tcp: Handle BPF SYN Cookie in cookie_v[46]_check() Kuniyuki Iwashima
2023-12-11  7:36 ` [PATCH v5 bpf-next 5/6] bpf: tcp: Support arbitrary SYN Cookie Kuniyuki Iwashima
2023-12-11  7:36 ` [PATCH v5 bpf-next 6/6] selftest: bpf: Test bpf_sk_assign_tcp_reqsk() Kuniyuki Iwashima
2023-12-13 20:44   ` Martin KaFai Lau [this message]
2023-12-14  3:18     ` Kuniyuki Iwashima
2023-12-14  6:46       ` Martin KaFai Lau
2023-12-14  7:49         ` Kuniyuki Iwashima
2023-12-14 12:26           ` Kuniyuki Iwashima

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=8fccb066-6d17-4fa8-ba67-287042046ea4@linux.dev \
    --to=martin.lau@linux.dev \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=dxu@dxuuu.xyz \
    --cc=edumazet@google.com \
    --cc=kuni1840@gmail.com \
    --cc=kuniyu@amazon.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 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.