// SPDX-License-Identifier: GPL-2.0-or-later
/* Address preferences management
 *
 * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": addr_prefs: " fmt
#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/inet.h>
#include <linux/seq_file.h>
#include <keys/rxrpc-type.h>
#include "internal.h"

static inline struct afs_net *afs_seq2net_single(struct seq_file *m)
{
	return afs_net(seq_file_single_net(m));
}

/*
 * Split a NUL-terminated string up to the first newline around spaces.  The
 * source string will be modified to have NUL-terminations inserted.
 */
static int afs_split_string(char **pbuf, char *strv[], unsigned int maxstrv)
{
	unsigned int count = 0;
	char *p = *pbuf;

	maxstrv--; /* Allow for terminal NULL */
	for (;;) {
		/* Skip over spaces */
		while (isspace(*p)) {
			if (*p == '\n') {
				p++;
				break;
			}
			p++;
		}
		if (!*p)
			break;

		/* Mark start of word */
		if (count >= maxstrv) {
			pr_warn("Too many elements in string\n");
			return -EINVAL;
		}
		strv[count++] = p;

		/* Skip over word */
		while (!isspace(*p))
			p++;
		if (!*p)
			break;

		/* Mark end of word */
		if (*p == '\n') {
			*p++ = 0;
			break;
		}
		*p++ = 0;
	}

	*pbuf = p;
	strv[count] = NULL;
	return count;
}

/*
 * Parse an address with an optional subnet mask.
 */
static int afs_parse_address(char *p, struct afs_addr_preference *pref)
{
	const char *stop;
	unsigned long mask, tmp;
	char *end = p + strlen(p);
	bool bracket = false;

	if (*p == '[') {
		p++;
		bracket = true;
	}

#if 0
	if (*p == '[') {
		p++;
		q = memchr(p, ']', end - p);
		if (!q) {
			pr_warn("Can't find closing ']'\n");
			return -EINVAL;
		}
	} else {
		for (q = p; q < end; q++)
			if (*q == '/')
				break;
	}
#endif

	if (in4_pton(p, end - p, (u8 *)&pref->ipv4_addr, -1, &stop)) {
		pref->family = AF_INET;
		mask = 32;
	} else if (in6_pton(p, end - p, (u8 *)&pref->ipv6_addr, -1, &stop)) {
		pref->family = AF_INET6;
		mask = 128;
	} else {
		pr_warn("Can't determine address family\n");
		return -EINVAL;
	}

	p = (char *)stop;
	if (bracket) {
		if (*p != ']') {
			pr_warn("Can't find closing ']'\n");
			return -EINVAL;
		}
		p++;
	}

	if (*p == '/') {
		p++;
		tmp = simple_strtoul(p, &p, 10);
		if (tmp > mask) {
			pr_warn("Subnet mask too large\n");
			return -EINVAL;
		}
		if (tmp == 0) {
			pr_warn("Subnet mask too small\n");
			return -EINVAL;
		}
		mask = tmp;
	}

	if (*p) {
		pr_warn("Invalid address\n");
		return -EINVAL;
	}

	pref->subnet_mask = mask;
	return 0;
}

enum cmp_ret {
	CONTINUE_SEARCH,
	INSERT_HERE,
	EXACT_MATCH,
	SUBNET_MATCH,
};

/*
 * See if a candidate address matches a listed address.
 */
