xref: /linux/tools/testing/selftests/bpf/progs/test_tunnel_kern.c (revision ae22a94997b8a03dcb3c922857c203246711f9d4)
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 SEC("tc")
571 int geneve_set_tunnel(struct __sk_buff *skb)
572 {
573 	int ret;
574 	struct bpf_tunnel_key key;
575 	struct geneve_opt gopt;
576 
577 	__builtin_memset(&key, 0x0, sizeof(key));
578 	key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
579 	key.tunnel_id = 2;
580 	key.tunnel_tos = 0;
581 	key.tunnel_ttl = 64;
582 
583 	__builtin_memset(&gopt, 0x0, sizeof(gopt));
584 	gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
585 	gopt.type = 0x08;
586 	gopt.r1 = 0;
587 	gopt.r2 = 0;
588 	gopt.r3 = 0;
589 	gopt.length = 2; /* 4-byte multiple */
590 	*(int *) &gopt.opt_data = bpf_htonl(0xdeadbeef);
591 
592 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
593 				     BPF_F_ZERO_CSUM_TX);
594 	if (ret < 0) {
595 		log_err(ret);
596 		return TC_ACT_SHOT;
597 	}
598 
599 	ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
600 	if (ret < 0) {
601 		log_err(ret);
602 		return TC_ACT_SHOT;
603 	}
604 
605 	return TC_ACT_OK;
606 }
607 
608 SEC("tc")
609 int geneve_get_tunnel(struct __sk_buff *skb)
610 {
611 	int ret;
612 	struct bpf_tunnel_key key;
613 	struct geneve_opt gopt;
614 
615 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
616 	if (ret < 0) {
617 		log_err(ret);
618 		return TC_ACT_SHOT;
619 	}
620 
621 	ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
622 	if (ret < 0)
623 		gopt.opt_class = 0;
624 
625 	bpf_printk("key %d remote ip 0x%x geneve class 0x%x\n",
626 		   key.tunnel_id, key.remote_ipv4, gopt.opt_class);
627 	return TC_ACT_OK;
628 }
629 
630 SEC("tc")
631 int ip6geneve_set_tunnel(struct __sk_buff *skb)
632 {
633 	struct bpf_tunnel_key key;
634 	struct geneve_opt gopt;
635 	int ret;
636 
637 	__builtin_memset(&key, 0x0, sizeof(key));
638 	key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
639 	key.tunnel_id = 22;
640 	key.tunnel_tos = 0;
641 	key.tunnel_ttl = 64;
642 
643 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
644 				     BPF_F_TUNINFO_IPV6);
645 	if (ret < 0) {
646 		log_err(ret);
647 		return TC_ACT_SHOT;
648 	}
649 
650 	__builtin_memset(&gopt, 0x0, sizeof(gopt));
651 	gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
652 	gopt.type = 0x08;
653 	gopt.r1 = 0;
654 	gopt.r2 = 0;
655 	gopt.r3 = 0;
656 	gopt.length = 2; /* 4-byte multiple */
657 	*(int *) &gopt.opt_data = bpf_htonl(0xfeedbeef);
658 
659 	ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
660 	if (ret < 0) {
661 		log_err(ret);
662 		return TC_ACT_SHOT;
663 	}
664 
665 	return TC_ACT_OK;
666 }
667 
668 SEC("tc")
669 int ip6geneve_get_tunnel(struct __sk_buff *skb)
670 {
671 	struct bpf_tunnel_key key;
672 	struct geneve_opt gopt;
673 	int ret;
674 
675 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
676 				     BPF_F_TUNINFO_IPV6);
677 	if (ret < 0) {
678 		log_err(ret);
679 		return TC_ACT_SHOT;
680 	}
681 
682 	ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
683 	if (ret < 0)
684 		gopt.opt_class = 0;
685 
686 	bpf_printk("key %d remote ip 0x%x geneve class 0x%x\n",
687 		   key.tunnel_id, key.remote_ipv4, gopt.opt_class);
688 
689 	return TC_ACT_OK;
690 }
691 
692 SEC("tc")
693 int ipip_set_tunnel(struct __sk_buff *skb)
694 {
695 	struct bpf_tunnel_key key = {};
696 	void *data = (void *)(long)skb->data;
697 	struct iphdr *iph = data;
698 	void *data_end = (void *)(long)skb->data_end;
699 	int ret;
700 
701 	/* single length check */
702 	if (data + sizeof(*iph) > data_end) {
703 		log_err(1);
704 		return TC_ACT_SHOT;
705 	}
706 
707 	key.tunnel_ttl = 64;
708 	if (iph->protocol == IPPROTO_ICMP) {
709 		key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
710 	}
711 
712 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
713 	if (ret < 0) {
714 		log_err(ret);
715 		return TC_ACT_SHOT;
716 	}
717 
718 	return TC_ACT_OK;
719 }
720 
721 SEC("tc")
722 int ipip_get_tunnel(struct __sk_buff *skb)
723 {
724 	int ret;
725 	struct bpf_tunnel_key key;
726 
727 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
728 	if (ret < 0) {
729 		log_err(ret);
730 		return TC_ACT_SHOT;
731 	}
732 
733 	bpf_printk("remote ip 0x%x\n", key.remote_ipv4);
734 	return TC_ACT_OK;
735 }
736 
737 SEC("tc")
738 int ipip_gue_set_tunnel(struct __sk_buff *skb)
739 {
740 	struct bpf_tunnel_key key = {};
741 	struct bpf_fou_encap encap = {};
742 	void *data = (void *)(long)skb->data;
743 	struct iphdr *iph = data;
744 	void *data_end = (void *)(long)skb->data_end;
745 	int ret;
746 
747 	if (data + sizeof(*iph) > data_end) {
748 		log_err(1);
749 		return TC_ACT_SHOT;
750 	}
751 
752 	key.tunnel_ttl = 64;
753 	if (iph->protocol == IPPROTO_ICMP)
754 		key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
755 
756 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
757 	if (ret < 0) {
758 		log_err(ret);
759 		return TC_ACT_SHOT;
760 	}
761 
762 	encap.sport = 0;
763 	encap.dport = bpf_htons(5555);
764 
765 	ret = bpf_skb_set_fou_encap(skb, &encap, FOU_BPF_ENCAP_GUE);
766 	if (ret < 0) {
767 		log_err(ret);
768 		return TC_ACT_SHOT;
769 	}
770 
771 	return TC_ACT_OK;
772 }
773 
774 SEC("tc")
775 int ipip_fou_set_tunnel(struct __sk_buff *skb)
776 {
777 	struct bpf_tunnel_key key = {};
778 	struct bpf_fou_encap encap = {};
779 	void *data = (void *)(long)skb->data;
780 	struct iphdr *iph = data;
781 	void *data_end = (void *)(long)skb->data_end;
782 	int ret;
783 
784 	if (data + sizeof(*iph) > data_end) {
785 		log_err(1);
786 		return TC_ACT_SHOT;
787 	}
788 
789 	key.tunnel_ttl = 64;
790 	if (iph->protocol == IPPROTO_ICMP)
791 		key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
792 
793 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
794 	if (ret < 0) {
795 		log_err(ret);
796 		return TC_ACT_SHOT;
797 	}
798 
799 	encap.sport = 0;
800 	encap.dport = bpf_htons(5555);
801 
802 	ret = bpf_skb_set_fou_encap(skb, &encap, FOU_BPF_ENCAP_FOU);
803 	if (ret < 0) {
804 		log_err(ret);
805 		return TC_ACT_SHOT;
806 	}
807 
808 	return TC_ACT_OK;
809 }
810 
811 SEC("tc")
812 int ipip_encap_get_tunnel(struct __sk_buff *skb)
813 {
814 	int ret;
815 	struct bpf_tunnel_key key = {};
816 	struct bpf_fou_encap encap = {};
817 
818 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
819 	if (ret < 0) {
820 		log_err(ret);
821 		return TC_ACT_SHOT;
822 	}
823 
824 	ret = bpf_skb_get_fou_encap(skb, &encap);
825 	if (ret < 0) {
826 		log_err(ret);
827 		return TC_ACT_SHOT;
828 	}
829 
830 	if (bpf_ntohs(encap.dport) != 5555)
831 		return TC_ACT_SHOT;
832 
833 	bpf_printk("%d remote ip 0x%x, sport %d, dport %d\n", ret,
834 		   key.remote_ipv4, bpf_ntohs(encap.sport),
835 		   bpf_ntohs(encap.dport));
836 	return TC_ACT_OK;
837 }
838 
839 SEC("tc")
840 int ipip6_set_tunnel(struct __sk_buff *skb)
841 {
842 	struct bpf_tunnel_key key = {};
843 	void *data = (void *)(long)skb->data;
844 	struct iphdr *iph = data;
845 	void *data_end = (void *)(long)skb->data_end;
846 	int ret;
847 
848 	/* single length check */
849 	if (data + sizeof(*iph) > data_end) {
850 		log_err(1);
851 		return TC_ACT_SHOT;
852 	}
853 
854 	__builtin_memset(&key, 0x0, sizeof(key));
855 	key.tunnel_ttl = 64;
856 	if (iph->protocol == IPPROTO_ICMP) {
857 		key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
858 	}
859 
860 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
861 				     BPF_F_TUNINFO_IPV6);
862 	if (ret < 0) {
863 		log_err(ret);
864 		return TC_ACT_SHOT;
865 	}
866 
867 	return TC_ACT_OK;
868 }
869 
870 SEC("tc")
871 int ipip6_get_tunnel(struct __sk_buff *skb)
872 {
873 	int ret;
874 	struct bpf_tunnel_key key;
875 
876 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
877 				     BPF_F_TUNINFO_IPV6);
878 	if (ret < 0) {
879 		log_err(ret);
880 		return TC_ACT_SHOT;
881 	}
882 
883 	bpf_printk("remote ip6 %x::%x\n", bpf_htonl(key.remote_ipv6[0]),
884 		   bpf_htonl(key.remote_ipv6[3]));
885 	return TC_ACT_OK;
886 }
887 
888 SEC("tc")
889 int ip6ip6_set_tunnel(struct __sk_buff *skb)
890 {
891 	struct bpf_tunnel_key key = {};
892 	void *data = (void *)(long)skb->data;
893 	struct ipv6hdr *iph = data;
894 	void *data_end = (void *)(long)skb->data_end;
895 	int ret;
896 
897 	/* single length check */
898 	if (data + sizeof(*iph) > data_end) {
899 		log_err(1);
900 		return TC_ACT_SHOT;
901 	}
902 
903 	key.tunnel_ttl = 64;
904 	if (iph->nexthdr == 58 /* NEXTHDR_ICMP */) {
905 		key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
906 	}
907 
908 	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
909 				     BPF_F_TUNINFO_IPV6);
910 	if (ret < 0) {
911 		log_err(ret);
912 		return TC_ACT_SHOT;
913 	}
914 
915 	return TC_ACT_OK;
916 }
917 
918 SEC("tc")
919 int ip6ip6_get_tunnel(struct __sk_buff *skb)
920 {
921 	int ret;
922 	struct bpf_tunnel_key key;
923 
924 	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
925 				     BPF_F_TUNINFO_IPV6);
926 	if (ret < 0) {
927 		log_err(ret);
928 		return TC_ACT_SHOT;
929 	}
930 
931 	bpf_printk("remote ip6 %x::%x\n", bpf_htonl(key.remote_ipv6[0]),
932 		   bpf_htonl(key.remote_ipv6[3]));
933 	return TC_ACT_OK;
934 }
935 
936 volatile int xfrm_reqid = 0;
937 volatile int xfrm_spi = 0;
938 volatile int xfrm_remote_ip = 0;
939 
940 SEC("tc")
941 int xfrm_get_state(struct __sk_buff *skb)
942 {
943 	struct bpf_xfrm_state x;
944 	int ret;
945 
946 	ret = bpf_skb_get_xfrm_state(skb, 0, &x, sizeof(x), 0);
947 	if (ret < 0)
948 		return TC_ACT_OK;
949 
950 	xfrm_reqid = x.reqid;
951 	xfrm_spi = bpf_ntohl(x.spi);
952 	xfrm_remote_ip = bpf_ntohl(x.remote_ipv4);
953 
954 	return TC_ACT_OK;
955 }
956 
957 volatile int xfrm_replay_window = 0;
958 
959 SEC("xdp")
960 int xfrm_get_state_xdp(struct xdp_md *xdp)
961 {
962 	struct bpf_xfrm_state_opts opts = {};
963 	struct xfrm_state *x = NULL;
964 	struct ip_esp_hdr *esph;
965 	struct bpf_dynptr ptr;
966 	u8 esph_buf[8] = {};
967 	u8 iph_buf[20] = {};
968 	struct iphdr *iph;
969 	u32 off;
970 
971 	if (bpf_dynptr_from_xdp(xdp, 0, &ptr))
972 		goto out;
973 
974 	off = sizeof(struct ethhdr);
975 	iph = bpf_dynptr_slice(&ptr, off, iph_buf, sizeof(iph_buf));
976 	if (!iph || iph->protocol != IPPROTO_ESP)
977 		goto out;
978 
979 	off += sizeof(struct iphdr);
980 	esph = bpf_dynptr_slice(&ptr, off, esph_buf, sizeof(esph_buf));
981 	if (!esph)
982 		goto out;
983 
984 	opts.netns_id = BPF_F_CURRENT_NETNS;
985 	opts.daddr.a4 = iph->daddr;
986 	opts.spi = esph->spi;
987 	opts.proto = IPPROTO_ESP;
988 	opts.family = AF_INET;
989 
990 	x = bpf_xdp_get_xfrm_state(xdp, &opts, sizeof(opts));
991 	if (!x)
992 		goto out;
993 
994 	if (!x->replay_esn)
995 		goto out;
996 
997 	xfrm_replay_window = x->replay_esn->replay_window;
998 out:
999 	if (x)
1000 		bpf_xdp_xfrm_state_release(x);
1001 	return XDP_PASS;
1002 }
1003 
1004 char _license[] SEC("license") = "GPL";
1005