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
29int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx,
30			  struct bpf_fou_encap *encap, int type) __ksym;
31int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx,
32			  struct bpf_fou_encap *encap) __ksym;
33struct xfrm_state *
34bpf_xdp_get_xfrm_state(struct xdp_md *ctx, struct bpf_xfrm_state_opts *opts,
35		       u32 opts__sz) __ksym;
36void bpf_xdp_xfrm_state_release(struct xfrm_state *x) __ksym;
37
38struct {
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
45SEC("tc")
46int 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
67SEC("tc")
68int 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
88SEC("tc")
89int 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
104SEC("tc")
105int 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
128SEC("tc")
129int 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
147SEC("tc")
148int 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
190SEC("tc")
191int 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
226SEC("tc")
227int 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
270SEC("tc")
271int 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
307SEC("tc")
308int 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
346SEC("tc")
347int 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
385SEC("tc")
386int 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
419SEC("tc")
420int 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
472SEC("tc")
473int 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
503SEC("tc")
504int 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
534SEC("tc")
535int 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
570SEC("tc")
571int 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
608SEC("tc")
609int 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
630SEC("tc")
631int 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
668SEC("tc")
669int 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
692SEC("tc")
693int 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
721SEC("tc")
722int 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
737SEC("tc")
738int 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
774SEC("tc")
775int 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
811SEC("tc")
812int 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
839SEC("tc")
840int 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
870SEC("tc")
871int 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
888SEC("tc")
889int 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
918SEC("tc")
919int 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
936volatile int xfrm_reqid = 0;
937volatile int xfrm_spi = 0;
938volatile int xfrm_remote_ip = 0;
939
940SEC("tc")
941int 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
957volatile int xfrm_replay_window = 0;
958
959SEC("xdp")
960int 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;
998out:
999	if (x)
1000		bpf_xdp_xfrm_state_release(x);
1001	return XDP_PASS;
1002}
1003
1004char _license[] SEC("license") = "GPL";
1005