tcp: Add saw_unknown to struct tcp_options_received
In a later patch, the bpf prog only wants to be called to handle a header option if that particular header option cannot be handled by the kernel. This unknown option could be written by the peer's bpf-prog. It could also be a new standard option that the running kernel does not support it while a bpf-prog can handle it. This patch adds a "saw_unknown" bit to "struct tcp_options_received" and it uses an existing one byte hole to do that. "saw_unknown" will be set in tcp_parse_options() if it sees an option that the kernel cannot handle. Signed-off-by: Martin KaFai Lau <kafai@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: Eric Dumazet <edumazet@google.com> Acked-by: John Fastabend <john.fastabend@gmail.com> Link: https://lore.kernel.org/bpf/20200820190033.2884430-1-kafai@fb.com
This commit is contained in:
parent
ca584ba070
commit
7656d68455
|
@ -92,6 +92,8 @@ struct tcp_options_received {
|
|||
smc_ok : 1, /* SMC seen on SYN packet */
|
||||
snd_wscale : 4, /* Window scaling received from sender */
|
||||
rcv_wscale : 4; /* Window scaling to send to receiver */
|
||||
u8 saw_unknown:1, /* Received unknown option */
|
||||
unused:7;
|
||||
u8 num_sacks; /* Number of SACK blocks */
|
||||
u16 user_mss; /* mss requested by user in ioctl */
|
||||
u16 mss_clamp; /* Maximal mss, negotiated at connection setup */
|
||||
|
|
|
@ -3801,7 +3801,7 @@ static void tcp_parse_fastopen_option(int len, const unsigned char *cookie,
|
|||
foc->exp = exp_opt;
|
||||
}
|
||||
|
||||
static void smc_parse_options(const struct tcphdr *th,
|
||||
static bool smc_parse_options(const struct tcphdr *th,
|
||||
struct tcp_options_received *opt_rx,
|
||||
const unsigned char *ptr,
|
||||
int opsize)
|
||||
|
@ -3810,10 +3810,13 @@ static void smc_parse_options(const struct tcphdr *th,
|
|||
if (static_branch_unlikely(&tcp_have_smc)) {
|
||||
if (th->syn && !(opsize & 1) &&
|
||||
opsize >= TCPOLEN_EXP_SMC_BASE &&
|
||||
get_unaligned_be32(ptr) == TCPOPT_SMC_MAGIC)
|
||||
get_unaligned_be32(ptr) == TCPOPT_SMC_MAGIC) {
|
||||
opt_rx->smc_ok = 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Try to parse the MSS option from the TCP header. Return 0 on failure, clamped
|
||||
|
@ -3874,6 +3877,7 @@ void tcp_parse_options(const struct net *net,
|
|||
|
||||
ptr = (const unsigned char *)(th + 1);
|
||||
opt_rx->saw_tstamp = 0;
|
||||
opt_rx->saw_unknown = 0;
|
||||
|
||||
while (length > 0) {
|
||||
int opcode = *ptr++;
|
||||
|
@ -3964,15 +3968,21 @@ void tcp_parse_options(const struct net *net,
|
|||
*/
|
||||
if (opsize >= TCPOLEN_EXP_FASTOPEN_BASE &&
|
||||
get_unaligned_be16(ptr) ==
|
||||
TCPOPT_FASTOPEN_MAGIC)
|
||||
TCPOPT_FASTOPEN_MAGIC) {
|
||||
tcp_parse_fastopen_option(opsize -
|
||||
TCPOLEN_EXP_FASTOPEN_BASE,
|
||||
ptr + 2, th->syn, foc, true);
|
||||
else
|
||||
smc_parse_options(th, opt_rx, ptr,
|
||||
opsize);
|
||||
break;
|
||||
}
|
||||
|
||||
if (smc_parse_options(th, opt_rx, ptr, opsize))
|
||||
break;
|
||||
|
||||
opt_rx->saw_unknown = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
opt_rx->saw_unknown = 1;
|
||||
}
|
||||
ptr += opsize-2;
|
||||
length -= opsize;
|
||||
|
|
Loading…
Reference in New Issue