Home | History | Annotate | Download | only in route
      1 /*
      2  * lib/route/neigh.c	Neighbours
      3  *
      4  *	This library is free software; you can redistribute it and/or
      5  *	modify it under the terms of the GNU Lesser General Public
      6  *	License as published by the Free Software Foundation version 2.1
      7  *	of the License.
      8  *
      9  * Copyright (c) 2003-2008 Thomas Graf <tgraf (at) suug.ch>
     10  */
     11 
     12 /**
     13  * @ingroup rtnl
     14  * @defgroup neigh Neighbours
     15  * @brief
     16  *
     17  * The neighbour table establishes bindings between protocol addresses and
     18  * link layer addresses for hosts sharing the same physical link. This
     19  * module allows you to access and manipulate the content of these tables.
     20  *
     21  * @par Neighbour States
     22  * @code
     23  * NUD_INCOMPLETE
     24  * NUD_REACHABLE
     25  * NUD_STALE
     26  * NUD_DELAY
     27  * NUD_PROBE
     28  * NUD_FAILED
     29  * NUD_NOARP
     30  * NUD_PERMANENT
     31  * @endcode
     32  *
     33  * @par Neighbour Flags
     34  * @code
     35  * NTF_USE
     36  * NTF_PROXY
     37  * NTF_ROUTER
     38  * @endcode
     39  *
     40  * @par Neighbour Identification
     41  * A neighbour is uniquely identified by the attributes listed below, whenever
     42  * you refer to an existing neighbour all of the attributes must be set.
     43  * Neighbours from caches automatically have all required attributes set.
     44  *   - interface index (rtnl_neigh_set_ifindex())
     45  *   - destination address (rtnl_neigh_set_dst())
     46  *
     47  * @par Changeable Attributes
     48  * \anchor neigh_changeable
     49  *  - state (rtnl_neigh_set_state())
     50  *  - link layer address (rtnl_neigh_set_lladdr())
     51  *
     52  * @par Required Caches for Dumping
     53  * In order to dump neighbour attributes you must provide the following
     54  * caches via nl_cache_provide()
     55  *  - link cache holding all links
     56  *
     57  * @par TODO
     58  *   - Document proxy settings
     59  *   - Document states and their influence
     60  *
     61  * @par 1) Retrieving information about configured neighbours
     62  * @code
     63  * // The first step is to retrieve a list of all available neighbour within
     64  * // the kernel and put them into a cache.
     65  * struct nl_cache *cache = rtnl_neigh_alloc_cache(sk);
     66  *
     67  * // Neighbours can then be looked up by the interface and destination
     68  * // address:
     69  * struct rtnl_neigh *neigh = rtnl_neigh_get(cache, ifindex, dst_addr);
     70  *
     71  * // After successful usage, the object must be given back to the cache
     72  * rtnl_neigh_put(neigh);
     73  * @endcode
     74  *
     75  * @par 2) Adding new neighbours
     76  * @code
     77  * // Allocate an empty neighbour handle to be filled out with the attributes
     78  * // of the new neighbour.
     79  * struct rtnl_neigh *neigh = rtnl_neigh_alloc();
     80  *
     81  * // Fill out the attributes of the new neighbour
     82  * rtnl_neigh_set_ifindex(neigh, ifindex);
     83  * rtnl_neigh_set_dst(neigh, dst_addr);
     84  * rtnl_neigh_set_state(neigh, rtnl_neigh_str2state("permanent"));
     85  *
     86  * // Build the netlink message and send it to the kernel, the operation will
     87  * // block until the operation has been completed. Alternatively the required
     88  * // netlink message can be built using rtnl_neigh_build_add_request()
     89  * // to be sent out using nl_send_auto_complete().
     90  * rtnl_neigh_add(sk, neigh, NLM_F_CREATE);
     91  *
     92  * // Free the memory
     93  * rtnl_neigh_put(neigh);
     94  * @endcode
     95  *
     96  * @par 3) Deleting an existing neighbour
     97  * @code
     98  * // Allocate an empty neighbour object to be filled out with the attributes
     99  * // matching the neighbour to be deleted. Alternatively a fully equipped
    100  * // neighbour object out of a cache can be used instead.
    101  * struct rtnl_neigh *neigh = rtnl_neigh_alloc();
    102  *
    103  * // Neighbours are uniquely identified by their interface index and
    104  * // destination address, you may fill out other attributes but they
    105  * // will have no influence.
    106  * rtnl_neigh_set_ifindex(neigh, ifindex);
    107  * rtnl_neigh_set_dst(neigh, dst_addr);
    108  *
    109  * // Build the netlink message and send it to the kernel, the operation will
    110  * // block until the operation has been completed. Alternatively the required
    111  * // netlink message can be built using rtnl_neigh_build_delete_request()
    112  * // to be sent out using nl_send_auto_complete().
    113  * rtnl_neigh_delete(sk, neigh, 0);
    114  *
    115  * // Free the memory
    116  * rtnl_neigh_put(neigh);
    117  * @endcode
    118  *
    119  * @par 4) Changing neighbour attributes
    120  * @code
    121  * // Allocate an empty neighbour object to be filled out with the attributes
    122  * // matching the neighbour to be changed and the new parameters. Alternatively
    123  * // a fully equipped modified neighbour object out of a cache can be used.
    124  * struct rtnl_neigh *neigh = rtnl_neigh_alloc();
    125  *
    126  * // Identify the neighbour to be changed by its interface index and
    127  * // destination address
    128  * rtnl_neigh_set_ifindex(neigh, ifindex);
    129  * rtnl_neigh_set_dst(neigh, dst_addr);
    130  *
    131  * // The link layer address may be modified, if so it is wise to change
    132  * // its state to "permanent" in order to avoid having it overwritten.
    133  * rtnl_neigh_set_lladdr(neigh, lladdr);
    134  *
    135  * // Secondly the state can be modified allowing normal neighbours to be
    136  * // converted into permanent entries or to manually confirm a neighbour.
    137  * rtnl_neigh_set_state(neigh, state);
    138  *
    139  * // Build the netlink message and send it to the kernel, the operation will
    140  * // block until the operation has been completed. Alternatively the required
    141  * // netlink message can be built using rtnl_neigh_build_change_request()
    142  * // to be sent out using nl_send_auto_complete().
    143  * rtnl_neigh_add(sk, neigh, NLM_F_REPLACE);
    144  *
    145  * // Free the memory
    146  * rtnl_neigh_put(neigh);
    147  * @endcode
    148  * @{
    149  */
    150 
    151 #include <netlink-private/netlink.h>
    152 #include <netlink/netlink.h>
    153 #include <netlink/utils.h>
    154 #include <netlink/hashtable.h>
    155 #include <netlink/route/rtnl.h>
    156 #include <netlink/route/neighbour.h>
    157 #include <netlink/route/link.h>
    158 #include <netlink/hashtable.h>
    159 
    160 /** @cond SKIP */
    161 #define NEIGH_ATTR_FLAGS        0x01
    162 #define NEIGH_ATTR_STATE        0x02
    163 #define NEIGH_ATTR_LLADDR       0x04
    164 #define NEIGH_ATTR_DST          0x08
    165 #define NEIGH_ATTR_CACHEINFO    0x10
    166 #define NEIGH_ATTR_IFINDEX      0x20
    167 #define NEIGH_ATTR_FAMILY       0x40
    168 #define NEIGH_ATTR_TYPE         0x80
    169 #define NEIGH_ATTR_PROBES       0x100
    170 #define NEIGH_ATTR_MASTER       0x200
    171 
    172 static struct nl_cache_ops rtnl_neigh_ops;
    173 static struct nl_object_ops neigh_obj_ops;
    174 /** @endcond */
    175 
    176 static void neigh_free_data(struct nl_object *c)
    177 {
    178 	struct rtnl_neigh *neigh = nl_object_priv(c);
    179 
    180 	if (!neigh)
    181 		return;
    182 
    183 	nl_addr_put(neigh->n_lladdr);
    184 	nl_addr_put(neigh->n_dst);
    185 }
    186 
    187 static int neigh_clone(struct nl_object *_dst, struct nl_object *_src)
    188 {
    189 	struct rtnl_neigh *dst = nl_object_priv(_dst);
    190 	struct rtnl_neigh *src = nl_object_priv(_src);
    191 
    192 	if (src->n_lladdr)
    193 		if (!(dst->n_lladdr = nl_addr_clone(src->n_lladdr)))
    194 			return -NLE_NOMEM;
    195 
    196 	if (src->n_dst)
    197 		if (!(dst->n_dst = nl_addr_clone(src->n_dst)))
    198 			return -NLE_NOMEM;
    199 
    200 	return 0;
    201 }
    202 
    203 static void neigh_keygen(struct nl_object *obj, uint32_t *hashkey,
    204 			 uint32_t table_sz)
    205 {
    206 	struct rtnl_neigh *neigh = (struct rtnl_neigh *) obj;
    207 	unsigned int nkey_sz;
    208 	struct nl_addr *addr = NULL;
    209 	struct neigh_hash_key {
    210 		uint32_t	n_family;
    211 		uint32_t	n_ifindex;
    212 		char		n_addr[0];
    213 	} __attribute__((packed)) *nkey;
    214 #ifdef NL_DEBUG
    215 	char buf[INET6_ADDRSTRLEN+5];
    216 #endif
    217 
    218 	if (neigh->n_family == AF_BRIDGE) {
    219 		if (neigh->n_lladdr)
    220 			addr = neigh->n_lladdr;
    221 	} else if (neigh->n_dst) {
    222 		addr = neigh->n_dst;
    223 	}
    224 
    225 	nkey_sz = sizeof(*nkey);
    226 	if (addr)
    227 		nkey_sz += nl_addr_get_len(addr);
    228 
    229 	nkey = calloc(1, nkey_sz);
    230 	if (!nkey) {
    231 		*hashkey = 0;
    232 		return;
    233 	}
    234 	nkey->n_family = neigh->n_family;
    235 	if (neigh->n_family == AF_BRIDGE)
    236 		nkey->n_ifindex = neigh->n_master;
    237 	else
    238 		nkey->n_ifindex = neigh->n_ifindex;
    239 	if (addr)
    240 		memcpy(nkey->n_addr,
    241 			nl_addr_get_binary_addr(addr),
    242 			nl_addr_get_len(addr));
    243 
    244 	*hashkey = nl_hash(nkey, nkey_sz, 0) % table_sz;
    245 
    246 	NL_DBG(5, "neigh %p key (fam %d dev %d addr %s) keysz %d hash 0x%x\n",
    247 		neigh, nkey->n_family, nkey->n_ifindex,
    248 		nl_addr2str(addr, buf, sizeof(buf)),
    249 		nkey_sz, *hashkey);
    250 
    251 	free(nkey);
    252 
    253 	return;
    254 }
    255 
    256 static int neigh_compare(struct nl_object *_a, struct nl_object *_b,
    257 			uint32_t attrs, int flags)
    258 {
    259 	struct rtnl_neigh *a = (struct rtnl_neigh *) _a;
    260 	struct rtnl_neigh *b = (struct rtnl_neigh *) _b;
    261 	int diff = 0;
    262 
    263 #define NEIGH_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, NEIGH_ATTR_##ATTR, a, b, EXPR)
    264 
    265 	diff |= NEIGH_DIFF(IFINDEX,	a->n_ifindex != b->n_ifindex);
    266 	diff |= NEIGH_DIFF(FAMILY,	a->n_family != b->n_family);
    267 	diff |= NEIGH_DIFF(TYPE,	a->n_type != b->n_type);
    268 	diff |= NEIGH_DIFF(LLADDR,	nl_addr_cmp(a->n_lladdr, b->n_lladdr));
    269 	diff |= NEIGH_DIFF(DST,		nl_addr_cmp(a->n_dst, b->n_dst));
    270 	diff |= NEIGH_DIFF(MASTER,	a->n_master != b->n_master);
    271 
    272 	if (flags & LOOSE_COMPARISON) {
    273 		diff |= NEIGH_DIFF(STATE,
    274 				  (a->n_state ^ b->n_state) & b->n_state_mask);
    275 		diff |= NEIGH_DIFF(FLAGS,
    276 				  (a->n_flags ^ b->n_flags) & b->n_flag_mask);
    277 	} else {
    278 		diff |= NEIGH_DIFF(STATE, a->n_state != b->n_state);
    279 		diff |= NEIGH_DIFF(FLAGS, a->n_flags != b->n_flags);
    280 	}
    281 
    282 #undef NEIGH_DIFF
    283 
    284 	return diff;
    285 }
    286 
    287 static const struct trans_tbl neigh_attrs[] = {
    288 	__ADD(NEIGH_ATTR_FLAGS, flags)
    289 	__ADD(NEIGH_ATTR_STATE, state)
    290 	__ADD(NEIGH_ATTR_LLADDR, lladdr)
    291 	__ADD(NEIGH_ATTR_DST, dst)
    292 	__ADD(NEIGH_ATTR_CACHEINFO, cacheinfo)
    293 	__ADD(NEIGH_ATTR_IFINDEX, ifindex)
    294 	__ADD(NEIGH_ATTR_FAMILY, family)
    295 	__ADD(NEIGH_ATTR_TYPE, type)
    296 	__ADD(NEIGH_ATTR_PROBES, probes)
    297 };
    298 
    299 static char *neigh_attrs2str(int attrs, char *buf, size_t len)
    300 {
    301 	return __flags2str(attrs, buf, len, neigh_attrs,
    302 			   ARRAY_SIZE(neigh_attrs));
    303 }
    304 
    305 static uint32_t neigh_id_attrs_get(struct nl_object *obj)
    306 {
    307 	struct rtnl_neigh *neigh = (struct rtnl_neigh *)obj;
    308 
    309 	if (neigh->n_family == AF_BRIDGE)
    310 		return (NEIGH_ATTR_LLADDR | NEIGH_ATTR_FAMILY | NEIGH_ATTR_MASTER);
    311 	else
    312 		return (NEIGH_ATTR_IFINDEX | NEIGH_ATTR_DST | NEIGH_ATTR_FAMILY);
    313 }
    314 
    315 static struct nla_policy neigh_policy[NDA_MAX+1] = {
    316 	[NDA_CACHEINFO]	= { .minlen = sizeof(struct nda_cacheinfo) },
    317 	[NDA_PROBES]	= { .type = NLA_U32 },
    318 };
    319 
    320 static int neigh_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
    321 			    struct nlmsghdr *n, struct nl_parser_param *pp)
    322 {
    323 	struct rtnl_neigh *neigh;
    324 	int err;
    325 
    326 	if ((err = rtnl_neigh_parse(n, &neigh)) < 0)
    327 		return err;
    328 
    329 	err = pp->pp_cb((struct nl_object *) neigh, pp);
    330 
    331 	rtnl_neigh_put(neigh);
    332 	return err;
    333 }
    334 
    335 
    336 int rtnl_neigh_parse(struct nlmsghdr *n, struct rtnl_neigh **result)
    337 {
    338 	struct rtnl_neigh *neigh;
    339 	struct nlattr *tb[NDA_MAX + 1];
    340 	struct ndmsg *nm;
    341 	int err;
    342 
    343 	neigh = rtnl_neigh_alloc();
    344 	if (!neigh) {
    345 		err = -NLE_NOMEM;
    346 		goto errout;
    347 	}
    348 
    349 	neigh->ce_msgtype = n->nlmsg_type;
    350 	nm = nlmsg_data(n);
    351 
    352 	err = nlmsg_parse(n, sizeof(*nm), tb, NDA_MAX, neigh_policy);
    353 	if (err < 0)
    354 		goto errout;
    355 
    356 	neigh->n_family  = nm->ndm_family;
    357 	neigh->n_ifindex = nm->ndm_ifindex;
    358 	neigh->n_state   = nm->ndm_state;
    359 	neigh->n_flags   = nm->ndm_flags;
    360 	neigh->n_type    = nm->ndm_type;
    361 
    362 	neigh->ce_mask |= (NEIGH_ATTR_FAMILY | NEIGH_ATTR_IFINDEX |
    363 			   NEIGH_ATTR_STATE | NEIGH_ATTR_FLAGS |
    364 			   NEIGH_ATTR_TYPE);
    365 
    366 	if (tb[NDA_LLADDR]) {
    367 		neigh->n_lladdr = nl_addr_alloc_attr(tb[NDA_LLADDR], AF_UNSPEC);
    368 		if (!neigh->n_lladdr) {
    369 			err = -NLE_NOMEM;
    370 			goto errout;
    371 		}
    372 		nl_addr_set_family(neigh->n_lladdr,
    373 				   nl_addr_guess_family(neigh->n_lladdr));
    374 		neigh->ce_mask |= NEIGH_ATTR_LLADDR;
    375 	}
    376 
    377 	if (tb[NDA_DST]) {
    378 		neigh->n_dst = nl_addr_alloc_attr(tb[NDA_DST], neigh->n_family);
    379 		if (!neigh->n_dst) {
    380 			err = -NLE_NOMEM;
    381 			goto errout;
    382 		}
    383 		neigh->ce_mask |= NEIGH_ATTR_DST;
    384 	}
    385 
    386 	if (tb[NDA_CACHEINFO]) {
    387 		struct nda_cacheinfo *ci = nla_data(tb[NDA_CACHEINFO]);
    388 
    389 		neigh->n_cacheinfo.nci_confirmed = ci->ndm_confirmed;
    390 		neigh->n_cacheinfo.nci_used = ci->ndm_used;
    391 		neigh->n_cacheinfo.nci_updated = ci->ndm_updated;
    392 		neigh->n_cacheinfo.nci_refcnt = ci->ndm_refcnt;
    393 
    394 		neigh->ce_mask |= NEIGH_ATTR_CACHEINFO;
    395 	}
    396 
    397 	if (tb[NDA_PROBES]) {
    398 		neigh->n_probes = nla_get_u32(tb[NDA_PROBES]);
    399 		neigh->ce_mask |= NEIGH_ATTR_PROBES;
    400 	}
    401 
    402 	/*
    403 	 * Get the bridge index for AF_BRIDGE family entries
    404 	 */
    405 	if (neigh->n_family == AF_BRIDGE) {
    406 		struct nl_cache *lcache = nl_cache_mngt_require_safe("route/link");
    407 		if (lcache ) {
    408 			struct rtnl_link *link = rtnl_link_get(lcache,
    409 							neigh->n_ifindex);
    410 			if (link) {
    411 				neigh->n_master = link->l_master;
    412 				rtnl_link_put(link);
    413 				neigh->ce_mask |= NEIGH_ATTR_MASTER;
    414 			}
    415 
    416 			nl_cache_put(lcache);
    417 		}
    418 	}
    419 
    420 	*result = neigh;
    421 	return 0;
    422 
    423 errout:
    424 	rtnl_neigh_put(neigh);
    425 	return err;
    426 }
    427 
    428 static int neigh_request_update(struct nl_cache *c, struct nl_sock *h)
    429 {
    430 	int family = c->c_iarg1;
    431 
    432 	return nl_rtgen_request(h, RTM_GETNEIGH, family, NLM_F_DUMP);
    433 }
    434 
    435 
    436 static void neigh_dump_line(struct nl_object *a, struct nl_dump_params *p)
    437 {
    438 	char dst[INET6_ADDRSTRLEN+5], lladdr[INET6_ADDRSTRLEN+5];
    439 	struct rtnl_neigh *n = (struct rtnl_neigh *) a;
    440 	struct nl_cache *link_cache;
    441 	char state[128], flags[64];
    442 
    443 	link_cache = nl_cache_mngt_require_safe("route/link");
    444 
    445 	if (n->n_family != AF_BRIDGE)
    446 		nl_dump_line(p, "%s ", nl_addr2str(n->n_dst, dst, sizeof(dst)));
    447 
    448 	if (link_cache)
    449 		nl_dump(p, "dev %s ",
    450 			rtnl_link_i2name(link_cache, n->n_ifindex,
    451 					 state, sizeof(state)));
    452 	else
    453 		nl_dump(p, "dev %d ", n->n_ifindex);
    454 
    455 	if (n->ce_mask & NEIGH_ATTR_LLADDR)
    456 		nl_dump(p, "lladdr %s ",
    457 			nl_addr2str(n->n_lladdr, lladdr, sizeof(lladdr)));
    458 
    459 	rtnl_neigh_state2str(n->n_state, state, sizeof(state));
    460 	rtnl_neigh_flags2str(n->n_flags, flags, sizeof(flags));
    461 
    462 	if (state[0])
    463 		nl_dump(p, "<%s", state);
    464 	if (flags[0])
    465 		nl_dump(p, "%s%s", state[0] ? "," : "<", flags);
    466 	if (state[0] || flags[0])
    467 		nl_dump(p, ">");
    468 	nl_dump(p, "\n");
    469 
    470 	if (link_cache)
    471 		nl_cache_put(link_cache);
    472 }
    473 
    474 static void neigh_dump_details(struct nl_object *a, struct nl_dump_params *p)
    475 {
    476 	char rtn_type[32];
    477 	struct rtnl_neigh *n = (struct rtnl_neigh *) a;
    478 	int hz = nl_get_user_hz();
    479 
    480 	neigh_dump_line(a, p);
    481 
    482 	nl_dump_line(p, "    refcnt %u type %s confirmed %u used "
    483 				"%u updated %u\n",
    484 		n->n_cacheinfo.nci_refcnt,
    485 		nl_rtntype2str(n->n_type, rtn_type, sizeof(rtn_type)),
    486 		n->n_cacheinfo.nci_confirmed/hz,
    487 		n->n_cacheinfo.nci_used/hz, n->n_cacheinfo.nci_updated/hz);
    488 }
    489 
    490 static void neigh_dump_stats(struct nl_object *a, struct nl_dump_params *p)
    491 {
    492 	neigh_dump_details(a, p);
    493 }
    494 
    495 /**
    496  * @name Neighbour Object Allocation/Freeage
    497  * @{
    498  */
    499 
    500 struct rtnl_neigh *rtnl_neigh_alloc(void)
    501 {
    502 	return (struct rtnl_neigh *) nl_object_alloc(&neigh_obj_ops);
    503 }
    504 
    505 void rtnl_neigh_put(struct rtnl_neigh *neigh)
    506 {
    507 	nl_object_put((struct nl_object *) neigh);
    508 }
    509 
    510 /** @} */
    511 
    512 /**
    513  * @name Neighbour Cache Managament
    514  * @{
    515  */
    516 
    517 /**
    518  * Build a neighbour cache including all neighbours currently configured in the kernel.
    519  * @arg sock		Netlink socket.
    520  * @arg result		Pointer to store resulting cache.
    521  *
    522  * Allocates a new neighbour cache, initializes it properly and updates it
    523  * to include all neighbours currently configured in the kernel.
    524  *
    525  * @return 0 on success or a negative error code.
    526  */
    527 int rtnl_neigh_alloc_cache(struct nl_sock *sock, struct nl_cache **result)
    528 {
    529 	return nl_cache_alloc_and_fill(&rtnl_neigh_ops, sock, result);
    530 }
    531 
    532 /**
    533  * Look up a neighbour by interface index and destination address
    534  * @arg cache		neighbour cache
    535  * @arg ifindex		interface index the neighbour is on
    536  * @arg dst		destination address of the neighbour
    537  *
    538  * @return neighbour handle or NULL if no match was found.
    539  */
    540 struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *cache, int ifindex,
    541 				   struct nl_addr *dst)
    542 {
    543 	struct rtnl_neigh *neigh;
    544 
    545 	nl_list_for_each_entry(neigh, &cache->c_items, ce_list) {
    546 		if (neigh->n_ifindex == ifindex &&
    547 		    !nl_addr_cmp(neigh->n_dst, dst)) {
    548 			nl_object_get((struct nl_object *) neigh);
    549 			return neigh;
    550 		}
    551 	}
    552 
    553 	return NULL;
    554 }
    555 
    556 /** @} */
    557 
    558 /**
    559  * @name Neighbour Addition
    560  * @{
    561  */
    562 
    563 static int build_neigh_msg(struct rtnl_neigh *tmpl, int cmd, int flags,
    564 			   struct nl_msg **result)
    565 {
    566 	struct nl_msg *msg;
    567 	struct ndmsg nhdr = {
    568 		.ndm_ifindex = tmpl->n_ifindex,
    569 		.ndm_state = NUD_PERMANENT,
    570 	};
    571 
    572 	if (tmpl->n_family != AF_BRIDGE) {
    573 		if (!(tmpl->ce_mask & NEIGH_ATTR_DST))
    574 			return -NLE_MISSING_ATTR;
    575 		nhdr.ndm_family = nl_addr_get_family(tmpl->n_dst);
    576 	}
    577 	else
    578 		nhdr.ndm_family = AF_BRIDGE;
    579 
    580 	if (tmpl->ce_mask & NEIGH_ATTR_FLAGS)
    581 		nhdr.ndm_flags = tmpl->n_flags;
    582 
    583 	if (tmpl->ce_mask & NEIGH_ATTR_STATE)
    584 		nhdr.ndm_state = tmpl->n_state;
    585 
    586 	msg = nlmsg_alloc_simple(cmd, flags);
    587 	if (!msg)
    588 		return -NLE_NOMEM;
    589 
    590 	if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0)
    591 		goto nla_put_failure;
    592 
    593 	if (tmpl->n_family != AF_BRIDGE)
    594 		NLA_PUT_ADDR(msg, NDA_DST, tmpl->n_dst);
    595 
    596 	if (tmpl->ce_mask & NEIGH_ATTR_LLADDR)
    597 		NLA_PUT_ADDR(msg, NDA_LLADDR, tmpl->n_lladdr);
    598 
    599 	*result = msg;
    600 	return 0;
    601 
    602 nla_put_failure:
    603 	nlmsg_free(msg);
    604 	return -NLE_MSGSIZE;
    605 }
    606 
    607 /**
    608  * Build netlink request message to add a new neighbour
    609  * @arg tmpl		template with data of new neighbour
    610  * @arg flags		additional netlink message flags
    611  * @arg result		Pointer to store resulting message.
    612  *
    613  * Builds a new netlink message requesting a addition of a new
    614  * neighbour. The netlink message header isn't fully equipped with
    615  * all relevant fields and must thus be sent out via nl_send_auto_complete()
    616  * or supplemented as needed. \a tmpl must contain the attributes of the new
    617  * neighbour set via \c rtnl_neigh_set_* functions.
    618  *
    619  * The following attributes must be set in the template:
    620  *  - Interface index (rtnl_neigh_set_ifindex())
    621  *  - State (rtnl_neigh_set_state())
    622  *  - Destination address (rtnl_neigh_set_dst())
    623  *  - Link layer address (rtnl_neigh_set_lladdr())
    624  *
    625  * @return 0 on success or a negative error code.
    626  */
    627 int rtnl_neigh_build_add_request(struct rtnl_neigh *tmpl, int flags,
    628 				 struct nl_msg **result)
    629 {
    630 	return build_neigh_msg(tmpl, RTM_NEWNEIGH, flags, result);
    631 }
    632 
    633 /**
    634  * Add a new neighbour
    635  * @arg sk		Netlink socket.
    636  * @arg tmpl		template with requested changes
    637  * @arg flags		additional netlink message flags
    638  *
    639  * Builds a netlink message by calling rtnl_neigh_build_add_request(),
    640  * sends the request to the kernel and waits for the next ACK to be
    641  * received and thus blocks until the request has been fullfilled.
    642  *
    643  * The following attributes must be set in the template:
    644  *  - Interface index (rtnl_neigh_set_ifindex())
    645  *  - State (rtnl_neigh_set_state())
    646  *  - Destination address (rtnl_neigh_set_dst())
    647  *  - Link layer address (rtnl_neigh_set_lladdr())
    648  *
    649  * @return 0 on sucess or a negative error if an error occured.
    650  */
    651 int rtnl_neigh_add(struct nl_sock *sk, struct rtnl_neigh *tmpl, int flags)
    652 {
    653 	int err;
    654 	struct nl_msg *msg;
    655 
    656 	if ((err = rtnl_neigh_build_add_request(tmpl, flags, &msg)) < 0)
    657 		return err;
    658 
    659 	err = nl_send_auto_complete(sk, msg);
    660 	nlmsg_free(msg);
    661 	if (err < 0)
    662 		return err;
    663 
    664 	return wait_for_ack(sk);
    665 }
    666 
    667 /** @} */
    668 
    669 /**
    670  * @name Neighbour Deletion
    671  * @{
    672  */
    673 
    674 /**
    675  * Build a netlink request message to delete a neighbour
    676  * @arg neigh		neighbour to delete
    677  * @arg flags		additional netlink message flags
    678  * @arg result		Pointer to store resulting message.
    679  *
    680  * Builds a new netlink message requesting a deletion of a neighbour.
    681  * The netlink message header isn't fully equipped with all relevant
    682  * fields and must thus be sent out via nl_send_auto_complete()
    683  * or supplemented as needed. \a neigh must point to an existing
    684  * neighbour.
    685  *
    686  * @return 0 on success or a negative error code.
    687  */
    688 int rtnl_neigh_build_delete_request(struct rtnl_neigh *neigh, int flags,
    689 				    struct nl_msg **result)
    690 {
    691 	return build_neigh_msg(neigh, RTM_DELNEIGH, flags, result);
    692 }
    693 
    694 /**
    695  * Delete a neighbour
    696  * @arg sk		Netlink socket.
    697  * @arg neigh		neighbour to delete
    698  * @arg flags		additional netlink message flags
    699  *
    700  * Builds a netlink message by calling rtnl_neigh_build_delete_request(),
    701  * sends the request to the kernel and waits for the next ACK to be
    702  * received and thus blocks until the request has been fullfilled.
    703  *
    704  * @return 0 on sucess or a negative error if an error occured.
    705  */
    706 int rtnl_neigh_delete(struct nl_sock *sk, struct rtnl_neigh *neigh,
    707 		      int flags)
    708 {
    709 	struct nl_msg *msg;
    710 	int err;
    711 
    712 	if ((err = rtnl_neigh_build_delete_request(neigh, flags, &msg)) < 0)
    713 		return err;
    714 
    715 	err = nl_send_auto_complete(sk, msg);
    716 	nlmsg_free(msg);
    717 	if (err < 0)
    718 		return err;
    719 
    720 	return wait_for_ack(sk);
    721 }
    722 
    723 /** @} */
    724 
    725 /**
    726  * @name Neighbour States Translations
    727  * @{
    728  */
    729 
    730 static const struct trans_tbl neigh_states[] = {
    731 	__ADD(NUD_INCOMPLETE, incomplete)
    732 	__ADD(NUD_REACHABLE, reachable)
    733 	__ADD(NUD_STALE, stale)
    734 	__ADD(NUD_DELAY, delay)
    735 	__ADD(NUD_PROBE, probe)
    736 	__ADD(NUD_FAILED, failed)
    737 	__ADD(NUD_NOARP, norarp)
    738 	__ADD(NUD_PERMANENT, permanent)
    739 };
    740 
    741 char * rtnl_neigh_state2str(int state, char *buf, size_t len)
    742 {
    743 	return __flags2str(state, buf, len, neigh_states,
    744 	    ARRAY_SIZE(neigh_states));
    745 }
    746 
    747 int rtnl_neigh_str2state(const char *name)
    748 {
    749 	return __str2type(name, neigh_states, ARRAY_SIZE(neigh_states));
    750 }
    751 
    752 /** @} */
    753 
    754 /**
    755  * @name Neighbour Flags Translations
    756  * @{
    757  */
    758 
    759 static const struct trans_tbl neigh_flags[] = {
    760 	__ADD(NTF_USE, use)
    761 	__ADD(NTF_PROXY, proxy)
    762 	__ADD(NTF_ROUTER, router)
    763 };
    764 
    765 char * rtnl_neigh_flags2str(int flags, char *buf, size_t len)
    766 {
    767 	return __flags2str(flags, buf, len, neigh_flags,
    768 	    ARRAY_SIZE(neigh_flags));
    769 }
    770 
    771 int rtnl_neigh_str2flag(const char *name)
    772 {
    773 	return __str2type(name, neigh_flags, ARRAY_SIZE(neigh_flags));
    774 }
    775 
    776 /** @} */
    777 
    778 /**
    779  * @name Attributes
    780  * @{
    781  */
    782 
    783 void rtnl_neigh_set_state(struct rtnl_neigh *neigh, int state)
    784 {
    785 	neigh->n_state_mask |= state;
    786 	neigh->n_state |= state;
    787 	neigh->ce_mask |= NEIGH_ATTR_STATE;
    788 }
    789 
    790 int rtnl_neigh_get_state(struct rtnl_neigh *neigh)
    791 {
    792 	if (neigh->ce_mask & NEIGH_ATTR_STATE)
    793 		return neigh->n_state;
    794 	else
    795 		return -1;
    796 }
    797 
    798 void rtnl_neigh_unset_state(struct rtnl_neigh *neigh, int state)
    799 {
    800 	neigh->n_state_mask |= state;
    801 	neigh->n_state &= ~state;
    802 	neigh->ce_mask |= NEIGH_ATTR_STATE;
    803 }
    804 
    805 void rtnl_neigh_set_flags(struct rtnl_neigh *neigh, unsigned int flags)
    806 {
    807 	neigh->n_flag_mask |= flags;
    808 	neigh->n_flags |= flags;
    809 	neigh->ce_mask |= NEIGH_ATTR_FLAGS;
    810 }
    811 
    812 unsigned int rtnl_neigh_get_flags(struct rtnl_neigh *neigh)
    813 {
    814 	return neigh->n_flags;
    815 }
    816 
    817 void rtnl_neigh_unset_flags(struct rtnl_neigh *neigh, unsigned int flags)
    818 {
    819 	neigh->n_flag_mask |= flags;
    820 	neigh->n_flags &= ~flags;
    821 	neigh->ce_mask |= NEIGH_ATTR_FLAGS;
    822 }
    823 
    824 void rtnl_neigh_set_ifindex(struct rtnl_neigh *neigh, int ifindex)
    825 {
    826 	neigh->n_ifindex = ifindex;
    827 	neigh->ce_mask |= NEIGH_ATTR_IFINDEX;
    828 }
    829 
    830 int rtnl_neigh_get_ifindex(struct rtnl_neigh *neigh)
    831 {
    832 	return neigh->n_ifindex;
    833 }
    834 
    835 static inline int __assign_addr(struct rtnl_neigh *neigh, struct nl_addr **pos,
    836 			        struct nl_addr *new, int flag, int nocheck)
    837 {
    838 	if (!nocheck) {
    839 		if (neigh->ce_mask & NEIGH_ATTR_FAMILY) {
    840 			if (new->a_family != neigh->n_family)
    841 				return -NLE_AF_MISMATCH;
    842 		} else {
    843 			neigh->n_family = new->a_family;
    844 			neigh->ce_mask |= NEIGH_ATTR_FAMILY;
    845 		}
    846 	}
    847 
    848 	if (*pos)
    849 		nl_addr_put(*pos);
    850 
    851 	nl_addr_get(new);
    852 	*pos = new;
    853 
    854 	neigh->ce_mask |= flag;
    855 
    856 	return 0;
    857 }
    858 
    859 void rtnl_neigh_set_lladdr(struct rtnl_neigh *neigh, struct nl_addr *addr)
    860 {
    861 	__assign_addr(neigh, &neigh->n_lladdr, addr, NEIGH_ATTR_LLADDR, 1);
    862 }
    863 
    864 struct nl_addr *rtnl_neigh_get_lladdr(struct rtnl_neigh *neigh)
    865 {
    866 	if (neigh->ce_mask & NEIGH_ATTR_LLADDR)
    867 		return neigh->n_lladdr;
    868 	else
    869 		return NULL;
    870 }
    871 
    872 int rtnl_neigh_set_dst(struct rtnl_neigh *neigh, struct nl_addr *addr)
    873 {
    874 	return __assign_addr(neigh, &neigh->n_dst, addr,
    875 			     NEIGH_ATTR_DST, 0);
    876 }
    877 
    878 struct nl_addr *rtnl_neigh_get_dst(struct rtnl_neigh *neigh)
    879 {
    880 	if (neigh->ce_mask & NEIGH_ATTR_DST)
    881 		return neigh->n_dst;
    882 	else
    883 		return NULL;
    884 }
    885 
    886 void rtnl_neigh_set_family(struct rtnl_neigh *neigh, int family)
    887 {
    888 	neigh->n_family = family;
    889 	neigh->ce_mask |= NEIGH_ATTR_FAMILY;
    890 }
    891 
    892 int rtnl_neigh_get_family(struct rtnl_neigh *neigh)
    893 {
    894 	return neigh->n_family;
    895 }
    896 
    897 void rtnl_neigh_set_type(struct rtnl_neigh *neigh, int type)
    898 {
    899 	neigh->n_type = type;
    900 	neigh->ce_mask = NEIGH_ATTR_TYPE;
    901 }
    902 
    903 int rtnl_neigh_get_type(struct rtnl_neigh *neigh)
    904 {
    905 	if (neigh->ce_mask & NEIGH_ATTR_TYPE)
    906 		return neigh->n_type;
    907 	else
    908 		return -1;
    909 }
    910 
    911 /** @} */
    912 
    913 static struct nl_object_ops neigh_obj_ops = {
    914 	.oo_name		= "route/neigh",
    915 	.oo_size		= sizeof(struct rtnl_neigh),
    916 	.oo_free_data		= neigh_free_data,
    917 	.oo_clone		= neigh_clone,
    918 	.oo_dump = {
    919 	    [NL_DUMP_LINE]	= neigh_dump_line,
    920 	    [NL_DUMP_DETAILS]	= neigh_dump_details,
    921 	    [NL_DUMP_STATS]	= neigh_dump_stats,
    922 	},
    923 	.oo_compare		= neigh_compare,
    924 	.oo_keygen		= neigh_keygen,
    925 	.oo_attrs2str		= neigh_attrs2str,
    926 	.oo_id_attrs		= (NEIGH_ATTR_IFINDEX | NEIGH_ATTR_DST | NEIGH_ATTR_FAMILY),
    927 	.oo_id_attrs_get	= neigh_id_attrs_get
    928 };
    929 
    930 static struct nl_af_group neigh_groups[] = {
    931 	{ AF_UNSPEC, RTNLGRP_NEIGH },
    932 	{ AF_BRIDGE, RTNLGRP_NEIGH },
    933 	{ END_OF_GROUP_LIST },
    934 };
    935 
    936 static struct nl_cache_ops rtnl_neigh_ops = {
    937 	.co_name		= "route/neigh",
    938 	.co_hdrsize		= sizeof(struct ndmsg),
    939 	.co_msgtypes		= {
    940 					{ RTM_NEWNEIGH, NL_ACT_NEW, "new" },
    941 					{ RTM_DELNEIGH, NL_ACT_DEL, "del" },
    942 					{ RTM_GETNEIGH, NL_ACT_GET, "get" },
    943 					END_OF_MSGTYPES_LIST,
    944 				  },
    945 	.co_protocol		= NETLINK_ROUTE,
    946 	.co_groups		= neigh_groups,
    947 	.co_request_update	= neigh_request_update,
    948 	.co_msg_parser		= neigh_msg_parser,
    949 	.co_obj_ops		= &neigh_obj_ops,
    950 };
    951 
    952 static void __init neigh_init(void)
    953 {
    954 	nl_cache_mngt_register(&rtnl_neigh_ops);
    955 }
    956 
    957 static void __exit neigh_exit(void)
    958 {
    959 	nl_cache_mngt_unregister(&rtnl_neigh_ops);
    960 }
    961 
    962 /** @} */
    963