/*
 * lib/route/neigh.c	Neighbours
 *
 *	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>
 */

/**
 * @ingroup rtnl
 * @defgroup neigh Neighbours
 * @brief
 *
 * The neighbour table establishes bindings between protocol addresses and
 * link layer addresses for hosts sharing the same physical link. This
 * module allows you to access and manipulate the content of these tables.
 *
 * @par Neighbour States
 * @code
 * NUD_INCOMPLETE
 * NUD_REACHABLE
 * NUD_STALE
 * NUD_DELAY
 * NUD_PROBE
 * NUD_FAILED
 * NUD_NOARP
 * NUD_PERMANENT
 * @endcode
 *
 * @par Neighbour Flags
 * @code
 * NTF_PROXY
 * NTF_ROUTER
 * @endcode
 *
 * @par Neighbour Identification
 * A neighbour is uniquely identified by the attributes listed below, whenever
 * you refer to an existing neighbour all of the attributes must be set.
 * Neighbours from caches automatically have all required attributes set.
 *   - interface index (rtnl_neigh_set_ifindex())
 *   - destination address (rtnl_neigh_set_dst())
 *
 * @par Changeable Attributes
 * \anchor neigh_changeable
 *  - state (rtnl_neigh_set_state())
 *  - link layer address (rtnl_neigh_set_lladdr())
 *
 * @par Required Caches for Dumping
 * In order to dump neighbour attributes you must provide the following
 * caches via nl_cache_provide()
 *  - link cache holding all links
 *
 * @par TODO
 *   - Document proxy settings
 *   - Document states and their influence
 *
 * @par 1) Retrieving information about configured neighbours
 * @code
 * // The first step is to retrieve a list of all available neighbour within
 * // the kernel and put them into a cache.
 * struct nl_cache *cache = rtnl_neigh_alloc_cache(sk);
 *
 * // Neighbours can then be looked up by the interface and destination
 * // address:
 * struct rtnl_neigh *neigh = rtnl_neigh_get(cache, ifindex, dst_addr);
 * 
 * // After successful usage, the object must be given back to the cache
 * rtnl_neigh_put(neigh);
 * @endcode
 *
 * @par 2) Adding new neighbours
 * @code
 * // Allocate an empty neighbour handle to be filled out with the attributes
 * // of the new neighbour.
 * struct rtnl_neigh *neigh = rtnl_neigh_alloc();
 *
 * // Fill out the attributes of the new neighbour
 * rtnl_neigh_set_ifindex(neigh, ifindex);
 * rtnl_neigh_set_dst(neigh, dst_addr);
 * rtnl_neigh_set_state(neigh, rtnl_neigh_str2state("permanent"));
 *
 * // Build the netlink message and send it to the kernel, the operation will
 * // block until the operation has been completed. Alternatively the required
 * // netlink message can be built using rtnl_neigh_build_add_request()
 * // to be sent out using nl_send_auto_complete().
 * rtnl_neigh_add(sk, neigh, NLM_F_CREATE);
 *
 * // Free the memory
 * rtnl_neigh_put(neigh);
 * @endcode
 *
 * @par 3) Deleting an existing neighbour
 * @code
 * // Allocate an empty neighbour object to be filled out with the attributes
 * // matching the neighbour to be deleted. Alternatively a fully equipped
 * // neighbour object out of a cache can be used instead.
 * struct rtnl_neigh *neigh = rtnl_neigh_alloc();
 *
 * // Neighbours are uniquely identified by their interface index and
 * // destination address, you may fill out other attributes but they
 * // will have no influence.
 * rtnl_neigh_set_ifindex(neigh, ifindex);
 * rtnl_neigh_set_dst(neigh, dst_addr);
 *
 * // Build the netlink message and send it to the kernel, the operation will
 * // block until the operation has been completed. Alternatively the required
 * // netlink message can be built using rtnl_neigh_build_delete_request()
 * // to be sent out using nl_send_auto_complete().
 * rtnl_neigh_delete(sk, neigh, 0);
 *
 * // Free the memory
 * rtnl_neigh_put(neigh);
 * @endcode
 *
 * @par 4) Changing neighbour attributes
 * @code
 * // Allocate an empty neighbour object to be filled out with the attributes
 * // matching the neighbour to be changed and the new parameters. Alternatively
 * // a fully equipped modified neighbour object out of a cache can be used.
 * struct rtnl_neigh *neigh = rtnl_neigh_alloc();
 *
 * // Identify the neighbour to be changed by its interface index and
 * // destination address
 * rtnl_neigh_set_ifindex(neigh, ifindex);
 * rtnl_neigh_set_dst(neigh, dst_addr);
 *
 * // The link layer address may be modified, if so it is wise to change
 * // its state to "permanent" in order to avoid having it overwritten.
 * rtnl_neigh_set_lladdr(neigh, lladdr);
 *
 * // Secondly the state can be modified allowing normal neighbours to be
 * // converted into permanent entries or to manually confirm a neighbour.
 * rtnl_neigh_set_state(neigh, state);
 *
 * // Build the netlink message and send it to the kernel, the operation will
 * // block until the operation has been completed. Alternatively the required
 * // netlink message can be built using rtnl_neigh_build_change_request()
 * // to be sent out using nl_send_auto_complete().
 * rtnl_neigh_add(sk, neigh, NLM_F_REPLACE);
 *
 * // Free the memory
 * rtnl_neigh_put(neigh);
 * @endcode
 * @{
 */

