Skip to content

Commit 71dd239

Browse files
mauriciobomfimVictorNogueiraRio
authored andcommitted
Add files for performance test
1 parent b355385 commit 71dd239

File tree

6 files changed

+517
-23
lines changed

6 files changed

+517
-23
lines changed

samples/bpf/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ always += task_fd_query_kern.o
172172
always += xdp_sample_pkts_kern.o
173173
# CONFIG_XDP_LUA
174174
always += xdplua_map_kern.o
175+
always += xdp_ssl_sni_drop_all.o
176+
always += xdp_ssl_sni_drop_ebpf.o
177+
always += xdp_ssl_sni_drop_lua.o
175178

176179
KBUILD_HOSTCFLAGS += -I$(objtree)/usr/include
177180
KBUILD_HOSTCFLAGS += -I$(srctree)/tools/lib/
@@ -204,6 +207,7 @@ LLC ?= llc
204207
CLANG ?= clang
205208
LLVM_OBJCOPY ?= llvm-objcopy
206209
BTF_PAHOLE ?= pahole
210+
LLVM_READELF ?= llvm-readelf
207211

208212
# Detect that we're cross compiling and use the cross compiler
209213
ifdef CROSS_COMPILE
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
struct sslsni_wrapper {
2+
char sslsni[100];
3+
};

