Linux Audio

Check our new training course

Real-Time Linux with PREEMPT_RT training

Feb 18-20, 2025
Register
Loading...
v6.13.7
   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
  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_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
 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_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
 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_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
 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_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
 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";
v6.9.4
   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";