cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

test_tunnel_kern.c (16067B)


      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 <stddef.h>
     10#include <string.h>
     11#include <arpa/inet.h>
     12#include <linux/bpf.h>
     13#include <linux/if_ether.h>
     14#include <linux/if_packet.h>
     15#include <linux/ip.h>
     16#include <linux/ipv6.h>
     17#include <linux/types.h>
     18#include <linux/socket.h>
     19#include <linux/pkt_cls.h>
     20#include <linux/erspan.h>
     21#include <bpf/bpf_helpers.h>
     22#include <bpf/bpf_endian.h>
     23
     24#define log_err(__ret) bpf_printk("ERROR line:%d ret:%d\n", __LINE__, __ret)
     25
     26struct geneve_opt {
     27	__be16	opt_class;
     28	__u8	type;
     29	__u8	length:5;
     30	__u8	r3:1;
     31	__u8	r2:1;
     32	__u8	r1:1;
     33	__u8	opt_data[8]; /* hard-coded to 8 byte */
     34};
     35
     36struct vxlan_metadata {
     37	__u32     gbp;
     38};
     39
     40struct {
     41	__uint(type, BPF_MAP_TYPE_ARRAY);
     42	__uint(max_entries, 1);
     43	__type(key, __u32);
     44	__type(value, __u32);
     45} local_ip_map SEC(".maps");
     46
     47SEC("tc")
     48int gre_set_tunnel(struct __sk_buff *skb)
     49{
     50	int ret;
     51	struct bpf_tunnel_key key;
     52
     53	__builtin_memset(&key, 0x0, sizeof(key));
     54	key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
     55	key.tunnel_id = 2;
     56	key.tunnel_tos = 0;
     57	key.tunnel_ttl = 64;
     58
     59	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
     60				     BPF_F_ZERO_CSUM_TX | BPF_F_SEQ_NUMBER);
     61	if (ret < 0) {
     62		log_err(ret);
     63		return TC_ACT_SHOT;
     64	}
     65
     66	return TC_ACT_OK;
     67}
     68
     69SEC("tc")
     70int gre_get_tunnel(struct __sk_buff *skb)
     71{
     72	int ret;
     73	struct bpf_tunnel_key key;
     74
     75	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
     76	if (ret < 0) {
     77		log_err(ret);
     78		return TC_ACT_SHOT;
     79	}
     80
     81	bpf_printk("key %d remote ip 0x%x\n", key.tunnel_id, key.remote_ipv4);
     82	return TC_ACT_OK;
     83}
     84
     85SEC("tc")
     86int ip6gretap_set_tunnel(struct __sk_buff *skb)
     87{
     88	struct bpf_tunnel_key key;
     89	int ret;
     90
     91	__builtin_memset(&key, 0x0, sizeof(key));
     92	key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
     93	key.tunnel_id = 2;
     94	key.tunnel_tos = 0;
     95	key.tunnel_ttl = 64;
     96	key.tunnel_label = 0xabcde;
     97
     98	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
     99				     BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX |
    100				     BPF_F_SEQ_NUMBER);
    101	if (ret < 0) {
    102		log_err(ret);
    103		return TC_ACT_SHOT;
    104	}
    105
    106	return TC_ACT_OK;
    107}
    108
    109SEC("tc")
    110int ip6gretap_get_tunnel(struct __sk_buff *skb)
    111{
    112	struct bpf_tunnel_key key;
    113	int ret;
    114
    115	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
    116				     BPF_F_TUNINFO_IPV6);
    117	if (ret < 0) {
    118		log_err(ret);
    119		return TC_ACT_SHOT;
    120	}
    121
    122	bpf_printk("key %d remote ip6 ::%x label %x\n",
    123		   key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
    124
    125	return TC_ACT_OK;
    126}
    127
    128SEC("tc")
    129int erspan_set_tunnel(struct __sk_buff *skb)
    130{
    131	struct bpf_tunnel_key key;
    132	struct erspan_metadata md;
    133	int ret;
    134
    135	__builtin_memset(&key, 0x0, sizeof(key));
    136	key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
    137	key.tunnel_id = 2;
    138	key.tunnel_tos = 0;
    139	key.tunnel_ttl = 64;
    140
    141	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
    142				     BPF_F_ZERO_CSUM_TX);
    143	if (ret < 0) {
    144		log_err(ret);
    145		return TC_ACT_SHOT;
    146	}
    147
    148	__builtin_memset(&md, 0, sizeof(md));
    149#ifdef ERSPAN_V1
    150	md.version = 1;
    151	md.u.index = bpf_htonl(123);
    152#else
    153	__u8 direction = 1;
    154	__u8 hwid = 7;
    155
    156	md.version = 2;
    157	md.u.md2.dir = direction;
    158	md.u.md2.hwid = hwid & 0xf;
    159	md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
    160#endif
    161
    162	ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
    163	if (ret < 0) {
    164		log_err(ret);
    165		return TC_ACT_SHOT;
    166	}
    167
    168	return TC_ACT_OK;
    169}
    170
    171SEC("tc")
    172int erspan_get_tunnel(struct __sk_buff *skb)
    173{
    174	struct bpf_tunnel_key key;
    175	struct erspan_metadata md;
    176	__u32 index;
    177	int ret;
    178
    179	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
    180	if (ret < 0) {
    181		log_err(ret);
    182		return TC_ACT_SHOT;
    183	}
    184
    185	ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
    186	if (ret < 0) {
    187		log_err(ret);
    188		return TC_ACT_SHOT;
    189	}
    190
    191	bpf_printk("key %d remote ip 0x%x erspan version %d\n",
    192		   key.tunnel_id, key.remote_ipv4, md.version);
    193
    194#ifdef ERSPAN_V1
    195	index = bpf_ntohl(md.u.index);
    196	bpf_printk("\tindex %x\n", index);
    197#else
    198	bpf_printk("\tdirection %d hwid %x timestamp %u\n",
    199		   md.u.md2.dir,
    200		   (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
    201		   bpf_ntohl(md.u.md2.timestamp));
    202#endif
    203
    204	return TC_ACT_OK;
    205}
    206
    207SEC("tc")
    208int ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
    209{
    210	struct bpf_tunnel_key key;
    211	struct erspan_metadata md;
    212	int ret;
    213
    214	__builtin_memset(&key, 0x0, sizeof(key));
    215	key.remote_ipv6[3] = bpf_htonl(0x11);
    216	key.tunnel_id = 2;
    217	key.tunnel_tos = 0;
    218	key.tunnel_ttl = 64;
    219
    220	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
    221				     BPF_F_TUNINFO_IPV6);
    222	if (ret < 0) {
    223		log_err(ret);
    224		return TC_ACT_SHOT;
    225	}
    226
    227	__builtin_memset(&md, 0, sizeof(md));
    228
    229#ifdef ERSPAN_V1
    230	md.u.index = bpf_htonl(123);
    231	md.version = 1;
    232#else
    233	__u8 direction = 0;
    234	__u8 hwid = 17;
    235
    236	md.version = 2;
    237	md.u.md2.dir = direction;
    238	md.u.md2.hwid = hwid & 0xf;
    239	md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
    240#endif
    241
    242	ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
    243	if (ret < 0) {
    244		log_err(ret);
    245		return TC_ACT_SHOT;
    246	}
    247
    248	return TC_ACT_OK;
    249}
    250
    251SEC("tc")
    252int ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
    253{
    254	struct bpf_tunnel_key key;
    255	struct erspan_metadata md;
    256	__u32 index;
    257	int ret;
    258
    259	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
    260				     BPF_F_TUNINFO_IPV6);
    261	if (ret < 0) {
    262		log_err(ret);
    263		return TC_ACT_SHOT;
    264	}
    265
    266	ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
    267	if (ret < 0) {
    268		log_err(ret);
    269		return TC_ACT_SHOT;
    270	}
    271
    272	bpf_printk("ip6erspan get key %d remote ip6 ::%x erspan version %d\n",
    273		   key.tunnel_id, key.remote_ipv4, md.version);
    274
    275#ifdef ERSPAN_V1
    276	index = bpf_ntohl(md.u.index);
    277	bpf_printk("\tindex %x\n", index);
    278#else
    279	bpf_printk("\tdirection %d hwid %x timestamp %u\n",
    280		   md.u.md2.dir,
    281		   (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
    282		   bpf_ntohl(md.u.md2.timestamp));
    283#endif
    284
    285	return TC_ACT_OK;
    286}
    287
    288SEC("tc")
    289int vxlan_set_tunnel_dst(struct __sk_buff *skb)
    290{
    291	int ret;
    292	struct bpf_tunnel_key key;
    293	struct vxlan_metadata md;
    294	__u32 index = 0;
    295	__u32 *local_ip = NULL;
    296
    297	local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
    298	if (!local_ip) {
    299		log_err(ret);
    300		return TC_ACT_SHOT;
    301	}
    302
    303	__builtin_memset(&key, 0x0, sizeof(key));
    304	key.local_ipv4 = 0xac100164; /* 172.16.1.100 */
    305	key.remote_ipv4 = *local_ip;
    306	key.tunnel_id = 2;
    307	key.tunnel_tos = 0;
    308	key.tunnel_ttl = 64;
    309
    310	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
    311				     BPF_F_ZERO_CSUM_TX);
    312	if (ret < 0) {
    313		log_err(ret);
    314		return TC_ACT_SHOT;
    315	}
    316
    317	md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
    318	ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
    319	if (ret < 0) {
    320		log_err(ret);
    321		return TC_ACT_SHOT;
    322	}
    323
    324	return TC_ACT_OK;
    325}
    326
    327SEC("tc")
    328int vxlan_set_tunnel_src(struct __sk_buff *skb)
    329{
    330	int ret;
    331	struct bpf_tunnel_key key;
    332	struct vxlan_metadata md;
    333	__u32 index = 0;
    334	__u32 *local_ip = NULL;
    335
    336	local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
    337	if (!local_ip) {
    338		log_err(ret);
    339		return TC_ACT_SHOT;
    340	}
    341
    342	__builtin_memset(&key, 0x0, sizeof(key));
    343	key.local_ipv4 = *local_ip;
    344	key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
    345	key.tunnel_id = 2;
    346	key.tunnel_tos = 0;
    347	key.tunnel_ttl = 64;
    348
    349	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
    350				     BPF_F_ZERO_CSUM_TX);
    351	if (ret < 0) {
    352		log_err(ret);
    353		return TC_ACT_SHOT;
    354	}
    355
    356	md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
    357	ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
    358	if (ret < 0) {
    359		log_err(ret);
    360		return TC_ACT_SHOT;
    361	}
    362
    363	return TC_ACT_OK;
    364}
    365
    366SEC("tc")
    367int vxlan_get_tunnel_src(struct __sk_buff *skb)
    368{
    369	int ret;
    370	struct bpf_tunnel_key key;
    371	struct vxlan_metadata md;
    372	__u32 index = 0;
    373	__u32 *local_ip = NULL;
    374
    375	local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
    376	if (!local_ip) {
    377		log_err(ret);
    378		return TC_ACT_SHOT;
    379	}
    380
    381	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
    382	if (ret < 0) {
    383		log_err(ret);
    384		return TC_ACT_SHOT;
    385	}
    386
    387	ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
    388	if (ret < 0) {
    389		log_err(ret);
    390		return TC_ACT_SHOT;
    391	}
    392
    393	if (key.local_ipv4 != *local_ip || md.gbp != 0x800FF) {
    394		bpf_printk("vxlan key %d local ip 0x%x remote ip 0x%x gbp 0x%x\n",
    395			   key.tunnel_id, key.local_ipv4,
    396			   key.remote_ipv4, md.gbp);
    397		bpf_printk("local_ip 0x%x\n", *local_ip);
    398		log_err(ret);
    399		return TC_ACT_SHOT;
    400	}
    401
    402	return TC_ACT_OK;
    403}
    404
    405SEC("tc")
    406int ip6vxlan_set_tunnel_dst(struct __sk_buff *skb)
    407{
    408	struct bpf_tunnel_key key;
    409	int ret;
    410	__u32 index = 0;
    411	__u32 *local_ip;
    412
    413	local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
    414	if (!local_ip) {
    415		log_err(ret);
    416		return TC_ACT_SHOT;
    417	}
    418
    419	__builtin_memset(&key, 0x0, sizeof(key));
    420	key.local_ipv6[3] = bpf_htonl(0x11); /* ::11 */
    421	key.remote_ipv6[3] = bpf_htonl(*local_ip);
    422	key.tunnel_id = 22;
    423	key.tunnel_tos = 0;
    424	key.tunnel_ttl = 64;
    425
    426	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
    427				     BPF_F_TUNINFO_IPV6);
    428	if (ret < 0) {
    429		log_err(ret);
    430		return TC_ACT_SHOT;
    431	}
    432
    433	return TC_ACT_OK;
    434}
    435
    436SEC("tc")
    437int ip6vxlan_set_tunnel_src(struct __sk_buff *skb)
    438{
    439	struct bpf_tunnel_key key;
    440	int ret;
    441	__u32 index = 0;
    442	__u32 *local_ip;
    443
    444	local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
    445	if (!local_ip) {
    446		log_err(ret);
    447		return TC_ACT_SHOT;
    448	}
    449
    450	__builtin_memset(&key, 0x0, sizeof(key));
    451	key.local_ipv6[3] = bpf_htonl(*local_ip);
    452	key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
    453	key.tunnel_id = 22;
    454	key.tunnel_tos = 0;
    455	key.tunnel_ttl = 64;
    456
    457	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
    458				     BPF_F_TUNINFO_IPV6);
    459	if (ret < 0) {
    460		log_err(ret);
    461		return TC_ACT_SHOT;
    462	}
    463
    464	return TC_ACT_OK;
    465}
    466
    467SEC("tc")
    468int ip6vxlan_get_tunnel_src(struct __sk_buff *skb)
    469{
    470	struct bpf_tunnel_key key;
    471	int ret;
    472	__u32 index = 0;
    473	__u32 *local_ip;
    474
    475	local_ip = bpf_map_lookup_elem(&local_ip_map, &index);
    476	if (!local_ip) {
    477		log_err(ret);
    478		return TC_ACT_SHOT;
    479	}
    480
    481	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
    482				     BPF_F_TUNINFO_IPV6);
    483	if (ret < 0) {
    484		log_err(ret);
    485		return TC_ACT_SHOT;
    486	}
    487
    488	if (bpf_ntohl(key.local_ipv6[3]) != *local_ip) {
    489		bpf_printk("ip6vxlan key %d local ip6 ::%x remote ip6 ::%x label 0x%x\n",
    490			   key.tunnel_id, bpf_ntohl(key.local_ipv6[3]),
    491			   bpf_ntohl(key.remote_ipv6[3]), key.tunnel_label);
    492		bpf_printk("local_ip 0x%x\n", *local_ip);
    493		log_err(ret);
    494		return TC_ACT_SHOT;
    495	}
    496
    497	return TC_ACT_OK;
    498}
    499
    500SEC("tc")
    501int geneve_set_tunnel(struct __sk_buff *skb)
    502{
    503	int ret;
    504	struct bpf_tunnel_key key;
    505	struct geneve_opt gopt;
    506
    507	__builtin_memset(&key, 0x0, sizeof(key));
    508	key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
    509	key.tunnel_id = 2;
    510	key.tunnel_tos = 0;
    511	key.tunnel_ttl = 64;
    512
    513	__builtin_memset(&gopt, 0x0, sizeof(gopt));
    514	gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
    515	gopt.type = 0x08;
    516	gopt.r1 = 0;
    517	gopt.r2 = 0;
    518	gopt.r3 = 0;
    519	gopt.length = 2; /* 4-byte multiple */
    520	*(int *) &gopt.opt_data = bpf_htonl(0xdeadbeef);
    521
    522	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
    523				     BPF_F_ZERO_CSUM_TX);
    524	if (ret < 0) {
    525		log_err(ret);
    526		return TC_ACT_SHOT;
    527	}
    528
    529	ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
    530	if (ret < 0) {
    531		log_err(ret);
    532		return TC_ACT_SHOT;
    533	}
    534
    535	return TC_ACT_OK;
    536}
    537
    538SEC("tc")
    539int geneve_get_tunnel(struct __sk_buff *skb)
    540{
    541	int ret;
    542	struct bpf_tunnel_key key;
    543	struct geneve_opt gopt;
    544
    545	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
    546	if (ret < 0) {
    547		log_err(ret);
    548		return TC_ACT_SHOT;
    549	}
    550
    551	ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
    552	if (ret < 0)
    553		gopt.opt_class = 0;
    554
    555	bpf_printk("key %d remote ip 0x%x geneve class 0x%x\n",
    556		   key.tunnel_id, key.remote_ipv4, gopt.opt_class);
    557	return TC_ACT_OK;
    558}
    559
    560SEC("tc")
    561int ip6geneve_set_tunnel(struct __sk_buff *skb)
    562{
    563	struct bpf_tunnel_key key;
    564	struct geneve_opt gopt;
    565	int ret;
    566
    567	__builtin_memset(&key, 0x0, sizeof(key));
    568	key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
    569	key.tunnel_id = 22;
    570	key.tunnel_tos = 0;
    571	key.tunnel_ttl = 64;
    572
    573	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
    574				     BPF_F_TUNINFO_IPV6);
    575	if (ret < 0) {
    576		log_err(ret);
    577		return TC_ACT_SHOT;
    578	}
    579
    580	__builtin_memset(&gopt, 0x0, sizeof(gopt));
    581	gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
    582	gopt.type = 0x08;
    583	gopt.r1 = 0;
    584	gopt.r2 = 0;
    585	gopt.r3 = 0;
    586	gopt.length = 2; /* 4-byte multiple */
    587	*(int *) &gopt.opt_data = bpf_htonl(0xfeedbeef);
    588
    589	ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
    590	if (ret < 0) {
    591		log_err(ret);
    592		return TC_ACT_SHOT;
    593	}
    594
    595	return TC_ACT_OK;
    596}
    597
    598SEC("tc")
    599int ip6geneve_get_tunnel(struct __sk_buff *skb)
    600{
    601	struct bpf_tunnel_key key;
    602	struct geneve_opt gopt;
    603	int ret;
    604
    605	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
    606				     BPF_F_TUNINFO_IPV6);
    607	if (ret < 0) {
    608		log_err(ret);
    609		return TC_ACT_SHOT;
    610	}
    611
    612	ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
    613	if (ret < 0)
    614		gopt.opt_class = 0;
    615
    616	bpf_printk("key %d remote ip 0x%x geneve class 0x%x\n",
    617		   key.tunnel_id, key.remote_ipv4, gopt.opt_class);
    618
    619	return TC_ACT_OK;
    620}
    621
    622SEC("tc")
    623int ipip_set_tunnel(struct __sk_buff *skb)
    624{
    625	struct bpf_tunnel_key key = {};
    626	void *data = (void *)(long)skb->data;
    627	struct iphdr *iph = data;
    628	void *data_end = (void *)(long)skb->data_end;
    629	int ret;
    630
    631	/* single length check */
    632	if (data + sizeof(*iph) > data_end) {
    633		log_err(1);
    634		return TC_ACT_SHOT;
    635	}
    636
    637	key.tunnel_ttl = 64;
    638	if (iph->protocol == IPPROTO_ICMP) {
    639		key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
    640	}
    641
    642	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
    643	if (ret < 0) {
    644		log_err(ret);
    645		return TC_ACT_SHOT;
    646	}
    647
    648	return TC_ACT_OK;
    649}
    650
    651SEC("tc")
    652int ipip_get_tunnel(struct __sk_buff *skb)
    653{
    654	int ret;
    655	struct bpf_tunnel_key key;
    656
    657	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
    658	if (ret < 0) {
    659		log_err(ret);
    660		return TC_ACT_SHOT;
    661	}
    662
    663	bpf_printk("remote ip 0x%x\n", key.remote_ipv4);
    664	return TC_ACT_OK;
    665}
    666
    667SEC("tc")
    668int ipip6_set_tunnel(struct __sk_buff *skb)
    669{
    670	struct bpf_tunnel_key key = {};
    671	void *data = (void *)(long)skb->data;
    672	struct iphdr *iph = data;
    673	void *data_end = (void *)(long)skb->data_end;
    674	int ret;
    675
    676	/* single length check */
    677	if (data + sizeof(*iph) > data_end) {
    678		log_err(1);
    679		return TC_ACT_SHOT;
    680	}
    681
    682	__builtin_memset(&key, 0x0, sizeof(key));
    683	key.tunnel_ttl = 64;
    684	if (iph->protocol == IPPROTO_ICMP) {
    685		key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
    686	}
    687
    688	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
    689				     BPF_F_TUNINFO_IPV6);
    690	if (ret < 0) {
    691		log_err(ret);
    692		return TC_ACT_SHOT;
    693	}
    694
    695	return TC_ACT_OK;
    696}
    697
    698SEC("tc")
    699int ipip6_get_tunnel(struct __sk_buff *skb)
    700{
    701	int ret;
    702	struct bpf_tunnel_key key;
    703
    704	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
    705				     BPF_F_TUNINFO_IPV6);
    706	if (ret < 0) {
    707		log_err(ret);
    708		return TC_ACT_SHOT;
    709	}
    710
    711	bpf_printk("remote ip6 %x::%x\n", bpf_htonl(key.remote_ipv6[0]),
    712		   bpf_htonl(key.remote_ipv6[3]));
    713	return TC_ACT_OK;
    714}
    715
    716SEC("tc")
    717int ip6ip6_set_tunnel(struct __sk_buff *skb)
    718{
    719	struct bpf_tunnel_key key = {};
    720	void *data = (void *)(long)skb->data;
    721	struct ipv6hdr *iph = data;
    722	void *data_end = (void *)(long)skb->data_end;
    723	int ret;
    724
    725	/* single length check */
    726	if (data + sizeof(*iph) > data_end) {
    727		log_err(1);
    728		return TC_ACT_SHOT;
    729	}
    730
    731	key.tunnel_ttl = 64;
    732	if (iph->nexthdr == 58 /* NEXTHDR_ICMP */) {
    733		key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
    734	}
    735
    736	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
    737				     BPF_F_TUNINFO_IPV6);
    738	if (ret < 0) {
    739		log_err(ret);
    740		return TC_ACT_SHOT;
    741	}
    742
    743	return TC_ACT_OK;
    744}
    745
    746SEC("tc")
    747int ip6ip6_get_tunnel(struct __sk_buff *skb)
    748{
    749	int ret;
    750	struct bpf_tunnel_key key;
    751
    752	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
    753				     BPF_F_TUNINFO_IPV6);
    754	if (ret < 0) {
    755		log_err(ret);
    756		return TC_ACT_SHOT;
    757	}
    758
    759	bpf_printk("remote ip6 %x::%x\n", bpf_htonl(key.remote_ipv6[0]),
    760		   bpf_htonl(key.remote_ipv6[3]));
    761	return TC_ACT_OK;
    762}
    763
    764SEC("tc")
    765int xfrm_get_state(struct __sk_buff *skb)
    766{
    767	struct bpf_xfrm_state x;
    768	int ret;
    769
    770	ret = bpf_skb_get_xfrm_state(skb, 0, &x, sizeof(x), 0);
    771	if (ret < 0)
    772		return TC_ACT_OK;
    773
    774	bpf_printk("reqid %d spi 0x%x remote ip 0x%x\n",
    775		   x.reqid, bpf_ntohl(x.spi),
    776		   bpf_ntohl(x.remote_ipv4));
    777	return TC_ACT_OK;
    778}
    779
    780char _license[] SEC("license") = "GPL";