@@ -49,30 +49,30 @@ static inline int read_tcp_options(struct xdp_md* xdp, struct tcphdr* tcp, __u32
49
49
struct tcp_options * opt ) {
50
50
__u8 opt_buf [80 ] = {};
51
51
__u32 len = (tcp -> doff << 2 ) - sizeof (* tcp );
52
- if (len > 80 ) { // TCP options too large
52
+ if (unlikely ( len > 80 ) ) { // TCP options too large
53
53
return XDP_DROP ;
54
54
} else if (len == 0 ) { // prevent zero-sized read
55
55
return XDP_PASS ;
56
56
} else {
57
- if (len < 2 ) len = 1 ;
57
+ if (unlikely ( len < 2 ) ) len = 1 ;
58
58
try_drop (bpf_xdp_load_bytes (xdp , ip_end + sizeof (* tcp ), opt_buf , len ));
59
59
}
60
60
61
61
for (__u32 i = 0 ; i < len ; i ++ ) {
62
- if (i > 80 - 1 ) return XDP_DROP ;
62
+ if (unlikely ( i > 80 - 1 ) ) return XDP_DROP ;
63
63
switch (opt_buf [i ]) {
64
64
case 0 : // end of option list
65
65
case 1 : // no-op
66
66
break ;
67
67
case 2 : // MSS
68
- if (i > 80 - 4 || opt_buf [i + 1 ] != 4 ) return XDP_DROP ;
68
+ if (unlikely ( i > 80 - 4 || opt_buf [i + 1 ] != 4 ) ) return XDP_DROP ;
69
69
opt -> mss = (opt_buf [i + 2 ] << 8 ) + opt_buf [i + 3 ];
70
70
i += 3 ;
71
71
break ;
72
72
default :
73
73
// HACK: `80 - 2` -> `80 - 3`
74
74
// mimic.bpf.o compiled with LLVM 18 failed eBPF verifier in Linux 6.6 or lower.
75
- if (i > 80 - 3 ) return XDP_DROP ;
75
+ if (unlikely ( i > 80 - 3 ) ) return XDP_DROP ;
76
76
__u8 l = opt_buf [i + 1 ];
77
77
if (l < 2 || i + l > len ) return XDP_DROP ;
78
78
i += l - 1 ;
@@ -92,24 +92,27 @@ int ingress_handler(struct xdp_md* xdp) {
92
92
struct ipv6hdr * ipv6 = NULL ;
93
93
__u32 ip_end , ip_payload_len , nexthdr = 0 ;
94
94
95
- if (eth_proto == ETH_P_IP ) {
96
- redecl_drop (struct iphdr , ipv4 , ETH_HLEN , xdp );
97
- ip_end = ETH_HLEN + (ipv4 -> ihl << 2 );
98
- ip_payload_len = ntohs (ipv4 -> tot_len ) - (ipv4 -> ihl << 2 );
99
- } else if (eth_proto == ETH_P_IPV6 ) {
100
- redecl_drop (struct ipv6hdr , ipv6 , ETH_HLEN , xdp );
101
- nexthdr = ipv6 -> nexthdr ;
102
- ip_end = ETH_HLEN + sizeof (* ipv6 );
103
- struct ipv6_opt_hdr * opt = NULL ;
104
- for (int i = 0 ; i < 8 ; i ++ ) {
105
- if (!ipv6_is_ext (nexthdr )) break ;
106
- redecl_drop (struct ipv6_opt_hdr , opt , ip_end , xdp );
107
- nexthdr = opt -> nexthdr ;
108
- ip_end += (opt -> hdrlen + 1 ) << 3 ;
109
- }
110
- ip_payload_len = ntohs (ipv6 -> payload_len );
111
- } else {
112
- return XDP_PASS ;
95
+ switch (eth_proto ) {
96
+ case ETH_P_IP :
97
+ redecl_drop (struct iphdr , ipv4 , ETH_HLEN , xdp );
98
+ ip_end = ETH_HLEN + (ipv4 -> ihl << 2 );
99
+ ip_payload_len = ntohs (ipv4 -> tot_len ) - (ipv4 -> ihl << 2 );
100
+ break ;
101
+ case ETH_P_IPV6 :
102
+ redecl_drop (struct ipv6hdr , ipv6 , ETH_HLEN , xdp );
103
+ nexthdr = ipv6 -> nexthdr ;
104
+ ip_end = ETH_HLEN + sizeof (* ipv6 );
105
+ struct ipv6_opt_hdr * opt = NULL ;
106
+ for (int i = 0 ; i < 8 ; i ++ ) {
107
+ if (!ipv6_is_ext (nexthdr )) break ;
108
+ redecl_drop (struct ipv6_opt_hdr , opt , ip_end , xdp );
109
+ nexthdr = opt -> nexthdr ;
110
+ ip_end += (opt -> hdrlen + 1 ) << 3 ;
111
+ }
112
+ ip_payload_len = ntohs (ipv6 -> payload_len );
113
+ break ;
114
+ default :
115
+ return XDP_PASS ;
113
116
}
114
117
115
118
__u8 ip_proto = ipv4 ? ipv4 -> protocol : ipv6 ? nexthdr : 0 ;
@@ -121,7 +124,7 @@ int ingress_handler(struct xdp_md* xdp) {
121
124
struct conn_tuple conn_key = gen_conn_key (QUARTET_TCP );
122
125
__u32 payload_len = ip_payload_len - (tcp -> doff << 2 );
123
126
124
- log_tcp (LOG_TRACE , true, & conn_key , tcp , payload_len );
127
+ log_tcp (true, & conn_key , tcp , payload_len );
125
128
struct connection * conn = bpf_map_lookup_elem (& mimic_conns , & conn_key );
126
129
127
130
struct tcp_options opt = {};
@@ -136,7 +139,7 @@ int ingress_handler(struct xdp_md* xdp) {
136
139
__u64 tstamp = bpf_ktime_get_boot_ns ();
137
140
138
141
// Quick path for RST and FIN
139
- if (tcp -> rst || tcp -> fin ) {
142
+ if (unlikely ( tcp -> rst || tcp -> fin ) ) {
140
143
if (conn ) {
141
144
__u32 cooldown ;
142
145
bpf_spin_lock (& conn -> lock );
@@ -146,16 +149,16 @@ int ingress_handler(struct xdp_md* xdp) {
146
149
bpf_spin_unlock (& conn -> lock );
147
150
use_pktbuf (RB_ITEM_FREE_PKTBUF , pktbuf );
148
151
if (tcp -> rst ) {
149
- log_destroy (LOG_WARN , & conn_key , DESTROY_RECV_RST , cooldown );
152
+ log_destroy (& conn_key , DESTROY_RECV_RST , cooldown );
150
153
} else {
151
154
send_ctrl_packet (& conn_key , TCP_FLAG_RST , htonl (tcp -> ack_seq ), 0 , 0 );
152
- log_destroy (LOG_WARN , & conn_key , DESTROY_RECV_FIN , cooldown );
155
+ log_destroy (& conn_key , DESTROY_RECV_FIN , cooldown );
153
156
}
154
157
}
155
158
return XDP_DROP ;
156
159
}
157
160
158
- if (!conn ) {
161
+ if (unlikely ( !conn ) ) {
159
162
if (!tcp -> syn || tcp -> ack ) {
160
163
send_ctrl_packet (& conn_key , TCP_FLAG_RST , htonl (tcp -> ack_seq ), 0 , 0 );
161
164
return XDP_DROP ;
@@ -180,7 +183,7 @@ int ingress_handler(struct xdp_md* xdp) {
180
183
181
184
switch (conn -> state ) {
182
185
case CONN_IDLE :
183
- if (tcp -> syn && !tcp -> ack ) {
186
+ if (likely ( tcp -> syn && !tcp -> ack ) ) {
184
187
conn -> state = CONN_SYN_RECV ;
185
188
flags |= TCP_FLAG_SYN | TCP_FLAG_ACK ;
186
189
seq = conn -> seq = random ;
@@ -193,14 +196,14 @@ int ingress_handler(struct xdp_md* xdp) {
193
196
break ;
194
197
195
198
case CONN_SYN_RECV :
196
- if (tcp -> syn && !tcp -> ack ) {
199
+ if (likely ( tcp -> syn && !tcp -> ack ) ) {
197
200
__u32 new_ack_seq = next_ack_seq (tcp , payload_len );
198
- if (new_ack_seq != conn -> ack_seq ) goto fsm_error ;
201
+ if (unlikely ( new_ack_seq != conn -> ack_seq ) ) goto fsm_error ;
199
202
flags |= TCP_FLAG_SYN | TCP_FLAG_ACK ;
200
203
seq = conn -> seq ++ ;
201
204
ack_seq = new_ack_seq ;
202
205
conn -> peer_mss = opt .mss ;
203
- } else if (!tcp -> syn && tcp -> ack ) {
206
+ } else if (likely ( !tcp -> syn && tcp -> ack ) ) {
204
207
will_send_ctrl_packet = false;
205
208
conn -> state = CONN_ESTABLISHED ;
206
209
conn -> ack_seq = next_ack_seq (tcp , payload_len );
@@ -213,9 +216,9 @@ int ingress_handler(struct xdp_md* xdp) {
213
216
break ;
214
217
215
218
case CONN_SYN_SENT :
216
- if (tcp -> syn ) {
219
+ if (likely ( tcp -> syn ) ) {
217
220
flags |= TCP_FLAG_ACK ;
218
- if (tcp -> ack ) {
221
+ if (likely ( tcp -> ack ) ) {
219
222
// 3-way handshake
220
223
conn -> state = CONN_ESTABLISHED ;
221
224
conn -> cooldown_mul = 0 ;
@@ -234,8 +237,8 @@ int ingress_handler(struct xdp_md* xdp) {
234
237
}
235
238
break ;
236
239
237
- case CONN_ESTABLISHED :
238
- if (tcp -> syn ) {
240
+ case CONN_ESTABLISHED : // TODO: likely
241
+ if (unlikely ( tcp -> syn ) ) {
239
242
goto fsm_error ;
240
243
} else if (ntohl (tcp -> seq ) == conn -> ack_seq - 1 ) {
241
244
// Received keepalive; send keepalive ACK
@@ -252,7 +255,7 @@ int ingress_handler(struct xdp_md* xdp) {
252
255
} else if (!tcp -> psh && payload_len == 0 ) {
253
256
// Empty segment without PSH will be treated as control packet
254
257
will_send_ctrl_packet = false;
255
- } else {
258
+ } else { // TODO: likely
256
259
will_send_ctrl_packet = will_drop = false;
257
260
conn -> ack_seq += payload_len ;
258
261
__u32 peer_mss = conn -> peer_mss ?: 1460 ;
@@ -269,7 +272,7 @@ int ingress_handler(struct xdp_md* xdp) {
269
272
}
270
273
break ;
271
274
272
- default :
275
+ default : // TODO: unlikely
273
276
fsm_error :
274
277
flags |= TCP_FLAG_RST ;
275
278
swap (pktbuf , conn -> pktbuf );
@@ -282,14 +285,14 @@ int ingress_handler(struct xdp_md* xdp) {
282
285
283
286
bpf_spin_unlock (& conn -> lock );
284
287
285
- if (flags & TCP_FLAG_SYN && flags & TCP_FLAG_ACK ) log_conn (LOG_INFO , LOG_CONN_ACCEPT , & conn_key );
288
+ if (flags & TCP_FLAG_SYN && flags & TCP_FLAG_ACK ) log_conn (LOG_CONN_ACCEPT , & conn_key );
286
289
if (will_send_ctrl_packet )
287
290
send_ctrl_packet (& conn_key , flags , seq , ack_seq , flags & TCP_FLAG_RST ? 0 : cwnd );
288
- if (flags & TCP_FLAG_RST ) {
289
- log_destroy (LOG_WARN , & conn_key , DESTROY_INVALID , cooldown );
291
+ if (unlikely ( flags & TCP_FLAG_RST ) ) {
292
+ log_destroy (& conn_key , DESTROY_INVALID , cooldown );
290
293
use_pktbuf (RB_ITEM_FREE_PKTBUF , pktbuf );
291
294
} else if (newly_estab ) {
292
- log_conn (LOG_INFO , LOG_CONN_ESTABLISH , & conn_key );
295
+ log_conn (LOG_CONN_ESTABLISH , & conn_key );
293
296
use_pktbuf (RB_ITEM_CONSUME_PKTBUF , pktbuf );
294
297
}
295
298
if (will_drop ) return XDP_DROP ;
0 commit comments