All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kuniyuki Iwashima <kuniyu@amazon.com>
To: <martin.lau@linux.dev>
Cc: <andrii@kernel.org>, <ast@kernel.org>, <bpf@vger.kernel.org>,
	<daniel@iogearbox.net>, <edumazet@google.com>,
	<kuni1840@gmail.com>, <kuniyu@amazon.com>,
	<netdev@vger.kernel.org>, <pabeni@redhat.com>
Subject: Re: [PATCH v7 bpf-next 5/6] bpf: tcp: Support arbitrary SYN Cookie.
Date: Mon, 15 Jan 2024 12:13:01 -0800	[thread overview]
Message-ID: <20240115201301.64265-1-kuniyu@amazon.com> (raw)
In-Reply-To: <aea7e756-9b3a-46b0-af27-207ba306b875@linux.dev>

From: Martin KaFai Lau <martin.lau@linux.dev>
Date: Thu, 11 Jan 2024 17:44:55 -0800
> On 12/20/23 5:28 PM, Kuniyuki Iwashima wrote:
> > This patch adds a new kfunc available at TC hook to support arbitrary
> > SYN Cookie.
> > 
> > The basic usage is as follows:
> > 
> >      struct bpf_tcp_req_attrs attrs = {
> >          .mss = mss,
> >          .wscale_ok = wscale_ok,
> >          .rcv_wscale = rcv_wscale, /* Server's WScale < 15 */
> >          .snd_wscale = snd_wscale, /* Client's WScale < 15 */
> >          .tstamp_ok = tstamp_ok,
> >          .rcv_tsval = tsval,
> >          .rcv_tsecr = tsecr, /* Server's Initial TSval */
> >          .usec_ts_ok = usec_ts_ok,
> >          .sack_ok = sack_ok,
> >          .ecn_ok = ecn_ok,
> >      }
> > 
> >      skc = bpf_skc_lookup_tcp(...);
> >      sk = (struct sock *)bpf_skc_to_tcp_sock(skc);
> >      bpf_sk_assign_tcp_reqsk(skb, sk, attrs, sizeof(attrs));
> >      bpf_sk_release(skc);
> > 
> > bpf_sk_assign_tcp_reqsk() takes skb, a listener sk, and struct
> > bpf_tcp_req_attrs and allocates reqsk and configures it.  Then,
> > bpf_sk_assign_tcp_reqsk() links reqsk with skb and the listener.
> > 
> > The notable thing here is that we do not hold refcnt for both reqsk
> > and listener.  To differentiate that, we mark reqsk->syncookie, which
> > is only used in TX for now.  So, if reqsk->syncookie is 1 in RX, it
> > means that the reqsk is allocated by kfunc.
> > 
> > When skb is freed, sock_pfree() checks if reqsk->syncookie is 1,
> > and in that case, we set NULL to reqsk->rsk_listener before calling
> > reqsk_free() as reqsk does not hold a refcnt of the listener.
> > 
> > When the TCP stack looks up a socket from the skb, we steal the
> > listener from the reqsk in skb_steal_sock() and create a full sk
> > in cookie_v[46]_check().
> > 
> > The refcnt of reqsk will finally be set to 1 in tcp_get_cookie_sock()
> > after creating a full sk.
> > 
> > Note that we can extend struct bpf_tcp_req_attrs in the future when
> > we add a new attribute that is determined in 3WHS.
> 
> Notice a few final details.
> 
> > 
> > Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
> > ---
> >   include/net/tcp.h |  13 ++++++
> >   net/core/filter.c | 113 +++++++++++++++++++++++++++++++++++++++++++++-
> >   net/core/sock.c   |  14 +++++-
> >   3 files changed, 136 insertions(+), 4 deletions(-)
> > 
> > diff --git a/include/net/tcp.h b/include/net/tcp.h
> > index a63916f41f77..20619df8819e 100644
> > --- a/include/net/tcp.h
> > +++ b/include/net/tcp.h
> > @@ -600,6 +600,19 @@ static inline bool cookie_ecn_ok(const struct net *net, const struct dst_entry *
> >   }
> >   
> >   #if IS_ENABLED(CONFIG_BPF)
> > +struct bpf_tcp_req_attrs {
> > +	u32 rcv_tsval;
> > +	u32 rcv_tsecr;
> > +	u16 mss;
> > +	u8 rcv_wscale;
> > +	u8 snd_wscale;
> > +	u8 ecn_ok;
> > +	u8 wscale_ok;
> > +	u8 sack_ok;
> > +	u8 tstamp_ok;
> > +	u8 usec_ts_ok;
> 
> Add "u8 reserved[3];" for the 3 bytes tail padding.
> 
> > +};
> > +
> >   static inline bool cookie_bpf_ok(struct sk_buff *skb)
> >   {
> >   	return skb->sk;
> > diff --git a/net/core/filter.c b/net/core/filter.c
> > index 24061f29c9dd..961c2d30bd72 100644
> > --- a/net/core/filter.c
> > +++ b/net/core/filter.c
> > @@ -11837,6 +11837,105 @@ __bpf_kfunc int bpf_sock_addr_set_sun_path(struct bpf_sock_addr_kern *sa_kern,
> >   
> >   	return 0;
> >   }
> > +
> > +__bpf_kfunc int bpf_sk_assign_tcp_reqsk(struct sk_buff *skb, struct sock *sk,
> > +					struct bpf_tcp_req_attrs *attrs, int attrs__sz)
> > +{
> > +#if IS_ENABLED(CONFIG_SYN_COOKIES)
> > +	const struct request_sock_ops *ops;
> > +	struct inet_request_sock *ireq;
> > +	struct tcp_request_sock *treq;
> > +	struct request_sock *req;
> > +	struct net *net;
> > +	__u16 min_mss;
> > +	u32 tsoff = 0;
> > +
> > +	if (attrs__sz != sizeof(*attrs))
> > +		return -EINVAL;
> > +
> > +	if (!sk)
> > +		return -EINVAL;
> > +
> > +	if (!skb_at_tc_ingress(skb))
> > +		return -EINVAL;
> > +
> > +	net = dev_net(skb->dev);
> > +	if (net != sock_net(sk))
> > +		return -ENETUNREACH;
> > +
> > +	switch (skb->protocol) {
> > +	case htons(ETH_P_IP):
> > +		ops = &tcp_request_sock_ops;
> > +		min_mss = 536;
> > +		break;
> > +#if IS_BUILTIN(CONFIG_IPV6)
> > +	case htons(ETH_P_IPV6):
> > +		ops = &tcp6_request_sock_ops;
> > +		min_mss = IPV6_MIN_MTU - 60;
> > +		break;
> > +#endif
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (sk->sk_type != SOCK_STREAM || sk->sk_state != TCP_LISTEN ||
> > +	    sk_is_mptcp(sk))
> > +		return -EINVAL;
> > +
> 
> and check for:
> 
> 	if (attrs->reserved[0] || attrs->reserved[1] || attrs->reserved[2])
> 		return -EINVAL;
> 
> It will be safer if it needs to extend "struct bpf_tcp_req_attrs". There is an 
> existing example in __bpf_nf_ct_lookup() when checking the 'struct bpf_ct_opts 
> *opts'.

I'll add that test in v8.

Thank you!

  reply	other threads:[~2024-01-15 20:13 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-21  1:28 [PATCH v7 bpf-next 0/6] bpf: tcp: Support arbitrary SYN Cookie at TC Kuniyuki Iwashima
2023-12-21  1:28 ` [PATCH v7 bpf-next 1/6] tcp: Move tcp_ns_to_ts() to tcp.h Kuniyuki Iwashima
2023-12-21  1:28 ` [PATCH v7 bpf-next 2/6] tcp: Move skb_steal_sock() to request_sock.h Kuniyuki Iwashima
2023-12-21  1:28 ` [PATCH v7 bpf-next 3/6] bpf: tcp: Handle BPF SYN Cookie in skb_steal_sock() Kuniyuki Iwashima
2023-12-21  1:28 ` [PATCH v7 bpf-next 4/6] bpf: tcp: Handle BPF SYN Cookie in cookie_v[46]_check() Kuniyuki Iwashima
2023-12-21  1:28 ` [PATCH v7 bpf-next 5/6] bpf: tcp: Support arbitrary SYN Cookie Kuniyuki Iwashima
2024-01-12  1:44   ` Martin KaFai Lau
2024-01-15 20:13     ` Kuniyuki Iwashima [this message]
2023-12-21  1:28 ` [PATCH v7 bpf-next 6/6] selftest: bpf: Test bpf_sk_assign_tcp_reqsk() Kuniyuki Iwashima
2023-12-21  6:35   ` Martin KaFai Lau
2023-12-21  7:04     ` Kuniyuki Iwashima
2023-12-21  8:43       ` Kuniyuki Iwashima
2024-01-02 19:17     ` Yonghong Song
2023-12-21 16:44   ` Matthieu Baerts
2024-01-12  6:20 ` [PATCH v7 bpf-next 0/6] bpf: tcp: Support arbitrary SYN Cookie at TC Martin KaFai Lau

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=20240115201301.64265-1-kuniyu@amazon.com \
    --to=kuniyu@amazon.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=edumazet@google.com \
    --cc=kuni1840@gmail.com \
    --cc=martin.lau@linux.dev \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    /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.