mirror of
https://github.com/netdata/libbpf.git
synced 2026-11-05 17:30:15 +08:00
bpf: tcp: Support parse/len/write header option hooks in bpf_tcp_ops
Add the TCP header option callbacks to the bpf_tcp_ops struct_ops type:
parse_hdr - parse the options of an incoming skb on an established
connection
hdr_opt_len - reserve space in the TCP header for bpf options
write_hdr_opt - write the reserved bpf options
These mirror the BPF_SOCK_OPS_PARSE_HDR_OPT_CB, _HDR_OPT_LEN_CB and
_WRITE_HDR_OPT_CB legacy sockops callbacks, but are exposed as struct_ops
members so a program can implement them with normal function signatures
and per-member helper sets.
The reserved header window is shared between the legacy sockops and
bpf_tcp_ops paths. tcp_{syn,synack,established}_options() first run the
legacy BPF_SOCK_OPS_HDR_OPT_LEN_CB and then call hdr_opt_len, so both
sources accumulate into opts->bpf_opt_len; at write time the legacy
options are emitted first and bpf_tcp_ops writes after them.
API design
bpf_tcp_ops overloads the sock_ops header-option helpers rather than
introducing a new API: bpf_reserve_hdr_opt(), bpf_store_hdr_opt() and
bpf_load_hdr_opt() are exposed per-member (reserve for hdr_opt_len,
store/load for write_hdr_opt, load for parse_hdr) and share the existing
kernel option-walking core via _bpf_sock_ops{store,load}hdr_opt(), with
the bpf_tcp_ops wrappers synthesizing a temporary bpf_sock_ops_kern from
the program ctx. This keeps a port from the legacy
BPF_SOCK_OPS*_HDR_OPT_CB callbacks mechanical (same helper calls) and
adds no new UAPI helper/kfunc surface.
An alternative considered was to drop the option helpers entirely: have
hdr_opt_len reserve space purely through its return value, and introduce
a dedicated TCP-header-option dynptr used for both reading and writing.
That is a cleaner, more self-contained interface, but it is a larger
change and does not reuse the legacy helpers, making a port from sockops
less mechanical. It can be pursued as a follow-up; the helper-based
interface here keeps this series focused on moving the hooks to
struct_ops.
The hdr_opt_len fast path in tcp_established_options() is gated by
cgroup_bpf_enabled(CGROUP_TCP_SOCK_OPS). Note this is a global,
per-attach-type static branch: it is enabled whenever any bpf_tcp_ops is
attached, even one that does not implement hdr_opt_len or that is attached
to a different cgroup. In those cases the block still runs but
bpf_tcp_ops_hdr_opt_len() no-ops via the per-member check in the dispatch
macro. A per-member/per-cgroup gate could be added later if the extra
fast-path work proves measurable.
Signed-off-by: Amery Hung <ameryhung@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Link: https://patch.msgid.link/20260917200542.3689605-13-ameryhung@gmail.com
This commit is contained in:
1 parent
a7ee927845
commit
bc48d4e164
1 file changed
+22
-13
+22
-13
@@ -4867,15 +4867,18 @@ union bpf_attr {
|
||||
* The non-negative copied *buf* length equal to or less than
|
||||
* *size* on success, or a negative error in case of failure.
|
||||
*
|
||||
* long bpf_load_hdr_opt(struct bpf_sock_ops *skops, void *searchby_res, u32 len, u64 flags)
|
||||
* long bpf_load_hdr_opt(void *ctx, void *searchby_res, u32 len, u64 flags)
|
||||
* Description
|
||||
* Load header option. Support reading a particular TCP header
|
||||
* option for bpf program (**BPF_PROG_TYPE_SOCK_OPS**).
|
||||
* option for bpf program (**BPF_PROG_TYPE_SOCK_OPS**). For the
|
||||
* **bpf_tcp_ops** struct_ops, this helper can be called from the
|
||||
* **parse_hdr**\ () and **write_hdr_opt**\ () operators.
|
||||
*
|
||||
* If *flags* is 0, it will search the option from the
|
||||
* *skops*\ **->skb_data**. The comment in **struct bpf_sock_ops**
|
||||
* has details on what skb_data contains under different
|
||||
* *skops*\ **->op**.
|
||||
* If *flags* is 0, it will search the option from the packet
|
||||
* associated with the current operation. For
|
||||
* **BPF_PROG_TYPE_SOCK_OPS**, the comment in
|
||||
* **struct bpf_sock_ops** has details on what skb_data
|
||||
* contains under different *op*.
|
||||
*
|
||||
* The first byte of the *searchby_res* specifies the
|
||||
* kind that it wants to search.
|
||||
@@ -4908,6 +4911,8 @@ union bpf_attr {
|
||||
*
|
||||
* * **BPF_LOAD_HDR_OPT_TCP_SYN** to search from the
|
||||
* saved_syn packet or the just-received syn packet.
|
||||
* Not supported by the **bpf_tcp_ops** struct_ops, which
|
||||
* rejects all flags.
|
||||
*
|
||||
* Return
|
||||
* > 0 when found, the header option is copied to *searchby_res*.
|
||||
@@ -4928,9 +4933,9 @@ union bpf_attr {
|
||||
* packet.
|
||||
*
|
||||
* **-EPERM** if the helper cannot be used under the current
|
||||
* *skops*\ **->op**.
|
||||
* operation.
|
||||
*
|
||||
* long bpf_store_hdr_opt(struct bpf_sock_ops *skops, const void *from, u32 len, u64 flags)
|
||||
* long bpf_store_hdr_opt(void *ctx, const void *from, u32 len, u64 flags)
|
||||
* Description
|
||||
* Store header option. The data will be copied
|
||||
* from buffer *from* with length *len* to the TCP header.
|
||||
@@ -4946,7 +4951,9 @@ union bpf_attr {
|
||||
* by searching the same option in the outgoing skb.
|
||||
*
|
||||
* This helper can only be called during
|
||||
* **BPF_SOCK_OPS_WRITE_HDR_OPT_CB**.
|
||||
* **BPF_SOCK_OPS_WRITE_HDR_OPT_CB**, or from the
|
||||
* **write_hdr_opt**\ () operator of the **bpf_tcp_ops**
|
||||
* struct_ops.
|
||||
*
|
||||
* Return
|
||||
* 0 on success, or negative error in case of failure:
|
||||
@@ -4961,9 +4968,9 @@ union bpf_attr {
|
||||
* **-EFAULT** on failure to parse the existing header options.
|
||||
*
|
||||
* **-EPERM** if the helper cannot be used under the current
|
||||
* *skops*\ **->op**.
|
||||
* operation.
|
||||
*
|
||||
* long bpf_reserve_hdr_opt(struct bpf_sock_ops *skops, u32 len, u64 flags)
|
||||
* long bpf_reserve_hdr_opt(void *ctx, u32 len, u64 flags)
|
||||
* Description
|
||||
* Reserve *len* bytes for the bpf header option. The
|
||||
* space will be used by **bpf_store_hdr_opt**\ () later in
|
||||
@@ -4973,7 +4980,9 @@ union bpf_attr {
|
||||
* the total number of bytes will be reserved.
|
||||
*
|
||||
* This helper can only be called during
|
||||
* **BPF_SOCK_OPS_HDR_OPT_LEN_CB**.
|
||||
* **BPF_SOCK_OPS_HDR_OPT_LEN_CB**, or from the
|
||||
* **hdr_opt_len**\ () operator of the **bpf_tcp_ops**
|
||||
* struct_ops.
|
||||
*
|
||||
* Return
|
||||
* 0 on success, or negative error in case of failure:
|
||||
@@ -4983,7 +4992,7 @@ union bpf_attr {
|
||||
* **-ENOSPC** if there is not enough space in the header.
|
||||
*
|
||||
* **-EPERM** if the helper cannot be used under the current
|
||||
* *skops*\ **->op**.
|
||||
* operation.
|
||||
*
|
||||
* void *bpf_inode_storage_get(struct bpf_map *map, void *inode, void *value, u64 flags)
|
||||
* Description
|
||||
|
||||
Reference in new issue
Block a user