static enum cmp_ret afs_cmp_address_pref(const struct afs_addr_preference *a,
					 const struct afs_addr_preference *b)
{
	int subnet = min(a->subnet_mask, b->subnet_mask);
	const __be32 *pa, *pb;
	u32 mask, na, nb;
	int diff;

	if (a->family != b->family)
		return INSERT_HERE;

	switch (a->family) {
	case AF_INET6:
		pa = a->ipv6_addr.s6_addr32;
		pb = b->ipv6_addr.s6_addr32;
		break;
	case AF_INET:
		pa = &a->ipv4_addr.s_addr;
		pb = &b->ipv4_addr.s_addr;
		break;
	}

	while (subnet > 32) {
		diff = ntohl(*pa++) - ntohl(*pb++);
		if (diff < 0)
			return INSERT_HERE; /* a<b */
		if (diff > 0)
			return CONTINUE_SEARCH; /* a>b */
		subnet -= 32;
	}

	if (subnet == 0)
		return EXACT_MATCH;

	mask = 0xffffffffU << (32 - subnet);
	na = ntohl(*pa);
	nb = ntohl(*pb);
	diff = (na & mask) - (nb & mask);
	//kdebug("diff %08x %08x %08x %d", na, nb, mask, diff);
	if (diff < 0)
		return INSERT_HERE; /* a<b */
	if (diff > 0)
		return CONTINUE_SEARCH; /* a>b */
	if (a->subnet_mask == b->subnet_mask)
		return EXACT_MATCH;
	if (a->subnet_mask > b->subnet_mask)
		return SUBNET_MATCH; /* a binds tighter than b */
	return CONTINUE_SEARCH; /* b binds tighter than a */
}

/*
 * Insert an address preference.
 */
static int afs_insert_address_pref(struct afs_addr_preference_list **_preflist,
				   struct afs_addr_preference *pref,
				   int index)
{
	struct afs_addr_preference_list *preflist = *_preflist, *old = preflist;
	size_t size, max_prefs;

	_enter("{%u/%u/%u},%u", preflist->ipv6_off, preflist->nr, preflist->max_prefs, index);

	if (preflist->nr == 255)
		return -ENOSPC;
	if (preflist->nr >= preflist->max_prefs) {
		max_prefs = preflist->max_prefs + 1;
		size = struct_size(preflist, prefs, max_prefs);
		size = roundup_pow_of_two(size);
		max_prefs = min_t(size_t, (size - sizeof(*preflist)) / sizeof(*pref), 255);
		preflist = kmalloc(size, GFP_KERNEL);
		if (!preflist)
			return -ENOMEM;
		*preflist = **_preflist;
		preflist->max_prefs = max_prefs;
		*_preflist = preflist;

		if (index < preflist->nr)
			memcpy(preflist->prefs + index + 1, old->prefs + index,
			       sizeof(*pref) * (preflist->nr - index));
		if (index > 0)
			memcpy(preflist->prefs, old->prefs, sizeof(*pref) * index);
	} else {
		if (index < preflist->nr)
			memmove(preflist->prefs + index + 1, preflist->prefs + index,
			       sizeof(*pref) * (preflist->nr - index));
	}

	preflist->prefs[index] = *pref;
	preflist->nr++;
	if (pref->family == AF_INET)
		preflist->ipv6_off++;
	return 0;
}

/*
 * Add an address preference.
 *	echo "add <proto> <IP>[/<mask>] <prior>" >/proc/fs/afs/addr_prefs
 */
static int afs_add_address_pref(struct afs_net *net, struct afs_addr_preference_list **_preflist,
				int argc, char **argv)
{
	struct afs_addr_preference_list *preflist = *_preflist;
	struct afs_addr_preference pref;
	enum cmp_ret cmp;
	int ret, i, stop;

	if (argc != 3) {
		pr_warn("Wrong number of params\n");
		return -EINVAL;
	}

	if (strcmp(argv[0], "udp") != 0) {
		pr_warn("Unsupported protocol\n");
		return -EINVAL;
	}

	ret = afs_parse_address(argv[1], &pref);
	if (ret < 0)
		return ret;

	ret = kstrtou16(argv[2], 10, &pref.prio);
	if (ret < 0) {
		pr_warn("Invalid priority\n");
		return ret;
	}

	if (pref.family == AF_INET) {
		i = 0;
		stop = preflist->ipv6_off;
	} else {
		i = preflist->ipv6_off;
		stop = preflist->nr;
	}

	for (; i < stop; i++) {
		cmp = afs_cmp_address_pref(&pref, &preflist->prefs[i]);
		switch (cmp) {
		case CONTINUE_SEARCH:
			continue;
		case INSERT_HERE:
		case SUBNET_MATCH:
			return afs_insert_address_pref(_preflist, &pref, i);
		case EXACT_MATCH:
			preflist->prefs[i].prio = pref.prio;
			return 0;
		}
	}

	return afs_insert_address_pref(_preflist, &pref, i);
}

