/*
 * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
 * All rights reserved.
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/kernel.h>
#include <linux/connector.h>
#include <linux/crypto.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/string.h>
#include <linux/in.h>
#include <linux/slab.h>

#include "netfs.h"

/*
 * Global configuration list.
 * Each client can be asked to get one of them.
 *
 * Allows to provide remote server address (ipv4/v6/whatever), port
 * and so on via kernel connector.
 */

static struct cb_id pohmelfs_cn_id = {.idx = POHMELFS_CN_IDX, .val = POHMELFS_CN_VAL};
static LIST_HEAD(pohmelfs_config_list);
static DEFINE_MUTEX(pohmelfs_config_lock);

static inline int pohmelfs_config_eql(struct pohmelfs_ctl *sc, struct pohmelfs_ctl *ctl)
{
	if (sc->idx == ctl->idx && sc->type == ctl->type &&
			sc->proto == ctl->proto &&
			sc->addrlen == ctl->addrlen &&
			!memcmp(&sc->addr, &ctl->addr, ctl->addrlen))
		return 1;

	return 0;
}

static struct pohmelfs_config_group *pohmelfs_find_config_group(unsigned int idx)
{
	struct pohmelfs_config_group *g, *group = NULL;

	list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
		if (g->idx == idx) {
			group = g;
			break;
		}
	}

	return group;
}

static struct pohmelfs_config_group *pohmelfs_find_create_config_group(unsigned int idx)
{
	struct pohmelfs_config_group *g;

	g = pohmelfs_find_config_group(idx);
	if (g)
		return g;

	g = kzalloc(sizeof(struct pohmelfs_config_group), GFP_KERNEL);
	if (!g)
		return NULL;

	INIT_LIST_HEAD(&g->config_list);
	g->idx = idx;
	g->num_entry = 0;

	list_add_tail(&g->group_entry, &pohmelfs_config_list);

	return g;
}

static inline void pohmelfs_insert_config_entry(struct pohmelfs_sb *psb, struct pohmelfs_config *dst)
{
	struct pohmelfs_config *tmp;

	INIT_LIST_HEAD(&dst->config_entry);

	list_for_each_entry(tmp, &psb->state_list, config_entry) {
		if (dst->state.ctl.prio > tmp->state.ctl.prio)
			list_add_tail(&dst->config_entry, &tmp->config_entry);
	}
	if (list_empty(&dst->config_entry))
		list_add_tail(&dst->config_entry, &psb->state_list);
}

static int pohmelfs_move_config_entry(struct pohmelfs_sb *psb,
		struct pohmelfs_config *dst, struct pohmelfs_config *new)
{
	if ((dst->state.ctl.prio == new->state.ctl.prio) &&
		(dst->state.ctl.perm == new->state.ctl.perm))
		return 0;

	dprintk("%s: dst: prio: %d, perm: %x, new: prio: %d, perm: %d.\n",
			__func__, dst->state.ctl.prio, dst->state.ctl.perm,
			new->state.ctl.prio, new->state.ctl.perm);
	dst->state.ctl.prio = new->state.ctl.prio;
	dst->state.ctl.perm = new->state.ctl.perm;

	list_del_init(&dst->config_entry);
	pohmelfs_insert_config_entry(psb, dst);
	return 0;
}

/*
 * pohmelfs_copy_config() is used to copy new state configs from the
 * config group (controlled by the netlink messages) into the superblock.
 * This happens either at startup time where no transactions can access
 * the list of the configs (and thus list of the network states), or at
 * run-time, where it is protected by the psb->state_lock.
 */
int pohmelfs_copy_config(struct pohmelfs_sb *psb)
{
	struct pohmelfs_config_group *g;
	struct pohmelfs_config *c, *dst;
	int err = -ENODEV;

	mutex_lock(&pohmelfs_config_lock);

	g = pohmelfs_find_config_group(psb->idx);
	if (!g)
		goto out_unlock;

	/*
	 * Run over all entries in given config group and try to crate and
	 * initialize those, which do not exist in superblock list.
	 * Skip all existing entries.
	 */

	list_for_each_entry(c, &g->config_list, config_entry) {
		err = 0;
		list_for_each_entry(dst, &psb->state_list, config_entry) {
			if (pohmelfs_config_eql(&dst->state.ctl, &c->state.ctl)) {
				err = pohmelfs_move_config_entry(psb, dst, c);
				if (!err)
					err = -EEXIST;
				break;
			}
		}

		if (err)
			continue;

		dst = kzalloc(sizeof(struct pohmelfs_config), GFP_KERNEL);
		if (!dst) {
			err = -ENOMEM;
			break;
		}

		memcpy(&dst->state.ctl, &c->state.ctl, sizeof(struct pohmelfs_ctl));

		pohmelfs_insert_config_entry(psb, dst);

		err = pohmelfs_state_init_one(psb, dst);
		if (err) {
			list_del(&dst->config_entry);
			kfree(dst);
		}

		err = 0;
	}

out_unlock:
	mutex_unlock(&pohmelfs_config_lock);

	return err;
}