#include <netlink-local.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/route/rtnl.h>
#include <netlink/route/neighbour.h>
#include <netlink/route/link.h>

/** @cond SKIP */
#define NEIGH_ATTR_FLAGS        0x01
#define NEIGH_ATTR_STATE        0x02
#define NEIGH_ATTR_LLADDR       0x04
#define NEIGH_ATTR_DST          0x08
#define NEIGH_ATTR_CACHEINFO    0x10
#define NEIGH_ATTR_IFINDEX      0x20
#define NEIGH_ATTR_FAMILY       0x40
#define NEIGH_ATTR_TYPE         0x80
#define NEIGH_ATTR_PROBES       0x100

static struct nl_cache_ops rtnl_neigh_ops;
static struct nl_object_ops neigh_obj_ops;
/** @endcond */

static void neigh_free_data(struct nl_object *c)
{
	struct rtnl_neigh *neigh = nl_object_priv(c);

	if (!neigh)
		return;

	nl_addr_put(neigh->n_lladdr);
	nl_addr_put(neigh->n_dst);
}

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

	if (src->n_lladdr)
		if (!(dst->n_lladdr = nl_addr_clone(src->n_lladdr)))
			return -NLE_NOMEM;

	if (src->n_dst)
		if (!(dst->n_dst = nl_addr_clone(src->n_dst)))
			return -NLE_NOMEM;

	return 0;
}

static int neigh_compare(struct nl_object *_a, struct nl_object *_b,
			uint32_t attrs, int flags)
{
	struct rtnl_neigh *a = (struct rtnl_neigh *) _a;
	struct rtnl_neigh *b = (struct rtnl_neigh *) _b;
	int diff = 0;

#define NEIGH_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, NEIGH_ATTR_##ATTR, a, b, EXPR)

	diff |= NEIGH_DIFF(IFINDEX,	a->n_ifindex != b->n_ifindex);
	diff |= NEIGH_DIFF(FAMILY,	a->n_family != b->n_family);
	diff |= NEIGH_DIFF(TYPE,	a->n_type != b->n_type);
	diff |= NEIGH_DIFF(LLADDR,	nl_addr_cmp(a->n_lladdr, b->n_lladdr));
	diff |= NEIGH_DIFF(DST,		nl_addr_cmp(a->n_dst, b->n_dst));

	if (flags & LOOSE_COMPARISON) {
		diff |= NEIGH_DIFF(STATE,
				  (a->n_state ^ b->n_state) & b->n_state_mask);
		diff |= NEIGH_DIFF(FLAGS,
				  (a->n_flags ^ b->n_flags) & b->n_flag_mask);
	} else {
		diff |= NEIGH_DIFF(STATE, a->n_state != b->n_state);
		diff |= NEIGH_DIFF(FLAGS, a->n_flags != b->n_flags);
	}

#undef NEIGH_DIFF

	return diff;
}

