// SPDX-License-Identifier: GPL-2.0
/* Toeplitz test
 *
 * 1. Read packets and their rx_hash using PF_PACKET/TPACKET_V3
 * 2. Compute the rx_hash in software based on the packet contents
 * 3. Compare the two
 *
 * Optionally, either '-C $rx_irq_cpu_list' or '-r $rps_bitmap' may be given.
 *
 * If '-C $rx_irq_cpu_list' is given, also
 *
 * 4. Identify the cpu on which the packet arrived with PACKET_FANOUT_CPU
 * 5. Compute the rxqueue that RSS would select based on this rx_hash
 * 6. Using the $rx_irq_cpu_list map, identify the arriving cpu based on rxq irq
 * 7. Compare the cpus from 4 and 6
 *
 * Else if '-r $rps_bitmap' is given, also
 *
 * 4. Identify the cpu on which the packet arrived with PACKET_FANOUT_CPU
 * 5. Compute the cpu that RPS should select based on rx_hash and $rps_bitmap
 * 6. Compare the cpus from 4 and 5
 */

#define _GNU_SOURCE

#include <arpa/inet.h>
#include <errno.h>
#include <error.h>
#include <fcntl.h>
#include <getopt.h>
#include <linux/filter.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <net/if.h>
#include <netdb.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <poll.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#include "../kselftest.h"

#define TOEPLITZ_KEY_MIN_LEN	40
#define TOEPLITZ_KEY_MAX_LEN	60

#define TOEPLITZ_STR_LEN(K)	(((K) * 3) - 1)	/* hex encoded: AA:BB:CC:...:ZZ */
#define TOEPLITZ_STR_MIN_LEN	TOEPLITZ_STR_LEN(TOEPLITZ_KEY_MIN_LEN)
#define TOEPLITZ_STR_MAX_LEN	TOEPLITZ_STR_LEN(TOEPLITZ_KEY_MAX_LEN)

#define FOUR_TUPLE_MAX_LEN	((sizeof(struct in6_addr) * 2) + (sizeof(uint16_t) * 2))

#define RSS_MAX_CPUS (1 << 16)	/* real constraint is PACKET_FANOUT_MAX */

#define RPS_MAX_CPUS 16UL	/* must be a power of 2 */

/* configuration options (cmdline arguments) */
static uint16_t cfg_dport =	8000;
static int cfg_family =		AF_INET6;
static char *cfg_ifname =	"eth0";
static int cfg_num_queues;
static int cfg_num_rps_cpus;
static bool cfg_sink;
static int cfg_type =		SOCK_STREAM;
static int cfg_timeout_msec =	1000;
static bool cfg_verbose;

/* global vars */
static int num_cpus;
static int ring_block_nr;
static int ring_block_sz;

/* stats */
static int frames_received;
static int frames_nohash;
static int frames_error;

#define log_verbose(args...)	do { if (cfg_verbose) fprintf(stderr, args); } while (0)

/* tpacket ring */
struct ring_state {
	int fd;
	char *mmap;
	int idx;
	int cpu;
};

static unsigned int rx_irq_cpus[RSS_MAX_CPUS];	/* map from rxq to cpu */
static int rps_silo_to_cpu[RPS_MAX_CPUS];
static unsigned char toeplitz_key[TOEPLITZ_KEY_MAX_LEN];
static struct ring_state rings[RSS_MAX_CPUS];

static inline uint32_t toeplitz(const unsigned char *four_tuple,
				const unsigned char *key)
{
	int i, bit, ret = 0;
	uint32_t key32;

	key32 = ntohl(*((uint32_t *)key));
	key += 4;

	for (i = 0; i < FOUR_TUPLE_MAX_LEN; i++) {
		for (bit = 7; bit >= 0; bit--) {
			if (four_tuple[i] & (1 << bit))
				ret ^= key32;

			key32 <<= 1;
			key32 |= !!(key[0] & (1 << bit));
		}
		key++;
	}

	return ret;
}

/* Compare computed cpu with arrival cpu from packet_fanout_cpu */
static void verify_rss(uint32_t rx_hash, int cpu)
{
	int queue = rx_hash % cfg_num_queues;

	log_verbose(" rxq %d (cpu %d)", queue, rx_irq_cpus[queue]);
	if (rx_irq_cpus[queue] != cpu) {
		log_verbose(". error: rss cpu mismatch (%d)", cpu);
		frames_error++;
	}
}

static void verify_rps(uint64_t rx_hash, int cpu)
{
	int silo = (rx_hash * cfg_num_rps_cpus) >> 32;

	log_verbose(" silo %d (cpu %d)", silo, rps_silo_to_cpu[silo]);
	if (rps_silo_to_cpu[silo] != cpu) {
		log_verbose(". error: rps cpu mismatch (%d)", cpu);
		frames_error++;
	}
}

