mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
BACKPORT: tcp: Use a struct to represent a saved_syn
The TCP_SAVE_SYN has both the network header and tcp header. The total length of the saved syn packet is currently stored in the first 4 bytes (u32) of an array and the actual packet data is stored after that. A later patch will add a bpf helper that allows to get the tcp header alone from the saved syn without the network header. It will be more convenient to have a direct offset to a specific header instead of re-parsing it. This requires to separately store the network hdrlen. The total header length (i.e. network + tcp) is still needed for the current usage in getsockopt. Although this total length can be obtained by looking into the tcphdr and then get the (th->doff << 2), this patch chooses to directly store the tcp hdrlen in the second four bytes of this newly created "struct saved_syn". By using a new struct, it can give a readable name to each individual header length. Change-Id: I4ba88ba12fed185f61c74c01b4eaf7f09d26299b Signed-off-by: Martin KaFai Lau <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Reviewed-by: Eric Dumazet <[email protected]> Acked-by: John Fastabend <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
This commit is contained in:
parent
a7f9cb8aa6
commit
65c272f187
5 changed files with 29 additions and 15 deletions
|
|
@ -3699,20 +3699,21 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
|
|||
|
||||
lock_sock(sk);
|
||||
if (tp->saved_syn) {
|
||||
if (len < tp->saved_syn[0]) {
|
||||
if (put_user(tp->saved_syn[0], optlen)) {
|
||||
if (len < tcp_saved_syn_len(tp->saved_syn)) {
|
||||
if (put_user(tcp_saved_syn_len(tp->saved_syn),
|
||||
optlen)) {
|
||||
release_sock(sk);
|
||||
return -EFAULT;
|
||||
}
|
||||
release_sock(sk);
|
||||
return -EINVAL;
|
||||
}
|
||||
len = tp->saved_syn[0];
|
||||
len = tcp_saved_syn_len(tp->saved_syn);
|
||||
if (put_user(len, optlen)) {
|
||||
release_sock(sk);
|
||||
return -EFAULT;
|
||||
}
|
||||
if (copy_to_user(optval, tp->saved_syn + 1, len)) {
|
||||
if (copy_to_user(optval, tp->saved_syn->data, len)) {
|
||||
release_sock(sk);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6646,13 +6646,15 @@ static void tcp_reqsk_record_syn(const struct sock *sk,
|
|||
{
|
||||
if (tcp_sk(sk)->save_syn) {
|
||||
u32 len = skb_network_header_len(skb) + tcp_hdrlen(skb);
|
||||
u32 *copy;
|
||||
struct saved_syn *saved_syn;
|
||||
|
||||
copy = kmalloc(len + sizeof(u32), GFP_ATOMIC);
|
||||
if (copy) {
|
||||
copy[0] = len;
|
||||
memcpy(©[1], skb_network_header(skb), len);
|
||||
req->saved_syn = copy;
|
||||
saved_syn = kmalloc(struct_size(saved_syn, data, len),
|
||||
GFP_ATOMIC);
|
||||
if (saved_syn) {
|
||||
saved_syn->network_hdrlen = skb_network_header_len(skb);
|
||||
saved_syn->tcp_hdrlen = tcp_hdrlen(skb);
|
||||
memcpy(saved_syn->data, skb_network_header(skb), len);
|
||||
req->saved_syn = saved_syn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue