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/socket.h>
19 #include <linux/pkt_cls.h>
20 #include <linux/erspan.h>
21 #include <bpf/bpf_helpers.h>
22 #include <bpf/bpf_endian.h>
24 #define ERROR(ret) do {\
25 char fmt[] = "ERROR line:%d ret:%d\n";\
26 bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \
29 int _version
SEC("version") = 1;
38 __u8 opt_data
[8]; /* hard-coded to 8 byte */
41 struct vxlan_metadata
{
46 int _gre_set_tunnel(struct __sk_buff
*skb
)
49 struct bpf_tunnel_key key
;
51 __builtin_memset(&key
, 0x0, sizeof(key
));
52 key
.remote_ipv4
= 0xac100164; /* 172.16.1.100 */
57 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
58 BPF_F_ZERO_CSUM_TX
| BPF_F_SEQ_NUMBER
);
68 int _gre_get_tunnel(struct __sk_buff
*skb
)
71 struct bpf_tunnel_key key
;
72 char fmt
[] = "key %d remote ip 0x%x\n";
74 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
), 0);
80 bpf_trace_printk(fmt
, sizeof(fmt
), key
.tunnel_id
, key
.remote_ipv4
);
84 SEC("ip6gretap_set_tunnel")
85 int _ip6gretap_set_tunnel(struct __sk_buff
*skb
)
87 struct bpf_tunnel_key key
;
90 __builtin_memset(&key
, 0x0, sizeof(key
));
91 key
.remote_ipv6
[3] = bpf_htonl(0x11); /* ::11 */
95 key
.tunnel_label
= 0xabcde;
97 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
98 BPF_F_TUNINFO_IPV6
| BPF_F_ZERO_CSUM_TX
|
108 SEC("ip6gretap_get_tunnel")
109 int _ip6gretap_get_tunnel(struct __sk_buff
*skb
)
111 char fmt
[] = "key %d remote ip6 ::%x label %x\n";
112 struct bpf_tunnel_key key
;
115 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
),
122 bpf_trace_printk(fmt
, sizeof(fmt
),
123 key
.tunnel_id
, key
.remote_ipv6
[3], key
.tunnel_label
);
128 SEC("erspan_set_tunnel")
129 int _erspan_set_tunnel(struct __sk_buff
*skb
)
131 struct bpf_tunnel_key key
;
132 struct erspan_metadata md
;
135 __builtin_memset(&key
, 0x0, sizeof(key
));
136 key
.remote_ipv4
= 0xac100164; /* 172.16.1.100 */
141 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
148 __builtin_memset(&md
, 0, sizeof(md
));
151 md
.u
.index
= bpf_htonl(123);
157 md
.u
.md2
.dir
= direction
;
158 md
.u
.md2
.hwid
= hwid
& 0xf;
159 md
.u
.md2
.hwid_upper
= (hwid
>> 4) & 0x3;
162 ret
= bpf_skb_set_tunnel_opt(skb
, &md
, sizeof(md
));
171 SEC("erspan_get_tunnel")
172 int _erspan_get_tunnel(struct __sk_buff
*skb
)
174 char fmt
[] = "key %d remote ip 0x%x erspan version %d\n";
175 struct bpf_tunnel_key key
;
176 struct erspan_metadata md
;
180 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
), 0);
186 ret
= bpf_skb_get_tunnel_opt(skb
, &md
, sizeof(md
));
192 bpf_trace_printk(fmt
, sizeof(fmt
),
193 key
.tunnel_id
, key
.remote_ipv4
, md
.version
);
196 char fmt2
[] = "\tindex %x\n";
198 index
= bpf_ntohl(md
.u
.index
);
199 bpf_trace_printk(fmt2
, sizeof(fmt2
), index
);
201 char fmt2
[] = "\tdirection %d hwid %x timestamp %u\n";
203 bpf_trace_printk(fmt2
, sizeof(fmt2
),
205 (md
.u
.md2
.hwid_upper
<< 4) + md
.u
.md2
.hwid
,
206 bpf_ntohl(md
.u
.md2
.timestamp
));
212 SEC("ip4ip6erspan_set_tunnel")
213 int _ip4ip6erspan_set_tunnel(struct __sk_buff
*skb
)
215 struct bpf_tunnel_key key
;
216 struct erspan_metadata md
;
219 __builtin_memset(&key
, 0x0, sizeof(key
));
220 key
.remote_ipv6
[3] = bpf_htonl(0x11);
225 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
232 __builtin_memset(&md
, 0, sizeof(md
));
235 md
.u
.index
= bpf_htonl(123);
242 md
.u
.md2
.dir
= direction
;
243 md
.u
.md2
.hwid
= hwid
& 0xf;
244 md
.u
.md2
.hwid_upper
= (hwid
>> 4) & 0x3;
247 ret
= bpf_skb_set_tunnel_opt(skb
, &md
, sizeof(md
));
256 SEC("ip4ip6erspan_get_tunnel")
257 int _ip4ip6erspan_get_tunnel(struct __sk_buff
*skb
)
259 char fmt
[] = "ip6erspan get key %d remote ip6 ::%x erspan version %d\n";
260 struct bpf_tunnel_key key
;
261 struct erspan_metadata md
;
265 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
),
272 ret
= bpf_skb_get_tunnel_opt(skb
, &md
, sizeof(md
));
278 bpf_trace_printk(fmt
, sizeof(fmt
),
279 key
.tunnel_id
, key
.remote_ipv4
, md
.version
);
282 char fmt2
[] = "\tindex %x\n";
284 index
= bpf_ntohl(md
.u
.index
);
285 bpf_trace_printk(fmt2
, sizeof(fmt2
), index
);
287 char fmt2
[] = "\tdirection %d hwid %x timestamp %u\n";
289 bpf_trace_printk(fmt2
, sizeof(fmt2
),
291 (md
.u
.md2
.hwid_upper
<< 4) + md
.u
.md2
.hwid
,
292 bpf_ntohl(md
.u
.md2
.timestamp
));
298 SEC("vxlan_set_tunnel")
299 int _vxlan_set_tunnel(struct __sk_buff
*skb
)
302 struct bpf_tunnel_key key
;
303 struct vxlan_metadata md
;
305 __builtin_memset(&key
, 0x0, sizeof(key
));
306 key
.remote_ipv4
= 0xac100164; /* 172.16.1.100 */
311 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
318 md
.gbp
= 0x800FF; /* Set VXLAN Group Policy extension */
319 ret
= bpf_skb_set_tunnel_opt(skb
, &md
, sizeof(md
));
328 SEC("vxlan_get_tunnel")
329 int _vxlan_get_tunnel(struct __sk_buff
*skb
)
332 struct bpf_tunnel_key key
;
333 struct vxlan_metadata md
;
334 char fmt
[] = "key %d remote ip 0x%x vxlan gbp 0x%x\n";
336 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
), 0);
342 ret
= bpf_skb_get_tunnel_opt(skb
, &md
, sizeof(md
));
348 bpf_trace_printk(fmt
, sizeof(fmt
),
349 key
.tunnel_id
, key
.remote_ipv4
, md
.gbp
);
354 SEC("ip6vxlan_set_tunnel")
355 int _ip6vxlan_set_tunnel(struct __sk_buff
*skb
)
357 struct bpf_tunnel_key key
;
360 __builtin_memset(&key
, 0x0, sizeof(key
));
361 key
.remote_ipv6
[3] = bpf_htonl(0x11); /* ::11 */
366 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
376 SEC("ip6vxlan_get_tunnel")
377 int _ip6vxlan_get_tunnel(struct __sk_buff
*skb
)
379 char fmt
[] = "key %d remote ip6 ::%x label %x\n";
380 struct bpf_tunnel_key key
;
383 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
),
390 bpf_trace_printk(fmt
, sizeof(fmt
),
391 key
.tunnel_id
, key
.remote_ipv6
[3], key
.tunnel_label
);
396 SEC("geneve_set_tunnel")
397 int _geneve_set_tunnel(struct __sk_buff
*skb
)
400 struct bpf_tunnel_key key
;
401 struct geneve_opt gopt
;
403 __builtin_memset(&key
, 0x0, sizeof(key
));
404 key
.remote_ipv4
= 0xac100164; /* 172.16.1.100 */
409 __builtin_memset(&gopt
, 0x0, sizeof(gopt
));
410 gopt
.opt_class
= bpf_htons(0x102); /* Open Virtual Networking (OVN) */
415 gopt
.length
= 2; /* 4-byte multiple */
416 *(int *) &gopt
.opt_data
= bpf_htonl(0xdeadbeef);
418 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
425 ret
= bpf_skb_set_tunnel_opt(skb
, &gopt
, sizeof(gopt
));
434 SEC("geneve_get_tunnel")
435 int _geneve_get_tunnel(struct __sk_buff
*skb
)
438 struct bpf_tunnel_key key
;
439 struct geneve_opt gopt
;
440 char fmt
[] = "key %d remote ip 0x%x geneve class 0x%x\n";
442 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
), 0);
448 ret
= bpf_skb_get_tunnel_opt(skb
, &gopt
, sizeof(gopt
));
454 bpf_trace_printk(fmt
, sizeof(fmt
),
455 key
.tunnel_id
, key
.remote_ipv4
, gopt
.opt_class
);
459 SEC("ip6geneve_set_tunnel")
460 int _ip6geneve_set_tunnel(struct __sk_buff
*skb
)
462 struct bpf_tunnel_key key
;
463 struct geneve_opt gopt
;
466 __builtin_memset(&key
, 0x0, sizeof(key
));
467 key
.remote_ipv6
[3] = bpf_htonl(0x11); /* ::11 */
472 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
479 __builtin_memset(&gopt
, 0x0, sizeof(gopt
));
480 gopt
.opt_class
= bpf_htons(0x102); /* Open Virtual Networking (OVN) */
485 gopt
.length
= 2; /* 4-byte multiple */
486 *(int *) &gopt
.opt_data
= bpf_htonl(0xfeedbeef);
488 ret
= bpf_skb_set_tunnel_opt(skb
, &gopt
, sizeof(gopt
));
497 SEC("ip6geneve_get_tunnel")
498 int _ip6geneve_get_tunnel(struct __sk_buff
*skb
)
500 char fmt
[] = "key %d remote ip 0x%x geneve class 0x%x\n";
501 struct bpf_tunnel_key key
;
502 struct geneve_opt gopt
;
505 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
),
512 ret
= bpf_skb_get_tunnel_opt(skb
, &gopt
, sizeof(gopt
));
518 bpf_trace_printk(fmt
, sizeof(fmt
),
519 key
.tunnel_id
, key
.remote_ipv4
, gopt
.opt_class
);
524 SEC("ipip_set_tunnel")
525 int _ipip_set_tunnel(struct __sk_buff
*skb
)
527 struct bpf_tunnel_key key
= {};
528 void *data
= (void *)(long)skb
->data
;
529 struct iphdr
*iph
= data
;
530 void *data_end
= (void *)(long)skb
->data_end
;
533 /* single length check */
534 if (data
+ sizeof(*iph
) > data_end
) {
540 if (iph
->protocol
== IPPROTO_ICMP
) {
541 key
.remote_ipv4
= 0xac100164; /* 172.16.1.100 */
544 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
), 0);
553 SEC("ipip_get_tunnel")
554 int _ipip_get_tunnel(struct __sk_buff
*skb
)
557 struct bpf_tunnel_key key
;
558 char fmt
[] = "remote ip 0x%x\n";
560 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
), 0);
566 bpf_trace_printk(fmt
, sizeof(fmt
), key
.remote_ipv4
);
570 SEC("ipip6_set_tunnel")
571 int _ipip6_set_tunnel(struct __sk_buff
*skb
)
573 struct bpf_tunnel_key key
= {};
574 void *data
= (void *)(long)skb
->data
;
575 struct iphdr
*iph
= data
;
576 void *data_end
= (void *)(long)skb
->data_end
;
579 /* single length check */
580 if (data
+ sizeof(*iph
) > data_end
) {
585 __builtin_memset(&key
, 0x0, sizeof(key
));
587 if (iph
->protocol
== IPPROTO_ICMP
) {
588 key
.remote_ipv6
[3] = bpf_htonl(0x11); /* ::11 */
591 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
601 SEC("ipip6_get_tunnel")
602 int _ipip6_get_tunnel(struct __sk_buff
*skb
)
605 struct bpf_tunnel_key key
;
606 char fmt
[] = "remote ip6 %x::%x\n";
608 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
),
615 bpf_trace_printk(fmt
, sizeof(fmt
), bpf_htonl(key
.remote_ipv6
[0]),
616 bpf_htonl(key
.remote_ipv6
[3]));
620 SEC("ip6ip6_set_tunnel")
621 int _ip6ip6_set_tunnel(struct __sk_buff
*skb
)
623 struct bpf_tunnel_key key
= {};
624 void *data
= (void *)(long)skb
->data
;
625 struct ipv6hdr
*iph
= data
;
626 void *data_end
= (void *)(long)skb
->data_end
;
629 /* single length check */
630 if (data
+ sizeof(*iph
) > data_end
) {
636 if (iph
->nexthdr
== 58 /* NEXTHDR_ICMP */) {
637 key
.remote_ipv6
[3] = bpf_htonl(0x11); /* ::11 */
640 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
),
650 SEC("ip6ip6_get_tunnel")
651 int _ip6ip6_get_tunnel(struct __sk_buff
*skb
)
654 struct bpf_tunnel_key key
;
655 char fmt
[] = "remote ip6 %x::%x\n";
657 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
),
664 bpf_trace_printk(fmt
, sizeof(fmt
), bpf_htonl(key
.remote_ipv6
[0]),
665 bpf_htonl(key
.remote_ipv6
[3]));
669 SEC("xfrm_get_state")
670 int _xfrm_get_state(struct __sk_buff
*skb
)
672 struct bpf_xfrm_state x
;
673 char fmt
[] = "reqid %d spi 0x%x remote ip 0x%x\n";
676 ret
= bpf_skb_get_xfrm_state(skb
, 0, &x
, sizeof(x
), 0);
680 bpf_trace_printk(fmt
, sizeof(fmt
), x
.reqid
, bpf_ntohl(x
.spi
),
681 bpf_ntohl(x
.remote_ipv4
));
685 char _license
[] SEC("license") = "GPL";