https://github.com/cilium/cilium
Raw File
Tip revision: 76d34dbdfc1bf14cb8976a86ccf1e98dae6d72c5 authored by Joe Stringer on 18 January 2022, 23:52:51 UTC
Prepare for release v1.11.1
Tip revision: 76d34db
bpf_ct_tests.c
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2016-2021 Authors of Cilium */

#include <bpf/ctx/skb.h>
#include <bpf/api.h>

/* most values taken from node_config.h */
#define CONNTRACK
#define ENDPOINTS_MAP test_cilium_lxc
#define POLICY_PROG_MAP_SIZE ENDPOINTS_MAP_SIZE
#define METRICS_MAP test_cilium_metrics
#define NAT46_PREFIX {.addr = {                   \
	0xbe, 0xef, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \
	0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0    \
} }

#define ENDPOINTS_MAP_SIZE 65536
#define IPCACHE_MAP_SIZE 512000
#define METRICS_MAP_SIZE 65536
#define EVENTS_MAP test_events_map

#define CT_MAP_TCP6 test_cilium_ct_tcp6_65535
#define CT_MAP_ANY6 test_cilium_ct_any6_65535
#define CT_MAP_TCP4 test_cilium_ct_tcp4_65535
#define CT_MAP_ANY4 test_cilium_ct_any4_65535
#define CT_MAP_SIZE_TCP 4096
#define CT_MAP_SIZE_ANY 4096
#define CT_CONNECTION_LIFETIME_TCP	21600
#define CT_CONNECTION_LIFETIME_NONTCP	60
#define CT_SERVICE_LIFETIME_TCP		21600
#define CT_SERVICE_LIFETIME_NONTCP	60
#define CT_SYN_TIMEOUT			60
#define CT_CLOSE_TIMEOUT		10
#define CT_REPORT_INTERVAL		5
#define CT_REPORT_FLAGS			0xff
#define MTU 1500

#define DEBUG

#include <lib/dbg.h>
#include <lib/conntrack.h>
#include <lib/conntrack_map.h>

__section("action/test-nop")
int test_nop(struct __ctx_buff __maybe_unused *ctx)
{
	return CTX_ACT_OK;
}

__section("action/test-map")
int test_map(struct __ctx_buff __maybe_unused *ctx)
{
	/*
	 * Declare static, otherwise this ends up in .rodata.
	 * On new clang + pre-5.12 kernel, this causes BTF to be rejected,
	 * since the Datasec is patched up to the real size of .rodata,
	 * but vlen remains 0, since this is a var with local scope.
	 * See https://lore.kernel.org/bpf/20210119153519.3901963-1-yhs@fb.com.
	 */
	static struct ipv4_ct_tuple ct_key = (struct ipv4_ct_tuple){
		.saddr = bpf_htonl(16843009), /* 1.1.1.1 */
		.daddr = bpf_htonl(16843010), /* 1.1.1.2 */
		.sport = bpf_htons(1001),
		.dport = bpf_htons(1002),
		.nexthdr = 0,
		.flags = 0,
	};

	struct ct_entry ct_val = (struct ct_entry){
		.rx_packets = 1000,
		.tx_packets = 1000,
	};

	map_update_elem(&CT_MAP_TCP4, &ct_key, &ct_val, 0);
	return CTX_ACT_OK;
}

__section("action/test-ct4-rst1")
int test_ct4_rst1(struct __ctx_buff *ctx)
{
	struct ipv4_ct_tuple tuple = {};
	void *data, *data_end;
	struct iphdr *ip4;
	int l3_off = ETH_HLEN, l4_off;
	struct ct_state ct_state = {}, ct_state_new = {};
	__u16 proto;
	__u32 monitor = 0;
	int ret;

	bpf_clear_meta(ctx);
	if (!validate_ethertype(ctx, &proto)) {
		ret = DROP_UNSUPPORTED_L2;
		goto out;
	}
	if (!revalidate_data(ctx, &data, &data_end, &ip4)) {
		ret = DROP_INVALID;
		goto out;
	}

	tuple.nexthdr = ip4->protocol;
	tuple.daddr = ip4->daddr;
	tuple.saddr = ip4->saddr;
	l4_off = l3_off + ipv4_hdrlen(ip4);

	ret = ct_lookup4(get_ct_map4(&tuple), &tuple, ctx, l4_off, CT_EGRESS,
			 &ct_state, &monitor);
	switch (ret) {
	case CT_NEW:
		ct_state_new.node_port = ct_state.node_port;
		ct_state_new.ifindex = ct_state.ifindex;
		ret = ct_create4(get_ct_map4(&tuple), &CT_MAP_ANY4, &tuple, ctx,
				 CT_EGRESS, &ct_state_new, 0);
		break;

	default:
		ret = -1;
		break;
	}

out:
	/* mark the termination of our program so that the go program stops
	 * blocking on the ring buffer
	 */
	cilium_dbg(ctx, DBG_UNSPEC, 0xe3d, 0xe3d);
	return ret;
}

__section("action/test-ct4-rst2")
int test_ct4_rst2(struct __ctx_buff *ctx)
{
	struct ipv4_ct_tuple tuple = {};
	void *data, *data_end;
	struct iphdr *ip4;
	int l3_off = ETH_HLEN, l4_off;
	struct ct_state ct_state = {};
	__u16 proto;
	__u32 monitor = 0;
	int ret;

	bpf_clear_meta(ctx);
	if (!validate_ethertype(ctx, &proto)) {
		ret = DROP_UNSUPPORTED_L2;
		goto out;
	}

	if (!revalidate_data(ctx, &data, &data_end, &ip4)) {
		ret = DROP_INVALID;
		goto out;
	}

	tuple.nexthdr = ip4->protocol;
	tuple.daddr = ip4->daddr;
	tuple.saddr = ip4->saddr;
	l4_off = l3_off + ipv4_hdrlen(ip4);

	ret = ct_lookup4(get_ct_map4(&tuple), &tuple, ctx, l4_off, CT_INGRESS,
			 &ct_state, &monitor);
	cilium_dbg(ctx, DBG_UNSPEC, 1000, ret);
out:
	/* mark the termination of our program so that the go program stops
	 * blocking on the ring buffer
	 */
	cilium_dbg(ctx, DBG_UNSPEC, 0xe3d, 0xe3d);
	return CTX_ACT_OK;
}

BPF_LICENSE("GPL");
back to top