samples/bpf/xdp_ssl_sni_drop_all.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#define KBUILD_MODNAME "foo"
2+
3+
#include <uapi/linux/bpf.h>
4+
#include "bpf_helpers.h"
5+
#include "bpf_endian.h"
6+
7+
struct bpf_map_def SEC("maps") rx_cnt = {
8+
.type = BPF_MAP_TYPE_PERCPU_ARRAY,
9+
.key_size = sizeof(u32),
10+
.value_size = sizeof(long),
11+
.max_entries = 1,
12+
};
13+
14+
SEC("sslparser")
15+
int handle_ingress(struct xdp_md *ctx)
16+
{
17+
u32 key_rx = 0;
18+
long *cnt;
19+
20+
cnt = bpf_map_lookup_elem(&rx_cnt, &key_rx);
21+
if (!cnt)
22+
return XDP_PASS;
23+
24+
(*cnt)++;
25+
26+
return XDP_DROP;
27+
}
28+
char _license[] SEC("license") = "GPL";
Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
#define KBUILD_MODNAME "foo"
2+
3+
#include <linux/if_ether.h>
4+
#include <linux/if_vlan.h>
5+
#include <linux/if_packet.h>
6+
#include <linux/ip.h>
7+
#include <linux/ipv6.h>
8+
#include <linux/in.h>
9+
#include <linux/tcp.h>
10+
#include <linux/udp.h>
11+
#include <uapi/linux/bpf.h>
12+
#include <net/ip.h>
13+
#include "bpf_helpers.h"
14+
#include "bpf_endian.h"
15+
#include "xdp_ssl_parser_common.h"
16+
17+
#define RANDLEN 32
18+
#define SNIMAXLEN 253
19+
#define MAXSSLEXTS 53
20+
21+
struct bpf_map_def SEC("maps") rx_cnt = {
22+
.type = BPF_MAP_TYPE_PERCPU_ARRAY,
23+
.key_size = sizeof(u32),
24+
.value_size = sizeof(long),
25+
.max_entries = 1,
26+
};
27+
28+
struct bpf_map_def SEC("maps") blocked_snis = {
29+
.type = BPF_MAP_TYPE_HASH,
30+
.key_size = sizeof(u32),
31+
.value_size = sizeof(struct sslsni_wrapper),
32+
.max_entries = 10,
33+
};
34+
35+
struct __attribute__((__packed__)) sslhdr1 {
36+
__u8 type;
37+
__u16 version;
38+
__u16 len;
39+
};
40+
41+
struct __attribute__((__packed__))sslhandshake {
42+
__u32 type:8,
43+
len:24;
44+
__u16 version;
45+
};
46+
47+
struct sslsession {
48+
__u8 len;
49+
};
50+
51+
struct sslcipher {
52+
__u16 len;
53+
};
54+
55+
struct exthdr {
56+
__u16 id;
57+
__u16 len;
58+
__u16 workaround;
59+
};
60+
61+
struct sniexthdr {
62+
__u16 len;
63+
};
64+
65+
static int parse_ext(void *data, uint64_t *ext_off, void *data_end, __u16 *snilen)
66+
{
67+
struct exthdr *sslext;
68+
__u16 *len;
69+
__u16 extlen;
70+
/* check possible access to offset outside of packet*/
71+
if (data + 1 > data_end)
72+
return -1;
73+
74+
/* check that needed to be made to bypass verifier(possible bug?) */
75+
if (*ext_off > 2000)
76+
return -1;
77+
78+
/* check that needed to be made to bypass verifier(possible bug?) */
79+
if (*ext_off < 1)
80+
return -1;
81+
82+
data += *ext_off;
83+
sslext = (struct exthdr *) data;
84+
85+
/* check possible access to offset outside of packet*/
86+
if (&(sslext->workaround) > data_end)
87+
return -1;
88+
89+
extlen = bpf_htons(sslext->len);
90+
/* check that needed to be made to bypass verifier(possible bug?) */
91+
if (extlen > 2000)
92+
return -1;
93+
94+
/* found server name extension header */
95+
if (bpf_htons(sslext->id) == 0) {
96+
/* check that needed to be made to bypass verifier(possible bug?) */
97+
if (*ext_off > 2000)
98+
return -1;
99+
100+
len = data + 7;
101+
/* check possible access to offset outside of packet*/
102+
if (len + 1 > data_end)
103+
return -1;
104+
105+
*snilen = bpf_htons(*len);
106+
return 1;
107+
}
108+
109+
*ext_off += extlen + 4;
110+
111+
/* check possible access to offset outside of packet*/
112+
if (data + 1 > data_end)
113+
return -1;
114+
115+
return -2;
116+
}
117+
118+
static int ssl(void *data, uint64_t ssl_off, void *data_end)
119+
{
120+
struct sslhdr1 *sslh;
121+
struct sslhandshake *sslhsk;
122+
struct sslsession *sesh;
123+
struct sslcipher *sslci;
124+
uint64_t acc_off = ssl_off;
125+
struct exthdr *sslext;
126+
struct sniexthdr *snihdr;
127+
struct sniexthdr *snihdraux;
128+
struct sslsni_wrapper wrapper = {};
129+
int ret_parse_ext = 0;
130+
__u16 cilen = 10;
131+
__u16 snilen = 0;
132+
__u16 extlen = 0;
133+
u32 key_rx = 0;
134+
char *sslsni;
135+
long *cnt;
136+
137+
char blocked_sni[9] = "test.com";
138+
139+
sslh = data + acc_off;
140+
/* check possible access to offset outside of packet*/
141+
if (sslh + 1 > data_end)
142+
return XDP_PASS;
143+
144+
/* check if content type is handshake*/
145+
if (sslh->type != 0x16)
146+
return XDP_PASS;
147+
acc_off += sizeof(struct sslhdr1);
148+
149+
sslhsk = (void *) data + acc_off;
150+
151+
/* check possible access to offset outside of packet*/
152+
if (sslhsk + 1 > data_end)
153+
return XDP_PASS;
154+
155+
/* check if handshake type is Client Hello*/
156+
if (sslhsk->type != 0x01)
157+
return XDP_PASS;
158+
159+
acc_off += sizeof(struct sslhandshake) + RANDLEN;
160+
161+
sesh = (void *) data + acc_off;
162+
163+
/* check possible access to offset outside of packet*/
164+
if (sesh + 1 > data_end)
165+
return XDP_PASS;
166+
167+
acc_off += sizeof(struct sslsession) + sesh->len;
168+
sslci = (void *) data + acc_off;
169+
170+
/* check possible access to offset outside of packet*/
171+
if (sslci + 1 > data_end)
172+
return XDP_PASS;
173+
174+
cilen = bpf_htons(sslci->len);
175+
/* check that needed to be made to bypass verifier(possible bug?) */
176+
if (cilen > 2000)
177+
return XDP_PASS;
178+
179+
acc_off += sizeof(struct sslcipher) + cilen + 4;
180+
#pragma clang loop unroll(full)
181+
for (int i = 0; i < MAXSSLEXTS; i++) {
182+
ret_parse_ext = parse_ext(data, &acc_off, data_end, &snilen);
183+
/* found server name extension header */
184+
if(ret_parse_ext == 1)
185+
break;
186+
/* one of the checks in parse_ext function failed*/
187+
else if(ret_parse_ext == -1)
188+
return XDP_PASS;
189+
190+
/* check that needed to be made to bypass verifier(possible bug?) */
191+
if (acc_off > 2000)
192+
return XDP_PASS;
193+
}
194+
195+
/* check that needed to be made to bypass verifier(possible bug?) */
196+
if (acc_off > 2000)
197+
return XDP_PASS;
198+
199+
data += acc_off;
200+
/* check possible access to offset outside of packet*/
201+
if (data + 11 > data_end)
202+
return XDP_PASS;
203+
sslsni = data + 9;
204+
205+
if (sslsni == NULL) {
206+
return XDP_PASS;
207+
}
208+
209+
char fmt[] = "sslsni %s\n";
210+
cnt = bpf_map_lookup_elem(&rx_cnt, &key_rx);
211+
if (!cnt) {
212+
return XDP_PASS;
213+
}
214+
(*cnt)++;
215+
216+
//return XDP_DROP;
217+
/*
218+
char blocked_sni[] = "test2.com.br";
219+
unsigned char *proxy = blocked_sni;
220+
if (strncmp(BLOCKEDSNI, sslsni, snilen) == 0) {
221+
return XDP_DROP;
222+
}
223+
if (sslsni[0] == 't')
224+
return XDP_DROP;
225+
if (snilen > 100)
226+
return XDP_PASS;
227+
*/
228+
229+
if (sslsni + 15 > data_end)
230+
return XDP_PASS;
231+
232+
/*
233+
if (strcmp(sslsni, fmt2->sslsni) == 0)
234+
return XDP_DROP;
235+
if (strncmp(sslsni, fmt, sizeof(fmt)) == 0)
236+
return XDP_DROP;
237+
238+
struct sslsni_wrapper *fmt2;
239+
fmt2 = bpf_map_lookup_elem(&blocked_snis, &key);
240+
if (fmt2 == NULL)
241+
return XDP_PASS;
242+
243+
for (int i = 0; i < 14; i++) {
244+
if (sslsni + 1 < data_end) {
245+
if (sslsni[i] != fmt2->sslsni[i])
246+
return XDP_PASS;
247+
248+
if (sslsni[i] == 0) {
249+
return XDP_DROP;
250+
}
251+
}
252+
}
253+
254+
*/
255+
int key = 1;
256+
257+
#pragma clang loop unroll(full)
258+
for (int i = 0; i < sizeof(blocked_sni); i++) {
259+
if (i == snilen) {
260+
return XDP_DROP;
261+
}
262+
263+
if (sslsni + 1 > data_end)
264+
return XDP_PASS;
265+
266+
if (blocked_sni[i] != *sslsni)
267+
return XDP_PASS;
268+
269+
sslsni += 1;
270+
}
271+
272+
return XDP_PASS;
273+
}
274+
275+
static int tcp(void *data, uint64_t tp_off, void *data_end)
276+
{
277+
struct tcphdr *tcp = data + tp_off;
278+
279+
if (tcp + 1 > data_end)
280+
return 0;
281+
282+
return ssl(data, tp_off + tcp->doff * 4, data_end);
283+
}
284+
285+
static int parse_ipv4(void *data, uint64_t nh_off, void *data_end)
286+
{
287+
288+
struct iphdr *iph = data + nh_off;
289+
uint64_t ihl_len;
290+
291+
if (iph + 1 > data_end)
292+
return 0;
293+
294+
ihl_len = iph->ihl * 4;
295+
return tcp(data, nh_off + ihl_len, data_end);
296+
}
297+
298+
SEC("sslparser")
299+
int handle_ingress(struct xdp_md *ctx)
300+
{
301+
void *data_end = (void *)(long)ctx->data_end;
302+
void *data = (void *)(long)ctx->data;
303+
struct ethhdr *eth = data;
304+
int rc = XDP_PASS;
305+
long *value;
306+
u16 h_proto;
307+
u64 nh_off;
308+
u32 ipproto;
309+
310+
nh_off = sizeof(*eth);
311+
if (data + nh_off > data_end)
312+
return rc;
313+
314+
h_proto = eth->h_proto;
315+
316+
if (h_proto == htons(ETH_P_8021Q) || h_proto == htons(ETH_P_8021AD)) {
317+
struct vlan_hdr *vhdr;
318+
319+
vhdr = data + nh_off;
320+
nh_off += sizeof(struct vlan_hdr);
321+
if (data + nh_off > data_end)
322+
return rc;
323+
h_proto = vhdr->h_vlan_encapsulated_proto;
324+
}
325+
if (h_proto == htons(ETH_P_8021Q) || h_proto == htons(ETH_P_8021AD)) {
326+
struct vlan_hdr *vhdr;
327+
328+
vhdr = data + nh_off;
329+
nh_off += sizeof(struct vlan_hdr);
330+
if (data + nh_off > data_end)
331+
return rc;
332+
h_proto = vhdr->h_vlan_encapsulated_proto;
333+
}
334+
335+
if (h_proto == htons(ETH_P_IP))
336+
return parse_ipv4(data, nh_off, data_end);
337+
338+
return rc;
339+
}
340+
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)