1 /* Copyright (c) 2016 VMware
2 * Copyright (c) 2016 Facebook
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.
8 #define KBUILD_MODNAME "foo"
9 #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>
13 #include <uapi/linux/ipv6.h>
14 #include <uapi/linux/in.h>
15 #include <uapi/linux/tcp.h>
16 #include <uapi/linux/filter.h>
17 #include <uapi/linux/pkt_cls.h>
19 #include "bpf_helpers.h"
20 #include "bpf_endian.h"
22 #define _htonl __builtin_bswap32
23 #define ERROR(ret) do {\
24 char fmt[] = "ERROR line:%d ret:%d\n";\
25 bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \
35 u8 opt_data[8]; /* hard-coded to 8 byte */
44 struct vxlan_metadata {
48 struct erspan_metadata {
51 struct erspan_md2 md2;
57 int _gre_set_tunnel(struct __sk_buff *skb)
60 struct bpf_tunnel_key key;
62 __builtin_memset(&key, 0x0, sizeof(key));
63 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
68 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
78 int _gre_get_tunnel(struct __sk_buff *skb)
81 struct bpf_tunnel_key key;
82 char fmt[] = "key %d remote ip 0x%x\n";
84 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
90 bpf_trace_printk(fmt, sizeof(fmt), key.tunnel_id, key.remote_ipv4);
94 SEC("ip6gretap_set_tunnel")
95 int _ip6gretap_set_tunnel(struct __sk_buff *skb)
97 struct bpf_tunnel_key key;
100 __builtin_memset(&key, 0x0, sizeof(key));
101 key.remote_ipv6[3] = _htonl(0x11); /* ::11 */
105 key.tunnel_label = 0xabcde;
107 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
108 BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX);
117 SEC("ip6gretap_get_tunnel")
118 int _ip6gretap_get_tunnel(struct __sk_buff *skb)
120 char fmt[] = "key %d remote ip6 ::%x label %x\n";
121 struct bpf_tunnel_key key;
124 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
131 bpf_trace_printk(fmt, sizeof(fmt),
132 key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
137 SEC("erspan_set_tunnel")
138 int _erspan_set_tunnel(struct __sk_buff *skb)
140 struct bpf_tunnel_key key;
141 struct erspan_metadata md;
144 __builtin_memset(&key, 0x0, sizeof(key));
145 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
150 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
156 __builtin_memset(&md, 0, sizeof(md));
159 md.u.index = htonl(123);
165 md.u.md2.flags = htons((direction << 3) | (hwid << 4));
168 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
177 SEC("erspan_get_tunnel")
178 int _erspan_get_tunnel(struct __sk_buff *skb)
180 char fmt[] = "key %d remote ip 0x%x erspan version %d\n";
181 struct bpf_tunnel_key key;
182 struct erspan_metadata md;
186 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
192 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
198 bpf_trace_printk(fmt, sizeof(fmt),
199 key.tunnel_id, key.remote_ipv4, md.version);
202 char fmt2[] = "\tindex %x\n";
204 index = bpf_ntohl(md.u.index);
205 bpf_trace_printk(fmt2, sizeof(fmt2), index);
207 char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
209 bpf_trace_printk(fmt2, sizeof(fmt2),
210 (ntohs(md.u.md2.flags) >> 3) & 0x1,
211 (ntohs(md.u.md2.flags) >> 4) & 0x3f,
212 bpf_ntohl(md.u.md2.timestamp));
218 SEC("ip4ip6erspan_set_tunnel")
219 int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
221 struct bpf_tunnel_key key;
222 struct erspan_metadata md;
225 __builtin_memset(&key, 0x0, sizeof(key));
226 key.remote_ipv6[3] = _htonl(0x11);
231 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
238 __builtin_memset(&md, 0, sizeof(md));
241 md.u.index = htonl(123);
248 md.u.md2.flags = htons((direction << 3) | (hwid << 4));
251 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
260 SEC("ip4ip6erspan_get_tunnel")
261 int _ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
263 char fmt[] = "ip6erspan get key %d remote ip6 ::%x erspan version %d\n";
264 struct bpf_tunnel_key key;
265 struct erspan_metadata md;
269 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
275 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
281 bpf_trace_printk(fmt, sizeof(fmt),
282 key.tunnel_id, key.remote_ipv4, md.version);
285 char fmt2[] = "\tindex %x\n";
287 index = bpf_ntohl(md.u.index);
288 bpf_trace_printk(fmt2, sizeof(fmt2), index);
290 char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
292 bpf_trace_printk(fmt2, sizeof(fmt2),
293 (ntohs(md.u.md2.flags) >> 3) & 0x1,
294 (ntohs(md.u.md2.flags) >> 4) & 0x3f,
295 bpf_ntohl(md.u.md2.timestamp));
301 SEC("vxlan_set_tunnel")
302 int _vxlan_set_tunnel(struct __sk_buff *skb)
305 struct bpf_tunnel_key key;
306 struct vxlan_metadata md;
308 __builtin_memset(&key, 0x0, sizeof(key));
309 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
314 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
320 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
321 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
330 SEC("vxlan_get_tunnel")
331 int _vxlan_get_tunnel(struct __sk_buff *skb)
334 struct bpf_tunnel_key key;
335 struct vxlan_metadata md;
336 char fmt[] = "key %d remote ip 0x%x vxlan gbp 0x%x\n";
338 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
344 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
350 bpf_trace_printk(fmt, sizeof(fmt),
351 key.tunnel_id, key.remote_ipv4, md.gbp);
356 SEC("geneve_set_tunnel")
357 int _geneve_set_tunnel(struct __sk_buff *skb)
360 struct bpf_tunnel_key key;
361 struct geneve_opt gopt;
363 __builtin_memset(&key, 0x0, sizeof(key));
364 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
369 __builtin_memset(&gopt, 0x0, sizeof(gopt));
370 gopt.opt_class = 0x102; /* Open Virtual Networking (OVN) */
375 gopt.length = 2; /* 4-byte multiple */
376 *(int *) &gopt.opt_data = 0xdeadbeef;
378 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
384 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
393 SEC("geneve_get_tunnel")
394 int _geneve_get_tunnel(struct __sk_buff *skb)
397 struct bpf_tunnel_key key;
398 struct geneve_opt gopt;
399 char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n";
401 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
407 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
413 bpf_trace_printk(fmt, sizeof(fmt),
414 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
418 SEC("ipip_set_tunnel")
419 int _ipip_set_tunnel(struct __sk_buff *skb)
421 struct bpf_tunnel_key key = {};
422 void *data = (void *)(long)skb->data;
423 struct iphdr *iph = data;
424 struct tcphdr *tcp = data + sizeof(*iph);
425 void *data_end = (void *)(long)skb->data_end;
428 /* single length check */
429 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
435 if (iph->protocol == IPPROTO_ICMP) {
436 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
438 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5)
441 if (tcp->dest == htons(5200))
442 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
443 else if (tcp->dest == htons(5201))
444 key.remote_ipv4 = 0xac100165; /* 172.16.1.101 */
449 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
458 SEC("ipip_get_tunnel")
459 int _ipip_get_tunnel(struct __sk_buff *skb)
462 struct bpf_tunnel_key key;
463 char fmt[] = "remote ip 0x%x\n";
465 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
471 bpf_trace_printk(fmt, sizeof(fmt), key.remote_ipv4);
475 SEC("ipip6_set_tunnel")
476 int _ipip6_set_tunnel(struct __sk_buff *skb)
478 struct bpf_tunnel_key key = {};
479 void *data = (void *)(long)skb->data;
480 struct iphdr *iph = data;
481 struct tcphdr *tcp = data + sizeof(*iph);
482 void *data_end = (void *)(long)skb->data_end;
485 /* single length check */
486 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
491 key.remote_ipv6[0] = _htonl(0x2401db00);
494 if (iph->protocol == IPPROTO_ICMP) {
495 key.remote_ipv6[3] = _htonl(1);
497 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5) {
498 ERROR(iph->protocol);
502 if (tcp->dest == htons(5200)) {
503 key.remote_ipv6[3] = _htonl(1);
504 } else if (tcp->dest == htons(5201)) {
505 key.remote_ipv6[3] = _htonl(2);
512 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
521 SEC("ipip6_get_tunnel")
522 int _ipip6_get_tunnel(struct __sk_buff *skb)
525 struct bpf_tunnel_key key;
526 char fmt[] = "remote ip6 %x::%x\n";
528 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
534 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
535 _htonl(key.remote_ipv6[3]));
539 SEC("ip6ip6_set_tunnel")
540 int _ip6ip6_set_tunnel(struct __sk_buff *skb)
542 struct bpf_tunnel_key key = {};
543 void *data = (void *)(long)skb->data;
544 struct ipv6hdr *iph = data;
545 struct tcphdr *tcp = data + sizeof(*iph);
546 void *data_end = (void *)(long)skb->data_end;
549 /* single length check */
550 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
555 key.remote_ipv6[0] = _htonl(0x2401db00);
558 if (iph->nexthdr == NEXTHDR_ICMP) {
559 key.remote_ipv6[3] = _htonl(1);
561 if (iph->nexthdr != NEXTHDR_TCP) {
566 if (tcp->dest == htons(5200)) {
567 key.remote_ipv6[3] = _htonl(1);
568 } else if (tcp->dest == htons(5201)) {
569 key.remote_ipv6[3] = _htonl(2);
576 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
585 SEC("ip6ip6_get_tunnel")
586 int _ip6ip6_get_tunnel(struct __sk_buff *skb)
589 struct bpf_tunnel_key key;
590 char fmt[] = "remote ip6 %x::%x\n";
592 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
598 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
599 _htonl(key.remote_ipv6[3]));
603 char _license[] SEC("license") = "GPL";