static void log_rxhash(int cpu, uint32_t rx_hash,
		       const char *addrs, int addr_len)
{
	char saddr[INET6_ADDRSTRLEN], daddr[INET6_ADDRSTRLEN];
	uint16_t *ports;

	if (!inet_ntop(cfg_family, addrs, saddr, sizeof(saddr)) ||
	    !inet_ntop(cfg_family, addrs + addr_len, daddr, sizeof(daddr)))
		error(1, 0, "address parse error");

	ports = (void *)addrs + (addr_len * 2);
	log_verbose("cpu %d: rx_hash 0x%08x [saddr %s daddr %s sport %02hu dport %02hu]",
		    cpu, rx_hash, saddr, daddr,
		    ntohs(ports[0]), ntohs(ports[1]));
}

/* Compare computed rxhash with rxhash received from tpacket_v3 */
static void verify_rxhash(const char *pkt, uint32_t rx_hash, int cpu)
{
	unsigned char four_tuple[FOUR_TUPLE_MAX_LEN] = {0};
	uint32_t rx_hash_sw;
	const char *addrs;
	int addr_len;

	if (cfg_family == AF_INET) {
		addr_len = sizeof(struct in_addr);
		addrs = pkt + offsetof(struct iphdr, saddr);
	} else {
		addr_len = sizeof(struct in6_addr);
		addrs = pkt + offsetof(struct ip6_hdr, ip6_src);
	}

	memcpy(four_tuple, addrs, (addr_len * 2) + (sizeof(uint16_t) * 2));
	rx_hash_sw = toeplitz(four_tuple, toeplitz_key);

	if (cfg_verbose)
		log_rxhash(cpu, rx_hash, addrs, addr_len);

	if (rx_hash != rx_hash_sw) {
		log_verbose(" != expected 0x%x\n", rx_hash_sw);
		frames_error++;
		return;
	}

	log_verbose(" OK");
	if (cfg_num_queues)
		verify_rss(rx_hash, cpu);
	else if (cfg_num_rps_cpus)
		verify_rps(rx_hash, cpu);
	log_verbose("\n");
}

static char *recv_frame(const struct ring_state *ring, char *frame)
{
	struct tpacket3_hdr *hdr = (void *)frame;

	if (hdr->hv1.tp_rxhash)
		verify_rxhash(frame + hdr->tp_net, hdr->hv1.tp_rxhash,
			      ring->cpu);
	else
		frames_nohash++;

	return frame + hdr->tp_next_offset;
}

/* A single TPACKET_V3 block can hold multiple frames */
static bool recv_block(struct ring_state *ring)
{
	struct tpacket_block_desc *block;
	char *frame;
	int i;

	block = (void *)(ring->mmap + ring->idx * ring_block_sz);
	if (!(block->hdr.bh1.block_status & TP_STATUS_USER))
		return false;

	frame = (char *)block;
	frame += block->hdr.bh1.offset_to_first_pkt;

	for (i = 0; i < block->hdr.bh1.num_pkts; i++) {
		frame = recv_frame(ring, frame);
		frames_received++;
	}

	block->hdr.bh1.block_status = TP_STATUS_KERNEL;
	ring->idx = (ring->idx + 1) % ring_block_nr;

	return true;
}

/* simple test: sleep once unconditionally and then process all rings */
static void process_rings(void)
{
	int i;

	usleep(1000 * cfg_timeout_msec);

	for (i = 0; i < num_cpus; i++)
		do {} while (recv_block(&rings[i]));

	fprintf(stderr, "count: pass=%u nohash=%u fail=%u\n",
		frames_received - frames_nohash - frames_error,
		frames_nohash, frames_error);
}

static char *setup_ring(int fd)
{
	struct tpacket_req3 req3 = {0};
	void *ring;

	req3.tp_retire_blk_tov = cfg_timeout_msec / 8;
	req3.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH;

	req3.tp_frame_size = 2048;
	req3.tp_frame_nr = 1 << 10;
	req3.tp_block_nr = 16;

	req3.tp_block_size = req3.tp_frame_size * req3.tp_frame_nr;
	req3.tp_block_size /= req3.tp_block_nr;

	if (setsockopt(fd, SOL_PACKET, PACKET_RX_RING, &req3, sizeof(req3)))
		error(1, errno, "setsockopt PACKET_RX_RING");

	ring_block_sz = req3.tp_block_size;
	ring_block_nr = req3.tp_block_nr;

	ring = mmap(0, req3.tp_block_size * req3.tp_block_nr,
		    PROT_READ | PROT_WRITE,
		    MAP_SHARED | MAP_LOCKED | MAP_POPULATE, fd, 0);
	if (ring == MAP_FAILED)
		error(1, 0, "mmap failed");

	return ring;
}

