/*
 * Copyright (c) 2018 Cumulus Networks. All rights reserved.
 * Copyright (c) 2018 David Ahern <dsa@cumulusnetworks.com>
 *
 * This software is licensed under the GNU General License Version 2,
 * June 1991 as shown in the file COPYING in the top-level directory of this
 * source tree.
 *
 * THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS"
 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
 * OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
 * THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
 */

#include <linux/device.h>
#include <net/devlink.h>
#include <net/netns/generic.h>

#include "netdevsim.h"

static unsigned int nsim_devlink_id;

/* place holder until devlink and namespaces is sorted out */
static struct net *nsim_devlink_net(struct devlink *devlink)
{
	return &init_net;
}

/* IPv4
 */
static u64 nsim_ipv4_fib_resource_occ_get(void *priv)
{
	struct net *net = priv;

	return nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB, false);
}

static u64 nsim_ipv4_fib_rules_res_occ_get(void *priv)
{
	struct net *net = priv;

	return nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB_RULES, false);
}

/* IPv6
 */
static u64 nsim_ipv6_fib_resource_occ_get(void *priv)
{
	struct net *net = priv;

	return nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB, false);
}

static u64 nsim_ipv6_fib_rules_res_occ_get(void *priv)
{
	struct net *net = priv;

	return nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB_RULES, false);
}

static int devlink_resources_register(struct devlink *devlink)
{
	struct devlink_resource_size_params params = {
		.size_max = (u64)-1,
		.size_granularity = 1,
		.unit = DEVLINK_RESOURCE_UNIT_ENTRY
	};
	struct net *net = nsim_devlink_net(devlink);
	int err;
	u64 n;

	/* Resources for IPv4 */
	err = devlink_resource_register(devlink, "IPv4", (u64)-1,
					NSIM_RESOURCE_IPV4,
					DEVLINK_RESOURCE_ID_PARENT_TOP,
					&params);
	if (err) {
		pr_err("Failed to register IPv4 top resource\n");
		goto out;
	}

	n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB, true);
	err = devlink_resource_register(devlink, "fib", n,
					NSIM_RESOURCE_IPV4_FIB,
					NSIM_RESOURCE_IPV4, &params);
	if (err) {
		pr_err("Failed to register IPv4 FIB resource\n");
		return err;
	}

	n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB_RULES, true);
	err = devlink_resource_register(devlink, "fib-rules", n,
					NSIM_RESOURCE_IPV4_FIB_RULES,
					NSIM_RESOURCE_IPV4, &params);
	if (err) {
		pr_err("Failed to register IPv4 FIB rules resource\n");
		return err;
	}

	/* Resources for IPv6 */
	err = devlink_resource_register(devlink, "IPv6", (u64)-1,
					NSIM_RESOURCE_IPV6,
					DEVLINK_RESOURCE_ID_PARENT_TOP,
					&params);
	if (err) {
		pr_err("Failed to register IPv6 top resource\n");
		goto out;
	}

	n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB, true);
	err = devlink_resource_register(devlink, "fib", n,
					NSIM_RESOURCE_IPV6_FIB,
					NSIM_RESOURCE_IPV6, &params);
	if (err) {
		pr_err("Failed to register IPv6 FIB resource\n");
		return err;
	}

	n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB_RULES, true);
	err = devlink_resource_register(devlink, "fib-rules", n,
					NSIM_RESOURCE_IPV6_FIB_RULES,
					NSIM_RESOURCE_IPV6, &params);
	if (err) {
		pr_err("Failed to register IPv6 FIB rules resource\n");
		return err;
	}

	devlink_resource_occ_get_register(devlink,
					  NSIM_RESOURCE_IPV4_FIB,
					  nsim_ipv4_fib_resource_occ_get,
					  net);
	devlink_resource_occ_get_register(devlink,
					  NSIM_RESOURCE_IPV4_FIB_RULES,
					  nsim_ipv4_fib_rules_res_occ_get,
					  net);
	devlink_resource_occ_get_register(devlink,
					  NSIM_RESOURCE_IPV6_FIB,
					  nsim_ipv6_fib_resource_occ_get,
					  net);
	devlink_resource_occ_get_register(devlink,
					  NSIM_RESOURCE_IPV6_FIB_RULES,
					  nsim_ipv6_fib_rules_res_occ_get,
					  net);