/*
 * Delete an address preference.
 */
static int afs_delete_address_pref(struct afs_addr_preference_list **_preflist,
				   int index)
{
	struct afs_addr_preference_list *preflist = *_preflist;

	_enter("{%u/%u/%u},%u", preflist->ipv6_off, preflist->nr, preflist->max_prefs, index);

	if (preflist->nr == 0)
		return -ENOENT;

	if (index < preflist->nr - 1)
		memmove(preflist->prefs + index, preflist->prefs + index + 1,
			sizeof(preflist->prefs[0]) * (preflist->nr - index - 1));

	if (index < preflist->ipv6_off)
		preflist->ipv6_off--;
	preflist->nr--;
	return 0;
}

/*
 * Delete an address preference.
 *	echo "del <proto> <IP>[/<mask>]" >/proc/fs/afs/addr_prefs
 */
static int afs_del_address_pref(struct afs_net *net, struct afs_addr_preference_list **_preflist,
				int argc, char **argv)
{
	struct afs_addr_preference_list *preflist = *_preflist;
	struct afs_addr_preference pref;
	enum cmp_ret cmp;
	int ret, i, stop;

	if (argc != 2) {
		pr_warn("Wrong number of params\n");
		return -EINVAL;
	}

	if (strcmp(argv[0], "udp") != 0) {
		pr_warn("Unsupported protocol\n");
		return -EINVAL;
	}

	ret = afs_parse_address(argv[1], &pref);
	if (ret < 0)
		return ret;

	if (pref.family == AF_INET) {
		i = 0;
		stop = preflist->ipv6_off;
	} else {
		i = preflist->ipv6_off;
		stop = preflist->nr;
	}

	for (; i < stop; i++) {
		cmp = afs_cmp_address_pref(&pref, &preflist->prefs[i]);
		switch (cmp) {
		case CONTINUE_SEARCH:
			continue;
		case INSERT_HERE:
		case SUBNET_MATCH:
			return 0;
		case EXACT_MATCH:
			return afs_delete_address_pref(_preflist, i);
		}
	}

	return -ENOANO;
}

/*
 * Handle writes to /proc/fs/afs/addr_prefs
 */
int afs_proc_addr_prefs_write(struct file *file, char *buf, size_t size)
{
	struct afs_addr_preference_list *preflist, *old;
	struct seq_file *m = file->private_data;
	struct afs_net *net = afs_seq2net_single(m);
	size_t psize;
	char *argv[5];
	int ret, argc, max_prefs;

	inode_lock(file_inode(file));

	/* Allocate a candidate new list and initialise it from the old. */
	old = rcu_dereference_protected(net->address_prefs,
					lockdep_is_held(&file_inode(file)->i_rwsem));

	if (old)
		max_prefs = old->nr + 1;
	else
		max_prefs = 1;

	psize = struct_size(old, prefs, max_prefs);
	psize = roundup_pow_of_two(psize);
	max_prefs = min_t(size_t, (psize - sizeof(*old)) / sizeof(old->prefs[0]), 255);

	ret = -ENOMEM;
	preflist = kmalloc(struct_size(preflist, prefs, max_prefs), GFP_KERNEL);
	if (!preflist)
		goto done;

	if (old)
		memcpy(preflist, old, struct_size(preflist, prefs, old->nr));
	else
		memset(preflist, 0, sizeof(*preflist));
	preflist->max_prefs = max_prefs;

	do {
		argc = afs_split_string(&buf, argv, ARRAY_SIZE(argv));
		if (argc < 0) {
			ret = argc;
			goto done;
		}
		if (argc < 2)
			goto inval;

		if (strcmp(argv[0], "add") == 0)
			ret = afs_add_address_pref(net, &preflist, argc - 1, argv + 1);
		else if (strcmp(argv[0], "del") == 0)
			ret = afs_del_address_pref(net, &preflist, argc - 1, argv + 1);
		else
			goto inval;
		if (ret < 0)
			goto done;
	} while (*buf);

	preflist->version++;
	rcu_assign_pointer(net->address_prefs, preflist);
	/* Store prefs before version */
	smp_store_release(&net->address_pref_version, preflist->version);
	kfree_rcu(old, rcu);
	preflist = NULL;
	ret = 0;

done:
	kfree(preflist);
	inode_unlock(file_inode(file));
	_leave(" = %d", ret);
	return ret;

inval:
	pr_warn("Invalid Command\n");
	ret = -EINVAL;
	goto done;
}

