/*
 * Copyright (c) 2017 Facebook
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 */
#define KBUILD_MODNAME "foo"
#include <linux/ptrace.h>
#include <linux/version.h>
#include <uapi/linux/bpf.h>
#include <uapi/linux/in6.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
#include "trace_common.h"

#define MAX_NR_PORTS 65536

/* map #0 */
struct inner_a {
	__uint(type, BPF_MAP_TYPE_ARRAY);
	__type(key, u32);
	__type(value, int);
	__uint(max_entries, MAX_NR_PORTS);
} port_a SEC(".maps");

/* map #1 */
struct inner_h {
	__uint(type, BPF_MAP_TYPE_HASH);
	__type(key, u32);
	__type(value, int);
	__uint(max_entries, 1);
} port_h SEC(".maps");

/* map #2 */
struct {
	__uint(type, BPF_MAP_TYPE_HASH);
	__type(key, u32);
	__type(value, int);
	__uint(max_entries, 1);
} reg_result_h SEC(".maps");

/* map #3 */
struct {
	__uint(type, BPF_MAP_TYPE_HASH);
	__type(key, u32);
	__type(value, int);
	__uint(max_entries, 1);
} inline_result_h SEC(".maps");

/* map #4 */ /* Test case #0 */
struct {
	__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
	__uint(max_entries, MAX_NR_PORTS);
	__uint(key_size, sizeof(u32));
	__array(values, struct inner_a); /* use inner_a as inner map */
} a_of_port_a SEC(".maps");

/* map #5 */ /* Test case #1 */
struct {
	__uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);
	__uint(max_entries, 1);
	__uint(key_size, sizeof(u32));
	__array(values, struct inner_a); /* use inner_a as inner map */
} h_of_port_a SEC(".maps");

/* map #6 */ /* Test case #2 */
struct {
	__uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);
	__uint(max_entries, 1);
	__uint(key_size, sizeof(u32));
	__array(values, struct inner_h); /* use inner_h as inner map */
} h_of_port_h SEC(".maps");

static __always_inline int do_reg_lookup(void *inner_map, u32 port)
{
	int *result;

	result = bpf_map_lookup_elem(inner_map, &port);
	return result ? *result : -ENOENT;
}

static __always_inline int do_inline_array_lookup(void *inner_map, u32 port)
{
	int *result;

	if (inner_map != &port_a)
		return -EINVAL;

	result = bpf_map_lookup_elem(&port_a, &port);
	return result ? *result : -ENOENT;
}

static __always_inline int do_inline_hash_lookup(void *inner_map, u32 port)
{
	int *result;

	if (inner_map != &port_h)
		return -EINVAL;

	result = bpf_map_lookup_elem(&port_h, &port);
	return result ? *result : -ENOENT;
}

SEC("kprobe/" SYSCALL(sys_connect))
int trace_sys_connect(struct pt_regs *ctx)
{
	struct pt_regs *real_regs = (struct pt_regs *)PT_REGS_PARM1_CORE(ctx);
	struct sockaddr_in6 *in6;
	u16 test_case, port, dst6[8];
	int addrlen, ret, inline_ret, ret_key = 0;
	u32 port_key;
	void *outer_map, *inner_map;
	bool inline_hash = false;

	in6 = (struct sockaddr_in6 *)PT_REGS_PARM2_CORE(real_regs);
	addrlen = (int)PT_REGS_PARM3_CORE(real_regs);

	if (addrlen != sizeof(*in6))
		return 0;

	ret = bpf_probe_read_user(dst6, sizeof(dst6), &in6->sin6_addr);
	if (ret) {
		inline_ret = ret;
		goto done;
	}

	if (dst6[0] != 0xdead || dst6[1] != 0xbeef)
		return 0;

	test_case = dst6[7];

	ret = bpf_probe_read_user(&port, sizeof(port), &in6->sin6_port);
	if (ret) {
		inline_ret = ret;
		goto done;
	}

	port_key = port;

	ret = -ENOENT;
	if (test_case == 0) {
		outer_map = &a_of_port_a;
	} else if (test_case == 1) {
		outer_map = &h_of_port_a;
	} else if (test_case == 2) {
		outer_map = &h_of_port_h;
	} else {
		ret = __LINE__;
		inline_ret = ret;
		goto done;
	}

	inner_map = bpf_map_lookup_elem(outer_map, &port_key);
	if (!inner_map) {
		ret = __LINE__;
		inline_ret = ret;
		goto done;
	}

	ret = do_reg_lookup(inner_map, port_key);

	if (test_case == 0 || test_case == 1)
		inline_ret = do_inline_array_lookup(inner_map, port_key);
	else
		inline_ret = do_inline_hash_lookup(inner_map, port_key);

done:
	bpf_map_update_elem(&reg_result_h, &ret_key, &ret, BPF_ANY);
	bpf_map_update_elem(&inline_result_h, &ret_key, &inline_ret, BPF_ANY);

	return 0;
}

char _license[] SEC("license") = "GPL";
u32 _version SEC("version") = LINUX_VERSION_CODE;
