Maxim Mikityanskiy wrote: > On 2022-01-25 09:54, John Fastabend wrote: > > Maxim Mikityanskiy wrote: > >> The new helpers bpf_tcp_raw_{gen,check}_syncookie 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@xxxxxxxxxx> > >> Reviewed-by: Tariq Toukan <tariqt@xxxxxxxxxx> > >> --- > > > > [...] > > > >> + > >> +BPF_CALL_4(bpf_tcp_raw_check_syncookie, void *, iph, u32, iph_len, > >> + struct tcphdr *, th, u32, th_len) > >> +{ > >> +#ifdef CONFIG_SYN_COOKIES > >> + u32 cookie; > >> + int ret; > >> + > >> + if (unlikely(th_len < sizeof(*th))) > >> + return -EINVAL; > >> + > >> + if (!th->ack || th->rst || th->syn) > >> + return -EINVAL; > >> + > >> + if (unlikely(iph_len < sizeof(struct iphdr))) > >> + return -EINVAL; > >> + > >> + cookie = ntohl(th->ack_seq) - 1; > >> + > >> + /* Both struct iphdr and struct ipv6hdr have the version field at the > >> + * same offset so we can cast to the shorter header (struct iphdr). > >> + */ > >> + switch (((struct iphdr *)iph)->version) { > >> + case 4: > > > > Did you consider just exposing __cookie_v4_check() and __cookie_v6_check()? > > No, I didn't, I just implemented it consistently with > bpf_tcp_check_syncookie, but let's consider it. > > I can't just pass a pointer from BPF without passing the size, so I > would need some wrappers around __cookie_v{4,6}_check anyway. The checks > for th_len and iph_len would have to stay in the helpers. The check for > TCP flags (ACK, !RST, !SYN) could be either in the helper or in BPF. The > switch would obviously be gone. I'm not sure you would need the len checks in helper, they provide some guarantees I guess, but the void * is just memory I don't see any checks on its size. It could be the last byte of a value for example? > > The bottom line is that it would be the same code, but without the > switch, and repeated twice. What benefit do you see in this approach? The only benefit would be to shave some instructions off the program. XDP is about performance so I figure we shouldn't be adding arbitrary stuff here. OTOH you're already jumping into a helper so it might not matter at all. > From my side, I only see the ability to drop one branch at the expense > of duplicating the code above the switch (th_len and iph_len checks). Just not sure you need the checks either, can you just assume the user gives good data? > > > My code at least has already run the code above before it would ever call > > this helper so all the other bits are duplicate. > > Sorry, I didn't quite understand this part. What "your code" are you > referring to? Just that the XDP code I maintain has a if ipv4 {...} else ipv6{...} structure in it so could use a v4_check... and v6_check... then call the correct version directly, removing the switch from the helper. Do you think there could be a performance reason to drop out those instructions or is it just hid by the hash itself. Also it seems a bit annoying if user is calling multiple helpers and they keep doing the same checks over and over.