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>
18 #include <uapi/linux/erspan.h>
20 #include "bpf_helpers.h"
21 #include "bpf_endian.h"
23 #define _htonl __builtin_bswap32
24 #define ERROR(ret) do {\
25 char fmt[] = "ERROR line:%d ret:%d\n";\
26 bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \
36 u8 opt_data[8]; /* hard-coded to 8 byte */
39 struct vxlan_metadata {
44 int _gre_set_tunnel(struct __sk_buff *skb)
47 struct bpf_tunnel_key key;
49 __builtin_memset(&key, 0x0, sizeof(key));
50 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
55 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
56 BPF_F_ZERO_CSUM_TX | BPF_F_SEQ_NUMBER);
66 int _gre_get_tunnel(struct __sk_buff *skb)
69 struct bpf_tunnel_key key;
70 char fmt[] = "key %d remote ip 0x%x\n";
72 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
78 bpf_trace_printk(fmt, sizeof(fmt), key.tunnel_id, key.remote_ipv4);
82 SEC("ip6gretap_set_tunnel")
83 int _ip6gretap_set_tunnel(struct __sk_buff *skb)
85 struct bpf_tunnel_key key;
88 __builtin_memset(&key, 0x0, sizeof(key));
89 key.remote_ipv6[3] = _htonl(0x11); /* ::11 */
93 key.tunnel_label = 0xabcde;
95 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
96 BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX |
106 SEC("ip6gretap_get_tunnel")
107 int _ip6gretap_get_tunnel(struct __sk_buff *skb)
109 char fmt[] = "key %d remote ip6 ::%x label %x\n";
110 struct bpf_tunnel_key key;
113 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
120 bpf_trace_printk(fmt, sizeof(fmt),
121 key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
126 SEC("erspan_set_tunnel")
127 int _erspan_set_tunnel(struct __sk_buff *skb)
129 struct bpf_tunnel_key key;
130 struct erspan_metadata md;
133 __builtin_memset(&key, 0x0, sizeof(key));
134 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
139 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
145 __builtin_memset(&md, 0, sizeof(md));
148 md.u.index = bpf_htonl(123);
154 md.u.md2.dir = direction;
155 md.u.md2.hwid = hwid & 0xf;
156 md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
159 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
168 SEC("erspan_get_tunnel")
169 int _erspan_get_tunnel(struct __sk_buff *skb)
171 char fmt[] = "key %d remote ip 0x%x erspan version %d\n";
172 struct bpf_tunnel_key key;
173 struct erspan_metadata md;
177 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
183 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
189 bpf_trace_printk(fmt, sizeof(fmt),
190 key.tunnel_id, key.remote_ipv4, md.version);
193 char fmt2[] = "\tindex %x\n";
195 index = bpf_ntohl(md.u.index);
196 bpf_trace_printk(fmt2, sizeof(fmt2), index);
198 char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
200 bpf_trace_printk(fmt2, sizeof(fmt2),
202 (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
203 bpf_ntohl(md.u.md2.timestamp));
209 SEC("ip4ip6erspan_set_tunnel")
210 int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
212 struct bpf_tunnel_key key;
213 struct erspan_metadata md;
216 __builtin_memset(&key, 0x0, sizeof(key));
217 key.remote_ipv6[3] = _htonl(0x11);
222 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
229 __builtin_memset(&md, 0, sizeof(md));
232 md.u.index = htonl(123);
239 md.u.md2.dir = direction;
240 md.u.md2.hwid = hwid & 0xf;
241 md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
244 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
253 SEC("ip4ip6erspan_get_tunnel")
254 int _ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
256 char fmt[] = "ip6erspan get key %d remote ip6 ::%x erspan version %d\n";
257 struct bpf_tunnel_key key;
258 struct erspan_metadata md;
262 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
268 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
274 bpf_trace_printk(fmt, sizeof(fmt),
275 key.tunnel_id, key.remote_ipv4, md.version);
278 char fmt2[] = "\tindex %x\n";
280 index = bpf_ntohl(md.u.index);
281 bpf_trace_printk(fmt2, sizeof(fmt2), index);
283 char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
285 bpf_trace_printk(fmt2, sizeof(fmt2),
287 (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
288 bpf_ntohl(md.u.md2.timestamp));
294 SEC("vxlan_set_tunnel")
295 int _vxlan_set_tunnel(struct __sk_buff *skb)
298 struct bpf_tunnel_key key;
299 struct vxlan_metadata md;
301 __builtin_memset(&key, 0x0, sizeof(key));
302 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
307 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
313 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
314 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
323 SEC("vxlan_get_tunnel")
324 int _vxlan_get_tunnel(struct __sk_buff *skb)
327 struct bpf_tunnel_key key;
328 struct vxlan_metadata md;
329 char fmt[] = "key %d remote ip 0x%x vxlan gbp 0x%x\n";
331 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
337 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
343 bpf_trace_printk(fmt, sizeof(fmt),
344 key.tunnel_id, key.remote_ipv4, md.gbp);
349 SEC("geneve_set_tunnel")
350 int _geneve_set_tunnel(struct __sk_buff *skb)
353 struct bpf_tunnel_key key;
354 struct geneve_opt gopt;
356 __builtin_memset(&key, 0x0, sizeof(key));
357 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
362 __builtin_memset(&gopt, 0x0, sizeof(gopt));
363 gopt.opt_class = 0x102; /* Open Virtual Networking (OVN) */
368 gopt.length = 2; /* 4-byte multiple */
369 *(int *) &gopt.opt_data = 0xdeadbeef;
371 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
377 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
386 SEC("geneve_get_tunnel")
387 int _geneve_get_tunnel(struct __sk_buff *skb)
390 struct bpf_tunnel_key key;
391 struct geneve_opt gopt;
392 char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n";
394 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
400 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
406 bpf_trace_printk(fmt, sizeof(fmt),
407 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
411 SEC("ipip_set_tunnel")
412 int _ipip_set_tunnel(struct __sk_buff *skb)
414 struct bpf_tunnel_key key = {};
415 void *data = (void *)(long)skb->data;
416 struct iphdr *iph = data;
417 struct tcphdr *tcp = data + sizeof(*iph);
418 void *data_end = (void *)(long)skb->data_end;
421 /* single length check */
422 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
428 if (iph->protocol == IPPROTO_ICMP) {
429 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
431 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5)
434 if (tcp->dest == htons(5200))
435 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
436 else if (tcp->dest == htons(5201))
437 key.remote_ipv4 = 0xac100165; /* 172.16.1.101 */
442 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
451 SEC("ipip_get_tunnel")
452 int _ipip_get_tunnel(struct __sk_buff *skb)
455 struct bpf_tunnel_key key;
456 char fmt[] = "remote ip 0x%x\n";
458 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
464 bpf_trace_printk(fmt, sizeof(fmt), key.remote_ipv4);
468 SEC("ipip6_set_tunnel")
469 int _ipip6_set_tunnel(struct __sk_buff *skb)
471 struct bpf_tunnel_key key = {};
472 void *data = (void *)(long)skb->data;
473 struct iphdr *iph = data;
474 struct tcphdr *tcp = data + sizeof(*iph);
475 void *data_end = (void *)(long)skb->data_end;
478 /* single length check */
479 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
484 key.remote_ipv6[0] = _htonl(0x2401db00);
487 if (iph->protocol == IPPROTO_ICMP) {
488 key.remote_ipv6[3] = _htonl(1);
490 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5) {
491 ERROR(iph->protocol);
495 if (tcp->dest == htons(5200)) {
496 key.remote_ipv6[3] = _htonl(1);
497 } else if (tcp->dest == htons(5201)) {
498 key.remote_ipv6[3] = _htonl(2);
505 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
514 SEC("ipip6_get_tunnel")
515 int _ipip6_get_tunnel(struct __sk_buff *skb)
518 struct bpf_tunnel_key key;
519 char fmt[] = "remote ip6 %x::%x\n";
521 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
527 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
528 _htonl(key.remote_ipv6[3]));
532 SEC("ip6ip6_set_tunnel")
533 int _ip6ip6_set_tunnel(struct __sk_buff *skb)
535 struct bpf_tunnel_key key = {};
536 void *data = (void *)(long)skb->data;
537 struct ipv6hdr *iph = data;
538 struct tcphdr *tcp = data + sizeof(*iph);
539 void *data_end = (void *)(long)skb->data_end;
542 /* single length check */
543 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
548 key.remote_ipv6[0] = _htonl(0x2401db00);
551 if (iph->nexthdr == NEXTHDR_ICMP) {
552 key.remote_ipv6[3] = _htonl(1);
554 if (iph->nexthdr != NEXTHDR_TCP) {
559 if (tcp->dest == htons(5200)) {
560 key.remote_ipv6[3] = _htonl(1);
561 } else if (tcp->dest == htons(5201)) {
562 key.remote_ipv6[3] = _htonl(2);
569 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
578 SEC("ip6ip6_get_tunnel")
579 int _ip6ip6_get_tunnel(struct __sk_buff *skb)
582 struct bpf_tunnel_key key;
583 char fmt[] = "remote ip6 %x::%x\n";
585 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
591 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
592 _htonl(key.remote_ipv6[3]));
596 char _license[] SEC("license") = "GPL";