static struct trans_tbl neigh_attrs[] = {
	__ADD(NEIGH_ATTR_FLAGS, flags)
	__ADD(NEIGH_ATTR_STATE, state)
	__ADD(NEIGH_ATTR_LLADDR, lladdr)
	__ADD(NEIGH_ATTR_DST, dst)
	__ADD(NEIGH_ATTR_CACHEINFO, cacheinfo)
	__ADD(NEIGH_ATTR_IFINDEX, ifindex)
	__ADD(NEIGH_ATTR_FAMILY, family)
	__ADD(NEIGH_ATTR_TYPE, type)
	__ADD(NEIGH_ATTR_PROBES, probes)
};

static char *neigh_attrs2str(int attrs, char *buf, size_t len)
{
	return __flags2str(attrs, buf, len, neigh_attrs,
			   ARRAY_SIZE(neigh_attrs));
}

static struct nla_policy neigh_policy[NDA_MAX+1] = {
	[NDA_CACHEINFO]	= { .minlen = sizeof(struct nda_cacheinfo) },
	[NDA_PROBES]	= { .type = NLA_U32 },
};

static int neigh_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
			    struct nlmsghdr *n, struct nl_parser_param *pp)
{
	struct rtnl_neigh *neigh;
	struct nlattr *tb[NDA_MAX + 1];
	struct ndmsg *nm;
	int err;

	neigh = rtnl_neigh_alloc();
	if (!neigh) {
		err = -NLE_NOMEM;
		goto errout;
	}

	neigh->ce_msgtype = n->nlmsg_type;
	nm = nlmsg_data(n);

	err = nlmsg_parse(n, sizeof(*nm), tb, NDA_MAX, neigh_policy);
	if (err < 0)
		goto errout;

	neigh->n_family  = nm->ndm_family;
	neigh->n_ifindex = nm->ndm_ifindex;
	neigh->n_state   = nm->ndm_state;
	neigh->n_flags   = nm->ndm_flags;
	neigh->n_type    = nm->ndm_type;

	neigh->ce_mask |= (NEIGH_ATTR_FAMILY | NEIGH_ATTR_IFINDEX |
			   NEIGH_ATTR_STATE | NEIGH_ATTR_FLAGS |
			   NEIGH_ATTR_TYPE);

	if (tb[NDA_LLADDR]) {
		neigh->n_lladdr = nl_addr_alloc_attr(tb[NDA_LLADDR], AF_UNSPEC);
		if (!neigh->n_lladdr) {
			err = -NLE_NOMEM;
			goto errout;
		}
		nl_addr_set_family(neigh->n_lladdr,
				   nl_addr_guess_family(neigh->n_lladdr));
		neigh->ce_mask |= NEIGH_ATTR_LLADDR;
	}

	if (tb[NDA_DST]) {
		neigh->n_dst = nl_addr_alloc_attr(tb[NDA_DST], neigh->n_family);
		if (!neigh->n_dst) {
			err = -NLE_NOMEM;
			goto errout;
		}
		neigh->ce_mask |= NEIGH_ATTR_DST;
	}