int pohmelfs_copy_crypto(struct pohmelfs_sb *psb)
{
	struct pohmelfs_config_group *g;
	int err = -ENOENT;

	mutex_lock(&pohmelfs_config_lock);
	g = pohmelfs_find_config_group(psb->idx);
	if (!g)
		goto err_out_exit;

	if (g->hash_string) {
		err = -ENOMEM;
		psb->hash_string = kstrdup(g->hash_string, GFP_KERNEL);
		if (!psb->hash_string)
			goto err_out_exit;
		psb->hash_strlen = g->hash_strlen;
	}

	if (g->cipher_string) {
		psb->cipher_string = kstrdup(g->cipher_string, GFP_KERNEL);
		if (!psb->cipher_string)
			goto err_out_free_hash_string;
		psb->cipher_strlen = g->cipher_strlen;
	}

	if (g->hash_keysize) {
		psb->hash_key = kmemdup(g->hash_key, g->hash_keysize,
					GFP_KERNEL);
		if (!psb->hash_key)
			goto err_out_free_cipher_string;
		psb->hash_keysize = g->hash_keysize;
	}

	if (g->cipher_keysize) {
		psb->cipher_key = kmemdup(g->cipher_key, g->cipher_keysize,
					  GFP_KERNEL);
		if (!psb->cipher_key)
			goto err_out_free_hash;
		psb->cipher_keysize = g->cipher_keysize;
	}

	mutex_unlock(&pohmelfs_config_lock);

	return 0;

err_out_free_hash:
	kfree(psb->hash_key);
err_out_free_cipher_string:
	kfree(psb->cipher_string);
err_out_free_hash_string:
	kfree(psb->hash_string);
err_out_exit:
	mutex_unlock(&pohmelfs_config_lock);
	return err;
}

static int pohmelfs_send_reply(int err, int msg_num, int action, struct cn_msg *msg, struct pohmelfs_ctl *ctl)
{
	struct pohmelfs_cn_ack *ack;

	ack = kzalloc(sizeof(struct pohmelfs_cn_ack), GFP_KERNEL);
	if (!ack)
		return -ENOMEM;

	memcpy(&ack->msg, msg, sizeof(struct cn_msg));

	if (action == POHMELFS_CTLINFO_ACK)
		memcpy(&ack->ctl, ctl, sizeof(struct pohmelfs_ctl));

	ack->msg.len = sizeof(struct pohmelfs_cn_ack) - sizeof(struct cn_msg);
	ack->msg.ack = msg->ack + 1;
	ack->error = err;
	ack->msg_num = msg_num;

	cn_netlink_send(&ack->msg, 0, GFP_KERNEL);
	kfree(ack);
	return 0;
}

static int pohmelfs_cn_disp(struct cn_msg *msg)
{
	struct pohmelfs_config_group *g;
	struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
	struct pohmelfs_config *c, *tmp;
	int err = 0, i = 1;

	if (msg->len != sizeof(struct pohmelfs_ctl))
		return -EBADMSG;

	mutex_lock(&pohmelfs_config_lock);

	g = pohmelfs_find_config_group(ctl->idx);
	if (!g) {
		pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL);
		goto out_unlock;
	}

	list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
		struct pohmelfs_ctl *sc = &c->state.ctl;
		if (pohmelfs_send_reply(err, g->num_entry - i, POHMELFS_CTLINFO_ACK, msg, sc)) {
			err = -ENOMEM;
			goto out_unlock;
		}
		i += 1;
	}

 out_unlock:
	mutex_unlock(&pohmelfs_config_lock);
	return err;
}

