Linux Audio

Check our new training course

Linux debugging, profiling, tracing and performance analysis training

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