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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/progs/test_misc_tcp_hdr_options.c
Extension
.c
Size
8877 bytes
Lines
343
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/ipv6.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"

__u16 last_addr16_n = __bpf_htons(1);
__u16 active_lport_n = 0;
__u16 active_lport_h = 0;
__u16 passive_lport_n = 0;
__u16 passive_lport_h = 0;

/* options received at passive side */
unsigned int nr_pure_ack = 0;
unsigned int nr_data = 0;
unsigned int nr_syn = 0;
unsigned int nr_fin = 0;
unsigned int nr_hwtstamp = 0;

bool nodelay_est_ok = false;
bool nodelay_hdr_len_reject = false;
bool nodelay_write_hdr_reject = false;

/* Check the header received from the active side */
static int __check_active_hdr_in(struct bpf_sock_ops *skops, bool check_syn)
{
	union {
		struct tcphdr th;
		struct ipv6hdr ip6;
		struct tcp_exprm_opt exprm_opt;
		struct tcp_opt reg_opt;
		__u8 data[100]; /* IPv6 (40) + Max TCP hdr (60) */
	} hdr = {};
	__u64 load_flags = check_syn ? BPF_LOAD_HDR_OPT_TCP_SYN : 0;
	struct tcphdr *pth;
	int ret;

	hdr.reg_opt.kind = 0xB9;

	/* The option is 4 bytes long instead of 2 bytes */
	ret = bpf_load_hdr_opt(skops, &hdr.reg_opt, 2, load_flags);
	if (ret != -ENOSPC)
		RET_CG_ERR(ret);

	/* Test searching magic with regular kind */
	hdr.reg_opt.len = 4;
	ret = bpf_load_hdr_opt(skops, &hdr.reg_opt, sizeof(hdr.reg_opt),
			       load_flags);
	if (ret != -EINVAL)
		RET_CG_ERR(ret);

	hdr.reg_opt.len = 0;
	ret = bpf_load_hdr_opt(skops, &hdr.reg_opt, sizeof(hdr.reg_opt),
			       load_flags);
	if (ret != 4 || hdr.reg_opt.len != 4 || hdr.reg_opt.kind != 0xB9 ||
	    hdr.reg_opt.data[0] != 0xfa || hdr.reg_opt.data[1] != 0xce)
		RET_CG_ERR(ret);

	/* Test searching experimental option with invalid kind length */
	hdr.exprm_opt.kind = TCPOPT_EXP;
	hdr.exprm_opt.len = 5;
	hdr.exprm_opt.magic = 0;
	ret = bpf_load_hdr_opt(skops, &hdr.exprm_opt, sizeof(hdr.exprm_opt),
			       load_flags);
	if (ret != -EINVAL)
		RET_CG_ERR(ret);

	/* Test searching experimental option with 0 magic value */
	hdr.exprm_opt.len = 4;
	ret = bpf_load_hdr_opt(skops, &hdr.exprm_opt, sizeof(hdr.exprm_opt),
			       load_flags);
	if (ret != -ENOMSG)
		RET_CG_ERR(ret);

	hdr.exprm_opt.magic = __bpf_htons(0xeB9F);
	ret = bpf_load_hdr_opt(skops, &hdr.exprm_opt, sizeof(hdr.exprm_opt),
			       load_flags);
	if (ret != 4 || hdr.exprm_opt.len != 4 ||

Annotation

Implementation Notes