blob: 79ad061079dd28c58257b158cde9414ec78764ca [file] [log] [blame]
William Tu6afb1e22016-08-19 11:55:44 -07001/* Copyright (c) 2016 VMware
Alexei Starovoitova1c82702016-09-15 13:00:31 -07002 * Copyright (c) 2016 Facebook
William Tu6afb1e22016-08-19 11:55:44 -07003 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 2 of the GNU General Public
6 * License as published by the Free Software Foundation.
7 */
Daniel Borkmann96a8eb12016-10-26 00:37:53 +02008#define KBUILD_MODNAME "foo"
William Tu6afb1e22016-08-19 11:55:44 -07009#include <uapi/linux/bpf.h>
10#include <uapi/linux/if_ether.h>
11#include <uapi/linux/if_packet.h>
12#include <uapi/linux/ip.h>
Alexei Starovoitov173ca262016-09-15 13:00:32 -070013#include <uapi/linux/ipv6.h>
William Tu6afb1e22016-08-19 11:55:44 -070014#include <uapi/linux/in.h>
15#include <uapi/linux/tcp.h>
16#include <uapi/linux/filter.h>
17#include <uapi/linux/pkt_cls.h>
Alexei Starovoitov173ca262016-09-15 13:00:32 -070018#include <net/ipv6.h>
William Tu6afb1e22016-08-19 11:55:44 -070019#include "bpf_helpers.h"
William Tuef88f892017-08-25 09:21:29 -070020#include "bpf_endian.h"
William Tu6afb1e22016-08-19 11:55:44 -070021
Alexei Starovoitov173ca262016-09-15 13:00:32 -070022#define _htonl __builtin_bswap32
William Tu6afb1e22016-08-19 11:55:44 -070023#define ERROR(ret) do {\
24 char fmt[] = "ERROR line:%d ret:%d\n";\
25 bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \
26 } while(0)
27
28struct geneve_opt {
29 __be16 opt_class;
30 u8 type;
31 u8 length:5;
32 u8 r3:1;
33 u8 r2:1;
34 u8 r1:1;
35 u8 opt_data[8]; /* hard-coded to 8 byte */
36};
37
38struct vxlan_metadata {
39 u32 gbp;
40};
41
William Tuef88f892017-08-25 09:21:29 -070042struct erspan_metadata {
43 __be32 index;
44};
45
William Tu6afb1e22016-08-19 11:55:44 -070046SEC("gre_set_tunnel")
47int _gre_set_tunnel(struct __sk_buff *skb)
48{
49 int ret;
50 struct bpf_tunnel_key key;
51
52 __builtin_memset(&key, 0x0, sizeof(key));
53 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
54 key.tunnel_id = 2;
55 key.tunnel_tos = 0;
56 key.tunnel_ttl = 64;
57
58 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
59 if (ret < 0) {
60 ERROR(ret);
61 return TC_ACT_SHOT;
62 }
63
64 return TC_ACT_OK;
65}
66
67SEC("gre_get_tunnel")
68int _gre_get_tunnel(struct __sk_buff *skb)
69{
70 int ret;
71 struct bpf_tunnel_key key;
72 char fmt[] = "key %d remote ip 0x%x\n";
73
74 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
75 if (ret < 0) {
76 ERROR(ret);
77 return TC_ACT_SHOT;
78 }
79
80 bpf_trace_printk(fmt, sizeof(fmt), key.tunnel_id, key.remote_ipv4);
81 return TC_ACT_OK;
82}
83
William Tu56ddd302017-12-01 15:26:10 -080084SEC("ip6gretap_set_tunnel")
85int _ip6gretap_set_tunnel(struct __sk_buff *skb)
86{
87 struct bpf_tunnel_key key;
88 int ret;
89
90 __builtin_memset(&key, 0x0, sizeof(key));
91 key.remote_ipv6[3] = _htonl(0x11); /* ::11 */
92 key.tunnel_id = 2;
93 key.tunnel_tos = 0;
94 key.tunnel_ttl = 64;
95 key.tunnel_label = 0xabcde;
96
97 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
98 BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX);
99 if (ret < 0) {
100 ERROR(ret);
101 return TC_ACT_SHOT;
102 }
103
104 return TC_ACT_OK;
105}
106
107SEC("ip6gretap_get_tunnel")
108int _ip6gretap_get_tunnel(struct __sk_buff *skb)
109{
110 char fmt[] = "key %d remote ip6 ::%x label %x\n";
111 struct bpf_tunnel_key key;
112 int ret;
113
114 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
115 BPF_F_TUNINFO_IPV6);
116 if (ret < 0) {
117 ERROR(ret);
118 return TC_ACT_SHOT;
119 }
120
121 bpf_trace_printk(fmt, sizeof(fmt),
122 key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
123
124 return TC_ACT_OK;
125}
126
William Tuef88f892017-08-25 09:21:29 -0700127SEC("erspan_set_tunnel")
128int _erspan_set_tunnel(struct __sk_buff *skb)
129{
130 struct bpf_tunnel_key key;
131 struct erspan_metadata md;
132 int ret;
133
134 __builtin_memset(&key, 0x0, sizeof(key));
135 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
136 key.tunnel_id = 2;
137 key.tunnel_tos = 0;
138 key.tunnel_ttl = 64;
139
140 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
141 if (ret < 0) {
142 ERROR(ret);
143 return TC_ACT_SHOT;
144 }
145
146 md.index = htonl(123);
147 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
148 if (ret < 0) {
149 ERROR(ret);
150 return TC_ACT_SHOT;
151 }
152
153 return TC_ACT_OK;
154}
155
156SEC("erspan_get_tunnel")
157int _erspan_get_tunnel(struct __sk_buff *skb)
158{
159 char fmt[] = "key %d remote ip 0x%x erspan index 0x%x\n";
160 struct bpf_tunnel_key key;
161 struct erspan_metadata md;
162 u32 index;
163 int ret;
164
165 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
166 if (ret < 0) {
167 ERROR(ret);
168 return TC_ACT_SHOT;
169 }
170
171 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
172 if (ret < 0) {
173 ERROR(ret);
174 return TC_ACT_SHOT;
175 }
176
177 index = bpf_ntohl(md.index);
178 bpf_trace_printk(fmt, sizeof(fmt),
179 key.tunnel_id, key.remote_ipv4, index);
180
181 return TC_ACT_OK;
182}
183
William Tud37e3bb2017-12-05 15:15:45 -0800184SEC("ip4ip6erspan_set_tunnel")
185int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
186{
187 struct bpf_tunnel_key key;
188 struct erspan_metadata md;
189 int ret;
190
191 __builtin_memset(&key, 0x0, sizeof(key));
192 key.remote_ipv6[3] = _htonl(0x11);
193 key.tunnel_id = 2;
194 key.tunnel_tos = 0;
195 key.tunnel_ttl = 64;
196
197 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
198 BPF_F_TUNINFO_IPV6);
199 if (ret < 0) {
200 ERROR(ret);
201 return TC_ACT_SHOT;
202 }
203
204 md.index = htonl(123);
205 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
206 if (ret < 0) {
207 ERROR(ret);
208 return TC_ACT_SHOT;
209 }
210
211 return TC_ACT_OK;
212}
213
214SEC("ip4ip6erspan_get_tunnel")
215int _ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
216{
217 char fmt[] = "key %d remote ip6 ::%x erspan index 0x%x\n";
218 struct bpf_tunnel_key key;
219 struct erspan_metadata md;
220 u32 index;
221 int ret;
222
223 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
224 if (ret < 0) {
225 ERROR(ret);
226 return TC_ACT_SHOT;
227 }
228
229 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
230 if (ret < 0) {
231 ERROR(ret);
232 return TC_ACT_SHOT;
233 }
234
235 index = bpf_ntohl(md.index);
236 bpf_trace_printk(fmt, sizeof(fmt),
237 key.tunnel_id, key.remote_ipv6[0], index);
238
239 return TC_ACT_OK;
240}
241
William Tu6afb1e22016-08-19 11:55:44 -0700242SEC("vxlan_set_tunnel")
243int _vxlan_set_tunnel(struct __sk_buff *skb)
244{
245 int ret;
246 struct bpf_tunnel_key key;
247 struct vxlan_metadata md;
248
249 __builtin_memset(&key, 0x0, sizeof(key));
250 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
251 key.tunnel_id = 2;
252 key.tunnel_tos = 0;
253 key.tunnel_ttl = 64;
254
255 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
256 if (ret < 0) {
257 ERROR(ret);
258 return TC_ACT_SHOT;
259 }
260
261 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
262 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
263 if (ret < 0) {
264 ERROR(ret);
265 return TC_ACT_SHOT;
266 }
267
268 return TC_ACT_OK;
269}
270
271SEC("vxlan_get_tunnel")
272int _vxlan_get_tunnel(struct __sk_buff *skb)
273{
274 int ret;
275 struct bpf_tunnel_key key;
276 struct vxlan_metadata md;
277 char fmt[] = "key %d remote ip 0x%x vxlan gbp 0x%x\n";
278
279 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
280 if (ret < 0) {
281 ERROR(ret);
282 return TC_ACT_SHOT;
283 }
284
285 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
286 if (ret < 0) {
287 ERROR(ret);
288 return TC_ACT_SHOT;
289 }
290
291 bpf_trace_printk(fmt, sizeof(fmt),
292 key.tunnel_id, key.remote_ipv4, md.gbp);
293
294 return TC_ACT_OK;
295}
296
297SEC("geneve_set_tunnel")
298int _geneve_set_tunnel(struct __sk_buff *skb)
299{
300 int ret, ret2;
301 struct bpf_tunnel_key key;
302 struct geneve_opt gopt;
303
304 __builtin_memset(&key, 0x0, sizeof(key));
305 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
306 key.tunnel_id = 2;
307 key.tunnel_tos = 0;
308 key.tunnel_ttl = 64;
309
310 __builtin_memset(&gopt, 0x0, sizeof(gopt));
311 gopt.opt_class = 0x102; /* Open Virtual Networking (OVN) */
312 gopt.type = 0x08;
William Tucc75f852017-07-31 14:40:50 -0700313 gopt.r1 = 0;
William Tu6afb1e22016-08-19 11:55:44 -0700314 gopt.r2 = 0;
William Tucc75f852017-07-31 14:40:50 -0700315 gopt.r3 = 0;
William Tu6afb1e22016-08-19 11:55:44 -0700316 gopt.length = 2; /* 4-byte multiple */
317 *(int *) &gopt.opt_data = 0xdeadbeef;
318
319 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
320 if (ret < 0) {
321 ERROR(ret);
322 return TC_ACT_SHOT;
323 }
324
325 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
326 if (ret < 0) {
327 ERROR(ret);
328 return TC_ACT_SHOT;
329 }
330
331 return TC_ACT_OK;
332}
333
334SEC("geneve_get_tunnel")
335int _geneve_get_tunnel(struct __sk_buff *skb)
336{
337 int ret;
338 struct bpf_tunnel_key key;
339 struct geneve_opt gopt;
340 char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n";
341
342 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
343 if (ret < 0) {
344 ERROR(ret);
345 return TC_ACT_SHOT;
346 }
347
348 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
349 if (ret < 0) {
350 ERROR(ret);
351 return TC_ACT_SHOT;
352 }
353
354 bpf_trace_printk(fmt, sizeof(fmt),
355 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
356 return TC_ACT_OK;
357}
358
Alexei Starovoitova1c82702016-09-15 13:00:31 -0700359SEC("ipip_set_tunnel")
360int _ipip_set_tunnel(struct __sk_buff *skb)
361{
362 struct bpf_tunnel_key key = {};
363 void *data = (void *)(long)skb->data;
364 struct iphdr *iph = data;
365 struct tcphdr *tcp = data + sizeof(*iph);
366 void *data_end = (void *)(long)skb->data_end;
367 int ret;
368
369 /* single length check */
370 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
371 ERROR(1);
372 return TC_ACT_SHOT;
373 }
374
375 key.tunnel_ttl = 64;
376 if (iph->protocol == IPPROTO_ICMP) {
377 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
378 } else {
379 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5)
380 return TC_ACT_SHOT;
381
382 if (tcp->dest == htons(5200))
383 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
384 else if (tcp->dest == htons(5201))
385 key.remote_ipv4 = 0xac100165; /* 172.16.1.101 */
386 else
387 return TC_ACT_SHOT;
388 }
389
390 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
391 if (ret < 0) {
392 ERROR(ret);
393 return TC_ACT_SHOT;
394 }
395
396 return TC_ACT_OK;
397}
398
399SEC("ipip_get_tunnel")
400int _ipip_get_tunnel(struct __sk_buff *skb)
401{
402 int ret;
403 struct bpf_tunnel_key key;
404 char fmt[] = "remote ip 0x%x\n";
405
406 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
407 if (ret < 0) {
408 ERROR(ret);
409 return TC_ACT_SHOT;
410 }
411
412 bpf_trace_printk(fmt, sizeof(fmt), key.remote_ipv4);
413 return TC_ACT_OK;
414}
415
Alexei Starovoitov173ca262016-09-15 13:00:32 -0700416SEC("ipip6_set_tunnel")
417int _ipip6_set_tunnel(struct __sk_buff *skb)
418{
419 struct bpf_tunnel_key key = {};
420 void *data = (void *)(long)skb->data;
421 struct iphdr *iph = data;
422 struct tcphdr *tcp = data + sizeof(*iph);
423 void *data_end = (void *)(long)skb->data_end;
424 int ret;
425
426 /* single length check */
427 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
428 ERROR(1);
429 return TC_ACT_SHOT;
430 }
431
432 key.remote_ipv6[0] = _htonl(0x2401db00);
433 key.tunnel_ttl = 64;
434
435 if (iph->protocol == IPPROTO_ICMP) {
436 key.remote_ipv6[3] = _htonl(1);
437 } else {
438 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5) {
439 ERROR(iph->protocol);
440 return TC_ACT_SHOT;
441 }
442
443 if (tcp->dest == htons(5200)) {
444 key.remote_ipv6[3] = _htonl(1);
445 } else if (tcp->dest == htons(5201)) {
446 key.remote_ipv6[3] = _htonl(2);
447 } else {
448 ERROR(tcp->dest);
449 return TC_ACT_SHOT;
450 }
451 }
452
453 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
454 if (ret < 0) {
455 ERROR(ret);
456 return TC_ACT_SHOT;
457 }
458
459 return TC_ACT_OK;
460}
461
462SEC("ipip6_get_tunnel")
463int _ipip6_get_tunnel(struct __sk_buff *skb)
464{
465 int ret;
466 struct bpf_tunnel_key key;
467 char fmt[] = "remote ip6 %x::%x\n";
468
469 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
470 if (ret < 0) {
471 ERROR(ret);
472 return TC_ACT_SHOT;
473 }
474
475 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
476 _htonl(key.remote_ipv6[3]));
477 return TC_ACT_OK;
478}
479
480SEC("ip6ip6_set_tunnel")
481int _ip6ip6_set_tunnel(struct __sk_buff *skb)
482{
483 struct bpf_tunnel_key key = {};
484 void *data = (void *)(long)skb->data;
485 struct ipv6hdr *iph = data;
486 struct tcphdr *tcp = data + sizeof(*iph);
487 void *data_end = (void *)(long)skb->data_end;
488 int ret;
489
490 /* single length check */
491 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
492 ERROR(1);
493 return TC_ACT_SHOT;
494 }
495
496 key.remote_ipv6[0] = _htonl(0x2401db00);
497 key.tunnel_ttl = 64;
498
499 if (iph->nexthdr == NEXTHDR_ICMP) {
500 key.remote_ipv6[3] = _htonl(1);
501 } else {
502 if (iph->nexthdr != NEXTHDR_TCP) {
503 ERROR(iph->nexthdr);
504 return TC_ACT_SHOT;
505 }
506
507 if (tcp->dest == htons(5200)) {
508 key.remote_ipv6[3] = _htonl(1);
509 } else if (tcp->dest == htons(5201)) {
510 key.remote_ipv6[3] = _htonl(2);
511 } else {
512 ERROR(tcp->dest);
513 return TC_ACT_SHOT;
514 }
515 }
516
517 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
518 if (ret < 0) {
519 ERROR(ret);
520 return TC_ACT_SHOT;
521 }
522
523 return TC_ACT_OK;
524}
525
526SEC("ip6ip6_get_tunnel")
527int _ip6ip6_get_tunnel(struct __sk_buff *skb)
528{
529 int ret;
530 struct bpf_tunnel_key key;
531 char fmt[] = "remote ip6 %x::%x\n";
532
533 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
534 if (ret < 0) {
535 ERROR(ret);
536 return TC_ACT_SHOT;
537 }
538
539 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
540 _htonl(key.remote_ipv6[3]));
541 return TC_ACT_OK;
542}
543
William Tu6afb1e22016-08-19 11:55:44 -0700544char _license[] SEC("license") = "GPL";