// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2007-2020  B.A.T.M.A.N. contributors:
 *
 * Marek Lindner, Simon Wunderlich
 */

#include "main.h"

#include <linux/errno.h>
#include <linux/list.h>
#include <linux/moduleparam.h>
#include <linux/netlink.h>
#include <linux/printk.h>
#include <linux/skbuff.h>
#include <linux/stddef.h>
#include <linux/string.h>
#include <net/genetlink.h>
#include <net/netlink.h>
#include <uapi/linux/batman_adv.h>

#include "bat_algo.h"
#include "netlink.h"

char batadv_routing_algo[20] = "BATMAN_IV";
static struct hlist_head batadv_algo_list;

/**
 * batadv_algo_init() - Initialize batman-adv algorithm management data
 *  structures
 */
void batadv_algo_init(void)
{
	INIT_HLIST_HEAD(&batadv_algo_list);
}

/**
 * batadv_algo_get() - Search for algorithm with specific name
 * @name: algorithm name to find
 *
 * Return: Pointer to batadv_algo_ops on success, NULL otherwise
 */
struct batadv_algo_ops *batadv_algo_get(const char *name)
{
	struct batadv_algo_ops *bat_algo_ops = NULL, *bat_algo_ops_tmp;

	hlist_for_each_entry(bat_algo_ops_tmp, &batadv_algo_list, list) {
		if (strcmp(bat_algo_ops_tmp->name, name) != 0)
			continue;

		bat_algo_ops = bat_algo_ops_tmp;
		break;
	}

	return bat_algo_ops;
}

/**
 * batadv_algo_register() - Register callbacks for a mesh algorithm
 * @bat_algo_ops: mesh algorithm callbacks to add
 *
 * Return: 0 on success or negative error number in case of failure
 */
int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops)
{
	struct batadv_algo_ops *bat_algo_ops_tmp;

	bat_algo_ops_tmp = batadv_algo_get(bat_algo_ops->name);
	if (bat_algo_ops_tmp) {
		pr_info("Trying to register already registered routing algorithm: %s\n",
			bat_algo_ops->name);
		return -EEXIST;
	}

	/* all algorithms must implement all ops (for now) */
	if (!bat_algo_ops->iface.enable ||
	    !bat_algo_ops->iface.disable ||
	    !bat_algo_ops->iface.update_mac ||
	    !bat_algo_ops->iface.primary_set ||
	    !bat_algo_ops->neigh.cmp ||
	    !bat_algo_ops->neigh.is_similar_or_better) {
		pr_info("Routing algo '%s' does not implement required ops\n",
			bat_algo_ops->name);
		return -EINVAL;
	}

	INIT_HLIST_NODE(&bat_algo_ops->list);
	hlist_add_head(&bat_algo_ops->list, &batadv_algo_list);

	return 0;
}

/**
 * batadv_algo_select() - Select algorithm of soft interface
 * @bat_priv: the bat priv with all the soft interface information
 * @name: name of the algorithm to select
 *
 * The algorithm callbacks for the soft interface will be set when the algorithm
 * with the correct name was found. Any previous selected algorithm will not be
 * deinitialized and the new selected algorithm will also not be initialized.
 * It is therefore not allowed to call batadv_algo_select outside the creation
 * function of the soft interface.
 *
 * Return: 0 on success or negative error number in case of failure
 */
int batadv_algo_select(struct batadv_priv *bat_priv, const char *name)
{
	struct batadv_algo_ops *bat_algo_ops;

	bat_algo_ops = batadv_algo_get(name);
	if (!bat_algo_ops)
		return -EINVAL;

	bat_priv->algo_ops = bat_algo_ops;

	return 0;
}

static int batadv_param_set_ra(const char *val, const struct kernel_param *kp)
{
	struct batadv_algo_ops *bat_algo_ops;
	char *algo_name = (char *)val;
	size_t name_len = strlen(algo_name);

	if (name_len > 0 && algo_name[name_len - 1] == '\n')
		algo_name[name_len - 1] = '\0';

	bat_algo_ops = batadv_algo_get(algo_name);
	if (!bat_algo_ops) {
		pr_err("Routing algorithm '%s' is not supported\n", algo_name);
		return -EINVAL;
	}

	return param_set_copystring(algo_name, kp);
}

static const struct kernel_param_ops batadv_param_ops_ra = {
	.set = batadv_param_set_ra,
	.get = param_get_string,
};

static struct kparam_string batadv_param_string_ra = {
	.maxlen = sizeof(batadv_routing_algo),
	.string = batadv_routing_algo,
};

module_param_cb(routing_algo, &batadv_param_ops_ra, &batadv_param_string_ra,
		0644);

/**
 * batadv_algo_dump_entry() - fill in information about one supported routing
 *  algorithm
 * @msg: netlink message to be sent back
 * @portid: Port to reply to
 * @seq: Sequence number of message
 * @bat_algo_ops: Algorithm to be dumped
 *
 * Return: Error number, or 0 on success
 */
static int batadv_algo_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
				  struct batadv_algo_ops *bat_algo_ops)
{
	void *hdr;

	hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
			  NLM_F_MULTI, BATADV_CMD_GET_ROUTING_ALGOS);
	if (!hdr)
		return -EMSGSIZE;

	if (nla_put_string(msg, BATADV_ATTR_ALGO_NAME, bat_algo_ops->name))
		goto nla_put_failure;

	genlmsg_end(msg, hdr);
	return 0;

 nla_put_failure:
	genlmsg_cancel(msg, hdr);
	return -EMSGSIZE;
}

/**
 * batadv_algo_dump() - fill in information about supported routing
 *  algorithms
 * @msg: netlink message to be sent back
 * @cb: Parameters to the netlink request
 *
 * Return: Length of reply message.
 */
int batadv_algo_dump(struct sk_buff *msg, struct netlink_callback *cb)
{
	int portid = NETLINK_CB(cb->skb).portid;
	struct batadv_algo_ops *bat_algo_ops;
	int skip = cb->args[0];
	int i = 0;

	hlist_for_each_entry(bat_algo_ops, &batadv_algo_list, list) {
		if (i++ < skip)
			continue;

		if (batadv_algo_dump_entry(msg, portid, cb->nlh->nlmsg_seq,
					   bat_algo_ops)) {
			i--;
			break;
		}
	}

	cb->args[0] = i;

	return msg->len;
}
