2020-08-20 12:01:17 -07:00
/* 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 ) ) ;
}
2020-10-01 18:34:54 -07:00
static inline void set_hdr_cb_flags ( struct bpf_sock_ops * skops , __u32 extra )
2020-08-20 12:01:17 -07:00
{
bpf_sock_ops_cb_flags_set ( skops ,
skops - > bpf_sock_ops_cb_flags |
BPF_SOCK_OPS_PARSE_UNKNOWN_HDR_OPT_CB_FLAG |
2020-10-01 18:34:54 -07:00
BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG |
extra ) ;
2020-08-20 12:01:17 -07:00
}
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 */