static int pohmelfs_cn_dump(struct cn_msg *msg)
{
	struct pohmelfs_config_group *g;
	struct pohmelfs_config *c, *tmp;
	int err = 0, i = 1;
	int total_msg = 0;

	if (msg->len != sizeof(struct pohmelfs_ctl))
		return -EBADMSG;

	mutex_lock(&pohmelfs_config_lock);

	list_for_each_entry(g, &pohmelfs_config_list, group_entry)
		total_msg += g->num_entry;
	if (total_msg == 0) {
		if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
			err = -ENOMEM;
		goto out_unlock;
	}

	list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
		list_for_each_entry_safe(c, tmp, &g->config_list,
					 config_entry) {
			struct pohmelfs_ctl *sc = &c->state.ctl;
			if (pohmelfs_send_reply(err, total_msg - i,
						POHMELFS_CTLINFO_ACK, msg,
						sc)) {
				err = -ENOMEM;
				goto out_unlock;
			}
			i += 1;
		}
	}

out_unlock:
	mutex_unlock(&pohmelfs_config_lock);
	return err;
}

static int pohmelfs_cn_flush(struct cn_msg *msg)
{
	struct pohmelfs_config_group *g;
	struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
	struct pohmelfs_config *c, *tmp;
	int err = 0;

	if (msg->len != sizeof(struct pohmelfs_ctl))
		return -EBADMSG;

	mutex_lock(&pohmelfs_config_lock);

	if (ctl->idx != POHMELFS_NULL_IDX) {
		g = pohmelfs_find_config_group(ctl->idx);

		if (!g)
			goto out_unlock;

		list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
			list_del(&c->config_entry);
			g->num_entry--;
			kfree(c);
		}
	} else {
		list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
			list_for_each_entry_safe(c, tmp, &g->config_list,
						 config_entry) {
				list_del(&c->config_entry);
				g->num_entry--;
				kfree(c);
			}
		}
	}

out_unlock:
	mutex_unlock(&pohmelfs_config_lock);
	pohmelfs_cn_dump(msg);

	return err;
}

static int pohmelfs_modify_config(struct pohmelfs_ctl *old, struct pohmelfs_ctl *new)
{
	old->perm = new->perm;
	old->prio = new->prio;
	return 0;
}

static int pohmelfs_cn_ctl(struct cn_msg *msg, int action)
{
	struct pohmelfs_config_group *g;
	struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
	struct pohmelfs_config *c, *tmp;
	int err = 0;

	if (msg->len != sizeof(struct pohmelfs_ctl))
		return -EBADMSG;

	mutex_lock(&pohmelfs_config_lock);

	g = pohmelfs_find_create_config_group(ctl->idx);
	if (!g) {
		err = -ENOMEM;
		goto out_unlock;
	}

	list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
		struct pohmelfs_ctl *sc = &c->state.ctl;

		if (pohmelfs_config_eql(sc, ctl)) {
			if (action == POHMELFS_FLAGS_ADD) {
				err = -EEXIST;
				goto out_unlock;
			} else if (action == POHMELFS_FLAGS_DEL) {
				list_del(&c->config_entry);
				g->num_entry--;
				kfree(c);
				goto out_unlock;
			} else if (action == POHMELFS_FLAGS_MODIFY) {
				err = pohmelfs_modify_config(sc, ctl);
				goto out_unlock;
			} else {
				err = -EEXIST;
				goto out_unlock;
			}
		}
	}
	if (action == POHMELFS_FLAGS_DEL) {
		err = -EBADMSG;
		goto out_unlock;
	}

	c = kzalloc(sizeof(struct pohmelfs_config), GFP_KERNEL);
	if (!c) {
		err = -ENOMEM;
		goto out_unlock;
	}
	memcpy(&c->state.ctl, ctl, sizeof(struct pohmelfs_ctl));
	g->num_entry++;

	list_add_tail(&c->config_entry, &g->config_list);

 out_unlock:
	mutex_unlock(&pohmelfs_config_lock);
	if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
		err = -ENOMEM;

	return err;
}

static int pohmelfs_crypto_hash_init(struct pohmelfs_config_group *g, struct pohmelfs_crypto *c)
{
	char *algo = (char *)c->data;
	u8 *key = (u8 *)(algo + c->strlen);

	if (g->hash_string)
		return -EEXIST;

	g->hash_string = kstrdup(algo, GFP_KERNEL);
	if (!g->hash_string)
		return -ENOMEM;
	g->hash_strlen = c->strlen;
	g->hash_keysize = c->keysize;

	g->hash_key = kmemdup(key, c->keysize, GFP_KERNEL);
	if (!g->hash_key) {
		kfree(g->hash_string);
		return -ENOMEM;
	}

	return 0;
}