	if (tb[NDA_CACHEINFO]) {
		struct nda_cacheinfo *ci = nla_data(tb[NDA_CACHEINFO]);

		neigh->n_cacheinfo.nci_confirmed = ci->ndm_confirmed;
		neigh->n_cacheinfo.nci_used = ci->ndm_used;
		neigh->n_cacheinfo.nci_updated = ci->ndm_updated;
		neigh->n_cacheinfo.nci_refcnt = ci->ndm_refcnt;
		
		neigh->ce_mask |= NEIGH_ATTR_CACHEINFO;
	}

	if (tb[NDA_PROBES]) {
		neigh->n_probes = nla_get_u32(tb[NDA_PROBES]);
		neigh->ce_mask |= NEIGH_ATTR_PROBES;
	}

	err = pp->pp_cb((struct nl_object *) neigh, pp);
errout:
	rtnl_neigh_put(neigh);
	return err;
}

static int neigh_request_update(struct nl_cache *c, struct nl_sock *h)
{
	return nl_rtgen_request(h, RTM_GETNEIGH, AF_UNSPEC, NLM_F_DUMP);
}


static void neigh_dump_line(struct nl_object *a, struct nl_dump_params *p)
{
	char dst[INET6_ADDRSTRLEN+5], lladdr[INET6_ADDRSTRLEN+5];
	struct rtnl_neigh *n = (struct rtnl_neigh *) a;
	struct nl_cache *link_cache;
	char state[128], flags[64];

	link_cache = nl_cache_mngt_require("route/link");

	nl_dump_line(p, "%s ", nl_addr2str(n->n_dst, dst, sizeof(dst)));

	if (link_cache)
		nl_dump(p, "dev %s ",
			rtnl_link_i2name(link_cache, n->n_ifindex,
					 state, sizeof(state)));
	else
		nl_dump(p, "dev %d ", n->n_ifindex);

	if (n->ce_mask & NEIGH_ATTR_LLADDR)
		nl_dump(p, "lladdr %s ",
			nl_addr2str(n->n_lladdr, lladdr, sizeof(lladdr)));

	rtnl_neigh_state2str(n->n_state, state, sizeof(state));
	rtnl_neigh_flags2str(n->n_flags, flags, sizeof(flags));

	if (state[0])
		nl_dump(p, "<%s", state);
	if (flags[0])
		nl_dump(p, "%s%s", state[0] ? "," : "<", flags);
	if (state[0] || flags[0])
		nl_dump(p, ">");
	nl_dump(p, "\n");
}

static void neigh_dump_details(struct nl_object *a, struct nl_dump_params *p)
{
	char rtn_type[32];
	struct rtnl_neigh *n = (struct rtnl_neigh *) a;
	int hz = nl_get_hz();

	neigh_dump_line(a, p);

	nl_dump_line(p, "    refcnt %u type %s confirmed %u used "
				"%u updated %u\n",
		n->n_cacheinfo.nci_refcnt,
		nl_rtntype2str(n->n_type, rtn_type, sizeof(rtn_type)),
		n->n_cacheinfo.nci_confirmed/hz,
		n->n_cacheinfo.nci_used/hz, n->n_cacheinfo.nci_updated/hz);
}

static void neigh_dump_stats(struct nl_object *a, struct nl_dump_params *p)
{
	neigh_dump_details(a, p);
}

