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