libnl  3.2.27
neigh.c
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@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 #define NEIGH_ATTR_VLAN 0x400
172 
173 static struct nl_cache_ops rtnl_neigh_ops;
174 static struct nl_object_ops neigh_obj_ops;
175 /** @endcond */
176 
177 static void neigh_free_data(struct nl_object *c)
178 {
179  struct rtnl_neigh *neigh = nl_object_priv(c);
180 
181  if (!neigh)
182  return;
183 
184  nl_addr_put(neigh->n_lladdr);
185  nl_addr_put(neigh->n_dst);
186 }
187 
188 static int neigh_clone(struct nl_object *_dst, struct nl_object *_src)
189 {
190  struct rtnl_neigh *dst = nl_object_priv(_dst);
191  struct rtnl_neigh *src = nl_object_priv(_src);
192 
193  if (src->n_lladdr)
194  if (!(dst->n_lladdr = nl_addr_clone(src->n_lladdr)))
195  return -NLE_NOMEM;
196 
197  if (src->n_dst)
198  if (!(dst->n_dst = nl_addr_clone(src->n_dst)))
199  return -NLE_NOMEM;
200 
201  return 0;
202 }
203 
204 static void neigh_keygen(struct nl_object *obj, uint32_t *hashkey,
205  uint32_t table_sz)
206 {
207  struct rtnl_neigh *neigh = (struct rtnl_neigh *) obj;
208  unsigned int nkey_sz;
209  struct nl_addr *addr = NULL;
210  struct neigh_hash_key {
211  uint32_t n_family;
212  uint32_t n_ifindex;
213  char n_addr[0];
214  } __attribute__((packed)) *nkey;
215 #ifdef NL_DEBUG
216  char buf[INET6_ADDRSTRLEN+5];
217 #endif
218 
219  if (neigh->n_family == AF_BRIDGE) {
220  if (neigh->n_lladdr)
221  addr = neigh->n_lladdr;
222  } else if (neigh->n_dst) {
223  addr = neigh->n_dst;
224  }
225 
226  nkey_sz = sizeof(*nkey);
227  if (addr)
228  nkey_sz += nl_addr_get_len(addr);
229 
230  nkey = calloc(1, nkey_sz);
231  if (!nkey) {
232  *hashkey = 0;
233  return;
234  }
235  nkey->n_family = neigh->n_family;
236  if (neigh->n_family == AF_BRIDGE)
237  nkey->n_ifindex = neigh->n_master;
238  else
239  nkey->n_ifindex = neigh->n_ifindex;
240  if (addr)
241  memcpy(nkey->n_addr,
243  nl_addr_get_len(addr));
244 
245  *hashkey = nl_hash(nkey, nkey_sz, 0) % table_sz;
246 
247  NL_DBG(5, "neigh %p key (fam %d dev %d addr %s) keysz %d hash 0x%x\n",
248  neigh, nkey->n_family, nkey->n_ifindex,
249  nl_addr2str(addr, buf, sizeof(buf)),
250  nkey_sz, *hashkey);
251 
252  free(nkey);
253 
254  return;
255 }
256 
257 static int neigh_compare(struct nl_object *_a, struct nl_object *_b,
258  uint32_t attrs, int flags)
259 {
260  struct rtnl_neigh *a = (struct rtnl_neigh *) _a;
261  struct rtnl_neigh *b = (struct rtnl_neigh *) _b;
262  int diff = 0;
263 
264 #define NEIGH_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, NEIGH_ATTR_##ATTR, a, b, EXPR)
265 
266  diff |= NEIGH_DIFF(IFINDEX, a->n_ifindex != b->n_ifindex);
267  diff |= NEIGH_DIFF(FAMILY, a->n_family != b->n_family);
268  diff |= NEIGH_DIFF(TYPE, a->n_type != b->n_type);
269  diff |= NEIGH_DIFF(LLADDR, nl_addr_cmp(a->n_lladdr, b->n_lladdr));
270  diff |= NEIGH_DIFF(DST, nl_addr_cmp(a->n_dst, b->n_dst));
271  diff |= NEIGH_DIFF(MASTER, a->n_master != b->n_master);
272  diff |= NEIGH_DIFF(VLAN, a->n_vlan != b->n_vlan);
273 
274  if (flags & LOOSE_COMPARISON) {
275  diff |= NEIGH_DIFF(STATE,
276  (a->n_state ^ b->n_state) & b->n_state_mask);
277  diff |= NEIGH_DIFF(FLAGS,
278  (a->n_flags ^ b->n_flags) & b->n_flag_mask);
279  } else {
280  diff |= NEIGH_DIFF(STATE, a->n_state != b->n_state);
281  diff |= NEIGH_DIFF(FLAGS, a->n_flags != b->n_flags);
282  }
283 
284 #undef NEIGH_DIFF
285 
286  return diff;
287 }
288 
289 static const struct trans_tbl neigh_attrs[] = {
290  __ADD(NEIGH_ATTR_FLAGS, flags),
291  __ADD(NEIGH_ATTR_STATE, state),
292  __ADD(NEIGH_ATTR_LLADDR, lladdr),
293  __ADD(NEIGH_ATTR_DST, dst),
294  __ADD(NEIGH_ATTR_CACHEINFO, cacheinfo),
295  __ADD(NEIGH_ATTR_IFINDEX, ifindex),
296  __ADD(NEIGH_ATTR_FAMILY, family),
297  __ADD(NEIGH_ATTR_TYPE, type),
298  __ADD(NEIGH_ATTR_PROBES, probes),
299  __ADD(NEIGH_ATTR_MASTER, master),
300  __ADD(NEIGH_ATTR_VLAN, vlan),
301 };
302 
303 static char *neigh_attrs2str(int attrs, char *buf, size_t len)
304 {
305  return __flags2str(attrs, buf, len, neigh_attrs,
306  ARRAY_SIZE(neigh_attrs));
307 }
308 
309 static uint32_t neigh_id_attrs_get(struct nl_object *obj)
310 {
311  struct rtnl_neigh *neigh = (struct rtnl_neigh *)obj;
312 
313  if (neigh->n_family == AF_BRIDGE)
314  return (NEIGH_ATTR_LLADDR | NEIGH_ATTR_FAMILY | NEIGH_ATTR_MASTER);
315  else
316  return (NEIGH_ATTR_IFINDEX | NEIGH_ATTR_DST | NEIGH_ATTR_FAMILY);
317 }
318 
319 static struct nla_policy neigh_policy[NDA_MAX+1] = {
320  [NDA_CACHEINFO] = { .minlen = sizeof(struct nda_cacheinfo) },
321  [NDA_PROBES] = { .type = NLA_U32 },
322 };
323 
324 static int neigh_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
325  struct nlmsghdr *n, struct nl_parser_param *pp)
326 {
327  struct rtnl_neigh *neigh;
328  int err;
329 
330  if ((err = rtnl_neigh_parse(n, &neigh)) < 0)
331  return err;
332 
333  err = pp->pp_cb((struct nl_object *) neigh, pp);
334 
335  rtnl_neigh_put(neigh);
336  return err;
337 }
338 
339 
340 int rtnl_neigh_parse(struct nlmsghdr *n, struct rtnl_neigh **result)
341 {
342  struct rtnl_neigh *neigh;
343  struct nlattr *tb[NDA_MAX + 1];
344  struct ndmsg *nm;
345  int err;
346 
347  neigh = rtnl_neigh_alloc();
348  if (!neigh) {
349  err = -NLE_NOMEM;
350  goto errout;
351  }
352 
353  neigh->ce_msgtype = n->nlmsg_type;
354  nm = nlmsg_data(n);
355 
356  err = nlmsg_parse(n, sizeof(*nm), tb, NDA_MAX, neigh_policy);
357  if (err < 0)
358  goto errout;
359 
360  neigh->n_family = nm->ndm_family;
361  neigh->n_ifindex = nm->ndm_ifindex;
362  neigh->n_state = nm->ndm_state;
363  neigh->n_flags = nm->ndm_flags;
364  neigh->n_type = nm->ndm_type;
365 
366  neigh->ce_mask |= (NEIGH_ATTR_FAMILY | NEIGH_ATTR_IFINDEX |
367  NEIGH_ATTR_STATE | NEIGH_ATTR_FLAGS |
368  NEIGH_ATTR_TYPE);
369 
370  if (tb[NDA_LLADDR]) {
371  neigh->n_lladdr = nl_addr_alloc_attr(tb[NDA_LLADDR], AF_UNSPEC);
372  if (!neigh->n_lladdr) {
373  err = -NLE_NOMEM;
374  goto errout;
375  }
376  nl_addr_set_family(neigh->n_lladdr,
377  nl_addr_guess_family(neigh->n_lladdr));
378  neigh->ce_mask |= NEIGH_ATTR_LLADDR;
379  }
380 
381  if (tb[NDA_DST]) {
382  neigh->n_dst = nl_addr_alloc_attr(tb[NDA_DST], neigh->n_family);
383  if (!neigh->n_dst) {
384  err = -NLE_NOMEM;
385  goto errout;
386  }
387  neigh->ce_mask |= NEIGH_ATTR_DST;
388  }
389 
390  if (tb[NDA_CACHEINFO]) {
391  struct nda_cacheinfo *ci = nla_data(tb[NDA_CACHEINFO]);
392 
393  neigh->n_cacheinfo.nci_confirmed = ci->ndm_confirmed;
394  neigh->n_cacheinfo.nci_used = ci->ndm_used;
395  neigh->n_cacheinfo.nci_updated = ci->ndm_updated;
396  neigh->n_cacheinfo.nci_refcnt = ci->ndm_refcnt;
397 
398  neigh->ce_mask |= NEIGH_ATTR_CACHEINFO;
399  }
400 
401  if (tb[NDA_PROBES]) {
402  neigh->n_probes = nla_get_u32(tb[NDA_PROBES]);
403  neigh->ce_mask |= NEIGH_ATTR_PROBES;
404  }
405 
406  if (tb[NDA_VLAN]) {
407  neigh->n_vlan = nla_get_u16(tb[NDA_VLAN]);
408  neigh->ce_mask |= NEIGH_ATTR_VLAN;
409  }
410 
411  /*
412  * Get the bridge index for AF_BRIDGE family entries
413  */
414  if (neigh->n_family == AF_BRIDGE) {
415  struct nl_cache *lcache = nl_cache_mngt_require_safe("route/link");
416  if (lcache ) {
417  struct rtnl_link *link = rtnl_link_get(lcache,
418  neigh->n_ifindex);
419  if (link) {
420  neigh->n_master = link->l_master;
421  rtnl_link_put(link);
422  neigh->ce_mask |= NEIGH_ATTR_MASTER;
423  }
424 
425  nl_cache_put(lcache);
426  }
427  }
428 
429  *result = neigh;
430  return 0;
431 
432 errout:
433  rtnl_neigh_put(neigh);
434  return err;
435 }
436 
437 static int neigh_request_update(struct nl_cache *c, struct nl_sock *h)
438 {
439  int family = c->c_iarg1;
440 
441  return nl_rtgen_request(h, RTM_GETNEIGH, family, NLM_F_DUMP);
442 }
443 
444 
445 static void neigh_dump_line(struct nl_object *a, struct nl_dump_params *p)
446 {
447  char dst[INET6_ADDRSTRLEN+5], lladdr[INET6_ADDRSTRLEN+5];
448  struct rtnl_neigh *n = (struct rtnl_neigh *) a;
449  struct nl_cache *link_cache;
450  char state[128], flags[64];
451 
452  link_cache = nl_cache_mngt_require_safe("route/link");
453 
454  if (n->n_family != AF_BRIDGE)
455  nl_dump_line(p, "%s ", nl_addr2str(n->n_dst, dst, sizeof(dst)));
456 
457  if (link_cache)
458  nl_dump(p, "dev %s ",
459  rtnl_link_i2name(link_cache, n->n_ifindex,
460  state, sizeof(state)));
461  else
462  nl_dump(p, "dev %d ", n->n_ifindex);
463 
464  if (n->ce_mask & NEIGH_ATTR_LLADDR)
465  nl_dump(p, "lladdr %s ",
466  nl_addr2str(n->n_lladdr, lladdr, sizeof(lladdr)));
467 
468  rtnl_neigh_state2str(n->n_state, state, sizeof(state));
469  rtnl_neigh_flags2str(n->n_flags, flags, sizeof(flags));
470 
471  if (state[0])
472  nl_dump(p, "<%s", state);
473  if (flags[0])
474  nl_dump(p, "%s%s", state[0] ? "," : "<", flags);
475  if (state[0] || flags[0])
476  nl_dump(p, ">");
477  nl_dump(p, "\n");
478 
479  if (link_cache)
480  nl_cache_put(link_cache);
481 }
482 
483 static void neigh_dump_details(struct nl_object *a, struct nl_dump_params *p)
484 {
485  char rtn_type[32];
486  struct rtnl_neigh *n = (struct rtnl_neigh *) a;
487  int hz = nl_get_user_hz();
488 
489  neigh_dump_line(a, p);
490 
491  nl_dump_line(p, " refcnt %u type %s confirmed %u used "
492  "%u updated %u\n",
493  n->n_cacheinfo.nci_refcnt,
494  nl_rtntype2str(n->n_type, rtn_type, sizeof(rtn_type)),
495  n->n_cacheinfo.nci_confirmed/hz,
496  n->n_cacheinfo.nci_used/hz, n->n_cacheinfo.nci_updated/hz);
497 }
498 
499 static void neigh_dump_stats(struct nl_object *a, struct nl_dump_params *p)
500 {
501  neigh_dump_details(a, p);
502 }
503 
504 /**
505  * @name Neighbour Object Allocation/Freeage
506  * @{
507  */
508 
509 struct rtnl_neigh *rtnl_neigh_alloc(void)
510 {
511  return (struct rtnl_neigh *) nl_object_alloc(&neigh_obj_ops);
512 }
513 
514 void rtnl_neigh_put(struct rtnl_neigh *neigh)
515 {
516  nl_object_put((struct nl_object *) neigh);
517 }
518 
519 /** @} */
520 
521 /**
522  * @name Neighbour Cache Managament
523  * @{
524  */
525 
526 /**
527  * Build a neighbour cache including all neighbours currently configured in the kernel.
528  * @arg sock Netlink socket.
529  * @arg result Pointer to store resulting cache.
530  *
531  * Allocates a new neighbour cache, initializes it properly and updates it
532  * to include all neighbours currently configured in the kernel.
533  *
534  * @return 0 on success or a negative error code.
535  */
536 int rtnl_neigh_alloc_cache(struct nl_sock *sock, struct nl_cache **result)
537 {
538  return nl_cache_alloc_and_fill(&rtnl_neigh_ops, sock, result);
539 }
540 
541 /**
542  * Look up a neighbour by interface index and destination address
543  * @arg cache neighbour cache
544  * @arg ifindex interface index the neighbour is on
545  * @arg dst destination address of the neighbour
546  *
547  * @return neighbour handle or NULL if no match was found.
548  */
549 struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *cache, int ifindex,
550  struct nl_addr *dst)
551 {
552  struct rtnl_neigh *neigh;
553 
554  nl_list_for_each_entry(neigh, &cache->c_items, ce_list) {
555  if (neigh->n_ifindex == ifindex &&
556  !nl_addr_cmp(neigh->n_dst, dst)) {
557  nl_object_get((struct nl_object *) neigh);
558  return neigh;
559  }
560  }
561 
562  return NULL;
563 }
564 
565 /** @} */
566 
567 /**
568  * @name Neighbour Addition
569  * @{
570  */
571 
572 static int build_neigh_msg(struct rtnl_neigh *tmpl, int cmd, int flags,
573  struct nl_msg **result)
574 {
575  struct nl_msg *msg;
576  struct ndmsg nhdr = {
577  .ndm_ifindex = tmpl->n_ifindex,
578  .ndm_state = NUD_PERMANENT,
579  };
580 
581  if (tmpl->n_family != AF_BRIDGE) {
582  if (!(tmpl->ce_mask & NEIGH_ATTR_DST))
583  return -NLE_MISSING_ATTR;
584  nhdr.ndm_family = nl_addr_get_family(tmpl->n_dst);
585  }
586  else
587  nhdr.ndm_family = AF_BRIDGE;
588 
589  if (tmpl->ce_mask & NEIGH_ATTR_FLAGS)
590  nhdr.ndm_flags = tmpl->n_flags;
591 
592  if (tmpl->ce_mask & NEIGH_ATTR_STATE)
593  nhdr.ndm_state = tmpl->n_state;
594 
595  msg = nlmsg_alloc_simple(cmd, flags);
596  if (!msg)
597  return -NLE_NOMEM;
598 
599  if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0)
600  goto nla_put_failure;
601 
602  if (tmpl->n_family != AF_BRIDGE)
603  NLA_PUT_ADDR(msg, NDA_DST, tmpl->n_dst);
604 
605  if (tmpl->ce_mask & NEIGH_ATTR_LLADDR)
606  NLA_PUT_ADDR(msg, NDA_LLADDR, tmpl->n_lladdr);
607 
608  if (tmpl->ce_mask & NEIGH_ATTR_VLAN)
609  NLA_PUT_U16(msg, NDA_VLAN, tmpl->n_vlan);
610 
611  *result = msg;
612  return 0;
613 
614 nla_put_failure:
615  nlmsg_free(msg);
616  return -NLE_MSGSIZE;
617 }
618 
619 /**
620  * Build netlink request message to add a new neighbour
621  * @arg tmpl template with data of new neighbour
622  * @arg flags additional netlink message flags
623  * @arg result Pointer to store resulting message.
624  *
625  * Builds a new netlink message requesting a addition of a new
626  * neighbour. The netlink message header isn't fully equipped with
627  * all relevant fields and must thus be sent out via nl_send_auto_complete()
628  * or supplemented as needed. \a tmpl must contain the attributes of the new
629  * neighbour set via \c rtnl_neigh_set_* functions.
630  *
631  * The following attributes must be set in the template:
632  * - Interface index (rtnl_neigh_set_ifindex())
633  * - State (rtnl_neigh_set_state())
634  * - Destination address (rtnl_neigh_set_dst())
635  * - Link layer address (rtnl_neigh_set_lladdr())
636  *
637  * @return 0 on success or a negative error code.
638  */
639 int rtnl_neigh_build_add_request(struct rtnl_neigh *tmpl, int flags,
640  struct nl_msg **result)
641 {
642  return build_neigh_msg(tmpl, RTM_NEWNEIGH, flags, result);
643 }
644 
645 /**
646  * Add a new neighbour
647  * @arg sk Netlink socket.
648  * @arg tmpl template with requested changes
649  * @arg flags additional netlink message flags
650  *
651  * Builds a netlink message by calling rtnl_neigh_build_add_request(),
652  * sends the request to the kernel and waits for the next ACK to be
653  * received and thus blocks until the request has been fullfilled.
654  *
655  * The following attributes must be set in the template:
656  * - Interface index (rtnl_neigh_set_ifindex())
657  * - State (rtnl_neigh_set_state())
658  * - Destination address (rtnl_neigh_set_dst())
659  * - Link layer address (rtnl_neigh_set_lladdr())
660  *
661  * @return 0 on sucess or a negative error if an error occured.
662  */
663 int rtnl_neigh_add(struct nl_sock *sk, struct rtnl_neigh *tmpl, int flags)
664 {
665  int err;
666  struct nl_msg *msg;
667 
668  if ((err = rtnl_neigh_build_add_request(tmpl, flags, &msg)) < 0)
669  return err;
670 
671  err = nl_send_auto_complete(sk, msg);
672  nlmsg_free(msg);
673  if (err < 0)
674  return err;
675 
676  return wait_for_ack(sk);
677 }
678 
679 /** @} */
680 
681 /**
682  * @name Neighbour Deletion
683  * @{
684  */
685 
686 /**
687  * Build a netlink request message to delete a neighbour
688  * @arg neigh neighbour to delete
689  * @arg flags additional netlink message flags
690  * @arg result Pointer to store resulting message.
691  *
692  * Builds a new netlink message requesting a deletion of a neighbour.
693  * The netlink message header isn't fully equipped with all relevant
694  * fields and must thus be sent out via nl_send_auto_complete()
695  * or supplemented as needed. \a neigh must point to an existing
696  * neighbour.
697  *
698  * @return 0 on success or a negative error code.
699  */
700 int rtnl_neigh_build_delete_request(struct rtnl_neigh *neigh, int flags,
701  struct nl_msg **result)
702 {
703  return build_neigh_msg(neigh, RTM_DELNEIGH, flags, result);
704 }
705 
706 /**
707  * Delete a neighbour
708  * @arg sk Netlink socket.
709  * @arg neigh neighbour to delete
710  * @arg flags additional netlink message flags
711  *
712  * Builds a netlink message by calling rtnl_neigh_build_delete_request(),
713  * sends the request to the kernel and waits for the next ACK to be
714  * received and thus blocks until the request has been fullfilled.
715  *
716  * @return 0 on sucess or a negative error if an error occured.
717  */
718 int rtnl_neigh_delete(struct nl_sock *sk, struct rtnl_neigh *neigh,
719  int flags)
720 {
721  struct nl_msg *msg;
722  int err;
723 
724  if ((err = rtnl_neigh_build_delete_request(neigh, flags, &msg)) < 0)
725  return err;
726 
727  err = nl_send_auto_complete(sk, msg);
728  nlmsg_free(msg);
729  if (err < 0)
730  return err;
731 
732  return wait_for_ack(sk);
733 }
734 
735 /** @} */
736 
737 /**
738  * @name Neighbour States Translations
739  * @{
740  */
741 
742 static const struct trans_tbl neigh_states[] = {
743  __ADD(NUD_INCOMPLETE, incomplete),
744  __ADD(NUD_REACHABLE, reachable),
745  __ADD(NUD_STALE, stale),
746  __ADD(NUD_DELAY, delay),
747  __ADD(NUD_PROBE, probe),
748  __ADD(NUD_FAILED, failed),
749  __ADD(NUD_NOARP, noarp),
750  __ADD(NUD_PERMANENT, permanent),
751 
752  /* Accept this value for backward compatibility. Originally
753  * there was a typo in the string value. This was fixed later,
754  * but we still want to successfully parse "norarp". */
755  __ADD(NUD_NOARP, norarp),
756 };
757 
758 char * rtnl_neigh_state2str(int state, char *buf, size_t len)
759 {
760  return __flags2str(state, buf, len, neigh_states,
761  ARRAY_SIZE(neigh_states) - 1);
762 }
763 
764 int rtnl_neigh_str2state(const char *name)
765 {
766  return __str2type(name, neigh_states, ARRAY_SIZE(neigh_states));
767 }
768 
769 /** @} */
770 
771 /**
772  * @name Neighbour Flags Translations
773  * @{
774  */
775 
776 static const struct trans_tbl neigh_flags[] = {
777  __ADD(NTF_USE, use),
778  __ADD(NTF_PROXY, proxy),
779  __ADD(NTF_ROUTER, router),
780 };
781 
782 char * rtnl_neigh_flags2str(int flags, char *buf, size_t len)
783 {
784  return __flags2str(flags, buf, len, neigh_flags,
785  ARRAY_SIZE(neigh_flags));
786 }
787 
788 int rtnl_neigh_str2flag(const char *name)
789 {
790  return __str2type(name, neigh_flags, ARRAY_SIZE(neigh_flags));
791 }
792 
793 /** @} */
794 
795 /**
796  * @name Attributes
797  * @{
798  */
799 
800 void rtnl_neigh_set_state(struct rtnl_neigh *neigh, int state)
801 {
802  neigh->n_state_mask |= state;
803  neigh->n_state |= state;
804  neigh->ce_mask |= NEIGH_ATTR_STATE;
805 }
806 
807 int rtnl_neigh_get_state(struct rtnl_neigh *neigh)
808 {
809  if (neigh->ce_mask & NEIGH_ATTR_STATE)
810  return neigh->n_state;
811  else
812  return -1;
813 }
814 
815 void rtnl_neigh_unset_state(struct rtnl_neigh *neigh, int state)
816 {
817  neigh->n_state_mask |= state;
818  neigh->n_state &= ~state;
819  neigh->ce_mask |= NEIGH_ATTR_STATE;
820 }
821 
822 void rtnl_neigh_set_flags(struct rtnl_neigh *neigh, unsigned int flags)
823 {
824  neigh->n_flag_mask |= flags;
825  neigh->n_flags |= flags;
826  neigh->ce_mask |= NEIGH_ATTR_FLAGS;
827 }
828 
829 unsigned int rtnl_neigh_get_flags(struct rtnl_neigh *neigh)
830 {
831  return neigh->n_flags;
832 }
833 
834 void rtnl_neigh_unset_flags(struct rtnl_neigh *neigh, unsigned int flags)
835 {
836  neigh->n_flag_mask |= flags;
837  neigh->n_flags &= ~flags;
838  neigh->ce_mask |= NEIGH_ATTR_FLAGS;
839 }
840 
841 void rtnl_neigh_set_ifindex(struct rtnl_neigh *neigh, int ifindex)
842 {
843  neigh->n_ifindex = ifindex;
844  neigh->ce_mask |= NEIGH_ATTR_IFINDEX;
845 }
846 
847 int rtnl_neigh_get_ifindex(struct rtnl_neigh *neigh)
848 {
849  return neigh->n_ifindex;
850 }
851 
852 static inline int __assign_addr(struct rtnl_neigh *neigh, struct nl_addr **pos,
853  struct nl_addr *new, int flag, int nocheck)
854 {
855  if (!nocheck) {
856  if (neigh->ce_mask & NEIGH_ATTR_FAMILY) {
857  if (new->a_family != neigh->n_family)
858  return -NLE_AF_MISMATCH;
859  } else {
860  neigh->n_family = new->a_family;
861  neigh->ce_mask |= NEIGH_ATTR_FAMILY;
862  }
863  }
864 
865  if (*pos)
866  nl_addr_put(*pos);
867 
868  nl_addr_get(new);
869  *pos = new;
870 
871  neigh->ce_mask |= flag;
872 
873  return 0;
874 }
875 
876 void rtnl_neigh_set_lladdr(struct rtnl_neigh *neigh, struct nl_addr *addr)
877 {
878  __assign_addr(neigh, &neigh->n_lladdr, addr, NEIGH_ATTR_LLADDR, 1);
879 }
880 
881 struct nl_addr *rtnl_neigh_get_lladdr(struct rtnl_neigh *neigh)
882 {
883  if (neigh->ce_mask & NEIGH_ATTR_LLADDR)
884  return neigh->n_lladdr;
885  else
886  return NULL;
887 }
888 
889 int rtnl_neigh_set_dst(struct rtnl_neigh *neigh, struct nl_addr *addr)
890 {
891  return __assign_addr(neigh, &neigh->n_dst, addr,
892  NEIGH_ATTR_DST, 0);
893 }
894 
895 struct nl_addr *rtnl_neigh_get_dst(struct rtnl_neigh *neigh)
896 {
897  if (neigh->ce_mask & NEIGH_ATTR_DST)
898  return neigh->n_dst;
899  else
900  return NULL;
901 }
902 
903 void rtnl_neigh_set_family(struct rtnl_neigh *neigh, int family)
904 {
905  neigh->n_family = family;
906  neigh->ce_mask |= NEIGH_ATTR_FAMILY;
907 }
908 
909 int rtnl_neigh_get_family(struct rtnl_neigh *neigh)
910 {
911  return neigh->n_family;
912 }
913 
914 void rtnl_neigh_set_type(struct rtnl_neigh *neigh, int type)
915 {
916  neigh->n_type = type;
917  neigh->ce_mask = NEIGH_ATTR_TYPE;
918 }
919 
920 int rtnl_neigh_get_type(struct rtnl_neigh *neigh)
921 {
922  if (neigh->ce_mask & NEIGH_ATTR_TYPE)
923  return neigh->n_type;
924  else
925  return -1;
926 }
927 
928 void rtnl_neigh_set_vlan(struct rtnl_neigh *neigh, int vlan)
929 {
930  neigh->n_vlan = vlan;
931  neigh->ce_mask |= NEIGH_ATTR_VLAN;
932 }
933 
934 int rtnl_neigh_get_vlan(struct rtnl_neigh *neigh)
935 {
936  if (neigh->ce_mask & NEIGH_ATTR_VLAN)
937  return neigh->n_vlan;
938  else
939  return -1;
940 }
941 
942 /** @} */
943 
944 static struct nl_object_ops neigh_obj_ops = {
945  .oo_name = "route/neigh",
946  .oo_size = sizeof(struct rtnl_neigh),
947  .oo_free_data = neigh_free_data,
948  .oo_clone = neigh_clone,
949  .oo_dump = {
950  [NL_DUMP_LINE] = neigh_dump_line,
951  [NL_DUMP_DETAILS] = neigh_dump_details,
952  [NL_DUMP_STATS] = neigh_dump_stats,
953  },
954  .oo_compare = neigh_compare,
955  .oo_keygen = neigh_keygen,
956  .oo_attrs2str = neigh_attrs2str,
957  .oo_id_attrs = (NEIGH_ATTR_IFINDEX | NEIGH_ATTR_DST | NEIGH_ATTR_FAMILY),
958  .oo_id_attrs_get = neigh_id_attrs_get
959 };
960 
961 static struct nl_af_group neigh_groups[] = {
962  { AF_UNSPEC, RTNLGRP_NEIGH },
963  { AF_BRIDGE, RTNLGRP_NEIGH },
964  { END_OF_GROUP_LIST },
965 };
966 
967 static struct nl_cache_ops rtnl_neigh_ops = {
968  .co_name = "route/neigh",
969  .co_hdrsize = sizeof(struct ndmsg),
970  .co_msgtypes = {
971  { RTM_NEWNEIGH, NL_ACT_NEW, "new" },
972  { RTM_DELNEIGH, NL_ACT_DEL, "del" },
973  { RTM_GETNEIGH, NL_ACT_GET, "get" },
974  END_OF_MSGTYPES_LIST,
975  },
976  .co_protocol = NETLINK_ROUTE,
977  .co_groups = neigh_groups,
978  .co_request_update = neigh_request_update,
979  .co_msg_parser = neigh_msg_parser,
980  .co_obj_ops = &neigh_obj_ops,
981 };
982 
983 static void __init neigh_init(void)
984 {
985  nl_cache_mngt_register(&rtnl_neigh_ops);
986 }
987 
988 static void __exit neigh_exit(void)
989 {
990  nl_cache_mngt_unregister(&rtnl_neigh_ops);
991 }
992 
993 /** @} */
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
Definition: nl.c:1252
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
Definition: addr.c:471
Dump object briefly on one line.
Definition: types.h:22
int nl_get_user_hz(void)
Return the value of HZ.
Definition: utils.c:465
void nlmsg_free(struct nl_msg *msg)
Release a reference from an netlink message.
Definition: msg.c:558
int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
Compare abstract addresses.
Definition: addr.c:563
int nl_addr_guess_family(const struct nl_addr *addr)
Guess address family of abstract address based on address size.
Definition: addr.c:673
int rtnl_neigh_delete(struct nl_sock *sk, struct rtnl_neigh *neigh, int flags)
Delete a neighbour.
Definition: neigh.c:718
void * nlmsg_data(const struct nlmsghdr *nlh)
Return pointer to message payload.
Definition: msg.c:105
#define NLA_PUT_ADDR(msg, attrtype, addr)
Add address attribute to netlink message.
Definition: attr.h:286
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
Definition: object.c:54
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
Definition: cache_mngt.c:287
Attribute validation policy.
Definition: attr.h:67
struct nl_cache * nl_cache_mngt_require_safe(const char *name)
Return cache previously provided via nl_cache_mngt_provide()
Definition: cache_mngt.c:430
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
Definition: object.c:204
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:699
int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, struct nla_policy *policy)
parse attributes of a netlink message
Definition: msg.c:213
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
Definition: addr.c:501
void nl_addr_set_family(struct nl_addr *addr, int family)
Set address family.
Definition: addr.c:832
struct nl_addr * nl_addr_alloc_attr(const struct nlattr *nla, int family)
Allocate abstract address based on Netlink attribute.
Definition: addr.c:255
int rtnl_neigh_add(struct nl_sock *sk, struct rtnl_neigh *tmpl, int flags)
Add a new neighbour.
Definition: neigh.c:663
Dump all attributes but no statistics.
Definition: types.h:23
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
Definition: cache_mngt.c:252
struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *cache, int ifindex, struct nl_addr *dst)
Look up a neighbour by interface index and destination address.
Definition: neigh.c:549
int rtnl_neigh_build_delete_request(struct rtnl_neigh *neigh, int flags, struct nl_msg **result)
Build a netlink request message to delete a neighbour.
Definition: neigh.c:700
int nl_rtgen_request(struct nl_sock *sk, int type, int family, int flags)
Send routing netlink request message.
Definition: rtnl.c:41
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
Definition: attr.c:120
int rtnl_neigh_build_add_request(struct rtnl_neigh *tmpl, int flags, struct nl_msg **result)
Build netlink request message to add a new neighbour.
Definition: neigh.c:639
int rtnl_neigh_alloc_cache(struct nl_sock *sock, struct nl_cache **result)
Build a neighbour cache including all neighbours currently configured in the kernel.
Definition: neigh.c:536
uint16_t minlen
Minimal length of payload required.
Definition: attr.h:72
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
Definition: msg.c:442
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
Definition: object.c:215
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
Definition: addr.c:517
struct nl_msg * nlmsg_alloc_simple(int nlmsgtype, int flags)
Allocate a new netlink message.
Definition: msg.c:346
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
Definition: attr.c:649
32 bit integer
Definition: attr.h:41
Dumping parameters.
Definition: types.h:33
#define NLA_PUT_U16(msg, attrtype, value)
Add 16 bit integer attribute to netlink message.
Definition: attr.h:215
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:914
unsigned int nl_addr_get_len(const struct nl_addr *addr)
Get length of binary address of abstract address object.
Definition: addr.c:905
Dump all attributes including statistics.
Definition: types.h:24
void * nl_addr_get_binary_addr(const struct nl_addr *addr)
Get binary address of abstract address object.
Definition: addr.c:893
int nl_cache_alloc_and_fill(struct nl_cache_ops *ops, struct nl_sock *sock, struct nl_cache **result)
Allocate new cache and fill it.
Definition: cache.c:233
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
Definition: addr.c:951
int nl_addr_get_family(const struct nl_addr *addr)
Return address family.
Definition: addr.c:845