static void neigh_dump_env(struct nl_object *obj, struct nl_dump_params *p)
{
	struct rtnl_neigh *neigh = (struct rtnl_neigh *) obj;
	char buf[128];

	nl_dump_line(p, "NEIGH_FAMILY=%s\n",
		     nl_af2str(neigh->n_family, buf, sizeof(buf)));

	if (neigh->ce_mask & NEIGH_ATTR_LLADDR)
		nl_dump_line(p, "NEIGHT_LLADDR=%s\n",
			     nl_addr2str(neigh->n_lladdr, buf, sizeof(buf)));

	if (neigh->ce_mask & NEIGH_ATTR_DST)
		nl_dump_line(p, "NEIGH_DST=%s\n",
			     nl_addr2str(neigh->n_dst, buf, sizeof(buf)));

	if (neigh->ce_mask & NEIGH_ATTR_IFINDEX) {
		struct nl_cache *link_cache;

		nl_dump_line(p, "NEIGH_IFINDEX=%u\n", neigh->n_ifindex);

		link_cache = nl_cache_mngt_require("route/link");
		if (link_cache)
			nl_dump_line(p, "NEIGH_IFNAME=%s\n",
				     rtnl_link_i2name(link_cache,
						      neigh->n_ifindex,
						      buf, sizeof(buf)));
	}

	if (neigh->ce_mask & NEIGH_ATTR_PROBES)
		nl_dump_line(p, "NEIGH_PROBES=%u\n", neigh->n_probes);

	if (neigh->ce_mask & NEIGH_ATTR_TYPE)
		nl_dump_line(p, "NEIGH_TYPE=%s\n",
			     nl_rtntype2str(neigh->n_type, buf, sizeof(buf)));

	rtnl_neigh_flags2str(neigh->n_flags, buf, sizeof(buf));
	if (buf[0])
		nl_dump_line(p, "NEIGH_FLAGS=%s\n", buf);

	rtnl_neigh_state2str(neigh->n_state, buf, sizeof(buf));
	if (buf[0])
		nl_dump_line(p, "NEIGH_STATE=%s\n", buf);
}

/**
 * @name Neighbour Object Allocation/Freeage
 * @{
 */

struct rtnl_neigh *rtnl_neigh_alloc(void)
{
	return (struct rtnl_neigh *) nl_object_alloc(&neigh_obj_ops);
}

void rtnl_neigh_put(struct rtnl_neigh *neigh)
{
	nl_object_put((struct nl_object *) neigh);
}

/** @} */

/**
 * @name Neighbour Cache Managament
 * @{
 */

/**
 * Build a neighbour cache including all neighbours currently configured in the kernel.
 * @arg sk		Netlink socket.
 * @arg result		Pointer to store resulting cache.
 *
 * Allocates a new neighbour cache, initializes it properly and updates it
 * to include all neighbours currently configured in the kernel.
 *
 * @return 0 on success or a negative error code.
 */
int rtnl_neigh_alloc_cache(struct nl_sock *sock, struct nl_cache **result)
{
	return nl_cache_alloc_and_fill(&rtnl_neigh_ops, sock, result);
}

/**
 * Look up a neighbour by interface index and destination address
 * @arg cache		neighbour cache
 * @arg ifindex		interface index the neighbour is on
 * @arg dst		destination address of the neighbour
 * @return neighbour handle or NULL if no match was found.
 */
struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *cache, int ifindex,
				   struct nl_addr *dst)
{
	struct rtnl_neigh *neigh;

	nl_list_for_each_entry(neigh, &cache->c_items, ce_list) {
		if (neigh->n_ifindex == ifindex &&
		    !nl_addr_cmp(neigh->n_dst, dst)) {
			nl_object_get((struct nl_object *) neigh);
			return neigh;
		}
	}

	return NULL;
}

/** @} */

/**
 * @name Neighbour Addition
 * @{
 */

static int build_neigh_msg(struct rtnl_neigh *tmpl, int cmd, int flags,
			   struct nl_msg **result)
{
	struct nl_msg *msg;
	struct ndmsg nhdr = {
		.ndm_ifindex = tmpl->n_ifindex,
		.ndm_state = NUD_PERMANENT,
	};

	if (!(tmpl->ce_mask & NEIGH_ATTR_DST))
		return -NLE_MISSING_ATTR;

	nhdr.ndm_family = nl_addr_get_family(tmpl->n_dst);

	if (tmpl->ce_mask & NEIGH_ATTR_STATE)
		nhdr.ndm_state = tmpl->n_state;

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

