/*
 * lib/netfilter/queue.c	Netfilter Queue
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation version 2.1
 *	of the License.
 *
 * Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
 */

/**
 * @ingroup nfnl
 * @defgroup queue Queue
 * @brief
 * @{
 */

#include <sys/types.h>
#include <linux/netfilter/nfnetlink_queue.h>

#include <netlink-local.h>
#include <netlink/attr.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/queue.h>

struct nl_sock *nfnl_queue_socket_alloc(void)
{
	struct nl_sock *nlsk;

	nlsk = nl_socket_alloc();
	if (nlsk)
		nl_socket_disable_auto_ack(nlsk);
	return nlsk;
}

static int send_queue_request(struct nl_sock *sk, struct nl_msg *msg)
{
	int err;

	err = nl_send_auto_complete(sk, msg);
	nlmsg_free(msg);
	if (err < 0)
		return err;

	return wait_for_ack(sk);
}

/**
 * @name Queue Commands
 * @{
 */

static int build_queue_cmd_request(uint8_t family, uint16_t queuenum,
				   uint8_t command, struct nl_msg **result)
{
	struct nl_msg *msg;
	struct nfqnl_msg_config_cmd cmd;

	msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_QUEUE, NFQNL_MSG_CONFIG, 0,
				   family, queuenum);
	if (msg == NULL)
		return -NLE_NOMEM;

	cmd.pf = htons(family);
	cmd._pad = 0;
	cmd.command = command;
	if (nla_put(msg, NFQA_CFG_CMD, sizeof(cmd), &cmd) < 0)
		goto nla_put_failure;

	*result = msg;
	return 0;

nla_put_failure:
	nlmsg_free(msg);
	return -NLE_MSGSIZE;
}

int nfnl_queue_build_pf_bind(uint8_t pf, struct nl_msg **result)
{
	return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_BIND, result);
}

int nfnl_queue_pf_bind(struct nl_sock *nlh, uint8_t pf)
{
	struct nl_msg *msg;
	int err;

	if ((err = nfnl_queue_build_pf_bind(pf, &msg)) < 0)
		return err;

	return send_queue_request(nlh, msg);
}

int nfnl_queue_build_pf_unbind(uint8_t pf, struct nl_msg **result)
{
	return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_UNBIND, result);
}

int nfnl_queue_pf_unbind(struct nl_sock *nlh, uint8_t pf)
{
	struct nl_msg *msg;
	int err;

	if ((err = nfnl_queue_build_pf_unbind(pf, &msg)) < 0)
		return err;

	return send_queue_request(nlh, msg);
}

static int nfnl_queue_build_request(const struct nfnl_queue *queue,
				    struct nl_msg **result)
{
	struct nl_msg *msg;

	if (!nfnl_queue_test_group(queue))
		return -NLE_MISSING_ATTR;

	msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_QUEUE, NFQNL_MSG_CONFIG, 0,
				   0, nfnl_queue_get_group(queue));
	if (msg == NULL)
		return -NLE_NOMEM;

	if (nfnl_queue_test_maxlen(queue) &&
	    nla_put_u32(msg, NFQA_CFG_QUEUE_MAXLEN,
			htonl(nfnl_queue_get_maxlen(queue))) < 0)
		goto nla_put_failure;

	/* This sucks, the nfnetlink_queue interface always expects both
	 * parameters to be present. Needs to be done properly.
	 */
	if (nfnl_queue_test_copy_mode(queue)) {
		struct nfqnl_msg_config_params params;

		switch (nfnl_queue_get_copy_mode(queue)) {
		case NFNL_QUEUE_COPY_NONE:
			params.copy_mode = NFQNL_COPY_NONE;
			break;
		case NFNL_QUEUE_COPY_META:
			params.copy_mode = NFQNL_COPY_META;
			break;
		case NFNL_QUEUE_COPY_PACKET:
			params.copy_mode = NFQNL_COPY_PACKET;
			break;
		}
		params.copy_range = htonl(nfnl_queue_get_copy_range(queue));

		if (nla_put(msg, NFQA_CFG_PARAMS, sizeof(params), &params) < 0)
			goto nla_put_failure;
	}

	*result = msg;
	return 0;

nla_put_failure:
	nlmsg_free(msg);
	return -NLE_MSGSIZE;
}

int nfnl_queue_build_create_request(const struct nfnl_queue *queue,
				    struct nl_msg **result)
{
	struct nfqnl_msg_config_cmd cmd;
	int err;

	if ((err = nfnl_queue_build_request(queue, result)) < 0)
		return err;

	cmd.pf = 0;
	cmd._pad = 0;
	cmd.command = NFQNL_CFG_CMD_BIND;

	NLA_PUT(*result, NFQA_CFG_CMD, sizeof(cmd), &cmd);

	return 0;

nla_put_failure:
	nlmsg_free(*result);
	return -NLE_MSGSIZE;
}

int nfnl_queue_create(struct nl_sock *nlh, const struct nfnl_queue *queue)
{
	struct nl_msg *msg;
	int err;

	if ((err = nfnl_queue_build_create_request(queue, &msg)) < 0)
		return err;

	return send_queue_request(nlh, msg);
}

int nfnl_queue_build_change_request(const struct nfnl_queue *queue,
				    struct nl_msg **result)
{
	return nfnl_queue_build_request(queue, result);
}

int nfnl_queue_change(struct nl_sock *nlh, const struct nfnl_queue *queue)
{
	struct nl_msg *msg;
	int err;

	if ((err = nfnl_queue_build_change_request(queue, &msg)) < 0)
		return err;

	return send_queue_request(nlh, msg);
}

int nfnl_queue_build_delete_request(const struct nfnl_queue *queue,
				    struct nl_msg **result)
{
	if (!nfnl_queue_test_group(queue))
		return -NLE_MISSING_ATTR;

	return build_queue_cmd_request(0, nfnl_queue_get_group(queue),
				       NFQNL_CFG_CMD_UNBIND, result);
}

int nfnl_queue_delete(struct nl_sock *nlh, const struct nfnl_queue *queue)
{
	struct nl_msg *msg;
	int err;

	if ((err = nfnl_queue_build_delete_request(queue, &msg)) < 0)
		return err;

	return send_queue_request(nlh, msg);
}

/** @} */

static struct nl_cache_ops nfnl_queue_ops = {
	.co_name		= "netfilter/queue",
	.co_obj_ops		= &queue_obj_ops,
	.co_msgtypes		= {
		END_OF_MSGTYPES_LIST,
	},
};

static void __init nfnl_queue_init(void)
{
	nl_cache_mngt_register(&nfnl_queue_ops);
}

static void __exit nfnl_queue_exit(void)
{
	nl_cache_mngt_unregister(&nfnl_queue_ops);
}

/** @} */
