]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/bpf-filter.ebpf.src
Merge pull request #7903 from Habbie/dnsdist-doc-nits
[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
87b515ed
RG
62BPF_TABLE("hash", u32, u64, v4filter, 1024);
63BPF_TABLE("hash", struct KeyV6, u64, v6filter, 1024);
64BPF_TABLE("hash", struct QNameKey, struct QNameValue, qnamefilter, 1024);
d45189b7 65BPF_TABLE("prog", int, int, progsarray, 1);
87b515ed 66
d45189b7
RG
67int bpf_qname_filter(struct __sk_buff *skb)
68{
69 uint32_t qname_off = skb->cb[0];
70 ssize_t labellen = skb->cb[3];
71 size_t idx = 2;
72 struct QNameKey qkey = { 0 };
73 u32 val = skb->cb[1];
74 if (val) {
75 qkey.qname[0] = val;
87b515ed 76 }
d45189b7
RG
77 val = skb->cb[2];
78 if (val) {
79 qkey.qname[1] = val;
87b515ed 80 }
87b515ed
RG
81 uint8_t temp;
82
83#define FILL_ONE_KEY \
84 temp = load_byte(skb, qname_off + idx); \
85 labellen--; \
86 if (labellen < 0) { \
87 labellen = temp; \
88 if (labellen == 0) { \
89 goto end; \
90 } \
d45189b7
RG
91 } else if (temp >= 'A' && temp <= 'Z') { \
92 temp += ('a' - 'A'); \
87b515ed
RG
93 } \
94 qkey.qname[idx] = temp; \
95 idx++;
96
d45189b7 97 /* 2 - 52 */
87b515ed
RG
98 FILL_ONE_KEY
99 FILL_ONE_KEY
100 FILL_ONE_KEY
101 FILL_ONE_KEY
102 FILL_ONE_KEY
103 FILL_ONE_KEY
104 FILL_ONE_KEY
105 FILL_ONE_KEY
106 FILL_ONE_KEY
107 FILL_ONE_KEY
108
109 FILL_ONE_KEY
110 FILL_ONE_KEY
111 FILL_ONE_KEY
112 FILL_ONE_KEY
113 FILL_ONE_KEY
114 FILL_ONE_KEY
115 FILL_ONE_KEY
116 FILL_ONE_KEY
117 FILL_ONE_KEY
118 FILL_ONE_KEY
119
120 FILL_ONE_KEY
121 FILL_ONE_KEY
122 FILL_ONE_KEY
123 FILL_ONE_KEY
124 FILL_ONE_KEY
125 FILL_ONE_KEY
126 FILL_ONE_KEY
127 FILL_ONE_KEY
128 FILL_ONE_KEY
129 FILL_ONE_KEY
130
131 FILL_ONE_KEY
132 FILL_ONE_KEY
133 FILL_ONE_KEY
134 FILL_ONE_KEY
135 FILL_ONE_KEY
136 FILL_ONE_KEY
137 FILL_ONE_KEY
138 FILL_ONE_KEY
139 FILL_ONE_KEY
140 FILL_ONE_KEY
141
142 FILL_ONE_KEY
143 FILL_ONE_KEY
144 FILL_ONE_KEY
145 FILL_ONE_KEY
146 FILL_ONE_KEY
147 FILL_ONE_KEY
148 FILL_ONE_KEY
149 FILL_ONE_KEY
150 FILL_ONE_KEY
151 FILL_ONE_KEY
152
d45189b7 153 /* 52 - 102 */
87b515ed
RG
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 FILL_ONE_KEY
164
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 FILL_ONE_KEY
175
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 FILL_ONE_KEY
186
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 FILL_ONE_KEY
197
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 FILL_ONE_KEY
208
d45189b7 209 /* 102 - 152 */
87b515ed
RG
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 FILL_ONE_KEY
220
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 FILL_ONE_KEY
231
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 FILL_ONE_KEY
242
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 FILL_ONE_KEY
253
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 FILL_ONE_KEY
264
d45189b7 265 /* 152 - 202 */
87b515ed
RG
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 FILL_ONE_KEY
276
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 FILL_ONE_KEY
287
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 FILL_ONE_KEY
298
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 FILL_ONE_KEY
309
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 FILL_ONE_KEY
320
d45189b7 321 /* 202 - 252 */
87b515ed
RG
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 FILL_ONE_KEY
332
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 FILL_ONE_KEY
343
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 FILL_ONE_KEY
354
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 FILL_ONE_KEY
365
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 FILL_ONE_KEY
376
d45189b7 377 /* 252 - 254 */
87b515ed
RG
378 FILL_ONE_KEY
379 FILL_ONE_KEY
380
d45189b7
RG
381 /* the only value that makes sense for
382 qkey.qname[255] is 0, and it's already
383 there */
87b515ed
RG
384 end:
385
386 {
d45189b7 387 idx++;
87b515ed 388 u16 qtype = load_half(skb, (qname_off + idx));
87b515ed
RG
389
390 struct QNameValue* qvalue = qnamefilter.lookup(&qkey);
391 if (qvalue &&
392 (qvalue->qtype == 255 || qtype == qvalue->qtype)) {
393 __sync_fetch_and_add(&qvalue->counter, 1);
394 return 0;
395 }
396 }
397
398 return 2147483647;
399}
d45189b7
RG
400
401int bpf_dns_filter(struct __sk_buff *skb) {
402 u8 ip_proto;
403 int proto_off;
404 int nh_off = BPF_LL_OFF + ETH_HLEN;
405
406 if (skb->protocol == ntohs(0x0800)) {
407 u32 key;
408 int off = nh_off + offsetof(struct iphdr, saddr);
409 key = load_word(skb, off);
410
411 u64* counter = v4filter.lookup(&key);
412 if (counter) {
413 __sync_fetch_and_add(counter, 1);
414 return 0;
415 }
416
417 ip_proto = load_byte(skb, nh_off + offsetof(struct iphdr, protocol));
418 proto_off = nh_off + sizeof(struct iphdr);
419 }
420 else if (skb->protocol == ntohs(0x86DD)) {
421 struct KeyV6 key;
422 int off = nh_off + offsetof(struct ipv6hdr, saddr);
423 key.src[0] = load_byte(skb, off++);
424 key.src[1] = load_byte(skb, off++);
425 key.src[2] = load_byte(skb, off++);
426 key.src[3] = load_byte(skb, off++);
427 key.src[4] = load_byte(skb, off++);
428 key.src[5] = load_byte(skb, off++);
429 key.src[6] = load_byte(skb, off++);
430 key.src[7] = load_byte(skb, off++);
431 key.src[8] = load_byte(skb, off++);
432 key.src[9] = load_byte(skb, off++);
433 key.src[10] = load_byte(skb, off++);
434 key.src[11] = load_byte(skb, off++);
435 key.src[12] = load_byte(skb, off++);
436 key.src[13] = load_byte(skb, off++);
437 key.src[14] = load_byte(skb, off++);
438 key.src[15] = load_byte(skb, off++);
439
440 u64* counter = v6filter.lookup(&key);
441 if (counter) {
442 __sync_fetch_and_add(counter, 1);
443 return 0;
444 }
445
446 ip_proto = load_byte(skb, nh_off + offsetof(struct ipv6hdr, nexthdr));
447 proto_off = nh_off + sizeof(struct ipv6hdr);
448 }
449 else {
450 /* neither IPv4 not IPv6, well */
451 return 2147483647;
452 }
453
454 /* allow TCP */
455 if (ip_proto == IPPROTO_TCP) {
456 return 2147483647;
457 }
458
459 struct QNameKey qkey = { 0 };
460 int dns_off = proto_off + sizeof(struct udphdr);
461 int qname_off = dns_off + sizeof(struct dnsheader);
462 skb->cb[0] = (uint32_t) qname_off;
463 u16 qtype;
464
465 uint8_t temp = load_byte(skb, qname_off);
466 if (temp > 63) {
467 return 0;
468 }
469
470 if (temp == 0) {
471 /* root, nothing else to see */
472 qtype = load_half(skb, (qname_off + 1));
473
474 struct QNameValue* qvalue = qnamefilter.lookup(&qkey);
475 if (qvalue &&
476 (qvalue->qtype == 255 || qtype == qvalue->qtype)) {
477 __sync_fetch_and_add(&qvalue->counter, 1);
478 return 0;
479 }
480 return 2147483647;
481 }
482
483 ssize_t labellen = temp;
484 skb->cb[1] = temp;
485 qkey.qname[0] = temp;
486
487 temp = load_byte(skb, qname_off + 1);
488 labellen--;
489 if (temp >= 'A' && temp <= 'Z') {
490 temp += ('a' - 'A');
491 }
492 skb->cb[2] = temp;
493 skb->cb[3] = labellen;
494 progsarray.call(skb, 0);
495
496 return 2147483647;
497}