/*
 * Mark the priorities on an address list if the address preferences table has
 * changed.  The caller must hold the RCU read lock.
 */
void afs_get_address_preferences_rcu(struct afs_net *net, struct afs_addr_list *alist)
{
	const struct afs_addr_preference_list *preflist =
		rcu_dereference(net->address_prefs);
	const struct sockaddr_in6 *sin6;
	const struct sockaddr_in *sin;
	const struct sockaddr *sa;
	struct afs_addr_preference test;
	enum cmp_ret cmp;
	int i, j;

	if (!preflist || !preflist->nr || !alist->nr_addrs ||
	    smp_load_acquire(&alist->addr_pref_version) == preflist->version)
		return;

	test.family = AF_INET;
	test.subnet_mask = 32;
	test.prio = 0;
	for (i = 0; i < alist->nr_ipv4; i++) {
		sa = rxrpc_kernel_remote_addr(alist->addrs[i].peer);
		sin = (const struct sockaddr_in *)sa;
		test.ipv4_addr = sin->sin_addr;
		for (j = 0; j < preflist->ipv6_off; j++) {
			cmp = afs_cmp_address_pref(&test, &preflist->prefs[j]);
			switch (cmp) {
			case CONTINUE_SEARCH:
				continue;
			case INSERT_HERE:
				break;
			case EXACT_MATCH:
			case SUBNET_MATCH:
				WRITE_ONCE(alist->addrs[i].prio, preflist->prefs[j].prio);
				break;
			}
		}
	}

	test.family = AF_INET6;
	test.subnet_mask = 128;
	test.prio = 0;
	for (; i < alist->nr_addrs; i++) {
		sa = rxrpc_kernel_remote_addr(alist->addrs[i].peer);
		sin6 = (const struct sockaddr_in6 *)sa;
		test.ipv6_addr = sin6->sin6_addr;
		for (j = preflist->ipv6_off; j < preflist->nr; j++) {
			cmp = afs_cmp_address_pref(&test, &preflist->prefs[j]);
			switch (cmp) {
			case CONTINUE_SEARCH:
				continue;
			case INSERT_HERE:
				break;
			case EXACT_MATCH:
			case SUBNET_MATCH:
				WRITE_ONCE(alist->addrs[i].prio, preflist->prefs[j].prio);
				break;
			}
		}
	}

	smp_store_release(&alist->addr_pref_version, preflist->version);
}

/*
 * Mark the priorities on an address list if the address preferences table has
 * changed.  Avoid taking the RCU read lock if we can.
 */
void afs_get_address_preferences(struct afs_net *net, struct afs_addr_list *alist)
{
	if (!net->address_prefs ||
	    /* Load version before prefs */
	    smp_load_acquire(&net->address_pref_version) == alist->addr_pref_version)
		return;

	rcu_read_lock();
	afs_get_address_preferences_rcu(net, alist);
	rcu_read_unlock();
}
