On 2022-05-07 00:19, Andrii Nakryiko wrote:
On Tue, May 3, 2022 at 10:15 AM Maxim Mikityanskiy maximmi@nvidia.com wrote:
The new helpers bpf_tcp_raw_{gen,check}_syncookie_ipv{4,6} allow an XDP program to generate SYN cookies in response to TCP SYN packets and to check those cookies upon receiving the first ACK packet (the final packet of the TCP handshake).
Unlike bpf_tcp_{gen,check}_syncookie these new helpers don't need a listening socket on the local machine, which allows to use them together with synproxy to accelerate SYN cookie generation.
Signed-off-by: Maxim Mikityanskiy maximmi@nvidia.com Reviewed-by: Tariq Toukan tariqt@nvidia.com
include/net/tcp.h | 1 + include/uapi/linux/bpf.h | 78 ++++++++++++++++++++++ net/core/filter.c | 118 +++++++++++++++++++++++++++++++++ net/ipv4/tcp_input.c | 3 +- scripts/bpf_doc.py | 4 ++ tools/include/uapi/linux/bpf.h | 78 ++++++++++++++++++++++ 6 files changed, 281 insertions(+), 1 deletion(-)
diff --git a/include/net/tcp.h b/include/net/tcp.h index 94a52ad1101c..45aafc28ce00 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -432,6 +432,7 @@ u16 tcp_v4_get_syncookie(struct sock *sk, struct iphdr *iph, struct tcphdr *th, u32 *cookie); u16 tcp_v6_get_syncookie(struct sock *sk, struct ipv6hdr *iph, struct tcphdr *th, u32 *cookie); +u16 tcp_parse_mss_option(const struct tcphdr *th, u16 user_mss); u16 tcp_get_syncookie_mss(struct request_sock_ops *rsk_ops, const struct tcp_request_sock_ops *af_ops, struct sock *sk, struct tcphdr *th); diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 4dd9e34f2a60..5e611d898302 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -5156,6 +5156,80 @@ union bpf_attr {
if not NULL, is a reference which must be released using its
corresponding release function, or moved into a BPF map before
program exit.
- s64 bpf_tcp_raw_gen_syncookie_ipv4(struct iphdr *iph, struct tcphdr *th, u32 th_len)
Description
Try to issue a SYN cookie for the packet with corresponding
IPv4/TCP headers, *iph* and *th*, without depending on a
listening socket.
*iph* points to the IPv4 header.
*th* points to the start of the TCP header, while *th_len*
contains the length of the TCP header (at least
**sizeof**\ (**struct tcphdr**)).
Return
On success, lower 32 bits hold the generated SYN cookie in
followed by 16 bits which hold the MSS value for that cookie,
and the top 16 bits are unused.
On failure, the returned value is one of the following:
**-EINVAL** if *th_len* is invalid.
- s64 bpf_tcp_raw_gen_syncookie_ipv6(struct ipv6hdr *iph, struct tcphdr *th, u32 th_len)
Description
Try to issue a SYN cookie for the packet with corresponding
IPv6/TCP headers, *iph* and *th*, without depending on a
listening socket.
*iph* points to the IPv6 header.
*th* points to the start of the TCP header, while *th_len*
contains the length of the TCP header (at least
**sizeof**\ (**struct tcphdr**)).
Return
On success, lower 32 bits hold the generated SYN cookie in
followed by 16 bits which hold the MSS value for that cookie,
and the top 16 bits are unused.
On failure, the returned value is one of the following:
**-EINVAL** if *th_len* is invalid.
**-EPROTONOSUPPORT** if CONFIG_IPV6 is not builtin.
- int bpf_tcp_raw_check_syncookie_ipv4(struct iphdr *iph, struct tcphdr *th)
Note that all existing helpers that just return error or 0 on success return long. Please use long for consistency.
OK. There are some existing helpers that return int, though: bpf_inode_storage_delete, bpf_get_retval, bpf_set_retval. They should probably be fixed by someone as well.
Description
Check whether *iph* and *th* contain a valid SYN cookie ACK
without depending on a listening socket.
*iph* points to the IPv4 header.
*th* points to the TCP header.
Return
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.
- int bpf_tcp_raw_check_syncookie_ipv6(struct ipv6hdr *iph, struct tcphdr *th)
same
Description
Check whether *iph* and *th* contain a valid SYN cookie ACK
without depending on a listening socket.
*iph* points to the IPv6 header.
*th* points to the TCP header.
Return
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.
**-EPROTONOSUPPORT** if CONFIG_IPV6 is not builtin.
[...]