1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2016 VMware
3 * Copyright (c) 2016 Facebook
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public
7 * License as published by the Free Software Foundation.
11 #include <arpa/inet.h>
12 #include <linux/bpf.h>
13 #include <linux/if_ether.h>
14 #include <linux/if_packet.h>
16 #include <linux/ipv6.h>
17 #include <linux/types.h>
18 #include <linux/tcp.h>
19 #include <linux/socket.h>
20 #include <linux/pkt_cls.h>
21 #include <linux/erspan.h>
22 #include "bpf_helpers.h"
23 #include "bpf_endian.h"
25 #define ERROR(ret) do {\
26 char fmt[] = "ERROR line:%d ret:%d\n";\
27 bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \
30 int _version
SEC("version") = 1;
39 __u8 opt_data
[8]; /* hard-coded to 8 byte */
42 struct vxlan_metadata
{
47 int _gre_set_tunnel(struct __sk_buff
*skb
)
50 struct bpf_tunnel_key key
;
52 __builtin_memset(&key
, 0x0, sizeof(key
));
53 key
.remote_ipv4
= 0xac100164; /* 172.16.1.100 */
58 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
59 BPF_F_ZERO_CSUM_TX
| BPF_F_SEQ_NUMBER
);
69 int _gre_get_tunnel(struct __sk_buff
*skb
)
72 struct bpf_tunnel_key key
;
73 char fmt
[] = "key %d remote ip 0x%x\n";
75 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
), 0);
81 bpf_trace_printk(fmt
, sizeof(fmt
), key
.tunnel_id
, key
.remote_ipv4
);
85 SEC("ip6gretap_set_tunnel")
86 int _ip6gretap_set_tunnel(struct __sk_buff
*skb
)
88 struct bpf_tunnel_key key
;
91 __builtin_memset(&key
, 0x0, sizeof(key
));
92 key
.remote_ipv6
[3] = bpf_htonl(0x11); /* ::11 */
96 key
.tunnel_label
= 0xabcde;
98 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
99 BPF_F_TUNINFO_IPV6
| BPF_F_ZERO_CSUM_TX
|
109 SEC("ip6gretap_get_tunnel")
110 int _ip6gretap_get_tunnel(struct __sk_buff
*skb
)
112 char fmt
[] = "key %d remote ip6 ::%x label %x\n";
113 struct bpf_tunnel_key key
;
116 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
),
123 bpf_trace_printk(fmt
, sizeof(fmt
),
124 key
.tunnel_id
, key
.remote_ipv6
[3], key
.tunnel_label
);
129 SEC("erspan_set_tunnel")
130 int _erspan_set_tunnel(struct __sk_buff
*skb
)
132 struct bpf_tunnel_key key
;
133 struct erspan_metadata md
;
136 __builtin_memset(&key
, 0x0, sizeof(key
));
137 key
.remote_ipv4
= 0xac100164; /* 172.16.1.100 */
142 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
149 __builtin_memset(&md
, 0, sizeof(md
));
152 md
.u
.index
= bpf_htonl(123);
158 md
.u
.md2
.dir
= direction
;
159 md
.u
.md2
.hwid
= hwid
& 0xf;
160 md
.u
.md2
.hwid_upper
= (hwid
>> 4) & 0x3;
163 ret
= bpf_skb_set_tunnel_opt(skb
, &md
, sizeof(md
));
172 SEC("erspan_get_tunnel")
173 int _erspan_get_tunnel(struct __sk_buff
*skb
)
175 char fmt
[] = "key %d remote ip 0x%x erspan version %d\n";
176 struct bpf_tunnel_key key
;
177 struct erspan_metadata md
;
181 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
), 0);
187 ret
= bpf_skb_get_tunnel_opt(skb
, &md
, sizeof(md
));
193 bpf_trace_printk(fmt
, sizeof(fmt
),
194 key
.tunnel_id
, key
.remote_ipv4
, md
.version
);
197 char fmt2
[] = "\tindex %x\n";
199 index
= bpf_ntohl(md
.u
.index
);
200 bpf_trace_printk(fmt2
, sizeof(fmt2
), index
);
202 char fmt2
[] = "\tdirection %d hwid %x timestamp %u\n";
204 bpf_trace_printk(fmt2
, sizeof(fmt2
),
206 (md
.u
.md2
.hwid_upper
<< 4) + md
.u
.md2
.hwid
,
207 bpf_ntohl(md
.u
.md2
.timestamp
));
213 SEC("ip4ip6erspan_set_tunnel")
214 int _ip4ip6erspan_set_tunnel(struct __sk_buff
*skb
)
216 struct bpf_tunnel_key key
;
217 struct erspan_metadata md
;
220 __builtin_memset(&key
, 0x0, sizeof(key
));
221 key
.remote_ipv6
[3] = bpf_htonl(0x11);
226 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
233 __builtin_memset(&md
, 0, sizeof(md
));
236 md
.u
.index
= bpf_htonl(123);
243 md
.u
.md2
.dir
= direction
;
244 md
.u
.md2
.hwid
= hwid
& 0xf;
245 md
.u
.md2
.hwid_upper
= (hwid
>> 4) & 0x3;
248 ret
= bpf_skb_set_tunnel_opt(skb
, &md
, sizeof(md
));
257 SEC("ip4ip6erspan_get_tunnel")
258 int _ip4ip6erspan_get_tunnel(struct __sk_buff
*skb
)
260 char fmt
[] = "ip6erspan get key %d remote ip6 ::%x erspan version %d\n";
261 struct bpf_tunnel_key key
;
262 struct erspan_metadata md
;
266 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
),
273 ret
= bpf_skb_get_tunnel_opt(skb
, &md
, sizeof(md
));
279 bpf_trace_printk(fmt
, sizeof(fmt
),
280 key
.tunnel_id
, key
.remote_ipv4
, md
.version
);
283 char fmt2
[] = "\tindex %x\n";
285 index
= bpf_ntohl(md
.u
.index
);
286 bpf_trace_printk(fmt2
, sizeof(fmt2
), index
);
288 char fmt2
[] = "\tdirection %d hwid %x timestamp %u\n";
290 bpf_trace_printk(fmt2
, sizeof(fmt2
),
292 (md
.u
.md2
.hwid_upper
<< 4) + md
.u
.md2
.hwid
,
293 bpf_ntohl(md
.u
.md2
.timestamp
));
299 SEC("vxlan_set_tunnel")
300 int _vxlan_set_tunnel(struct __sk_buff
*skb
)
303 struct bpf_tunnel_key key
;
304 struct vxlan_metadata md
;
306 __builtin_memset(&key
, 0x0, sizeof(key
));
307 key
.remote_ipv4
= 0xac100164; /* 172.16.1.100 */
312 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
319 md
.gbp
= 0x800FF; /* Set VXLAN Group Policy extension */
320 ret
= bpf_skb_set_tunnel_opt(skb
, &md
, sizeof(md
));
329 SEC("vxlan_get_tunnel")
330 int _vxlan_get_tunnel(struct __sk_buff
*skb
)
333 struct bpf_tunnel_key key
;
334 struct vxlan_metadata md
;
335 char fmt
[] = "key %d remote ip 0x%x vxlan gbp 0x%x\n";
337 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
), 0);
343 ret
= bpf_skb_get_tunnel_opt(skb
, &md
, sizeof(md
));
349 bpf_trace_printk(fmt
, sizeof(fmt
),
350 key
.tunnel_id
, key
.remote_ipv4
, md
.gbp
);
355 SEC("ip6vxlan_set_tunnel")
356 int _ip6vxlan_set_tunnel(struct __sk_buff
*skb
)
358 struct bpf_tunnel_key key
;
361 __builtin_memset(&key
, 0x0, sizeof(key
));
362 key
.remote_ipv6
[3] = bpf_htonl(0x11); /* ::11 */
367 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
377 SEC("ip6vxlan_get_tunnel")
378 int _ip6vxlan_get_tunnel(struct __sk_buff
*skb
)
380 char fmt
[] = "key %d remote ip6 ::%x label %x\n";
381 struct bpf_tunnel_key key
;
384 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
),
391 bpf_trace_printk(fmt
, sizeof(fmt
),
392 key
.tunnel_id
, key
.remote_ipv6
[3], key
.tunnel_label
);
397 SEC("geneve_set_tunnel")
398 int _geneve_set_tunnel(struct __sk_buff
*skb
)
401 struct bpf_tunnel_key key
;
402 struct geneve_opt gopt
;
404 __builtin_memset(&key
, 0x0, sizeof(key
));
405 key
.remote_ipv4
= 0xac100164; /* 172.16.1.100 */
410 __builtin_memset(&gopt
, 0x0, sizeof(gopt
));
411 gopt
.opt_class
= bpf_htons(0x102); /* Open Virtual Networking (OVN) */
416 gopt
.length
= 2; /* 4-byte multiple */
417 *(int *) &gopt
.opt_data
= bpf_htonl(0xdeadbeef);
419 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
426 ret
= bpf_skb_set_tunnel_opt(skb
, &gopt
, sizeof(gopt
));
435 SEC("geneve_get_tunnel")
436 int _geneve_get_tunnel(struct __sk_buff
*skb
)
439 struct bpf_tunnel_key key
;
440 struct geneve_opt gopt
;
441 char fmt
[] = "key %d remote ip 0x%x geneve class 0x%x\n";
443 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
), 0);
449 ret
= bpf_skb_get_tunnel_opt(skb
, &gopt
, sizeof(gopt
));
455 bpf_trace_printk(fmt
, sizeof(fmt
),
456 key
.tunnel_id
, key
.remote_ipv4
, gopt
.opt_class
);
460 SEC("ip6geneve_set_tunnel")
461 int _ip6geneve_set_tunnel(struct __sk_buff
*skb
)
463 struct bpf_tunnel_key key
;
464 struct geneve_opt gopt
;
467 __builtin_memset(&key
, 0x0, sizeof(key
));
468 key
.remote_ipv6
[3] = bpf_htonl(0x11); /* ::11 */
473 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
480 __builtin_memset(&gopt
, 0x0, sizeof(gopt
));
481 gopt
.opt_class
= bpf_htons(0x102); /* Open Virtual Networking (OVN) */
486 gopt
.length
= 2; /* 4-byte multiple */
487 *(int *) &gopt
.opt_data
= bpf_htonl(0xfeedbeef);
489 ret
= bpf_skb_set_tunnel_opt(skb
, &gopt
, sizeof(gopt
));
498 SEC("ip6geneve_get_tunnel")
499 int _ip6geneve_get_tunnel(struct __sk_buff
*skb
)
501 char fmt
[] = "key %d remote ip 0x%x geneve class 0x%x\n";
502 struct bpf_tunnel_key key
;
503 struct geneve_opt gopt
;
506 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
),
513 ret
= bpf_skb_get_tunnel_opt(skb
, &gopt
, sizeof(gopt
));
519 bpf_trace_printk(fmt
, sizeof(fmt
),
520 key
.tunnel_id
, key
.remote_ipv4
, gopt
.opt_class
);
525 SEC("ipip_set_tunnel")
526 int _ipip_set_tunnel(struct __sk_buff
*skb
)
528 struct bpf_tunnel_key key
= {};
529 void *data
= (void *)(long)skb
->data
;
530 struct iphdr
*iph
= data
;
531 struct tcphdr
*tcp
= data
+ sizeof(*iph
);
532 void *data_end
= (void *)(long)skb
->data_end
;
535 /* single length check */
536 if (data
+ sizeof(*iph
) + sizeof(*tcp
) > data_end
) {
542 if (iph
->protocol
== IPPROTO_ICMP
) {
543 key
.remote_ipv4
= 0xac100164; /* 172.16.1.100 */
545 if (iph
->protocol
!= IPPROTO_TCP
|| iph
->ihl
!= 5)
548 if (tcp
->dest
== bpf_htons(5200))
549 key
.remote_ipv4
= 0xac100164; /* 172.16.1.100 */
550 else if (tcp
->dest
== bpf_htons(5201))
551 key
.remote_ipv4
= 0xac100165; /* 172.16.1.101 */
556 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
), 0);
565 SEC("ipip_get_tunnel")
566 int _ipip_get_tunnel(struct __sk_buff
*skb
)
569 struct bpf_tunnel_key key
;
570 char fmt
[] = "remote ip 0x%x\n";
572 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
), 0);
578 bpf_trace_printk(fmt
, sizeof(fmt
), key
.remote_ipv4
);
582 SEC("ipip6_set_tunnel")
583 int _ipip6_set_tunnel(struct __sk_buff
*skb
)
585 struct bpf_tunnel_key key
= {};
586 void *data
= (void *)(long)skb
->data
;
587 struct iphdr
*iph
= data
;
588 struct tcphdr
*tcp
= data
+ sizeof(*iph
);
589 void *data_end
= (void *)(long)skb
->data_end
;
592 /* single length check */
593 if (data
+ sizeof(*iph
) + sizeof(*tcp
) > data_end
) {
598 __builtin_memset(&key
, 0x0, sizeof(key
));
599 key
.remote_ipv6
[3] = bpf_htonl(0x11); /* ::11 */
602 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
612 SEC("ipip6_get_tunnel")
613 int _ipip6_get_tunnel(struct __sk_buff
*skb
)
616 struct bpf_tunnel_key key
;
617 char fmt
[] = "remote ip6 %x::%x\n";
619 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
),
626 bpf_trace_printk(fmt
, sizeof(fmt
), bpf_htonl(key
.remote_ipv6
[0]),
627 bpf_htonl(key
.remote_ipv6
[3]));
631 SEC("ip6ip6_set_tunnel")
632 int _ip6ip6_set_tunnel(struct __sk_buff
*skb
)
634 struct bpf_tunnel_key key
= {};
635 void *data
= (void *)(long)skb
->data
;
636 struct ipv6hdr
*iph
= data
;
637 struct tcphdr
*tcp
= data
+ sizeof(*iph
);
638 void *data_end
= (void *)(long)skb
->data_end
;
641 /* single length check */
642 if (data
+ sizeof(*iph
) + sizeof(*tcp
) > data_end
) {
647 key
.remote_ipv6
[0] = bpf_htonl(0x2401db00);
650 if (iph
->nexthdr
== 58 /* NEXTHDR_ICMP */) {
651 key
.remote_ipv6
[3] = bpf_htonl(1);
653 if (iph
->nexthdr
!= 6 /* NEXTHDR_TCP */) {
658 if (tcp
->dest
== bpf_htons(5200)) {
659 key
.remote_ipv6
[3] = bpf_htonl(1);
660 } else if (tcp
->dest
== bpf_htons(5201)) {
661 key
.remote_ipv6
[3] = bpf_htonl(2);
668 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
678 SEC("ip6ip6_get_tunnel")
679 int _ip6ip6_get_tunnel(struct __sk_buff
*skb
)
682 struct bpf_tunnel_key key
;
683 char fmt
[] = "remote ip6 %x::%x\n";
685 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
),
692 bpf_trace_printk(fmt
, sizeof(fmt
), bpf_htonl(key
.remote_ipv6
[0]),
693 bpf_htonl(key
.remote_ipv6
[3]));
697 SEC("xfrm_get_state")
698 int _xfrm_get_state(struct __sk_buff
*skb
)
700 struct bpf_xfrm_state x
;
701 char fmt
[] = "reqid %d spi 0x%x remote ip 0x%x\n";
704 ret
= bpf_skb_get_xfrm_state(skb
, 0, &x
, sizeof(x
), 0);
708 bpf_trace_printk(fmt
, sizeof(fmt
), x
.reqid
, bpf_ntohl(x
.spi
),
709 bpf_ntohl(x
.remote_ipv4
));
713 char _license
[] SEC("license") = "GPL";