tools/testing/selftests/bpf/progs/test_tcp_hdr_options.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/progs/test_tcp_hdr_options.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/progs/test_tcp_hdr_options.c
Extension
.c
Size
14351 bytes
Lines
624
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2020 Facebook */

#include <stddef.h>
#include <errno.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/tcp.h>
#include <linux/socket.h>
#include <linux/bpf.h>
#include <linux/types.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_endian.h>
#define BPF_PROG_TEST_TCP_HDR_OPTIONS
#include "test_tcp_hdr_options.h"
#include "bpf_misc.h"

__u8 test_kind = TCPOPT_EXP;
__u16 test_magic = 0xeB9F;
__u32 inherit_cb_flags = 0;

struct bpf_test_option passive_synack_out = {};
struct bpf_test_option passive_fin_out	= {};

struct bpf_test_option passive_estab_in = {};
struct bpf_test_option passive_fin_in	= {};

struct bpf_test_option active_syn_out	= {};
struct bpf_test_option active_fin_out	= {};

struct bpf_test_option active_estab_in	= {};
struct bpf_test_option active_fin_in	= {};

struct {
	__uint(type, BPF_MAP_TYPE_SK_STORAGE);
	__uint(map_flags, BPF_F_NO_PREALLOC);
	__type(key, int);
	__type(value, struct hdr_stg);
} hdr_stg_map SEC(".maps");

static bool skops_want_cookie(const struct bpf_sock_ops *skops)
{
	return skops->args[0] == BPF_WRITE_HDR_TCP_SYNACK_COOKIE;
}

static bool skops_current_mss(const struct bpf_sock_ops *skops)
{
	return skops->args[0] == BPF_WRITE_HDR_TCP_CURRENT_MSS;
}

static __u8 option_total_len(__u8 flags)
{
	__u8 i, len = 1; /* +1 for flags */

	if (!flags)
		return 0;

	/* RESEND bit does not use a byte */
	for (i = OPTION_RESEND + 1; i < __NR_OPTION_FLAGS; i++)
		len += !!TEST_OPTION_FLAGS(flags, i);

	if (test_kind == TCPOPT_EXP)
		return len + TCP_BPF_EXPOPT_BASE_LEN;
	else
		return len + 2; /* +1 kind, +1 kind-len */
}

static void write_test_option(const struct bpf_test_option *test_opt,
			      __u8 *data)
{
	__u8 offset = 0;

	data[offset++] = test_opt->flags;
	if (TEST_OPTION_FLAGS(test_opt->flags, OPTION_MAX_DELACK_MS))
		data[offset++] = test_opt->max_delack_ms;

	if (TEST_OPTION_FLAGS(test_opt->flags, OPTION_RAND))
		data[offset++] = test_opt->rand;
}

static int store_option(struct bpf_sock_ops *skops,
			const struct bpf_test_option *test_opt)
{
	union {
		struct tcp_exprm_opt exprm;
		struct tcp_opt regular;
	} write_opt;
	int err;

Annotation

Implementation Notes