out:
	return err;
}

static int nsim_devlink_reload(struct devlink *devlink,
			       struct netlink_ext_ack *extack)
{
	enum nsim_resource_id res_ids[] = {
		NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4_FIB_RULES,
		NSIM_RESOURCE_IPV6_FIB, NSIM_RESOURCE_IPV6_FIB_RULES
	};
	struct net *net = nsim_devlink_net(devlink);
	int i;

	for (i = 0; i < ARRAY_SIZE(res_ids); ++i) {
		int err;
		u64 val;

		err = devlink_resource_size_get(devlink, res_ids[i], &val);
		if (!err) {
			err = nsim_fib_set_max(net, res_ids[i], val, extack);
			if (err)
				return err;
		}
	}

	return 0;
}

static void nsim_devlink_net_reset(struct net *net)
{
	enum nsim_resource_id res_ids[] = {
		NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4_FIB_RULES,
		NSIM_RESOURCE_IPV6_FIB, NSIM_RESOURCE_IPV6_FIB_RULES
	};
	int i;

	for (i = 0; i < ARRAY_SIZE(res_ids); ++i) {
		if (nsim_fib_set_max(net, res_ids[i], (u64)-1, NULL)) {
			pr_err("Failed to reset limit for resource %u\n",
			       res_ids[i]);
		}
	}
}

static const struct devlink_ops nsim_devlink_ops = {
	.reload = nsim_devlink_reload,
};

/* once devlink / namespace issues are sorted out
 * this needs to be net in which a devlink instance
 * is to be created. e.g., dev_net(ns->netdev)
 */
static struct net *nsim_to_net(struct netdevsim *ns)
{
	return &init_net;
}

void nsim_devlink_teardown(struct netdevsim *ns)
{
	if (ns->devlink) {
		struct net *net = nsim_to_net(ns);
		bool *reg_devlink = net_generic(net, nsim_devlink_id);

		devlink_resources_unregister(ns->devlink, NULL);
		devlink_unregister(ns->devlink);
		devlink_free(ns->devlink);
		ns->devlink = NULL;

		nsim_devlink_net_reset(net);
		*reg_devlink = true;
	}
}

int nsim_devlink_setup(struct netdevsim *ns)
{
	struct net *net = nsim_to_net(ns);
	bool *reg_devlink = net_generic(net, nsim_devlink_id);
	struct devlink *devlink;
	int err;

	/* only one device per namespace controls devlink */
	if (!*reg_devlink) {
		ns->devlink = NULL;
		return 0;
	}

	devlink = devlink_alloc(&nsim_devlink_ops, 0);
	if (!devlink)
		return -ENOMEM;

	err = devlink_register(devlink, &ns->dev);
	if (err)
		goto err_devlink_free;

	err = devlink_resources_register(devlink);
	if (err)
		goto err_dl_unregister;

	ns->devlink = devlink;

	*reg_devlink = false;

	return 0;

err_dl_unregister:
	devlink_unregister(devlink);
err_devlink_free:
	devlink_free(devlink);

	return err;
}

/* Initialize per network namespace state */
static int __net_init nsim_devlink_netns_init(struct net *net)
{
	bool *reg_devlink = net_generic(net, nsim_devlink_id);

	*reg_devlink = true;

	return 0;
}

static struct pernet_operations nsim_devlink_net_ops = {
	.init = nsim_devlink_netns_init,
	.id   = &nsim_devlink_id,
	.size = sizeof(bool),
};

void nsim_devlink_exit(void)
{
	unregister_pernet_subsys(&nsim_devlink_net_ops);
	nsim_fib_exit();
}

int nsim_devlink_init(void)
{
	int err;

	err = nsim_fib_init();
	if (err)
		goto err_out;

	err = register_pernet_subsys(&nsim_devlink_net_ops);
	if (err)
		nsim_fib_exit();

err_out:
	return err;
}
