/*
 * lib/fib_lookup/lookup.c	FIB Lookup
 *
 *	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) 2003-2008 Thomas Graf <tgraf@suug.ch>
 */

/**
 * @defgroup fib_lookup FIB Lookup
 * @brief
 * @{
 */

#include <netlink-local.h>
#include <netlink/netlink.h>
#include <netlink/attr.h>
#include <netlink/utils.h>
#include <netlink/object.h>
#include <netlink/route/rtnl.h>
#include <netlink/route/route.h>
#include <netlink/fib_lookup/request.h>
#include <netlink/fib_lookup/lookup.h>

/** @cond SKIP */
static struct nl_cache_ops fib_lookup_ops;
static struct nl_object_ops result_obj_ops;

/* not exported so far */
struct fib_result_nl {
	uint32_t	fl_addr;   /* To be looked up*/ 
	uint32_t	fl_fwmark; 
	unsigned char	fl_tos;
	unsigned char   fl_scope;
	unsigned char   tb_id_in;

	unsigned char   tb_id;      /* Results */
	unsigned char	prefixlen;
	unsigned char	nh_sel;
	unsigned char	type;
	unsigned char	scope;
	int             err;      
};
/** @endcond */

static void result_free_data(struct nl_object *obj)
{
	struct flnl_result *res = nl_object_priv(obj);

	if (res && res->fr_req)
		nl_object_put(OBJ_CAST(res->fr_req));
}

static int result_clone(struct nl_object *_dst, struct nl_object *_src)
{
	struct flnl_result *dst = nl_object_priv(_dst);
	struct flnl_result *src = nl_object_priv(_src);

	if (src->fr_req)
		if (!(dst->fr_req = (struct flnl_request *)
				nl_object_clone(OBJ_CAST(src->fr_req))))
			return -NLE_NOMEM;
	
	return 0;
}

static int result_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
			     struct nlmsghdr *n, struct nl_parser_param *pp)
{
	struct flnl_result *res;
	struct fib_result_nl *fr;
	struct nl_addr *addr;
	int err = -NLE_INVAL;

	res = flnl_result_alloc();
	if (!res)
		goto errout;

	res->ce_msgtype = n->nlmsg_type;

	res->fr_req = flnl_request_alloc();
	if (!res->fr_req)
		goto errout;

	fr = nlmsg_data(n);
	addr = nl_addr_build(AF_INET, &fr->fl_addr, 4);
	if (!addr)
		goto errout;
	err = flnl_request_set_addr(res->fr_req, addr);
	nl_addr_put(addr);
	if (err < 0)
		goto errout;

	flnl_request_set_fwmark(res->fr_req, fr->fl_fwmark);
	flnl_request_set_tos(res->fr_req, fr->fl_tos);
	flnl_request_set_scope(res->fr_req, fr->fl_scope);
	flnl_request_set_table(res->fr_req, fr->tb_id_in);

	res->fr_table_id = fr->tb_id;
	res->fr_prefixlen = fr->prefixlen;
	res->fr_nh_sel = fr->nh_sel;
	res->fr_type = fr->type;
	res->fr_scope = fr->scope;
	res->fr_error = fr->err;

	err = pp->pp_cb((struct nl_object *) res, pp);
	if (err < 0)
		goto errout;

	/* REAL HACK, fib_lookup doesn't support ACK nor does it
	 * send a DONE message, enforce end of message stream
	 * after just the first message */
	err = NL_STOP;

errout:
	flnl_result_put(res);
	return err;
}

static void result_dump_line(struct nl_object *obj, struct nl_dump_params *p)
{
	struct flnl_result *res = (struct flnl_result *) obj;
	char buf[128];

	nl_dump_line(p, "table %s prefixlen %u next-hop-selector %u\n",
		rtnl_route_table2str(res->fr_table_id, buf, sizeof(buf)),
		res->fr_prefixlen, res->fr_nh_sel);
	nl_dump_line(p, "type %s ",
		     nl_rtntype2str(res->fr_type, buf, sizeof(buf)));
	nl_dump(p, "scope %s error %s (%d)\n",
		rtnl_scope2str(res->fr_scope, buf, sizeof(buf)),
		strerror(-res->fr_error), res->fr_error);
}

static void result_dump_details(struct nl_object *obj, struct nl_dump_params *p)
{
	result_dump_line(obj, p);
}

static int result_compare(struct nl_object *_a, struct nl_object *_b,
			uint32_t attrs, int flags)
{
	return 0;
}

/**
 * @name Allocation/Freeing
 * @{
 */

struct flnl_result *flnl_result_alloc(void)
{
	return (struct flnl_result *) nl_object_alloc(&result_obj_ops);
}

void flnl_result_put(struct flnl_result *res)
{
	nl_object_put((struct nl_object *) res);
}

/** @} */

/**
 * @name Cache Management
 * @{
 */