static void __set_filter(int fd, int off_proto, uint8_t proto, int off_dport)
{
	struct sock_filter filter[] = {
		BPF_STMT(BPF_LD  + BPF_B   + BPF_ABS, SKF_AD_OFF + SKF_AD_PKTTYPE),
		BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, PACKET_HOST, 0, 4),
		BPF_STMT(BPF_LD  + BPF_B   + BPF_ABS, off_proto),
		BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, proto, 0, 2),
		BPF_STMT(BPF_LD  + BPF_H   + BPF_ABS, off_dport),
		BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, cfg_dport, 1, 0),
		BPF_STMT(BPF_RET + BPF_K, 0),
		BPF_STMT(BPF_RET + BPF_K, 0xFFFF),
	};
	struct sock_fprog prog = {};

	prog.filter = filter;
	prog.len = ARRAY_SIZE(filter);
	if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog)))
		error(1, errno, "setsockopt filter");
}

/* filter on transport protocol and destination port */
static void set_filter(int fd)
{
	const int off_dport = offsetof(struct tcphdr, dest);	/* same for udp */
	uint8_t proto;

	proto = cfg_type == SOCK_STREAM ? IPPROTO_TCP : IPPROTO_UDP;
	if (cfg_family == AF_INET)
		__set_filter(fd, offsetof(struct iphdr, protocol), proto,
			     sizeof(struct iphdr) + off_dport);
	else
		__set_filter(fd, offsetof(struct ip6_hdr, ip6_nxt), proto,
			     sizeof(struct ip6_hdr) + off_dport);
}

/* drop everything: used temporarily during setup */
static void set_filter_null(int fd)
{
	struct sock_filter filter[] = {
		BPF_STMT(BPF_RET + BPF_K, 0),
	};
	struct sock_fprog prog = {};

	prog.filter = filter;
	prog.len = ARRAY_SIZE(filter);
	if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog)))
		error(1, errno, "setsockopt filter");
}

static int create_ring(char **ring)
{
	struct fanout_args args = {
		.id = 1,
		.type_flags = PACKET_FANOUT_CPU,
		.max_num_members = RSS_MAX_CPUS
	};
	struct sockaddr_ll ll = { 0 };
	int fd, val;

	fd = socket(PF_PACKET, SOCK_DGRAM, 0);
	if (fd == -1)
		error(1, errno, "socket creation failed");

	val = TPACKET_V3;
	if (setsockopt(fd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val)))
		error(1, errno, "setsockopt PACKET_VERSION");
	*ring = setup_ring(fd);

	/* block packets until all rings are added to the fanout group:
	 * else packets can arrive during setup and get misclassified
	 */
	set_filter_null(fd);

	ll.sll_family = AF_PACKET;
	ll.sll_ifindex = if_nametoindex(cfg_ifname);
	ll.sll_protocol = cfg_family == AF_INET ? htons(ETH_P_IP) :
						  htons(ETH_P_IPV6);
	if (bind(fd, (void *)&ll, sizeof(ll)))
		error(1, errno, "bind");

	/* must come after bind: verifies all programs in group match */
	if (setsockopt(fd, SOL_PACKET, PACKET_FANOUT, &args, sizeof(args))) {
		/* on failure, retry using old API if that is sufficient:
		 * it has a hard limit of 256 sockets, so only try if
		 * (a) only testing rxhash, not RSS or (b) <= 256 cpus.
		 * in this API, the third argument is left implicit.
		 */
		if (cfg_num_queues || num_cpus > 256 ||
		    setsockopt(fd, SOL_PACKET, PACKET_FANOUT,
			       &args, sizeof(uint32_t)))
			error(1, errno, "setsockopt PACKET_FANOUT cpu");
	}

	return fd;
}

/* setup inet(6) socket to blackhole the test traffic, if arg '-s' */
static int setup_sink(void)
{
	int fd, val;

	fd = socket(cfg_family, cfg_type, 0);
	if (fd == -1)
		error(1, errno, "socket %d.%d", cfg_family, cfg_type);

	val = 1 << 20;
	if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &val, sizeof(val)))
		error(1, errno, "setsockopt rcvbuf");

	return fd;
}

static void setup_rings(void)
{
	int i;

	for (i = 0; i < num_cpus; i++) {
		rings[i].cpu = i;
		rings[i].fd = create_ring(&rings[i].mmap);
	}

	/* accept packets once all rings in the fanout group are up */
	for (i = 0; i < num_cpus; i++)
		set_filter(rings[i].fd);
}

static void cleanup_rings(void)
{
	int i;

	for (i = 0; i < num_cpus; i++) {
		if (munmap(rings[i].mmap, ring_block_nr * ring_block_sz))
			error(1, errno, "munmap");
		if (close(rings[i].fd))
			error(1, errno, "close");
	}
}

