Skip to content

KFunc bpf_sk_assign_tcp_reqsk

v6.11

Assign custom parameters used to validate SYN cookies.

Definition

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.

int bpf_sk_assign_tcp_reqsk(struct __sk_buff *s, struct sock *sk, struct bpf_tcp_req_attrs *attrs, int attrs__sz)

Usage

Under SYN Flood, the TCP stack generates SYN Cookie to remain stateless for the connection request until a valid ACK is responded to the SYN+ACK.

The cookie contains two kinds of host-specific bits, a timestamp and secrets, so only can it be validated by the generator. It means SYN Cookie consumes network resources between the client and the server; intermediate nodes must remember which nodes to route ACK for the cookie.

SYN Proxy reduces such unwanted resource allocation by handling 3WHS at the edge network. After SYN Proxy completes 3WHS, it forwards SYN to the backend server and completes another 3WHS. However, since the server's ISN differs from the cookie, the proxy must manage the ISN mappings and fix up SEQ/ACK numbers in every packet for each connection. If a proxy node goes down, all the connections through it are terminated. Keeping a state at proxy is painful from that perspective.

This kfunc allows BPF to validate an arbitrary SYN Cookie on the backend server, the proxy doesn't need not restore SYN nor pass it. After validating ACK, the proxy node just needs to forward it, and then the server can do the lightweight validation (e.g. check if ACK came from proxy nodes, etc) and create a connection from the ACK.

The arguments supplied to the kfunc can be derived from the SYN Cookie.

See also: patch set

Program types

The following program types can make use of this kfunc:

Example

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);