	if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0)
		goto nla_put_failure;

	NLA_PUT_ADDR(msg, NDA_DST, tmpl->n_dst);

	if (tmpl->ce_mask & NEIGH_ATTR_LLADDR)
		NLA_PUT_ADDR(msg, NDA_LLADDR, tmpl->n_lladdr);

	*result = msg;
	return 0;

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

/**
 * Build netlink request message to add a new neighbour
 * @arg tmpl		template with data of new neighbour
 * @arg flags		additional netlink message flags
 * @arg result		Pointer to store resulting message.
 *
 * Builds a new netlink message requesting a addition of a new
 * neighbour. The netlink message header isn't fully equipped with
 * all relevant fields and must thus be sent out via nl_send_auto_complete()
 * or supplemented as needed. \a tmpl must contain the attributes of the new
 * neighbour set via \c rtnl_neigh_set_* functions.
 * 
 * The following attributes must be set in the template:
 *  - Interface index (rtnl_neigh_set_ifindex())
 *  - State (rtnl_neigh_set_state())
 *  - Destination address (rtnl_neigh_set_dst())
 *  - Link layer address (rtnl_neigh_set_lladdr())
 *
 * @return 0 on success or a negative error code.
 */
int rtnl_neigh_build_add_request(struct rtnl_neigh *tmpl, int flags,
				 struct nl_msg **result)
{
	return build_neigh_msg(tmpl, RTM_NEWNEIGH, flags, result);
}

/**
 * Add a new neighbour
 * @arg sk		Netlink socket.
 * @arg tmpl		template with requested changes
 * @arg flags		additional netlink message flags
 *
 * Builds a netlink message by calling rtnl_neigh_build_add_request(),
 * sends the request to the kernel and waits for the next ACK to be
 * received and thus blocks until the request has been fullfilled.
 *
 * The following attributes must be set in the template:
 *  - Interface index (rtnl_neigh_set_ifindex())
 *  - State (rtnl_neigh_set_state())
 *  - Destination address (rtnl_neigh_set_dst())
 *  - Link layer address (rtnl_neigh_set_lladdr())
 *
 * @return 0 on sucess or a negative error if an error occured.
 */
int rtnl_neigh_add(struct nl_sock *sk, struct rtnl_neigh *tmpl, int flags)
{
	int err;
	struct nl_msg *msg;
	
	if ((err = rtnl_neigh_build_add_request(tmpl, flags, &msg)) < 0)
		return err;

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

	return wait_for_ack(sk);
}

/** @} */

/**
 * @name Neighbour Deletion
 * @{
 */

/**
 * Build a netlink request message to delete a neighbour
 * @arg neigh		neighbour to delete
 * @arg flags		additional netlink message flags
 * @arg result		Pointer to store resulting message.
 *
 * Builds a new netlink message requesting a deletion of a neighbour.
 * The netlink message header isn't fully equipped with all relevant
 * fields and must thus be sent out via nl_send_auto_complete()
 * or supplemented as needed. \a neigh must point to an existing
 * neighbour.
 *
 * @return 0 on success or a negative error code.
 */
int rtnl_neigh_build_delete_request(struct rtnl_neigh *neigh, int flags,
				    struct nl_msg **result)
{
	return build_neigh_msg(neigh, RTM_DELNEIGH, flags, result);
}

/**
 * Delete a neighbour
 * @arg sk		Netlink socket.
 * @arg neigh		neighbour to delete
 * @arg flags		additional netlink message flags
 *
 * Builds a netlink message by calling rtnl_neigh_build_delete_request(),
 * sends the request to the kernel and waits for the next ACK to be
 * received and thus blocks until the request has been fullfilled.
 *
 * @return 0 on sucess or a negative error if an error occured.
 */
int rtnl_neigh_delete(struct nl_sock *sk, struct rtnl_neigh *neigh,
		      int flags)
{
	struct nl_msg *msg;
	int err;
	
	if ((err = rtnl_neigh_build_delete_request(neigh, flags, &msg)) < 0)
		return err;

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

	return wait_for_ack(sk);
}