static void parse_cpulist(const char *arg)
{
	do {
		rx_irq_cpus[cfg_num_queues++] = strtol(arg, NULL, 10);

		arg = strchr(arg, ',');
		if (!arg)
			break;
		arg++;			// skip ','
	} while (1);
}

static void show_cpulist(void)
{
	int i;

	for (i = 0; i < cfg_num_queues; i++)
		fprintf(stderr, "rxq %d: cpu %d\n", i, rx_irq_cpus[i]);
}

static void show_silos(void)
{
	int i;

	for (i = 0; i < cfg_num_rps_cpus; i++)
		fprintf(stderr, "silo %d: cpu %d\n", i, rps_silo_to_cpu[i]);
}

static void parse_toeplitz_key(const char *str, int slen, unsigned char *key)
{
	int i, ret, off;

	if (slen < TOEPLITZ_STR_MIN_LEN ||
	    slen > TOEPLITZ_STR_MAX_LEN + 1)
		error(1, 0, "invalid toeplitz key");

	for (i = 0, off = 0; off < slen; i++, off += 3) {
		ret = sscanf(str + off, "%hhx", &key[i]);
		if (ret != 1)
			error(1, 0, "key parse error at %d off %d len %d",
			      i, off, slen);
	}
}

static void parse_rps_bitmap(const char *arg)
{
	unsigned long bitmap;
	int i;

	bitmap = strtoul(arg, NULL, 0);

	if (bitmap & ~(RPS_MAX_CPUS - 1))
		error(1, 0, "rps bitmap 0x%lx out of bounds 0..%lu",
		      bitmap, RPS_MAX_CPUS - 1);

	for (i = 0; i < RPS_MAX_CPUS; i++)
		if (bitmap & 1UL << i)
			rps_silo_to_cpu[cfg_num_rps_cpus++] = i;
}

static void parse_opts(int argc, char **argv)
{
	static struct option long_options[] = {
	    {"dport",	required_argument, 0, 'd'},
	    {"cpus",	required_argument, 0, 'C'},
	    {"key",	required_argument, 0, 'k'},
	    {"iface",	required_argument, 0, 'i'},
	    {"ipv4",	no_argument, 0, '4'},
	    {"ipv6",	no_argument, 0, '6'},
	    {"sink",	no_argument, 0, 's'},
	    {"tcp",	no_argument, 0, 't'},
	    {"timeout",	required_argument, 0, 'T'},
	    {"udp",	no_argument, 0, 'u'},
	    {"verbose",	no_argument, 0, 'v'},
	    {"rps",	required_argument, 0, 'r'},
	    {0, 0, 0, 0}
	};
	bool have_toeplitz = false;
	int index, c;

	while ((c = getopt_long(argc, argv, "46C:d:i:k:r:stT:uv", long_options, &index)) != -1) {
		switch (c) {
		case '4':
			cfg_family = AF_INET;
			break;
		case '6':
			cfg_family = AF_INET6;
			break;
		case 'C':
			parse_cpulist(optarg);
			break;
		case 'd':
			cfg_dport = strtol(optarg, NULL, 0);
			break;
		case 'i':
			cfg_ifname = optarg;
			break;
		case 'k':
			parse_toeplitz_key(optarg, strlen(optarg),
					   toeplitz_key);
			have_toeplitz = true;
			break;
		case 'r':
			parse_rps_bitmap(optarg);
			break;
		case 's':
			cfg_sink = true;
			break;
		case 't':
			cfg_type = SOCK_STREAM;
			break;
		case 'T':
			cfg_timeout_msec = strtol(optarg, NULL, 0);
			break;
		case 'u':
			cfg_type = SOCK_DGRAM;
			break;
		case 'v':
			cfg_verbose = true;
			break;

		default:
			error(1, 0, "unknown option %c", optopt);
			break;
		}
	}

	if (!have_toeplitz)
		error(1, 0, "Must supply rss key ('-k')");

	num_cpus = get_nprocs();
	if (num_cpus > RSS_MAX_CPUS)
		error(1, 0, "increase RSS_MAX_CPUS");

	if (cfg_num_queues && cfg_num_rps_cpus)
		error(1, 0,
		      "Can't supply both RSS cpus ('-C') and RPS map ('-r')");
	if (cfg_verbose) {
		show_cpulist();
		show_silos();
	}
}

int main(int argc, char **argv)
{
	const int min_tests = 10;
	int fd_sink = -1;

	parse_opts(argc, argv);

	if (cfg_sink)
		fd_sink = setup_sink();

	setup_rings();
	process_rings();
	cleanup_rings();

	if (cfg_sink && close(fd_sink))
		error(1, errno, "close sink");

	if (frames_received - frames_nohash < min_tests)
		error(1, 0, "too few frames for verification");

	return frames_error;
}
