]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/bpf-filter.ebpf.src
dnsdist: Add eBPF source address v4/v6 and qname filtering
[thirdparty/pdns.git] / pdns / bpf-filter.ebpf.src
CommitLineData
87b515ed
RG
1
2#include <net/sock.h>
3#include <linux/types.h>
4#include <uapi/linux/tcp.h>
5#include <uapi/linux/udp.h>
6#include <uapi/linux/ip.h>
7#include <uapi/linux/ipv6.h>
8#include <bcc/proto.h>
9
10struct dnsheader {
11 unsigned id :16; /* query identification number */
12#if BYTE_ORDER == BIG_ENDIAN
13 /* fields in third byte */
14 unsigned qr: 1; /* response flag */
15 unsigned opcode: 4; /* purpose of message */
16 unsigned aa: 1; /* authoritative answer */
17 unsigned tc: 1; /* truncated message */
18 unsigned rd: 1; /* recursion desired */
19 /* fields in fourth byte */
20 unsigned ra: 1; /* recursion available */
21 unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
22 unsigned ad: 1; /* authentic data from named */
23 unsigned cd: 1; /* checking disabled by resolver */
24 unsigned rcode :4; /* response code */
25#elif BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
26 /* fields in third byte */
27 unsigned rd :1; /* recursion desired */
28 unsigned tc :1; /* truncated message */
29 unsigned aa :1; /* authoritative answer */
30 unsigned opcode :4; /* purpose of message */
31 unsigned qr :1; /* response flag */
32 /* fields in fourth byte */
33 unsigned rcode :4; /* response code */
34 unsigned cd: 1; /* checking disabled by resolver */
35 unsigned ad: 1; /* authentic data from named */
36 unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
37 unsigned ra :1; /* recursion available */
38#endif
39 /* remaining bytes */
40 unsigned qdcount :16; /* number of question entries */
41 unsigned ancount :16; /* number of answer entries */
42 unsigned nscount :16; /* number of authority entries */
43 unsigned arcount :16; /* number of resource entries */
44};
45
46struct QNameKey
47{
48 uint8_t qname[255];
49};
50
51struct KeyV6
52{
53 uint8_t src[16];
54};
55
56struct QNameValue
57{
58 u64 counter;
59 u16 qtype;
60};
61
62#define IP_MF 0x2000
63#define IP_OFFSET 0x1FFF
64
65BPF_TABLE("hash", u32, u64, v4filter, 1024);
66BPF_TABLE("hash", struct KeyV6, u64, v6filter, 1024);
67BPF_TABLE("hash", struct QNameKey, struct QNameValue, qnamefilter, 1024);
68
69int bpf_dns_filter(struct __sk_buff *skb) {
70 u8 ip_proto;
71 u32 proto_off;
72 int nh_off = BPF_LL_OFF + ETH_HLEN;
73
74 if (skb->protocol == ntohs(0x0800)) {
75 u32 key;
76 int off = nh_off + offsetof(struct iphdr, saddr);
77 key = load_word(skb, off);
78
79 u64* counter = v4filter.lookup(&key);
80 if (counter) {
81 __sync_fetch_and_add(counter, 1);
82 return 0;
83 }
84
85#if 0
86 if (load_half(skb, (nh_off + (int32_t)offsetof(struct iphdr, frag_off)) & (IP_MF | IP_OFFSET))) {
87 /* fragment */
88 return 2147483647;
89 }
90#endif
91 ip_proto = load_byte(skb, nh_off + offsetof(struct iphdr, protocol));
92 proto_off = nh_off + sizeof(struct iphdr);
93 }
94 else if (skb->protocol == ntohs(0x86DD)) {
95 struct KeyV6 key;
96 int off = nh_off + offsetof(struct ipv6hdr, saddr);
97 key.src[0] = load_byte(skb, off++);
98 key.src[1] = load_byte(skb, off++);
99 key.src[2] = load_byte(skb, off++);
100 key.src[3] = load_byte(skb, off++);
101 key.src[4] = load_byte(skb, off++);
102 key.src[5] = load_byte(skb, off++);
103 key.src[6] = load_byte(skb, off++);
104 key.src[7] = load_byte(skb, off++);
105 key.src[8] = load_byte(skb, off++);
106 key.src[9] = load_byte(skb, off++);
107 key.src[10] = load_byte(skb, off++);
108 key.src[11] = load_byte(skb, off++);
109 key.src[12] = load_byte(skb, off++);
110 key.src[13] = load_byte(skb, off++);
111 key.src[14] = load_byte(skb, off++);
112 key.src[15] = load_byte(skb, off++);
113
114 u64* counter = v6filter.lookup(&key);
115 if (counter) {
116 __sync_fetch_and_add(counter, 1);
117 return 0;
118 }
119
120 ip_proto = load_byte(skb, nh_off + offsetof(struct ipv6hdr, nexthdr));
121 proto_off = nh_off + sizeof(struct ipv6hdr);
122 }
123 else {
124 /* neither IPv4 not IPv6, well */
125 return 2147483647;
126 }
127
128 /* allow TCP */
129 if (ip_proto == IPPROTO_TCP) {
130 return 2147483647;
131 }
132
133 int dns_off = proto_off + sizeof(struct udphdr);
134 int qname_off = dns_off + sizeof(struct dnsheader);
135 size_t idx = 0;
136 struct QNameKey qkey = { 0 };
137 int32_t labellen = 0;
138 uint8_t temp;
139
140#define FILL_ONE_KEY \
141 temp = load_byte(skb, qname_off + idx); \
142 labellen--; \
143 if (labellen < 0) { \
144 labellen = temp; \
145 if (labellen == 0) { \
146 goto end; \
147 } \
148 } \
149 qkey.qname[idx] = temp; \
150 idx++;
151
152 /* 0 - 50 */
153 FILL_ONE_KEY
154 FILL_ONE_KEY
155 FILL_ONE_KEY
156 FILL_ONE_KEY
157 FILL_ONE_KEY
158 FILL_ONE_KEY
159 FILL_ONE_KEY
160 FILL_ONE_KEY
161 FILL_ONE_KEY
162 FILL_ONE_KEY
163
164 FILL_ONE_KEY
165 FILL_ONE_KEY
166 FILL_ONE_KEY
167 FILL_ONE_KEY
168 FILL_ONE_KEY
169 FILL_ONE_KEY
170 FILL_ONE_KEY
171 FILL_ONE_KEY
172 FILL_ONE_KEY
173 FILL_ONE_KEY
174
175 FILL_ONE_KEY
176 FILL_ONE_KEY
177 FILL_ONE_KEY
178 FILL_ONE_KEY
179 FILL_ONE_KEY
180 FILL_ONE_KEY
181 FILL_ONE_KEY
182 FILL_ONE_KEY
183 FILL_ONE_KEY
184 FILL_ONE_KEY
185
186 FILL_ONE_KEY
187 FILL_ONE_KEY
188 FILL_ONE_KEY
189 FILL_ONE_KEY
190 FILL_ONE_KEY
191 FILL_ONE_KEY
192 FILL_ONE_KEY
193 FILL_ONE_KEY
194 FILL_ONE_KEY
195 FILL_ONE_KEY
196
197 FILL_ONE_KEY
198 FILL_ONE_KEY
199 FILL_ONE_KEY
200 FILL_ONE_KEY
201 FILL_ONE_KEY
202 FILL_ONE_KEY
203 FILL_ONE_KEY
204 FILL_ONE_KEY
205 FILL_ONE_KEY
206 FILL_ONE_KEY
207
208 /* 50 - 100 */
209 FILL_ONE_KEY
210 FILL_ONE_KEY
211 FILL_ONE_KEY
212 FILL_ONE_KEY
213 FILL_ONE_KEY
214 FILL_ONE_KEY
215 FILL_ONE_KEY
216 FILL_ONE_KEY
217 FILL_ONE_KEY
218 FILL_ONE_KEY
219
220 FILL_ONE_KEY
221 FILL_ONE_KEY
222 FILL_ONE_KEY
223 FILL_ONE_KEY
224 FILL_ONE_KEY
225 FILL_ONE_KEY
226 FILL_ONE_KEY
227 FILL_ONE_KEY
228 FILL_ONE_KEY
229 FILL_ONE_KEY
230
231 FILL_ONE_KEY
232 FILL_ONE_KEY
233 FILL_ONE_KEY
234 FILL_ONE_KEY
235 FILL_ONE_KEY
236 FILL_ONE_KEY
237 FILL_ONE_KEY
238 FILL_ONE_KEY
239 FILL_ONE_KEY
240 FILL_ONE_KEY
241
242 FILL_ONE_KEY
243 FILL_ONE_KEY
244 FILL_ONE_KEY
245 FILL_ONE_KEY
246 FILL_ONE_KEY
247 FILL_ONE_KEY
248 FILL_ONE_KEY
249 FILL_ONE_KEY
250 FILL_ONE_KEY
251 FILL_ONE_KEY
252
253 FILL_ONE_KEY
254 FILL_ONE_KEY
255 FILL_ONE_KEY
256 FILL_ONE_KEY
257 FILL_ONE_KEY
258 FILL_ONE_KEY
259 FILL_ONE_KEY
260 FILL_ONE_KEY
261 FILL_ONE_KEY
262 FILL_ONE_KEY
263
264 /* 100 - 150 */
265 FILL_ONE_KEY
266 FILL_ONE_KEY
267 FILL_ONE_KEY
268 FILL_ONE_KEY
269 FILL_ONE_KEY
270 FILL_ONE_KEY
271 FILL_ONE_KEY
272 FILL_ONE_KEY
273 FILL_ONE_KEY
274 FILL_ONE_KEY
275
276 FILL_ONE_KEY
277 FILL_ONE_KEY
278 FILL_ONE_KEY
279 FILL_ONE_KEY
280 FILL_ONE_KEY
281 FILL_ONE_KEY
282 FILL_ONE_KEY
283 FILL_ONE_KEY
284 FILL_ONE_KEY
285 FILL_ONE_KEY
286
287 FILL_ONE_KEY
288 FILL_ONE_KEY
289 FILL_ONE_KEY
290 FILL_ONE_KEY
291 FILL_ONE_KEY
292 FILL_ONE_KEY
293 FILL_ONE_KEY
294 FILL_ONE_KEY
295 FILL_ONE_KEY
296 FILL_ONE_KEY
297
298 FILL_ONE_KEY
299 FILL_ONE_KEY
300 FILL_ONE_KEY
301 FILL_ONE_KEY
302 FILL_ONE_KEY
303 FILL_ONE_KEY
304 FILL_ONE_KEY
305 FILL_ONE_KEY
306 FILL_ONE_KEY
307 FILL_ONE_KEY
308
309 FILL_ONE_KEY
310 FILL_ONE_KEY
311 FILL_ONE_KEY
312 FILL_ONE_KEY
313 FILL_ONE_KEY
314 FILL_ONE_KEY
315 FILL_ONE_KEY
316 FILL_ONE_KEY
317 FILL_ONE_KEY
318 FILL_ONE_KEY
319
320 /* 150 - 200 */
321 FILL_ONE_KEY
322 FILL_ONE_KEY
323 FILL_ONE_KEY
324 FILL_ONE_KEY
325 FILL_ONE_KEY
326 FILL_ONE_KEY
327 FILL_ONE_KEY
328 FILL_ONE_KEY
329 FILL_ONE_KEY
330 FILL_ONE_KEY
331
332 FILL_ONE_KEY
333 FILL_ONE_KEY
334 FILL_ONE_KEY
335 FILL_ONE_KEY
336 FILL_ONE_KEY
337 FILL_ONE_KEY
338 FILL_ONE_KEY
339 FILL_ONE_KEY
340 FILL_ONE_KEY
341 FILL_ONE_KEY
342
343 FILL_ONE_KEY
344 FILL_ONE_KEY
345 FILL_ONE_KEY
346 FILL_ONE_KEY
347 FILL_ONE_KEY
348 FILL_ONE_KEY
349 FILL_ONE_KEY
350 FILL_ONE_KEY
351 FILL_ONE_KEY
352 FILL_ONE_KEY
353
354 FILL_ONE_KEY
355 FILL_ONE_KEY
356 FILL_ONE_KEY
357 FILL_ONE_KEY
358 FILL_ONE_KEY
359 FILL_ONE_KEY
360 FILL_ONE_KEY
361 FILL_ONE_KEY
362 FILL_ONE_KEY
363 FILL_ONE_KEY
364
365 FILL_ONE_KEY
366 FILL_ONE_KEY
367 FILL_ONE_KEY
368 FILL_ONE_KEY
369 FILL_ONE_KEY
370 FILL_ONE_KEY
371 FILL_ONE_KEY
372 FILL_ONE_KEY
373 FILL_ONE_KEY
374 FILL_ONE_KEY
375
376 /* 200 - 250 */
377 FILL_ONE_KEY
378 FILL_ONE_KEY
379 FILL_ONE_KEY
380 FILL_ONE_KEY
381 FILL_ONE_KEY
382 FILL_ONE_KEY
383 FILL_ONE_KEY
384 FILL_ONE_KEY
385 FILL_ONE_KEY
386 FILL_ONE_KEY
387
388 FILL_ONE_KEY
389 FILL_ONE_KEY
390 FILL_ONE_KEY
391 FILL_ONE_KEY
392 FILL_ONE_KEY
393 FILL_ONE_KEY
394 FILL_ONE_KEY
395 FILL_ONE_KEY
396 FILL_ONE_KEY
397 FILL_ONE_KEY
398
399 FILL_ONE_KEY
400 FILL_ONE_KEY
401 FILL_ONE_KEY
402 FILL_ONE_KEY
403 FILL_ONE_KEY
404 FILL_ONE_KEY
405 FILL_ONE_KEY
406 FILL_ONE_KEY
407 FILL_ONE_KEY
408 FILL_ONE_KEY
409
410 FILL_ONE_KEY
411 FILL_ONE_KEY
412 FILL_ONE_KEY
413 FILL_ONE_KEY
414 FILL_ONE_KEY
415 FILL_ONE_KEY
416 FILL_ONE_KEY
417 FILL_ONE_KEY
418 FILL_ONE_KEY
419 FILL_ONE_KEY
420
421 FILL_ONE_KEY
422 FILL_ONE_KEY
423 FILL_ONE_KEY
424 FILL_ONE_KEY
425 FILL_ONE_KEY
426 FILL_ONE_KEY
427 FILL_ONE_KEY
428 FILL_ONE_KEY
429 FILL_ONE_KEY
430 FILL_ONE_KEY
431
432 /* 250 - 255 */
433 FILL_ONE_KEY
434 FILL_ONE_KEY
435 FILL_ONE_KEY
436 FILL_ONE_KEY
437 FILL_ONE_KEY
438
439 end:
440
441 {
442 if (idx < 255) {
443 idx++;
444 }
445 u16 qtype = load_half(skb, (qname_off + idx));
446 idx += 2;
447
448 struct QNameValue* qvalue = qnamefilter.lookup(&qkey);
449 if (qvalue &&
450 (qvalue->qtype == 255 || qtype == qvalue->qtype)) {
451 __sync_fetch_and_add(&qvalue->counter, 1);
452 return 0;
453 }
454 }
455
456 return 2147483647;
457}