/** @} */

/**
 * @name Neighbour States Translations
 * @{
 */

static struct trans_tbl neigh_states[] = {
	__ADD(NUD_INCOMPLETE, incomplete)
	__ADD(NUD_REACHABLE, reachable)
	__ADD(NUD_STALE, stale)
	__ADD(NUD_DELAY, delay)
	__ADD(NUD_PROBE, probe)
	__ADD(NUD_FAILED, failed)
	__ADD(NUD_NOARP, norarp)
	__ADD(NUD_PERMANENT, permanent)
};

char * rtnl_neigh_state2str(int state, char *buf, size_t len)
{
	return __flags2str(state, buf, len, neigh_states,
	    ARRAY_SIZE(neigh_states));
}

int rtnl_neigh_str2state(const char *name)
{
	return __str2type(name, neigh_states, ARRAY_SIZE(neigh_states));
}

/** @} */

/**
 * @name Neighbour Flags Translations
 * @{
 */

static struct trans_tbl neigh_flags[] = {
	__ADD(NTF_PROXY, proxy)
	__ADD(NTF_ROUTER, router)
};

char * rtnl_neigh_flags2str(int flags, char *buf, size_t len)
{
	return __flags2str(flags, buf, len, neigh_flags,
	    ARRAY_SIZE(neigh_flags));
}

int rtnl_neigh_str2flag(const char *name)
{
	return __str2type(name, neigh_flags, ARRAY_SIZE(neigh_flags));
}

/** @} */

/**
 * @name Attributes
 * @{
 */

void rtnl_neigh_set_state(struct rtnl_neigh *neigh, int state)
{
	neigh->n_state_mask |= state;
	neigh->n_state |= state;
	neigh->ce_mask |= NEIGH_ATTR_STATE;
}

int rtnl_neigh_get_state(struct rtnl_neigh *neigh)
{
	if (neigh->ce_mask & NEIGH_ATTR_STATE)
		return neigh->n_state;
	else
		return -1;
}

void rtnl_neigh_unset_state(struct rtnl_neigh *neigh, int state)
{
	neigh->n_state_mask |= state;
	neigh->n_state &= ~state;
	neigh->ce_mask |= NEIGH_ATTR_STATE;
}

void rtnl_neigh_set_flags(struct rtnl_neigh *neigh, unsigned int flags)
{
	neigh->n_flag_mask |= flags;
	neigh->n_flags |= flags;
	neigh->ce_mask |= NEIGH_ATTR_FLAGS;
}

unsigned int rtnl_neigh_get_flags(struct rtnl_neigh *neigh)
{
	return neigh->n_flags;
}

void rtnl_neigh_unset_flags(struct rtnl_neigh *neigh, unsigned int flags)
{
	neigh->n_flag_mask |= flags;
	neigh->n_flags &= ~flags;
	neigh->ce_mask |= NEIGH_ATTR_FLAGS;
}

void rtnl_neigh_set_ifindex(struct rtnl_neigh *neigh, int ifindex)
{
	neigh->n_ifindex = ifindex;
	neigh->ce_mask |= NEIGH_ATTR_IFINDEX;
}

int rtnl_neigh_get_ifindex(struct rtnl_neigh *neigh)
{
	return neigh->n_ifindex;
}

static inline int __assign_addr(struct rtnl_neigh *neigh, struct nl_addr **pos,
			        struct nl_addr *new, int flag, int nocheck)
{
	if (!nocheck) {
		if (neigh->ce_mask & NEIGH_ATTR_FAMILY) {
			if (new->a_family != neigh->n_family)
				return -NLE_AF_MISMATCH;
		} else {
			neigh->n_family = new->a_family;
			neigh->ce_mask |= NEIGH_ATTR_FAMILY;
		}
	}

