/*
 *     MPTCP implementation - MPTCP-subflow-management
 *
 *     Initial Design & Implementation:
 *     Sébastien Barré <sebastien.barre@uclouvain.be>
 *
 *     Current Maintainer & Author:
 *     Christoph Paasch <christoph.paasch@uclouvain.be>
 *
 *     Additional authors:
 *     Jaakko Korkeaniemi <jaakko.korkeaniemi@aalto.fi>
 *     Gregory Detal <gregory.detal@uclouvain.be>
 *     Fabien Duchêne <fabien.duchene@uclouvain.be>
 *     Andreas Seelinger <Andreas.Seelinger@rwth-aachen.de>
 *     Lavkesh Lahngir <lavkesh51@gmail.com>
 *     Andreas Ripke <ripke@neclab.eu>
 *     Vlad Dogaru <vlad.dogaru@intel.com>
 *     Octavian Purdila <octavian.purdila@intel.com>
 *     John Ronan <jronan@tssg.org>
 *     Catalin Nicutar <catalin.nicutar@gmail.com>
 *     Brandon Heller <brandonh@stanford.edu>
 *
 *
 *     This program is free software; you can redistribute it and/or
 *      modify it under the terms of the GNU General Public License
 *      as published by the Free Software Foundation; either version
 *      2 of the License, or (at your option) any later version.
 */


#include <linux/module.h>
#include <net/mptcp.h>

static DEFINE_SPINLOCK(mptcp_pm_list_lock);
static LIST_HEAD(mptcp_pm_list);

static int mptcp_default_id(sa_family_t family, union inet_addr *addr,
			    struct net *net, bool *low_prio)
{
	return 0;
}

struct mptcp_pm_ops mptcp_pm_default = {
	.get_local_id = mptcp_default_id, /* We do not care */
	.name = "default",
	.owner = THIS_MODULE,
};

static struct mptcp_pm_ops *mptcp_pm_find(const char *name)
{
	struct mptcp_pm_ops *e;

	list_for_each_entry_rcu(e, &mptcp_pm_list, list) {
		if (strcmp(e->name, name) == 0)
			return e;
	}

	return NULL;
}

int mptcp_register_path_manager(struct mptcp_pm_ops *pm)
{
	int ret = 0;

	if (!pm->get_local_id)
		return -EINVAL;

	spin_lock(&mptcp_pm_list_lock);
	if (mptcp_pm_find(pm->name)) {
		pr_notice("%s already registered\n", pm->name);
		ret = -EEXIST;
	} else {
		list_add_tail_rcu(&pm->list, &mptcp_pm_list);
		pr_info("%s registered\n", pm->name);
	}
	spin_unlock(&mptcp_pm_list_lock);

	return ret;
}
EXPORT_SYMBOL_GPL(mptcp_register_path_manager);

void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm)
{
	spin_lock(&mptcp_pm_list_lock);
	list_del_rcu(&pm->list);
	spin_unlock(&mptcp_pm_list_lock);

	/* Wait for outstanding readers to complete before the
	 * module gets removed entirely.
	 *
	 * A try_module_get() should fail by now as our module is
	 * in "going" state since no refs are held anymore and
	 * module_exit() handler being called.
	 */
	synchronize_rcu();
}
EXPORT_SYMBOL_GPL(mptcp_unregister_path_manager);

void mptcp_get_default_path_manager(char *name)
{
	struct mptcp_pm_ops *pm;

	BUG_ON(list_empty(&mptcp_pm_list));

	rcu_read_lock();
	pm = list_entry(mptcp_pm_list.next, struct mptcp_pm_ops, list);
	strncpy(name, pm->name, MPTCP_PM_NAME_MAX);
	rcu_read_unlock();
}

int mptcp_set_default_path_manager(const char *name)
{
	struct mptcp_pm_ops *pm;
	int ret = -ENOENT;

	spin_lock(&mptcp_pm_list_lock);
	pm = mptcp_pm_find(name);
#ifdef CONFIG_MODULES
	if (!pm && capable(CAP_NET_ADMIN)) {
		spin_unlock(&mptcp_pm_list_lock);

		request_module("mptcp_%s", name);
		spin_lock(&mptcp_pm_list_lock);
		pm = mptcp_pm_find(name);
	}
#endif

	if (pm) {
		list_move(&pm->list, &mptcp_pm_list);
		ret = 0;
	} else {
		pr_info("%s is not available\n", name);
	}
	spin_unlock(&mptcp_pm_list_lock);

	return ret;
}

static struct mptcp_pm_ops *__mptcp_pm_find_autoload(const char *name)
{
	struct mptcp_pm_ops *pm = mptcp_pm_find(name);
#ifdef CONFIG_MODULES
	if (!pm && capable(CAP_NET_ADMIN)) {
		rcu_read_unlock();
		request_module("mptcp_%s", name);
		rcu_read_lock();
		pm = mptcp_pm_find(name);
	}
#endif
	return pm;
}

void mptcp_init_path_manager(struct mptcp_cb *mpcb)
{
	struct mptcp_pm_ops *pm;
	struct sock *meta_sk = mpcb->meta_sk;
	struct tcp_sock *meta_tp = tcp_sk(meta_sk);

	rcu_read_lock();
	/* if path manager was set using socket option */
	if (meta_tp->mptcp_pm_setsockopt) {
		pm = __mptcp_pm_find_autoload(meta_tp->mptcp_pm_name);
		if (pm && try_module_get(pm->owner)) {
			mpcb->pm_ops = pm;
			goto out;
		}
	}

	list_for_each_entry_rcu(pm, &mptcp_pm_list, list) {
		if (try_module_get(pm->owner)) {
			mpcb->pm_ops = pm;
			break;
		}
	}
out:
	rcu_read_unlock();
}

/* Change path manager for socket */
int mptcp_set_path_manager(struct sock *sk, const char *name)
{
	struct mptcp_pm_ops *pm;
	int err = 0;

	rcu_read_lock();
	pm = __mptcp_pm_find_autoload(name);

	if (!pm) {
		err = -ENOENT;
	} else if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
		err = -EPERM;
	} else {
		strcpy(tcp_sk(sk)->mptcp_pm_name, name);
		tcp_sk(sk)->mptcp_pm_setsockopt = 1;
	}
	rcu_read_unlock();

	return err;
}

/* Manage refcounts on socket close. */
void mptcp_cleanup_path_manager(struct mptcp_cb *mpcb)
{
	module_put(mpcb->pm_ops->owner);
}

/* Fallback to the default path-manager. */
void mptcp_fallback_default(struct mptcp_cb *mpcb)
{
	struct mptcp_pm_ops *pm;

	mptcp_cleanup_path_manager(mpcb);
	pm = mptcp_pm_find("default");

	/* Cannot fail - it's the default module */
	try_module_get(pm->owner);
	mpcb->pm_ops = pm;
}
EXPORT_SYMBOL_GPL(mptcp_fallback_default);

/* Set default value from kernel configuration at bootup */
static int __init mptcp_path_manager_default(void)
{
	return mptcp_set_default_path_manager("fullmesh");
}
late_initcall(mptcp_path_manager_default);
