brintos

brintos / linux-shallow public Read only

0
0
Text · 21.7 KiB · 32127f1 Raw
1027 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2016 VMware3 * Copyright (c) 2016 Facebook4 *5 * This program is free software; you can redistribute it and/or6 * modify it under the terms of version 2 of the GNU General Public7 * 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		478919#define ETH_P_IP		0x080020#define PACKET_HOST		021#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.20026 */27#define ASSIGNED_ADDR_VETH1 0xac1001c828 29struct bpf_fou_encap___local {30	__be16 sport;31	__be16 dport;32} __attribute__((preserve_access_index));33 34enum bpf_fou_encap_type___local {35	FOU_BPF_ENCAP_FOU___local,36	FOU_BPF_ENCAP_GUE___local,37};38 39struct bpf_fou_encap;40 41int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx,42			  struct bpf_fou_encap *encap, int type) __ksym;43int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx,44			  struct bpf_fou_encap *encap) __ksym;45struct xfrm_state *46bpf_xdp_get_xfrm_state(struct xdp_md *ctx, struct bpf_xfrm_state_opts *opts,47		       u32 opts__sz) __ksym;48void bpf_xdp_xfrm_state_release(struct xfrm_state *x) __ksym;49 50struct {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 57SEC("tc")58int 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 79SEC("tc")80int 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 100SEC("tc")101int 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 116SEC("tc")117int 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 140SEC("tc")141int 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 159SEC("tc")160int 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_V1181	md.version = 1;182	md.u.index = bpf_htonl(123);183#else184	__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#endif192 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 202SEC("tc")203int 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_V1225	index = bpf_ntohl(md.u.index);226	bpf_printk("\tindex %x\n", index);227#else228	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#endif234 235	return TC_ACT_OK;236}237 238SEC("tc")239int 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_V1261	md.u.index = bpf_htonl(123);262	md.version = 1;263#else264	__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#endif272 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 282SEC("tc")283int 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_V1306	index = bpf_ntohl(md.u.index);307	bpf_printk("\tindex %x\n", index);308#else309	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#endif315 316	return TC_ACT_OK;317}318 319SEC("tc")320int 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 358SEC("tc")359int 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 397SEC("tc")398int 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 431SEC("tc")432int 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 484SEC("tc")485int 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 515SEC("tc")516int 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 546SEC("tc")547int 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 582struct local_geneve_opt {583	struct geneve_opt gopt;584	int data;585};586 587SEC("tc")588int 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 626SEC("tc")627int 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 648SEC("tc")649int 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 687SEC("tc")688int 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 711SEC("tc")712int 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 740SEC("tc")741int 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 756SEC("tc")757int 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 795SEC("tc")796int 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 833SEC("tc")834int 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 861SEC("tc")862int 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 892SEC("tc")893int 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 910SEC("tc")911int 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 940SEC("tc")941int 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 958volatile int xfrm_reqid = 0;959volatile int xfrm_spi = 0;960volatile int xfrm_remote_ip = 0;961 962SEC("tc")963int 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 979volatile int xfrm_replay_window = 0;980 981SEC("xdp")982int 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;1020out:1021	if (x)1022		bpf_xdp_xfrm_state_release(x);1023	return XDP_PASS;1024}1025 1026char _license[] SEC("license") = "GPL";1027