	if (*pos)
		nl_addr_put(*pos);

	nl_addr_get(new);
	*pos = new;

	neigh->ce_mask |= flag;

	return 0;
}

void rtnl_neigh_set_lladdr(struct rtnl_neigh *neigh, struct nl_addr *addr)
{
	__assign_addr(neigh, &neigh->n_lladdr, addr, NEIGH_ATTR_LLADDR, 1);
}

struct nl_addr *rtnl_neigh_get_lladdr(struct rtnl_neigh *neigh)
{
	if (neigh->ce_mask & NEIGH_ATTR_LLADDR)
		return neigh->n_lladdr;
	else
		return NULL;
}

int rtnl_neigh_set_dst(struct rtnl_neigh *neigh, struct nl_addr *addr)
{
	return __assign_addr(neigh, &neigh->n_dst, addr,
			     NEIGH_ATTR_DST, 0);
}

struct nl_addr *rtnl_neigh_get_dst(struct rtnl_neigh *neigh)
{
	if (neigh->ce_mask & NEIGH_ATTR_DST)
		return neigh->n_dst;
	else
		return NULL;
}

void rtnl_neigh_set_family(struct rtnl_neigh *neigh, int family)
{
	neigh->n_family = family;
	neigh->ce_mask |= NEIGH_ATTR_FAMILY;
}

int rtnl_neigh_get_family(struct rtnl_neigh *neigh)
{
	return neigh->n_family;
}

void rtnl_neigh_set_type(struct rtnl_neigh *neigh, int type)
{
	neigh->n_type = type;
	neigh->ce_mask = NEIGH_ATTR_TYPE;
}

int rtnl_neigh_get_type(struct rtnl_neigh *neigh)
{
	if (neigh->ce_mask & NEIGH_ATTR_TYPE)
		return neigh->n_type;
	else
		return -1;
}

/** @} */

static struct nl_object_ops neigh_obj_ops = {
	.oo_name		= "route/neigh",
	.oo_size		= sizeof(struct rtnl_neigh),
	.oo_free_data		= neigh_free_data,
	.oo_clone		= neigh_clone,
	.oo_dump = {
	    [NL_DUMP_LINE]	= neigh_dump_line,
	    [NL_DUMP_DETAILS]	= neigh_dump_details,
	    [NL_DUMP_STATS]	= neigh_dump_stats,
	    [NL_DUMP_ENV]	= neigh_dump_env,
	},
	.oo_compare		= neigh_compare,
	.oo_attrs2str		= neigh_attrs2str,
	.oo_id_attrs		= (NEIGH_ATTR_IFINDEX | NEIGH_ATTR_DST | NEIGH_ATTR_FAMILY),
};

static struct nl_af_group neigh_groups[] = {
	{ AF_UNSPEC, RTNLGRP_NEIGH },
	{ END_OF_GROUP_LIST },
};

static struct nl_cache_ops rtnl_neigh_ops = {
	.co_name		= "route/neigh",
	.co_hdrsize		= sizeof(struct ndmsg),
	.co_msgtypes		= {
					{ RTM_NEWNEIGH, NL_ACT_NEW, "new" },
					{ RTM_DELNEIGH, NL_ACT_DEL, "del" },
					{ RTM_GETNEIGH, NL_ACT_GET, "get" },
					END_OF_MSGTYPES_LIST,
				  },
	.co_protocol		= NETLINK_ROUTE,
	.co_groups		= neigh_groups,
	.co_request_update	= neigh_request_update,
	.co_msg_parser		= neigh_msg_parser,
	.co_obj_ops		= &neigh_obj_ops,
};

static void __init neigh_init(void)
{
	nl_cache_mngt_register(&rtnl_neigh_ops);
}

static void __exit neigh_exit(void)
{
	nl_cache_mngt_unregister(&rtnl_neigh_ops);
}

/** @} */
