2 * lib/route/neigh.c Neighbours
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
9 * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
14 * @defgroup neigh Neighbours
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.
21 * @par Neighbour States
33 * @par Neighbour Flags
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())
46 * @par Changeable Attributes
47 * \anchor neigh_changeable
48 * - state (rtnl_neigh_set_state())
49 * - link layer address (rtnl_neigh_set_lladdr())
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
57 * - Document proxy settings
58 * - Document states and their influence
60 * @par 1) Retrieving information about configured neighbours
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(handle);
66 * // Neighbours can then be looked up by the interface and destination
68 * struct rtnl_neigh *neigh = rtnl_neigh_get(cache, ifindex, dst_addr);
70 * // After successful usage, the object must be given back to the cache
71 * rtnl_neigh_put(neigh);
74 * @par 2) Adding new neighbours
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();
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"));
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(nl_handle, neigh, NLM_F_REPLACE);
92 * rtnl_neigh_put(neigh);
95 * @par 3) Deleting an existing neighbour
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();
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);
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(handle, neigh, 0);
115 * rtnl_neigh_put(neigh);
118 * @par 4) Changing neighbour attributes
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();
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);
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);
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);
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_change(handle, neigh, 0);
145 * rtnl_neigh_put(neigh);
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>
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
168 static struct nl_cache_ops rtnl_neigh_ops;
171 static void neigh_free_data(struct nl_object *c)
173 struct rtnl_neigh *neigh = nl_object_priv(c);
178 nl_addr_put(neigh->n_lladdr);
179 nl_addr_put(neigh->n_dst);
182 static int neigh_filter(struct nl_object *obj, struct nl_object *filter)
184 struct rtnl_neigh *o = (struct rtnl_neigh *) obj;
185 struct rtnl_neigh *f = (struct rtnl_neigh *) filter;
187 #define REQ(F) (f->n_mask & NEIGH_ATTR_##F)
188 #define AVAIL(F) (o->n_mask & NEIGH_ATTR_##F)
189 #define _O(F, EXPR) (REQ(F) && (!AVAIL(F) || (EXPR)))
190 #define _C(F, N) (REQ(F) && (!AVAIL(F) || (o->N != f->N)))
191 if (_C(IFINDEX, n_ifindex) ||
192 _C(FAMILY, n_family) ||
194 _O(LLADDR, nl_addr_cmp(o->n_lladdr, f->n_lladdr)) ||
195 _O(DST, nl_addr_cmp(o->n_dst, f->n_dst)) ||
196 _O(STATE, f->n_state ^ (o->n_state & f->n_state_mask)) ||
197 _O(FLAGS, f->n_flags ^ (o->n_flags & f->n_flag_mask)))
207 static struct nla_policy neigh_policy[NDA_MAX+1] = {
208 [NDA_CACHEINFO] = { .minlen = sizeof(struct nda_cacheinfo) },
209 [NDA_PROBES] = { .type = NLA_U32 },
212 static int neigh_msg_parser(struct sockaddr_nl *who, struct nlmsghdr *n,
215 struct rtnl_neigh *neigh;
216 struct nlattr *tb[NDA_MAX + 1];
217 struct nl_parser_param *pp = arg;
221 neigh = rtnl_neigh_alloc();
223 err = nl_errno(ENOMEM);
227 neigh->ce_msgtype = n->nlmsg_type;
230 err = nlmsg_parse(n, sizeof(*nm), tb, NDA_MAX, neigh_policy);
234 neigh->n_family = nm->ndm_family;
235 neigh->n_ifindex = nm->ndm_ifindex;
236 neigh->n_state = nm->ndm_state;
237 neigh->n_flags = nm->ndm_flags;
238 neigh->n_type = nm->ndm_type;
240 neigh->n_mask |= (NEIGH_ATTR_FAMILY | NEIGH_ATTR_IFINDEX |
241 NEIGH_ATTR_STATE | NEIGH_ATTR_FLAGS |
244 if (tb[NDA_LLADDR]) {
245 neigh->n_lladdr = nla_get_addr(tb[NDA_LLADDR], AF_UNSPEC);
246 if (!neigh->n_lladdr)
248 nl_addr_set_family(neigh->n_lladdr,
249 nl_addr_guess_family(neigh->n_lladdr));
250 neigh->n_mask |= NEIGH_ATTR_LLADDR;
254 neigh->n_dst = nla_get_addr(tb[NDA_DST], neigh->n_family);
257 neigh->n_mask |= NEIGH_ATTR_DST;
260 if (tb[NDA_CACHEINFO]) {
261 struct nda_cacheinfo *ci = nla_data(tb[NDA_CACHEINFO]);
263 neigh->n_cacheinfo.nci_confirmed = ci->ndm_confirmed;
264 neigh->n_cacheinfo.nci_used = ci->ndm_used;
265 neigh->n_cacheinfo.nci_updated = ci->ndm_updated;
266 neigh->n_cacheinfo.nci_refcnt = ci->ndm_refcnt;
268 neigh->n_mask |= NEIGH_ATTR_CACHEINFO;
271 if (tb[NDA_PROBES]) {
272 neigh->n_probes = nla_get_u32(tb[NDA_PROBES]);
273 neigh->n_mask |= NEIGH_ATTR_PROBES;
276 err = pp->pp_cb((struct nl_object *) neigh, pp);
283 rtnl_neigh_put(neigh);
287 static int neigh_request_update(struct nl_cache *c, struct nl_handle *h)
289 return nl_rtgen_request(h, RTM_GETNEIGH, AF_UNSPEC, NLM_F_DUMP);
293 static int neigh_dump_brief(struct nl_object *a, struct nl_dump_params *p)
295 char dst[INET6_ADDRSTRLEN+5], lladdr[INET6_ADDRSTRLEN+5];
296 struct rtnl_neigh *n = (struct rtnl_neigh *) a;
297 struct nl_cache *link_cache;
298 char state[128], flags[64];
300 link_cache = nl_cache_mngt_require("route/link");
302 dp_dump(p, "%s ", nl_addr2str(n->n_dst, dst, sizeof(dst)));
305 dp_dump(p, "dev %s ",
306 rtnl_link_i2name(link_cache, n->n_ifindex,
307 state, sizeof(state)));
309 dp_dump(p, "dev %d ", n->n_ifindex);
311 if (n->n_mask & NEIGH_ATTR_LLADDR)
312 dp_dump(p, "lladdr %s ",
313 nl_addr2str(n->n_lladdr, lladdr, sizeof(lladdr)));
315 rtnl_neigh_state2str(n->n_state, state, sizeof(state));
316 rtnl_neigh_flags2str(n->n_flags, flags, sizeof(flags));
319 dp_dump(p, "<%s", state);
321 dp_dump(p, "%s%s", state[0] ? "," : "<", flags);
322 if (state[0] || flags[0])
329 static int neigh_dump_full(struct nl_object *a, struct nl_dump_params *p)
332 struct rtnl_neigh *n = (struct rtnl_neigh *) a;
333 int hz = nl_get_hz();
335 int line = neigh_dump_brief(a, p);
337 dp_dump_line(p, line++, " refcnt %u type %s confirmed %u used "
339 n->n_cacheinfo.nci_refcnt,
340 nl_rtntype2str(n->n_type, rtn_type, sizeof(rtn_type)),
341 n->n_cacheinfo.nci_confirmed/hz,
342 n->n_cacheinfo.nci_used/hz, n->n_cacheinfo.nci_updated/hz);
347 static int neigh_dump_stats(struct nl_object *a, struct nl_dump_params *p)
349 return neigh_dump_full(a, p);
352 static int neigh_dump_xml(struct nl_object *obj, struct nl_dump_params *p)
354 struct rtnl_neigh *neigh = (struct rtnl_neigh *) obj;
358 dp_dump_line(p, line++, "<neighbour>\n");
359 dp_dump_line(p, line++, " <family>%s</family>\n",
360 nl_af2str(neigh->n_family, buf, sizeof(buf)));
362 if (neigh->n_mask & NEIGH_ATTR_LLADDR)
363 dp_dump_line(p, line++, " <lladdr>%s</lladdr>\n",
364 nl_addr2str(neigh->n_lladdr, buf, sizeof(buf)));
366 if (neigh->n_mask & NEIGH_ATTR_DST)
367 dp_dump_line(p, line++, " <dst>%s</dst>\n",
368 nl_addr2str(neigh->n_dst, buf, sizeof(buf)));
370 if (neigh->n_mask & NEIGH_ATTR_IFINDEX) {
371 struct nl_cache *link_cache;
373 link_cache = nl_cache_mngt_require("route/link");
376 dp_dump_line(p, line++, " <device>%s</device>\n",
377 rtnl_link_i2name(link_cache,
381 dp_dump_line(p, line++, " <device>%u</device>\n",
385 if (neigh->n_mask & NEIGH_ATTR_PROBES)
386 dp_dump_line(p, line++, " <probes>%u</probes>\n",
389 if (neigh->n_mask & NEIGH_ATTR_TYPE)
390 dp_dump_line(p, line++, " <type>%s</type>\n",
391 nl_rtntype2str(neigh->n_type, buf, sizeof(buf)));
393 rtnl_neigh_flags2str(neigh->n_flags, buf, sizeof(buf));
395 dp_dump_line(p, line++, " <flags>%s</flags>\n", buf);
397 rtnl_neigh_state2str(neigh->n_state, buf, sizeof(buf));
399 dp_dump_line(p, line++, " <state>%s</state>\n", buf);
401 dp_dump_line(p, line++, "</neighbour>\n");
404 struct rtnl_ncacheinfo n_cacheinfo;
410 static int neigh_dump_env(struct nl_object *obj, struct nl_dump_params *p)
412 struct rtnl_neigh *neigh = (struct rtnl_neigh *) obj;
416 dp_dump_line(p, line++, "NEIGH_FAMILY=%s\n",
417 nl_af2str(neigh->n_family, buf, sizeof(buf)));
419 if (neigh->n_mask & NEIGH_ATTR_LLADDR)
420 dp_dump_line(p, line++, "NEIGHT_LLADDR=%s\n",
421 nl_addr2str(neigh->n_lladdr, buf, sizeof(buf)));
423 if (neigh->n_mask & NEIGH_ATTR_DST)
424 dp_dump_line(p, line++, "NEIGH_DST=%s\n",
425 nl_addr2str(neigh->n_dst, buf, sizeof(buf)));
427 if (neigh->n_mask & NEIGH_ATTR_IFINDEX) {
428 struct nl_cache *link_cache;
430 dp_dump_line(p, line++, "NEIGH_IFINDEX=%u\n",
433 link_cache = nl_cache_mngt_require("route/link");
435 dp_dump_line(p, line++, "NEIGH_IFNAME=%s\n",
436 rtnl_link_i2name(link_cache,
441 if (neigh->n_mask & NEIGH_ATTR_PROBES)
442 dp_dump_line(p, line++, "NEIGH_PROBES=%u\n",
445 if (neigh->n_mask & NEIGH_ATTR_TYPE)
446 dp_dump_line(p, line++, "NEIGH_TYPE=%s\n",
447 nl_rtntype2str(neigh->n_type, buf, sizeof(buf)));
449 rtnl_neigh_flags2str(neigh->n_flags, buf, sizeof(buf));
451 dp_dump_line(p, line++, "NEIGH_FLAGS=%s\n", buf);
453 rtnl_neigh_state2str(neigh->n_state, buf, sizeof(buf));
455 dp_dump_line(p, line++, "NEIGH_STATE=%s\n", buf);
461 * @name Neighbour Object Allocation/Freeage
466 * Allocate a new neighbour object
467 * @return New neighbour object
469 struct rtnl_neigh *rtnl_neigh_alloc(void)
471 return (struct rtnl_neigh *) nl_object_alloc_from_ops(&rtnl_neigh_ops);
475 * Give back reference on neighbour object.
476 * @arg neigh Neighbour object to be given back.
478 * Decrements the reference counter and frees the object if the
479 * last reference has been released.
481 void rtnl_neigh_put(struct rtnl_neigh *neigh)
483 nl_object_put((struct nl_object *) neigh);
486 * Free neighbour object.
487 * @arg neigh Neighbour object to be freed.
489 * @note Always use rtnl_neigh_put() unless you're absolutely sure
490 * that no other user may have a reference on this object.
492 void rtnl_neigh_free(struct rtnl_neigh *neigh)
494 nl_object_free((struct nl_object *) neigh);
500 * @name Neighbour Cache Managament
505 * Build a neighbour cache including all neighbours currently configured in the kernel.
506 * @arg handle netlink handle
508 * Allocates a new neighbour cache, initializes it properly and updates it
509 * to include all neighbours currently configured in the kernel.
511 * @note The caller is responsible for destroying and freeing the
512 * cache after using it.
513 * @return The new cache or NULL if an error occured.
515 struct nl_cache *rtnl_neigh_alloc_cache(struct nl_handle *handle)
517 struct nl_cache *cache = nl_cache_alloc_from_ops(&rtnl_neigh_ops);
522 if (nl_cache_update(handle, cache) < 0) {
523 nl_cache_free(cache);
527 NL_DBG(2, "Returning new cache %p\n", cache);
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 * @return neighbour handle or NULL if no match was found.
539 struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *cache, int ifindex,
542 struct rtnl_neigh *neigh;
544 nl_list_for_each_entry(neigh, &cache->c_items, ce_list) {
545 if (neigh->n_ifindex == ifindex &&
546 !nl_addr_cmp(neigh->n_dst, dst)) {
547 nl_object_get((struct nl_object *) neigh);
558 * @name Neighbour Addition
562 static struct nl_msg * build_neigh_msg(struct rtnl_neigh *tmpl, int cmd,
566 struct ndmsg nhdr = {
567 .ndm_ifindex = tmpl->n_ifindex,
568 .ndm_family = nl_addr_get_family(tmpl->n_dst),
569 .ndm_state = NUD_PERMANENT,
572 if (tmpl->n_mask & NEIGH_ATTR_STATE)
573 nhdr.ndm_state = tmpl->n_state;
575 msg = nlmsg_build_simple(cmd, flags);
579 if (nlmsg_append(msg, &nhdr, sizeof(nhdr), 1) < 0)
580 goto nla_put_failure;
582 NLA_PUT_ADDR(msg, NDA_DST, tmpl->n_dst);
584 if (tmpl->n_mask & NEIGH_ATTR_LLADDR)
585 NLA_PUT_ADDR(msg, NDA_LLADDR, tmpl->n_lladdr);
595 * Build netlink request message to add a new neighbour
596 * @arg tmpl template with data of new neighbour
597 * @arg flags additional netlink message flags
599 * Builds a new netlink message requesting a addition of a new
600 * neighbour. The netlink message header isn't fully equipped with
601 * all relevant fields and must thus be sent out via nl_send_auto_complete()
602 * or supplemented as needed. \a tmpl must contain the attributes of the new
603 * neighbour set via \c rtnl_neigh_set_* functions.
605 * The following attributes must be set in the template:
606 * - Interface index (rtnl_neigh_set_ifindex())
607 * - State (rtnl_neigh_set_state())
608 * - Destination address (rtnl_neigh_set_dst())
609 * - Link layer address (rtnl_neigh_set_lladdr())
611 * @return The netlink message
613 struct nl_msg * rtnl_neigh_build_add_request(struct rtnl_neigh *tmpl, int flags)
615 return build_neigh_msg(tmpl, RTM_NEWNEIGH, NLM_F_CREATE | flags);
619 * Add a new neighbour
620 * @arg handle netlink handle
621 * @arg tmpl template with requested changes
622 * @arg flags additional netlink message flags
624 * Builds a netlink message by calling rtnl_neigh_build_add_request(),
625 * sends the request to the kernel and waits for the next ACK to be
626 * received and thus blocks until the request has been fullfilled.
628 * The following attributes must be set in the template:
629 * - Interface index (rtnl_neigh_set_ifindex())
630 * - State (rtnl_neigh_set_state())
631 * - Destination address (rtnl_neigh_set_dst())
632 * - Link layer address (rtnl_neigh_set_lladdr())
634 * @return 0 on sucess or a negative error if an error occured.
636 int rtnl_neigh_add(struct nl_handle *handle, struct rtnl_neigh *tmpl, int flags)
641 msg = rtnl_neigh_build_add_request(tmpl, flags);
643 return nl_errno(ENOMEM);
645 err = nl_send_auto_complete(handle, msg);
650 return nl_wait_for_ack(handle);
656 * @name Neighbour Deletion
661 * Build a netlink request message to delete a neighbour
662 * @arg neigh neighbour to delete
663 * @arg flags additional netlink message flags
665 * Builds a new netlink message requesting a deletion of a neighbour.
666 * The netlink message header isn't fully equipped with all relevant
667 * fields and must thus be sent out via nl_send_auto_complete()
668 * or supplemented as needed. \a neigh must point to an existing
671 * @return The netlink message
673 struct nl_msg *rtnl_neigh_build_delete_request(struct rtnl_neigh *neigh,
676 return build_neigh_msg(neigh, RTM_DELNEIGH, flags);
681 * @arg handle netlink handle
682 * @arg neigh neighbour to delete
683 * @arg flags additional netlink message flags
685 * Builds a netlink message by calling rtnl_neigh_build_delete_request(),
686 * sends the request to the kernel and waits for the next ACK to be
687 * received and thus blocks until the request has been fullfilled.
689 * @return 0 on sucess or a negative error if an error occured.
691 int rtnl_neigh_delete(struct nl_handle *handle, struct rtnl_neigh *neigh,
697 msg = rtnl_neigh_build_delete_request(neigh, flags);
699 return nl_errno(ENOMEM);
701 err = nl_send_auto_complete(handle, msg);
706 return nl_wait_for_ack(handle);
712 * @name Neighbour Modification
717 * Build a netlink request message to change neighbour attributes
718 * @arg neigh the neighbour to change
719 * @arg flags additional netlink message flags
721 * Builds a new netlink message requesting a change of a neigh
722 * attributes. The netlink message header isn't fully equipped with
723 * all relevant fields and must thus be sent out via nl_send_auto_complete()
724 * or supplemented as needed.
726 * @return The netlink message
727 * @note Not all attributes can be changed, see
728 * \ref neigh_changeable "Changeable Attributes" for a list.
730 struct nl_msg *rtnl_neigh_build_change_request(struct rtnl_neigh *neigh,
733 return build_neigh_msg(neigh, RTM_NEWNEIGH, NLM_F_REPLACE | flags);
737 * Change neighbour attributes
738 * @arg handle netlink handle
739 * @arg neigh neighbour to be changed
740 * @arg flags additional netlink message flags
742 * Builds a netlink message by calling rtnl_neigh_build_change_request(),
743 * sends the request to the kernel and waits for the next ACK to be
744 * received and thus blocks until the request has been fullfilled.
746 * @return 0 on sucess or a negative error if an error occured.
747 * @note Not all attributes can be changed, see
748 * \ref neigh_changeable "Changeable Attributes" for a list.
750 int rtnl_neigh_change(struct nl_handle *handle, struct rtnl_neigh *neigh,
756 msg = rtnl_neigh_build_change_request(neigh, flags);
758 return nl_errno(ENOMEM);
760 err = nl_send_auto_complete(handle, msg);
765 return nl_wait_for_ack(handle);
771 * @name Neighbour States Translations
775 static struct trans_tbl neigh_states[] = {
776 __ADD(NUD_INCOMPLETE, incomplete)
777 __ADD(NUD_REACHABLE, reachable)
778 __ADD(NUD_STALE, stale)
779 __ADD(NUD_DELAY, delay)
780 __ADD(NUD_PROBE, probe)
781 __ADD(NUD_FAILED, failed)
782 __ADD(NUD_NOARP, norarp)
783 __ADD(NUD_PERMANENT, permanent)
787 * Convert neighbour states to a character string (Reentrant).
788 * @arg state neighbour state
789 * @arg buf destination buffer
790 * @arg len buffer length
792 * Converts a neighbour state to a character string separated by
793 * commands and stores it in the specified destination buffer.
795 * @return The destination buffer
797 char * rtnl_neigh_state2str(int state, char *buf, size_t len)
799 return __flags2str(state, buf, len, neigh_states,
800 ARRAY_SIZE(neigh_states));
804 * Convert a character string to a neighbour state
805 * @arg name Name of cscope
807 * Converts the provided character string specifying a neighbour
808 * state the corresponding numeric value.
810 * @return Neighbour state or a negative value if none was found.
812 int rtnl_neigh_str2state(const char *name)
814 return __str2type(name, neigh_states, ARRAY_SIZE(neigh_states));
820 * @name Neighbour Flags Translations
824 static struct trans_tbl neigh_flags[] = {
825 __ADD(NTF_PROXY, proxy)
826 __ADD(NTF_ROUTER, router)
830 * Convert neighbour flags to a character string (Reentrant).
831 * @arg flags neighbour flags
832 * @arg buf destination buffer
833 * @arg len buffer length
835 * Converts neighbour flags to a character string separated by
836 * commands and stores it in the specified destination buffer.
838 * @return The destination buffer or a empty string if no flags are set.
840 char * rtnl_neigh_flags2str(int flags, char *buf, size_t len)
842 return __flags2str(flags, buf, len, neigh_flags,
843 ARRAY_SIZE(neigh_flags));
847 * Convert a character string to a neighbour flag
848 * @arg name name of the flag
850 * Converts the provided character string specifying a neighbour
851 * flag the corresponding numeric value.
853 * @return Neighbour flag or a negative value if none was found.
855 int rtnl_neigh_str2flag(const char *name)
857 return __str2type(name, neigh_flags, ARRAY_SIZE(neigh_flags));
863 * @name Attribute Modification
868 * Set a neighbour state
869 * @arg neigh neighbour to change
870 * @arg state state to set
872 void rtnl_neigh_set_state(struct rtnl_neigh *neigh, int state)
874 neigh->n_state_mask |= state;
875 neigh->n_state |= state;
876 neigh->n_mask |= NEIGH_ATTR_STATE;
880 * Get neighbour states
881 * @arg neigh neighbour handle
882 * @return Neighbour state or -1 if not set
884 int rtnl_neigh_get_state(struct rtnl_neigh *neigh)
886 if (neigh->n_mask & NEIGH_ATTR_STATE)
887 return neigh->n_state;
893 * Unset a neigbour state
894 * @arg neigh neighbour to change
895 * @arg state state to unset
897 void rtnl_neigh_unset_state(struct rtnl_neigh *neigh, int state)
899 neigh->n_state_mask |= state;
900 neigh->n_state &= ~state;
901 neigh->n_mask |= NEIGH_ATTR_STATE;
905 * Set neighbour flags
906 * @arg neigh neighbour to change
907 * @arg flags flag to set
909 void rtnl_neigh_set_flags(struct rtnl_neigh *neigh, unsigned int flags)
911 neigh->n_flag_mask |= flags;
912 neigh->n_flags |= flags;
913 neigh->n_mask |= NEIGH_ATTR_FLAGS;
917 * Get neighbour flags
918 * @arg neigh neighbour handle
919 * @return Neighbour flags
921 unsigned int rtnl_neigh_get_flags(struct rtnl_neigh *neigh)
923 return neigh->n_flags;
927 * Unset neighbour flags
928 * @arg neigh neighbour to change
929 * @arg flags flag to unset
931 void rtnl_neigh_unset_flags(struct rtnl_neigh *neigh, unsigned int flags)
933 neigh->n_flag_mask |= flags;
934 neigh->n_flags &= ~flags;
935 neigh->n_mask |= NEIGH_ATTR_FLAGS;
939 * Set the interface index of device this neighbour is on
940 * @arg neigh neighbour to change
941 * @arg ifindex new interface index
943 void rtnl_neigh_set_ifindex(struct rtnl_neigh *neigh, int ifindex)
945 neigh->n_ifindex = ifindex;
946 neigh->n_mask |= NEIGH_ATTR_IFINDEX;
950 * Get the interface index of the device this neighbour is on
951 * @arg neigh neighbour handle
952 * @return Interface index or RTNL_LINK_NOT_FOUND if not set
954 int rtnl_neigh_get_ifindex(struct rtnl_neigh *neigh)
956 if (neigh->n_mask & NEIGH_ATTR_IFINDEX)
957 return neigh->n_ifindex;
959 return RTNL_LINK_NOT_FOUND;
962 static inline int __assign_addr(struct rtnl_neigh *neigh, struct nl_addr **pos,
963 struct nl_addr *new, int flag, int nocheck)
966 if (neigh->n_mask & NEIGH_ATTR_FAMILY) {
967 if (new->a_family != neigh->n_family)
968 return nl_error(EINVAL,
969 "Address family mismatch");
971 neigh->n_family = new->a_family;
972 neigh->n_mask |= NEIGH_ATTR_FAMILY;
982 neigh->n_mask |= flag;
988 * Set link layer address of a neighbour
989 * @arg neigh neighbour to change
990 * @arg addr new link layer address
992 * Assigns the new link layer address to the specified neighbour handle.
994 * @note The prefix length of the address will be ignored.
996 void rtnl_neigh_set_lladdr(struct rtnl_neigh *neigh, struct nl_addr *addr)
998 __assign_addr(neigh, &neigh->n_lladdr, addr, NEIGH_ATTR_LLADDR, 1);
1002 * Get link layer address of a neighbour
1003 * @arg neigh neighbour handle
1004 * @return Link layer address or NULL if not set
1006 struct nl_addr *rtnl_neigh_get_lladdr(struct rtnl_neigh *neigh)
1008 if (neigh->n_mask & NEIGH_ATTR_LLADDR)
1009 return neigh->n_lladdr;
1015 * Set destination address of a neighbour
1016 * @arg neigh neighbour to change
1017 * @arg addr new destination address
1019 * Assigns the new destination address to the specified neighbour handle.
1020 * The address is validated against the address family if set already via
1021 * rtnl_neigh_set_family(). The assignment fails if the address families
1022 * mismatch. In case the address family has not been specified yet, the
1023 * address family of this new address is elected to be the requirement.
1025 * @return 0 on success or a negative error code.
1027 int rtnl_neigh_set_dst(struct rtnl_neigh *neigh, struct nl_addr *addr)
1029 return __assign_addr(neigh, &neigh->n_dst, addr,
1034 * Get the destination address of a neighbour
1035 * @arg neigh neighbour handle
1036 * @return Destination address or NULL if not set
1038 struct nl_addr *rtnl_neigh_get_dst(struct rtnl_neigh *neigh)
1040 if (neigh->n_mask & NEIGH_ATTR_DST)
1041 return neigh->n_dst;
1047 * Set destination address family
1048 * @arg neigh neighbour to change
1049 * @arg family new destination address family
1051 void rtnl_neigh_set_family(struct rtnl_neigh *neigh, int family)
1053 neigh->n_family = family;
1054 neigh->n_mask |= NEIGH_ATTR_FAMILY;
1058 * Set RTN type of a neighbour
1059 * @arg neigh neighbour to change
1060 * @arg type new rtn type
1062 void rtnl_neigh_set_type(struct rtnl_neigh *neigh, int type)
1064 neigh->n_type = type;
1065 neigh->n_mask = NEIGH_ATTR_TYPE;
1069 * Get RTN type of a neighbour
1070 * @arg neigh neighbour handle
1071 * @return Type or -1 if not set
1073 int rtnl_neigh_get_type(struct rtnl_neigh *neigh)
1075 if (neigh->n_mask & NEIGH_ATTR_TYPE)
1076 return neigh->n_type;
1083 static struct nl_cache_ops rtnl_neigh_ops = {
1084 .co_name = "route/neigh",
1085 .co_size = sizeof(struct rtnl_neigh),
1086 .co_hdrsize = sizeof(struct ndmsg),
1088 { RTM_NEWNEIGH, "new" },
1089 { RTM_DELNEIGH, "delete" },
1090 { RTM_GETNEIGH, "get" },
1093 .co_protocol = NETLINK_ROUTE,
1094 .co_request_update = neigh_request_update,
1095 .co_msg_parser = neigh_msg_parser,
1096 .co_free_data = neigh_free_data,
1097 .co_dump[NL_DUMP_BRIEF] = neigh_dump_brief,
1098 .co_dump[NL_DUMP_FULL] = neigh_dump_full,
1099 .co_dump[NL_DUMP_STATS] = neigh_dump_stats,
1100 .co_dump[NL_DUMP_XML] = neigh_dump_xml,
1101 .co_dump[NL_DUMP_ENV] = neigh_dump_env,
1102 .co_filter = neigh_filter,
1105 static void __init neigh_init(void)
1107 nl_cache_mngt_register(&rtnl_neigh_ops);
1110 static void __exit neigh_exit(void)
1112 nl_cache_mngt_unregister(&rtnl_neigh_ops);