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), BPF_F_ZERO_CSUM_TX);
65 int _gre_get_tunnel(struct __sk_buff *skb)
68 struct bpf_tunnel_key key;
69 char fmt[] = "key %d remote ip 0x%x\n";
71 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
77 bpf_trace_printk(fmt, sizeof(fmt), key.tunnel_id, key.remote_ipv4);
81 SEC("ip6gretap_set_tunnel")
82 int _ip6gretap_set_tunnel(struct __sk_buff *skb)
84 struct bpf_tunnel_key key;
87 __builtin_memset(&key, 0x0, sizeof(key));
88 key.remote_ipv6[3] = _htonl(0x11); /* ::11 */
92 key.tunnel_label = 0xabcde;
94 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
95 BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX);
104 SEC("ip6gretap_get_tunnel")
105 int _ip6gretap_get_tunnel(struct __sk_buff *skb)
107 char fmt[] = "key %d remote ip6 ::%x label %x\n";
108 struct bpf_tunnel_key key;
111 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
118 bpf_trace_printk(fmt, sizeof(fmt),
119 key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
124 SEC("erspan_set_tunnel")
125 int _erspan_set_tunnel(struct __sk_buff *skb)
127 struct bpf_tunnel_key key;
128 struct erspan_metadata md;
131 __builtin_memset(&key, 0x0, sizeof(key));
132 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
137 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
143 __builtin_memset(&md, 0, sizeof(md));
146 md.u.index = bpf_htonl(123);
152 md.u.md2.dir = direction;
153 md.u.md2.hwid = hwid & 0xf;
154 md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
157 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
166 SEC("erspan_get_tunnel")
167 int _erspan_get_tunnel(struct __sk_buff *skb)
169 char fmt[] = "key %d remote ip 0x%x erspan version %d\n";
170 struct bpf_tunnel_key key;
171 struct erspan_metadata md;
175 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
181 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
187 bpf_trace_printk(fmt, sizeof(fmt),
188 key.tunnel_id, key.remote_ipv4, md.version);
191 char fmt2[] = "\tindex %x\n";
193 index = bpf_ntohl(md.u.index);
194 bpf_trace_printk(fmt2, sizeof(fmt2), index);
196 char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
198 bpf_trace_printk(fmt2, sizeof(fmt2),
200 (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
201 bpf_ntohl(md.u.md2.timestamp));
207 SEC("ip4ip6erspan_set_tunnel")
208 int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
210 struct bpf_tunnel_key key;
211 struct erspan_metadata md;
214 __builtin_memset(&key, 0x0, sizeof(key));
215 key.remote_ipv6[3] = _htonl(0x11);
220 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
227 __builtin_memset(&md, 0, sizeof(md));
230 md.u.index = htonl(123);
237 md.u.md2.dir = direction;
238 md.u.md2.hwid = hwid & 0xf;
239 md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
242 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
251 SEC("ip4ip6erspan_get_tunnel")
252 int _ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
254 char fmt[] = "ip6erspan get key %d remote ip6 ::%x erspan version %d\n";
255 struct bpf_tunnel_key key;
256 struct erspan_metadata md;
260 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
266 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
272 bpf_trace_printk(fmt, sizeof(fmt),
273 key.tunnel_id, key.remote_ipv4, md.version);
276 char fmt2[] = "\tindex %x\n";
278 index = bpf_ntohl(md.u.index);
279 bpf_trace_printk(fmt2, sizeof(fmt2), index);
281 char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
283 bpf_trace_printk(fmt2, sizeof(fmt2),
285 (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
286 bpf_ntohl(md.u.md2.timestamp));
292 SEC("vxlan_set_tunnel")
293 int _vxlan_set_tunnel(struct __sk_buff *skb)
296 struct bpf_tunnel_key key;
297 struct vxlan_metadata md;
299 __builtin_memset(&key, 0x0, sizeof(key));
300 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
305 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
311 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
312 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
321 SEC("vxlan_get_tunnel")
322 int _vxlan_get_tunnel(struct __sk_buff *skb)
325 struct bpf_tunnel_key key;
326 struct vxlan_metadata md;
327 char fmt[] = "key %d remote ip 0x%x vxlan gbp 0x%x\n";
329 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
335 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
341 bpf_trace_printk(fmt, sizeof(fmt),
342 key.tunnel_id, key.remote_ipv4, md.gbp);
347 SEC("geneve_set_tunnel")
348 int _geneve_set_tunnel(struct __sk_buff *skb)
351 struct bpf_tunnel_key key;
352 struct geneve_opt gopt;
354 __builtin_memset(&key, 0x0, sizeof(key));
355 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
360 __builtin_memset(&gopt, 0x0, sizeof(gopt));
361 gopt.opt_class = 0x102; /* Open Virtual Networking (OVN) */
366 gopt.length = 2; /* 4-byte multiple */
367 *(int *) &gopt.opt_data = 0xdeadbeef;
369 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
375 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
384 SEC("geneve_get_tunnel")
385 int _geneve_get_tunnel(struct __sk_buff *skb)
388 struct bpf_tunnel_key key;
389 struct geneve_opt gopt;
390 char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n";
392 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
398 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
404 bpf_trace_printk(fmt, sizeof(fmt),
405 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
409 SEC("ipip_set_tunnel")
410 int _ipip_set_tunnel(struct __sk_buff *skb)
412 struct bpf_tunnel_key key = {};
413 void *data = (void *)(long)skb->data;
414 struct iphdr *iph = data;
415 struct tcphdr *tcp = data + sizeof(*iph);
416 void *data_end = (void *)(long)skb->data_end;
419 /* single length check */
420 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
426 if (iph->protocol == IPPROTO_ICMP) {
427 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
429 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5)
432 if (tcp->dest == htons(5200))
433 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
434 else if (tcp->dest == htons(5201))
435 key.remote_ipv4 = 0xac100165; /* 172.16.1.101 */
440 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
449 SEC("ipip_get_tunnel")
450 int _ipip_get_tunnel(struct __sk_buff *skb)
453 struct bpf_tunnel_key key;
454 char fmt[] = "remote ip 0x%x\n";
456 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
462 bpf_trace_printk(fmt, sizeof(fmt), key.remote_ipv4);
466 SEC("ipip6_set_tunnel")
467 int _ipip6_set_tunnel(struct __sk_buff *skb)
469 struct bpf_tunnel_key key = {};
470 void *data = (void *)(long)skb->data;
471 struct iphdr *iph = data;
472 struct tcphdr *tcp = data + sizeof(*iph);
473 void *data_end = (void *)(long)skb->data_end;
476 /* single length check */
477 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
482 key.remote_ipv6[0] = _htonl(0x2401db00);
485 if (iph->protocol == IPPROTO_ICMP) {
486 key.remote_ipv6[3] = _htonl(1);
488 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5) {
489 ERROR(iph->protocol);
493 if (tcp->dest == htons(5200)) {
494 key.remote_ipv6[3] = _htonl(1);
495 } else if (tcp->dest == htons(5201)) {
496 key.remote_ipv6[3] = _htonl(2);
503 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
512 SEC("ipip6_get_tunnel")
513 int _ipip6_get_tunnel(struct __sk_buff *skb)
516 struct bpf_tunnel_key key;
517 char fmt[] = "remote ip6 %x::%x\n";
519 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
525 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
526 _htonl(key.remote_ipv6[3]));
530 SEC("ip6ip6_set_tunnel")
531 int _ip6ip6_set_tunnel(struct __sk_buff *skb)
533 struct bpf_tunnel_key key = {};
534 void *data = (void *)(long)skb->data;
535 struct ipv6hdr *iph = data;
536 struct tcphdr *tcp = data + sizeof(*iph);
537 void *data_end = (void *)(long)skb->data_end;
540 /* single length check */
541 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
546 key.remote_ipv6[0] = _htonl(0x2401db00);
549 if (iph->nexthdr == NEXTHDR_ICMP) {
550 key.remote_ipv6[3] = _htonl(1);
552 if (iph->nexthdr != NEXTHDR_TCP) {
557 if (tcp->dest == htons(5200)) {
558 key.remote_ipv6[3] = _htonl(1);
559 } else if (tcp->dest == htons(5201)) {
560 key.remote_ipv6[3] = _htonl(2);
567 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
576 SEC("ip6ip6_get_tunnel")
577 int _ip6ip6_get_tunnel(struct __sk_buff *skb)
580 struct bpf_tunnel_key key;
581 char fmt[] = "remote ip6 %x::%x\n";
583 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
589 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
590 _htonl(key.remote_ipv6[3]));
594 char _license[] SEC("license") = "GPL";