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