static int pohmelfs_crypto_cipher_init(struct pohmelfs_config_group *g, struct pohmelfs_crypto *c)
{
	char *algo = (char *)c->data;
	u8 *key = (u8 *)(algo + c->strlen);

	if (g->cipher_string)
		return -EEXIST;

	g->cipher_string = kstrdup(algo, GFP_KERNEL);
	if (!g->cipher_string)
		return -ENOMEM;
	g->cipher_strlen = c->strlen;
	g->cipher_keysize = c->keysize;

	g->cipher_key = kmemdup(key, c->keysize, GFP_KERNEL);
	if (!g->cipher_key) {
		kfree(g->cipher_string);
		return -ENOMEM;
	}

	return 0;
}

static int pohmelfs_cn_crypto(struct cn_msg *msg)
{
	struct pohmelfs_crypto *crypto = (struct pohmelfs_crypto *)msg->data;
	struct pohmelfs_config_group *g;
	int err = 0;

	dprintk("%s: idx: %u, strlen: %u, type: %u, keysize: %u, algo: %s.\n",
			__func__, crypto->idx, crypto->strlen, crypto->type,
			crypto->keysize, (char *)crypto->data);

	mutex_lock(&pohmelfs_config_lock);
	g = pohmelfs_find_create_config_group(crypto->idx);
	if (!g) {
		err = -ENOMEM;
		goto out_unlock;
	}

	switch (crypto->type) {
	case POHMELFS_CRYPTO_HASH:
			err = pohmelfs_crypto_hash_init(g, crypto);
			break;
	case POHMELFS_CRYPTO_CIPHER:
			err = pohmelfs_crypto_cipher_init(g, crypto);
			break;
	default:
			err = -ENOTSUPP;
			break;
	}

out_unlock:
	mutex_unlock(&pohmelfs_config_lock);
	if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
		err = -ENOMEM;

	return err;
}

static void pohmelfs_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
{
	int err;

	if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN))
		return;

	switch (msg->flags) {
	case POHMELFS_FLAGS_ADD:
	case POHMELFS_FLAGS_DEL:
	case POHMELFS_FLAGS_MODIFY:
			err = pohmelfs_cn_ctl(msg, msg->flags);
			break;
	case POHMELFS_FLAGS_FLUSH:
			err = pohmelfs_cn_flush(msg);
			break;
	case POHMELFS_FLAGS_SHOW:
			err = pohmelfs_cn_disp(msg);
			break;
	case POHMELFS_FLAGS_DUMP:
			err = pohmelfs_cn_dump(msg);
			break;
	case POHMELFS_FLAGS_CRYPTO:
			err = pohmelfs_cn_crypto(msg);
			break;
	default:
			err = -ENOSYS;
			break;
	}
}

int pohmelfs_config_check(struct pohmelfs_config *config, int idx)
{
	struct pohmelfs_ctl *ctl = &config->state.ctl;
	struct pohmelfs_config *tmp;
	int err = -ENOENT;
	struct pohmelfs_ctl *sc;
	struct pohmelfs_config_group *g;

	mutex_lock(&pohmelfs_config_lock);

	g = pohmelfs_find_config_group(ctl->idx);
	if (g) {
		list_for_each_entry(tmp, &g->config_list, config_entry) {
			sc = &tmp->state.ctl;

			if (pohmelfs_config_eql(sc, ctl)) {
				err = 0;
				break;
			}
		}
	}

	mutex_unlock(&pohmelfs_config_lock);

	return err;
}

int __init pohmelfs_config_init(void)
{
	/* XXX remove (void *) cast when vanilla connector got synced */
	return cn_add_callback(&pohmelfs_cn_id, "pohmelfs", (void *)pohmelfs_cn_callback);
}

void pohmelfs_config_exit(void)
{
	struct pohmelfs_config *c, *tmp;
	struct pohmelfs_config_group *g, *gtmp;

	cn_del_callback(&pohmelfs_cn_id);

	mutex_lock(&pohmelfs_config_lock);
	list_for_each_entry_safe(g, gtmp, &pohmelfs_config_list, group_entry) {
		list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
			list_del(&c->config_entry);
			kfree(c);
		}

		list_del(&g->group_entry);

		if (g->hash_string)
			kfree(g->hash_string);

		if (g->cipher_string)
			kfree(g->cipher_string);

		kfree(g);
	}
	mutex_unlock(&pohmelfs_config_lock);
}
