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