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";