diff options
Diffstat (limited to 'tools/testing/selftests/bpf/test_tcp_hdr_options.h')
| -rw-r--r-- | tools/testing/selftests/bpf/test_tcp_hdr_options.h | 152 | 
1 files changed, 152 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/test_tcp_hdr_options.h b/tools/testing/selftests/bpf/test_tcp_hdr_options.h new file mode 100644 index 000000000000..6118e3ab61fc --- /dev/null +++ b/tools/testing/selftests/bpf/test_tcp_hdr_options.h @@ -0,0 +1,152 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2020 Facebook */ + +#ifndef _TEST_TCP_HDR_OPTIONS_H +#define _TEST_TCP_HDR_OPTIONS_H + +struct bpf_test_option { +	__u8 flags; +	__u8 max_delack_ms; +	__u8 rand; +} __attribute__((packed)); + +enum { +	OPTION_RESEND, +	OPTION_MAX_DELACK_MS, +	OPTION_RAND, +	__NR_OPTION_FLAGS, +}; + +#define OPTION_F_RESEND		(1 << OPTION_RESEND) +#define OPTION_F_MAX_DELACK_MS	(1 << OPTION_MAX_DELACK_MS) +#define OPTION_F_RAND		(1 << OPTION_RAND) +#define OPTION_MASK		((1 << __NR_OPTION_FLAGS) - 1) + +#define TEST_OPTION_FLAGS(flags, option) (1 & ((flags) >> (option))) +#define SET_OPTION_FLAGS(flags, option)	((flags) |= (1 << (option))) + +/* Store in bpf_sk_storage */ +struct hdr_stg { +	bool active; +	bool resend_syn; /* active side only */ +	bool syncookie;  /* passive side only */ +	bool fastopen;	/* passive side only */ +}; + +struct linum_err { +	unsigned int linum; +	int err; +}; + +#define TCPHDR_FIN 0x01 +#define TCPHDR_SYN 0x02 +#define TCPHDR_RST 0x04 +#define TCPHDR_PSH 0x08 +#define TCPHDR_ACK 0x10 +#define TCPHDR_URG 0x20 +#define TCPHDR_ECE 0x40 +#define TCPHDR_CWR 0x80 +#define TCPHDR_SYNACK (TCPHDR_SYN | TCPHDR_ACK) + +#define TCPOPT_EOL		0 +#define TCPOPT_NOP		1 +#define TCPOPT_WINDOW		3 +#define TCPOPT_EXP		254 + +#define TCP_BPF_EXPOPT_BASE_LEN 4 +#define MAX_TCP_HDR_LEN		60 +#define MAX_TCP_OPTION_SPACE	40 + +#ifdef BPF_PROG_TEST_TCP_HDR_OPTIONS + +#define CG_OK	1 +#define CG_ERR	0 + +#ifndef SOL_TCP +#define SOL_TCP 6 +#endif + +struct tcp_exprm_opt { +	__u8 kind; +	__u8 len; +	__u16 magic; +	union { +		__u8 data[4]; +		__u32 data32; +	}; +} __attribute__((packed)); + +struct tcp_opt { +	__u8 kind; +	__u8 len; +	union { +		__u8 data[4]; +		__u32 data32; +	}; +} __attribute__((packed)); + +struct { +	__uint(type, BPF_MAP_TYPE_HASH); +	__uint(max_entries, 2); +	__type(key, int); +	__type(value, struct linum_err); +} lport_linum_map SEC(".maps"); + +static inline unsigned int tcp_hdrlen(const struct tcphdr *th) +{ +	return th->doff << 2; +} + +static inline __u8 skops_tcp_flags(const struct bpf_sock_ops *skops) +{ +	return skops->skb_tcp_flags; +} + +static inline void clear_hdr_cb_flags(struct bpf_sock_ops *skops) +{ +	bpf_sock_ops_cb_flags_set(skops, +				  skops->bpf_sock_ops_cb_flags & +				  ~(BPF_SOCK_OPS_PARSE_UNKNOWN_HDR_OPT_CB_FLAG | +				    BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG)); +} + +static inline void set_hdr_cb_flags(struct bpf_sock_ops *skops, __u32 extra) +{ +	bpf_sock_ops_cb_flags_set(skops, +				  skops->bpf_sock_ops_cb_flags | +				  BPF_SOCK_OPS_PARSE_UNKNOWN_HDR_OPT_CB_FLAG | +				  BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG | +				  extra); +} +static inline void +clear_parse_all_hdr_cb_flags(struct bpf_sock_ops *skops) +{ +	bpf_sock_ops_cb_flags_set(skops, +				  skops->bpf_sock_ops_cb_flags & +				  ~BPF_SOCK_OPS_PARSE_ALL_HDR_OPT_CB_FLAG); +} + +static inline void +set_parse_all_hdr_cb_flags(struct bpf_sock_ops *skops) +{ +	bpf_sock_ops_cb_flags_set(skops, +				  skops->bpf_sock_ops_cb_flags | +				  BPF_SOCK_OPS_PARSE_ALL_HDR_OPT_CB_FLAG); +} + +#define RET_CG_ERR(__err) ({			\ +	struct linum_err __linum_err;		\ +	int __lport;				\ +						\ +	__linum_err.linum = __LINE__;		\ +	__linum_err.err = __err;		\ +	__lport = skops->local_port;		\ +	bpf_map_update_elem(&lport_linum_map, &__lport, &__linum_err, BPF_NOEXIST); \ +	clear_hdr_cb_flags(skops);					\ +	clear_parse_all_hdr_cb_flags(skops);				\ +	return CG_ERR;							\ +}) + +#endif /* BPF_PROG_TEST_TCP_HDR_OPTIONS */ + +#endif /* _TEST_TCP_HDR_OPTIONS_H */  | 