/**
 * Allocate lookup result cache.
 *
 * Allocates a new lookup result cache and initializes it properly.
 *
 * @note Free the memory after usage using nl_cache_destroy_and_free().
 * @return Newly allocated cache or NULL if an error occured.
 */
struct nl_cache *flnl_result_alloc_cache(void)
{
	return nl_cache_alloc(&fib_lookup_ops);
}

/** @} */

/**
 * @name Lookup
 * @{
 */

/**
 * Builds a netlink request message to do a lookup
 * @arg req		Requested match.
 * @arg flags		additional netlink message flags
 *
 * Builds a new netlink message requesting a change of link attributes.
 * The netlink message header isn't fully equipped with all relevant
 * fields and must be sent out via nl_send_auto_complete() or
 * supplemented as needed.
 * \a old must point to a link currently configured in the kernel
 * and \a tmpl must contain the attributes to be changed set via
 * \c rtnl_link_set_* functions.
 *
 * @return New netlink message
 * @note Not all attributes can be changed, see
 *       \ref link_changeable "Changeable Attributes" for more details.
 */
int flnl_lookup_build_request(struct flnl_request *req, int flags,
			      struct nl_msg **result)
{
	struct nl_msg *msg;
	struct nl_addr *addr;
	uint64_t fwmark;
	int tos, scope, table;
	struct fib_result_nl fr = {0};

	fwmark = flnl_request_get_fwmark(req);
	tos = flnl_request_get_tos(req);
	scope = flnl_request_get_scope(req);
	table = flnl_request_get_table(req);

	fr.fl_fwmark = fwmark != UINT_LEAST64_MAX ? fwmark : 0;
	fr.fl_tos = tos >= 0 ? tos : 0;
	fr.fl_scope = scope >= 0 ? scope : RT_SCOPE_UNIVERSE;
	fr.tb_id_in = table >= 0 ? table : RT_TABLE_UNSPEC;

	addr = flnl_request_get_addr(req);
	if (!addr)
		return -NLE_MISSING_ATTR;

	fr.fl_addr = *(uint32_t *) nl_addr_get_binary_addr(addr);

	msg = nlmsg_alloc_simple(0, flags);
	if (!msg)
		return -NLE_NOMEM;

	if (nlmsg_append(msg, &fr, sizeof(fr), NLMSG_ALIGNTO) < 0)
		goto errout;

	*result = msg;
	return 0;

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

/**
 * Perform FIB Lookup
 * @arg sk		Netlink socket.
 * @arg req		Lookup request object.
 * @arg cache		Cache for result.
 *
 * Builds a netlink message to request a FIB lookup, waits for the
 * reply and adds the result to the specified cache.
 *
 * @return 0 on success or a negative error code.
 */
int flnl_lookup(struct nl_sock *sk, struct flnl_request *req,
		struct nl_cache *cache)
{
	struct nl_msg *msg;
	int err;

	if ((err = flnl_lookup_build_request(req, 0, &msg)) < 0)
		return err;

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

	return nl_cache_pickup(sk, cache);
}

/** @} */

/**
 * @name Attribute Access
 * @{
 */

int flnl_result_get_table_id(struct flnl_result *res)
{
	return res->fr_table_id;
}

int flnl_result_get_prefixlen(struct flnl_result *res)
{
	return res->fr_prefixlen;
}

int flnl_result_get_nexthop_sel(struct flnl_result *res)
{
	return res->fr_nh_sel;
}

int flnl_result_get_type(struct flnl_result *res)
{
	return res->fr_type;
}

int flnl_result_get_scope(struct flnl_result *res)
{
	return res->fr_scope;
}

int flnl_result_get_error(struct flnl_result *res)
{
	return res->fr_error;
}

/** @} */

static struct nl_object_ops result_obj_ops = {
	.oo_name		= "fib_lookup/result",
	.oo_size		= sizeof(struct flnl_result),
	.oo_free_data		= result_free_data,
	.oo_clone		= result_clone,
	.oo_dump = {
	    [NL_DUMP_LINE]	= result_dump_line,
	    [NL_DUMP_DETAILS]	= result_dump_details,
	},
	.oo_compare		= result_compare,
};

static struct nl_cache_ops fib_lookup_ops = {
	.co_name		= "fib_lookup/fib_lookup",
	.co_hdrsize		= sizeof(struct fib_result_nl),
	.co_msgtypes		= {
					{ 0, NL_ACT_UNSPEC, "any" },
					END_OF_MSGTYPES_LIST,
				  },
	.co_protocol		= NETLINK_FIB_LOOKUP,
	.co_msg_parser		= result_msg_parser,
	.co_obj_ops		= &result_obj_ops,
};

static void __init fib_lookup_init(void)
{
	nl_cache_mngt_register(&fib_lookup_ops);
}

static void __exit fib_lookup_exit(void)
{
	nl_cache_mngt_unregister(&fib_lookup_ops);
}

/** @} */
