From 76cd278721e896ce5f71d44a27b28dd14a8f82ec Mon Sep 17 00:00:00 2001 From: Dylan Reimerink Date: Tue, 15 Oct 2024 14:42:37 +0200 Subject: [PATCH 1/4] tools: Add tool to generate libbpf version tags This commit adds a tool that parses the libbpf.map file in the libbpf sources, then finds specific annotations in libbpf userspace pages and inserts the version tags for the functions in question. Signed-off-by: Dylan Reimerink --- Makefile | 18 +++-- tools/libbpf-tag-gen/main.go | 153 +++++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+), 6 deletions(-) create mode 100644 tools/libbpf-tag-gen/main.go diff --git a/Makefile b/Makefile index 3317241..218d6a9 100644 --- a/Makefile +++ b/Makefile @@ -51,28 +51,34 @@ serve: -w /docs -e "AS_USER=$$(id -u $${USER})" -e "AS_GROUP=$$(id -g $${USER})" \ "${IMAGE}:${VERSION}" "mkdocs serve -a 0.0.0.0:8000 --watch /docs/docs" -.PHONY: build-tools -build-tools: +.PHONY: build-spellcheck +build-spellcheck: ${CONTAINER_ENGINE} run --rm -v "${REPODIR}:/docs" -w /docs golang:latest bash -c \ - "CGO_ENABLED=0 go build -buildvcs=false -o /docs/tools/bin/spellcheck /docs/tools/spellcheck/. && \ + "CGO_ENABLED=0 go build -buildvcs=false -o /docs/tools/bin/spellcheck /docs/tools/spellcheck/." + +.PHONY: build-gen-tools +build-gen-tools: + ${CONTAINER_ENGINE} run --rm -v "${REPODIR}:/docs" -w /docs golang:latest bash -c \ + "CGO_ENABLED=0 go build -buildvcs=false -o /docs/tools/bin/libbpf-tag-gen /docs/tools/libbpf-tag-gen/. && \ CGO_ENABLED=0 go build -buildvcs=false -o /docs/tools/bin/helper-ref-gen /docs/tools/helper-ref-gen/. && \ CGO_ENABLED=0 go build -buildvcs=false -o /docs/tools/bin/feature-tag-gen /docs/tools/feature-tag-gen/. && \ - CGO_ENABLED=0 go build -buildvcs=false -o /docs/tools/bin/kfunc-gen /docs/tools/spellcheck/. && \ + CGO_ENABLED=0 go build -buildvcs=false -o /docs/tools/bin/kfunc-gen /docs/tools/kfunc-gen/. && \ CGO_ENABLED=0 go build -buildvcs=false -o /docs/tools/bin/mtu-calc /docs/tools/mtu-calc/. && \ CGO_ENABLED=0 go build -buildvcs=false -o /docs/tools/bin/helper-def-scraper /docs/tools/helper-def-scraper/." .PHONY: generate-docs -generate-docs: build-tools +generate-docs: build-gen-tools ${CONTAINER_ENGINE} run --rm -v "${REPODIR}:/docs" \ -w /docs -e "AS_USER=$$(id -u $${USER})" -e "AS_GROUP=$$(id -g $${USER})" "${IMAGE}:${VERSION}" \ "/docs/tools/bin/helper-ref-gen --project-root /docs && \ + /docs/tools/bin/libbpf-tag-gen --project-root /docs && \ /docs/tools/bin/feature-tag-gen --project-root /docs && \ /docs/tools/bin/kfunc-gen --project-root /docs && \ /docs/tools/bin/mtu-calc --project-root /docs && \ /docs/tools/bin/helper-def-scraper --helper-path /docs/docs/linux/helper-function" .PHONY: spellcheck -spellcheck: build-tools html +spellcheck: build-spellcheck html ${CONTAINER_ENGINE} run --rm -v "${REPODIR}:/docs" \ -w /docs -e "AS_USER=$$(id -u $${USER})" -e "AS_GROUP=$$(id -g $${USER})" "${IMAGE}:${VERSION}" \ "/docs/tools/bin/spellcheck --project-root /docs" diff --git a/tools/libbpf-tag-gen/main.go b/tools/libbpf-tag-gen/main.go new file mode 100644 index 0000000..7eb1683 --- /dev/null +++ b/tools/libbpf-tag-gen/main.go @@ -0,0 +1,153 @@ +package main + +import ( + "bufio" + "flag" + "fmt" + "io" + "net/http" + "os" + "path" + "strings" +) + +var projectroot = flag.String("project-root", "", "Root of the project") + +const libbpfMapURL = "https://raw.githubusercontent.com/libbpf/libbpf/refs/heads/master/src/libbpf.map" + +const ( + LIBBPF_TAG_START = "" + LIBBPF_TAG_END = "" +) + +func main() { + flag.Parse() + if *projectroot == "" { + panic("project-root is required") + } + + resp, err := http.Get(libbpfMapURL) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to download libbpf.map: %v\n", err) + os.Exit(1) + } + + defer resp.Body.Close() + funcToTag, err := parseLibbpfMap(resp.Body) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to parse libbpf.map: %v\n", err) + os.Exit(1) + } + + dirPath := path.Join(*projectroot, "docs", "ebpf-library", "libbpf", "userspace") + dirEntries, err := os.ReadDir(dirPath) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to read directory: %v\n", err) + os.Exit(1) + } + + for _, entry := range dirEntries { + if entry.IsDir() { + continue + } + if !strings.HasSuffix(entry.Name(), ".md") { + continue + } + + entrypath := path.Join([]string{*projectroot, "docs", "ebpf-library", "libbpf", "userspace", entry.Name()}...) + file, err := os.OpenFile(entrypath, os.O_RDWR, 0644) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to open file: %v\n", err) + continue + } + + fileContents, err := io.ReadAll(file) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to read file: %v\n", err) + continue + } + + funcName := strings.TrimSuffix(entry.Name(), ".md") + tag, ok := funcToTag[funcName] + if !ok { + fmt.Fprintf(os.Stderr, "Function %s not found in libbpf.map\n", funcName) + continue + } + + fileStr := string(fileContents) + startIndex := strings.Index(fileStr, LIBBPF_TAG_START) + endIndex := strings.Index(fileStr, LIBBPF_TAG_END) + + if startIndex == -1 || endIndex == -1 { + fmt.Fprintf(os.Stderr, "Skipping, can not find tag markers in file '%s'\n", entry.Name()) + continue + } + + var newFile strings.Builder + // Write everything before the marker + newFile.WriteString(fileStr[:startIndex]) + newFile.WriteString(LIBBPF_TAG_START) + fmt.Fprintf(&newFile, "\n[:octicons-tag-24: %s](https://github.com/libbpf/libbpf/releases/tag/v%s)\n", tag, tag) + newFile.WriteString(LIBBPF_TAG_END) + newFile.WriteString(fileStr[endIndex+len(LIBBPF_TAG_END):]) + + _, err = file.Seek(0, 0) + if err != nil { + panic(err) + } + + err = file.Truncate(0) + if err != nil { + panic(err) + } + + _, err = io.Copy(file, strings.NewReader(newFile.String())) + if err != nil { + panic(err) + } + file.Close() + } +} + +func parseLibbpfMap(body io.Reader) (map[string]string, error) { + scan := bufio.NewScanner(body) + funcToTag := make(map[string]string) + + for scan.Scan() { + line := scan.Text() + if strings.HasPrefix(strings.TrimSpace(line), "LIBBPF_") { + if err := parseBlock(scan, funcToTag); err != nil { + return nil, err + } + } + } + + return funcToTag, nil +} + +func parseBlock(scan *bufio.Scanner, funcToTag map[string]string) error { + line := scan.Text() + bareLine := strings.TrimSpace(line) + fields := strings.Fields(bareLine) + if len(fields) == 0 { + return nil + } + + tag := strings.TrimPrefix(fields[0], "LIBBPF_") + + for scan.Scan() { + line := scan.Text() + bareLine := strings.TrimSpace(line) + if strings.HasPrefix(bareLine, "}") { + break + } + + if strings.HasSuffix(bareLine, ":") { + continue + } + + funcToTag[bareLine[:len(bareLine)-1]] = tag + } + + return nil +} From fdf11759ceb6bd0f6dfc77dbbdf3ec6c95b1e1c5 Mon Sep 17 00:00:00 2001 From: Dylan Reimerink Date: Tue, 15 Oct 2024 14:47:04 +0200 Subject: [PATCH 2/4] libbpf: Added pages for libbpf_{major_version, minor_version, strerror} This commit adds pages for the libbpf_{major_version, minor_version, strerror} functions. These are simple functions, pages were added to prove the libbpf-tag-gen tool works as expected. Signed-off-by: Dylan Reimerink --- .aspell.en.pws | 1 + docs/ebpf-library/libbpf/SUMMARY.md | 2 +- docs/ebpf-library/libbpf/userspace/SUMMARY.md | 5 +++ docs/ebpf-library/libbpf/userspace/index.md | 38 +++++++++---------- .../libbpf/userspace/libbpf_major_version.md | 22 +++++++++++ .../libbpf/userspace/libbpf_minor_version.md | 22 +++++++++++ .../libbpf/userspace/libbpf_strerror.md | 30 +++++++++++++++ 7 files changed, 100 insertions(+), 20 deletions(-) create mode 100644 docs/ebpf-library/libbpf/userspace/SUMMARY.md create mode 100644 docs/ebpf-library/libbpf/userspace/libbpf_major_version.md create mode 100644 docs/ebpf-library/libbpf/userspace/libbpf_minor_version.md create mode 100644 docs/ebpf-library/libbpf/userspace/libbpf_strerror.md diff --git a/.aspell.en.pws b/.aspell.en.pws index 1665828..ecec8af 100644 --- a/.aspell.en.pws +++ b/.aspell.en.pws @@ -210,3 +210,4 @@ GID decl inlining backend +programmatically diff --git a/docs/ebpf-library/libbpf/SUMMARY.md b/docs/ebpf-library/libbpf/SUMMARY.md index c3afeba..1763ba1 100644 --- a/docs/ebpf-library/libbpf/SUMMARY.md +++ b/docs/ebpf-library/libbpf/SUMMARY.md @@ -1,4 +1,4 @@ * [`index.md`](index.md) -* [Userspace](userspace/index.md) +* [Userspace](userspace/) * [eBPF side](ebpf/index.md) * [Concepts](concepts/index.md) diff --git a/docs/ebpf-library/libbpf/userspace/SUMMARY.md b/docs/ebpf-library/libbpf/userspace/SUMMARY.md new file mode 100644 index 0000000..1f69842 --- /dev/null +++ b/docs/ebpf-library/libbpf/userspace/SUMMARY.md @@ -0,0 +1,5 @@ +- [index](index.md) +- Misc libbpf functions + - [`libbpf_major_version`](libbpf_major_version.md) + - [`libbpf_minor_version`](libbpf_minor_version.md) + - [`libbpf_strerror`](libbpf_strerror.md) diff --git a/docs/ebpf-library/libbpf/userspace/index.md b/docs/ebpf-library/libbpf/userspace/index.md index 9e993dd..712bd25 100644 --- a/docs/ebpf-library/libbpf/userspace/index.md +++ b/docs/ebpf-library/libbpf/userspace/index.md @@ -6,24 +6,6 @@ Definitions for the libbpf userspace library are split across a few different he In the `libbpf.h` header file you will find the high level APIs which do a lot of work for you under the hood. These are the most commonly used APIs. -* `libbpf_major_version` -* `libbpf_minor_version` -* `libbpf_version_string` -* `libbpf_strerror` -* `libbpf_bpf_attach_type_str` -* `libbpf_bpf_link_type_str` -* `libbpf_bpf_map_type_str` -* `libbpf_bpf_prog_type_str` -* `libbpf_set_print` -* `libbpf_prog_type_by_name` -* `libbpf_attach_type_by_name` -* `libbpf_find_vmlinux_btf_id` -* `libbpf_probe_bpf_prog_type` -* `libbpf_probe_bpf_map_type` -* `libbpf_probe_bpf_helper` -* `libbpf_num_possible_cpus` -* `libbpf_register_prog_handler` -* `libbpf_unregister_prog_handler` * BPF Object functions * `bpf_object__open` * `bpf_object__open_file` @@ -221,6 +203,25 @@ In the `libbpf.h` header file you will find the high level APIs which do a lot o * `bpf_linker__add_file` * `bpf_linker__finalize` * `bpf_linker__free` +* Misc libbpf functions + * [`libbpf_major_version`](libbpf_major_version.md) + * [`libbpf_minor_version`](libbpf_minor_version.md) + * `libbpf_version_string` + * [`libbpf_strerror`](libbpf_strerror.md) + * `libbpf_bpf_attach_type_str` + * `libbpf_bpf_link_type_str` + * `libbpf_bpf_map_type_str` + * `libbpf_bpf_prog_type_str` + * `libbpf_set_print` + * `libbpf_prog_type_by_name` + * `libbpf_attach_type_by_name` + * `libbpf_find_vmlinux_btf_id` + * `libbpf_probe_bpf_prog_type` + * `libbpf_probe_bpf_map_type` + * `libbpf_probe_bpf_helper` + * `libbpf_num_possible_cpus` + * `libbpf_register_prog_handler` + * `libbpf_unregister_prog_handler` ## BTF APIs @@ -359,7 +360,6 @@ In the `bpf.h` header file you will find the low level APIs which are used to in * `bpf_raw_tracepoint_open` * `bpf_task_fd_query` * `bpf_enable_stats` -* `bpf_enable_stats` * `bpf_prog_bind_map` * `bpf_prog_test_run_opts` * `bpf_token_create` diff --git a/docs/ebpf-library/libbpf/userspace/libbpf_major_version.md b/docs/ebpf-library/libbpf/userspace/libbpf_major_version.md new file mode 100644 index 0000000..db25ecb --- /dev/null +++ b/docs/ebpf-library/libbpf/userspace/libbpf_major_version.md @@ -0,0 +1,22 @@ +--- +title: "Libbpf userspace function 'libbpf_major_version'" +description: "This page documents the 'libbpf_major_version' libbpf userspace function, including its definition, usage, and examples." +--- +# Libbpf userspace function `libbpf_major_version` + + +[:octicons-tag-24: 0.6.0](https://github.com/libbpf/libbpf/releases/tag/v0.6.0) + + +## Definition + +`#!c __u32 libbpf_major_version(void)` + +## Usage + +This function returns the minor version of the libbpf library programmatically. Especially useful when dynamically linking against libbpf. + +### Example + +!!! example "Docs could be improved" + This part of the docs is incomplete, contributions are very welcome diff --git a/docs/ebpf-library/libbpf/userspace/libbpf_minor_version.md b/docs/ebpf-library/libbpf/userspace/libbpf_minor_version.md new file mode 100644 index 0000000..d7a2fbd --- /dev/null +++ b/docs/ebpf-library/libbpf/userspace/libbpf_minor_version.md @@ -0,0 +1,22 @@ +--- +title: "Libbpf userspace function 'libbpf_minor_version'" +description: "This page documents the 'libbpf_minor_version' libbpf userspace function, including its definition, usage, and examples." +--- +# Libbpf userspace function `libbpf_minor_version` + + +[:octicons-tag-24: 0.6.0](https://github.com/libbpf/libbpf/releases/tag/v0.6.0) + + +## Definition + +`#!c __u32 libbpf_minor_version(void)` + +## Usage + +This function returns the minor version of the libbpf library programmatically. Especially useful when dynamically linking against libbpf. + +### Example + +!!! example "Docs could be improved" + This part of the docs is incomplete, contributions are very welcome diff --git a/docs/ebpf-library/libbpf/userspace/libbpf_strerror.md b/docs/ebpf-library/libbpf/userspace/libbpf_strerror.md new file mode 100644 index 0000000..efb741b --- /dev/null +++ b/docs/ebpf-library/libbpf/userspace/libbpf_strerror.md @@ -0,0 +1,30 @@ +--- +title: "Libbpf userspace function 'libbpf_strerror'" +description: "This page documents the 'libbpf_strerror' libbpf userspace function, including its definition, usage, and examples." +--- +# Libbpf userspace function `libbpf_strerror` + + +[:octicons-tag-24: 0.0.1](https://github.com/libbpf/libbpf/releases/tag/v0.0.1) + + +Convert an error code into a human-readable string. + +## Definition + +`#!c int libbpf_strerror(int err, char *buf, size_t size)` + +`err` - error code to convert into a string + +`buf` - buffer to store the string + +`size` - size of the buffer + +## Usage + +This function converts an error code into a human-readable string. It is useful for debugging and logging purposes. + +### Example + +!!! example "Docs could be improved" + This part of the docs is incomplete, contributions are very welcome From 5c40691cdfe73445d3ce94d38e81309b094f625d Mon Sep 17 00:00:00 2001 From: Dylan Reimerink Date: Tue, 15 Oct 2024 14:49:49 +0200 Subject: [PATCH 3/4] tools/spellcheck: Remove project root from spellcheck output The spellcheck will output its best guess for the location of misspelled words in the markdown files. This is useful for the user to quickly find and fix the misspelled words. However, the output also includes the project root, which is likely different for every system including the host vs in a docker container. By removing the project root from the output, we get a relative path which most terminals can use to open the file as long as the working directory is the project root. Signed-off-by: Dylan Reimerink --- tools/spellcheck/main.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/spellcheck/main.go b/tools/spellcheck/main.go index 375f524..10a51c9 100644 --- a/tools/spellcheck/main.go +++ b/tools/spellcheck/main.go @@ -278,7 +278,8 @@ func checkFile(path string) error { fmt.Printf("Possible locations in markdown:\n") for _, loc := range possibleLocations { - fmt.Printf(" %s:%d:%d\n", loc.file, loc.line, loc.column+m.offset) + noRoot := strings.TrimPrefix(strings.TrimPrefix(loc.file, *projectroot), "/") + fmt.Printf(" %s:%d:%d\n", noRoot, loc.line, loc.column+m.offset) } } fmt.Println() From 6ddcdda5659c5795a3b10423f38bb4df89783f7d Mon Sep 17 00:00:00 2001 From: Dylan Reimerink Date: Tue, 15 Oct 2024 14:52:47 +0200 Subject: [PATCH 4/4] linux/helper-function: Update helper function signatures A few helper functions have been updated with a new `__bpf_fastcall` attribute. This commit updates the helper function signatures to reflect this change in the libbpf headers. Signed-off-by: Dylan Reimerink --- docs/linux/helper-function/bpf_get_smp_processor_id.md | 2 +- docs/linux/helper-function/bpf_kptr_xchg.md | 4 ++-- docs/linux/helper-function/bpf_loop.md | 2 +- docs/linux/helper-function/bpf_override_return.md | 2 -- docs/linux/helper-function/bpf_setsockopt.md | 2 +- 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/linux/helper-function/bpf_get_smp_processor_id.md b/docs/linux/helper-function/bpf_get_smp_processor_id.md index 987f8e1..46b757c 100644 --- a/docs/linux/helper-function/bpf_get_smp_processor_id.md +++ b/docs/linux/helper-function/bpf_get_smp_processor_id.md @@ -20,7 +20,7 @@ Get the SMP (symmetric multiprocessing) processor id. Note that all programs run The SMP id of the processor running the program. -`#!c static __u32 (* const bpf_get_smp_processor_id)(void) = (void *) 8;` +`#!c static __bpf_fastcall __u32 (* const bpf_get_smp_processor_id)(void) = (void *) 8;` ## Usage diff --git a/docs/linux/helper-function/bpf_kptr_xchg.md b/docs/linux/helper-function/bpf_kptr_xchg.md index e80d55a..1a9a3bd 100644 --- a/docs/linux/helper-function/bpf_kptr_xchg.md +++ b/docs/linux/helper-function/bpf_kptr_xchg.md @@ -14,13 +14,13 @@ description: "This page documents the 'bpf_kptr_xchg' eBPF helper function, incl -Exchange kptr at pointer _map_value_ with _ptr_, and return the old value. _ptr_ can be NULL, otherwise it must be a referenced pointer which will be released when this helper is called. +Exchange kptr at pointer _dst_ with _ptr_, and return the old value. _dst_ can be map value or local kptr. _ptr_ can be NULL, otherwise it must be a referenced pointer which will be released when this helper is called. ### Returns The old value of kptr (which can be NULL). The returned pointer if not NULL, is a reference which must be released using its corresponding release function, or moved into a BPF map before program exit. -`#!c static void *(* const bpf_kptr_xchg)(void *map_value, void *ptr) = (void *) 194;` +`#!c static void *(* const bpf_kptr_xchg)(void *dst, void *ptr) = (void *) 194;` ## Usage diff --git a/docs/linux/helper-function/bpf_loop.md b/docs/linux/helper-function/bpf_loop.md index b88518f..7c10fb1 100644 --- a/docs/linux/helper-function/bpf_loop.md +++ b/docs/linux/helper-function/bpf_loop.md @@ -16,7 +16,7 @@ description: "This page documents the 'bpf_loop' eBPF helper function, including For **nr_loops**, call **callback_fn** function with **callback_ctx** as the context parameter. The **callback_fn** should be a static function and the **callback_ctx** should be a pointer to the stack. The **flags** is used to control certain aspects of the helper. Currently, the **flags** must be 0. Currently, nr_loops is limited to 1 << 23 (~8 million) loops. -long (\_callback_fn)(u32 index, void \_ctx); +long (\_callback_fn)(u64 index, void \_ctx); where **index** is the current index in the loop. The index is zero-indexed. diff --git a/docs/linux/helper-function/bpf_override_return.md b/docs/linux/helper-function/bpf_override_return.md index d684c1b..654140e 100644 --- a/docs/linux/helper-function/bpf_override_return.md +++ b/docs/linux/helper-function/bpf_override_return.md @@ -20,8 +20,6 @@ This helper works by setting the PC (program counter) to an override function wh This helper has security implications, and thus is subject to restrictions. It is only available if the kernel was compiled with the **CONFIG_BPF_KPROBE_OVERRIDE** configuration option, and in this case it only works on functions tagged with **ALLOW_ERROR_INJECTION** in the kernel code. -Also, the helper is only available for the architectures having the CONFIG_FUNCTION_ERROR_INJECTION option. As of this writing, x86 architecture is the only one to support this feature. - ### Returns 0 diff --git a/docs/linux/helper-function/bpf_setsockopt.md b/docs/linux/helper-function/bpf_setsockopt.md index 641295a..3fa5ddb 100644 --- a/docs/linux/helper-function/bpf_setsockopt.md +++ b/docs/linux/helper-function/bpf_setsockopt.md @@ -26,7 +26,7 @@ This helper actually implements a subset of **setsockopt()**. It supports the fo * **SOL_SOCKET**, which supports the following _optname_s: **SO_RCVBUF**, **SO_SNDBUF**, **SO_MAX_PACING_RATE**, **SO_PRIORITY**, **SO_RCVLOWAT**, **SO_MARK**, **SO_BINDTODEVICE**, **SO_KEEPALIVE**, **SO_REUSEADDR**, **SO_REUSEPORT**, **SO_BINDTOIFINDEX**, **SO_TXREHASH**. * **IPPROTO_TCP**, which supports the following _optname_s: - **TCP_CONGESTION**, **TCP_BPF_IW**, **TCP_BPF_SNDCWND_CLAMP**, **TCP_SAVE_SYN**, **TCP_KEEPIDLE**, **TCP_KEEPINTVL**, **TCP_KEEPCNT**, **TCP_SYNCNT**, **TCP_USER_TIMEOUT**, **TCP_NOTSENT_LOWAT**, **TCP_NODELAY**, **TCP_MAXSEG**, **TCP_WINDOW_CLAMP**, **TCP_THIN_LINEAR_TIMEOUTS**, **TCP_BPF_DELACK_MAX**, **TCP_BPF_RTO_MIN**. * **IPPROTO_IP**, which supports _optname_ **IP_TOS**. + **TCP_CONGESTION**, **TCP_BPF_IW**, **TCP_BPF_SNDCWND_CLAMP**, **TCP_SAVE_SYN**, **TCP_KEEPIDLE**, **TCP_KEEPINTVL**, **TCP_KEEPCNT**, **TCP_SYNCNT**, **TCP_USER_TIMEOUT**, **TCP_NOTSENT_LOWAT**, **TCP_NODELAY**, **TCP_MAXSEG**, **TCP_WINDOW_CLAMP**, **TCP_THIN_LINEAR_TIMEOUTS**, **TCP_BPF_DELACK_MAX**, **TCP_BPF_RTO_MIN**, **TCP_BPF_SOCK_OPS_CB_FLAGS**. * **IPPROTO_IP**, which supports _optname_ **IP_TOS**. * **IPPROTO_IPV6**, which supports the following _optname_s: **IPV6_TCLASS**, **IPV6_AUTOFLOWLABEL**.