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