@@ -30,17 +30,18 @@ struct __tcphdr {
30
30
__be16 dest ;
31
31
__be32 seq ;
32
32
__be32 ack_seq ;
33
- __u16 res1 : 4 , doff : 4 , fin : 1 , syn : 1 , rst : 1 , psh : 1 , ack : 1 , urg : 1 , ece : 1 , cwr : 1 ;
33
+ __u16 res1 : 4 , doff : 4 , fin : 1 , syn : 1 , rst : 1 , psh : 1 , ack : 1 , urg : 1 , ece : 1 ,
34
+ cwr : 1 ;
34
35
__be16 window ;
35
36
__sum16 check ;
36
37
__be16 urg_ptr ;
37
38
};
38
39
39
40
struct __udphdr {
40
- __be16 source ;
41
- __be16 dest ;
42
- __be16 len ;
43
- __sum16 check ;
41
+ __be16 source ;
42
+ __be16 dest ;
43
+ __be16 len ;
44
+ __sum16 check ;
44
45
};
45
46
46
47
static __always_inline bool read_sk_buff (struct __sk_buff * skb , flow_id * id , u16 * custom_flags ) {
@@ -85,10 +86,17 @@ static __always_inline bool read_sk_buff(struct __sk_buff *skb, flow_id *id, u16
85
86
break ;
86
87
}
87
88
case ETH_P_IPV6 :
88
- bpf_skb_load_bytes (skb , ETH_HLEN + offsetof(struct ipv6hdr , nexthdr ), & proto , sizeof (proto ));
89
-
90
- bpf_skb_load_bytes (skb , ETH_HLEN + offsetof(struct ipv6hdr , saddr ), & id -> src_ip .s6_addr , sizeof (id -> src_ip .s6_addr ));
91
- bpf_skb_load_bytes (skb , ETH_HLEN + offsetof(struct ipv6hdr , daddr ), & id -> dst_ip .s6_addr , sizeof (id -> dst_ip .s6_addr ));
89
+ bpf_skb_load_bytes (
90
+ skb , ETH_HLEN + offsetof(struct ipv6hdr , nexthdr ), & proto , sizeof (proto ));
91
+
92
+ bpf_skb_load_bytes (skb ,
93
+ ETH_HLEN + offsetof(struct ipv6hdr , saddr ),
94
+ & id -> src_ip .s6_addr ,
95
+ sizeof (id -> src_ip .s6_addr ));
96
+ bpf_skb_load_bytes (skb ,
97
+ ETH_HLEN + offsetof(struct ipv6hdr , daddr ),
98
+ & id -> dst_ip .s6_addr ,
99
+ sizeof (id -> dst_ip .s6_addr ));
92
100
93
101
hdr_len = ETH_HLEN + sizeof (struct ipv6hdr );
94
102
break ;
@@ -100,40 +108,49 @@ static __always_inline bool read_sk_buff(struct __sk_buff *skb, flow_id *id, u16
100
108
id -> dst_port = 0 ;
101
109
id -> transport_protocol = proto ;
102
110
103
- switch (proto ) {
104
- case IPPROTO_TCP : {
105
- u16 port ;
106
- bpf_skb_load_bytes (skb , hdr_len + offsetof(struct __tcphdr , source ), & port , sizeof (port ));
107
- id -> src_port = __bpf_htons (port );
108
-
109
- bpf_skb_load_bytes (skb , hdr_len + offsetof(struct __tcphdr , dest ), & port , sizeof (port ));
110
- id -> dst_port = __bpf_htons (port );
111
-
112
- u8 doff ;
113
- bpf_skb_load_bytes (skb , hdr_len + offsetof(struct __tcphdr , ack_seq ) + 4 , & doff , sizeof (doff )); // read the first byte past __tcphdr->ack_seq, we can't do offsetof bit fields
114
- doff &= 0xf0 ; // clean-up res1
115
- doff >>= 4 ; // move the upper 4 bits to low
116
- doff *= 4 ; // convert to bytes length
117
-
118
- u8 flags ;
119
- bpf_skb_load_bytes (skb , hdr_len + offsetof(struct __tcphdr , ack_seq ) + 4 + 1 , & flags , sizeof (flags )); // read the second byte past __tcphdr->doff, again bit fields offsets
120
- * custom_flags = ((u16 )flags & 0x00ff );
121
-
122
- hdr_len += doff ;
123
-
124
- if ((skb -> len - hdr_len ) < 0 ) { // less than 0 is a packet we can't parse
125
- return false;
126
- }
127
-
128
- break ;
129
- }
130
- case IPPROTO_UDP : {
131
- u16 port ;
132
- bpf_skb_load_bytes (skb , hdr_len + offsetof(struct __udphdr , source ), & port , sizeof (port ));
133
- id -> src_port = __bpf_htons (port );
134
- bpf_skb_load_bytes (skb , hdr_len + offsetof(struct __udphdr , dest ), & port , sizeof (port ));
135
- id -> dst_port = __bpf_htons (port );
111
+ switch (proto ) {
112
+ case IPPROTO_TCP : {
113
+ u16 port ;
114
+ bpf_skb_load_bytes (skb , hdr_len + offsetof(struct __tcphdr , source ), & port , sizeof (port ));
115
+ id -> src_port = __bpf_htons (port );
116
+
117
+ bpf_skb_load_bytes (skb , hdr_len + offsetof(struct __tcphdr , dest ), & port , sizeof (port ));
118
+ id -> dst_port = __bpf_htons (port );
119
+
120
+ u8 doff ;
121
+ bpf_skb_load_bytes (
122
+ skb ,
123
+ hdr_len + offsetof(struct __tcphdr , ack_seq ) + 4 ,
124
+ & doff ,
125
+ sizeof (
126
+ doff )); // read the first byte past __tcphdr->ack_seq, we can't do offsetof bit fields
127
+ doff &= 0xf0 ; // clean-up res1
128
+ doff >>= 4 ; // move the upper 4 bits to low
129
+ doff *= 4 ; // convert to bytes length
130
+
131
+ u8 flags ;
132
+ bpf_skb_load_bytes (
133
+ skb ,
134
+ hdr_len + offsetof(struct __tcphdr , ack_seq ) + 4 + 1 ,
135
+ & flags ,
136
+ sizeof (flags )); // read the second byte past __tcphdr->doff, again bit fields offsets
137
+ * custom_flags = ((u16 )flags & 0x00ff );
138
+
139
+ hdr_len += doff ;
140
+
141
+ if ((skb -> len - hdr_len ) < 0 ) { // less than 0 is a packet we can't parse
142
+ return false;
136
143
}
144
+
145
+ break ;
146
+ }
147
+ case IPPROTO_UDP : {
148
+ u16 port ;
149
+ bpf_skb_load_bytes (skb , hdr_len + offsetof(struct __udphdr , source ), & port , sizeof (port ));
150
+ id -> src_port = __bpf_htons (port );
151
+ bpf_skb_load_bytes (skb , hdr_len + offsetof(struct __udphdr , dest ), & port , sizeof (port ));
152
+ id -> dst_port = __bpf_htons (port );
153
+ }
137
154
}
138
155
139
156
// custom flags
@@ -149,8 +166,8 @@ static __always_inline bool read_sk_buff(struct __sk_buff *skb, flow_id *id, u16
149
166
}
150
167
151
168
static __always_inline bool same_ip (u8 * ip1 , u8 * ip2 ) {
152
- for (int i = 0 ; i < 16 ; i += 4 ) {
153
- if (* ((u32 * )(ip1 + i )) != * ((u32 * )(ip2 + i ))) {
169
+ for (int i = 0 ; i < 16 ; i += 4 ) {
170
+ if (* ((u32 * )(ip1 + i )) != * ((u32 * )(ip2 + i ))) {
154
171
return false;
155
172
}
156
173
}
@@ -214,21 +231,21 @@ int socket__http_filter(struct __sk_buff *skb) {
214
231
};
215
232
216
233
u8 * direction = (u8 * )bpf_map_lookup_elem (& flow_directions , & id );
217
- if (direction == NULL ) {
234
+ if (direction == NULL ) {
218
235
// Calculate direction based on first flag received
219
236
// SYN and ACK mean someone else initiated the connection and this is the INGRESS direction
220
- if ((flags & (SYN_FLAG | ACK_FLAG )) == (SYN_FLAG | ACK_FLAG )) {
237
+ if ((flags & (SYN_FLAG | ACK_FLAG )) == (SYN_FLAG | ACK_FLAG )) {
221
238
new_flow .iface_direction = INGRESS ;
222
239
}
223
240
// SYN only means we initiated the connection and this is the EGRESS direction
224
- else if ((flags & SYN_FLAG ) == SYN_FLAG ) {
241
+ else if ((flags & SYN_FLAG ) == SYN_FLAG ) {
225
242
new_flow .iface_direction = EGRESS ;
226
243
}
227
244
// save, when direction was calculated based on TCP flag
228
- if (new_flow .iface_direction != UNKNOWN ) {
245
+ if (new_flow .iface_direction != UNKNOWN ) {
229
246
// errors are intentionally omitted
230
247
bpf_map_update_elem (& flow_directions , & id , & new_flow .iface_direction , BPF_NOEXIST );
231
- }
248
+ }
232
249
// fallback for lost or already started connections and UDP
233
250
else {
234
251
new_flow .iface_direction = INGRESS ;
@@ -257,7 +274,8 @@ int socket__http_filter(struct __sk_buff *skb) {
257
274
}
258
275
259
276
new_flow .errno = - ret ;
260
- flow_record * record = (flow_record * )bpf_ringbuf_reserve (& direct_flows , sizeof (flow_record ), 0 );
277
+ flow_record * record =
278
+ (flow_record * )bpf_ringbuf_reserve (& direct_flows , sizeof (flow_record ), 0 );
261
279
if (!record ) {
262
280
if (trace_messages ) {
263
281
bpf_dbg_printk ("couldn't reserve space in the ringbuf. Dropping flow" );
@@ -272,7 +290,7 @@ int socket__http_filter(struct __sk_buff *skb) {
272
290
273
291
cleanup :
274
292
// finally, when flow receives FIN or RST, clean flow_directions
275
- if (flags & FIN_FLAG || flags & RST_FLAG ) {
293
+ if (flags & FIN_FLAG || flags & RST_FLAG ) {
276
294
bpf_map_delete_elem (& flow_directions , & id );
277
295
}
278
296
return TC_ACT_OK ;
0 commit comments