Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
   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";