Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | /* 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_MSS 2 #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 */ |