xref: /linux/tools/testing/selftests/bpf/progs/test_tunnel_kern.c (revision b2128290c29902315e632ea59e0504d6bc9e9b42)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2016 VMware
3  * Copyright (c) 2016 Facebook
4  *
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.
8  */
9 #define BPF_NO_KFUNC_PROTOTYPES
10 #include "vmlinux.h"
11 #include <bpf/bpf_core_read.h>
12 #include <bpf/bpf_helpers.h>
13 #include <bpf/bpf_endian.h>
14 #include "bpf_kfuncs.h"
15 #include "bpf_tracing_net.h"
16 
17 #define log_err(__ret) bpf_printk("ERROR line:%d ret:%d\n", __LINE__, __ret)
18 
19 #define VXLAN_UDP_PORT		4789
20 #define ETH_P_IP		0x0800
21 #define PACKET_HOST		0
22 #define TUNNEL_CSUM		bpf_htons(0x01)
23 #define TUNNEL_KEY		bpf_htons(0x04)
24 
25 /* Only IPv4 address assigned to veth1.
26  * 172.16.1.200
27  */
28 #define ASSIGNED_ADDR_VETH1 0xac1001c8
29 
30 struct bpf_fou_encap___local {
31 	__be16 sport;
32 	__be16 dport;
33 } __attribute__((preserve_access_index));
34 
35 enum bpf_fou_encap_type___local {
36 	FOU_BPF_ENCAP_FOU___local,
37 	FOU_BPF_ENCAP_GUE___local,
38 };
39 
40 int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx,
41 			  struct bpf_fou_encap___local *encap, int type) __ksym;
42 int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx,
43 			  struct bpf_fou_encap___local *encap) __ksym;
44 struct xfrm_state *
45 bpf_xdp_get_xfrm_state(struct xdp_md *ctx, struct bpf_xfrm_state_opts *opts,
46 		       u32 opts__sz) __ksym;
47 void bpf_xdp_xfrm_state_release(struct xfrm_state *x) __ksym;
48 
49 struct {
50 	__uint(type, BPF_MAP_TYPE_ARRAY);
51 	__uint(max_entries, 1);
52 	__type(key, __u32);
53 	__type(value, __u32);
54 } local_ip_map SEC(".maps");
55 
56 SEC("tc")
57 int gre_set_tunnel(struct __sk_buff *skb)
58 {
59 	int ret;
60 	struct bpf_tunnel_key key;
61 
62 	__builtin_memset(&key, 0x0, sizeof(key));
63 	key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
64 	key.tunnel_id = 2;
65 	key.tunnel_tos = 0;
66 	key.tunnel_ttl = 64;
67 
68 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
69 				     BPF_F_ZERO_CSUM_TX | BPF_F_SEQ_NUMBER);
70 	if (ret < 0) {
71 		log_err(ret);
72 		return TC_ACT_SHOT;
73 	}
74 
75 	return TC_ACT_OK;
76 }
77 
78 SEC("tc")
79 int gre_set_tunnel_no_key(struct __sk_buff *skb)
80 {
81 	int ret;
82 	struct bpf_tunnel_key key;
83 
84 	__builtin_memset(&key, 0x0, sizeof(key));
85 	key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
86 	key.tunnel_ttl = 64;
87 
88 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
89 				     BPF_F_ZERO_CSUM_TX | BPF_F_SEQ_NUMBER |
90 				     BPF_F_NO_TUNNEL_KEY);
91 	if (ret < 0) {
92 		log_err(ret);
93 		return TC_ACT_SHOT;
94 	}
95 
96 	return TC_ACT_OK;
97 }
98 
99 SEC("tc")
100 int gre_get_tunnel(struct __sk_buff *skb)
101 {
102 	int ret;
103 	struct bpf_tunnel_key key;
104 
105 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
106 	if (ret < 0) {
107 		log_err(ret);
108 		return TC_ACT_SHOT;
109 	}
110 
111 	bpf_printk("key %d remote ip 0x%x\n", key.tunnel_id, key.remote_ipv4);
112 	return TC_ACT_OK;
113 }
114 
115 SEC("tc")
116 int ip6gretap_set_tunnel(struct __sk_buff *skb)
117 {
118 	struct bpf_tunnel_key key;
119 	int ret;
120 
121 	__builtin_memset(&key, 0x0, sizeof(key));
122 	key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
123 	key.tunnel_id = 2;
124 	key.tunnel_tos = 0;
125 	key.tunnel_ttl = 64;
126 	key.tunnel_label = 0xabcde;
127 
128 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
129 				     BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX |
130 				     BPF_F_SEQ_NUMBER);
131 	if (ret < 0) {
132 		log_err(ret);
133 		return TC_ACT_SHOT;
134 	}
135 
136 	return TC_ACT_OK;
137 }
138 
139 SEC("tc")
140 int ip6gretap_get_tunnel(struct __sk_buff *skb)
141 {
142 	struct bpf_tunnel_key key;
143 	int ret;
144 
145 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
146 				     BPF_F_TUNINFO_IPV6);
147 	if (ret < 0) {
148 		log_err(ret);
149 		return TC_ACT_SHOT;
150 	}
151 
152 	bpf_printk("key %d remote ip6 ::%x label %x\n",
153 		   key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
154 
155 	return TC_ACT_OK;
156 }
157 
158 SEC("tc")
159 int erspan_set_tunnel(struct __sk_buff *skb)
160 {
161 	struct bpf_tunnel_key key;
162 	struct erspan_metadata md;
163 	int ret;
164 
165 	__builtin_memset(&key, 0x0, sizeof(key));
166 	key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
167 	key.tunnel_id = 2;
168 	key.tunnel_tos = 0;
169 	key.tunnel_ttl = 64;
170 
171 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
172 				     BPF_F_ZERO_CSUM_TX);
173 	if (ret < 0) {
174 		log_err(ret);
175 		return TC_ACT_SHOT;
176 	}
177 
178 	__builtin_memset(&md, 0, sizeof(md));
179 #ifdef ERSPAN_V1
180 	md.version = 1;
181 	md.u.index = bpf_htonl(123);
182 #else
183 	__u8 direction = 1;
184 	__u8 hwid = 7;
185 
186 	md.version = 2;
187 	BPF_CORE_WRITE_BITFIELD(&md.u.md2, dir, direction);
188 	BPF_CORE_WRITE_BITFIELD(&md.u.md2, hwid, (hwid & 0xf));
189 	BPF_CORE_WRITE_BITFIELD(&md.u.md2, hwid_upper, (hwid >> 4) & 0x3);
190 #endif
191 
192 	ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
193 	if (ret < 0) {
194 		log_err(ret);
195 		return TC_ACT_SHOT;
196 	}
197 
198 	return TC_ACT_OK;
199 }
200 
201 SEC("tc")
202 int erspan_get_tunnel(struct __sk_buff *skb)
203 {
204 	struct bpf_tunnel_key key;
205 	struct erspan_metadata md;
206 	int ret;
207 
208 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
209 	if (ret < 0) {
210 		log_err(ret);
211 		return TC_ACT_SHOT;
212 	}
213 
214 	ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
215 	if (ret < 0) {
216 		log_err(ret);
217 		return TC_ACT_SHOT;
218 	}
219 
220 	bpf_printk("key %d remote ip 0x%x erspan version %d\n",
221 		   key.tunnel_id, key.remote_ipv4, md.version);
222 
223 #ifdef ERSPAN_V1
224 	index = bpf_ntohl(md.u.index);
225 	bpf_printk("\tindex %x\n", index);
226 #else
227 	bpf_printk("\tdirection %d hwid %x timestamp %u\n",
228 		   BPF_CORE_READ_BITFIELD(&md.u.md2, dir),
229 		   (BPF_CORE_READ_BITFIELD(&md.u.md2, hwid_upper) << 4) +
230 		   BPF_CORE_READ_BITFIELD(&md.u.md2, hwid),
231 		   bpf_ntohl(md.u.md2.timestamp));
232 #endif
233 
234 	return TC_ACT_OK;
235 }
236 
237 SEC("tc")
238 int ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
239 {
240 	struct bpf_tunnel_key key;
241 	struct erspan_metadata md;
242 	int ret;
243 
244 	__builtin_memset(&key, 0x0, sizeof(key));
245 	key.remote_ipv6[3] = bpf_htonl(0x11);
246 	key.tunnel_id = 2;
247 	key.tunnel_tos = 0;
248 	key.tunnel_ttl = 64;
249 
250 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
251 				     BPF_F_TUNINFO_IPV6);
252 	if (ret < 0) {
253 		log_err(ret);
254 		return TC_ACT_SHOT;
255 	}
256 
257 	__builtin_memset(&md, 0, sizeof(md));
258 
259 #ifdef ERSPAN_V1
260 	md.u.index = bpf_htonl(123);
261 	md.version = 1;
262 #else
263 	__u8 direction = 0;
264 	__u8 hwid = 17;
265 
266 	md.version = 2;
267 	BPF_CORE_WRITE_BITFIELD(&md.u.md2, dir, direction);
268 	BPF_CORE_WRITE_BITFIELD(&md.u.md2, hwid, (hwid & 0xf));
269 	BPF_CORE_WRITE_BITFIELD(&md.u.md2, hwid_upper, (hwid >> 4) & 0x3);
270 #endif
271 
272 	ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
273 	if (ret < 0) {
274 		log_err(ret);
275 		return TC_ACT_SHOT;
276 	}
277 
278 	return TC_ACT_OK;
279 }
280 
281 SEC("tc")
282 int ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
283 {
284 	struct bpf_tunnel_key key;
285 	struct erspan_metadata md;
286 	int ret;
287 
288 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
289 				     BPF_F_TUNINFO_IPV6);
290 	if (ret < 0) {
291 		log_err(ret);
292 		return TC_ACT_SHOT;
293 	}
294 
295 	ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
296 	if (ret < 0) {
297 		log_err(ret);
298 		return TC_ACT_SHOT;
299 	}
300 
301 	bpf_printk("ip6erspan get key %d remote ip6 ::%x erspan version %d\n",
302 		   key.tunnel_id, key.remote_ipv4, md.version);
303 
304 #ifdef ERSPAN_V1
305 	index = bpf_ntohl(md.u.index);
306 	bpf_printk("\tindex %x\n", index);
307 #else
308 	bpf_printk("\tdirection %d hwid %x timestamp %u\n",
309 		   BPF_CORE_READ_BITFIELD(&md.u.md2, dir),
310 		   (BPF_CORE_READ_BITFIELD(&md.u.md2, hwid_upper) << 4) +
311 		   BPF_CORE_READ_BITFIELD(&md.u.md2, hwid),
312 		   bpf_ntohl(md.u.md2.timestamp));
313 #endif
314 
315 	return TC_ACT_OK;
316 }
317 
318 SEC("tc")
319 int vxlan_set_tunnel_dst(struct __sk_buff *skb)
320 {
321 	struct bpf_tunnel_key key;
322 	struct vxlan_metadata md;
323 	__u32 index = 0;
324 	__u32 *local_ip = NULL;
325 	int ret = 0;
326 
327 	local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
328 	if (!local_ip) {
329 		log_err(ret);
330 		return TC_ACT_SHOT;
331 	}
332 
333 	__builtin_memset(&key, 0x0, sizeof(key));
334 	key.local_ipv4 = 0xac100164; /* 172.16.1.100 */
335 	key.remote_ipv4 = *local_ip;
336 	key.tunnel_id = 2;
337 	key.tunnel_tos = 0;
338 	key.tunnel_ttl = 64;
339 
340 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
341 				     BPF_F_ZERO_CSUM_TX);
342 	if (ret < 0) {
343 		log_err(ret);
344 		return TC_ACT_SHOT;
345 	}
346 
347 	md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
348 	ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
349 	if (ret < 0) {
350 		log_err(ret);
351 		return TC_ACT_SHOT;
352 	}
353 
354 	return TC_ACT_OK;
355 }
356 
357 SEC("tc")
358 int vxlan_set_tunnel_src(struct __sk_buff *skb)
359 {
360 	struct bpf_tunnel_key key;
361 	struct vxlan_metadata md;
362 	__u32 index = 0;
363 	__u32 *local_ip = NULL;
364 	int ret = 0;
365 
366 	local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
367 	if (!local_ip) {
368 		log_err(ret);
369 		return TC_ACT_SHOT;
370 	}
371 
372 	__builtin_memset(&key, 0x0, sizeof(key));
373 	key.local_ipv4 = *local_ip;
374 	key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
375 	key.tunnel_id = 2;
376 	key.tunnel_tos = 0;
377 	key.tunnel_ttl = 64;
378 
379 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
380 				     BPF_F_ZERO_CSUM_TX);
381 	if (ret < 0) {
382 		log_err(ret);
383 		return TC_ACT_SHOT;
384 	}
385 
386 	md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
387 	ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
388 	if (ret < 0) {
389 		log_err(ret);
390 		return TC_ACT_SHOT;
391 	}
392 
393 	return TC_ACT_OK;
394 }
395 
396 SEC("tc")
397 int vxlan_get_tunnel_src(struct __sk_buff *skb)
398 {
399 	int ret;
400 	struct bpf_tunnel_key key;
401 	struct vxlan_metadata md;
402 
403 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
404 				     BPF_F_TUNINFO_FLAGS);
405 	if (ret < 0) {
406 		log_err(ret);
407 		return TC_ACT_SHOT;
408 	}
409 
410 	ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
411 	if (ret < 0) {
412 		log_err(ret);
413 		return TC_ACT_SHOT;
414 	}
415 
416 	if (key.local_ipv4 != ASSIGNED_ADDR_VETH1 || md.gbp != 0x800FF ||
417 	    !(key.tunnel_flags & TUNNEL_KEY) ||
418 	    (key.tunnel_flags & TUNNEL_CSUM)) {
419 		bpf_printk("vxlan key %d local ip 0x%x remote ip 0x%x gbp 0x%x flags 0x%x\n",
420 			   key.tunnel_id, key.local_ipv4,
421 			   key.remote_ipv4, md.gbp,
422 			   bpf_ntohs(key.tunnel_flags));
423 		log_err(ret);
424 		return TC_ACT_SHOT;
425 	}
426 
427 	return TC_ACT_OK;
428 }
429 
430 SEC("tc")
431 int veth_set_outer_dst(struct __sk_buff *skb)
432 {
433 	struct ethhdr *eth = (struct ethhdr *)(long)skb->data;
434 	__u32 assigned_ip = bpf_htonl(ASSIGNED_ADDR_VETH1);
435 	void *data_end = (void *)(long)skb->data_end;
436 	struct udphdr *udph;
437 	struct iphdr *iph;
438 	int ret = 0;
439 	__s64 csum;
440 
441 	if ((void *)eth + sizeof(*eth) > data_end) {
442 		log_err(ret);
443 		return TC_ACT_SHOT;
444 	}
445 
446 	if (eth->h_proto != bpf_htons(ETH_P_IP))
447 		return TC_ACT_OK;
448 
449 	iph = (struct iphdr *)(eth + 1);
450 	if ((void *)iph + sizeof(*iph) > data_end) {
451 		log_err(ret);
452 		return TC_ACT_SHOT;
453 	}
454 	if (iph->protocol != IPPROTO_UDP)
455 		return TC_ACT_OK;
456 
457 	udph = (struct udphdr *)(iph + 1);
458 	if ((void *)udph + sizeof(*udph) > data_end) {
459 		log_err(ret);
460 		return TC_ACT_SHOT;
461 	}
462 	if (udph->dest != bpf_htons(VXLAN_UDP_PORT))
463 		return TC_ACT_OK;
464 
465 	if (iph->daddr != assigned_ip) {
466 		csum = bpf_csum_diff(&iph->daddr, sizeof(__u32), &assigned_ip,
467 				     sizeof(__u32), 0);
468 		if (bpf_skb_store_bytes(skb, ETH_HLEN + offsetof(struct iphdr, daddr),
469 					&assigned_ip, sizeof(__u32), 0) < 0) {
470 			log_err(ret);
471 			return TC_ACT_SHOT;
472 		}
473 		if (bpf_l3_csum_replace(skb, ETH_HLEN + offsetof(struct iphdr, check),
474 					0, csum, 0) < 0) {
475 			log_err(ret);
476 			return TC_ACT_SHOT;
477 		}
478 		bpf_skb_change_type(skb, PACKET_HOST);
479 	}
480 	return TC_ACT_OK;
481 }
482 
483 SEC("tc")
484 int ip6vxlan_set_tunnel_dst(struct __sk_buff *skb)
485 {
486 	struct bpf_tunnel_key key;
487 	__u32 index = 0;
488 	__u32 *local_ip;
489 	int ret = 0;
490 
491 	local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
492 	if (!local_ip) {
493 		log_err(ret);
494 		return TC_ACT_SHOT;
495 	}
496 
497 	__builtin_memset(&key, 0x0, sizeof(key));
498 	key.local_ipv6[3] = bpf_htonl(0x11); /* ::11 */
499 	key.remote_ipv6[3] = bpf_htonl(*local_ip);
500 	key.tunnel_id = 22;
501 	key.tunnel_tos = 0;
502 	key.tunnel_ttl = 64;
503 
504 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
505 				     BPF_F_TUNINFO_IPV6);
506 	if (ret < 0) {
507 		log_err(ret);
508 		return TC_ACT_SHOT;
509 	}
510 
511 	return TC_ACT_OK;
512 }
513 
514 SEC("tc")
515 int ip6vxlan_set_tunnel_src(struct __sk_buff *skb)
516 {
517 	struct bpf_tunnel_key key;
518 	__u32 index = 0;
519 	__u32 *local_ip;
520 	int ret = 0;
521 
522 	local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
523 	if (!local_ip) {
524 		log_err(ret);
525 		return TC_ACT_SHOT;
526 	}
527 
528 	__builtin_memset(&key, 0x0, sizeof(key));
529 	key.local_ipv6[3] = bpf_htonl(*local_ip);
530 	key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
531 	key.tunnel_id = 22;
532 	key.tunnel_tos = 0;
533 	key.tunnel_ttl = 64;
534 
535 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
536 				     BPF_F_TUNINFO_IPV6);
537 	if (ret < 0) {
538 		log_err(ret);
539 		return TC_ACT_SHOT;
540 	}
541 
542 	return TC_ACT_OK;
543 }
544 
545 SEC("tc")
546 int ip6vxlan_get_tunnel_src(struct __sk_buff *skb)
547 {
548 	struct bpf_tunnel_key key;
549 	__u32 index = 0;
550 	__u32 *local_ip;
551 	int ret = 0;
552 
553 	local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
554 	if (!local_ip) {
555 		log_err(ret);
556 		return TC_ACT_SHOT;
557 	}
558 
559 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
560 				     BPF_F_TUNINFO_IPV6 | BPF_F_TUNINFO_FLAGS);
561 	if (ret < 0) {
562 		log_err(ret);
563 		return TC_ACT_SHOT;
564 	}
565 
566 	if (bpf_ntohl(key.local_ipv6[3]) != *local_ip ||
567 	    !(key.tunnel_flags & TUNNEL_KEY) ||
568 	    !(key.tunnel_flags & TUNNEL_CSUM)) {
569 		bpf_printk("ip6vxlan key %d local ip6 ::%x remote ip6 ::%x label 0x%x flags 0x%x\n",
570 			   key.tunnel_id, bpf_ntohl(key.local_ipv6[3]),
571 			   bpf_ntohl(key.remote_ipv6[3]), key.tunnel_label,
572 			   bpf_ntohs(key.tunnel_flags));
573 		bpf_printk("local_ip 0x%x\n", *local_ip);
574 		log_err(ret);
575 		return TC_ACT_SHOT;
576 	}
577 
578 	return TC_ACT_OK;
579 }
580 
581 struct local_geneve_opt {
582 	struct geneve_opt gopt;
583 	int data;
584 };
585 
586 SEC("tc")
587 int geneve_set_tunnel(struct __sk_buff *skb)
588 {
589 	int ret;
590 	struct bpf_tunnel_key key;
591 	struct local_geneve_opt local_gopt;
592 	struct geneve_opt *gopt = (struct geneve_opt *) &local_gopt;
593 
594 	__builtin_memset(&key, 0x0, sizeof(key));
595 	key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
596 	key.tunnel_id = 2;
597 	key.tunnel_tos = 0;
598 	key.tunnel_ttl = 64;
599 
600 	__builtin_memset(gopt, 0x0, sizeof(local_gopt));
601 	gopt->opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
602 	gopt->type = 0x08;
603 	gopt->r1 = 0;
604 	gopt->r2 = 0;
605 	gopt->r3 = 0;
606 	gopt->length = 2; /* 4-byte multiple */
607 	*(int *) &gopt->opt_data = bpf_htonl(0xdeadbeef);
608 
609 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
610 				     BPF_F_ZERO_CSUM_TX);
611 	if (ret < 0) {
612 		log_err(ret);
613 		return TC_ACT_SHOT;
614 	}
615 
616 	ret = bpf_skb_set_tunnel_opt(skb, gopt, sizeof(local_gopt));
617 	if (ret < 0) {
618 		log_err(ret);
619 		return TC_ACT_SHOT;
620 	}
621 
622 	return TC_ACT_OK;
623 }
624 
625 SEC("tc")
626 int geneve_get_tunnel(struct __sk_buff *skb)
627 {
628 	int ret;
629 	struct bpf_tunnel_key key;
630 	struct geneve_opt gopt;
631 
632 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
633 	if (ret < 0) {
634 		log_err(ret);
635 		return TC_ACT_SHOT;
636 	}
637 
638 	ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
639 	if (ret < 0)
640 		gopt.opt_class = 0;
641 
642 	bpf_printk("key %d remote ip 0x%x geneve class 0x%x\n",
643 		   key.tunnel_id, key.remote_ipv4, gopt.opt_class);
644 	return TC_ACT_OK;
645 }
646 
647 SEC("tc")
648 int ip6geneve_set_tunnel(struct __sk_buff *skb)
649 {
650 	struct bpf_tunnel_key key;
651 	struct local_geneve_opt local_gopt;
652 	struct geneve_opt *gopt = (struct geneve_opt *) &local_gopt;
653 	int ret;
654 
655 	__builtin_memset(&key, 0x0, sizeof(key));
656 	key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
657 	key.tunnel_id = 22;
658 	key.tunnel_tos = 0;
659 	key.tunnel_ttl = 64;
660 
661 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
662 				     BPF_F_TUNINFO_IPV6);
663 	if (ret < 0) {
664 		log_err(ret);
665 		return TC_ACT_SHOT;
666 	}
667 
668 	__builtin_memset(gopt, 0x0, sizeof(local_gopt));
669 	gopt->opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
670 	gopt->type = 0x08;
671 	gopt->r1 = 0;
672 	gopt->r2 = 0;
673 	gopt->r3 = 0;
674 	gopt->length = 2; /* 4-byte multiple */
675 	*(int *) &gopt->opt_data = bpf_htonl(0xfeedbeef);
676 
677 	ret = bpf_skb_set_tunnel_opt(skb, gopt, sizeof(gopt));
678 	if (ret < 0) {
679 		log_err(ret);
680 		return TC_ACT_SHOT;
681 	}
682 
683 	return TC_ACT_OK;
684 }
685 
686 SEC("tc")
687 int ip6geneve_get_tunnel(struct __sk_buff *skb)
688 {
689 	struct bpf_tunnel_key key;
690 	struct geneve_opt gopt;
691 	int ret;
692 
693 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
694 				     BPF_F_TUNINFO_IPV6);
695 	if (ret < 0) {
696 		log_err(ret);
697 		return TC_ACT_SHOT;
698 	}
699 
700 	ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
701 	if (ret < 0)
702 		gopt.opt_class = 0;
703 
704 	bpf_printk("key %d remote ip 0x%x geneve class 0x%x\n",
705 		   key.tunnel_id, key.remote_ipv4, gopt.opt_class);
706 
707 	return TC_ACT_OK;
708 }
709 
710 SEC("tc")
711 int ipip_set_tunnel(struct __sk_buff *skb)
712 {
713 	struct bpf_tunnel_key key = {};
714 	void *data = (void *)(long)skb->data;
715 	struct iphdr *iph = data;
716 	void *data_end = (void *)(long)skb->data_end;
717 	int ret;
718 
719 	/* single length check */
720 	if (data + sizeof(*iph) > data_end) {
721 		log_err(1);
722 		return TC_ACT_SHOT;
723 	}
724 
725 	key.tunnel_ttl = 64;
726 	if (iph->protocol == IPPROTO_ICMP) {
727 		key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
728 	}
729 
730 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
731 	if (ret < 0) {
732 		log_err(ret);
733 		return TC_ACT_SHOT;
734 	}
735 
736 	return TC_ACT_OK;
737 }
738 
739 SEC("tc")
740 int ipip_get_tunnel(struct __sk_buff *skb)
741 {
742 	int ret;
743 	struct bpf_tunnel_key key;
744 
745 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
746 	if (ret < 0) {
747 		log_err(ret);
748 		return TC_ACT_SHOT;
749 	}
750 
751 	bpf_printk("remote ip 0x%x\n", key.remote_ipv4);
752 	return TC_ACT_OK;
753 }
754 
755 SEC("tc")
756 int ipip_gue_set_tunnel(struct __sk_buff *skb)
757 {
758 	struct bpf_tunnel_key key = {};
759 	struct bpf_fou_encap___local encap = {};
760 	void *data = (void *)(long)skb->data;
761 	struct iphdr *iph = data;
762 	void *data_end = (void *)(long)skb->data_end;
763 	int ret;
764 
765 	if (data + sizeof(*iph) > data_end) {
766 		log_err(1);
767 		return TC_ACT_SHOT;
768 	}
769 
770 	key.tunnel_ttl = 64;
771 	if (iph->protocol == IPPROTO_ICMP)
772 		key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
773 
774 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
775 	if (ret < 0) {
776 		log_err(ret);
777 		return TC_ACT_SHOT;
778 	}
779 
780 	encap.sport = 0;
781 	encap.dport = bpf_htons(5555);
782 
783 	ret = bpf_skb_set_fou_encap(skb, &encap,
784 				    bpf_core_enum_value(enum bpf_fou_encap_type___local,
785 							FOU_BPF_ENCAP_GUE___local));
786 	if (ret < 0) {
787 		log_err(ret);
788 		return TC_ACT_SHOT;
789 	}
790 
791 	return TC_ACT_OK;
792 }
793 
794 SEC("tc")
795 int ipip_fou_set_tunnel(struct __sk_buff *skb)
796 {
797 	struct bpf_tunnel_key key = {};
798 	struct bpf_fou_encap___local encap = {};
799 	void *data = (void *)(long)skb->data;
800 	struct iphdr *iph = data;
801 	void *data_end = (void *)(long)skb->data_end;
802 	int ret;
803 
804 	if (data + sizeof(*iph) > data_end) {
805 		log_err(1);
806 		return TC_ACT_SHOT;
807 	}
808 
809 	key.tunnel_ttl = 64;
810 	if (iph->protocol == IPPROTO_ICMP)
811 		key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
812 
813 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
814 	if (ret < 0) {
815 		log_err(ret);
816 		return TC_ACT_SHOT;
817 	}
818 
819 	encap.sport = 0;
820 	encap.dport = bpf_htons(5555);
821 
822 	ret = bpf_skb_set_fou_encap(skb, &encap,
823 				    FOU_BPF_ENCAP_FOU___local);
824 	if (ret < 0) {
825 		log_err(ret);
826 		return TC_ACT_SHOT;
827 	}
828 
829 	return TC_ACT_OK;
830 }
831 
832 SEC("tc")
833 int ipip_encap_get_tunnel(struct __sk_buff *skb)
834 {
835 	int ret;
836 	struct bpf_tunnel_key key = {};
837 	struct bpf_fou_encap___local encap = {};
838 
839 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
840 	if (ret < 0) {
841 		log_err(ret);
842 		return TC_ACT_SHOT;
843 	}
844 
845 	ret = bpf_skb_get_fou_encap(skb, &encap);
846 	if (ret < 0) {
847 		log_err(ret);
848 		return TC_ACT_SHOT;
849 	}
850 
851 	if (bpf_ntohs(encap.dport) != 5555)
852 		return TC_ACT_SHOT;
853 
854 	bpf_printk("%d remote ip 0x%x, sport %d, dport %d\n", ret,
855 		   key.remote_ipv4, bpf_ntohs(encap.sport),
856 		   bpf_ntohs(encap.dport));
857 	return TC_ACT_OK;
858 }
859 
860 SEC("tc")
861 int ipip6_set_tunnel(struct __sk_buff *skb)
862 {
863 	struct bpf_tunnel_key key = {};
864 	void *data = (void *)(long)skb->data;
865 	struct iphdr *iph = data;
866 	void *data_end = (void *)(long)skb->data_end;
867 	int ret;
868 
869 	/* single length check */
870 	if (data + sizeof(*iph) > data_end) {
871 		log_err(1);
872 		return TC_ACT_SHOT;
873 	}
874 
875 	__builtin_memset(&key, 0x0, sizeof(key));
876 	key.tunnel_ttl = 64;
877 	if (iph->protocol == IPPROTO_ICMP) {
878 		key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
879 	}
880 
881 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
882 				     BPF_F_TUNINFO_IPV6);
883 	if (ret < 0) {
884 		log_err(ret);
885 		return TC_ACT_SHOT;
886 	}
887 
888 	return TC_ACT_OK;
889 }
890 
891 SEC("tc")
892 int ipip6_get_tunnel(struct __sk_buff *skb)
893 {
894 	int ret;
895 	struct bpf_tunnel_key key;
896 
897 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
898 				     BPF_F_TUNINFO_IPV6);
899 	if (ret < 0) {
900 		log_err(ret);
901 		return TC_ACT_SHOT;
902 	}
903 
904 	bpf_printk("remote ip6 %x::%x\n", bpf_htonl(key.remote_ipv6[0]),
905 		   bpf_htonl(key.remote_ipv6[3]));
906 	return TC_ACT_OK;
907 }
908 
909 SEC("tc")
910 int ip6ip6_set_tunnel(struct __sk_buff *skb)
911 {
912 	struct bpf_tunnel_key key = {};
913 	void *data = (void *)(long)skb->data;
914 	struct ipv6hdr *iph = data;
915 	void *data_end = (void *)(long)skb->data_end;
916 	int ret;
917 
918 	/* single length check */
919 	if (data + sizeof(*iph) > data_end) {
920 		log_err(1);
921 		return TC_ACT_SHOT;
922 	}
923 
924 	key.tunnel_ttl = 64;
925 	if (iph->nexthdr == 58 /* NEXTHDR_ICMP */) {
926 		key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
927 	}
928 
929 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
930 				     BPF_F_TUNINFO_IPV6);
931 	if (ret < 0) {
932 		log_err(ret);
933 		return TC_ACT_SHOT;
934 	}
935 
936 	return TC_ACT_OK;
937 }
938 
939 SEC("tc")
940 int ip6ip6_get_tunnel(struct __sk_buff *skb)
941 {
942 	int ret;
943 	struct bpf_tunnel_key key;
944 
945 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
946 				     BPF_F_TUNINFO_IPV6);
947 	if (ret < 0) {
948 		log_err(ret);
949 		return TC_ACT_SHOT;
950 	}
951 
952 	bpf_printk("remote ip6 %x::%x\n", bpf_htonl(key.remote_ipv6[0]),
953 		   bpf_htonl(key.remote_ipv6[3]));
954 	return TC_ACT_OK;
955 }
956 
957 volatile int xfrm_reqid = 0;
958 volatile int xfrm_spi = 0;
959 volatile int xfrm_remote_ip = 0;
960 
961 SEC("tc")
962 int xfrm_get_state(struct __sk_buff *skb)
963 {
964 	struct bpf_xfrm_state x;
965 	int ret;
966 
967 	ret = bpf_skb_get_xfrm_state(skb, 0, &x, sizeof(x), 0);
968 	if (ret < 0)
969 		return TC_ACT_OK;
970 
971 	xfrm_reqid = x.reqid;
972 	xfrm_spi = bpf_ntohl(x.spi);
973 	xfrm_remote_ip = bpf_ntohl(x.remote_ipv4);
974 
975 	return TC_ACT_OK;
976 }
977 
978 volatile int xfrm_replay_window = 0;
979 
980 SEC("xdp")
981 int xfrm_get_state_xdp(struct xdp_md *xdp)
982 {
983 	struct bpf_xfrm_state_opts opts = {};
984 	struct xfrm_state *x = NULL;
985 	struct ip_esp_hdr *esph;
986 	struct bpf_dynptr ptr;
987 	u8 esph_buf[8] = {};
988 	u8 iph_buf[20] = {};
989 	struct iphdr *iph;
990 	u32 off;
991 
992 	if (bpf_dynptr_from_xdp(xdp, 0, &ptr))
993 		goto out;
994 
995 	off = sizeof(struct ethhdr);
996 	iph = bpf_dynptr_slice(&ptr, off, iph_buf, sizeof(iph_buf));
997 	if (!iph || iph->protocol != IPPROTO_ESP)
998 		goto out;
999 
1000 	off += sizeof(struct iphdr);
1001 	esph = bpf_dynptr_slice(&ptr, off, esph_buf, sizeof(esph_buf));
1002 	if (!esph)
1003 		goto out;
1004 
1005 	opts.netns_id = BPF_F_CURRENT_NETNS;
1006 	opts.daddr.a4 = iph->daddr;
1007 	opts.spi = esph->spi;
1008 	opts.proto = IPPROTO_ESP;
1009 	opts.family = AF_INET;
1010 
1011 	x = bpf_xdp_get_xfrm_state(xdp, &opts, sizeof(opts));
1012 	if (!x)
1013 		goto out;
1014 
1015 	if (!x->replay_esn)
1016 		goto out;
1017 
1018 	xfrm_replay_window = x->replay_esn->replay_window;
1019 out:
1020 	if (x)
1021 		bpf_xdp_xfrm_state_release(x);
1022 	return XDP_PASS;
1023 }
1024 
1025 char _license[] SEC("license") = "GPL";
1026